Skip to content

Commit

Permalink
[PATCH] ppc64: SMU based macs cpufreq support
Browse files Browse the repository at this point in the history
CPU freq support using 970FX powertune facility for iMac G5 and SMU
based single CPU desktop.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Benjamin Herrenschmidt authored and Paul Mackerras committed Nov 8, 2005
1 parent a82765b commit 4350147
Show file tree
Hide file tree
Showing 11 changed files with 572 additions and 25 deletions.
8 changes: 8 additions & 0 deletions arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,14 @@ config CPU_FREQ_PMAC
this currently includes some models of iBook & Titanium
PowerBook.

config CPU_FREQ_PMAC64
bool "Support for some Apple G5s"
depends on CPU_FREQ && PMAC_SMU && PPC64
select CPU_FREQ_TABLE
help
This adds support for frequency switching on Apple iMac G5,
and some of the more recent desktop G5 machines as well.

config PPC601_SYNC_FIX
bool "Workarounds for PPC601 bugs"
depends on 6xx && (PPC_PREP || PPC_PMAC)
Expand Down
70 changes: 70 additions & 0 deletions arch/powerpc/kernel/misc_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,76 @@ _GLOBAL(real_writeb)
blr
#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */

/*
* SCOM access functions for 970 (FX only for now)
*
* unsigned long scom970_read(unsigned int address);
* void scom970_write(unsigned int address, unsigned long value);
*
* The address passed in is the 24 bits register address. This code
* is 970 specific and will not check the status bits, so you should
* know what you are doing.
*/
_GLOBAL(scom970_read)
/* interrupts off */
mfmsr r4
ori r0,r4,MSR_EE
xori r0,r0,MSR_EE
mtmsrd r0,1

/* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
* (including parity). On current CPUs they must be 0'd,
* and finally or in RW bit
*/
rlwinm r3,r3,8,0,15
ori r3,r3,0x8000

/* do the actual scom read */
sync
mtspr SPRN_SCOMC,r3
isync
mfspr r3,SPRN_SCOMD
isync
mfspr r0,SPRN_SCOMC
isync

/* XXX: fixup result on some buggy 970's (ouch ! we lost a bit, bah
* that's the best we can do). Not implemented yet as we don't use
* the scom on any of the bogus CPUs yet, but may have to be done
* ultimately
*/

/* restore interrupts */
mtmsrd r4,1
blr


_GLOBAL(scom970_write)
/* interrupts off */
mfmsr r5
ori r0,r5,MSR_EE
xori r0,r0,MSR_EE
mtmsrd r0,1

/* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
* (including parity). On current CPUs they must be 0'd.
*/

rlwinm r3,r3,8,0,15

sync
mtspr SPRN_SCOMD,r4 /* write data */
isync
mtspr SPRN_SCOMC,r3 /* write command */
isync
mfspr 3,SPRN_SCOMC
isync

/* restore interrupts */
mtmsrd r5,1
blr


/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
Expand Down
3 changes: 2 additions & 1 deletion arch/powerpc/platforms/powermac/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
obj-y += pic.o setup.o time.o feature.o pci.o \
sleep.o low_i2c.o cache.o
obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o
obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
obj-$(CONFIG_NVRAM) += nvram.o
# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
obj-$(CONFIG_PPC64) += nvram.o
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,18 +397,16 @@ static int pmac_cpufreq_target( struct cpufreq_policy *policy,
unsigned int relation)
{
unsigned int newstate = 0;
int rc;

if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
target_freq, relation, &newstate))
return -EINVAL;

return do_set_cpu_speed(newstate, 1);
}
rc = do_set_cpu_speed(newstate, 1);

unsigned int pmac_get_one_cpufreq(int i)
{
/* Supports only one CPU for now */
return (i == 0) ? cur_freq : 0;
ppc_proc_freq = cur_freq * 1000ul;
return rc;
}

static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
Expand Down Expand Up @@ -464,7 +462,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
/* If we resume, first check if we have a get() function */
if (get_speed_proc)
cur_freq = get_speed_proc();
else
else)
cur_freq = 0;

/* We don't, hrm... we don't really know our speed here, best
Expand All @@ -474,6 +472,8 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
do_set_cpu_speed(sleep_freq == low_freq ?
CPUFREQ_LOW : CPUFREQ_HIGH, 0);

ppc_proc_freq = cur_freq * 1000ul;

no_schedule = 0;
return 0;
}
Expand Down Expand Up @@ -547,7 +547,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
*/
if (low_freq < 98000000)
low_freq = 101000000;

/* Convert those to CPU core clocks */
low_freq = (low_freq * (*ratio)) / 2000;
hi_freq = (hi_freq * (*ratio)) / 2000;
Expand Down Expand Up @@ -714,6 +714,7 @@ static int __init pmac_cpufreq_setup(void)

pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
ppc_proc_freq = cur_freq * 1000ul;

printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
Expand Down
Loading

0 comments on commit 4350147

Please sign in to comment.