提交 af3b146d 编写于 作者: L Linus Torvalds

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (23 commits)
  [POWERPC] Add arch/powerpc support for the Motorola PrPMC2800
  [POWERPC] Add bootwrapper support for Motorola PrPMC2800 platform
  [POWERPC] Add DTS file for the Motorola PrPMC2800 platform
  [POWERPC] Check cache coherency of kernel vs firmware
  [POWERPC] Add Marvell mv64x60 PCI bridge support
  [POWERPC] Create Marvell mv64x60 I2C platform_data
  [POWERPC] Create Marvell mv64x60 ethernet platform_data
  [POWERPC] Create Marvell mv64x60 MPSC (serial) platform_data
  [POWERPC] Add interrupt support for Marvell mv64x60 chips
  [POWERPC] Add bootwrapper support for Marvell/mv64x60 I2C
  [POWERPC] Add bootwrapper support for Marvell MPSC
  [POWERPC] Add bootwrapper support for Marvell/mv64x60 hostbridge
  [POWERPC] Add Makefile rules to wrap dts file in zImage
  [POWERPC] Spelling fixes: arch/ppc/
  [POWERPC] U-boot passes the initrd as start/end, not start/size.
  [POWERPC] PS3: Update ps3_defconfig
  [POWERPC] PS3: Fix request_irq warning
  [POWERPC] Don't complain if size-cells == 0 in prom_parse()
  [POWERPC] Simplify smp_space_timers
  [POWERPC] Trivial ps3 warning fixes
  ...
