[PATCH] cpufreq support for 7447A on 2004 iBooks
John Steele Scott
toojays at toojays.net
Sat Jun 5 19:15:58 EST 2004
Okay, thanks to some tips from Benjamin Herrenschmidt, I now have a patch
against 2.6.6 which lets you control dynamic frequency scaling on the latest
model iBook G4. I imagine that this same method would apply to the new
PowerBooks as well.
cheers,
John
diff -upr -X dontdiff linux/arch/ppc/kernel/misc.S
linux-2.6.6-dfs/arch/ppc/kernel/misc.S
- --- linux/arch/ppc/kernel/misc.S 2004-06-05 18:02:48.000000000 +0930
+++ linux-2.6.6-dfs/arch/ppc/kernel/misc.S 2004-05-28 12:47:22.000000000 +0930
@@ -253,6 +253,24 @@ _GLOBAL(low_choose_750fx_pll)
mtmsr r7
blr
+_GLOBAL(choose_7447a_dfs)
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* Calc new HID1 value */
+ mfspr r4,SPRN_HID1
+ insrwi r4,r3,1,9 /* insert parameter into bit 9 */
+ sync
+ mtspr SPRN_HID1,r4
+ sync
+ isync
+
+ /* Return */
+ mtmsr r7
+ blr
+
#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
/* void local_save_flags_ptr(unsigned long *flags) */
diff -upr -X dontdiff linux/arch/ppc/platforms/pmac_cpufreq.c
linux-2.6.6-dfs/arch/ppc/platforms/pmac_cpufreq.c
- --- linux/arch/ppc/platforms/pmac_cpufreq.c 2004-06-05 18:02:48.000000000
+0930
+++ linux-2.6.6-dfs/arch/ppc/platforms/pmac_cpufreq.c 2004-06-05
18:08:06.000000000 +0930
@@ -47,6 +47,7 @@
#warning "WARNING, CPUFREQ not recommended on SMP kernels"
#endif
+extern void choose_7447a_dfs(int dfs);
extern void low_choose_750fx_pll(int pll);
extern void low_sleep_handler(void);
extern void openpic_suspend(struct sys_device *sysdev, u32 state);
@@ -61,6 +62,7 @@ static unsigned int cur_freq;
/* Clean that up some day ... use a func ptr or at least an enum... */
static int cpufreq_uses_pmu;
static int cpufreq_uses_gpios;
+static int cpufreq_uses_dfs;
static u32 voltage_gpio;
static u32 frequency_gpio;
@@ -123,6 +125,29 @@ static int __pmac cpu_750fx_cpu_speed(in
return 0;
}
+/* Switch CPU speed using DFS */
+static int __pmac dfs_set_cpu_speed(int low_speed)
+{
+ /* If ramping up, set voltage first */
+ if (low_speed == 0) {
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ/1000);
+ }
+
+ /* set frequency */
+ choose_7447a_dfs(low_speed);
+
+ /* If ramping down, set voltage last */
+ if (low_speed == 1) {
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ/1000);
+ }
+
+ return 0;
+}
+
/* Switch CPU speed using slewing GPIOs
*/
static int __pmac gpios_set_cpu_speed(unsigned int low_speed)
@@ -273,6 +298,8 @@ static int __pmac do_set_cpu_speed(int s
rc = pmu_set_cpu_speed(speed_mode);
else if (cpufreq_uses_gpios)
rc = gpios_set_cpu_speed(speed_mode);
+ else if (cpufreq_uses_dfs)
+ rc = dfs_set_cpu_speed(speed_mode);
else
rc = cpu_750fx_cpu_speed(speed_mode);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
@@ -346,6 +373,7 @@ static struct cpufreq_driver pmac_cpufre
* - iBook2 500 (PMU based, 400Mhz & 500Mhz)
* - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
* - Recent MacRISC3 machines
+ * - iBook G4s with 7447A CPUs
*/
static int __init pmac_cpufreq_setup(void)
{
@@ -375,6 +403,32 @@ static int __init pmac_cpufreq_setup(voi
struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
"frequency-gpio");
struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
"slewing-done");
+ /* Check for 7447A based iBook G4 */
+ if (machine_is_compatible("PowerBook6,5")) {
+ /* OF only reports the high frequency */
+ hi_freq = cur_freq;
+ low_freq = cur_freq/2;
+ if(mfspr(HID1) & HID1_DFS)
+ cur_freq = low_freq;
+ else
+ cur_freq = hi_freq;
+
+ volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+ if (!volt_gpio_np){
+ printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
+ goto out;
+ }
+
+ u32 *reg = (u32 *)get_property(volt_gpio_np, "reg", NULL);
+ voltage_gpio = *reg;
+
+ cpufreq_uses_pmu = 0;
+ cpufreq_uses_gpios = 0;
+ cpufreq_uses_dfs = 1;
+ has_freq_ctl = 1;
+ goto out;
+ }
+
/*
* Check to see if it's GPIO driven or PMU only
*
@@ -497,7 +551,7 @@ out:
printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz, switch method:
%s\n",
low_freq/1000, hi_freq/1000, cur_freq/1000,
- - cpufreq_uses_pmu ? "PMU" : (cpufreq_uses_gpios ? "GPIOs" : "CPU"));
+ cpufreq_uses_pmu ? "PMU" : (cpufreq_uses_gpios ? "GPIOs" :
(cpufreq_uses_dfs ? "DFS" : "CPU")));
return cpufreq_register_driver(&pmac_cpufreq_driver);
}
diff -upr -X dontdiff linux/include/asm-ppc/reg.h
linux-2.6.6-dfs/include/asm-ppc/reg.h
- --- linux/include/asm-ppc/reg.h 2004-06-05 18:02:48.000000000 +0930
+++ linux-2.6.6-dfs/include/asm-ppc/reg.h 2004-06-05 18:37:00.778149544 +0930
@@ -174,6 +174,7 @@
#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */
+#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */
#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */
#define HID1_PC1 (1<<15) /* 7450 PLL_CFG[1] */
#define HID1_PC2 (1<<14) /* 7450 PLL_CFG[2] */
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list