diff options
author | Paul Mackerras <paulus@samba.org> | 2006-01-15 17:30:44 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-15 17:30:44 +1100 |
commit | a7fdd90bc43e3e9cb08bc1b13650024d419b89e5 (patch) | |
tree | 5c99a41b9d157186668ed63c001f72a09965143b /arch/ppc/platforms | |
parent | e8625d463560198cff7cb3eb22886c47d728d501 (diff) |
[PATCH] ppc: Remove powermac support from ARCH=ppc
This makes it possible to build kernels for PReP and/or CHRP
with ARCH=ppc by removing the (non-building) powermac support.
It's now also possible to select PReP and CHRP independently.
Powermac users should now build with ARCH=powerpc instead of
ARCH=ppc. (This does mean that it is no longer possible to
build a 32-bit kernel for a G5.)
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/ppc/platforms')
-rw-r--r-- | arch/ppc/platforms/Makefile | 11 | ||||
-rw-r--r-- | arch/ppc/platforms/chrp_pci.c | 2 | ||||
-rw-r--r-- | arch/ppc/platforms/chrp_setup.c | 73 | ||||
-rw-r--r-- | arch/ppc/platforms/chrp_time.c | 64 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_backlight.c | 202 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_cache.S | 359 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_cpufreq.c | 735 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_feature.c | 3023 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_low_i2c.c | 511 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_nvram.c | 584 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_pci.c | 1124 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_pic.c | 693 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_pic.h | 11 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_setup.c | 745 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_sleep.S | 396 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_smp.c | 692 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_time.c | 291 |
17 files changed, 136 insertions, 9380 deletions
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile index 7c5cdabf6f3..51430e294b3 100644 --- a/arch/ppc/platforms/Makefile +++ b/arch/ppc/platforms/Makefile @@ -3,26 +3,18 @@ # # Extra CFLAGS so we don't have to do relative includes -CFLAGS_pmac_setup.o += -Iarch/$(ARCH)/mm +CFLAGS_chrp_setup.o += -Iarch/$(ARCH)/mm obj-$(CONFIG_APUS) += apus_setup.o ifeq ($(CONFIG_APUS),y) obj-$(CONFIG_PCI) += apus_pci.o endif -obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \ - pmac_feature.o pmac_pci.o pmac_sleep.o \ - pmac_low_i2c.o pmac_cache.o obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \ chrp_pegasos_eth.o ifeq ($(CONFIG_PPC_CHRP),y) obj-$(CONFIG_NVRAM) += chrp_nvram.o endif obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o -ifeq ($(CONFIG_PPC_PMAC),y) -obj-$(CONFIG_NVRAM) += pmac_nvram.o -obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o -endif -obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o obj-$(CONFIG_PREP_RESIDUAL) += residual.o obj-$(CONFIG_PQ2ADS) += pq2ads.o obj-$(CONFIG_TQM8260) += tqm8260_setup.o @@ -47,6 +39,5 @@ obj-$(CONFIG_LITE5200) += lite5200.o obj-$(CONFIG_EV64360) += ev64360.o ifeq ($(CONFIG_SMP),y) -obj-$(CONFIG_PPC_PMAC) += pmac_smp.o obj-$(CONFIG_PPC_CHRP) += chrp_smp.o endif diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c index bd047aac01b..c7fe6182bb7 100644 --- a/arch/ppc/platforms/chrp_pci.c +++ b/arch/ppc/platforms/chrp_pci.c @@ -275,7 +275,7 @@ chrp_find_bridges(void) setup_python(hose, dev); } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { - setup_grackle(hose); + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); } else if (is_longtrail) { void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); hose->ops = &gg2_pci_ops; diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index 056ac2a7b5c..48996b78737 100644 --- a/arch/ppc/platforms/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c @@ -53,6 +53,7 @@ #include <asm/i8259.h> #include <asm/open_pic.h> #include <asm/xmon.h> +#include "mem_pieces.h" unsigned long chrp_get_rtc_time(void); int chrp_set_rtc_time(unsigned long nowtime); @@ -65,7 +66,6 @@ void rtas_display_progress(char *, unsigned short); void rtas_indicator_progress(char *, unsigned short); void btext_progress(char *, unsigned short); -extern unsigned long pmac_find_end_of_memory(void); extern int of_show_percpuinfo(struct seq_file *, int); int _chrp_type; @@ -467,6 +467,75 @@ chrp_init2(void) ppc_md.progress(" Have fun! ", 0x7777); } +static struct device_node *memory_node; + +static int __init get_mem_prop(char *name, struct mem_pieces *mp) +{ + struct reg_property *rp; + int i, s; + unsigned int *ip; + int nac = prom_n_addr_cells(memory_node); + int nsc = prom_n_size_cells(memory_node); + + ip = (unsigned int *) get_property(memory_node, name, &s); + if (ip == NULL) { + printk(KERN_ERR "error: couldn't get %s property on /memory\n", + name); + return 0; + } + s /= (nsc + nac) * 4; + rp = mp->regions; + for (i = 0; i < s; ++i, ip += nac+nsc) { + if (nac >= 2 && ip[nac-2] != 0) + continue; + rp->address = ip[nac-1]; + if (nsc >= 2 && ip[nac+nsc-2] != 0) + rp->size = ~0U; + else + rp->size = ip[nac+nsc-1]; + ++rp; + } + mp->n_regions = rp - mp->regions; + + /* Make sure the pieces are sorted. */ + mem_pieces_sort(mp); + mem_pieces_coalesce(mp); + return 1; +} + +static unsigned long __init chrp_find_end_of_memory(void) +{ + unsigned long a, total; + struct mem_pieces phys_mem; + + /* + * Find out where physical memory is, and check that it + * starts at 0 and is contiguous. It seems that RAM is + * always physically contiguous on Power Macintoshes. + * + * Supporting discontiguous physical memory isn't hard, + * it just makes the virtual <-> physical mapping functions + * more complicated (or else you end up wasting space + * in mem_map). + */ + memory_node = find_devices("memory"); + if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) + || phys_mem.n_regions == 0) + panic("No RAM??"); + a = phys_mem.regions[0].address; + if (a != 0) + panic("RAM doesn't start at physical address 0"); + total = phys_mem.regions[0].size; + + if (phys_mem.n_regions > 1) { + printk("RAM starting at 0x%x is not contiguous\n", + phys_mem.regions[1].address); + printk("Using RAM from 0 to 0x%lx\n", total-1); + } + + return total; +} + void __init chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) @@ -525,7 +594,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_rtc_time = chrp_get_rtc_time; ppc_md.calibrate_decr = chrp_calibrate_decr; - ppc_md.find_end_of_memory = pmac_find_end_of_memory; + ppc_md.find_end_of_memory = chrp_find_end_of_memory; if (rtas_data) { struct device_node *rtas; diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c index 29d074c305f..57753a55b58 100644 --- a/arch/ppc/platforms/chrp_time.c +++ b/arch/ppc/platforms/chrp_time.c @@ -163,13 +163,75 @@ unsigned long chrp_get_rtc_time(void) return mktime(year, mon, day, hour, min, sec); } +/* + * Calibrate the decrementer frequency with the VIA timer 1. + */ +#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ + +/* VIA registers */ +#define RS 0x200 /* skip between registers */ +#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ +#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ +#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ +#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ +#define ACR (11*RS) /* Auxiliary control register */ +#define IFR (13*RS) /* Interrupt flag register */ + +/* Bits in ACR */ +#define T1MODE 0xc0 /* Timer 1 mode */ +#define T1MODE_CONT 0x40 /* continuous interrupts */ + +/* Bits in IFR and IER */ +#define T1_INT 0x40 /* Timer 1 interrupt */ + +static int __init chrp_via_calibrate_decr(void) +{ + struct device_node *vias; + volatile unsigned char __iomem *via; + int count = VIA_TIMER_FREQ_6 / 100; + unsigned int dstart, dend; + + vias = find_devices("via-cuda"); + if (vias == 0) + vias = find_devices("via"); + if (vias == 0 || vias->n_addrs == 0) + return 0; + via = ioremap(vias->addrs[0].address, vias->addrs[0].size); + + /* set timer 1 for continuous interrupts */ + out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); + /* set the counter to a small value */ + out_8(&via[T1CH], 2); + /* set the latch to `count' */ + out_8(&via[T1LL], count); + out_8(&via[T1LH], count >> 8); + /* wait until it hits 0 */ + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dstart = get_dec(); + /* clear the interrupt & wait until it hits 0 again */ + in_8(&via[T1CL]); + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dend = get_dec(); + + tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); + tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); + + printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", + tb_ticks_per_jiffy, dstart - dend); + + iounmap(via); + + return 1; +} void __init chrp_calibrate_decr(void) { struct device_node *cpu; unsigned int freq, *fp; - if (via_calibrate_decr()) + if (chrp_via_calibrate_decr()) return; /* diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c deleted file mode 100644 index 8be2f7d071f..00000000000 --- a/arch/ppc/platforms/pmac_backlight.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Miscellaneous procedures for dealing with the PowerMac hardware. - * Contains support for the backlight. - * - * Copyright (C) 2000 Benjamin Herrenschmidt - * - */ - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/stddef.h> -#include <linux/reboot.h> -#include <linux/nvram.h> -#include <linux/console.h> -#include <asm/sections.h> -#include <asm/ptrace.h> -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/prom.h> -#include <asm/machdep.h> -#include <asm/nvram.h> -#include <asm/backlight.h> - -#include <linux/adb.h> -#include <linux/pmu.h> - -static struct backlight_controller *backlighter; -static void* backlighter_data; -static int backlight_autosave; -static int backlight_level = BACKLIGHT_MAX; -static int backlight_enabled = 1; -static int backlight_req_level = -1; -static int backlight_req_enable = -1; - -static void backlight_callback(void *); -static DECLARE_WORK(backlight_work, backlight_callback, NULL); - -void register_backlight_controller(struct backlight_controller *ctrler, - void *data, char *type) -{ - struct device_node* bk_node; - char *prop; - int valid = 0; - - /* There's already a matching controller, bail out */ - if (backlighter != NULL) - return; - - bk_node = find_devices("backlight"); - -#ifdef CONFIG_ADB_PMU - /* Special case for the old PowerBook since I can't test on it */ - backlight_autosave = machine_is_compatible("AAPL,3400/2400") - || machine_is_compatible("AAPL,3500"); - if ((backlight_autosave - || machine_is_compatible("AAPL,PowerBook1998") - || machine_is_compatible("PowerBook1,1")) - && !strcmp(type, "pmu")) - valid = 1; -#endif - if (bk_node) { - prop = get_property(bk_node, "backlight-control", NULL); - if (prop && !strncmp(prop, type, strlen(type))) - valid = 1; - } - if (!valid) - return; - backlighter = ctrler; - backlighter_data = data; - - if (bk_node && !backlight_autosave) - prop = get_property(bk_node, "bklt", NULL); - else - prop = NULL; - if (prop) { - backlight_level = ((*prop)+1) >> 1; - if (backlight_level > BACKLIGHT_MAX) - backlight_level = BACKLIGHT_MAX; - } - -#ifdef CONFIG_ADB_PMU - if (backlight_autosave) { - struct adb_request req; - pmu_request(&req, NULL, 2, 0xd9, 0); - while (!req.complete) - pmu_poll(); - backlight_level = req.reply[0] >> 4; - } -#endif - acquire_console_sem(); - if (!backlighter->set_enable(1, backlight_level, data)) - backlight_enabled = 1; - release_console_sem(); - - printk(KERN_INFO "Registered \"%s\" backlight controller," - "level: %d/15\n", type, backlight_level); -} -EXPORT_SYMBOL(register_backlight_controller); - -void unregister_backlight_controller(struct backlight_controller - *ctrler, void *data) -{ - /* We keep the current backlight level (for now) */ - if (ctrler == backlighter && data == backlighter_data) - backlighter = NULL; -} -EXPORT_SYMBOL(unregister_backlight_controller); - -static int __set_backlight_enable(int enable) -{ - int rc; - - if (!backlighter) - return -ENODEV; - acquire_console_sem(); - rc = backlighter->set_enable(enable, backlight_level, - backlighter_data); - if (!rc) - backlight_enabled = enable; - release_console_sem(); - return rc; -} -int set_backlight_enable(int enable) -{ - if (!backlighter) - return -ENODEV; - backlight_req_enable = enable; - schedule_work(&backlight_work); - return 0; -} - -EXPORT_SYMBOL(set_backlight_enable); - -int get_backlight_enable(void) -{ - if (!backlighter) - return -ENODEV; - return backlight_enabled; -} -EXPORT_SYMBOL(get_backlight_enable); - -static int __set_backlight_level(int level) -{ - int rc = 0; - - if (!backlighter) - return -ENODEV; - if (level < BACKLIGHT_MIN) - level = BACKLIGHT_OFF; - if (level > BACKLIGHT_MAX) - level = BACKLIGHT_MAX; - acquire_console_sem(); - if (backlight_enabled) - rc = backlighter->set_level(level, backlighter_data); - if (!rc) - backlight_level = level; - release_console_sem(); - if (!rc && !backlight_autosave) { - level <<=1; - if (level & 0x10) - level |= 0x01; - // -- todo: save to property "bklt" - } - return rc; -} -int set_backlight_level(int level) -{ - if (!backlighter) - return -ENODEV; - backlight_req_level = level; - schedule_work(&backlight_work); - return 0; -} - -EXPORT_SYMBOL(set_backlight_level); - -int get_backlight_level(void) -{ - if (!backlighter) - return -ENODEV; - return backlight_level; -} -EXPORT_SYMBOL(get_backlight_level); - -static void backlight_callback(void *dummy) -{ - int level, enable; - - do { - level = backlight_req_level; - enable = backlight_req_enable; - mb(); - - if (level >= 0) - __set_backlight_level(level); - if (enable >= 0) - __set_backlight_enable(enable); - } while(cmpxchg(&backlight_req_level, level, -1) != level || - cmpxchg(&backlight_req_enable, enable, -1) != enable); -} diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S deleted file mode 100644 index fb977de6b70..00000000000 --- a/arch/ppc/platforms/pmac_cache.S +++ /dev/null @@ -1,359 +0,0 @@ -/* - * This file contains low-level cache management functions - * used for sleep and CPU speed changes on Apple machines. - * (In fact the only thing that is Apple-specific is that we assume - * that we can read from ROM at physical address 0xfff00000.) - * - * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and - * Benjamin Herrenschmidt (benh@kernel.crashing.org) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include <linux/config.h> -#include <asm/processor.h> -#include <asm/ppc_asm.h> -#include <asm/cputable.h> - -/* - * Flush and disable all data caches (dL1, L2, L3). This is used - * when going to sleep, when doing a PMU based cpufreq transition, - * or when "offlining" a CPU on SMP machines. This code is over - * paranoid, but I've had enough issues with various CPU revs and - * bugs that I decided it was worth beeing over cautious - */ - -_GLOBAL(flush_disable_caches) -#ifndef CONFIG_6xx - blr -#else -BEGIN_FTR_SECTION - b flush_disable_745x -END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) -BEGIN_FTR_SECTION - b flush_disable_75x -END_FTR_SECTION_IFSET(CPU_FTR_L2CR) - b __flush_disable_L1 - -/* This is the code for G3 and 74[01]0 */ -flush_disable_75x: - mflr r10 - - /* Turn off EE and DR in MSR */ - mfmsr r11 - rlwinm r0,r11,0,~MSR_EE - rlwinm r0,r0,0,~MSR_DR - sync - mtmsr r0 - isync - - /* Stop DST streams */ -BEGIN_FTR_SECTION - DSSALL - sync -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - - /* Stop DPM */ - mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */ - rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */ - sync - mtspr SPRN_HID0,r4 /* Disable DPM */ - sync - - /* Disp-flush L1. We have a weird problem here that I never - * totally figured out. On 750FX, using the ROM for the flush - * results in a non-working flush. We use that workaround for - * now until I finally understand what's going on. --BenH - */ - - /* ROM base by default */ - lis r4,0xfff0 - mfpvr r3 - srwi r3,r3,16 - cmplwi cr0,r3,0x7000 - bne+ 1f - /* RAM base on 750FX */ - li r4,0 -1: li r4,0x4000 - mtctr r4 -1: lwz r0,0(r4) - addi r4,r4,32 - bdnz 1b - sync - isync - - /* Disable / invalidate / enable L1 data */ - mfspr r3,SPRN_HID0 - rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE) - mtspr SPRN_HID0,r3 - sync - isync - ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI) - sync - isync - mtspr SPRN_HID0,r3 - xori r3,r3,(HID0_DCI|HID0_ICFI) - mtspr SPRN_HID0,r3 - sync - - /* Get the current enable bit of the L2CR into r4 */ - mfspr r5,SPRN_L2CR - /* Set to data-only (pre-745x bit) */ - oris r3,r5,L2CR_L2DO@h - b 2f - /* When disabling L2, code must be in L1 */ - .balign 32 -1: mtspr SPRN_L2CR,r3 -3: sync - isync - b 1f -2: b 3f -3: sync - isync - b 1b -1: /* disp-flush L2. The interesting thing here is that the L2 can be - * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory - * but that is probbaly fine. We disp-flush over 4Mb to be safe - */ - lis r4,2 - mtctr r4 - lis r4,0xfff0 -1: lwz r0,0(r4) - addi r4,r4,32 - bdnz 1b - sync - isync - lis r4,2 - mtctr r4 - lis r4,0xfff0 -1: dcbf 0,r4 - addi r4,r4,32 - bdnz 1b - sync - isync - - /* now disable L2 */ - rlwinm r5,r5,0,~L2CR_L2E - b 2f - /* When disabling L2, code must be in L1 */ - .balign 32 -1: mtspr SPRN_L2CR,r5 -3: sync - isync - b 1f -2: b 3f -3: sync - isync - b 1b -1: sync - isync - /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */ - oris r4,r5,L2CR_L2I@h - mtspr SPRN_L2CR,r4 - sync - isync - - /* Wait for the invalidation to complete */ -1: mfspr r3,SPRN_L2CR - rlwinm. r0,r3,0,31,31 - bne 1b - - /* Clear L2I */ - xoris r4,r4,L2CR_L2I@h - sync - mtspr SPRN_L2CR,r4 - sync - - /* now disable the L1 data cache */ - mfspr r0,SPRN_HID0 - rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE) - mtspr SPRN_HID0,r0 - sync - isync - - /* Restore HID0[DPM] to whatever it was before */ - sync - mfspr r0,SPRN_HID0 - rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */ - mtspr SPRN_HID0,r0 - sync - - /* restore DR and EE */ - sync - mtmsr r11 - isync - - mtlr r10 - blr - -/* This code is for 745x processors */ -flush_disable_745x: - /* Turn off EE and DR in MSR */ - mfmsr r11 - rlwinm r0,r11,0,~MSR_EE - rlwinm r0,r0,0,~MSR_DR - sync - mtmsr r0 - isync - - /* Stop prefetch streams */ - DSSALL - sync - - /* Disable L2 prefetching */ - mfspr r0,SPRN_MSSCR0 - rlwinm r0,r0,0,0,29 - mtspr SPRN_MSSCR0,r0 - sync - isync - lis r4,0 - dcbf 0,r4 - dcbf 0,r4 - dcbf 0,r4 - dcbf 0,r4 - dcbf 0,r4 - dcbf 0,r4 - dcbf 0,r4 - dcbf 0,r4 - - /* Due to a bug with the HW flush on some CPU revs, we occasionally - * experience data corruption. I'm adding a displacement flush along - * with a dcbf loop over a few Mb to "help". The problem isn't totally - * fixed by this in theory, but at least, in practice, I couldn't reproduce - * it even with a big hammer... - */ - - lis r4,0x0002 - mtctr r4 - li r4,0 -1: - lwz r0,0(r4) - addi r4,r4,32 /* Go to start of next cache line */ - bdnz 1b - isync - - /* Now, flush the first 4MB of memory */ - lis r4,0x0002 - mtctr r4 - li r4,0 - sync -1: - dcbf 0,r4 - addi r4,r4,32 /* Go to start of next cache line */ - bdnz 1b - - /* Flush and disable the L1 data cache */ - mfspr r6,SPRN_LDSTCR - lis r3,0xfff0 /* read from ROM for displacement flush */ - li r4,0xfe /* start with only way 0 unlocked */ - li r5,128 /* 128 lines in each way */ -1: mtctr r5 - rlwimi r6,r4,0,24,31 - mtspr SPRN_LDSTCR,r6 - sync - isync -2: lwz r0,0(r3) /* touch each cache line */ - addi r3,r3,32 - bdnz 2b - rlwinm r4,r4,1,24,30 /* move on to the next way */ - ori r4,r4,1 - cmpwi r4,0xff /* all done? */ - bne 1b - /* now unlock the L1 data cache */ - li r4,0 - rlwimi r6,r4,0,24,31 - sync - mtspr SPRN_LDSTCR,r6 - sync - isync - - /* Flush the L2 cache using the hardware assist */ - mfspr r3,SPRN_L2CR - cmpwi r3,0 /* check if it is enabled first */ - bge 4f - oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h - b 2f - /* When disabling/locking L2, code must be in L1 */ - .balign 32 -1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */ -3: sync - isync - b 1f -2: b 3f -3: sync - isync - b 1b -1: sync - isync - ori r0,r3,L2CR_L2HWF_745x - sync - mtspr SPRN_L2CR,r0 /* set the hardware flush bit */ -3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */ - andi. r0,r0,L2CR_L2HWF_745x - bne 3b - sync - rlwinm r3,r3,0,~L2CR_L2E - b 2f - /* When disabling L2, code must be in L1 */ - .balign 32 -1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */ -3: sync - isync - b 1f -2: b 3f -3: sync - isync - b 1b -1: sync - isync - oris r4,r3,L2CR_L2I@h - mtspr SPRN_L2CR,r4 - sync - isync -1: mfspr r4,SPRN_L2CR - andis. r0,r4,L2CR_L2I@h - bne 1b - sync - -BEGIN_FTR_SECTION - /* Flush the L3 cache using the hardware assist */ -4: mfspr r3,SPRN_L3CR - cmpwi r3,0 /* check if it is enabled */ - bge 6f - oris r0,r3,L3CR_L3IO@h - ori r0,r0,L3CR_L3DO - sync - mtspr SPRN_L3CR,r0 /* lock the L3 cache */ - sync - isync - ori r0,r0,L3CR_L3HWF - sync - mtspr SPRN_L3CR,r0 /* set the hardware flush bit */ -5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */ - andi. r0,r0,L3CR_L3HWF - bne 5b - rlwinm r3,r3,0,~L3CR_L3E - sync - mtspr SPRN_L3CR,r3 /* disable the L3 cache */ - sync - ori r4,r3,L3CR_L3I - mtspr SPRN_L3CR,r4 -1: mfspr r4,SPRN_L3CR - andi. r0,r4,L3CR_L3I - bne 1b - sync -END_FTR_SECTION_IFSET(CPU_FTR_L3CR) - -6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */ - rlwinm r0,r0,0,~HID0_DCE - mtspr SPRN_HID0,r0 - sync - isync - mtmsr r11 /* restore DR and EE */ - isync - blr -#endif /* CONFIG_6xx */ diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c deleted file mode 100644 index fba7e4d7c0b..00000000000 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * arch/ppc/platforms/pmac_cpufreq.c - * - * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> - * Copyright (C) 2004 John Steele Scott <toojays@toojays.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * TODO: Need a big cleanup here. Basically, we need to have different - * cpufreq_driver structures for the different type of HW instead of the - * current mess. We also need to better deal with the detection of the - * type of machine. - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/sched.h> -#include <linux/adb.h> -#include <linux/pmu.h> -#include <linux/slab.h> -#include <linux/cpufreq.h> -#include <linux/init.h> -#include <linux/sysdev.h> -#include <linux/i2c.h> -#include <linux/hardirq.h> -#include <asm/prom.h> -#include <asm/machdep.h> -#include <asm/irq.h> -#include <asm/pmac_feature.h> -#include <asm/mmu_context.h> -#include <asm/sections.h> -#include <asm/cputable.h> -#include <asm/time.h> -#include <asm/system.h> -#include <asm/open_pic.h> -#include <asm/keylargo.h> - -/* WARNING !!! This will cause calibrate_delay() to be called, - * but this is an __init function ! So you MUST go edit - * init/main.c to make it non-init before enabling DEBUG_FREQ - */ -#undef DEBUG_FREQ - -/* - * There is a problem with the core cpufreq code on SMP kernels, - * it won't recalculate the Bogomips properly - */ -#ifdef CONFIG_SMP -#warning "WARNING, CPUFREQ not recommended on SMP kernels" -#endif - -extern void low_choose_7447a_dfs(int dfs); -extern void low_choose_750fx_pll(int pll); -extern void low_sleep_handler(void); - -/* - * Currently, PowerMac cpufreq supports only high & low frequencies - * that are set by the firmware - */ -static unsigned int low_freq; -static unsigned int hi_freq; -static unsigned int cur_freq; -static unsigned int sleep_freq; - -/* - * Different models uses different mecanisms to switch the frequency - */ -static int (*set_speed_proc)(int low_speed); -static unsigned int (*get_speed_proc)(void); - -/* - * Some definitions used by the various speedprocs - */ -static u32 voltage_gpio; -static u32 frequency_gpio; -static u32 slew_done_gpio; -static int no_schedule; -static int has_cpu_l2lve; -static int is_pmu_based; - -/* There are only two frequency states for each processor. Values - * are in kHz for the time being. - */ -#define CPUFREQ_HIGH 0 -#define CPUFREQ_LOW 1 - -static struct cpufreq_frequency_table pmac_cpu_freqs[] = { - {CPUFREQ_HIGH, 0}, - {CPUFREQ_LOW, 0}, - {0, CPUFREQ_TABLE_END}, -}; - -static struct freq_attr* pmac_cpu_freqs_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static inline void local_delay(unsigned long ms) -{ - if (no_schedule) - mdelay(ms); - else - msleep(ms); -} - -static inline void wakeup_decrementer(void) -{ - set_dec(tb_ticks_per_jiffy); - /* No currently-supported powerbook has a 601, - * so use get_tbl, not native - */ - last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); -} - -#ifdef DEBUG_FREQ -static inline void debug_calc_bogomips(void) -{ - /* This will cause a recalc of bogomips and display the - * result. We backup/restore the value to avoid affecting the - * core cpufreq framework's own calculation. - */ - extern void calibrate_delay(void); - - unsigned long save_lpj = loops_per_jiffy; - calibrate_delay(); - loops_per_jiffy = save_lpj; -} -#endif /* DEBUG_FREQ */ - -/* Switch CPU speed under 750FX CPU control - */ -static int cpu_750fx_cpu_speed(int low_speed) -{ - u32 hid2; - - if (low_speed == 0) { - /* ramping up, set voltage first */ - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); - /* Make sure we sleep for at least 1ms */ - local_delay(10); - - /* tweak L2 for high voltage */ - if (has_cpu_l2lve) { - hid2 = mfspr(SPRN_HID2); - hid2 &= ~0x2000; - mtspr(SPRN_HID2, hid2); - } - } -#ifdef CONFIG_6xx - low_choose_750fx_pll(low_speed); -#endif - if (low_speed == 1) { - /* tweak L2 for low voltage */ - if (has_cpu_l2lve) { - hid2 = mfspr(SPRN_HID2); - hid2 |= 0x2000; - mtspr(SPRN_HID2, hid2); - } - - /* ramping down, set voltage last */ - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); - local_delay(10); - } - - return 0; -} - -static unsigned int cpu_750fx_get_cpu_speed(void) -{ - if (mfspr(SPRN_HID1) & HID1_PS) - return low_freq; - else - return hi_freq; -} - -/* Switch CPU speed using DFS */ -static int dfs_set_cpu_speed(int low_speed) -{ - if (low_speed == 0) { - /* ramping up, set voltage first */ - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); - /* Make sure we sleep for at least 1ms */ - local_delay(1); - } - - /* set frequency */ -#ifdef CONFIG_6xx - low_choose_7447a_dfs(low_speed); -#endif - udelay(100); - - if (low_speed == 1) { - /* ramping down, set voltage last */ - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); - local_delay(1); - } - - return 0; -} - -static unsigned int dfs_get_cpu_speed(void) -{ - if (mfspr(SPRN_HID1) & HID1_DFS) - return low_freq; - else - return hi_freq; -} - - -/* Switch CPU speed using slewing GPIOs - */ -static int gpios_set_cpu_speed(int low_speed) -{ - int gpio, timeout = 0; - - /* If ramping up, set voltage first */ - if (low_speed == 0) { - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); - /* Delay is way too big but it's ok, we schedule */ - local_delay(10); - } - - /* Set frequency */ - gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); - if (low_speed == ((gpio & 0x01) == 0)) - goto skip; - - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, - low_speed ? 0x04 : 0x05); - udelay(200); - do { - if (++timeout > 100) - break; - local_delay(1); - gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0); - } while((gpio & 0x02) == 0); - skip: - /* If rampin |