linux/arch/powerpc/platforms/powermac/cpufreq_32.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
   3 *  Copyright (C) 2004        John Steele Scott <toojays@toojays.net>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 *
   9 * TODO: Need a big cleanup here. Basically, we need to have different
  10 * cpufreq_driver structures for the different type of HW instead of the
  11 * current mess. We also need to better deal with the detection of the
  12 * type of machine.
  13 *
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/types.h>
  18#include <linux/errno.h>
  19#include <linux/kernel.h>
  20#include <linux/delay.h>
  21#include <linux/sched.h>
  22#include <linux/adb.h>
  23#include <linux/pmu.h>
  24#include <linux/cpufreq.h>
  25#include <linux/init.h>
  26#include <linux/device.h>
  27#include <linux/hardirq.h>
  28#include <asm/prom.h>
  29#include <asm/machdep.h>
  30#include <asm/irq.h>
  31#include <asm/pmac_feature.h>
  32#include <asm/mmu_context.h>
  33#include <asm/sections.h>
  34#include <asm/cputable.h>
  35#include <asm/time.h>
  36#include <asm/system.h>
  37#include <asm/mpic.h>
  38#include <asm/keylargo.h>
  39
  40/* WARNING !!! This will cause calibrate_delay() to be called,
  41 * but this is an __init function ! So you MUST go edit
  42 * init/main.c to make it non-init before enabling DEBUG_FREQ
  43 */
  44#undef DEBUG_FREQ
  45
  46extern void low_choose_7447a_dfs(int dfs);
  47extern void low_choose_750fx_pll(int pll);
  48extern void low_sleep_handler(void);
  49
  50/*
  51 * Currently, PowerMac cpufreq supports only high & low frequencies
  52 * that are set by the firmware
  53 */
  54static unsigned int low_freq;
  55static unsigned int hi_freq;
  56static unsigned int cur_freq;
  57static unsigned int sleep_freq;
  58
  59/*
  60 * Different models uses different mechanisms to switch the frequency
  61 */
  62static int (*set_speed_proc)(int low_speed);
  63static unsigned int (*get_speed_proc)(void);
  64
  65/*
  66 * Some definitions used by the various speedprocs
  67 */
  68static u32 voltage_gpio;
  69static u32 frequency_gpio;
  70static u32 slew_done_gpio;
  71static int no_schedule;
  72static int has_cpu_l2lve;
  73static int is_pmu_based;
  74
  75/* There are only two frequency states for each processor. Values
  76 * are in kHz for the time being.
  77 */
  78#define CPUFREQ_HIGH                  0
  79#define CPUFREQ_LOW                   1
  80
  81static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
  82        {CPUFREQ_HIGH,          0},
  83        {CPUFREQ_LOW,           0},
  84        {0,                     CPUFREQ_TABLE_END},
  85};
  86
  87static struct freq_attr* pmac_cpu_freqs_attr[] = {
  88        &cpufreq_freq_attr_scaling_available_freqs,
  89        NULL,
  90};
  91
  92static inline void local_delay(unsigned long ms)
  93{
  94        if (no_schedule)
  95                mdelay(ms);
  96        else
  97                msleep(ms);
  98}
  99
 100#ifdef DEBUG_FREQ
 101static inline void debug_calc_bogomips(void)
 102{
 103        /* This will cause a recalc of bogomips and display the
 104         * result. We backup/restore the value to avoid affecting the
 105         * core cpufreq framework's own calculation.
 106         */
 107        unsigned long save_lpj = loops_per_jiffy;
 108        calibrate_delay();
 109        loops_per_jiffy = save_lpj;
 110}
 111#endif /* DEBUG_FREQ */
 112
 113/* Switch CPU speed under 750FX CPU control
 114 */
 115static int cpu_750fx_cpu_speed(int low_speed)
 116{
 117        u32 hid2;
 118
 119        if (low_speed == 0) {
 120                /* ramping up, set voltage first */
 121                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
 122                /* Make sure we sleep for at least 1ms */
 123                local_delay(10);
 124
 125                /* tweak L2 for high voltage */
 126                if (has_cpu_l2lve) {
 127                        hid2 = mfspr(SPRN_HID2);
 128                        hid2 &= ~0x2000;
 129                        mtspr(SPRN_HID2, hid2);
 130                }
 131        }
 132#ifdef CONFIG_6xx
 133        low_choose_750fx_pll(low_speed);
 134#endif
 135        if (low_speed == 1) {
 136                /* tweak L2 for low voltage */
 137                if (has_cpu_l2lve) {
 138                        hid2 = mfspr(SPRN_HID2);
 139                        hid2 |= 0x2000;
 140                        mtspr(SPRN_HID2, hid2);
 141                }
 142
 143                /* ramping down, set voltage last */
 144                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
 145                local_delay(10);
 146        }
 147
 148        return 0;
 149}
 150
 151static unsigned int cpu_750fx_get_cpu_speed(void)
 152{
 153        if (mfspr(SPRN_HID1) & HID1_PS)
 154                return low_freq;
 155        else
 156                return hi_freq;
 157}
 158
 159/* Switch CPU speed using DFS */
 160static int dfs_set_cpu_speed(int low_speed)
 161{
 162        if (low_speed == 0) {
 163                /* ramping up, set voltage first */
 164                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
 165                /* Make sure we sleep for at least 1ms */
 166                local_delay(1);
 167        }
 168
 169        /* set frequency */
 170#ifdef CONFIG_6xx
 171        low_choose_7447a_dfs(low_speed);
 172#endif
 173        udelay(100);
 174
 175        if (low_speed == 1) {
 176                /* ramping down, set voltage last */
 177                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
 178                local_delay(1);
 179        }
 180
 181        return 0;
 182}
 183
 184static unsigned int dfs_get_cpu_speed(void)
 185{
 186        if (mfspr(SPRN_HID1) & HID1_DFS)
 187                return low_freq;
 188        else
 189                return hi_freq;
 190}
 191
 192
 193/* Switch CPU speed using slewing GPIOs
 194 */
 195static int gpios_set_cpu_speed(int low_speed)
 196{
 197        int gpio, timeout = 0;
 198
 199        /* If ramping up, set voltage first */
 200        if (low_speed == 0) {
 201                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
 202                /* Delay is way too big but it's ok, we schedule */
 203                local_delay(10);
 204        }
 205
 206        /* Set frequency */
 207        gpio =  pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
 208        if (low_speed == ((gpio & 0x01) == 0))
 209                goto skip;
 210
 211        pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
 212                          low_speed ? 0x04 : 0x05);
 213        udelay(200);
 214        do {
 215                if (++timeout > 100)
 216                        break;
 217                local_delay(1);
 218                gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
 219        } while((gpio & 0x02) == 0);
 220 skip:
 221        /* If ramping down, set voltage last */
 222        if (low_speed == 1) {
 223                pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
 224                /* Delay is way too big but it's ok, we schedule */
 225                local_delay(10);
 226        }
 227
 228#ifdef DEBUG_FREQ
 229        debug_calc_bogomips();
 230#endif
 231
 232        return 0;
 233}
 234
 235/* Switch CPU speed under PMU control
 236 */
 237static int pmu_set_cpu_speed(int low_speed)
 238{
 239        struct adb_request req;
 240        unsigned long save_l2cr;
 241        unsigned long save_l3cr;
 242        unsigned int pic_prio;
 243        unsigned long flags;
 244
 245        preempt_disable();
 246
 247#ifdef DEBUG_FREQ
 248        printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 249#endif
 250        pmu_suspend();
 251
 252        /* Disable all interrupt sources on openpic */
 253        pic_prio = mpic_cpu_get_priority();
 254        mpic_cpu_set_priority(0xf);
 255
 256        /* Make sure the decrementer won't interrupt us */
 257        asm volatile("mtdec %0" : : "r" (0x7fffffff));
 258        /* Make sure any pending DEC interrupt occurring while we did
 259         * the above didn't re-enable the DEC */
 260        mb();
 261        asm volatile("mtdec %0" : : "r" (0x7fffffff));
 262
 263        /* We can now disable MSR_EE */
 264        local_irq_save(flags);
 265
 266        /* Giveup the FPU & vec */
 267        enable_kernel_fp();
 268
 269#ifdef CONFIG_ALTIVEC
 270        if (cpu_has_feature(CPU_FTR_ALTIVEC))
 271                enable_kernel_altivec();
 272#endif /* CONFIG_ALTIVEC */
 273
 274        /* Save & disable L2 and L3 caches */
 275        save_l3cr = _get_L3CR();        /* (returns -1 if not available) */
 276        save_l2cr = _get_L2CR();        /* (returns -1 if not available) */
 277
 278        /* Send the new speed command. My assumption is that this command
 279         * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
 280         */
 281        pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
 282        while (!req.complete)
 283                pmu_poll();
 284
 285        /* Prepare the northbridge for the speed transition */
 286        pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
 287
 288        /* Call low level code to backup CPU state and recover from
 289         * hardware reset
 290         */
 291        low_sleep_handler();
 292
 293        /* Restore the northbridge */
 294        pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
 295
 296        /* Restore L2 cache */
 297        if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
 298                _set_L2CR(save_l2cr);
 299        /* Restore L3 cache */
 300        if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
 301                _set_L3CR(save_l3cr);
 302
 303        /* Restore userland MMU context */
 304        switch_mmu_context(NULL, current->active_mm);
 305
 306#ifdef DEBUG_FREQ
 307        printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
 308#endif
 309
 310        /* Restore low level PMU operations */
 311        pmu_unlock();
 312
 313        /*
 314         * Restore decrementer; we'll take a decrementer interrupt
 315         * as soon as interrupts are re-enabled and the generic
 316         * clockevents code will reprogram it with the right value.
 317         */
 318        set_dec(1);
 319
 320        /* Restore interrupts */
 321        mpic_cpu_set_priority(pic_prio);
 322
 323        /* Let interrupts flow again ... */
 324        local_irq_restore(flags);
 325
 326#ifdef DEBUG_FREQ
 327        debug_calc_bogomips();
 328#endif
 329
 330        pmu_resume();
 331
 332        preempt_enable();
 333
 334        return 0;
 335}
 336
 337static int do_set_cpu_speed(int speed_mode, int notify)
 338{
 339        struct cpufreq_freqs freqs;
 340        unsigned long l3cr;
 341        static unsigned long prev_l3cr;
 342
 343        freqs.old = cur_freq;
 344        freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
 345        freqs.cpu = smp_processor_id();
 346
 347        if (freqs.old == freqs.new)
 348                return 0;
 349
 350        if (notify)
 351                cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 352        if (speed_mode == CPUFREQ_LOW &&
 353            cpu_has_feature(CPU_FTR_L3CR)) {
 354                l3cr = _get_L3CR();
 355                if (l3cr & L3CR_L3E) {
 356                        prev_l3cr = l3cr;
 357                        _set_L3CR(0);
 358                }
 359        }
 360        set_speed_proc(speed_mode == CPUFREQ_LOW);
 361        if (speed_mode == CPUFREQ_HIGH &&
 362            cpu_has_feature(CPU_FTR_L3CR)) {
 363                l3cr = _get_L3CR();
 364                if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
 365                        _set_L3CR(prev_l3cr);
 366        }
 367        if (notify)
 368                cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 369        cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
 370
 371        return 0;
 372}
 373
 374static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
 375{
 376        return cur_freq;
 377}
 378
 379static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
 380{
 381        return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
 382}
 383
 384static int pmac_cpufreq_target( struct cpufreq_policy *policy,
 385                                        unsigned int target_freq,
 386                                        unsigned int relation)
 387{
 388        unsigned int    newstate = 0;
 389        int             rc;
 390
 391        if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
 392                        target_freq, relation, &newstate))
 393                return -EINVAL;
 394
 395        rc = do_set_cpu_speed(newstate, 1);
 396
 397        ppc_proc_freq = cur_freq * 1000ul;
 398        return rc;
 399}
 400
 401static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
 402{
 403        if (policy->cpu != 0)
 404                return -ENODEV;
 405
 406        policy->cpuinfo.transition_latency      = CPUFREQ_ETERNAL;
 407        policy->cur = cur_freq;
 408
 409        cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
 410        return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
 411}
 412
 413static u32 read_gpio(struct device_node *np)
 414{
 415        const u32 *reg = of_get_property(np, "reg", NULL);
 416        u32 offset;
 417
 418        if (reg == NULL)
 419                return 0;
 420        /* That works for all keylargos but shall be fixed properly
 421         * some day... The problem is that it seems we can't rely
 422         * on the "reg" property of the GPIO nodes, they are either
 423         * relative to the base of KeyLargo or to the base of the
 424         * GPIO space, and the device-tree doesn't help.
 425         */
 426        offset = *reg;
 427        if (offset < KEYLARGO_GPIO_LEVELS0)
 428                offset += KEYLARGO_GPIO_LEVELS0;
 429        return offset;
 430}
 431
 432static int pmac_cpufreq_suspend(struct cpufreq_policy *policy)
 433{
 434        /* Ok, this could be made a bit smarter, but let's be robust for now. We
 435         * always force a speed change to high speed before sleep, to make sure
 436         * we have appropriate voltage and/or bus speed for the wakeup process,
 437         * and to make sure our loops_per_jiffies are "good enough", that is will
 438         * not cause too short delays if we sleep in low speed and wake in high
 439         * speed..
 440         */
 441        no_schedule = 1;
 442        sleep_freq = cur_freq;
 443        if (cur_freq == low_freq && !is_pmu_based)
 444                do_set_cpu_speed(CPUFREQ_HIGH, 0);
 445        return 0;
 446}
 447
 448static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
 449{
 450        /* If we resume, first check if we have a get() function */
 451        if (get_speed_proc)
 452                cur_freq = get_speed_proc();
 453        else
 454                cur_freq = 0;
 455
 456        /* We don't, hrm... we don't really know our speed here, best
 457         * is that we force a switch to whatever it was, which is
 458         * probably high speed due to our suspend() routine
 459         */
 460        do_set_cpu_speed(sleep_freq == low_freq ?
 461                         CPUFREQ_LOW : CPUFREQ_HIGH, 0);
 462
 463        ppc_proc_freq = cur_freq * 1000ul;
 464
 465        no_schedule = 0;
 466        return 0;
 467}
 468
 469static struct cpufreq_driver pmac_cpufreq_driver = {
 470        .verify         = pmac_cpufreq_verify,
 471        .target         = pmac_cpufreq_target,
 472        .get            = pmac_cpufreq_get_speed,
 473        .init           = pmac_cpufreq_cpu_init,
 474        .suspend        = pmac_cpufreq_suspend,
 475        .resume         = pmac_cpufreq_resume,
 476        .flags          = CPUFREQ_PM_NO_WARN,
 477        .attr           = pmac_cpu_freqs_attr,
 478        .name           = "powermac",
 479        .owner          = THIS_MODULE,
 480};
 481
 482
 483static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
 484{
 485        struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
 486                                                                "voltage-gpio");
 487        struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
 488                                                                "frequency-gpio");
 489        struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
 490                                                                     "slewing-done");
 491        const u32 *value;
 492
 493        /*
 494         * Check to see if it's GPIO driven or PMU only
 495         *
 496         * The way we extract the GPIO address is slightly hackish, but it
 497         * works well enough for now. We need to abstract the whole GPIO
 498         * stuff sooner or later anyway
 499         */
 500
 501        if (volt_gpio_np)
 502                voltage_gpio = read_gpio(volt_gpio_np);
 503        if (freq_gpio_np)
 504                frequency_gpio = read_gpio(freq_gpio_np);
 505        if (slew_done_gpio_np)
 506                slew_done_gpio = read_gpio(slew_done_gpio_np);
 507
 508        /* If we use the frequency GPIOs, calculate the min/max speeds based
 509         * on the bus frequencies
 510         */
 511        if (frequency_gpio && slew_done_gpio) {
 512                int lenp, rc;
 513                const u32 *freqs, *ratio;
 514
 515                freqs = of_get_property(cpunode, "bus-frequencies", &lenp);
 516                lenp /= sizeof(u32);
 517                if (freqs == NULL || lenp != 2) {
 518                        printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
 519                        return 1;
 520                }
 521                ratio = of_get_property(cpunode, "processor-to-bus-ratio*2",
 522                                                NULL);
 523                if (ratio == NULL) {
 524                        printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
 525                        return 1;
 526                }
 527
 528                /* Get the min/max bus frequencies */
 529                low_freq = min(freqs[0], freqs[1]);
 530                hi_freq = max(freqs[0], freqs[1]);
 531
 532                /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
 533                 * frequency, it claims it to be around 84Mhz on some models while
 534                 * it appears to be approx. 101Mhz on all. Let's hack around here...
 535                 * fortunately, we don't need to be too precise
 536                 */
 537                if (low_freq < 98000000)
 538                        low_freq = 101000000;
 539
 540                /* Convert those to CPU core clocks */
 541                low_freq = (low_freq * (*ratio)) / 2000;
 542                hi_freq = (hi_freq * (*ratio)) / 2000;
 543
 544                /* Now we get the frequencies, we read the GPIO to see what is out current
 545                 * speed
 546                 */
 547                rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
 548                cur_freq = (rc & 0x01) ? hi_freq : low_freq;
 549
 550                set_speed_proc = gpios_set_cpu_speed;
 551                return 1;
 552        }
 553
 554        /* If we use the PMU, look for the min & max frequencies in the
 555         * device-tree
 556         */
 557        value = of_get_property(cpunode, "min-clock-frequency", NULL);
 558        if (!value)
 559                return 1;
 560        low_freq = (*value) / 1000;
 561        /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
 562         * here */
 563        if (low_freq < 100000)
 564                low_freq *= 10;
 565
 566        value = of_get_property(cpunode, "max-clock-frequency", NULL);
 567        if (!value)
 568                return 1;
 569        hi_freq = (*value) / 1000;
 570        set_speed_proc = pmu_set_cpu_speed;
 571        is_pmu_based = 1;
 572
 573        return 0;
 574}
 575
 576static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
 577{
 578        struct device_node *volt_gpio_np;
 579
 580        if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
 581                return 1;
 582
 583        volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
 584        if (volt_gpio_np)
 585                voltage_gpio = read_gpio(volt_gpio_np);
 586        if (!voltage_gpio){
 587                printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
 588                return 1;
 589        }
 590
 591        /* OF only reports the high frequency */
 592        hi_freq = cur_freq;
 593        low_freq = cur_freq/2;
 594
 595        /* Read actual frequency from CPU */
 596        cur_freq = dfs_get_cpu_speed();
 597        set_speed_proc = dfs_set_cpu_speed;
 598        get_speed_proc = dfs_get_cpu_speed;
 599
 600        return 0;
 601}
 602
 603static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
 604{
 605        struct device_node *volt_gpio_np;
 606        u32 pvr;
 607        const u32 *value;
 608
 609        if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
 610                return 1;
 611
 612        hi_freq = cur_freq;
 613        value = of_get_property(cpunode, "reduced-clock-frequency", NULL);
 614        if (!value)
 615                return 1;
 616        low_freq = (*value) / 1000;
 617
 618        volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
 619        if (volt_gpio_np)
 620                voltage_gpio = read_gpio(volt_gpio_np);
 621
 622        pvr = mfspr(SPRN_PVR);
 623        has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
 624
 625        set_speed_proc = cpu_750fx_cpu_speed;
 626        get_speed_proc = cpu_750fx_get_cpu_speed;
 627        cur_freq = cpu_750fx_get_cpu_speed();
 628
 629        return 0;
 630}
 631
 632/* Currently, we support the following machines:
 633 *
 634 *  - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
 635 *  - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
 636 *  - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
 637 *  - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
 638 *  - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
 639 *  - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
 640 *  - Recent MacRISC3 laptops
 641 *  - All new machines with 7447A CPUs
 642 */
 643static int __init pmac_cpufreq_setup(void)
 644{
 645        struct device_node      *cpunode;
 646        const u32               *value;
 647
 648        if (strstr(cmd_line, "nocpufreq"))
 649                return 0;
 650
 651        /* Assume only one CPU */
 652        cpunode = of_find_node_by_type(NULL, "cpu");
 653        if (!cpunode)
 654                goto out;
 655
 656        /* Get current cpu clock freq */
 657        value = of_get_property(cpunode, "clock-frequency", NULL);
 658        if (!value)
 659                goto out;
 660        cur_freq = (*value) / 1000;
 661
 662        /*  Check for 7447A based MacRISC3 */
 663        if (of_machine_is_compatible("MacRISC3") &&
 664            of_get_property(cpunode, "dynamic-power-step", NULL) &&
 665            PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
 666                pmac_cpufreq_init_7447A(cpunode);
 667        /* Check for other MacRISC3 machines */
 668        } else if (of_machine_is_compatible("PowerBook3,4") ||
 669                   of_machine_is_compatible("PowerBook3,5") ||
 670                   of_machine_is_compatible("MacRISC3")) {
 671                pmac_cpufreq_init_MacRISC3(cpunode);
 672        /* Else check for iBook2 500/600 */
 673        } else if (of_machine_is_compatible("PowerBook4,1")) {
 674                hi_freq = cur_freq;
 675                low_freq = 400000;
 676                set_speed_proc = pmu_set_cpu_speed;
 677                is_pmu_based = 1;
 678        }
 679        /* Else check for TiPb 550 */
 680        else if (of_machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
 681                hi_freq = cur_freq;
 682                low_freq = 500000;
 683                set_speed_proc = pmu_set_cpu_speed;
 684                is_pmu_based = 1;
 685        }
 686        /* Else check for TiPb 400 & 500 */
 687        else if (of_machine_is_compatible("PowerBook3,2")) {
 688                /* We only know about the 400 MHz and the 500Mhz model
 689                 * they both have 300 MHz as low frequency
 690                 */
 691                if (cur_freq < 350000 || cur_freq > 550000)
 692                        goto out;
 693                hi_freq = cur_freq;
 694                low_freq = 300000;
 695                set_speed_proc = pmu_set_cpu_speed;
 696                is_pmu_based = 1;
 697        }
 698        /* Else check for 750FX */
 699        else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
 700                pmac_cpufreq_init_750FX(cpunode);
 701out:
 702        of_node_put(cpunode);
 703        if (set_speed_proc == NULL)
 704                return -ENODEV;
 705
 706        pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
 707        pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
 708        ppc_proc_freq = cur_freq * 1000ul;
 709
 710        printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
 711        printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
 712               low_freq/1000, hi_freq/1000, cur_freq/1000);
 713
 714        return cpufreq_register_driver(&pmac_cpufreq_driver);
 715}
 716
 717module_init(pmac_cpufreq_setup);
 718
 719