aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-06 22:27:33 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-07 19:17:34 -0500
commit4350147a816b9c5b40fa59e4fa23f17490630b79 (patch)
treec333986047de60aa90809d669895726610c0c3e5
parenta82765b6eee3d1267ded3320ca67b39fe1844599 (diff)
[PATCH] ppc64: SMU based macs cpufreq support
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>
-rw-r--r--arch/powerpc/Kconfig8
-rw-r--r--arch/powerpc/kernel/misc_64.S70
-rw-r--r--arch/powerpc/platforms/powermac/Makefile3
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c (renamed from arch/powerpc/platforms/powermac/cpufreq.c)17
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c323
-rw-r--r--arch/powerpc/platforms/powermac/setup.c13
-rw-r--r--arch/ppc64/Kconfig10
-rw-r--r--arch/ppc64/kernel/misc.S72
-rw-r--r--drivers/macintosh/smu.c12
-rw-r--r--include/asm-powerpc/reg.h9
-rw-r--r--include/asm-powerpc/smu.h60
11 files changed, 572 insertions, 25 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6ffae2d2b3fa..3ac9195dab35 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -404,6 +404,14 @@ config CPU_FREQ_PMAC
404 this currently includes some models of iBook & Titanium 404 this currently includes some models of iBook & Titanium
405 PowerBook. 405 PowerBook.
406 406
407config CPU_FREQ_PMAC64
408 bool "Support for some Apple G5s"
409 depends on CPU_FREQ && PMAC_SMU && PPC64
410 select CPU_FREQ_TABLE
411 help
412 This adds support for frequency switching on Apple iMac G5,
413 and some of the more recent desktop G5 machines as well.
414
407config PPC601_SYNC_FIX 415config PPC601_SYNC_FIX
408 bool "Workarounds for PPC601 bugs" 416 bool "Workarounds for PPC601 bugs"
409 depends on 6xx && (PPC_PREP || PPC_PMAC) 417 depends on 6xx && (PPC_PREP || PPC_PMAC)
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index b3e95ff0dba0..ae1433da09b2 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -604,6 +604,76 @@ _GLOBAL(real_writeb)
604#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ 604#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
605 605
606/* 606/*
607 * SCOM access functions for 970 (FX only for now)
608 *
609 * unsigned long scom970_read(unsigned int address);
610 * void scom970_write(unsigned int address, unsigned long value);
611 *
612 * The address passed in is the 24 bits register address. This code
613 * is 970 specific and will not check the status bits, so you should
614 * know what you are doing.
615 */
616_GLOBAL(scom970_read)
617 /* interrupts off */
618 mfmsr r4
619 ori r0,r4,MSR_EE
620 xori r0,r0,MSR_EE
621 mtmsrd r0,1
622
623 /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
624 * (including parity). On current CPUs they must be 0'd,
625 * and finally or in RW bit
626 */
627 rlwinm r3,r3,8,0,15
628 ori r3,r3,0x8000
629
630 /* do the actual scom read */
631 sync
632 mtspr SPRN_SCOMC,r3
633 isync
634 mfspr r3,SPRN_SCOMD
635 isync
636 mfspr r0,SPRN_SCOMC
637 isync
638
639 /* XXX: fixup result on some buggy 970's (ouch ! we lost a bit, bah
640 * that's the best we can do). Not implemented yet as we don't use
641 * the scom on any of the bogus CPUs yet, but may have to be done
642 * ultimately
643 */
644
645 /* restore interrupts */
646 mtmsrd r4,1
647 blr
648
649
650_GLOBAL(scom970_write)
651 /* interrupts off */
652 mfmsr r5
653 ori r0,r5,MSR_EE
654 xori r0,r0,MSR_EE
655 mtmsrd r0,1
656
657 /* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
658 * (including parity). On current CPUs they must be 0'd.
659 */
660
661 rlwinm r3,r3,8,0,15
662
663 sync
664 mtspr SPRN_SCOMD,r4 /* write data */
665 isync
666 mtspr SPRN_SCOMC,r3 /* write command */
667 isync
668 mfspr 3,SPRN_SCOMC
669 isync
670
671 /* restore interrupts */
672 mtmsrd r5,1
673 blr
674
675
676/*
607 * Create a kernel thread 677 * Create a kernel thread
608 * kernel_thread(fn, arg, flags) 678 * kernel_thread(fn, arg, flags)
609 */ 679 */
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 4369676f1d54..c9df44fcf571 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -1,7 +1,8 @@
1obj-y += pic.o setup.o time.o feature.o pci.o \ 1obj-y += pic.o setup.o time.o feature.o pci.o \
2 sleep.o low_i2c.o cache.o 2 sleep.o low_i2c.o cache.o
3obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o 3obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
4obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o 4obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
5obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
5obj-$(CONFIG_NVRAM) += nvram.o 6obj-$(CONFIG_NVRAM) += nvram.o
6# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff 7# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
7obj-$(CONFIG_PPC64) += nvram.o 8obj-$(CONFIG_PPC64) += nvram.o
diff --git a/arch/powerpc/platforms/powermac/cpufreq.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index c47f8b69725c..7960a7bfca0a 100644
--- a/arch/powerpc/platforms/powermac/cpufreq.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -397,18 +397,16 @@ static int pmac_cpufreq_target( struct cpufreq_policy *policy,
397 unsigned int relation) 397 unsigned int relation)
398{ 398{
399 unsigned int newstate = 0; 399 unsigned int newstate = 0;
400 int rc;
400 401
401 if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs, 402 if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
402 target_freq, relation, &newstate)) 403 target_freq, relation, &newstate))
403 return -EINVAL; 404 return -EINVAL;
404 405
405 return do_set_cpu_speed(newstate, 1); 406 rc = do_set_cpu_speed(newstate, 1);
406}
407 407
408unsigned int pmac_get_one_cpufreq(int i) 408 ppc_proc_freq = cur_freq * 1000ul;
409{ 409 return rc;
410 /* Supports only one CPU for now */
411 return (i == 0) ? cur_freq : 0;
412} 410}
413 411
414static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) 412static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
@@ -464,7 +462,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
464 /* If we resume, first check if we have a get() function */ 462 /* If we resume, first check if we have a get() function */
465 if (get_speed_proc) 463 if (get_speed_proc)
466 cur_freq = get_speed_proc(); 464 cur_freq = get_speed_proc();
467 else 465 else)
468 cur_freq = 0; 466 cur_freq = 0;
469 467
470 /* We don't, hrm... we don't really know our speed here, best 468 /* We don't, hrm... we don't really know our speed here, best
@@ -474,6 +472,8 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
474 do_set_cpu_speed(sleep_freq == low_freq ? 472 do_set_cpu_speed(sleep_freq == low_freq ?
475 CPUFREQ_LOW : CPUFREQ_HIGH, 0); 473 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
476 474
475 ppc_proc_freq = cur_freq * 1000ul;
476
477 no_schedule = 0; 477 no_schedule = 0;
478 return 0; 478 return 0;
479} 479}
@@ -547,7 +547,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
547 */ 547 */
548 if (low_freq < 98000000) 548 if (low_freq < 98000000)
549 low_freq = 101000000; 549 low_freq = 101000000;
550 550
551 /* Convert those to CPU core clocks */