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