Commit a7fdd90b authored by Paul Mackerras's avatar Paul Mackerras

[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: default avatarPaul Mackerras <paulus@samba.org>
parent e8625d46
......@@ -58,11 +58,11 @@ config 6xx
help
There are four types of PowerPC chips supported. The more common
types (601, 603, 604, 740, 750, 7400), the Motorola embedded
versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM embedded
versions (403 and 405) and the high end 64 bit Power processors
(POWER 3, POWER4, and IBM 970 also known as G5)
versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM
embedded versions (403 and 405) and the POWER3 processor.
(For support for more recent 64-bit processors, set ARCH=powerpc.)
Unless you are building a kernel for one of the embedded processor
systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
systems or a POWER3-based IBM RS/6000, choose 6xx.
Note that the kernel runs in 32-bit mode even on 64-bit chips.
Also note that because the 52xx, 82xx, & 83xx family has a 603e core,
specific support for that chipset is asked later on.
......@@ -77,10 +77,6 @@ config POWER3
select PPC_FPU
bool "POWER3"
config POWER4
select PPC_FPU
bool "POWER4 and 970 (G5)"
config 8xx
bool "8xx"
......@@ -123,7 +119,7 @@ config PHYS_64BIT
config ALTIVEC
bool "AltiVec Support"
depends on 6xx || POWER4
depends on 6xx
depends on !8260 && !83xx
---help---
This option enables kernel support for the Altivec extensions to the
......@@ -235,18 +231,9 @@ config KEXEC
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_PMAC
bool "Support for Apple PowerBooks"
depends on CPU_FREQ && ADB_PMU
select CPU_FREQ_TABLE
help
This adds support for frequency switching on Apple PowerBooks,
this currently includes some models of iBook & Titanium
PowerBook.
config PPC601_SYNC_FIX
bool "Workarounds for PPC601 bugs"
depends on 6xx && (PPC_PREP || PPC_PMAC)
depends on 6xx && PPC_PREP
help
Some versions of the PPC601 (the first PowerPC chip) have bugs which
mean that extra synchronization instructions are required near
......@@ -258,26 +245,17 @@ config PPC601_SYNC_FIX
If in doubt, say Y here.
config HOTPLUG_CPU
bool "Support for enabling/disabling CPUs"
depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PMAC
---help---
Say Y here to be able to disable and re-enable individual
CPUs at runtime on SMP machines.
Say N if you are unsure.
source arch/ppc/platforms/4xx/Kconfig
source arch/ppc/platforms/85xx/Kconfig
config PPC64BRIDGE
bool
depends on POWER3 || POWER4
depends on POWER3
default y
config PPC_STD_MMU
bool
depends on 6xx || POWER3 || POWER4
depends on 6xx || POWER3
default y
config NOT_COHERENT_CACHE
......@@ -505,7 +483,7 @@ endchoice
choice
prompt "Machine Type"
depends on 6xx || POWER3 || POWER4
depends on 6xx || POWER3
default PPC_MULTIPLATFORM
---help---
Linux currently supports several different kinds of PowerPC-based
......@@ -516,11 +494,15 @@ choice
Platform) machines (including all of the recent IBM RS/6000 and
pSeries machines), and several embedded PowerPC systems containing
4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the
default option is to build a kernel which works on the first three.
default option is to build a kernel which works on PReP and CHRP.
Select CHRP/PowerMac/PReP if configuring for an IBM RS/6000 or
pSeries machine, a Power Macintosh (including iMacs, iBooks and
Powerbooks), or a PReP machine.
Note that support for Apple machines is now only available with
ARCH=powerpc, and has been removed from this menu. If you wish
to build a kernel for an Apple machine, exit this configuration
process and re-run it with ARCH=powerpc.
Select CHRP/PReP if configuring for an IBM RS/6000 or
pSeries machine, or a PReP machine.
Select Gemini if configuring for a Synergy Microsystems' Gemini
series Single Board Computer. More information is available at:
......@@ -530,7 +512,7 @@ choice
available at: <http://linux-apus.sourceforge.net/>.
config PPC_MULTIPLATFORM
bool "CHRP/PowerMac/PReP"
bool "CHRP/PReP"
config APUS
bool "Amiga-APUS"
......@@ -768,25 +750,14 @@ config CPM2
on it (826x, 827x, 8560).
config PPC_CHRP
bool
bool "Support for CHRP (Common Hardware Reference Platform) machines"
depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI
default y
config PPC_PMAC
bool
depends on PPC_MULTIPLATFORM
select PPC_INDIRECT_PCI
default y
config PPC_PMAC64
bool
depends on PPC_PMAC && POWER4
default y
config PPC_PREP
bool
bool "Support for PReP (PowerPC Reference Platform) machines"
depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI
......@@ -794,7 +765,7 @@ config PPC_PREP
config PPC_OF
bool
depends on PPC_PMAC || PPC_CHRP
depends on PPC_CHRP
default y
config PPC_GEN550
......@@ -1166,7 +1137,7 @@ config ISA
config GENERIC_ISA_DMA
bool
depends on POWER3 || POWER4 || 6xx && !CPM2
depends on POWER3 || 6xx && !CPM2
default y
config PPC_I8259
......
......@@ -18,7 +18,7 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
bootdir-y := simple
bootdir-$(CONFIG_PPC_OF) += openfirmware
subdir-y := lib common images
subdir-$(CONFIG_PPC_OF) += of1275
subdir-$(CONFIG_PPC_MULTIPLATFORM) += of1275
# for cleaning
subdir- += simple openfirmware
......
......@@ -21,26 +21,16 @@ bootlib := $(boot)/lib
of1275 := $(boot)/of1275
images := $(boot)/images
OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
COFF_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \
-Bstatic
CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000
NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000
COMMONOBJS := start.o misc.o common.o
COFFOBJS := coffcrt0.o $(COMMONOBJS) coffmain.o
CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o
NEWWORLDOBJS := crt0.o $(COMMONOBJS) newworldmain.o
targets := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o
COFFOBJS := $(addprefix $(obj)/, $(COFFOBJS))
targets := $(CHRPOBJS) dummy.o
CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS))
NEWWORLDOBJS := $(addprefix $(obj)/, $(NEWWORLDOBJS))
LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
HACKCOFF := $(utils)/hack-coff
ifdef CONFIG_SMP
END := .smp
endif
......@@ -72,56 +62,11 @@ targets += image.initrd.o
$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE
$(call if_changed,genimage-initrd)
# Create the note section for New-World PowerMacs.
quiet_cmd_mknote = MKNOTE $@
cmd_mknote = $(utils)/mknote > $@
targets += note
$(obj)/note: $(utils)/mknote FORCE
$(call if_changed,mknote)
$(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF
targets += coffcrt0.o crt0.o
$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
targets += crt0.o
$(obj)/crt0.o: $(common)/crt0.S FORCE
$(call if_changed_dep,as_o_S)
quiet_cmd_gencoffb = COFF $@
cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \
$(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
targets += coffboot
$(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE
$(call if_changed,gencoffb)
targets += coffboot.initrd
$(obj)/coffboot.initrd: $(obj)/image.initrd.o $(COFFOBJS) $(LIBS) \
$(srctree)/$(boot)/ld.script FORCE
$(call if_changed,gencoffb)
quiet_cmd_gen-coff = COFF $@
cmd_gen-coff = $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ && \
$(HACKCOFF) $@ && \
ln -sf $(notdir $@) $(images)/zImage$(initrd).pmac
$(images)/vmlinux.coff: $(obj)/coffboot
$(call cmd,gen-coff)
$(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd
$(call cmd,gen-coff)
quiet_cmd_gen-elf-pmac = ELF $@
cmd_gen-elf-pmac = $(LD) $(NEWWORLD_LD_ARGS) -o $@ \
$(NEWWORLDOBJS) $(LIBS) $< && \
$(OBJCOPY) $@ $@ --add-section=.note=$(obj)/note \
-R .comment $(del-ramdisk-sec)
$(images)/vmlinux.elf-pmac: $(obj)/image.o $(NEWWORLDOBJS) $(LIBS) \
$(obj)/note $(srctree)/$(boot)/ld.script
$(call cmd,gen-elf-pmac)
$(images)/vmlinux.initrd.elf-pmac: $(obj)/image.initrd.o $(NEWWORLDOBJS) \
$(LIBS) $(obj)/note \
$(srctree)/$(boot)/ld.script
$(call cmd,gen-elf-pmac)
quiet_cmd_gen-chrp = CHRP $@
cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \
$(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
......@@ -139,46 +84,23 @@ $(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \
%-rs6k: %
$(call cmd,addnote)
quiet_cmd_gen-miboot = GEN $@
cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_ARGS) \
--add-section=$1=$(word 2, $^) $< $@
$(images)/miboot.image: $(obj)/dummy.o $(images)/vmlinux.gz
$(call cmd,gen-miboot,image)
$(images)/miboot.initrd.image: $(images)/miboot.image $(images)/ramdisk.image.gz
$(call cmd,gen-miboot,initrd)
# The targets used on the make command-line
.PHONY: zImage zImage.initrd
zImage: $(images)/vmlinux.coff \
$(images)/vmlinux.elf-pmac \
$(images)/zImage.chrp \
$(images)/zImage.chrp-rs6k \
$(images)/miboot.image
zImage: $(images)/zImage.chrp \
$(images)/zImage.chrp-rs6k
@echo ' kernel: $@ is ready ($<)'
zImage.initrd: $(images)/vmlinux.initrd.coff \
$(images)/vmlinux.initrd.elf-pmac \
$(images)/zImage.initrd.chrp \
$(images)/zImage.initrd.chrp-rs6k \
$(images)/miboot.initrd.image
zImage.initrd: $(images)/zImage.initrd.chrp \
$(images)/zImage.initrd.chrp-rs6k
@echo ' kernel: $@ is ready ($<)'
TFTPIMAGE := /tftpboot/zImage
.PHONY: znetboot znetboot.initrd
znetboot: $(images)/vmlinux.coff \
$(images)/vmlinux.elf-pmac \
$(images)/zImage.chrp
cp $(images)/vmlinux.coff $(TFTPIMAGE).pmac$(END)
cp $(images)/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END).elf
znetboot: $(images)/zImage.chrp
cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END)
@echo ' kernel: $@ is ready ($<)'
znetboot.initrd:$(images)/vmlinux.initrd.coff \
$(images)/vmlinux.initrd.elf-pmac \
$(images)/zImage.initrd.chrp
cp $(images)/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END)
cp $(images)/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf
znetboot.initrd:$(images)/zImage.initrd.chrp
cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END)
@echo ' kernel: $@ is ready ($<)'
/*
* Copyright (C) Paul Mackerras 1997.
*
* 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/string.h>
#include <asm/processor.h>
#include <asm/page.h>
#include "nonstdio.h"
#include "of1275.h"
/* Passed from the linker */
extern char __image_begin, __image_end;
extern char __ramdisk_begin[], __ramdisk_end;
extern char _start, _end;
extern char image_data[], initrd_data[];
extern int initrd_len, image_len;
extern unsigned int heap_max;
extern void flush_cache(void *start, unsigned int len);
extern void gunzip(void *, int, unsigned char *, int *);
extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
unsigned int progend);
extern void setup_bats(unsigned long start);
char *avail_ram;
char *begin_avail, *end_avail;
char *avail_high;
#define SCRATCH_SIZE (128 << 10)
static char heap[SCRATCH_SIZE];
static unsigned long ram_start = 0;
static unsigned long ram_end = 0x1000000;
static unsigned long prog_start = 0x800000;
static unsigned long prog_size = 0x700000;
typedef void (*kernel_start_t)(int, int, void *);
void boot(int a1, int a2, void *prom)
{
unsigned sa, len;
void *dst;
unsigned char *im;
unsigned initrd_start, initrd_size;
printf("coffboot starting: loaded at 0x%p\n", &_start);
setup_bats(ram_start);
initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
if (initrd_size) {
initrd_start = (ram_end - initrd_size) & ~0xFFF;
a1 = initrd_start;
a2 = initrd_size;
claim(initrd_start, ram_end - initrd_start, 0);
printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
initrd_start, (char *)(&__ramdisk_begin), initrd_size);
memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
prog_size = initrd_start - prog_start;
} else
a2 = 0xdeadbeef;
im = (char *)(&__image_begin);
len = (char *)(&__image_end) - (char *)(&__image_begin);
/* claim 4MB starting at PROG_START */
claim(prog_start, prog_size, 0);
map(prog_start, prog_start, prog_size);
dst = (void *) prog_start;
if (im[0] == 0x1f && im[1] == 0x8b) {
/* set up scratch space */
begin_avail = avail_high = avail_ram = heap;
end_avail = heap + sizeof(heap);
printf("heap at 0x%p\n", avail_ram);
printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
gunzip(dst, prog_size, im, &len);
printf("done %u bytes\n", len);
printf("%u bytes of heap consumed, max in use %u\n",
avail_high - begin_avail, heap_max);
} else {
memmove(dst, im, len);
}
flush_cache(dst, len);
make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac,
(prog_start + prog_size));
sa = (unsigned long)prog_start;
printf("start address = 0x%x\n", sa);
(*(kernel_start_t)sa)(a1, a2, prom);
printf("returned?\n");
pause();
}
/*
* Copyright (C) Paul Mackerras 1997.
*
* 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/string.h>
#include "nonstdio.h"
#include "of1275.h"
#include <asm/processor.h>
#include <asm/page.h>
/* Passed from the linker */
extern char __image_begin, __image_end;
extern char __ramdisk_begin[], __ramdisk_end;
extern char _start, _end;
extern unsigned int heap_max;
extern void flush_cache(void *start, unsigned int len);
extern void gunzip(void *, int, unsigned char *, int *);
extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
unsigned int progend);
char *avail_ram;
char *begin_avail, *end_avail;
char *avail_high;
#define RAM_END (16 << 20)
#define PROG_START 0x00010000
#define PROG_SIZE 0x007f0000
#define SCRATCH_SIZE (128 << 10)
typedef void (*kernel_start_t)(int, int, void *);
void boot(int a1, int a2, void *prom)
{
unsigned sa, len;
void *dst;
unsigned char *im;
unsigned initrd_start, initrd_size;
printf("chrpboot starting: loaded at 0x%p\n", &_start);
initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
if (initrd_size) {
initrd_start = (RAM_END - initrd_size) & ~0xFFF;
a1 = initrd_start;
a2 = initrd_size;
claim(initrd_start, RAM_END - initrd_start, 0);
printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
initrd_start, (char *)(&__ramdisk_begin), initrd_size);
memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
} else
a2 = 0xdeadbeef;
im = (char *)(&__image_begin);
len = (char *)(&__image_end) - (char *)(&__image_begin);
/* claim 3MB starting at PROG_START */
claim(PROG_START, PROG_SIZE, 0);
dst = (void *) PROG_START;
if (im[0] == 0x1f && im[1] == 0x8b) {
/* claim some memory for scratch space */
avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
begin_avail = avail_high = avail_ram;
end_avail = avail_ram + SCRATCH_SIZE;
printf("heap at 0x%p\n", avail_ram);
printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
gunzip(dst, PROG_SIZE, im, &len);
printf("done %u bytes\n", len);
printf("%u bytes of heap consumed, max in use %u\n",
avail_high - begin_avail, heap_max);
release(begin_avail, SCRATCH_SIZE);
} else {
memmove(dst, im, len);
}
flush_cache(dst, len);
make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac,
(PROG_START + PROG_SIZE));
sa = (unsigned long)PROG_START;
printf("start address = 0x%x\n", sa);
(*(kernel_start_t)sa)(a1, a2, prom);
printf("returned?\n");
pause();
}
......@@ -9,7 +9,6 @@ extra-$(CONFIG_44x) := head_44x.o
extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-$(CONFIG_POWER4) += idle_power4.o
extra-y += vmlinux.lds
obj-y := entry.o traps.o idle.o time.o misc.o \
......@@ -17,7 +16,6 @@ obj-y := entry.o traps.o idle.o time.o misc.o \
ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_POWER4) += cpu_setup_power4.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
obj-$(CONFIG_PCI) += pci.o
......
......@@ -204,78 +204,6 @@ _GLOBAL(call_setup_cpu)
mtctr r5
bctr
#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
/* This gets called by via-pmu.c to switch the PLL selection
* on 750fx CPU. This function should really be moved to some
* other place (as most of the cpufreq code in via-pmu
*/
_GLOBAL(low_choose_750fx_pll)
/* Clear MSR:EE */
mfmsr r7
rlwinm r0,r7,0,17,15
mtmsr r0
/* If switching to PLL1, disable HID0:BTIC */
cmplwi cr0,r3,0
beq 1f
mfspr r5,SPRN_HID0
rlwinm r5,r5,0,27,25
sync
mtspr SPRN_HID0,r5
isync
sync
1:
/* Calc new HID1 value */
mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */
rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */
rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */
or r4,r4,r5
mtspr SPRN_HID1,r4
/* Store new HID1 image */
rlwinm r6,r1,0,0,18
lwz r6,TI_CPU(r6)
slwi r6,r6,2
addis r6,r6,nap_save_hid1@ha
stw r4,nap_save_hid1@l(r6)
/* If switching to PLL0, enable HID0:BTIC */
cmplwi cr0,r3,0
bne 1f
mfspr r5,SPRN_HID0
ori r5,r5,HID0_BTIC
sync
mtspr SPRN_HID0,r5
isync
sync
1:
/* Return */
mtmsr r7
blr
_GLOBAL(low_choose_7447a_dfs)
/* Clear MSR:EE */
mfmsr r7
rlwinm r0,r7,0,17,15
mtmsr r0
/* Calc new HID1 value */
mfspr r4,SPRN_HID1
insrwi r4,r3,1,9 /* insert parameter into bit 9 */
sync
mtspr SPRN_HID1,r4
sync
isync
/* Return */
mtmsr r7
blr
#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
/*
* complement mask on the msr then "or" some values on.
* _nmask_and_or_msr(nmask, value_to_or)
......
/*
* Common pmac/prep/chrp pci routines. -- Cort
* Common prep/chrp pci routines. -- Cort
*/
#include <linux/config.h>
......@@ -50,8 +50,7 @@ static void fixup_cpc710_pci64(struct pci_dev* dev);
static u8* pci_to_OF_bus_map;
#endif
/* By default, we don't re-assign bus numbers. We do this only on
* some pmacs
/* By default, we don't re-assign bus numbers.
*/
int pci_assign_all_buses;
......@@ -780,17 +779,6 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
return NULL;
/* Fixup bus number according to what OF think it is. */
#ifdef CONFIG_PPC_PMAC
/* The G5 need a special case here. Basically, we don't remap all
* busses on it so we don't create the pci-OF-map. However, we do
* remap the AGP bus and so have to deal with it. A future better
* fix has to be done by making the remapping per-host and always
* filling the pci_to_OF map. --BenH
*/
if (_machine == _MACH_Pmac && busnr >= 0xf0)
busnr -= 0xf0;
else
#endif
if (pci_to_OF_bus_map)
busnr = pci_to_OF_bus_map[busnr];
if (busnr == 0xff)
......@@ -1040,216 +1028,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev)
}
#ifdef CONFIG_PPC_PMAC
/*
* This set of routines checks for PCI<->PCI bridges that have closed
* IO resources and have child devices. It tries to re-open an IO
* window on them.
*
* This is a _temporary_ fix to workaround a problem with Apple's OF
* closing IO windows on P2P bridges when the OF drivers of cards
* below this bridge don't claim any IO range (typically ATI or
* Adaptec).
*
* A more complete fix would be to use drivers/pci/setup-bus.c, which
* involves a working pcibios_fixup_pbus_ranges(), some more care about
* ordering when creating the host bus resources, and maybe a few more
* minor tweaks
*/
/* Initialize bridges with base/limit values we have collected */
static void __init
do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
{
struct pci_dev *bridge = bus->self;
struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
u32 l;
u16 w;
struct resource res;
if (bus->resource[0] == NULL)
return;
res = *(bus->resource[0]);
DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
DBG(" IO window: %08lx-%08lx\n", res.start, res.end);
/* Set up the top and bottom of the PCI I/O segment for this bus. */
pci_read_config_dword(bridge, PCI_IO_BASE, &l);
l &= 0xffff000f;
l |= (res.start >> 8) & 0x00f0;
l |= res.end & 0xf000;
pci_write_config_dword(bridge, PCI_IO_BASE, l);
if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
l = (res.start >> 16) | (res.end & 0xffff0000);
pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
}
pci_read_config_word(bridge, PCI_COMMAND, &w);
w |= PCI_COMMAND_IO;
pci_write_config_word(bridge, PCI_COMMAND, w);
#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
if (enable_vga) {
pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
w |= PCI_BRIDGE_CTL_VGA;
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
}
#endif
}
/* This function is pretty basic and actually quite broken for the
* general case, it's enough for us right now though. It's supposed
* to tell us if we need to open an IO range at all or not and what
* size.
*/
static int __init
check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
{
struct pci_dev *dev;
int i;
int rc = 0;
#define push_end(res, size) do { unsigned long __sz = (size) ; \
res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \
} while (0)
list_for_each_entry(dev, &bus->devices, bus_list) {
u16 class = dev->class >> 8;
if (class == PCI_CLASS_DISPLAY_VGA ||
class == PCI_CLASS_NOT_DEFINED_VGA)
*found_vga = 1;
if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
rc |= check_for_io_childs(dev->subordinate, res, found_vga);
if (class == PCI_CLASS_BRIDGE_CARDBUS)
push_end(res, 0xfff);
for (i=0; i<PCI_NUM_RESOURCES; i++) {
struct resource *r;
unsigned long r_size;
if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
&& i >= PCI_BRIDGE_RESOURCES)
continue;
r = &dev->resource[i];
r_size = r->end - r->start;
if (r_size < 0xfff)
r_size = 0xfff;
if (r->flags & IORESOURCE_IO && (r_size) != 0) {
rc = 1;
push_end(res, r_size);
}
}
}
return rc;
}
/* Here we scan all P2P bridges of a given level that have a closed
* IO window. Note that the test for the presence of a VGA card should
* be improved to take into account already configured P2P bridges,
* currently, we don't see them and might end up configuring 2 bridges
* with VGA pass through enabled
*/
static void __init
do_fixup_p2p_level(struct pci_bus *bus)
{
struct pci_bus *b;
int i, parent_io;
int has_vga = 0;
for (parent_io=0; parent_io<4; parent_io++)
if (bus->resource[parent_io]
&& bus->resource[parent_io]->flags & IORESOURCE_IO)
break;
if (parent_io >= 4)
return;
list_for_each_entry(b, &bus->children, node) {
struct pci_dev *d = b->self;
struct pci_controller* hose = (struct pci_controller *)d->sysdata;
struct resource *res = b->resource[0];
struct resource tmp_res;
unsigned long max;
int found_vga = 0;
memset(&tmp_res, 0, sizeof(tmp_res));
tmp_res.start = bus->resource[parent_io]->start;
/* We don't let low addresses go through that closed P2P bridge, well,
* that may not be necessary but I feel safer that way
*/
if (tmp_res.start == 0)
tmp_res.start = 0x1000;
if (!list_empty(&b->devices) && res && res->flags == 0 &&
res != bus->resource[parent_io] &&
(d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
check_for_io_childs(b, &tmp_res, &found_vga)) {
u8 io_base_lo;
printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
if (found_vga) {
if (has_vga) {
printk(KERN_WARNING "Skipping VGA, already active"
" on bus segment\n");
found_vga = 0;
} else
has_vga = 1;
}
pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
max = ((unsigned long) hose->io_base_virt
- isa_io_base) + 0xffffffff;
else
max = ((unsigned long) hose->io_base_virt
- isa_io_base) + 0xffff;
*res = tmp_res;
res->flags = IORESOURCE_IO;
res->name = b->name;
/* Find a resource in the parent where we can allocate */
for (i = 0 ; i < 4; i++) {
struct resource *r = bus->resource[i];
if (!r)
continue;
if ((r->flags & IORESOURCE_IO) == 0)
continue;
DBG("Trying to allocate from %08lx, size %08lx from parent"
" res %d: %08lx -> %08lx\n",
res->start, res->end, i, r->start, r->end);
if (allocate_resource(r, res, res->end + 1, res->start, max,
res->end + 1, NULL, NULL) < 0) {
DBG("Failed !\n");
continue;
}
do_update_p2p_io_resource(b, found_vga);
break;
}
}
do_fixup_p2p_level(b);
}
}
static void
pcibios_fixup_p2p_bridges(void)
{
struct pci_bus *b;
list_for_each_entry(b, &pci_root_buses, node)
do_fixup_p2p_level(b);
}
#endif /* CONFIG_PPC_PMAC */
static int __init
pcibios_init(void)
{
......@@ -1290,9 +1068,6 @@ pcibios_init(void)
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
#ifdef CONFIG_PPC_PMAC
pcibios_fixup_p2p_bridges();
#endif /* CONFIG_PPC_PMAC */
pcibios_assign_resources();
/* Call machine dependent post-init code */
......@@ -1722,17 +1497,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
struct pci_controller* hose;
long result = -EOPNOTSUPP;
/* Argh ! Please forgive me for that hack, but that's the
* simplest way to get existing XFree to not lockup on some
* G5 machines... So when something asks for bus 0 io base
* (bus 0 is HT root), we return the AGP one instead.
*/
#ifdef CONFIG_PPC_PMAC
if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))
if (bus == 0)
bus = 0xf0;
#endif /* CONFIG_PPC_PMAC */
hose = pci_bus_to_hose(bus);
if (!hose)
return -ENODEV;
......
......@@ -34,7 +34,6 @@
#include <asm/system.h>
#include <asm/pci-bridge.h>
#include <asm/irq.h>
#include <asm/pmac_feature.h>
#include <asm/dma.h>
#include <asm/machdep.h>
#include <asm/hw_irq.h>
......@@ -58,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
extern void alignment_exception(struct pt_regs *regs);
extern void program_check_exception(struct pt_regs *regs);
extern void single_step_exception(struct pt_regs *regs);
extern int pmac_newworld;
extern int sys_sigreturn(struct pt_regs *regs);
long long __ashrdi3(long long, int);
......@@ -213,10 +211,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
EXPORT_SYMBOL(cuda_request);
EXPORT_SYMBOL(cuda_poll);
#endif /* CONFIG_ADB_CUDA */
#ifdef CONFIG_PPC_PMAC
EXPORT_SYMBOL(sys_ctrler);
EXPORT_SYMBOL(pmac_newworld);
#endif
#ifdef CONFIG_PPC_OF
EXPORT_SYMBOL(find_devices);
EXPORT_SYMBOL(find_type_devices);
......@@ -241,9 +235,6 @@ EXPORT_SYMBOL(of_node_put);
#if defined(CONFIG_BOOTX_TEXT)
EXPORT_SYMBOL(btext_update_display);
#endif
#if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC)
EXPORT_SYMBOL(note_scsi_host);
#endif
#ifdef CONFIG_VT
EXPORT_SYMBOL(kd_mksound);
#endif
......
/*
* Common prep/pmac/chrp boot and setup code.
* Common prep/chrp boot and setup code.
*/
#include <linux/config.h>
......@@ -35,7 +35,6 @@
#include <asm/machdep.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/pmac_feature.h>
#include <asm/sections.h>
#include <asm/nvram.h>
#include <asm/xmon.h>
......@@ -55,7 +54,6 @@
extern void platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
extern void bootx_init(unsigned long r4, unsigned long phys);
extern void identify_cpu(unsigned long offset, unsigned long cpu);
extern void do_cpu_ftr_fixups(unsigned long offset);
extern void reloc_got2(unsigned long offset);
......@@ -80,8 +78,6 @@ EXPORT_SYMBOL(_machine);
extern void prep_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
extern void pmac_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
extern void chrp_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
......@@ -324,20 +320,15 @@ early_init(int r3, int r4, int r5)
identify_cpu(offset, 0);
do_cpu_ftr_fixups(offset);
#if defined(CONFIG_PPC_MULTIPLATFORM)
#if defined(CONFIG_PPC_OF)
reloc_got2(offset);
/* If we came here from BootX, clear the screen,
* set up some pointers and return. */
if ((r3 == 0x426f6f58) && (r5 == 0))
bootx_init(r4, phys);
/*
* don't do anything on prep
* for now, don't use bootinfo because it breaks yaboot 0.5
* and assume that if we didn't find a magic number, we have OF
*/
else if (*(unsigned long *)(0) != 0xdeadc0de)
if (*(unsigned long *)(0) != 0xdeadc0de)
phys = prom_init(r3, r4, (prom_entry)r5);
reloc_got2(-offset);
......@@ -424,6 +415,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
}
#endif
#ifdef CONFIG_PPC_OF
have_of = 1;
/* prom_init has already been called from __start */
......@@ -495,19 +487,17 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* CONFIG_ADB */
switch (_machine) {
#ifdef CONFIG_PPC_PMAC
case _MACH_Pmac:
pmac_init(r3, r4, r5, r6, r7);
break;
#endif
#ifdef CONFIG_PPC_CHRP
case _MACH_chrp:
chrp_init(r3, r4, r5, r6, r7);
break;
#endif
}
#endif /* CONFIG_PPC_OF */
}
#endif /* CONFIG_PPC_MULTIPLATFORM */
#ifdef CONFIG_PPC_OF
#ifdef CONFIG_SERIAL_CORE_CONSOLE
extern char *of_stdout_device;
......@@ -564,7 +554,7 @@ static int __init set_preferred_console(void)
}
console_initcall(set_preferred_console);
#endif /* CONFIG_SERIAL_CORE_CONSOLE */
#endif /* CONFIG_PPC_MULTIPLATFORM */
#endif /* CONFIG_PPC_OF */
struct bi_record *find_bootinfo(void)
{
......@@ -747,14 +737,6 @@ void __init setup_arch(char **cmdline_p)
if (ppc_md.init_early)
ppc_md.init_early();
#ifdef CONFIG_PPC_MULTIPLATFORM
/* This could be called "early setup arch", it must be done
* now because xmon need it
*/
if (_machine == _MACH_Pmac)
pmac_feature_init(); /* New cool way */
#endif
#ifdef CONFIG_XMON
xmon_init(1);
if (strstr(cmd_line, "xmon"))
......
......@@ -38,9 +38,6 @@
#include <asm/io.h>
#include <asm/reg.h>
#include <asm/xmon.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
#include <asm/pmc.h>
#ifdef CONFIG_XMON
......@@ -85,12 +82,6 @@ int die(const char * str, struct pt_regs * fp, long err)
int nl = 0;
console_verbose();
spin_lock_irq(&die_lock);
#ifdef CONFIG_PMAC_BACKLIGHT
if (_machine == _MACH_Pmac) {
set_backlight_enable(1);
set_backlight_level(BACKLIGHT_MAX);
}
#endif
printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
#ifdef CONFIG_PREEMPT
printk("PREEMPT ");
......@@ -159,7 +150,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
*/
static inline int check_io_access(struct pt_regs *regs)
{
#if defined CONFIG_PPC_PMAC || defined CONFIG_8xx
#if defined CONFIG_8xx
unsigned long msr = regs->msr;
const struct exception_table_entry *entry;
unsigned int *nip = (unsigned int *)regs->nip;
......@@ -196,7 +187,7 @@ static inline int check_io_access(struct pt_regs *regs)
return 1;
}
}
#endif /* CONFIG_PPC_PMAC */
#endif /* CONFIG_8xx */
return 0;
}
......
......@@ -67,10 +67,6 @@ unsigned long ppc_memoffset = PAGE_OFFSET;
int mem_init_done;
int init_bootmem_done;
int boot_mapsize;
#ifdef CONFIG_PPC_PMAC
unsigned long agp_special_page;
EXPORT_SYMBOL(agp_special_page);
#endif
extern char _end[];
extern char etext[], _stext[];
......@@ -423,10 +419,6 @@ void __init mem_init(void)
addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ;
addr += PAGE_SIZE)
SetPageReserved(virt_to_page(addr));
#endif
#ifdef CONFIG_PPC_PMAC
if (agp_special_page)
SetPageReserved(virt_to_page(agp_special_page));
#endif
for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;
addr += PAGE_SIZE) {
......@@ -463,11 +455,6 @@ void __init mem_init(void)
initpages<< (PAGE_SHIFT-10),
(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
#ifdef CONFIG_PPC_PMAC
if (agp_special_page)
printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page);
#endif
mem_init_done = 1;
}
......@@ -512,22 +499,6 @@ set_phys_avail(unsigned long total_memory)
if (rtas_data)
mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
#endif
#ifdef CONFIG_PPC_PMAC
/* Because of some uninorth weirdness, we need a page of
* memory as high as possible (it must be outside of the
* bus address seen as the AGP aperture). It will be used
* by the r128 DRM driver
*
* FIXME: We need to make sure that page doesn't overlap any of the\
* above. This could be done by improving mem_pieces_find to be able
* to do a backward search from the end of the list.
*/
if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) {
agp_special_page = (total_memory - PAGE_SIZE);
mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0);
agp_special_page = (unsigned long)__va(agp_special_page);
}
#endif /* CONFIG_PPC_PMAC */
}
/* Mark some memory as reserved by removing it from phys_avail. */
......
......@@ -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
......@@ -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;
......
......@@ -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;
......
......@@ -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;
/*
......
/*
* 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);
}
/*
* 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 */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef __PPC_PLATFORMS_PMAC_PIC_H
#define __PPC_PLATFORMS_PMAC_PIC_H
#include <linux/irq.h>
extern struct hw_interrupt_type pmac_pic;
void pmac_pic_init(void);
int pmac_get_irq(struct pt_regs *regs);
#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -39,8 +39,6 @@ obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
obj-$(CONFIG_PPC_OF) += prom_init.o prom.o
obj-$(CONFIG_PPC_PMAC) += open_pic.o
obj-$(CONFIG_POWER4) += open_pic2.o
obj-$(CONFIG_PPC_CHRP) += open_pic.o
obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
......
......@@ -70,8 +70,6 @@ int use_of_interrupt_tree;
struct device_node *dflt_interrupt_controller;
int num_interrupt_controllers;
int pmac_newworld;
extern unsigned int rtas_entry; /* physical pointer */
extern struct device_node *allnodes;
......@@ -123,22 +121,13 @@ finish_device_tree(void)
unsigned long mem = (unsigned long) klimit;
struct device_node *np;
/* All newworld pmac machines and CHRPs now use the interrupt tree */
/* All CHRPs now use the interrupt tree */
for (np = allnodes; np != NULL; np = np->allnext) {
if (get_property(np, "interrupt-parent", NULL)) {
use_of_interrupt_tree = 1;
break;
}
}
if (_machine == _MACH_Pmac && use_of_interrupt_tree)
pmac_newworld = 1;
#ifdef CONFIG_BOOTX_TEXT
if (boot_infos && pmac_newworld) {
prom_print("WARNING ! BootX/miBoot booting is not supported on this machine\n");
prom_print(" You should use an Open Firmware bootloader\n");
}
#endif /* CONFIG_BOOTX_TEXT */
if (use_of_interrupt_tree) {
/*
......@@ -434,16 +423,10 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start)
* those machines, we want to offset interrupts from the
* second openpic by 128 -- BenH
*/
if (_machine != _MACH_Pmac && num_interrupt_controllers > 1
if (num_interrupt_controllers > 1
&& ic != NULL
&& get_property(ic, "interrupt-parent", NULL) == NULL)
offset = 16;
else if (_machine == _MACH_Pmac && num_interrupt_controllers > 1
&& ic != NULL && ic->parent != NULL) {
char *name = get_property(ic->parent, "name", NULL);
if (name && !strcmp(name, "u3"))
offset = 128;
}
np->intrs[i].line = irq[0] + offset;
if (n > 1)
......
This diff is collapsed.
......@@ -16,9 +16,6 @@
#include <asm/bootx.h>
#include <asm/machdep.h>
#include <asm/xmon.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
#include "nonstdio.h"
#include "privinst.h"
......@@ -260,16 +257,6 @@ int xmon(struct pt_regs *excp)
*/
#endif /* CONFIG_SMP */
remove_bpts();
#ifdef CONFIG_PMAC_BACKLIGHT
if( setjmp(bus_error_jmp) == 0 ) {
debugger_fault_handler = handle_fault;
sync();
set_backlight_enable(1);
set_backlight_level(BACKLIGHT_MAX);
sync();
}
debugger_fault_handler = NULL;
#endif /* CONFIG_PMAC_BACKLIGHT */
cmd = cmds(excp);
if (cmd == 's') {
xmon_trace[smp_processor_id()] = SSTEP;
......
......@@ -2734,7 +2734,7 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
* BIOS does tho. Right now, all this PM stuff is pmac-only for that
* reason. --BenH
*/
#if defined(CONFIG_PM) && defined(CONFIG_PPC_OF)
#if defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC)
if (_machine == _MACH_Pmac && rinfo->of_node) {
if (rinfo->is_mobility && rinfo->pm_reg &&
rinfo->family <= CHIP_FAMILY_RV250)
......@@ -2778,12 +2778,12 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
OUTREG(TV_DAC_CNTL, INREG(TV_DAC_CNTL) | 0x07000000);
#endif
}
#endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_OF) */
#endif /* defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC) */
}
void radeonfb_pm_exit(struct radeonfb_info *rinfo)
{
#if defined(CONFIG_PM) && defined(CONFIG_PPC_OF)
#if defined(CONFIG_PM) && defined(CONFIG_PPC_PMAC)
if (rinfo->pm_mode != radeon_pm_none)
pmac_set_early_video_resume(NULL, NULL);
#endif
......
......@@ -167,6 +167,14 @@ extern int of_address_to_resource(struct device_node *dev, int index,
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
struct resource *r);
#ifndef CONFIG_PPC_OF
/*
* Fallback definitions for builds where we don't have prom.c included.
*/
#define machine_is_compatible(x) 0
#define of_find_compatible_node(f, t, c) NULL
#define get_property(p, n, l) NULL
#endif
#endif /* _PPC_PROM_H */
#endif /* __KERNEL__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment