diff options
| author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-11-06 22:27:33 -0500 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2005-11-07 19:17:34 -0500 |
| commit | 4350147a816b9c5b40fa59e4fa23f17490630b79 (patch) | |
| tree | c333986047de60aa90809d669895726610c0c3e5 | |
| parent | a82765b6eee3d1267ded3320ca67b39fe1844599 (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/Kconfig | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/misc_64.S | 70 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powermac/Makefile | 3 | ||||
| -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.c | 323 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 13 | ||||
| -rw-r--r-- | arch/ppc64/Kconfig | 10 | ||||
| -rw-r--r-- | arch/ppc64/kernel/misc.S | 72 | ||||
| -rw-r--r-- | drivers/macintosh/smu.c | 12 | ||||
| -rw-r--r-- | include/asm-powerpc/reg.h | 9 | ||||
| -rw-r--r-- | include/asm-powerpc/smu.h | 60 |
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 | ||
| 407 | config 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 | |||
| 407 | config PPC601_SYNC_FIX | 415 | config 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 @@ | |||
| 1 | obj-y += pic.o setup.o time.o feature.o pci.o \ | 1 | obj-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 |
| 3 | obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o | 3 | obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o |
| 4 | obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq.o | 4 | obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o |
| 5 | obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o | ||
| 5 | obj-$(CONFIG_NVRAM) += nvram.o | 6 | obj-$(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 |
| 7 | obj-$(CONFIG_PPC64) += nvram.o | 8 | obj-$(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 | ||
| 408 | unsigned 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 | ||
| 414 | static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) | 412 | static 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 */ | ||