......@@ -389,6 +389,9 @@ config NOT_COHERENT_CACHE
bool
depends on 4xx || 8xx || E200
default y
config CONFIG_CHECK_CACHE_COHERENCY
bool
endmenu
source "init/Kconfig"
......@@ -451,7 +454,7 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
depends on PPC_MULTIPLATFORM && EXPERIMENTAL
depends on (PPC_PRPMC2800 || PPC_MULTIPLATFORM) && EXPERIMENTAL
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
......
......@@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE)
CPPFLAGS_vmlinux.lds := -Upowerpc
BOOT_TARGETS = zImage zImage.initrd uImage
BOOT_TARGETS = zImage zImage.initrd zImage.dts zImage.dts_initrd uImage
PHONY += $(BOOT_TARGETS)
......
......@@ -43,9 +43,9 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c \
44x.c ebony.c
44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c
src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
cuboot-ebony.c treeboot-ebony.c
cuboot-ebony.c treeboot-ebony.c prpmc2800.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
......@@ -132,6 +132,7 @@ image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
image-$(CONFIG_PPC_PMAC) += zImage.pmac
image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf
image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
image-$(CONFIG_DEFAULT_UIMAGE) += uImage
ifneq ($(CONFIG_DEVICE_TREE),"")
......@@ -154,9 +155,27 @@ targets += $(image-y) $(initrd-y)
$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
dts- := $(patsubst zImage%, zImage.dts%, $(image-n) $(image-))
dts-y := $(patsubst zImage%, zImage.dts%, $(image-y))
dts-y := $(filter-out $(image-y), $(dts-y))
targets += $(image-y) $(dts-y)
dts_initrd- := $(patsubst zImage%, zImage.dts_initrd%, $(image-n) $(image-))
dts_initrd-y := $(patsubst zImage%, zImage.dts_initrd%, $(image-y))
dts_initrd-y := $(filter-out $(image-y), $(dts_initrd-y))
targets += $(image-y) $(dts_initrd-y)
$(addprefix $(obj)/, $(dts_initrd-y)): $(obj)/ramdisk.image.gz
# Don't put the ramdisk on the pattern rule; when its missing make will try
# the pattern rule with less dependencies that also matches (even with the
# hard dependency listed).
$(obj)/zImage.dts_initrd.%: vmlinux $(wrapperbits) $(dts) $(obj)/ramdisk.image.gz
$(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz)
$(obj)/zImage.dts.%: vmlinux $(wrapperbits) $(dts)
$(call if_changed,wrap,$*,$(dts))
$(obj)/zImage.initrd.%: vmlinux $(wrapperbits)
$(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz)
......@@ -195,13 +214,18 @@ $(obj)/zImage: $(addprefix $(obj)/, $(image-y))
@rm -f $@; ln $< $@
$(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y))
@rm -f $@; ln $< $@
$(obj)/zImage.dts: $(addprefix $(obj)/, $(dts-y))
@rm -f $@; ln $< $@
$(obj)/zImage.dts_initrd: $(addprefix $(obj)/, $(dts_initrd-y))
@rm -f $@; ln $< $@
install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y))
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
# anything not in $(targets)
clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \
treeImage.*
treeImage.* zImage.dts zImage.dts_initrd
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin
......
......@@ -57,7 +57,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
memcpy(&bd, (bd_t *)r3, sizeof(bd));
loader_info.initrd_addr = r4;
loader_info.initrd_size = r4 ? r5 : 0;
loader_info.initrd_size = r4 ? r5 - r4 : 0;
loader_info.cmdline = (char *)r6;
loader_info.cmdline_len = r7 - r6;
......
......@@ -58,7 +58,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
memcpy(&bd, (bd_t *)r3, sizeof(bd));
loader_info.initrd_addr = r4;
loader_info.initrd_size = r4 ? r5 : 0;
loader_info.initrd_size = r4 ? r5 - r4 : 0;
loader_info.cmdline = (char *)r6;
loader_info.cmdline_len = r7 - r6;
......
/* Device Tree Source for Motorola PrPMC2800
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*
* Property values that are labeled as "Default" will be updated by bootwrapper
* if it can determine the exact PrPMC type.
*
* To build:
* dtc -I dts -O asm -o prpmc2800.S -b 0 prpmc2800.dts
* dtc -I dts -O dtb -o prpmc2800.dtb -b 0 prpmc2800.dts
*/
/ {
#address-cells = <1>;
#size-cells = <1>;
model = "PrPMC280/PrPMC2800"; /* Default */
compatible = "motorola,PrPMC2800";
coherency-off;
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,7447 {
device_type = "cpu";
reg = <0>;
clock-frequency = <2bb0b140>; /* Default (733 MHz) */
bus-frequency = <7f28155>; /* 133.333333 MHz */
timebase-frequency = <1fca055>; /* 33.333333 MHz */
i-cache-line-size = <20>;
d-cache-line-size = <20>;
i-cache-size = <8000>;
d-cache-size = <8000>;
};
};
memory {
device_type = "memory";
reg = <00000000 20000000>; /* Default (512MB) */
};
mv64x60@f1000000 { /* Marvell Discovery */
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <1>;
model = "mv64360"; /* Default */
compatible = "marvell,mv64x60";
clock-frequency = <7f28155>; /* 133.333333 MHz */
reg = <f1000000 00010000>;
virtual-reg = <f1000000>;
ranges = <88000000 88000000 01000000 /* PCI 0 I/O Space */
80000000 80000000 08000000 /* PCI 0 MEM Space */
a0000000 a0000000 04000000 /* User FLASH */
00000000 f1000000 00010000 /* Bridge's regs */
f2000000 f2000000 00040000>; /* Integrated SRAM */
flash@a0000000 {
device_type = "rom";
compatible = "direct-mapped";
reg = <a0000000 4000000>; /* Default (64MB) */
probe-type = "CFI";
bank-width = <4>;
partitions = <00000000 00100000 /* RO */
00100000 00040001 /* RW */
00140000 00400000 /* RO */
00540000 039c0000 /* RO */
03f00000 00100000>; /* RO */
partition-names = "FW Image A", "FW Config Data", "Kernel Image", "Filesystem", "FW Image B";
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
device_type = "mdio";
compatible = "marvell,mv64x60-mdio";
ethernet-phy@1 {
device_type = "ethernet-phy";
compatible = "broadcom,bcm5421";
interrupts = <4c>; /* GPP 12 */
interrupt-parent = <&/mv64x60/pic>;
reg = <1>;
};
ethernet-phy@3 {
device_type = "ethernet-phy";
compatible = "broadcom,bcm5421";
interrupts = <4c>; /* GPP 12 */
interrupt-parent = <&/mv64x60/pic>;
reg = <3>;
};
};
ethernet@2000 {
reg = <2000 2000>;
eth0 {
device_type = "network";
compatible = "marvell,mv64x60-eth";
block-index = <0>;
interrupts = <20>;
interrupt-parent = <&/mv64x60/pic>;
phy = <&/mv64x60/mdio/ethernet-phy@1>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
eth1 {
device_type = "network";
compatible = "marvell,mv64x60-eth";
block-index = <1>;
interrupts = <21>;
interrupt-parent = <&/mv64x60/pic>;
phy = <&/mv64x60/mdio/ethernet-phy@3>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
sdma@4000 {
device_type = "dma";
compatible = "marvell,mv64x60-sdma";
reg = <4000 c18>;
virtual-reg = <f1004000>;
interrupt-base = <0>;
interrupts = <24>;
interrupt-parent = <&/mv64x60/pic>;
};
sdma@6000 {
device_type = "dma";
compatible = "marvell,mv64x60-sdma";
reg = <6000 c18>;
virtual-reg = <f1006000>;
interrupt-base = <0>;
interrupts = <26>;
interrupt-parent = <&/mv64x60/pic>;
};
brg@b200 {
compatible = "marvell,mv64x60-brg";
reg = <b200 8>;
clock-src = <8>;
clock-frequency = <7ed6b40>;
current-speed = <2580>;
bcr = <0>;
};
brg@b208 {
compatible = "marvell,mv64x60-brg";
reg = <b208 8>;
clock-src = <8>;
clock-frequency = <7ed6b40>;
current-speed = <2580>;
bcr = <0>;
};
cunit@f200 {
reg = <f200 200>;
};
mpscrouting@b400 {
reg = <b400 c>;
};
mpscintr@b800 {
reg = <b800 100>;
virtual-reg = <f100b800>;
};
mpsc@8000 {
device_type = "serial";
compatible = "marvell,mpsc";
reg = <8000 38>;
virtual-reg = <f1008000>;
sdma = <&/mv64x60/sdma@4000>;
brg = <&/mv64x60/brg@b200>;
cunit = <&/mv64x60/cunit@f200>;
mpscrouting = <&/mv64x60/mpscrouting@b400>;
mpscintr = <&/mv64x60/mpscintr@b800>;
block-index = <0>;
max_idle = <28>;
chr_1 = <0>;
chr_2 = <0>;
chr_10 = <3>;
mpcr = <0>;
interrupts = <28>;
interrupt-parent = <&/mv64x60/pic>;
};
mpsc@9000 {
device_type = "serial";
compatible = "marvell,mpsc";
reg = <9000 38>;
virtual-reg = <f1009000>;
sdma = <&/mv64x60/sdma@6000>;
brg = <&/mv64x60/brg@b208>;
cunit = <&/mv64x60/cunit@f200>;
mpscrouting = <&/mv64x60/mpscrouting@b400>;
mpscintr = <&/mv64x60/mpscintr@b800>;
block-index = <1>;
max_idle = <28>;
chr_1 = <0>;
chr_2 = <0>;
chr_10 = <3>;
mpcr = <0>;
interrupts = <2a>;
interrupt-parent = <&/mv64x60/pic>;
};
i2c@c000 {
device_type = "i2c";
compatible = "marvell,mv64x60-i2c";
reg = <c000 20>;
virtual-reg = <f100c000>;
freq_m = <8>;
freq_n = <3>;
timeout = <3e8>; /* 1000 = 1 second */
retries = <1>;
interrupts = <25>;
interrupt-parent = <&/mv64x60/pic>;
};
pic {
#interrupt-cells = <1>;
#address-cells = <0>;
compatible = "marvell,mv64x60-pic";
reg = <0000 88>;
interrupt-controller;
};
mpp@f000 {
compatible = "marvell,mv64x60-mpp";
reg = <f000 10>;
};
gpp@f100 {
compatible = "marvell,mv64x60-gpp";
reg = <f100 20>;
};
pci@80000000 {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
device_type = "pci";
compatible = "marvell,mv64x60-pci";
reg = <0cf8 8>;
ranges = <01000000 0 0 88000000 0 01000000
02000000 0 80000000 80000000 0 08000000>;
bus-range = <0 ff>;
clock-frequency = <3EF1480>;
interrupt-pci-iack = <0c34>;
interrupt-parent = <&/mv64x60/pic>;
interrupt-map-mask = <f800 0 0 7>;
interrupt-map = <
/* IDSEL 0x0a */
5000 0 0 1 &/mv64x60/pic 50
5000 0 0 2 &/mv64x60/pic 51
5000 0 0 3 &/mv64x60/pic 5b
5000 0 0 4 &/mv64x60/pic 5d
/* IDSEL 0x0b */
5800 0 0 1 &/mv64x60/pic 5b
5800 0 0 2 &/mv64x60/pic 5d
5800 0 0 3 &/mv64x60/pic 50
5800 0 0 4 &/mv64x60/pic 51
/* IDSEL 0x0c */
6000 0 0 1 &/mv64x60/pic 5b
6000 0 0 2 &/mv64x60/pic 5d
6000 0 0 3 &/mv64x60/pic 50
6000 0 0 4 &/mv64x60/pic 51
/* IDSEL 0x0d */
6800 0 0 1 &/mv64x60/pic 5d
6800 0 0 2 &/mv64x60/pic 50
6800 0 0 3 &/mv64x60/pic 51
6800 0 0 4 &/mv64x60/pic 5b
>;
};
cpu-error@0070 {
compatible = "marvell,mv64x60-cpu-error";
reg = <0070 10 0128 28>;
interrupts = <03>;
interrupt-parent = <&/mv64x60/pic>;
};
sram-ctrl@0380 {
compatible = "marvell,mv64x60-sram-ctrl";
reg = <0380 80>;
interrupts = <0d>;
interrupt-parent = <&/mv64x60/pic>;
};
pci-error@1d40 {
compatible = "marvell,mv64x60-pci-error";
reg = <1d40 40 0c28 4>;
interrupts = <0c>;
interrupt-parent = <&/mv64x60/pic>;
};
mem-ctrl@1400 {
compatible = "marvell,mv64x60-mem-ctrl";
reg = <1400 60>;
interrupts = <11>;
interrupt-parent = <&/mv64x60/pic>;
};
};
chosen {
bootargs = "ip=on console=ttyMM0";
linux,stdout-path = "/mv64x60@f1000000/mpsc@8000";
};
};
/*
* MPSC/UART driver for the Marvell mv64360, mv64460, ...
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#include "string.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
extern void udelay(long delay);
#define MPSC_CHR_1 0x000c
#define MPSC_CHR_2 0x0010
#define MPSC_CHR_2_TA (1<<7)
#define MPSC_CHR_2_TCS (1<<9)
#define MPSC_CHR_2_RA (1<<23)
#define MPSC_CHR_2_CRD (1<<25)
#define MPSC_CHR_2_EH (1<<31)
#define MPSC_CHR_4 0x0018
#define MPSC_CHR_4_Z (1<<29)
#define MPSC_CHR_5 0x001c
#define MPSC_CHR_5_CTL1_INTR (1<<12)
#define MPSC_CHR_5_CTL1_VALID (1<<15)
#define MPSC_CHR_10 0x0030
#define MPSC_INTR_CAUSE 0x0000
#define MPSC_INTR_CAUSE_RCC (1<<6)
#define MPSC_INTR_MASK 0x0080
#define SDMA_SDCM 0x0008
#define SDMA_SDCM_AR (1<<15)
#define SDMA_SDCM_AT (1<<31)
static volatile char *mpsc_base;
static volatile char *mpscintr_base;
static u32 chr1, chr2;
static int mpsc_open(void)
{
chr1 = in_le32((u32 *)(mpsc_base + MPSC_CHR_1)) & 0x00ff0000;
chr2 = in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & ~(MPSC_CHR_2_TA
| MPSC_CHR_2_TCS | MPSC_CHR_2_RA | MPSC_CHR_2_CRD
| MPSC_CHR_2_EH);
out_le32((u32 *)(mpsc_base + MPSC_CHR_4), MPSC_CHR_4_Z);
out_le32((u32 *)(mpsc_base + MPSC_CHR_5),
MPSC_CHR_5_CTL1_INTR | MPSC_CHR_5_CTL1_VALID);
out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_EH);
return 0;
}
static void mpsc_putc(unsigned char c)
{
while (in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & MPSC_CHR_2_TCS);
out_le32((u32 *)(mpsc_base + MPSC_CHR_1), chr1 | c);
out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_TCS);
}
static unsigned char mpsc_getc(void)
{
u32 cause = 0;
unsigned char c;
while (!(cause & MPSC_INTR_CAUSE_RCC))
cause = in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE));
c = in_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2));
out_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2), c);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE),
cause & ~MPSC_INTR_CAUSE_RCC);
return c;
}
static u8 mpsc_tstc(void)
{
return (u8)((in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE))
& MPSC_INTR_CAUSE_RCC) != 0);
}
static void mpsc_stop_dma(volatile char *sdma_base)
{
out_le32((u32 *)(mpsc_base + MPSC_CHR_2),MPSC_CHR_2_TA | MPSC_CHR_2_RA);
out_le32((u32 *)(sdma_base + SDMA_SDCM), SDMA_SDCM_AR | SDMA_SDCM_AT);
while ((in_le32((u32 *)(sdma_base + SDMA_SDCM))
& (SDMA_SDCM_AR | SDMA_SDCM_AT)) != 0)
udelay(100);
}
static volatile char *mpsc_get_virtreg_of_phandle(void *devp, char *prop)
{
void *v;
int n;
n = getprop(devp, prop, &v, sizeof(v));
if (n != sizeof(v))
goto err_out;
devp = find_node_by_linuxphandle((u32)v);
if (devp == NULL)
goto err_out;
n = getprop(devp, "virtual-reg", &v, sizeof(v));
if (n == sizeof(v))
return v;
err_out:
return NULL;
}
int mpsc_console_init(void *devp, struct serial_console_data *scdp)
{
void *v;
int n, reg_set;
volatile char *sdma_base;
n = getprop(devp, "virtual-reg", &v, sizeof(v));
if (n != sizeof(v))
goto err_out;
mpsc_base = v;
sdma_base = mpsc_get_virtreg_of_phandle(devp, "sdma");
if (sdma_base == NULL)
goto err_out;
mpscintr_base = mpsc_get_virtreg_of_phandle(devp, "mpscintr");
if (mpscintr_base == NULL)
goto err_out;
n = getprop(devp, "block-index", &v, sizeof(v));
if (n != sizeof(v))
goto err_out;
reg_set = (int)v;
mpscintr_base += (reg_set == 0) ? 0x4 : 0xc;
/* Make sure the mpsc ctlrs are shutdown */
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
mpsc_stop_dma(sdma_base);
scdp->open = mpsc_open;
scdp->putc = mpsc_putc;
scdp->getc = mpsc_getc;
scdp->tstc = mpsc_tstc;
scdp->close = NULL;
return 0;
err_out:
return -1;
}
/*
* Marvell hostbridge routines
*
* Author: Mark A. Greer <source@mvista.com>
*
* 2004, 2005, 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#include "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
#include "mv64x60.h"
#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define MV64x60_CPU2MEM_WINDOWS 4
#define MV64x60_CPU2MEM_0_BASE 0x0008
#define MV64x60_CPU2MEM_0_SIZE 0x0010
#define MV64x60_CPU2MEM_1_BASE 0x0208
#define MV64x60_CPU2MEM_1_SIZE 0x0210
#define MV64x60_CPU2MEM_2_BASE 0x0018
#define MV64x60_CPU2MEM_2_SIZE 0x0020
#define MV64x60_CPU2MEM_3_BASE 0x0218
#define MV64x60_CPU2MEM_3_SIZE 0x0220
#define MV64x60_ENET2MEM_BAR_ENABLE 0x2290
#define MV64x60_ENET2MEM_0_BASE 0x2200
#define MV64x60_ENET2MEM_0_SIZE 0x2204
#define MV64x60_ENET2MEM_1_BASE 0x2208
#define MV64x60_ENET2MEM_1_SIZE 0x220c
#define MV64x60_ENET2MEM_2_BASE 0x2210
#define MV64x60_ENET2MEM_2_SIZE 0x2214
#define MV64x60_ENET2MEM_3_BASE 0x2218
#define MV64x60_ENET2MEM_3_SIZE 0x221c
#define MV64x60_ENET2MEM_4_BASE 0x2220
#define MV64x60_ENET2MEM_4_SIZE 0x2224
#define MV64x60_ENET2MEM_5_BASE 0x2228
#define MV64x60_ENET2MEM_5_SIZE 0x222c
#define MV64x60_ENET2MEM_ACC_PROT_0 0x2294
#define MV64x60_ENET2MEM_ACC_PROT_1 0x2298
#define MV64x60_ENET2MEM_ACC_PROT_2 0x229c
#define MV64x60_MPSC2MEM_BAR_ENABLE 0xf250
#define MV64x60_MPSC2MEM_0_BASE 0xf200
#define MV64x60_MPSC2MEM_0_SIZE 0xf204
#define MV64x60_MPSC2MEM_1_BASE 0xf208
#define MV64x60_MPSC2MEM_1_SIZE 0xf20c
#define MV64x60_MPSC2MEM_2_BASE 0xf210
#define MV64x60_MPSC2MEM_2_SIZE 0xf214
#define MV64x60_MPSC2MEM_3_BASE 0xf218
#define MV64x60_MPSC2MEM_3_SIZE 0xf21c
#define MV64x60_MPSC_0_REMAP 0xf240
#define MV64x60_MPSC_1_REMAP 0xf244
#define MV64x60_MPSC2MEM_ACC_PROT_0 0xf254
#define MV64x60_MPSC2MEM_ACC_PROT_1 0xf258
#define MV64x60_MPSC2REGS_BASE 0xf25c
#define MV64x60_IDMA2MEM_BAR_ENABLE 0x0a80
#define MV64x60_IDMA2MEM_0_BASE 0x0a00
#define MV64x60_IDMA2MEM_0_SIZE 0x0a04
#define MV64x60_IDMA2MEM_1_BASE 0x0a08
#define MV64x60_IDMA2MEM_1_SIZE 0x0a0c
#define MV64x60_IDMA2MEM_2_BASE 0x0a10
#define MV64x60_IDMA2MEM_2_SIZE 0x0a14
#define MV64x60_IDMA2MEM_3_BASE 0x0a18
#define MV64x60_IDMA2MEM_3_SIZE 0x0a1c
#define MV64x60_IDMA2MEM_4_BASE 0x0a20
#define MV64x60_IDMA2MEM_4_SIZE 0x0a24
#define MV64x60_IDMA2MEM_5_BASE 0x0a28
#define MV64x60_IDMA2MEM_5_SIZE 0x0a2c
#define MV64x60_IDMA2MEM_6_BASE 0x0a30
#define MV64x60_IDMA2MEM_6_SIZE 0x0a34
#define MV64x60_IDMA2MEM_7_BASE 0x0a38
#define MV64x60_IDMA2MEM_7_SIZE 0x0a3c
#define MV64x60_IDMA2MEM_ACC_PROT_0 0x0a70
#define MV64x60_IDMA2MEM_ACC_PROT_1 0x0a74
#define MV64x60_IDMA2MEM_ACC_PROT_2 0x0a78
#define MV64x60_IDMA2MEM_ACC_PROT_3 0x0a7c
#define MV64x60_PCI_ACC_CNTL_WINDOWS 6
#define MV64x60_PCI0_PCI_DECODE_CNTL 0x0d3c
#define MV64x60_PCI1_PCI_DECODE_CNTL 0x0dbc
#define MV64x60_PCI0_BAR_ENABLE 0x0c3c
#define MV64x60_PCI02MEM_0_SIZE 0x0c08
#define MV64x60_PCI0_ACC_CNTL_0_BASE_LO 0x1e00
#define MV64x60_PCI0_ACC_CNTL_0_BASE_HI 0x1e04
#define MV64x60_PCI0_ACC_CNTL_0_SIZE 0x1e08
#define MV64x60_PCI0_ACC_CNTL_1_BASE_LO 0x1e10
#define MV64x60_PCI0_ACC_CNTL_1_BASE_HI 0x1e14
#define MV64x60_PCI0_ACC_CNTL_1_SIZE 0x1e18
#define MV64x60_PCI0_ACC_CNTL_2_BASE_LO 0x1e20
#define MV64x60_PCI0_ACC_CNTL_2_BASE_HI 0x1e24
#define MV64x60_PCI0_ACC_CNTL_2_SIZE 0x1e28
#define MV64x60_PCI0_ACC_CNTL_3_BASE_LO 0x1e30
#define MV64x60_PCI0_ACC_CNTL_3_BASE_HI 0x1e34
#define MV64x60_PCI0_ACC_CNTL_3_SIZE 0x1e38
#define MV64x60_PCI0_ACC_CNTL_4_BASE_LO 0x1e40
#define MV64x60_PCI0_ACC_CNTL_4_BASE_HI 0x1e44
#define MV64x60_PCI0_ACC_CNTL_4_SIZE 0x1e48
#define MV64x60_PCI0_ACC_CNTL_5_BASE_LO 0x1e50
#define MV64x60_PCI0_ACC_CNTL_5_BASE_HI 0x1e54
#define MV64x60_PCI0_ACC_CNTL_5_SIZE 0x1e58
#define MV64x60_PCI1_BAR_ENABLE 0x0cbc
#define MV64x60_PCI12MEM_0_SIZE 0x0c88
#define MV64x60_PCI1_ACC_CNTL_0_BASE_LO 0x1e80
#define MV64x60_PCI1_ACC_CNTL_0_BASE_HI 0x1e84
#define MV64x60_PCI1_ACC_CNTL_0_SIZE 0x1e88
#define MV64x60_PCI1_ACC_CNTL_1_BASE_LO 0x1e90
#define MV64x60_PCI1_ACC_CNTL_1_BASE_HI 0x1e94
#define MV64x60_PCI1_ACC_CNTL_1_SIZE 0x1e98
#define MV64x60_PCI1_ACC_CNTL_2_BASE_LO 0x1ea0
#define MV64x60_PCI1_ACC_CNTL_2_BASE_HI 0x1ea4
#define MV64x60_PCI1_ACC_CNTL_2_SIZE 0x1ea8
#define MV64x60_PCI1_ACC_CNTL_3_BASE_LO 0x1eb0
#define MV64x60_PCI1_ACC_CNTL_3_BASE_HI 0x1eb4
#define MV64x60_PCI1_ACC_CNTL_3_SIZE 0x1eb8
#define MV64x60_PCI1_ACC_CNTL_4_BASE_LO 0x1ec0
#define MV64x60_PCI1_ACC_CNTL_4_BASE_HI 0x1ec4
#define MV64x60_PCI1_ACC_CNTL_4_SIZE 0x1ec8
#define MV64x60_PCI1_ACC_CNTL_5_BASE_LO 0x1ed0
#define MV64x60_PCI1_ACC_CNTL_5_BASE_HI 0x1ed4
#define MV64x60_PCI1_ACC_CNTL_5_SIZE 0x1ed8
#define MV64x60_CPU2PCI_SWAP_NONE 0x01000000
#define MV64x60_CPU2PCI0_IO_BASE 0x0048
#define MV64x60_CPU2PCI0_IO_SIZE 0x0050
#define MV64x60_CPU2PCI0_IO_REMAP 0x00f0
#define MV64x60_CPU2PCI0_MEM_0_BASE 0x0058
#define MV64x60_CPU2PCI0_MEM_0_SIZE 0x0060
#define MV64x60_CPU2PCI0_MEM_0_REMAP_LO 0x00f8
#define MV64x60_CPU2PCI0_MEM_0_REMAP_HI 0x0320
#define MV64x60_CPU2PCI1_IO_BASE 0x0090
#define MV64x60_CPU2PCI1_IO_SIZE 0x0098
#define MV64x60_CPU2PCI1_IO_REMAP 0x0108
#define MV64x60_CPU2PCI1_MEM_0_BASE 0x00a0
#define MV64x60_CPU2PCI1_MEM_0_SIZE 0x00a8
#define MV64x60_CPU2PCI1_MEM_0_REMAP_LO 0x0110
#define MV64x60_CPU2PCI1_MEM_0_REMAP_HI 0x0340
struct mv64x60_mem_win {
u32 hi;
u32 lo;
u32 size;
};
struct mv64x60_pci_win {
u32 fcn;
u32 hi;
u32 lo;
u32 size;
};
/* PCI config access routines */
struct {
u32 addr;
u32 data;
} static mv64x60_pci_cfgio[2] = {
{ /* hose 0 */
.addr = 0xcf8,
.data = 0xcfc,
},
{ /* hose 1 */
.addr = 0xc78,
.data = 0xc7c,
}
};
u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset)
{
out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
(1 << 31) | (bus << 16) | (devfn << 8) | offset);
return in_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data));
}
void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset,
u32 val)
{
out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
(1 << 31) | (bus << 16) | (devfn << 8) | offset);
out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data), val);
}
/* I/O ctlr -> system memory setup */
static struct mv64x60_mem_win mv64x60_cpu2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_CPU2MEM_0_BASE,
.size = MV64x60_CPU2MEM_0_SIZE,
},
{
.lo = MV64x60_CPU2MEM_1_BASE,
.size = MV64x60_CPU2MEM_1_SIZE,
},
{
.lo = MV64x60_CPU2MEM_2_BASE,
.size = MV64x60_CPU2MEM_2_SIZE,
},
{
.lo = MV64x60_CPU2MEM_3_BASE,
.size = MV64x60_CPU2MEM_3_SIZE,
},
};
static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_ENET2MEM_0_BASE,
.size = MV64x60_ENET2MEM_0_SIZE,
},
{
.lo = MV64x60_ENET2MEM_1_BASE,
.size = MV64x60_ENET2MEM_1_SIZE,
},
{
.lo = MV64x60_ENET2MEM_2_BASE,
.size = MV64x60_ENET2MEM_2_SIZE,
},
{
.lo = MV64x60_ENET2MEM_3_BASE,
.size = MV64x60_ENET2MEM_3_SIZE,
},
};
static struct mv64x60_mem_win mv64x60_mpsc2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_MPSC2MEM_0_BASE,
.size = MV64x60_MPSC2MEM_0_SIZE,
},
{
.lo = MV64x60_MPSC2MEM_1_BASE,
.size = MV64x60_MPSC2MEM_1_SIZE,
},
{
.lo = MV64x60_MPSC2MEM_2_BASE,
.size = MV64x60_MPSC2MEM_2_SIZE,
},
{
.lo = MV64x60_MPSC2MEM_3_BASE,
.size = MV64x60_MPSC2MEM_3_SIZE,
},
};
static struct mv64x60_mem_win mv64x60_idma2mem[MV64x60_CPU2MEM_WINDOWS] = {
{
.lo = MV64x60_IDMA2MEM_0_BASE,
.size = MV64x60_IDMA2MEM_0_SIZE,
},
{
.lo = MV64x60_IDMA2MEM_1_BASE,
.size = MV64x60_IDMA2MEM_1_SIZE,
},
{
.lo = MV64x60_IDMA2MEM_2_BASE,
.size = MV64x60_IDMA2MEM_2_SIZE,
},
{
.lo = MV64x60_IDMA2MEM_3_BASE,
.size = MV64x60_IDMA2MEM_3_SIZE,
},
};
static u32 mv64x60_dram_selects[MV64x60_CPU2MEM_WINDOWS] = {0xe,0xd,0xb,0x7};
/*
* ENET, MPSC, and IDMA ctlrs on the MV64x60 have separate windows that
* must be set up so that the respective ctlr can access system memory.
* Configure them to be same as cpu->memory windows.
*/
void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
u8 is_coherent)
{
u32 i, base, size, enables, prot = 0, snoop_bits = 0;
/* Disable ctlr->mem windows */
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0x3f);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), 0xf);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0xff);
if (is_coherent)
snoop_bits = 0x2 << 12; /* Writeback */
enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
if (enables & (1 << i)) /* Set means disabled */
continue;
base = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].lo))
<< 16;
base |= snoop_bits | (mv64x60_dram_selects[i] << 8);
size = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].size))
<< 16;
prot |= (0x3 << (i << 1)); /* RW access */
out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].lo), base);
out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].size), size);
out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].lo), base);
out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].size), size);
out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].lo), base);
out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].size), size);
}
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_0), prot);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_1), prot);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_2), prot);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_0), prot);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_1), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_0), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_1), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_2), prot);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_3), prot);
/* Set mpsc->bridge's reg window to the bridge's internal registers. */
out_le32((u32 *)(bridge_base + MV64x60_MPSC2REGS_BASE),
(u32)bridge_pbase);
out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), enables);
out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), enables);
out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_BAR_ENABLE), enables);
}
/* PCI MEM -> system memory, et. al. setup */
static struct mv64x60_pci_win mv64x60_pci2mem[2] = {
{ /* hose 0 */
.fcn = 0,
.hi = 0x14,
.lo = 0x10,
.size = MV64x60_PCI02MEM_0_SIZE,
},
{ /* hose 1 */
.fcn = 0,
.hi = 0x94,
.lo = 0x90,
.size = MV64x60_PCI12MEM_0_SIZE,
},
};
static struct
mv64x60_mem_win mv64x60_pci_acc[2][MV64x60_PCI_ACC_CNTL_WINDOWS] = {
{ /* hose 0 */
{
.hi = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_0_SIZE,
},
{
.hi = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_1_SIZE,
},
{
.hi = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_2_SIZE,
},
{
.hi = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
.lo = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
.size = MV64x60_PCI0_ACC_CNTL_3_SIZE,
},
},
{ /* hose 1 */
{
.hi = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_0_SIZE,
},
{
.hi = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_1_SIZE,
},
{
.hi = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_2_SIZE,
},
{
.hi = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
.lo = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
.size = MV64x60_PCI1_ACC_CNTL_3_SIZE,
},
},
};
static struct mv64x60_mem_win mv64x60_pci2reg[2] = {
{
.hi = 0x24,
.lo = 0x20,
.size = 0,
},
{
.hi = 0xa4,
.lo = 0xa0,
.size = 0,
},
};
/* Only need to use 1 window (per hose) to get access to all of system memory */
void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
u8 bus, u32 mem_size, u32 acc_bits)
{
u32 i, offset, bar_enable, enables;
/* Disable all windows but PCI MEM -> Bridge's regs window */
enables = ~(1 << 9);
bar_enable = hose ? MV64x60_PCI1_BAR_ENABLE : MV64x60_PCI0_BAR_ENABLE;
out_le32((u32 *)(bridge_base + bar_enable), enables);
for (i=0; i<MV64x60_PCI_ACC_CNTL_WINDOWS; i++)
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][i].lo), 0);
/* If mem_size is 0, leave windows disabled */
if (mem_size == 0)
return;
/* Cause automatic updates of PCI remap regs */
offset = hose ?
MV64x60_PCI1_PCI_DECODE_CNTL : MV64x60_PCI0_PCI_DECODE_CNTL;
i = in_le32((u32 *)(bridge_base + offset));
out_le32((u32 *)(bridge_base + offset), i & ~0x1);
mem_size = (mem_size - 1) & 0xfffff000;
/* Map PCI MEM addr 0 -> System Mem addr 0 */
mv64x60_cfg_write(bridge_base, hose, bus,
PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
mv64x60_pci2mem[hose].hi, 0);
mv64x60_cfg_write(bridge_base, hose, bus,
PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
mv64x60_pci2mem[hose].lo, 0);
out_le32((u32 *)(bridge_base + mv64x60_pci2mem[hose].size),mem_size);
acc_bits |= MV64x60_PCI_ACC_CNTL_ENABLE;
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].hi), 0);
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].lo), acc_bits);
out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].size),mem_size);
/* Set PCI MEM->bridge's reg window to where they are in CPU mem map */
i = (u32)bridge_base;
i &= 0xffff0000;
i |= (0x2 << 1);
mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
mv64x60_pci2reg[hose].hi, 0);
mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
mv64x60_pci2reg[hose].lo, i);
enables &= ~0x1; /* Enable PCI MEM -> System Mem window 0 */
out_le32((u32 *)(bridge_base + bar_enable), enables);
}
/* CPU -> PCI I/O & MEM setup */
struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2] = {
{ /* hose 0 */
.lo = MV64x60_CPU2PCI0_IO_BASE,
.size = MV64x60_CPU2PCI0_IO_SIZE,
.remap_hi = 0,
.remap_lo = MV64x60_CPU2PCI0_IO_REMAP,
},
{ /* hose 1 */
.lo = MV64x60_CPU2PCI1_IO_BASE,
.size = MV64x60_CPU2PCI1_IO_SIZE,
.remap_hi = 0,
.remap_lo = MV64x60_CPU2PCI1_IO_REMAP,
},
};
struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2] = {
{ /* hose 0 */
.lo = MV64x60_CPU2PCI0_MEM_0_BASE,
.size = MV64x60_CPU2PCI0_MEM_0_SIZE,
.remap_hi = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
.remap_lo = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
},
{ /* hose 1 */
.lo = MV64x60_CPU2PCI1_MEM_0_BASE,
.size = MV64x60_CPU2PCI1_MEM_0_SIZE,
.remap_hi = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
.remap_lo = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
},
};
/* Only need to set up 1 window to pci mem space */
void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
u32 pci_base_lo, u32 cpu_base, u32 size,
struct mv64x60_cpu2pci_win *offset_tbl)
{
cpu_base >>= 16;
cpu_base |= MV64x60_CPU2PCI_SWAP_NONE;
out_le32((u32 *)(bridge_base + offset_tbl[hose].lo), cpu_base);
if (offset_tbl[hose].remap_hi != 0)
out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_hi),
pci_base_hi);
out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_lo),
pci_base_lo >> 16);
size = (size - 1) >> 16;
out_le32((u32 *)(bridge_base + offset_tbl[hose].size), size);
}
/* Read mem ctlr to get the amount of mem in system */
u32 mv64x60_get_mem_size(u8 *bridge_base)
{
u32 enables, i, v;
u32 mem = 0;
enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
if (!(enables & (1<<i))) {
v = in_le32((u32*)(bridge_base
+ mv64x60_cpu2mem[i].size));
v = ((v & 0xffff) + 1) << 16;
mem += v;
}
return mem;
}
/* Get physical address of bridge's registers */
u8 *mv64x60_get_bridge_pbase(void)
{
u32 v[2];
void *devp;
devp = finddevice("/mv64x60");
if (devp == NULL)
goto err_out;
if (getprop(devp, "reg", v, sizeof(v)) != sizeof(v))
goto err_out;
return (u8 *)v[0];
err_out:
return 0;
}
/* Get virtual address of bridge's registers */
u8 *mv64x60_get_bridge_base(void)
{
u32 v;
void *devp;
devp = finddevice("/mv64x60");
if (devp == NULL)
goto err_out;
if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
goto err_out;
return (u8 *)v;
err_out:
return 0;
}
u8 mv64x60_is_coherent(void)
{
u32 v;
void *devp;
devp = finddevice("/");
if (devp == NULL)
return 1; /* Assume coherency on */
if (getprop(devp, "coherency-off", &v, sizeof(v)) < 0)
return 1; /* Coherency on */
else
return 0;
}
/*
* Author: Mark A. Greer <source@mvista.com>
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef _PPC_BOOT_MV64x60_H_
#define _PPC_BOOT_MV64x60_H_
#define MV64x60_CPU_BAR_ENABLE 0x0278
#define MV64x60_PCI_ACC_CNTL_ENABLE (1<<0)
#define MV64x60_PCI_ACC_CNTL_REQ64 (1<<1)
#define MV64x60_PCI_ACC_CNTL_SNOOP_NONE 0x00000000
#define MV64x60_PCI_ACC_CNTL_SNOOP_WT 0x00000004
#define MV64x60_PCI_ACC_CNTL_SNOOP_WB 0x00000008
#define MV64x60_PCI_ACC_CNTL_SNOOP_MASK 0x0000000c
#define MV64x60_PCI_ACC_CNTL_ACCPROT (1<<4)
#define MV64x60_PCI_ACC_CNTL_WRPROT (1<<5)
#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE 0x00000000
#define MV64x60_PCI_ACC_CNTL_SWAP_NONE 0x00000040
#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE_WORD 0x00000080
#define MV64x60_PCI_ACC_CNTL_SWAP_WORD 0x000000c0
#define MV64x60_PCI_ACC_CNTL_SWAP_MASK 0x000000c0
#define MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES 0x00000000
#define MV64x60_PCI_ACC_CNTL_MBURST_64_BYTES 0x00000100
#define MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES 0x00000200
#define MV64x60_PCI_ACC_CNTL_MBURST_MASK 0x00000300
#define MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES 0x00000000
#define MV64x60_PCI_ACC_CNTL_RDSIZE_64_BYTES 0x00000400
#define MV64x60_PCI_ACC_CNTL_RDSIZE_128_BYTES 0x00000800
#define MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES 0x00000c00
#define MV64x60_PCI_ACC_CNTL_RDSIZE_MASK 0x00000c00
struct mv64x60_cpu2pci_win {
u32 lo;
u32 size;
u32 remap_hi;
u32 remap_lo;
};
extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2];
extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2];
u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
u8 offset);
void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
u8 offset, u32 val);
void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
u8 is_coherent);
void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
u8 bus, u32 mem_size, u32 acc_bits);
void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
u32 pci_base_lo, u32 cpu_base, u32 size,
struct mv64x60_cpu2pci_win *offset_tbl);
u32 mv64x60_get_mem_size(u8 *bridge_base);
u8 *mv64x60_get_bridge_pbase(void);
u8 *mv64x60_get_bridge_base(void);
u8 mv64x60_is_coherent(void);
int mv64x60_i2c_open(void);
int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
u32 count);
void mv64x60_i2c_close(void);
#endif /* _PPC_BOOT_MV64x60_H_ */
/*
* Bootloader version of the i2c driver for the MV64x60.
*
* Author: Dale Farnsworth <dfarnsworth@mvista.com>
* Maintained by: Mark A. Greer <mgreer@mvista.com>
*
* 2003, 2007 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program is
* licensed "as is" without any warranty of any kind, whether express or
* implied.
*/
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#include "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
#include "mv64x60.h"
extern void udelay(long);
/* Register defines */
#define MV64x60_I2C_REG_SLAVE_ADDR 0x00
#define MV64x60_I2C_REG_DATA 0x04
#define MV64x60_I2C_REG_CONTROL 0x08
#define MV64x60_I2C_REG_STATUS 0x0c
#define MV64x60_I2C_REG_BAUD 0x0c
#define MV64x60_I2C_REG_EXT_SLAVE_ADDR 0x10
#define MV64x60_I2C_REG_SOFT_RESET 0x1c
#define MV64x60_I2C_CONTROL_ACK 0x04
#define MV64x60_I2C_CONTROL_IFLG 0x08
#define MV64x60_I2C_CONTROL_STOP 0x10
#define MV64x60_I2C_CONTROL_START 0x20
#define MV64x60_I2C_CONTROL_TWSIEN 0x40
#define MV64x60_I2C_CONTROL_INTEN 0x80
#define MV64x60_I2C_STATUS_BUS_ERR 0x00
#define MV64x60_I2C_STATUS_MAST_START 0x08
#define MV64x60_I2C_STATUS_MAST_REPEAT_START 0x10
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
#define MV64x60_I2C_STATUS_MAST_WR_ACK 0x28
#define MV64x60_I2C_STATUS_MAST_WR_NO_ACK 0x30
#define MV64x60_I2C_STATUS_MAST_LOST_ARB 0x38
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
#define MV64x60_I2C_STATUS_MAST_RD_DATA_ACK 0x50
#define MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
#define MV64x60_I2C_STATUS_NO_STATUS 0xf8
static u8 *ctlr_base;
static int mv64x60_i2c_wait_for_status(int wanted)
{
int i;
int status;
for (i=0; i<1000; i++) {
udelay(10);
status = in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_STATUS))
& 0xff;
if (status == wanted)
return status;
}
return -status;
}
static int mv64x60_i2c_control(int control, int status)
{
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
return mv64x60_i2c_wait_for_status(status);
}
static int mv64x60_i2c_read_byte(int control, int status)
{
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
if (mv64x60_i2c_wait_for_status(status) < 0)
return -1;
return in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA)) & 0xff;
}
static int mv64x60_i2c_write_byte(int data, int control, int status)
{
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA), data & 0xff);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
return mv64x60_i2c_wait_for_status(status);
}
int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
u32 count)
{
int i;
int data;
int control;
int status;
if (ctlr_base == NULL)
return -1;
/* send reset */
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SOFT_RESET), 0);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SLAVE_ADDR), 0);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_EXT_SLAVE_ADDR), 0);
out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_BAUD), (4 << 3) | 0x4);
if (mv64x60_i2c_control(MV64x60_I2C_CONTROL_TWSIEN,
MV64x60_I2C_STATUS_NO_STATUS) < 0)
return -1;
/* send start */
control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_START;
if (mv64x60_i2c_control(control, status) < 0)
return -1;
/* select device for writing */
data = devaddr & ~0x1;
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK;
if (mv64x60_i2c_write_byte(data, control, status) < 0)
return -1;
/* send offset of data */
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_WR_ACK;
if (offset_size > 1) {
if (mv64x60_i2c_write_byte(offset >> 8, control, status) < 0)
return -1;
}
if (mv64x60_i2c_write_byte(offset, control, status) < 0)
return -1;
/* resend start */
control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_REPEAT_START;
if (mv64x60_i2c_control(control, status) < 0)
return -1;
/* select device for reading */
data = devaddr | 0x1;
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK;
if (mv64x60_i2c_write_byte(data, control, status) < 0)
return -1;
/* read all but last byte of data */
control = MV64x60_I2C_CONTROL_ACK | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_RD_DATA_ACK;
for (i=1; i<count; i++) {
data = mv64x60_i2c_read_byte(control, status);
if (data < 0) {
printf("errors on iteration %d\n", i);
return -1;
}
*buf++ = data;
}
/* read last byte of data */
control = MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK;
data = mv64x60_i2c_read_byte(control, status);
if (data < 0)
return -1;
*buf++ = data;
/* send stop */
control = MV64x60_I2C_CONTROL_STOP | MV64x60_I2C_CONTROL_TWSIEN;
status = MV64x60_I2C_STATUS_NO_STATUS;
if (mv64x60_i2c_control(control, status) < 0)
return -1;
return count;
}
int mv64x60_i2c_open(void)
{
u32 v;
void *devp;
devp = finddevice("/mv64x60/i2c");
if (devp == NULL)
goto err_out;
if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
goto err_out;
ctlr_base = (u8 *)v;
return 0;
err_out:
return -1;
}
void mv64x60_i2c_close(void)
{
ctlr_base = NULL;
}
......@@ -79,6 +79,7 @@ void start(void);
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
int mpsc_console_init(void *devp, struct serial_console_data *scdp);
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
extern void flush_cache(void *, unsigned long);
......
/*
* Motorola ECC prpmc280/f101 & prpmc2800/f101e platform code.
*
* Author: Mark A. Greer <mgreer@mvista.com>
*
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#include "elf.h"
#include "page.h"
#include "string.h"
#include "stdio.h"
#include "io.h"
#include "ops.h"
#include "gunzip_util.h"
#include "mv64x60.h"
extern char _end[];
extern char _vmlinux_start[], _vmlinux_end[];
extern char _dtb_start[], _dtb_end[];
extern void udelay(long delay);
#define KB 1024U
#define MB (KB*KB)
#define GB (KB*MB)
#define MHz (1000U*1000U)
#define GHz (1000U*MHz)
#define BOARD_MODEL "PrPMC2800"
#define BOARD_MODEL_MAX 32 /* max strlen(BOARD_MODEL) + 1 */
#define EEPROM2_ADDR 0xa4
#define EEPROM3_ADDR 0xa8
BSS_STACK(16*KB);
static u8 *bridge_base;
typedef enum {
BOARD_MODEL_PRPMC280,
BOARD_MODEL_PRPMC2800,
} prpmc2800_board_model;
typedef enum {
BRIDGE_TYPE_MV64360,
BRIDGE_TYPE_MV64362,
} prpmc2800_bridge_type;
struct prpmc2800_board_info {
prpmc2800_board_model model;
char variant;
prpmc2800_bridge_type bridge_type;
u8 subsys0;
u8 subsys1;
u8 vpd4;
u8 vpd4_mask;
u32 core_speed;
u32 mem_size;
u32 boot_flash;
u32 user_flash;
};
static struct prpmc2800_board_info prpmc2800_board_info[] = {
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'a',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x00,
.vpd4_mask = 0x0f,
.core_speed = 1*GHz,
.mem_size = 512*MB,
.boot_flash = 1*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'b',
.bridge_type = BRIDGE_TYPE_MV64362,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x01,
.vpd4_mask = 0x0f,
.core_speed = 1*GHz,
.mem_size = 512*MB,
.boot_flash = 0,
.user_flash = 0,
},
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'c',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x02,
.vpd4_mask = 0x0f,
.core_speed = 733*MHz,
.mem_size = 512*MB,
.boot_flash = 1*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'd',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x03,
.vpd4_mask = 0x0f,
.core_speed = 1*GHz,
.mem_size = 1*GB,
.boot_flash = 1*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'e',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x04,
.vpd4_mask = 0x0f,
.core_speed = 1*GHz,
.mem_size = 512*MB,
.boot_flash = 1*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'f',
.bridge_type = BRIDGE_TYPE_MV64362,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x05,
.vpd4_mask = 0x0f,
.core_speed = 733*MHz,
.mem_size = 128*MB,
.boot_flash = 1*MB,
.user_flash = 0,
},
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'g',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x06,
.vpd4_mask = 0x0f,
.core_speed = 1*GHz,
.mem_size = 256*MB,
.boot_flash = 1*MB,
.user_flash = 0,
},
{
.model = BOARD_MODEL_PRPMC280,
.variant = 'h',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xff,
.subsys1 = 0xff,
.vpd4 = 0x07,
.vpd4_mask = 0x0f,
.core_speed = 1*GHz,
.mem_size = 1*GB,
.boot_flash = 1*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'a',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xb2,
.subsys1 = 0x8c,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 1*GHz,
.mem_size = 512*MB,
.boot_flash = 2*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'b',
.bridge_type = BRIDGE_TYPE_MV64362,
.subsys0 = 0xb2,
.subsys1 = 0x8d,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 1*GHz,
.mem_size = 512*MB,
.boot_flash = 0,
.user_flash = 0,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'c',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xb2,
.subsys1 = 0x8e,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 733*MHz,
.mem_size = 512*MB,
.boot_flash = 2*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'd',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xb2,
.subsys1 = 0x8f,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 1*GHz,
.mem_size = 1*GB,
.boot_flash = 2*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'e',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xa2,
.subsys1 = 0x8a,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 1*GHz,
.mem_size = 512*MB,
.boot_flash = 2*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'f',
.bridge_type = BRIDGE_TYPE_MV64362,
.subsys0 = 0xa2,
.subsys1 = 0x8b,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 733*MHz,
.mem_size = 128*MB,
.boot_flash = 2*MB,
.user_flash = 0,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'g',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xa2,
.subsys1 = 0x8c,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 1*GHz,
.mem_size = 2*GB,
.boot_flash = 2*MB,
.user_flash = 64*MB,
},
{
.model = BOARD_MODEL_PRPMC2800,
.variant = 'h',
.bridge_type = BRIDGE_TYPE_MV64360,
.subsys0 = 0xa2,
.subsys1 = 0x8d,
.vpd4 = 0x00,
.vpd4_mask = 0x00,
.core_speed = 733*MHz,
.mem_size = 1*GB,
.boot_flash = 2*MB,
.user_flash = 64*MB,
},
};
static struct prpmc2800_board_info *prpmc2800_get_board_info(u8 *vpd)
{
struct prpmc2800_board_info *bip;
int i;
for (i=0,bip=prpmc2800_board_info; i<ARRAY_SIZE(prpmc2800_board_info);
i++,bip++)
if ((vpd[0] == bip->subsys0) && (vpd[1] == bip->subsys1)
&& ((vpd[4] & bip->vpd4_mask) == bip->vpd4))
return bip;
return NULL;
}
/* Get VPD from i2c eeprom 2, then match it to a board info entry */
static struct prpmc2800_board_info *prpmc2800_get_bip(void)
{
struct prpmc2800_board_info *bip;
u8 vpd[5];
int rc;
if (mv64x60_i2c_open())
fatal("Error: Can't open i2c device\n\r");
/* Get VPD from i2c eeprom-2 */
memset(vpd, 0, sizeof(vpd));
rc = mv64x60_i2c_read(EEPROM2_ADDR, vpd, 0x1fde, 2, sizeof(vpd));
if (rc < 0)
fatal("Error: Couldn't read eeprom2\n\r");
mv64x60_i2c_close();
/* Get board type & related info */
bip = prpmc2800_get_board_info(vpd);
if (bip == NULL) {
printf("Error: Unsupported board or corrupted VPD:\n\r");
printf(" 0x%x 0x%x 0x%x 0x%x 0x%x\n\r",
vpd[0], vpd[1], vpd[2], vpd[3], vpd[4]);
printf("Using device tree defaults...\n\r");
}
return bip;
}
static void prpmc2800_bridge_setup(u32 mem_size)
{
u32 i, v[12], enables, acc_bits;
u32 pci_base_hi, pci_base_lo, size, buf[2];
unsigned long cpu_base;
int rc;
void *devp;
u8 *bridge_pbase, is_coherent;
struct mv64x60_cpu2pci_win *tbl;
bridge_pbase = mv64x60_get_bridge_pbase();
is_coherent = mv64x60_is_coherent();
if (is_coherent)
acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
| MV64x60_PCI_ACC_CNTL_SWAP_NONE
| MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
| MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
else
acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
| MV64x60_PCI_ACC_CNTL_SWAP_NONE
| MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
| MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
mv64x60_config_pci_windows(bridge_base, bridge_pbase, 0, 0, mem_size,
acc_bits);
/* Get the cpu -> pci i/o & mem mappings from the device tree */
devp = finddevice("/mv64x60/pci@80000000");
if (devp == NULL)
fatal("Error: Missing /mv64x60/pci@80000000"
" device tree node\n\r");
rc = getprop(devp, "ranges", v, sizeof(v));
if (rc != sizeof(v))
fatal("Error: Can't find /mv64x60/pci@80000000/ranges"
" property\n\r");
/* Get the cpu -> pci i/o & mem mappings from the device tree */
devp = finddevice("/mv64x60");
if (devp == NULL)
fatal("Error: Missing /mv64x60 device tree node\n\r");
enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
enables |= 0x0007fe00; /* Disable all cpu->pci windows */
out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
for (i=0; i<12; i+=6) {
switch (v[i] & 0xff000000) {
case 0x01000000: /* PCI I/O Space */
tbl = mv64x60_cpu2pci_io;
break;
case 0x02000000: /* PCI MEM Space */
tbl = mv64x60_cpu2pci_mem;
break;
default:
continue;
}
pci_base_hi = v[i+1];
pci_base_lo = v[i+2];
cpu_base = v[i+3];
size = v[i+5];
buf[0] = cpu_base;
buf[1] = size;
if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base))
fatal("Error: Can't translate PCI address 0x%x\n\r",
(u32)cpu_base);
mv64x60_config_cpu2pci_window(bridge_base, 0, pci_base_hi,
pci_base_lo, cpu_base, size, tbl);
}
enables &= ~0x00000600; /* Enable cpu->pci0 i/o, cpu->pci0 mem0 */
out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
}
static void prpmc2800_fixups(void)
{
u32 v[2], l, mem_size;
int rc;
void *devp;
char model[BOARD_MODEL_MAX];
struct prpmc2800_board_info *bip;
bip = prpmc2800_get_bip(); /* Get board info based on VPD */
mem_size = (bip) ? bip->mem_size : mv64x60_get_mem_size(bridge_base);
prpmc2800_bridge_setup(mem_size); /* Do necessary bridge setup */
/* If the VPD doesn't match what we know about, just use the
* defaults already in the device tree.
*/
if (!bip)
return;
/* Know the board type so override device tree defaults */
/* Set /model appropriately */
devp = finddevice("/");
if (devp == NULL)
fatal("Error: Missing '/' device tree node\n\r");
memset(model, 0, BOARD_MODEL_MAX);
strncpy(model, BOARD_MODEL, BOARD_MODEL_MAX - 2);
l = strlen(model);
if (bip->model == BOARD_MODEL_PRPMC280)
l--;
model[l++] = bip->variant;
model[l++] = '\0';
setprop(devp, "model", model, l);
/* Set /cpus/PowerPC,7447/clock-frequency */
devp = finddevice("/cpus/PowerPC,7447");
if (devp == NULL)
fatal("Error: Missing proper /cpus device tree node\n\r");
v[0] = bip->core_speed;
setprop(devp, "clock-frequency", &v[0], sizeof(v[0]));
/* Set /memory/reg size */
devp = finddevice("/memory");
if (devp == NULL)
fatal("Error: Missing /memory device tree node\n\r");
v[0] = 0;
v[1] = bip->mem_size;
setprop(devp, "reg", v, sizeof(v));
/* Update /mv64x60/model, if this is a mv64362 */
if (bip->bridge_type == BRIDGE_TYPE_MV64362) {
devp = finddevice("/mv64x60");
if (devp == NULL)
fatal("Error: Missing /mv64x60 device tree node\n\r");
setprop(devp, "model", "mv64362", strlen("mv64362") + 1);
}
/* Set User FLASH size */
devp = finddevice("/mv64x60/flash@a0000000");
if (devp == NULL)
fatal("Error: Missing User FLASH device tree node\n\r");
rc = getprop(devp, "reg", v, sizeof(v));
if (rc != sizeof(v))
fatal("Error: Can't find User FLASH reg property\n\r");
v[1] = bip->user_flash;
setprop(devp, "reg", v, sizeof(v));
}
#define MV64x60_MPP_CNTL_0 0xf000
#define MV64x60_MPP_CNTL_2 0xf008
#define MV64x60_GPP_IO_CNTL 0xf100
#define MV64x60_GPP_LEVEL_CNTL 0xf110
#define MV64x60_GPP_VALUE_SET 0xf118
static void prpmc2800_reset(void)
{
u32 temp;
udelay(5000000);
if (bridge_base != 0) {
temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
temp &= 0xFFFF0FFF;
out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
temp |= 0x00000004;
out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
temp |= 0x00000004;
out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
temp &= 0xFFFF0FFF;
out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
temp |= 0x00080000;
out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
temp |= 0x00080000;
out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
0x00080004);
}
for (;;);
}
#define HEAP_SIZE (16*MB)
static struct gunzip_state gzstate;
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
struct elf_info ei;
char *heap_start, *dtb;
int dt_size = _dtb_end - _dtb_start;
void *vmlinuz_addr = _vmlinux_start;
unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start;
char elfheader[256];
if (dt_size <= 0) /* No fdt */
exit();
/*
* Start heap after end of the kernel (after decompressed to
* address 0) or the end of the zImage, whichever is higher.
* That's so things allocated by simple_alloc won't overwrite
* any part of the zImage and the kernel won't overwrite the dtb
* when decompressed & relocated.
*/
gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
if (!parse_elf32(elfheader, &ei))
exit();
heap_start = (char *)(ei.memsize + ei.elfoffset); /* end of kernel*/
heap_start = max(heap_start, (char *)_end); /* end of zImage */
if ((unsigned)simple_alloc_init(heap_start, HEAP_SIZE, 2*KB, 16)
> (128*MB))
exit();
/* Relocate dtb to safe area past end of zImage & kernel */
dtb = malloc(dt_size);
if (!dtb)
exit();
memmove(dtb, _dtb_start, dt_size);
if (ft_init(dtb, dt_size, 16))
exit();
bridge_base = mv64x60_get_bridge_base();
platform_ops.fixups = prpmc2800_fixups;
platform_ops.exit = prpmc2800_reset;
if (serial_console_init() < 0)
exit();
}
/* _zimage_start called very early--need to turn off external interrupts */
asm (" .globl _zimage_start\n\
_zimage_start:\n\
mfmsr 10\n\
rlwinm 10,10,0,~(1<<15) /* Clear MSR_EE */\n\
sync\n\
mtmsr 10\n\
isync\n\
b _zimage_start_lib\n\
");
......@@ -125,6 +125,8 @@ int serial_console_init(void)
if (!strcmp(compat, "ns16550"))
rc = ns16550_console_init(devp, &serial_cd);
else if (!strcmp(compat, "marvell,mpsc"))
rc = mpsc_console_init(devp, &serial_cd);
/* Add other serial console driver calls here */
......
此差异已折叠。
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.21
# Mon Apr 30 12:03:35 2007
# Fri May 11 10:16:27 2007
#
CONFIG_PPC64=y
CONFIG_64BIT=y
......@@ -40,6 +40,7 @@ CONFIG_PPC_FPU=y
# CONFIG_PPC_OF_PLATFORM_PCI is not set
CONFIG_ALTIVEC=y
CONFIG_PPC_STD_MMU=y
# CONFIG_PPC_MM_SLICES is not set
CONFIG_VIRT_CPU_ACCOUNTING=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
......@@ -67,6 +68,7 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
# CONFIG_CPUSETS is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
......@@ -87,12 +89,13 @@ CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
#
# Loadable module support
......@@ -213,6 +216,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_ARCH_MEMORY_PROBE=y
# CONFIG_PPC_HAS_HASH_64K is not set
# CONFIG_PPC_64K_PAGES is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PROC_DEVICETREE=y
......@@ -229,15 +233,12 @@ CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# PCI Hotplug Support
#
CONFIG_KERNEL_START=0xc000000000000000
#
......@@ -363,7 +364,9 @@ CONFIG_BT_HCIUSB_SCO=y
#
# CONFIG_CFG80211 is not set
CONFIG_WIRELESS_EXT=y
# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
# CONFIG_RFKILL is not set
#
# Device Drivers
......@@ -414,6 +417,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
#
# Misc devices
#
# CONFIG_BLINK is not set
#
# ATA/ATAPI/MFM/RLL support
......@@ -447,6 +451,7 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
......@@ -473,25 +478,7 @@ CONFIG_CHR_DEV_SG=m
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
#
#
# I2O device support
#
#
# Macintosh device drivers
#
# CONFIG_MAC_EMUMOUSEBTN is not set
# CONFIG_WINDFARM is not set
# CONFIG_MACINTOSH_DRIVERS is not set
#
# Network device support
......@@ -519,6 +506,7 @@ CONFIG_MII=m
#
# Ethernet (10000 Mbit)
#
CONFIG_MLX4_DEBUG=y
#
# Token Ring devices
......@@ -530,6 +518,25 @@ CONFIG_MII=m
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
CONFIG_USB_PEGASUS=m
# CONFIG_USB_RTL8150 is not set
CONFIG_USB_USBNET_MII=m
CONFIG_USB_USBNET=m
# CONFIG_USB_NET_CDCETHER is not set
# CONFIG_USB_NET_DM9601 is not set
# CONFIG_USB_NET_GL620A is not set
# CONFIG_USB_NET_NET1080 is not set
# CONFIG_USB_NET_PLUSB is not set
CONFIG_USB_NET_MCS7830=m
# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_CDC_SUBSET is not set
# CONFIG_USB_NET_ZAURUS is not set
#
# Wan interfaces
#
......@@ -575,6 +582,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
......@@ -609,15 +617,10 @@ CONFIG_LEGACY_PTY_COUNT=16
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set
......@@ -626,10 +629,6 @@ CONFIG_GEN_RTC=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
#
# I2C support
#
# CONFIG_I2C is not set
#
......@@ -642,12 +641,7 @@ CONFIG_GEN_RTC=y
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Hardware Monitoring support
#
# CONFIG_HWMON is not set
# CONFIG_HWMON_VID is not set
#
# Multifunction device drivers
......@@ -669,12 +663,23 @@ CONFIG_GEN_RTC=y
# Graphics support
#
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
# CONFIG_VGASTATE is not set
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
# CONFIG_FB_SYS_FOPS is not set
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
......@@ -702,10 +707,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
#
# Logo configuration
#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
......@@ -767,6 +768,20 @@ CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
#
# USB Input Devices
#
CONFIG_USB_HID=m
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
#
# USB support
#
......@@ -826,57 +841,11 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Input Devices
#
CONFIG_USB_HID=m
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
# CONFIG_USB_GTCO is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
CONFIG_USB_PEGASUS=m
# CONFIG_USB_RTL8150 is not set
CONFIG_USB_USBNET_MII=m
CONFIG_USB_USBNET=m
# CONFIG_USB_NET_CDCETHER is not set
# CONFIG_USB_NET_DM9601 is not set
# CONFIG_USB_NET_GL620A is not set
# CONFIG_USB_NET_NET1080 is not set
# CONFIG_USB_NET_PLUSB is not set
CONFIG_USB_NET_MCS7830=m
# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_CDC_SUBSET is not set
# CONFIG_USB_NET_ZAURUS is not set
CONFIG_USB_MON=y
#
......@@ -920,10 +889,6 @@ CONFIG_USB_MON=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
# MMC/SD Card support
#
# CONFIG_MMC is not set
#
......@@ -965,14 +930,6 @@ CONFIG_USB_MON=y
# DMA Devices
#
#
# Auxiliary Display support
#
#
# Virtualization
#
#
# File systems
#
......@@ -1071,6 +1028,7 @@ CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
......@@ -1148,11 +1106,13 @@ CONFIG_NLS_ISO8859_1=y
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
#
# Instrumentation Support
......@@ -1171,7 +1131,6 @@ CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
......@@ -1205,6 +1164,7 @@ CONFIG_PPC_EARLY_DEBUG=y
# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
# CONFIG_PPC_EARLY_DEBUG_44x is not set
#
# Security options
......@@ -1234,6 +1194,7 @@ CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
......
......@@ -24,7 +24,7 @@
/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
(ns) > 0)
(ns) >= 0)
static struct of_bus *of_match_bus(struct device_node *np);
static int __of_address_to_resource(struct device_node *dev,
......
......@@ -530,3 +530,44 @@ void __init setup_panic(void)
{
atomic_notifier_chain_register(&panic_notifier_list, &ppc_panic_block);
}
#ifdef CONFIG_CHECK_CACHE_COHERENCY
/*
* For platforms that have configurable cache-coherency. This function
* checks that the cache coherency setting of the kernel matches the setting
* left by the firmware, as indicated in the device tree. Since a mismatch
* will eventually result in DMA failures, we print * and error and call
* BUG() in that case.
*/
#ifdef CONFIG_NOT_COHERENT_CACHE
#define KERNEL_COHERENCY 0
#else
#define KERNEL_COHERENCY 1
#endif
static int __init check_cache_coherency(void)
{
struct device_node *np;
const void *prop;
int devtree_coherency;
np = of_find_node_by_path("/");
prop = of_get_property(np, "coherency-off", NULL);
of_node_put(np);
devtree_coherency = prop ? 0 : 1;
if (devtree_coherency != KERNEL_COHERENCY) {
printk(KERN_ERR
"kernel coherency:%s != device tree_coherency:%s\n",
KERNEL_COHERENCY ? "on" : "off",
devtree_coherency ? "on" : "off");
BUG();
}
return 0;
}
late_initcall(check_cache_coherency);
#endif /* CONFIG_CHECK_CACHE_COHERENCY */
......@@ -711,30 +711,15 @@ void wakeup_decrementer(void)
void __init smp_space_timers(unsigned int max_cpus)
{
int i;
unsigned long half = tb_ticks_per_jiffy / 2;
unsigned long offset = tb_ticks_per_jiffy / max_cpus;
u64 previous_tb = per_cpu(last_jiffy, boot_cpuid);
/* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
previous_tb -= tb_ticks_per_jiffy;
/*
* The stolen time calculation for POWER5 shared-processor LPAR
* systems works better if the two threads' timebase interrupts
* are staggered by half a jiffy with respect to each other.
*/
for_each_possible_cpu(i) {
if (i == boot_cpuid)
continue;
if (i == (boot_cpuid ^ 1))
per_cpu(last_jiffy, i) =
per_cpu(last_jiffy, boot_cpuid) - half;
else if (i & 1)
per_cpu(last_jiffy, i) =
per_cpu(last_jiffy, i ^ 1) + half;
else {
previous_tb += offset;
per_cpu(last_jiffy, i) = previous_tb;
}
per_cpu(last_jiffy, i) = previous_tb;
}
}
#endif
......
......@@ -351,7 +351,7 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot,
unsigned long hpte_r = hpte->r;
unsigned long hpte_v = hpte->v;
unsigned long avpn;
int i, size, shift, penc, avpnm_bits;
int i, size, shift, penc;
if (!(hpte_v & HPTE_V_LARGE))
size = MMU_PAGE_4K;
......@@ -395,7 +395,7 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot,
vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask;
break;
default:
avpn = vpi = psize = 0;
avpn = vpi = size = 0;
}
avpn |= (vpi << mmu_psize_defs[size].shift);
}
......
......@@ -31,6 +31,14 @@ config PPC_HOLLY
help
Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
Board with TSI108/9 bridge (Hickory/Holly)
config PPC_PRPMC2800
bool "Motorola-PrPMC2800"
select MV64X60
select NOT_COHERENT_CACHE
select WANT_DEVICE_TREE
help
This option enables support for the Motorola PrPMC2800 board
endchoice
config TSI108_BRIDGE
......@@ -46,6 +54,11 @@ config MPC10X_BRIDGE
select PPC_INDIRECT_PCI
default y
config MV64X60
bool
select PPC_INDIRECT_PCI
select CONFIG_CHECK_CACHE_COHERENCY
config MPC10X_OPENPIC
bool
depends on LINKSTATION
......
......@@ -4,3 +4,4 @@
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
obj-$(CONFIG_PPC_HOLLY) += holly.o
obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o
/*
* Board setup routines for the Motorola PrPMC2800
*
* Author: Dale Farnsworth <dale@farnsworth.org>
*
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/seq_file.h>
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/kexec.h>
#include <mm/mmu_decl.h>
#include <sysdev/mv64x60.h>
#define MV64x60_MPP_CNTL_0 0x0000
#define MV64x60_MPP_CNTL_2 0x0008
#define MV64x60_GPP_IO_CNTL 0x0000
#define MV64x60_GPP_LEVEL_CNTL 0x0010
#define MV64x60_GPP_VALUE_SET 0x0018
#define PLATFORM_NAME_MAX 32
static char prpmc2800_platform_name[PLATFORM_NAME_MAX];
static void __iomem *mv64x60_mpp_reg_base;
static void __iomem *mv64x60_gpp_reg_base;
static void __init prpmc2800_setup_arch(void)
{
struct device_node *np;
phys_addr_t paddr;
const unsigned int *reg;
const unsigned int *prop;
/*
* ioremap mpp and gpp registers in case they are later
* needed by prpmc2800_reset_board().
*/
np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-mpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-gpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
np = of_find_node_by_type(NULL, "cpu");
prop = of_get_property(np, "clock-frequency", NULL);
if (prop)
loops_per_jiffy = *prop / HZ;
of_node_put(np);
#ifdef CONFIG_PCI
mv64x60_pci_init();
#endif
printk("Motorola %s\n", prpmc2800_platform_name);
}
static void prpmc2800_reset_board(void)
{
u32 temp;
local_irq_disable();
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
temp &= 0xFFFF0FFF;
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
temp |= 0x00000004;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
temp |= 0x00000004;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
temp &= 0xFFFF0FFF;
out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
temp |= 0x00080000;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
temp |= 0x00080000;
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
}
static void prpmc2800_restart(char *cmd)
{
volatile ulong i = 10000000;
prpmc2800_reset_board();
while (i-- > 0);
panic("restart failed\n");
}
#ifdef CONFIG_NOT_COHERENT_CACHE
#define PPRPM2800_COHERENCY_SETTING "off"
#else
#define PPRPM2800_COHERENCY_SETTING "on"
#endif
void prpmc2800_show_cpuinfo(struct seq_file *m)
{
uint memsize = total_memory;
seq_printf(m, "Vendor\t\t: Motorola\n");
seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING);
}
/*
* Called very early, device-tree isn't unflattened
*/
static int __init prpmc2800_probe(void)
{
unsigned long root = of_get_flat_dt_root();
unsigned long len = PLATFORM_NAME_MAX;
void *m;
if (!of_flat_dt_is_compatible(root, "motorola,PrPMC2800"))
return 0;
/* Update ppc_md.name with name from dt */
m = of_get_flat_dt_prop(root, "model", &len);
if (m)
strncpy(prpmc2800_platform_name, m,
min((int)len, PLATFORM_NAME_MAX - 1));
return 1;
}
define_machine(prpmc2800){
.name = prpmc2800_platform_name,
.probe = prpmc2800_probe,
.setup_arch = prpmc2800_setup_arch,
.show_cpuinfo = prpmc2800_show_cpuinfo,
.init_IRQ = mv64x60_init_irq,
.get_irq = mv64x60_get_irq,
.restart = prpmc2800_restart,
.calibrate_decr = generic_calibrate_decr,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
.machine_crash_shutdown = default_machine_crash_shutdown,
#endif
};
......@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/irq.h>
#include <asm/machdep.h>
#include <asm/reg.h>
......
......@@ -99,6 +99,7 @@ static void ps3_panic(char *str)
while(1);
}
#ifdef CONFIG_FB_PS3
static void prealloc(struct ps3_prealloc *p)
{
if (!p->size)
......@@ -115,7 +116,6 @@ static void prealloc(struct ps3_prealloc *p)
p->address);
}
#ifdef CONFIG_FB_PS3
struct ps3_prealloc ps3fb_videomemory = {
.name = "ps3fb videomemory",
.size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
......
......@@ -118,9 +118,11 @@ static void __init ps3_smp_setup_cpu(int cpu)
DBG("%s:%d: (%d, %d) => virq %u\n",
__func__, __LINE__, cpu, i, virqs[i]);
result = request_irq(virqs[i], ipi_function_handler,
IRQF_DISABLED, names[i], (void*)(long)i);
request_irq(virqs[i], ipi_function_handler, IRQF_DISABLED,
names[i], (void*)(long)i);
if (result)
virqs[i] = NO_IRQ;
}
ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
......
......@@ -274,13 +274,13 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
int i;
#if defined(CONFIG_PS3_DYNAMIC_DMA)
BUG_ON("do");
return -EPERM;
#else
struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
int i;
for (i = 0; i < nents; i++, sg++) {
int result = ps3_dma_map(dev->d_region,
page_to_phys(sg->page) + sg->offset, sg->length,
......
......@@ -16,6 +16,8 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_FSL_PCIE) += fsl_pcie.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o
# contains only the suspend handler for time
obj-$(CONFIG_PM) += timer.o
......
#ifndef __MV64X60_H__
#define __MV64X60_H__
#include <linux/init.h>
extern void __init mv64x60_init_irq(void);
extern unsigned int mv64x60_get_irq(void);
extern void __init mv64x60_pci_init(void);
#endif /* __MV64X60_H__ */
/*
* Platform device setup for Marvell mv64360/mv64460 host bridges (Discovery)
*
* Author: Dale Farnsworth <dale@farnsworth.org>
*
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mv643xx.h>
#include <linux/platform_device.h>
#include <asm/prom.h>
/*
* These functions provide the necessary setup for the mv64x60 drivers.
* These drivers are unusual in that they work on both the MIPS and PowerPC
* architectures. Because of that, the drivers do not support the normal
* PowerPC of_platform_bus_type. They support platform_bus_type instead.
*/
/*
* Create MPSC platform devices
*/
static int __init mv64x60_mpsc_register_shared_pdev(struct device_node *np)
{
struct platform_device *pdev;
struct resource r[2];
struct mpsc_shared_pdata pdata;
const phandle *ph;
struct device_node *mpscrouting, *mpscintr;
int err;
ph = of_get_property(np, "mpscrouting", NULL);
mpscrouting = of_find_node_by_phandle(*ph);
if (!mpscrouting)
return -ENODEV;
err = of_address_to_resource(mpscrouting, 0, &r[0]);
of_node_put(mpscrouting);
if (err)
return err;
ph = of_get_property(np, "mpscintr", NULL);
mpscintr = of_find_node_by_phandle(*ph);
if (!mpscintr)
return -ENODEV;
err = of_address_to_resource(mpscintr, 0, &r[1]);
of_node_put(mpscintr);
if (err)
return err;
memset(&pdata, 0, sizeof(pdata));
pdev = platform_device_alloc(MPSC_SHARED_NAME, 0);
if (!pdev)
return -ENOMEM;
err = platform_device_add_resources(pdev, r, 2);
if (err)
goto error;
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
if (err)
goto error;
err = platform_device_add(pdev);
if (err)
goto error;
return 0;
error:
platform_device_put(pdev);
return err;
}
static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
{
struct resource r[5];
struct mpsc_pdata pdata;
struct platform_device *pdev;
const unsigned int *prop;
const phandle *ph;
struct device_node *sdma, *brg;
int err;
int port_number;
/* only register the shared platform device the first time through */
if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
return err;
memset(r, 0, sizeof(r));
err = of_address_to_resource(np, 0, &r[0]);
if (err)
return err;
of_irq_to_resource(np, 0, &r[4]);
ph = of_get_property(np, "sdma", NULL);
sdma = of_find_node_by_phandle(*ph);
if (!sdma)
return -ENODEV;
of_irq_to_resource(sdma, 0, &r[3]);
err = of_address_to_resource(sdma, 0, &r[1]);
of_node_put(sdma);
if (err)
return err;
ph = of_get_property(np, "brg", NULL);
brg = of_find_node_by_phandle(*ph);
if (!brg)
return -ENODEV;
err = of_address_to_resource(brg, 0, &r[2]);
of_node_put(brg);
if (err)
return err;
prop = of_get_property(np, "block-index", NULL);
if (!prop)
return -ENODEV;
port_number = *(int *)prop;
memset(&pdata, 0, sizeof(pdata));
pdata.cache_mgmt = 1; /* All current revs need this set */
prop = of_get_property(np, "max_idle", NULL);
if (prop)
pdata.max_idle = *prop;
prop = of_get_property(brg, "current-speed", NULL);
if (prop)
pdata.default_baud = *prop;
/* Default is 8 bits, no parity, no flow control */
pdata.default_bits = 8;
pdata.default_parity = 'n';
pdata.default_flow = 'n';
prop = of_get_property(np, "chr_1", NULL);
if (prop)
pdata.chr_1_val = *prop;
prop = of_get_property(np, "chr_2", NULL);
if (prop)
pdata.chr_2_val = *prop;
prop = of_get_property(np, "chr_10", NULL);
if (prop)
pdata.chr_10_val = *prop;
prop = of_get_property(np, "mpcr", NULL);
if (prop)
pdata.mpcr_val = *prop;
prop = of_get_property(brg, "bcr", NULL);
if (prop)
pdata.bcr_val = *prop;
pdata.brg_can_tune = 1; /* All current revs need this set */
prop = of_get_property(brg, "clock-src", NULL);
if (prop)
pdata.brg_clk_src = *prop;
prop = of_get_property(brg, "clock-frequency", NULL);
if (prop)
pdata.brg_clk_freq = *prop;
pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
if (!pdev)
return -ENOMEM;
err = platform_device_add_resources(pdev, r, 5);
if (err)
goto error;
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
if (err)
goto error;
err = platform_device_add(pdev);
if (err)
goto error;
return 0;
error:
platform_device_put(pdev);
return err;
}
/*
* Create mv64x60_eth platform devices
*/
static int __init eth_register_shared_pdev(struct device_node *np)
{
struct platform_device *pdev;
struct resource r[1];
int err;
np = of_get_parent(np);
if (!np)
return -ENODEV;
err = of_address_to_resource(np, 0, &r[0]);
of_node_put(np);
if (err)
return err;
pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, 0,
r, 1);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
return 0;
}
static int __init mv64x60_eth_device_setup(struct device_node *np, int id)
{
struct resource r[1];
struct mv643xx_eth_platform_data pdata;
struct platform_device *pdev;
struct device_node *phy;
const u8 *mac_addr;
const int *prop;
const phandle *ph;
int err;
/* only register the shared platform device the first time through */
if (id == 0 && (err = eth_register_shared_pdev(np)))
return err;;
memset(r, 0, sizeof(r));
of_irq_to_resource(np, 0, &r[0]);
memset(&pdata, 0, sizeof(pdata));
prop = of_get_property(np, "block-index", NULL);
if (!prop)
return -ENODEV;
pdata.port_number = *prop;
mac_addr = of_get_mac_address(np);
if (mac_addr)
memcpy(pdata.mac_addr, mac_addr, 6);
prop = of_get_property(np, "speed", NULL);
if (prop)
pdata.speed = *prop;
prop = of_get_property(np, "tx_queue_size", NULL);
if (prop)
pdata.tx_queue_size = *prop;
prop = of_get_property(np, "rx_queue_size", NULL);
if (prop)
pdata.rx_queue_size = *prop;
prop = of_get_property(np, "tx_sram_addr", NULL);
if (prop)
pdata.tx_sram_addr = *prop;
prop = of_get_property(np, "tx_sram_size", NULL);
if (prop)
pdata.tx_sram_size = *prop;
prop = of_get_property(np, "rx_sram_addr", NULL);
if (prop)
pdata.rx_sram_addr = *prop;
prop = of_get_property(np, "rx_sram_size", NULL);
if (prop)
pdata.rx_sram_size = *prop;
ph = of_get_property(np, "phy", NULL);
if (!ph)
return -ENODEV;
phy = of_find_node_by_phandle(*ph);
if (phy == NULL)
return -ENODEV;
prop = of_get_property(phy, "reg", NULL);
if (prop) {
pdata.force_phy_addr = 1;
pdata.phy_addr = *prop;
}
of_node_put(phy);
pdev = platform_device_alloc(MV643XX_ETH_NAME, pdata.port_number);
if (!pdev)
return -ENOMEM;
err = platform_device_add_resources(pdev, r, 1);
if (err)
goto error;
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
if (err)
goto error;
err = platform_device_add(pdev);
if (err)
goto error;
return 0;
error:
platform_device_put(pdev);
return err;
}
/*
* Create mv64x60_i2c platform devices
*/
static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
{
struct resource r[2];
struct platform_device *pdev;
struct mv64xxx_i2c_pdata pdata;
const unsigned int *prop;
int err;
memset(r, 0, sizeof(r));
err = of_address_to_resource(np, 0, &r[0]);
if (err)
return err;
of_irq_to_resource(np, 0, &r[1]);
memset(&pdata, 0, sizeof(pdata));
prop = of_get_property(np, "freq_m", NULL);
if (!prop)
return -ENODEV;
pdata.freq_m = *prop;
prop = of_get_property(np, "freq_n", NULL);
if (!prop)
return -ENODEV;
pdata.freq_n = *prop;
prop = of_get_property(np, "timeout", NULL);
if (prop)
pdata.timeout = *prop;
else
pdata.timeout = 1000; /* 1 second */
prop = of_get_property(np, "retries", NULL);
if (prop)
pdata.retries = *prop;
else
pdata.retries = 1;
pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
if (!pdev)
return -ENOMEM;
err = platform_device_add_resources(pdev, r, 2);
if (err)
goto error;
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
if (err)
goto error;
err = platform_device_add(pdev);
if (err)
goto error;
return 0;
error:
platform_device_put(pdev);
return err;
}
static int __init mv64x60_device_setup(void)
{
struct device_node *np = NULL;
int id;
int err;
for (id = 0;
(np = of_find_compatible_node(np, "serial", "marvell,mpsc")); id++)
if ((err = mv64x60_mpsc_device_setup(np, id)))
goto error;
for (id = 0;
(np = of_find_compatible_node(np, "network",
"marvell,mv64x60-eth"));
id++)
if ((err = mv64x60_eth_device_setup(np, id)))
goto error;
for (id = 0;
(np = of_find_compatible_node(np, "i2c", "marvell,mv64x60-i2c"));
id++)
if ((err = mv64x60_i2c_device_setup(np, id)))
goto error;
return 0;
error:
of_node_put(np);
return err;
}
arch_initcall(mv64x60_device_setup);
/*
* PCI bus setup for Marvell mv64360/mv64460 host bridges (Discovery)
*
* Author: Dale Farnsworth <dale@farnsworth.org>
*
* 2007 (c) MontaVista, Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#define PCI_HEADER_TYPE_INVALID 0x7f /* Invalid PCI header type */
#ifdef CONFIG_SYSFS
/* 32-bit hex or dec stringified number + '\n' */
#define MV64X60_VAL_LEN_MAX 11
#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
size_t count)
{
struct pci_dev *phb;
u32 v;
if (off > 0)
return 0;
if (count < MV64X60_VAL_LEN_MAX)
return -EINVAL;
phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
if (!phb)
return -ENODEV;
pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
pci_dev_put(phb);
return sprintf(buf, "0x%08x\n", v);
}
static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, char *buf, loff_t off,
size_t count)
{
struct pci_dev *phb;
u32 v;
if (off > 0)
return 0;
if (count <= 0)
return -EINVAL;
if (sscanf(buf, "%i", &v) != 1)
return -EINVAL;
phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
if (!phb)
return -ENODEV;
pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
pci_dev_put(phb);
return count;
}
static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
.attr = {
.name = "hs_reg",
.mode = S_IRUGO | S_IWUSR,
.owner = THIS_MODULE,
},
.size = MV64X60_VAL_LEN_MAX,
.read = mv64x60_hs_reg_read,
.write = mv64x60_hs_reg_write,
};
static int __init mv64x60_sysfs_init(void)
{
struct device_node *np;
struct platform_device *pdev;
const unsigned int *prop;
np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60");
if (!np)
return 0;
prop = of_get_property(np, "hs_reg_valid", NULL);
of_node_put(np);
pdev = platform_device_register_simple("marvell,mv64x60", 0, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
return sysfs_create_bin_file(&pdev->dev.kobj, &mv64x60_hs_reg_attr);
}
subsys_initcall(mv64x60_sysfs_init);
#endif /* CONFIG_SYSFS */
static void __init mv64x60_pci_fixup_early(struct pci_dev *dev)
{
/*
* Set the host bridge hdr_type to an invalid value so that
* pci_setup_device() will ignore the host bridge.
*/
dev->hdr_type = PCI_HEADER_TYPE_INVALID;
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360,
mv64x60_pci_fixup_early);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64460,
mv64x60_pci_fixup_early);
static int __init mv64x60_add_bridge(struct device_node *dev)
{
int len;
struct pci_controller *hose;
struct resource rsrc;
const int *bus_range;
int primary;
memset(&rsrc, 0, sizeof(rsrc));
/* Fetch host bridge registers address */
if (of_address_to_resource(dev, 0, &rsrc)) {
printk(KERN_ERR "No PCI reg property in device tree\n");
return -ENODEV;
}
/* Get bus range if any */
bus_range = of_get_property(dev, "bus-range", &len);
if (bus_range == NULL || len < 2 * sizeof(int))
printk(KERN_WARNING "Can't get bus-range for %s, assume"
" bus 0\n", dev->full_name);
hose = pcibios_alloc_controller();
if (!hose)
return -ENOMEM;
hose->arch_data = dev;
hose->set_cfg_type = 1;
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
setup_indirect_pci(hose, rsrc.start, rsrc.start + 4);
hose->bus_offset = hose->first_busno;
printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. "
"Firmware bus number: %d->%d\n",
(unsigned long long)rsrc.start, hose->first_busno,
hose->last_busno);
/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
primary = (hose->first_busno == 0);
pci_process_bridge_OF_ranges(hose, dev, primary);
return 0;
}
void __init mv64x60_pci_init(void)
{
struct device_node *np = NULL;
while ((np = of_find_compatible_node(np, "pci", "marvell,mv64x60-pci")))
mv64x60_add_bridge(np);
}
此差异已折叠。
......@@ -3,7 +3,7 @@
*
* Based on drivers/char/serial_amba.c, by ARM Ltd.
*
* Copyright 2001 IBM Crop.
* Copyright 2001 IBM Corp.
* Author: IBM China Research Lab
* Yudong Yang <yangyud@cn.ibm.com>
* Yi Ge <geyi@cn.ibm.com>
......@@ -155,16 +155,16 @@
/* serial port transmit command register */
#define _TxCR_ET_MASK 0x80 /* transmiter enable mask */
#define _TxCR_ET_MASK 0x80 /* transmitter enable mask */
#define _TxCR_DME_MASK 0x60 /* dma mode mask */
#define _TxCR_TIE_MASK 0x10 /* empty interrupt enable mask */
#define _TxCR_EIE_MASK 0x08 /* error interrupt enable mask */
#define _TxCR_SPE_MASK 0x04 /* stop/pause mask */
#define _TxCR_TB_MASK 0x02 /* transmit break mask */
#define _TxCR_ET_ENABLE _TxCR_ET_MASK /* transmiter enabled */
#define _TxCR_DME_DISABLE 0x00 /* transmiter disabled, TBR intr disabled */
#define _TxCR_DME_TBR 0x20 /* transmiter disabled, TBR intr enabled */
#define _TxCR_ET_ENABLE _TxCR_ET_MASK /* transmitter enabled */
#define _TxCR_DME_DISABLE 0x00 /* transmitter disabled, TBR intr disabled */
#define _TxCR_DME_TBR 0x20 /* transmitter disabled, TBR intr enabled */
#define _TxCR_DME_CHAN_2 0x40 /* dma enabled, destination chann 2 */
#define _TxCR_DME_CHAN_3 0x60 /* dma enabled, destination chann 3 */
......
......@@ -144,7 +144,7 @@ m8xx_cpm_reset(void)
/* Set SDMA Bus Request priority 5.
* On 860T, this also enables FEC priority 6. I am not sure
* this is what we realy want for some applications, but the
* this is what we really want for some applications, but the
* manual recommends it.
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
*/
......
......@@ -1878,7 +1878,7 @@ fec_restart(struct net_device *dev, int duplex)
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
/* ...and the same for transmmit.
/* ...and the same for transmit.
*/
bdp = fep->tx_bd_base;
for (i=0; i<TX_RING_SIZE; i++) {
......
......@@ -518,7 +518,7 @@ setTextRegs(struct VgaRegs *svp)
outb(0x3c6, 0xff); /* MASK */
for ( i = 0; i < 0x10; i++)
writeAttr(i, AC[i], 0); /* pallete */
writeAttr(i, AC[i], 0); /* palette */
writeAttr(0x10, 0x0c, 0); /* text mode */
writeAttr(0x11, 0x00, 0); /* overscan color (border) */
writeAttr(0x12, 0x0f, 0); /* plane enable */
......
/* Minimal serial functions needed to send messages out the serial
* port on the MBX console.
*
* The MBX uxes SMC1 for the serial port. We reset the port and use
* The MBX uses SMC1 for the serial port. We reset the port and use
* only the first BD that EPPC-Bug set up as a character FIFO.
*
* Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
......
......@@ -136,7 +136,7 @@ load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *b
/*
* We link ourself to an arbitrary low address. When we run, we
* relocate outself to that address. __image_being points to
* relocate ourself to that address. __image_being points to
* the part of the image where the zImage is. -- Tom
*/
zimage_start = (char *)(unsigned long)(&__image_begin);
......
......@@ -33,7 +33,7 @@ static struct mpc52xx_psc __iomem *psc =
* rtc. We read the decrementer change during one rtc tick
* and multiply by 4 to get the system bus clock frequency. Since a
* rtc tick is one seconds, and that's pretty long, we change the rtc
* dividers temporarly to set them 64x faster ;)
* dividers temporarily to set them 64x faster ;)
*/
static int
mpc52xx_ipbfreq(void)
......
......@@ -338,7 +338,7 @@ serial_tstc(unsigned long com_port)
rdp = &rd[com_port][cur_rd[com_port]];
/* Go thru rcv desc's until empty looking for one with data (no error)*/
/* Go through rcv descs until empty looking for one with data (no error)*/
while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) &&
(loop_count++ < RX_NUM_DESC)) {
......
......@@ -88,7 +88,7 @@
/*----------------------------------------------------------------------------+
| STB tasks, task stack sizes, and task priorities. The actual task priority
| is 1 more than the specified number since priority 0 is reserved (system
| internaly adds 1 to supplied priority number).
| internally adds 1 to supplied priority number).
+----------------------------------------------------------------------------*/
#define STB_IDLE_TASK_SS (5* 1024)
#define STB_IDLE_TASK_PRIO 0
......
......@@ -577,7 +577,7 @@ void program_check_exception(struct pt_regs *regs)
* ESR_DST (!?) or 0. In the process of chasing this with the
* hardware people - not sure if it can happen on any illegal
* instruction or only on FP instructions, whether there is a
* pattern to occurences etc. -dgibson 31/Mar/2003 */
* pattern to occurrences etc. -dgibson 31/Mar/2003 */
if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
emulate_single_step(regs);
return;
......@@ -860,7 +860,7 @@ void SPEFloatingPointException(struct pt_regs *regs)
spefscr = current->thread.spefscr;
fpexc_mode = current->thread.fpexc_mode;
/* Hardware does not neccessarily set sticky
/* Hardware does not necessarily set sticky
* underflow/overflow/invalid flags */
if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
code = FPE_FLTOVF;
......
......@@ -48,7 +48,7 @@
#include "mmu_decl.h"
#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
/* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */
#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - KERNELBASE))
#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
#endif
......
......@@ -197,7 +197,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
/* end work arround */
/* end workaround */
#ifdef DEBUG
printk("PCI bridge regs after fixup \n");
......
......@@ -130,7 +130,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
/* end work arround */
/* end workaround */
#endif
}
......
......@@ -80,7 +80,7 @@
#define DCRN_CPMFR_BASE 0x0B9
#define DCRN_CPMER_BASE 0x0B8
/* CPM Clocking & Power Mangement defines */
/* CPM Clocking & Power Management defines */
#define IBM_CPM_PCI 0x40000000 /* PCI */
#define IBM_CPM_EMAC2 0x20000000 /* EMAC 2 MII */
#define IBM_CPM_EMAC3 0x04000000 /* EMAC 3 MII */
......
......@@ -225,7 +225,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
/* end work arround */
/* end workaround */
#ifdef DEBUG
printk("PCI bridge regs after fixup \n");
......
......@@ -200,7 +200,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
/* end work arround */
/* end work around */
#ifdef DEBUG
printk("PCI bridge regs after fixup \n");
......
......@@ -473,7 +473,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
* are non-zero, then we should use the board info from the bd_t
* structure and the cmdline pointed to by r6 instead of the
* information from birecs, if any. Otherwise, use the information
* from birecs as discovered by the preceeding call to
* from birecs as discovered by the preceding call to
* parse_bootinfo(). This rule should work with both PPCBoot, which
* uses a bd_t board info structure, and the kernel boot wrapper,
* which uses birecs.
......
......@@ -144,7 +144,7 @@ static void __init hdpu_setup_peripherals(void)
/* Enable pipelining */
mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1 << 13));
/* Enable Snoop Pipelineing */
/* Enable Snoop Pipelining */
mv64x60_set_bits(&bh, MV64360_D_UNIT_CONTROL_HIGH, (1 << 24));
/*
......
......@@ -880,7 +880,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
* are non-zero, then we should use the board info from the bd_t
* structure and the cmdline pointed to by r6 instead of the
* information from birecs, if any. Otherwise, use the information
* from birecs as discovered by the preceeding call to
* from birecs as discovered by the preceding call to
* parse_bootinfo(). This rule should work with both PPCBoot, which
* uses a bd_t board info structure, and the kernel boot wrapper,
* which uses birecs.
......
......@@ -37,7 +37,7 @@ typedef struct bd_info {
/* Memory map for the MBX as configured by EPPC-Bug. We could reprogram
* The SIU and PCI bridge, and try to use larger MMU pages, but the
* performance gain is not measureable and it certainly complicates the
* performance gain is not measurable and it certainly complicates the
* generic MMU model.
*
* In a effort to minimize memory usage for embedded applications, any
......
......@@ -69,7 +69,7 @@
#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
/* All UART IRQ's are wire-OR'd to one MPIC IRQ */
/* All UART IRQs are wire-OR'd to one MPIC IRQ */
#define STD_SERIAL_PORT_DFNS \
{ 0, BASE_BAUD, MVME5100_SERIAL_1, \
MVME5100_SERIAL_IRQ, \
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册