aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac/smp.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-01-06 19:41:02 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:47:18 -0500
commit5b9ca526917b7bc7d1da3beaccb2251a8f0b5fe2 (patch)
treef345cbb73a4c5bb4c5645d53df2653c916e54172 /arch/powerpc/platforms/powermac/smp.c
parenta28d3af2a26c89aaa6470ca36edb212e05143d67 (diff)
[PATCH] 3/5 powerpc: Add platform functions interpreter
This is the platform function interpreter itself along with the backends for UniN/U3/U4, mac-io, GPIOs and i2c. It adds the ability to execute those do-platform-* scripts in the device-tree (at least for most devices for which a backend is provided). This should replace the clock spreading hacks properly. It might also have an impact on all sort of machines since some of the scripts marked "at init" will now be executed on boot (or some other on sleep/wakeup), those will possibly do things that the kernel didn't do at all, like setting some values into some i2c devices (changing thermal sensor calibration or conversion rate) etc... Thus regression testing is MUCH welcome. Also loook for errors in dmesg. That's also why I've left rather verbose debugging enabled in this version of the patch. (I do expect some Windtunnel G4s to show some errors as they have an i2c clock chip on the PMU bus that uses some primitives that the i2c backend doesn't implement yet. I really need users that have one of those machine to come back to me so we can get that done right, though the errors themselves should be harmless, I suspect the machine might not run at full speed). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac/smp.c')
-rw-r--r--arch/powerpc/platforms/powermac/smp.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index ab72ba86be1e..0df2cdcd805c 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -52,8 +52,9 @@
52#include <asm/cacheflush.h> 52#include <asm/cacheflush.h>
53#include <asm/keylargo.h> 53#include <asm/keylargo.h>
54#include <asm/pmac_low_i2c.h> 54#include <asm/pmac_low_i2c.h>
55#include <asm/pmac_pfunc.h>
55 56
56#undef DEBUG 57#define DEBUG
57 58
58#ifdef DEBUG 59#ifdef DEBUG
59#define DBG(fmt...) udbg_printf(fmt) 60#define DBG(fmt...) udbg_printf(fmt)
@@ -62,6 +63,7 @@
62#endif 63#endif
63 64
64extern void __secondary_start_pmac_0(void); 65extern void __secondary_start_pmac_0(void);
66extern int pmac_pfunc_base_install(void);
65 67
66#ifdef CONFIG_PPC32 68#ifdef CONFIG_PPC32
67 69
@@ -602,11 +604,29 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
602 pmac_tb_clock_chip_host = NULL; 604 pmac_tb_clock_chip_host = NULL;
603} 605}
604 606
605#endif /* CONFIG_PPC64 */
606 607
607 608
608/* 609/*
609 * SMP G4 and newer G5 use a GPIO to enable/disable the timebase. 610 * Newer G5s uses a platform function
611 */
612
613static void smp_core99_pfunc_tb_freeze(int freeze)
614{
615 struct device_node *cpus;
616 struct pmf_args args;
617
618 cpus = of_find_node_by_path("/cpus");
619 BUG_ON(cpus == NULL);
620 args.count = 1;
621 args.u[0].v = !freeze;
622 pmf_call_function(cpus, "cpu-timebase", &args);
623 of_node_put(cpus);
624}
625
626#else /* CONFIG_PPC64 */
627
628/*
629 * SMP G4 use a GPIO to enable/disable the timebase.
610 */ 630 */
611 631
612static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */ 632static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */
@@ -620,6 +640,9 @@ static void smp_core99_gpio_tb_freeze(int freeze)
620 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); 640 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
621} 641}
622 642
643
644#endif /* !CONFIG_PPC64 */
645
623/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ 646/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
624volatile static long int core99_l2_cache; 647volatile static long int core99_l2_cache;
625volatile static long int core99_l3_cache; 648volatile static long int core99_l3_cache;
@@ -665,19 +688,15 @@ static void __init smp_core99_setup(int ncpus)
665 machine_is_compatible("RackMac3,1")) 688 machine_is_compatible("RackMac3,1"))
666 smp_core99_setup_i2c_hwsync(ncpus); 689 smp_core99_setup_i2c_hwsync(ncpus);
667 690
668 /* GPIO based HW sync on recent G5s */ 691 /* pfunc based HW sync on recent G5s */
669 if (pmac_tb_freeze == NULL) { 692 if (pmac_tb_freeze == NULL) {
670 struct device_node *np = 693 struct device_node *cpus =
671 of_find_node_by_name(NULL, "timebase-enable"); 694 of_find_node_by_path("/cpus");
672 u32 *reg = (u32 *)get_property(np, "reg", NULL); 695 if (cpus &&
673 696 get_property(cpus, "platform-cpu-timebase", NULL)) {
674 if (np && reg && !strcmp(np->type, "gpio")) { 697 pmac_tb_freeze = smp_core99_pfunc_tb_freeze;
675 core99_tb_gpio = *reg;
676 if (core99_tb_gpio < 0x50)
677 core99_tb_gpio += 0x50;
678 pmac_tb_freeze = smp_core99_gpio_tb_freeze;
679 printk(KERN_INFO "Processor timebase sync using" 698 printk(KERN_INFO "Processor timebase sync using"
680 " GPIO 0x%02x\n", core99_tb_gpio); 699 " platform function\n");
681 } 700 }
682 } 701 }
683 702
@@ -746,6 +765,7 @@ static int __init smp_core99_probe(void)
746 /* We need to perform some early initialisations before we can start 765 /* We need to perform some early initialisations before we can start
747 * setting up SMP as we are running before initcalls 766 * setting up SMP as we are running before initcalls
748 */ 767 */
768 pmac_pfunc_base_install();
749 pmac_i2c_init(); 769 pmac_i2c_init();
750 770
751 /* Setup various bits like timebase sync method, ability to nap, ... */ 771 /* Setup various bits like timebase sync method, ability to nap, ... */