Commit 2a2c74b2efcb1a0ca3fdcb5fbb96ad8de6a29177
Committed by
Benjamin Herrenschmidt
1 parent
6b11930f72
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
IBM Akebono: Add the Akebono platform
This patch adds support for the IBM Akebono board. Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Showing 11 changed files with 901 additions and 26 deletions Inline Diff
- Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
- arch/powerpc/boot/Makefile
- arch/powerpc/boot/dcr.h
- arch/powerpc/boot/dts/akebono.dts
- arch/powerpc/boot/treeboot-akebono.c
- arch/powerpc/boot/wrapper
- arch/powerpc/configs/44x/akebono_defconfig
- arch/powerpc/platforms/44x/Kconfig
- arch/powerpc/platforms/44x/Makefile
- arch/powerpc/platforms/44x/ppc476.c
- arch/powerpc/sysdev/ppc4xx_pci.c
Documentation/devicetree/bindings/powerpc/4xx/akebono.txt
File was created | 1 | ||
2 | IBM Akebono board device tree | ||
3 | ============================= | ||
4 | |||
5 | The IBM Akebono board is a development board for the PPC476GTR SoC. | ||
6 | |||
7 | 0) The root node | ||
8 | |||
9 | Required properties: | ||
10 | |||
11 | - model : "ibm,akebono". | ||
12 | - compatible : "ibm,akebono" , "ibm,476gtr". | ||
13 | |||
14 | 1.a) The Secure Digital Host Controller Interface (SDHCI) node | ||
15 | |||
16 | Represent the Secure Digital Host Controller Interfaces. | ||
17 | |||
18 | Required properties: | ||
19 | |||
20 | - compatible : should be "ibm,476gtr-sdhci","generic-sdhci". | ||
21 | - reg : should contain the SDHCI registers location and length. | ||
22 | - interrupt-parent : a phandle for the interrupt controller. | ||
23 | - interrupts : should contain the SDHCI interrupt. | ||
24 | |||
25 | 1.b) The Advanced Host Controller Interface (AHCI) SATA node | ||
26 | |||
27 | Represents the advanced host controller SATA interface. | ||
28 | |||
29 | Required properties: | ||
30 | |||
31 | - compatible : should be "ibm,476gtr-ahci". | ||
32 | - reg : should contain the AHCI registers location and length. | ||
33 | - interrupt-parent : a phandle for the interrupt controller. | ||
34 | - interrupts : should contain the AHCI interrupt. | ||
35 | |||
36 | 1.c) The FPGA node | ||
37 | |||
38 | The Akebono board stores some board information such as the revision | ||
39 | number in an FPGA which is represented by this node. | ||
40 | |||
41 | Required properties: | ||
42 | |||
43 | - compatible : should be "ibm,akebono-fpga". | ||
44 | - reg : should contain the FPGA registers location and length. | ||
45 | |||
46 | 1.d) The AVR node | ||
47 | |||
48 | The Akebono board has an Atmel AVR microprocessor attached to the I2C | ||
49 | bus as a power controller for the board. | ||
50 | |||
51 | Required properties: | ||
52 | |||
53 | - compatible : should be "ibm,akebono-avr". | ||
54 | - reg : should contain the I2C bus address for the AVR. | ||
55 |
arch/powerpc/boot/Makefile
1 | # Makefile for making ELF bootable images for booting on CHRP | 1 | # Makefile for making ELF bootable images for booting on CHRP |
2 | # using Open Firmware. | 2 | # using Open Firmware. |
3 | # | 3 | # |
4 | # Geert Uytterhoeven September 1997 | 4 | # Geert Uytterhoeven September 1997 |
5 | # | 5 | # |
6 | # Based on coffboot by Paul Mackerras | 6 | # Based on coffboot by Paul Mackerras |
7 | # Simplified for ppc64 by Todd Inglett | 7 | # Simplified for ppc64 by Todd Inglett |
8 | # | 8 | # |
9 | # NOTE: this code is built for 32 bit in ELF32 format even though | 9 | # NOTE: this code is built for 32 bit in ELF32 format even though |
10 | # it packages a 64 bit kernel. We do this to simplify the | 10 | # it packages a 64 bit kernel. We do this to simplify the |
11 | # bootloader and increase compatibility with OpenFirmware. | 11 | # bootloader and increase compatibility with OpenFirmware. |
12 | # | 12 | # |
13 | # To this end we need to define BOOTCC, etc, as the tools | 13 | # To this end we need to define BOOTCC, etc, as the tools |
14 | # needed to build the 32 bit image. That's normally the same | 14 | # needed to build the 32 bit image. That's normally the same |
15 | # compiler for the rest of the kernel, with the -m32 flag added. | 15 | # compiler for the rest of the kernel, with the -m32 flag added. |
16 | # To make it easier to setup a cross compiler, | 16 | # To make it easier to setup a cross compiler, |
17 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE | 17 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE |
18 | # in the toplevel makefile. | 18 | # in the toplevel makefile. |
19 | 19 | ||
20 | all: $(obj)/zImage | 20 | all: $(obj)/zImage |
21 | 21 | ||
22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ | 22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
23 | -fno-strict-aliasing -Os -msoft-float -pipe \ | 23 | -fno-strict-aliasing -Os -msoft-float -pipe \ |
24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ | 24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ |
25 | -isystem $(shell $(CROSS32CC) -print-file-name=include) | 25 | -isystem $(shell $(CROSS32CC) -print-file-name=include) |
26 | ifdef CONFIG_PPC64_BOOT_WRAPPER | 26 | ifdef CONFIG_PPC64_BOOT_WRAPPER |
27 | BOOTCFLAGS += -m64 | 27 | BOOTCFLAGS += -m64 |
28 | endif | 28 | endif |
29 | ifdef CONFIG_CPU_BIG_ENDIAN | 29 | ifdef CONFIG_CPU_BIG_ENDIAN |
30 | BOOTCFLAGS += -mbig-endian | 30 | BOOTCFLAGS += -mbig-endian |
31 | endif | 31 | endif |
32 | 32 | ||
33 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc | 33 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc |
34 | 34 | ||
35 | ifdef CONFIG_DEBUG_INFO | 35 | ifdef CONFIG_DEBUG_INFO |
36 | BOOTCFLAGS += -g | 36 | BOOTCFLAGS += -g |
37 | endif | 37 | endif |
38 | 38 | ||
39 | ifeq ($(call cc-option-yn, -fstack-protector),y) | 39 | ifeq ($(call cc-option-yn, -fstack-protector),y) |
40 | BOOTCFLAGS += -fno-stack-protector | 40 | BOOTCFLAGS += -fno-stack-protector |
41 | endif | 41 | endif |
42 | 42 | ||
43 | BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) | 43 | BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) |
44 | 44 | ||
45 | DTC_FLAGS ?= -p 1024 | 45 | DTC_FLAGS ?= -p 1024 |
46 | 46 | ||
47 | $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405 | 47 | $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405 |
48 | $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405 | 48 | $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405 |
49 | $(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405 | 49 | $(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405 |
50 | $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 | 50 | $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 |
51 | $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 | 51 | $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 |
52 | $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405 | 52 | $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405 |
53 | $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 | 53 | $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 |
54 | $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 | 54 | $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 |
55 | $(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405 | 55 | $(obj)/treeboot-currituck.o: BOOTCFLAGS += -mcpu=405 |
56 | $(obj)/treeboot-akebono.o: BOOTCFLAGS += -mcpu=405 | ||
56 | $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405 | 57 | $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405 |
57 | 58 | ||
58 | 59 | ||
59 | zlib := inffast.c inflate.c inftrees.c | 60 | zlib := inffast.c inflate.c inftrees.c |
60 | zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h | 61 | zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h |
61 | zliblinuxheader := zlib.h zconf.h zutil.h | 62 | zliblinuxheader := zlib.h zconf.h zutil.h |
62 | 63 | ||
63 | $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o): \ | 64 | $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o): \ |
64 | $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) | 65 | $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) |
65 | 66 | ||
66 | libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c | 67 | libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c |
67 | libfdtheader := fdt.h libfdt.h libfdt_internal.h | 68 | libfdtheader := fdt.h libfdt.h libfdt_internal.h |
68 | 69 | ||
69 | $(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \ | 70 | $(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \ |
70 | $(addprefix $(obj)/,$(libfdtheader)) | 71 | $(addprefix $(obj)/,$(libfdtheader)) |
71 | 72 | ||
72 | src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \ | 73 | src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \ |
73 | $(libfdt) libfdt-wrapper.c \ | 74 | $(libfdt) libfdt-wrapper.c \ |
74 | ns16550.c serial.c simple_alloc.c div64.S util.S \ | 75 | ns16550.c serial.c simple_alloc.c div64.S util.S \ |
75 | gunzip_util.c elf_util.c $(zlib) devtree.c stdlib.c \ | 76 | gunzip_util.c elf_util.c $(zlib) devtree.c stdlib.c \ |
76 | oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \ | 77 | oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \ |
77 | uartlite.c mpc52xx-psc.c | 78 | uartlite.c mpc52xx-psc.c |
78 | src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c | 79 | src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c |
79 | src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c | 80 | src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c |
80 | src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c | 81 | src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c |
81 | src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c | 82 | src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c |
82 | src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c | 83 | src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c |
83 | 84 | ||
84 | src-plat-y := of.c epapr.c | 85 | src-plat-y := of.c epapr.c |
85 | src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ | 86 | src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ |
86 | treeboot-walnut.c cuboot-acadia.c \ | 87 | treeboot-walnut.c cuboot-acadia.c \ |
87 | cuboot-kilauea.c simpleboot.c \ | 88 | cuboot-kilauea.c simpleboot.c \ |
88 | virtex405-head.S virtex.c | 89 | virtex405-head.S virtex.c |
89 | src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \ | 90 | src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \ |
90 | cuboot-bamboo.c cuboot-sam440ep.c \ | 91 | cuboot-bamboo.c cuboot-sam440ep.c \ |
91 | cuboot-sequoia.c cuboot-rainier.c \ | 92 | cuboot-sequoia.c cuboot-rainier.c \ |
92 | cuboot-taishan.c cuboot-katmai.c \ | 93 | cuboot-taishan.c cuboot-katmai.c \ |
93 | cuboot-warp.c cuboot-yosemite.c \ | 94 | cuboot-warp.c cuboot-yosemite.c \ |
94 | treeboot-iss4xx.c treeboot-currituck.c \ | 95 | treeboot-iss4xx.c treeboot-currituck.c \ |
96 | treeboot-akebono.c \ | ||
95 | simpleboot.c fixed-head.S virtex.c | 97 | simpleboot.c fixed-head.S virtex.c |
96 | src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c | 98 | src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c |
97 | src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c | 99 | src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c |
98 | src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S ep8248e.c cuboot-824x.c | 100 | src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S ep8248e.c cuboot-824x.c |
99 | src-plat-$(CONFIG_PPC_83xx) += cuboot-83xx.c fixed-head.S redboot-83xx.c | 101 | src-plat-$(CONFIG_PPC_83xx) += cuboot-83xx.c fixed-head.S redboot-83xx.c |
100 | src-plat-$(CONFIG_FSL_SOC_BOOKE) += cuboot-85xx.c cuboot-85xx-cpm2.c | 102 | src-plat-$(CONFIG_FSL_SOC_BOOKE) += cuboot-85xx.c cuboot-85xx-cpm2.c |
101 | src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \ | 103 | src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \ |
102 | cuboot-c2k.c gamecube-head.S \ | 104 | cuboot-c2k.c gamecube-head.S \ |
103 | gamecube.c wii-head.S wii.c holly.c \ | 105 | gamecube.c wii-head.S wii.c holly.c \ |
104 | fixed-head.S mvme5100.c | 106 | fixed-head.S mvme5100.c |
105 | src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c | 107 | src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c |
106 | src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c | 108 | src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c |
107 | src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c | 109 | src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c |
108 | src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S | 110 | src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S |
109 | src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S | 111 | src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S |
110 | src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S | 112 | src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S |
111 | src-plat-$(CONFIG_PPC_CELLEB) += pseries-head.S | 113 | src-plat-$(CONFIG_PPC_CELLEB) += pseries-head.S |
112 | src-plat-$(CONFIG_PPC_CELL_QPACE) += pseries-head.S | 114 | src-plat-$(CONFIG_PPC_CELL_QPACE) += pseries-head.S |
113 | 115 | ||
114 | src-wlib := $(sort $(src-wlib-y)) | 116 | src-wlib := $(sort $(src-wlib-y)) |
115 | src-plat := $(sort $(src-plat-y)) | 117 | src-plat := $(sort $(src-plat-y)) |
116 | src-boot := $(src-wlib) $(src-plat) empty.c | 118 | src-boot := $(src-wlib) $(src-plat) empty.c |
117 | 119 | ||
118 | src-boot := $(addprefix $(obj)/, $(src-boot)) | 120 | src-boot := $(addprefix $(obj)/, $(src-boot)) |
119 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) | 121 | obj-boot := $(addsuffix .o, $(basename $(src-boot))) |
120 | obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib)))) | 122 | obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib)))) |
121 | obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) | 123 | obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) |
122 | obj-plat: $(libfdt) | 124 | obj-plat: $(libfdt) |
123 | 125 | ||
124 | quiet_cmd_copy_zlib = COPY $@ | 126 | quiet_cmd_copy_zlib = COPY $@ |
125 | cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ | 127 | cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ |
126 | 128 | ||
127 | quiet_cmd_copy_zlibheader = COPY $@ | 129 | quiet_cmd_copy_zlibheader = COPY $@ |
128 | cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ | 130 | cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ |
129 | # stddef.h for NULL | 131 | # stddef.h for NULL |
130 | quiet_cmd_copy_zliblinuxheader = COPY $@ | 132 | quiet_cmd_copy_zliblinuxheader = COPY $@ |
131 | cmd_copy_zliblinuxheader = sed "s@<linux/string.h>@\"string.h\"@;s@<linux/kernel.h>@<stddef.h>@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ | 133 | cmd_copy_zliblinuxheader = sed "s@<linux/string.h>@\"string.h\"@;s@<linux/kernel.h>@<stddef.h>@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ |
132 | 134 | ||
133 | $(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% | 135 | $(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% |
134 | $(call cmd,copy_zlib) | 136 | $(call cmd,copy_zlib) |
135 | 137 | ||
136 | $(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/% | 138 | $(addprefix $(obj)/,$(zlibheader)): $(obj)/%: $(srctree)/lib/zlib_inflate/% |
137 | $(call cmd,copy_zlibheader) | 139 | $(call cmd,copy_zlibheader) |
138 | 140 | ||
139 | $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% | 141 | $(addprefix $(obj)/,$(zliblinuxheader)): $(obj)/%: $(srctree)/include/linux/% |
140 | $(call cmd,copy_zliblinuxheader) | 142 | $(call cmd,copy_zliblinuxheader) |
141 | 143 | ||
142 | quiet_cmd_copy_libfdt = COPY $@ | 144 | quiet_cmd_copy_libfdt = COPY $@ |
143 | cmd_copy_libfdt = cp $< $@ | 145 | cmd_copy_libfdt = cp $< $@ |
144 | 146 | ||
145 | $(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/% | 147 | $(addprefix $(obj)/,$(libfdt) $(libfdtheader)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/% |
146 | $(call cmd,copy_libfdt) | 148 | $(call cmd,copy_libfdt) |
147 | 149 | ||
148 | $(obj)/empty.c: | 150 | $(obj)/empty.c: |
149 | @touch $@ | 151 | @touch $@ |
150 | 152 | ||
151 | $(obj)/zImage.lds: $(obj)/%: $(srctree)/$(src)/%.S | 153 | $(obj)/zImage.lds: $(obj)/%: $(srctree)/$(src)/%.S |
152 | $(CROSS32CC) $(cpp_flags) -E -Wp,-MD,$(depfile) -P -Upowerpc \ | 154 | $(CROSS32CC) $(cpp_flags) -E -Wp,-MD,$(depfile) -P -Upowerpc \ |
153 | -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< | 155 | -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< |
154 | 156 | ||
155 | $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S | 157 | $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S |
156 | @cp $< $@ | 158 | @cp $< $@ |
157 | 159 | ||
158 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ | 160 | clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ |
159 | $(libfdt) $(libfdtheader) \ | 161 | $(libfdt) $(libfdtheader) \ |
160 | empty.c zImage.coff.lds zImage.ps3.lds zImage.lds | 162 | empty.c zImage.coff.lds zImage.ps3.lds zImage.lds |
161 | 163 | ||
162 | quiet_cmd_bootcc = BOOTCC $@ | 164 | quiet_cmd_bootcc = BOOTCC $@ |
163 | cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< | 165 | cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< |
164 | 166 | ||
165 | quiet_cmd_bootas = BOOTAS $@ | 167 | quiet_cmd_bootas = BOOTAS $@ |
166 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< | 168 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< |
167 | 169 | ||
168 | quiet_cmd_bootar = BOOTAR $@ | 170 | quiet_cmd_bootar = BOOTAR $@ |
169 | cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@ | 171 | cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@ |
170 | 172 | ||
171 | $(obj-libfdt): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c FORCE | 173 | $(obj-libfdt): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c FORCE |
172 | $(call if_changed_dep,bootcc) | 174 | $(call if_changed_dep,bootcc) |
173 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE | 175 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE |
174 | $(Q)mkdir -p $(dir $@) | 176 | $(Q)mkdir -p $(dir $@) |
175 | $(call if_changed_dep,bootcc) | 177 | $(call if_changed_dep,bootcc) |
176 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE | 178 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE |
177 | $(Q)mkdir -p $(dir $@) | 179 | $(Q)mkdir -p $(dir $@) |
178 | $(call if_changed_dep,bootas) | 180 | $(call if_changed_dep,bootas) |
179 | 181 | ||
180 | $(obj)/wrapper.a: $(obj-wlib) FORCE | 182 | $(obj)/wrapper.a: $(obj-wlib) FORCE |
181 | $(call if_changed,bootar) | 183 | $(call if_changed,bootar) |
182 | 184 | ||
183 | hostprogs-y := addnote hack-coff mktree | 185 | hostprogs-y := addnote hack-coff mktree |
184 | 186 | ||
185 | targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) | 187 | targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) |
186 | extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ | 188 | extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ |
187 | $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds | 189 | $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds |
188 | 190 | ||
189 | dtstree := $(srctree)/$(src)/dts | 191 | dtstree := $(srctree)/$(src)/dts |
190 | 192 | ||
191 | wrapper :=$(srctree)/$(src)/wrapper | 193 | wrapper :=$(srctree)/$(src)/wrapper |
192 | wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ | 194 | wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ |
193 | $(wrapper) FORCE | 195 | $(wrapper) FORCE |
194 | 196 | ||
195 | ############# | 197 | ############# |
196 | # Bits for building various flavours of zImage | 198 | # Bits for building various flavours of zImage |
197 | 199 | ||
198 | ifneq ($(CROSS32_COMPILE),) | 200 | ifneq ($(CROSS32_COMPILE),) |
199 | CROSSWRAP := -C "$(CROSS32_COMPILE)" | 201 | CROSSWRAP := -C "$(CROSS32_COMPILE)" |
200 | else | 202 | else |
201 | ifneq ($(CROSS_COMPILE),) | 203 | ifneq ($(CROSS_COMPILE),) |
202 | CROSSWRAP := -C "$(CROSS_COMPILE)" | 204 | CROSSWRAP := -C "$(CROSS_COMPILE)" |
203 | endif | 205 | endif |
204 | endif | 206 | endif |
205 | 207 | ||
206 | # args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd | 208 | # args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd |
207 | quiet_cmd_wrap = WRAP $@ | 209 | quiet_cmd_wrap = WRAP $@ |
208 | cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ | 210 | cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ |
209 | $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux | 211 | $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux |
210 | 212 | ||
211 | image-$(CONFIG_PPC_PSERIES) += zImage.pseries | 213 | image-$(CONFIG_PPC_PSERIES) += zImage.pseries |
212 | image-$(CONFIG_PPC_POWERNV) += zImage.pseries | 214 | image-$(CONFIG_PPC_POWERNV) += zImage.pseries |
213 | image-$(CONFIG_PPC_MAPLE) += zImage.maple | 215 | image-$(CONFIG_PPC_MAPLE) += zImage.maple |
214 | image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries | 216 | image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries |
215 | image-$(CONFIG_PPC_PS3) += dtbImage.ps3 | 217 | image-$(CONFIG_PPC_PS3) += dtbImage.ps3 |
216 | image-$(CONFIG_PPC_CELLEB) += zImage.pseries | 218 | image-$(CONFIG_PPC_CELLEB) += zImage.pseries |
217 | image-$(CONFIG_PPC_CELL_QPACE) += zImage.pseries | 219 | image-$(CONFIG_PPC_CELL_QPACE) += zImage.pseries |
218 | image-$(CONFIG_PPC_CHRP) += zImage.chrp | 220 | image-$(CONFIG_PPC_CHRP) += zImage.chrp |
219 | image-$(CONFIG_PPC_EFIKA) += zImage.chrp | 221 | image-$(CONFIG_PPC_EFIKA) += zImage.chrp |
220 | image-$(CONFIG_PPC_PMAC) += zImage.pmac | 222 | image-$(CONFIG_PPC_PMAC) += zImage.pmac |
221 | image-$(CONFIG_PPC_HOLLY) += dtbImage.holly | 223 | image-$(CONFIG_PPC_HOLLY) += dtbImage.holly |
222 | image-$(CONFIG_DEFAULT_UIMAGE) += uImage | 224 | image-$(CONFIG_DEFAULT_UIMAGE) += uImage |
223 | image-$(CONFIG_EPAPR_BOOT) += zImage.epapr | 225 | image-$(CONFIG_EPAPR_BOOT) += zImage.epapr |
224 | 226 | ||
225 | # | 227 | # |
226 | # Targets which embed a device tree blob | 228 | # Targets which embed a device tree blob |
227 | # | 229 | # |
228 | # Theses are default targets to build images which embed device tree blobs. | 230 | # Theses are default targets to build images which embed device tree blobs. |
229 | # They are only required on boards which do not have FDT support in firmware. | 231 | # They are only required on boards which do not have FDT support in firmware. |
230 | # Boards with newish u-boot firmware can use the uImage target above | 232 | # Boards with newish u-boot firmware can use the uImage target above |
231 | # | 233 | # |
232 | 234 | ||
233 | # Board ports in arch/powerpc/platform/40x/Kconfig | 235 | # Board ports in arch/powerpc/platform/40x/Kconfig |
234 | image-$(CONFIG_EP405) += dtbImage.ep405 | 236 | image-$(CONFIG_EP405) += dtbImage.ep405 |
235 | image-$(CONFIG_HOTFOOT) += cuImage.hotfoot | 237 | image-$(CONFIG_HOTFOOT) += cuImage.hotfoot |
236 | image-$(CONFIG_WALNUT) += treeImage.walnut | 238 | image-$(CONFIG_WALNUT) += treeImage.walnut |
237 | image-$(CONFIG_ACADIA) += cuImage.acadia | 239 | image-$(CONFIG_ACADIA) += cuImage.acadia |
238 | image-$(CONFIG_OBS600) += uImage.obs600 | 240 | image-$(CONFIG_OBS600) += uImage.obs600 |
239 | 241 | ||
240 | # Board ports in arch/powerpc/platform/44x/Kconfig | 242 | # Board ports in arch/powerpc/platform/44x/Kconfig |
241 | image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony | 243 | image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony |
242 | image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo | 244 | image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo |
243 | image-$(CONFIG_SAM440EP) += cuImage.sam440ep | 245 | image-$(CONFIG_SAM440EP) += cuImage.sam440ep |
244 | image-$(CONFIG_SEQUOIA) += cuImage.sequoia | 246 | image-$(CONFIG_SEQUOIA) += cuImage.sequoia |
245 | image-$(CONFIG_RAINIER) += cuImage.rainier | 247 | image-$(CONFIG_RAINIER) += cuImage.rainier |
246 | image-$(CONFIG_TAISHAN) += cuImage.taishan | 248 | image-$(CONFIG_TAISHAN) += cuImage.taishan |
247 | image-$(CONFIG_KATMAI) += cuImage.katmai | 249 | image-$(CONFIG_KATMAI) += cuImage.katmai |
248 | image-$(CONFIG_WARP) += cuImage.warp | 250 | image-$(CONFIG_WARP) += cuImage.warp |
249 | image-$(CONFIG_YOSEMITE) += cuImage.yosemite | 251 | image-$(CONFIG_YOSEMITE) += cuImage.yosemite |
250 | image-$(CONFIG_ISS4xx) += treeImage.iss4xx \ | 252 | image-$(CONFIG_ISS4xx) += treeImage.iss4xx \ |
251 | treeImage.iss4xx-mpic | 253 | treeImage.iss4xx-mpic |
252 | image-$(CONFIG_CURRITUCK) += treeImage.currituck | 254 | image-$(CONFIG_CURRITUCK) += treeImage.currituck |
255 | image-$(CONFIG_AKEBONO) += treeImage.akebono | ||
253 | 256 | ||
254 | # Board ports in arch/powerpc/platform/8xx/Kconfig | 257 | # Board ports in arch/powerpc/platform/8xx/Kconfig |
255 | image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads | 258 | image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads |
256 | image-$(CONFIG_MPC885ADS) += cuImage.mpc885ads | 259 | image-$(CONFIG_MPC885ADS) += cuImage.mpc885ads |
257 | image-$(CONFIG_PPC_EP88XC) += dtbImage.ep88xc | 260 | image-$(CONFIG_PPC_EP88XC) += dtbImage.ep88xc |
258 | image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \ | 261 | image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \ |
259 | dtbImage.adder875-redboot | 262 | dtbImage.adder875-redboot |
260 | 263 | ||
261 | # Board ports in arch/powerpc/platform/52xx/Kconfig | 264 | # Board ports in arch/powerpc/platform/52xx/Kconfig |
262 | image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 lite5200.dtb | 265 | image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 lite5200.dtb |
263 | image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200b lite5200b.dtb | 266 | image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200b lite5200b.dtb |
264 | image-$(CONFIG_PPC_MEDIA5200) += cuImage.media5200 media5200.dtb | 267 | image-$(CONFIG_PPC_MEDIA5200) += cuImage.media5200 media5200.dtb |
265 | 268 | ||
266 | # Board ports in arch/powerpc/platform/82xx/Kconfig | 269 | # Board ports in arch/powerpc/platform/82xx/Kconfig |
267 | image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads | 270 | image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads |
268 | image-$(CONFIG_PQ2FADS) += cuImage.pq2fads | 271 | image-$(CONFIG_PQ2FADS) += cuImage.pq2fads |
269 | image-$(CONFIG_EP8248E) += dtbImage.ep8248e | 272 | image-$(CONFIG_EP8248E) += dtbImage.ep8248e |
270 | 273 | ||
271 | # Board ports in arch/powerpc/platform/83xx/Kconfig | 274 | # Board ports in arch/powerpc/platform/83xx/Kconfig |
272 | image-$(CONFIG_MPC832x_MDS) += cuImage.mpc832x_mds | 275 | image-$(CONFIG_MPC832x_MDS) += cuImage.mpc832x_mds |
273 | image-$(CONFIG_MPC832x_RDB) += cuImage.mpc832x_rdb | 276 | image-$(CONFIG_MPC832x_RDB) += cuImage.mpc832x_rdb |
274 | image-$(CONFIG_MPC834x_ITX) += cuImage.mpc8349emitx \ | 277 | image-$(CONFIG_MPC834x_ITX) += cuImage.mpc8349emitx \ |
275 | cuImage.mpc8349emitxgp | 278 | cuImage.mpc8349emitxgp |
276 | image-$(CONFIG_MPC834x_MDS) += cuImage.mpc834x_mds | 279 | image-$(CONFIG_MPC834x_MDS) += cuImage.mpc834x_mds |
277 | image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds | 280 | image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds |
278 | image-$(CONFIG_ASP834x) += dtbImage.asp834x-redboot | 281 | image-$(CONFIG_ASP834x) += dtbImage.asp834x-redboot |
279 | 282 | ||
280 | # Board ports in arch/powerpc/platform/85xx/Kconfig | 283 | # Board ports in arch/powerpc/platform/85xx/Kconfig |
281 | image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads | 284 | image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads |
282 | image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads | 285 | image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads |
283 | image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \ | 286 | image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \ |
284 | cuImage.mpc8548cds_32b \ | 287 | cuImage.mpc8548cds_32b \ |
285 | cuImage.mpc8555cds | 288 | cuImage.mpc8555cds |
286 | image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds | 289 | image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds |
287 | image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \ | 290 | image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \ |
288 | cuImage.mpc8572ds | 291 | cuImage.mpc8572ds |
289 | image-$(CONFIG_TQM8540) += cuImage.tqm8540 | 292 | image-$(CONFIG_TQM8540) += cuImage.tqm8540 |
290 | image-$(CONFIG_TQM8541) += cuImage.tqm8541 | 293 | image-$(CONFIG_TQM8541) += cuImage.tqm8541 |
291 | image-$(CONFIG_TQM8548) += cuImage.tqm8548 | 294 | image-$(CONFIG_TQM8548) += cuImage.tqm8548 |
292 | image-$(CONFIG_TQM8555) += cuImage.tqm8555 | 295 | image-$(CONFIG_TQM8555) += cuImage.tqm8555 |
293 | image-$(CONFIG_TQM8560) += cuImage.tqm8560 | 296 | image-$(CONFIG_TQM8560) += cuImage.tqm8560 |
294 | image-$(CONFIG_SBC8548) += cuImage.sbc8548 | 297 | image-$(CONFIG_SBC8548) += cuImage.sbc8548 |
295 | image-$(CONFIG_KSI8560) += cuImage.ksi8560 | 298 | image-$(CONFIG_KSI8560) += cuImage.ksi8560 |
296 | 299 | ||
297 | # Board ports in arch/powerpc/platform/embedded6xx/Kconfig | 300 | # Board ports in arch/powerpc/platform/embedded6xx/Kconfig |
298 | image-$(CONFIG_STORCENTER) += cuImage.storcenter | 301 | image-$(CONFIG_STORCENTER) += cuImage.storcenter |
299 | image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 | 302 | image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2 |
300 | image-$(CONFIG_PPC_C2K) += cuImage.c2k | 303 | image-$(CONFIG_PPC_C2K) += cuImage.c2k |
301 | image-$(CONFIG_GAMECUBE) += dtbImage.gamecube | 304 | image-$(CONFIG_GAMECUBE) += dtbImage.gamecube |
302 | image-$(CONFIG_WII) += dtbImage.wii | 305 | image-$(CONFIG_WII) += dtbImage.wii |
303 | image-$(CONFIG_MVME5100) += dtbImage.mvme5100 | 306 | image-$(CONFIG_MVME5100) += dtbImage.mvme5100 |
304 | 307 | ||
305 | # Board port in arch/powerpc/platform/amigaone/Kconfig | 308 | # Board port in arch/powerpc/platform/amigaone/Kconfig |
306 | image-$(CONFIG_AMIGAONE) += cuImage.amigaone | 309 | image-$(CONFIG_AMIGAONE) += cuImage.amigaone |
307 | 310 | ||
308 | # For 32-bit powermacs, build the COFF and miboot images | 311 | # For 32-bit powermacs, build the COFF and miboot images |
309 | # as well as the ELF images. | 312 | # as well as the ELF images. |
310 | ifeq ($(CONFIG_PPC32),y) | 313 | ifeq ($(CONFIG_PPC32),y) |
311 | image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot | 314 | image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot |
312 | endif | 315 | endif |
313 | 316 | ||
314 | # Allow extra targets to be added to the defconfig | 317 | # Allow extra targets to be added to the defconfig |
315 | image-y += $(subst ",,$(CONFIG_EXTRA_TARGETS)) | 318 | image-y += $(subst ",,$(CONFIG_EXTRA_TARGETS)) |
316 | 319 | ||
317 | initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-)) | 320 | initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-)) |
318 | initrd-y := $(patsubst zImage%, zImage.initrd%, \ | 321 | initrd-y := $(patsubst zImage%, zImage.initrd%, \ |
319 | $(patsubst dtbImage%, dtbImage.initrd%, \ | 322 | $(patsubst dtbImage%, dtbImage.initrd%, \ |
320 | $(patsubst simpleImage%, simpleImage.initrd%, \ | 323 | $(patsubst simpleImage%, simpleImage.initrd%, \ |
321 | $(patsubst treeImage%, treeImage.initrd%, $(image-y))))) | 324 | $(patsubst treeImage%, treeImage.initrd%, $(image-y))))) |
322 | initrd-y := $(filter-out $(image-y), $(initrd-y)) | 325 | initrd-y := $(filter-out $(image-y), $(initrd-y)) |
323 | targets += $(image-y) $(initrd-y) | 326 | targets += $(image-y) $(initrd-y) |
324 | 327 | ||
325 | $(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz | 328 | $(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz |
326 | 329 | ||
327 | # Don't put the ramdisk on the pattern rule; when its missing make will try | 330 | # Don't put the ramdisk on the pattern rule; when its missing make will try |
328 | # the pattern rule with less dependencies that also matches (even with the | 331 | # the pattern rule with less dependencies that also matches (even with the |
329 | # hard dependency listed). | 332 | # hard dependency listed). |
330 | $(obj)/zImage.initrd.%: vmlinux $(wrapperbits) | 333 | $(obj)/zImage.initrd.%: vmlinux $(wrapperbits) |
331 | $(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz) | 334 | $(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz) |
332 | 335 | ||
333 | $(obj)/zImage.%: vmlinux $(wrapperbits) | 336 | $(obj)/zImage.%: vmlinux $(wrapperbits) |
334 | $(call if_changed,wrap,$*) | 337 | $(call if_changed,wrap,$*) |
335 | 338 | ||
336 | # dtbImage% - a dtbImage is a zImage with an embedded device tree blob | 339 | # dtbImage% - a dtbImage is a zImage with an embedded device tree blob |
337 | $(obj)/dtbImage.initrd.%: vmlinux $(wrapperbits) $(obj)/%.dtb | 340 | $(obj)/dtbImage.initrd.%: vmlinux $(wrapperbits) $(obj)/%.dtb |
338 | $(call if_changed,wrap,$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) | 341 | $(call if_changed,wrap,$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) |
339 | 342 | ||
340 | $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb | 343 | $(obj)/dtbImage.%: vmlinux $(wrapperbits) $(obj)/%.dtb |
341 | $(call if_changed,wrap,$*,,$(obj)/$*.dtb) | 344 | $(call if_changed,wrap,$*,,$(obj)/$*.dtb) |
342 | 345 | ||
343 | # This cannot be in the root of $(src) as the zImage rule always adds a $(obj) | 346 | # This cannot be in the root of $(src) as the zImage rule always adds a $(obj) |
344 | # prefix | 347 | # prefix |
345 | $(obj)/vmlinux.strip: vmlinux | 348 | $(obj)/vmlinux.strip: vmlinux |
346 | $(STRIP) -s -R .comment $< -o $@ | 349 | $(STRIP) -s -R .comment $< -o $@ |
347 | 350 | ||
348 | $(obj)/uImage: vmlinux $(wrapperbits) | 351 | $(obj)/uImage: vmlinux $(wrapperbits) |
349 | $(call if_changed,wrap,uboot) | 352 | $(call if_changed,wrap,uboot) |
350 | 353 | ||
351 | $(obj)/uImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 354 | $(obj)/uImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
352 | $(call if_changed,wrap,uboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) | 355 | $(call if_changed,wrap,uboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) |
353 | 356 | ||
354 | $(obj)/uImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 357 | $(obj)/uImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
355 | $(call if_changed,wrap,uboot-$*,,$(obj)/$*.dtb) | 358 | $(call if_changed,wrap,uboot-$*,,$(obj)/$*.dtb) |
356 | 359 | ||
357 | $(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 360 | $(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
358 | $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) | 361 | $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) |
359 | 362 | ||
360 | $(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 363 | $(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
361 | $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb) | 364 | $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb) |
362 | 365 | ||
363 | $(obj)/simpleImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 366 | $(obj)/simpleImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
364 | $(call if_changed,wrap,simpleboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) | 367 | $(call if_changed,wrap,simpleboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) |
365 | 368 | ||
366 | $(obj)/simpleImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 369 | $(obj)/simpleImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
367 | $(call if_changed,wrap,simpleboot-$*,,$(obj)/$*.dtb) | 370 | $(call if_changed,wrap,simpleboot-$*,,$(obj)/$*.dtb) |
368 | 371 | ||
369 | $(obj)/treeImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 372 | $(obj)/treeImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
370 | $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) | 373 | $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) |
371 | 374 | ||
372 | $(obj)/treeImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) | 375 | $(obj)/treeImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) |
373 | $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb) | 376 | $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb) |
374 | 377 | ||
375 | # Rule to build device tree blobs | 378 | # Rule to build device tree blobs |
376 | $(obj)/%.dtb: $(src)/dts/%.dts FORCE | 379 | $(obj)/%.dtb: $(src)/dts/%.dts FORCE |
377 | $(call if_changed_dep,dtc) | 380 | $(call if_changed_dep,dtc) |
378 | 381 | ||
379 | # If there isn't a platform selected then just strip the vmlinux. | 382 | # If there isn't a platform selected then just strip the vmlinux. |
380 | ifeq (,$(image-y)) | 383 | ifeq (,$(image-y)) |
381 | image-y := vmlinux.strip | 384 | image-y := vmlinux.strip |
382 | endif | 385 | endif |
383 | 386 | ||
384 | $(obj)/zImage: $(addprefix $(obj)/, $(image-y)) | 387 | $(obj)/zImage: $(addprefix $(obj)/, $(image-y)) |
385 | @rm -f $@; ln $< $@ | 388 | @rm -f $@; ln $< $@ |
386 | $(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) | 389 | $(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) |
387 | @rm -f $@; ln $< $@ | 390 | @rm -f $@; ln $< $@ |
388 | 391 | ||
389 | install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) | 392 | install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) |
390 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $^ | 393 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $^ |
391 | 394 | ||
392 | # anything not in $(targets) | 395 | # anything not in $(targets) |
393 | clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ | 396 | clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ |
394 | zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \ | 397 | zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \ |
395 | zImage.miboot zImage.pmac zImage.pseries \ | 398 | zImage.miboot zImage.pmac zImage.pseries \ |
396 | zImage.maple simpleImage.* otheros.bld *.dtb | 399 | zImage.maple simpleImage.* otheros.bld *.dtb |
397 | 400 | ||
398 | # clean up files cached by wrapper | 401 | # clean up files cached by wrapper |
399 | clean-kernel := vmlinux.strip vmlinux.bin | 402 | clean-kernel := vmlinux.strip vmlinux.bin |
400 | clean-kernel += $(addsuffix .gz,$(clean-kernel)) | 403 | clean-kernel += $(addsuffix .gz,$(clean-kernel)) |
401 | # If not absolute clean-files are relative to $(obj). | 404 | # If not absolute clean-files are relative to $(obj). |
402 | clean-files += $(addprefix $(objtree)/, $(clean-kernel)) | 405 | clean-files += $(addprefix $(objtree)/, $(clean-kernel)) |
403 | 406 | ||
404 | WRAPPER_OBJDIR := /usr/lib/kernel-wrapper | 407 | WRAPPER_OBJDIR := /usr/lib/kernel-wrapper |
405 | WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts | 408 | WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts |
406 | WRAPPER_BINDIR := /usr/sbin | 409 | WRAPPER_BINDIR := /usr/sbin |
407 | INSTALL := install | 410 | INSTALL := install |
408 | 411 | ||
409 | extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y)) | 412 | extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y)) |
410 | hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y)) | 413 | hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y)) |
411 | wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper | 414 | wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper |
412 | dts-installed := $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts)) | 415 | dts-installed := $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts)) |
413 | 416 | ||
414 | all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed) | 417 | all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed) |
415 | 418 | ||
416 | quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) | 419 | quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) |
417 | cmd_mkdir = mkdir -p $@ | 420 | cmd_mkdir = mkdir -p $@ |
418 | 421 | ||
419 | quiet_cmd_install = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@) | 422 | quiet_cmd_install = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@) |
420 | cmd_install = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@ | 423 | cmd_install = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@ |
421 | 424 | ||
422 | quiet_cmd_install_dts = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@) | 425 | quiet_cmd_install_dts = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@) |
423 | cmd_install_dts = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@ | 426 | cmd_install_dts = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@ |
424 | 427 | ||
425 | quiet_cmd_install_exe = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) | 428 | quiet_cmd_install_exe = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) |
426 | cmd_install_exe = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@ | 429 | cmd_install_exe = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@ |
427 | 430 | ||
428 | quiet_cmd_install_wrapper = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) | 431 | quiet_cmd_install_wrapper = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) |
429 | cmd_install_wrapper = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(srctree)/$(obj)/%,$@) $@ ;\ | 432 | cmd_install_wrapper = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(srctree)/$(obj)/%,$@) $@ ;\ |
430 | sed -i $@ -e 's%^object=.*%object=$(WRAPPER_OBJDIR)%' \ | 433 | sed -i $@ -e 's%^object=.*%object=$(WRAPPER_OBJDIR)%' \ |
431 | -e 's%^objbin=.*%objbin=$(WRAPPER_BINDIR)%' \ | 434 | -e 's%^objbin=.*%objbin=$(WRAPPER_BINDIR)%' \ |
432 | 435 | ||
433 | 436 | ||
434 | $(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR): | 437 | $(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR): |
435 | $(call cmd,mkdir) | 438 | $(call cmd,mkdir) |
436 | 439 | ||
437 | $(extra-installed) : $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR) | 440 | $(extra-installed) : $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR) |
438 | $(call cmd,install) | 441 | $(call cmd,install) |
439 | 442 | ||
440 | $(hostprogs-installed) : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR) | 443 | $(hostprogs-installed) : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR) |
441 | $(call cmd,install_exe) | 444 | $(call cmd,install_exe) |
442 | 445 | ||
443 | $(dts-installed) : $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR) | 446 | $(dts-installed) : $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR) |
444 | $(call cmd,install_dts) | 447 | $(call cmd,install_dts) |
445 | 448 | ||
446 | $(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR) | 449 | $(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR) |
447 | $(call cmd,install_wrapper) | 450 | $(call cmd,install_wrapper) |
448 | 451 | ||
449 | $(obj)/bootwrapper_install: $(all-installed) | 452 | $(obj)/bootwrapper_install: $(all-installed) |
450 | 453 |
arch/powerpc/boot/dcr.h
1 | #ifndef _PPC_BOOT_DCR_H_ | 1 | #ifndef _PPC_BOOT_DCR_H_ |
2 | #define _PPC_BOOT_DCR_H_ | 2 | #define _PPC_BOOT_DCR_H_ |
3 | 3 | ||
4 | #define mfdcr(rn) \ | 4 | #define mfdcr(rn) \ |
5 | ({ \ | 5 | ({ \ |
6 | unsigned long rval; \ | 6 | unsigned long rval; \ |
7 | asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \ | 7 | asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \ |
8 | rval; \ | 8 | rval; \ |
9 | }) | 9 | }) |
10 | #define mtdcr(rn, val) \ | 10 | #define mtdcr(rn, val) \ |
11 | asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val)) | 11 | asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val)) |
12 | #define mfdcrx(rn) \ | 12 | #define mfdcrx(rn) \ |
13 | ({ \ | 13 | ({ \ |
14 | unsigned long rval; \ | 14 | unsigned long rval; \ |
15 | asm volatile("mfdcrx %0,%1" : "=r"(rval) : "r"(rn)); \ | 15 | asm volatile("mfdcrx %0,%1" : "=r"(rval) : "r"(rn)); \ |
16 | rval; \ | 16 | rval; \ |
17 | }) | 17 | }) |
18 | #define mtdcrx(rn, val) \ | ||
19 | ({ \ | ||
20 | asm volatile("mtdcrx %0,%1" : : "r"(rn), "r" (val)); \ | ||
21 | }) | ||
18 | 22 | ||
19 | /* 440GP/440GX SDRAM controller DCRs */ | 23 | /* 440GP/440GX SDRAM controller DCRs */ |
20 | #define DCRN_SDRAM0_CFGADDR 0x010 | 24 | #define DCRN_SDRAM0_CFGADDR 0x010 |
21 | #define DCRN_SDRAM0_CFGDATA 0x011 | 25 | #define DCRN_SDRAM0_CFGDATA 0x011 |
22 | 26 | ||
23 | #define SDRAM0_READ(offset) ({\ | 27 | #define SDRAM0_READ(offset) ({\ |
24 | mtdcr(DCRN_SDRAM0_CFGADDR, offset); \ | 28 | mtdcr(DCRN_SDRAM0_CFGADDR, offset); \ |
25 | mfdcr(DCRN_SDRAM0_CFGDATA); }) | 29 | mfdcr(DCRN_SDRAM0_CFGDATA); }) |
26 | #define SDRAM0_WRITE(offset, data) ({\ | 30 | #define SDRAM0_WRITE(offset, data) ({\ |
27 | mtdcr(DCRN_SDRAM0_CFGADDR, offset); \ | 31 | mtdcr(DCRN_SDRAM0_CFGADDR, offset); \ |
28 | mtdcr(DCRN_SDRAM0_CFGDATA, data); }) | 32 | mtdcr(DCRN_SDRAM0_CFGDATA, data); }) |
29 | 33 | ||
30 | #define SDRAM0_B0CR 0x40 | 34 | #define SDRAM0_B0CR 0x40 |
31 | #define SDRAM0_B1CR 0x44 | 35 | #define SDRAM0_B1CR 0x44 |
32 | #define SDRAM0_B2CR 0x48 | 36 | #define SDRAM0_B2CR 0x48 |
33 | #define SDRAM0_B3CR 0x4c | 37 | #define SDRAM0_B3CR 0x4c |
34 | 38 | ||
35 | static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, | 39 | static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, |
36 | SDRAM0_B2CR, SDRAM0_B3CR }; | 40 | SDRAM0_B2CR, SDRAM0_B3CR }; |
37 | 41 | ||
38 | #define SDRAM_CONFIG_BANK_ENABLE 0x00000001 | 42 | #define SDRAM_CONFIG_BANK_ENABLE 0x00000001 |
39 | #define SDRAM_CONFIG_SIZE_MASK 0x000e0000 | 43 | #define SDRAM_CONFIG_SIZE_MASK 0x000e0000 |
40 | #define SDRAM_CONFIG_BANK_SIZE(reg) \ | 44 | #define SDRAM_CONFIG_BANK_SIZE(reg) \ |
41 | (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17)) | 45 | (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17)) |
42 | 46 | ||
43 | /* 440GP External Bus Controller (EBC) */ | 47 | /* 440GP External Bus Controller (EBC) */ |
44 | #define DCRN_EBC0_CFGADDR 0x012 | 48 | #define DCRN_EBC0_CFGADDR 0x012 |
45 | #define DCRN_EBC0_CFGDATA 0x013 | 49 | #define DCRN_EBC0_CFGDATA 0x013 |
46 | #define EBC_NUM_BANKS 8 | 50 | #define EBC_NUM_BANKS 8 |
47 | #define EBC_B0CR 0x00 | 51 | #define EBC_B0CR 0x00 |
48 | #define EBC_B1CR 0x01 | 52 | #define EBC_B1CR 0x01 |
49 | #define EBC_B2CR 0x02 | 53 | #define EBC_B2CR 0x02 |
50 | #define EBC_B3CR 0x03 | 54 | #define EBC_B3CR 0x03 |
51 | #define EBC_B4CR 0x04 | 55 | #define EBC_B4CR 0x04 |
52 | #define EBC_B5CR 0x05 | 56 | #define EBC_B5CR 0x05 |
53 | #define EBC_B6CR 0x06 | 57 | #define EBC_B6CR 0x06 |
54 | #define EBC_B7CR 0x07 | 58 | #define EBC_B7CR 0x07 |
55 | #define EBC_BXCR(n) (n) | 59 | #define EBC_BXCR(n) (n) |
56 | #define EBC_BXCR_BAS 0xfff00000 | 60 | #define EBC_BXCR_BAS 0xfff00000 |
57 | #define EBC_BXCR_BS 0x000e0000 | 61 | #define EBC_BXCR_BS 0x000e0000 |
58 | #define EBC_BXCR_BANK_SIZE(reg) \ | 62 | #define EBC_BXCR_BANK_SIZE(reg) \ |
59 | (0x100000 << (((reg) & EBC_BXCR_BS) >> 17)) | 63 | (0x100000 << (((reg) & EBC_BXCR_BS) >> 17)) |
60 | #define EBC_BXCR_BU 0x00018000 | 64 | #define EBC_BXCR_BU 0x00018000 |
61 | #define EBC_BXCR_BU_OFF 0x00000000 | 65 | #define EBC_BXCR_BU_OFF 0x00000000 |
62 | #define EBC_BXCR_BU_RO 0x00008000 | 66 | #define EBC_BXCR_BU_RO 0x00008000 |
63 | #define EBC_BXCR_BU_WO 0x00010000 | 67 | #define EBC_BXCR_BU_WO 0x00010000 |
64 | #define EBC_BXCR_BU_RW 0x00018000 | 68 | #define EBC_BXCR_BU_RW 0x00018000 |
65 | #define EBC_BXCR_BW 0x00006000 | 69 | #define EBC_BXCR_BW 0x00006000 |
66 | #define EBC_B0AP 0x10 | 70 | #define EBC_B0AP 0x10 |
67 | #define EBC_B1AP 0x11 | 71 | #define EBC_B1AP 0x11 |
68 | #define EBC_B2AP 0x12 | 72 | #define EBC_B2AP 0x12 |
69 | #define EBC_B3AP 0x13 | 73 | #define EBC_B3AP 0x13 |
70 | #define EBC_B4AP 0x14 | 74 | #define EBC_B4AP 0x14 |
71 | #define EBC_B5AP 0x15 | 75 | #define EBC_B5AP 0x15 |
72 | #define EBC_B6AP 0x16 | 76 | #define EBC_B6AP 0x16 |
73 | #define EBC_B7AP 0x17 | 77 | #define EBC_B7AP 0x17 |
74 | #define EBC_BXAP(n) (0x10+(n)) | 78 | #define EBC_BXAP(n) (0x10+(n)) |
75 | #define EBC_BEAR 0x20 | 79 | #define EBC_BEAR 0x20 |
76 | #define EBC_BESR 0x21 | 80 | #define EBC_BESR 0x21 |
77 | #define EBC_CFG 0x23 | 81 | #define EBC_CFG 0x23 |
78 | #define EBC_CID 0x24 | 82 | #define EBC_CID 0x24 |
79 | 83 | ||
80 | /* 440GP Clock, PM, chip control */ | 84 | /* 440GP Clock, PM, chip control */ |
81 | #define DCRN_CPC0_SR 0x0b0 | 85 | #define DCRN_CPC0_SR 0x0b0 |
82 | #define DCRN_CPC0_ER 0x0b1 | 86 | #define DCRN_CPC0_ER 0x0b1 |
83 | #define DCRN_CPC0_FR 0x0b2 | 87 | #define DCRN_CPC0_FR 0x0b2 |
84 | #define DCRN_CPC0_SYS0 0x0e0 | 88 | #define DCRN_CPC0_SYS0 0x0e0 |
85 | #define CPC0_SYS0_TUNE 0xffc00000 | 89 | #define CPC0_SYS0_TUNE 0xffc00000 |
86 | #define CPC0_SYS0_FBDV_MASK 0x003c0000 | 90 | #define CPC0_SYS0_FBDV_MASK 0x003c0000 |
87 | #define CPC0_SYS0_FWDVA_MASK 0x00038000 | 91 | #define CPC0_SYS0_FWDVA_MASK 0x00038000 |
88 | #define CPC0_SYS0_FWDVB_MASK 0x00007000 | 92 | #define CPC0_SYS0_FWDVB_MASK 0x00007000 |
89 | #define CPC0_SYS0_OPDV_MASK 0x00000c00 | 93 | #define CPC0_SYS0_OPDV_MASK 0x00000c00 |
90 | #define CPC0_SYS0_EPDV_MASK 0x00000300 | 94 | #define CPC0_SYS0_EPDV_MASK 0x00000300 |
91 | /* Helper macros to compute the actual clock divider values from the | 95 | /* Helper macros to compute the actual clock divider values from the |
92 | * encodings in the CPC0 register */ | 96 | * encodings in the CPC0 register */ |
93 | #define CPC0_SYS0_FBDV(reg) \ | 97 | #define CPC0_SYS0_FBDV(reg) \ |
94 | ((((((reg) & CPC0_SYS0_FBDV_MASK) >> 18) - 1) & 0xf) + 1) | 98 | ((((((reg) & CPC0_SYS0_FBDV_MASK) >> 18) - 1) & 0xf) + 1) |
95 | #define CPC0_SYS0_FWDVA(reg) \ | 99 | #define CPC0_SYS0_FWDVA(reg) \ |
96 | (8 - (((reg) & CPC0_SYS0_FWDVA_MASK) >> 15)) | 100 | (8 - (((reg) & CPC0_SYS0_FWDVA_MASK) >> 15)) |
97 | #define CPC0_SYS0_FWDVB(reg) \ | 101 | #define CPC0_SYS0_FWDVB(reg) \ |
98 | (8 - (((reg) & CPC0_SYS0_FWDVB_MASK) >> 12)) | 102 | (8 - (((reg) & CPC0_SYS0_FWDVB_MASK) >> 12)) |
99 | #define CPC0_SYS0_OPDV(reg) \ | 103 | #define CPC0_SYS0_OPDV(reg) \ |
100 | ((((reg) & CPC0_SYS0_OPDV_MASK) >> 10) + 1) | 104 | ((((reg) & CPC0_SYS0_OPDV_MASK) >> 10) + 1) |
101 | #define CPC0_SYS0_EPDV(reg) \ | 105 | #define CPC0_SYS0_EPDV(reg) \ |
102 | ((((reg) & CPC0_SYS0_EPDV_MASK) >> 8) + 1) | 106 | ((((reg) & CPC0_SYS0_EPDV_MASK) >> 8) + 1) |
103 | #define CPC0_SYS0_EXTSL 0x00000080 | 107 | #define CPC0_SYS0_EXTSL 0x00000080 |
104 | #define CPC0_SYS0_RW_MASK 0x00000060 | 108 | #define CPC0_SYS0_RW_MASK 0x00000060 |
105 | #define CPC0_SYS0_RL 0x00000010 | 109 | #define CPC0_SYS0_RL 0x00000010 |
106 | #define CPC0_SYS0_ZMIISL_MASK 0x0000000c | 110 | #define CPC0_SYS0_ZMIISL_MASK 0x0000000c |
107 | #define CPC0_SYS0_BYPASS 0x00000002 | 111 | #define CPC0_SYS0_BYPASS 0x00000002 |
108 | #define CPC0_SYS0_NTO1 0x00000001 | 112 | #define CPC0_SYS0_NTO1 0x00000001 |
109 | #define DCRN_CPC0_SYS1 0x0e1 | 113 | #define DCRN_CPC0_SYS1 0x0e1 |
110 | #define DCRN_CPC0_CUST0 0x0e2 | 114 | #define DCRN_CPC0_CUST0 0x0e2 |
111 | #define DCRN_CPC0_CUST1 0x0e3 | 115 | #define DCRN_CPC0_CUST1 0x0e3 |
112 | #define DCRN_CPC0_STRP0 0x0e4 | 116 | #define DCRN_CPC0_STRP0 0x0e4 |
113 | #define DCRN_CPC0_STRP1 0x0e5 | 117 | #define DCRN_CPC0_STRP1 0x0e5 |
114 | #define DCRN_CPC0_STRP2 0x0e6 | 118 | #define DCRN_CPC0_STRP2 0x0e6 |
115 | #define DCRN_CPC0_STRP3 0x0e7 | 119 | #define DCRN_CPC0_STRP3 0x0e7 |
116 | #define DCRN_CPC0_GPIO 0x0e8 | 120 | #define DCRN_CPC0_GPIO 0x0e8 |
117 | #define DCRN_CPC0_PLB 0x0e9 | 121 | #define DCRN_CPC0_PLB 0x0e9 |
118 | #define DCRN_CPC0_CR1 0x0ea | 122 | #define DCRN_CPC0_CR1 0x0ea |
119 | #define DCRN_CPC0_CR0 0x0eb | 123 | #define DCRN_CPC0_CR0 0x0eb |
120 | #define CPC0_CR0_SWE 0x80000000 | 124 | #define CPC0_CR0_SWE 0x80000000 |
121 | #define CPC0_CR0_CETE 0x40000000 | 125 | #define CPC0_CR0_CETE 0x40000000 |
122 | #define CPC0_CR0_U1FCS 0x20000000 | 126 | #define CPC0_CR0_U1FCS 0x20000000 |
123 | #define CPC0_CR0_U0DTE 0x10000000 | 127 | #define CPC0_CR0_U0DTE 0x10000000 |
124 | #define CPC0_CR0_U0DRE 0x08000000 | 128 | #define CPC0_CR0_U0DRE 0x08000000 |
125 | #define CPC0_CR0_U0DC 0x04000000 | 129 | #define CPC0_CR0_U0DC 0x04000000 |
126 | #define CPC0_CR0_U1DTE 0x02000000 | 130 | #define CPC0_CR0_U1DTE 0x02000000 |
127 | #define CPC0_CR0_U1DRE 0x01000000 | 131 | #define CPC0_CR0_U1DRE 0x01000000 |
128 | #define CPC0_CR0_U1DC 0x00800000 | 132 | #define CPC0_CR0_U1DC 0x00800000 |
129 | #define CPC0_CR0_U0EC 0x00400000 | 133 | #define CPC0_CR0_U0EC 0x00400000 |
130 | #define CPC0_CR0_U1EC 0x00200000 | 134 | #define CPC0_CR0_U1EC 0x00200000 |
131 | #define CPC0_CR0_UDIV_MASK 0x001f0000 | 135 | #define CPC0_CR0_UDIV_MASK 0x001f0000 |
132 | #define CPC0_CR0_UDIV(reg) \ | 136 | #define CPC0_CR0_UDIV(reg) \ |
133 | ((((reg) & CPC0_CR0_UDIV_MASK) >> 16) + 1) | 137 | ((((reg) & CPC0_CR0_UDIV_MASK) >> 16) + 1) |
134 | #define DCRN_CPC0_MIRQ0 0x0ec | 138 | #define DCRN_CPC0_MIRQ0 0x0ec |
135 | #define DCRN_CPC0_MIRQ1 0x0ed | 139 | #define DCRN_CPC0_MIRQ1 0x0ed |
136 | #define DCRN_CPC0_JTAGID 0x0ef | 140 | #define DCRN_CPC0_JTAGID 0x0ef |
137 | 141 | ||
138 | #define DCRN_MAL0_CFG 0x180 | 142 | #define DCRN_MAL0_CFG 0x180 |
139 | #define MAL_RESET 0x80000000 | 143 | #define MAL_RESET 0x80000000 |
140 | 144 | ||
141 | /* 440EP Clock/Power-on Reset regs */ | 145 | /* 440EP Clock/Power-on Reset regs */ |
142 | #define DCRN_CPR0_ADDR 0xc | 146 | #define DCRN_CPR0_ADDR 0xc |
143 | #define DCRN_CPR0_DATA 0xd | 147 | #define DCRN_CPR0_DATA 0xd |
144 | #define CPR0_PLLD0 0x60 | 148 | #define CPR0_PLLD0 0x60 |
145 | #define CPR0_OPBD0 0xc0 | 149 | #define CPR0_OPBD0 0xc0 |
146 | #define CPR0_PERD0 0xe0 | 150 | #define CPR0_PERD0 0xe0 |
147 | #define CPR0_PRIMBD0 0xa0 | 151 | #define CPR0_PRIMBD0 0xa0 |
148 | #define CPR0_SCPID 0x120 | 152 | #define CPR0_SCPID 0x120 |
149 | #define CPR0_PLLC0 0x40 | 153 | #define CPR0_PLLC0 0x40 |
150 | 154 | ||
151 | /* 405GP Clocking/Power Management/Chip Control regs */ | 155 | /* 405GP Clocking/Power Management/Chip Control regs */ |
152 | #define DCRN_CPC0_PLLMR 0xb0 | 156 | #define DCRN_CPC0_PLLMR 0xb0 |
153 | #define DCRN_405_CPC0_CR0 0xb1 | 157 | #define DCRN_405_CPC0_CR0 0xb1 |
154 | #define DCRN_405_CPC0_CR1 0xb2 | 158 | #define DCRN_405_CPC0_CR1 0xb2 |
155 | #define DCRN_405_CPC0_PSR 0xb4 | 159 | #define DCRN_405_CPC0_PSR 0xb4 |
156 | 160 | ||
157 | /* 405EP Clocking/Power Management/Chip Control regs */ | 161 | /* 405EP Clocking/Power Management/Chip Control regs */ |
158 | #define DCRN_CPC0_PLLMR0 0xf0 | 162 | #define DCRN_CPC0_PLLMR0 0xf0 |
159 | #define DCRN_CPC0_PLLMR1 0xf4 | 163 | #define DCRN_CPC0_PLLMR1 0xf4 |
160 | #define DCRN_CPC0_UCR 0xf5 | 164 | #define DCRN_CPC0_UCR 0xf5 |
161 | 165 | ||
162 | /* 440GX/405EX Clock Control reg */ | 166 | /* 440GX/405EX Clock Control reg */ |
163 | #define DCRN_CPR0_CLKUPD 0x020 | 167 | #define DCRN_CPR0_CLKUPD 0x020 |
164 | #define DCRN_CPR0_PLLC 0x040 | 168 | #define DCRN_CPR0_PLLC 0x040 |
165 | #define DCRN_CPR0_PLLD 0x060 | 169 | #define DCRN_CPR0_PLLD 0x060 |
166 | #define DCRN_CPR0_PRIMAD 0x080 | 170 | #define DCRN_CPR0_PRIMAD 0x080 |
167 | #define DCRN_CPR0_PRIMBD 0x0a0 | 171 | #define DCRN_CPR0_PRIMBD 0x0a0 |
168 | #define DCRN_CPR0_OPBD 0x0c0 | 172 | #define DCRN_CPR0_OPBD 0x0c0 |
169 | #define DCRN_CPR0_PERD 0x0e0 | 173 | #define DCRN_CPR0_PERD 0x0e0 |
170 | #define DCRN_CPR0_MALD 0x100 | 174 | #define DCRN_CPR0_MALD 0x100 |
171 | 175 | ||
172 | #define DCRN_SDR0_CONFIG_ADDR 0xe | 176 | #define DCRN_SDR0_CONFIG_ADDR 0xe |
173 | #define DCRN_SDR0_CONFIG_DATA 0xf | 177 | #define DCRN_SDR0_CONFIG_DATA 0xf |
174 | 178 | ||
175 | /* SDR read/write helper macros */ | 179 | /* SDR read/write helper macros */ |
176 | #define SDR0_READ(offset) ({\ | 180 | #define SDR0_READ(offset) ({\ |
177 | mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \ | 181 | mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \ |
178 | mfdcr(DCRN_SDR0_CONFIG_DATA); }) | 182 | mfdcr(DCRN_SDR0_CONFIG_DATA); }) |
179 | #define SDR0_WRITE(offset, data) ({\ | 183 | #define SDR0_WRITE(offset, data) ({\ |
180 | mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \ | 184 | mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \ |
181 | mtdcr(DCRN_SDR0_CONFIG_DATA, data); }) | 185 | mtdcr(DCRN_SDR0_CONFIG_DATA, data); }) |
182 | 186 | ||
183 | #define DCRN_SDR0_UART0 0x0120 | 187 | #define DCRN_SDR0_UART0 0x0120 |
184 | #define DCRN_SDR0_UART1 0x0121 | 188 | #define DCRN_SDR0_UART1 0x0121 |
185 | #define DCRN_SDR0_UART2 0x0122 | 189 | #define DCRN_SDR0_UART2 0x0122 |
186 | #define DCRN_SDR0_UART3 0x0123 | 190 | #define DCRN_SDR0_UART3 0x0123 |
187 | 191 | ||
188 | 192 | ||
189 | /* CPRs read/write helper macros - based off include/asm-ppc/ibm44x.h */ | 193 | /* CPRs read/write helper macros - based off include/asm-ppc/ibm44x.h */ |
190 | 194 | ||
191 | #define DCRN_CPR0_CFGADDR 0xc | 195 | #define DCRN_CPR0_CFGADDR 0xc |
192 | #define DCRN_CPR0_CFGDATA 0xd | 196 | #define DCRN_CPR0_CFGDATA 0xd |
193 | 197 | ||
194 | #define CPR0_READ(offset) ({\ | 198 | #define CPR0_READ(offset) ({\ |
195 | mtdcr(DCRN_CPR0_CFGADDR, offset); \ | 199 | mtdcr(DCRN_CPR0_CFGADDR, offset); \ |
196 | mfdcr(DCRN_CPR0_CFGDATA); }) | 200 | mfdcr(DCRN_CPR0_CFGDATA); }) |
197 | #define CPR0_WRITE(offset, data) ({\ | 201 | #define CPR0_WRITE(offset, data) ({\ |
198 | mtdcr(DCRN_CPR0_CFGADDR, offset); \ | 202 | mtdcr(DCRN_CPR0_CFGADDR, offset); \ |
199 | mtdcr(DCRN_CPR0_CFGDATA, data); }) | 203 | mtdcr(DCRN_CPR0_CFGDATA, data); }) |
200 | 204 | ||
201 | 205 | ||
202 | 206 | ||
203 | #endif /* _PPC_BOOT_DCR_H_ */ | 207 | #endif /* _PPC_BOOT_DCR_H_ */ |
204 | 208 |
arch/powerpc/boot/dts/akebono.dts
File was created | 1 | /* | |
2 | * Device Tree Source for IBM Embedded PPC 476 Platform | ||
3 | * | ||
4 | * Copyright ยฉ 2013 Tony Breeds IBM Corporation | ||
5 | * Copyright ยฉ 2013 Alistair Popple IBM Corporation | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without | ||
9 | * any warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | /dts-v1/; | ||
13 | |||
14 | /memreserve/ 0x01f00000 0x00100000; // spin table | ||
15 | |||
16 | / { | ||
17 | #address-cells = <2>; | ||
18 | #size-cells = <2>; | ||
19 | model = "ibm,akebono"; | ||
20 | compatible = "ibm,akebono", "ibm,476gtr"; | ||
21 | dcr-parent = <&{/cpus/cpu@0}>; | ||
22 | |||
23 | aliases { | ||
24 | serial0 = &UART0; | ||
25 | }; | ||
26 | |||
27 | cpus { | ||
28 | #address-cells = <1>; | ||
29 | #size-cells = <0>; | ||
30 | |||
31 | cpu@0 { | ||
32 | device_type = "cpu"; | ||
33 | model = "PowerPC,476"; | ||
34 | reg = <0>; | ||
35 | clock-frequency = <1600000000>; // 1.6 GHz | ||
36 | timebase-frequency = <100000000>; // 100Mhz | ||
37 | i-cache-line-size = <32>; | ||
38 | d-cache-line-size = <32>; | ||
39 | i-cache-size = <32768>; | ||
40 | d-cache-size = <32768>; | ||
41 | dcr-controller; | ||
42 | dcr-access-method = "native"; | ||
43 | status = "ok"; | ||
44 | }; | ||
45 | cpu@1 { | ||
46 | device_type = "cpu"; | ||
47 | model = "PowerPC,476"; | ||
48 | reg = <1>; | ||
49 | clock-frequency = <1600000000>; // 1.6 GHz | ||
50 | timebase-frequency = <100000000>; // 100Mhz | ||
51 | i-cache-line-size = <32>; | ||
52 | d-cache-line-size = <32>; | ||
53 | i-cache-size = <32768>; | ||
54 | d-cache-size = <32768>; | ||
55 | dcr-controller; | ||
56 | dcr-access-method = "native"; | ||
57 | status = "disabled"; | ||
58 | enable-method = "spin-table"; | ||
59 | cpu-release-addr = <0x0 0x01f00000>; | ||
60 | }; | ||
61 | }; | ||
62 | |||
63 | memory { | ||
64 | device_type = "memory"; | ||
65 | reg = <0x0 0x0 0x0 0x0>; // filled in by zImage | ||
66 | }; | ||
67 | |||
68 | MPIC: interrupt-controller { | ||
69 | compatible = "chrp,open-pic"; | ||
70 | interrupt-controller; | ||
71 | dcr-reg = <0xffc00000 0x00040000>; | ||
72 | #address-cells = <0>; | ||
73 | #size-cells = <0>; | ||
74 | #interrupt-cells = <2>; | ||
75 | single-cpu-affinity; | ||
76 | }; | ||
77 | |||
78 | plb { | ||
79 | compatible = "ibm,plb6"; | ||
80 | #address-cells = <2>; | ||
81 | #size-cells = <2>; | ||
82 | ranges; | ||
83 | clock-frequency = <200000000>; // 200Mhz | ||
84 | |||
85 | MAL0: mcmal { | ||
86 | compatible = "ibm,mcmal-476gtr", "ibm,mcmal2"; | ||
87 | dcr-reg = <0xc0000000 0x062>; | ||
88 | num-tx-chans = <1>; | ||
89 | num-rx-chans = <1>; | ||
90 | #address-cells = <0>; | ||
91 | #size-cells = <0>; | ||
92 | interrupt-parent = <&MPIC>; | ||
93 | interrupts = < /*TXEOB*/ 77 0x4 | ||
94 | /*RXEOB*/ 78 0x4 | ||
95 | /*SERR*/ 76 0x4 | ||
96 | /*TXDE*/ 79 0x4 | ||
97 | /*RXDE*/ 80 0x4>; | ||
98 | }; | ||
99 | |||
100 | SATA0: sata@30000010000 { | ||
101 | compatible = "ibm,476gtr-ahci"; | ||
102 | reg = <0x300 0x00010000 0x0 0x10000>; | ||
103 | interrupt-parent = <&MPIC>; | ||
104 | interrupts = <93 2>; | ||
105 | }; | ||
106 | |||
107 | EHCI0: ehci@30010000000 { | ||
108 | compatible = "ibm,476gtr-ehci", "generic-ehci"; | ||
109 | reg = <0x300 0x10000000 0x0 0x10000>; | ||
110 | interrupt-parent = <&MPIC>; | ||
111 | interrupts = <85 2>; | ||
112 | }; | ||
113 | |||
114 | SD0: sd@30000000000 { | ||
115 | compatible = "ibm,476gtr-sdhci", "generic-sdhci"; | ||
116 | reg = <0x300 0x00000000 0x0 0x10000>; | ||
117 | interrupts = <91 2>; | ||
118 | interrupt-parent = <&MPIC>; | ||
119 | }; | ||
120 | |||
121 | OHCI0: ohci@30010010000 { | ||
122 | compatible = "ibm,476gtr-ohci", "generic-ohci"; | ||
123 | reg = <0x300 0x10010000 0x0 0x10000>; | ||
124 | interrupt-parent = <&MPIC>; | ||
125 | interrupts = <89 1>; | ||
126 | }; | ||
127 | |||
128 | OHCI1: ohci@30010020000 { | ||
129 | compatible = "ibm,476gtr-ohci", "generic-ohci"; | ||
130 | reg = <0x300 0x10020000 0x0 0x10000>; | ||
131 | interrupt-parent = <&MPIC>; | ||
132 | interrupts = <88 1>; | ||
133 | }; | ||
134 | |||
135 | POB0: opb { | ||
136 | compatible = "ibm,opb-4xx", "ibm,opb"; | ||
137 | #address-cells = <1>; | ||
138 | #size-cells = <1>; | ||
139 | /* Wish there was a nicer way of specifying a full | ||
140 | * 32-bit range | ||
141 | */ | ||
142 | ranges = <0x00000000 0x0000033f 0x00000000 0x80000000 | ||
143 | 0x80000000 0x0000033f 0x80000000 0x80000000>; | ||
144 | clock-frequency = <100000000>; | ||
145 | |||
146 | RGMII0: emac-rgmii-wol@50004 { | ||
147 | compatible = "ibm,rgmii-wol-476gtr", "ibm,rgmii-wol"; | ||
148 | reg = <0x50004 0x00000008>; | ||
149 | has-mdio; | ||
150 | }; | ||
151 | |||
152 | EMAC0: ethernet@30000 { | ||
153 | device_type = "network"; | ||
154 | compatible = "ibm,emac-476gtr", "ibm,emac4sync"; | ||
155 | interrupt-parent = <&EMAC0>; | ||
156 | interrupts = <0x0 0x1>; | ||
157 | #interrupt-cells = <1>; | ||
158 | #address-cells = <0>; | ||
159 | #size-cells = <0>; | ||
160 | interrupt-map = </*Status*/ 0x0 &MPIC 81 0x4 | ||
161 | /*Wake*/ 0x1 &MPIC 82 0x4>; | ||
162 | reg = <0x30000 0x78>; | ||
163 | |||
164 | /* local-mac-address will normally be added by | ||
165 | * the wrapper. If your device doesn't support | ||
166 | * passing data to the wrapper (in the form | ||
167 | * local-mac-addr=<hwaddr>) then you will need | ||
168 | * to set it manually here. */ | ||
169 | //local-mac-address = [000000000000]; | ||
170 | |||
171 | mal-device = <&MAL0>; | ||
172 | mal-tx-channel = <0>; | ||
173 | mal-rx-channel = <0>; | ||
174 | cell-index = <0>; | ||
175 | max-frame-size = <9000>; | ||
176 | rx-fifo-size = <4096>; | ||
177 | tx-fifo-size = <2048>; | ||
178 | rx-fifo-size-gige = <16384>; | ||
179 | phy-mode = "rgmii"; | ||
180 | phy-map = <0x00000000>; | ||
181 | rgmii-wol-device = <&RGMII0>; | ||
182 | has-inverted-stacr-oc; | ||
183 | has-new-stacr-staopc; | ||
184 | }; | ||
185 | |||
186 | UART0: serial@10000 { | ||
187 | device_type = "serial"; | ||
188 | compatible = "ns16750", "ns16550"; | ||
189 | reg = <0x10000 0x00000008>; | ||
190 | virtual-reg = <0xe8010000>; | ||
191 | clock-frequency = <1851851>; | ||
192 | current-speed = <38400>; | ||
193 | interrupt-parent = <&MPIC>; | ||
194 | interrupts = <39 2>; | ||
195 | }; | ||
196 | |||
197 | IIC0: i2c@00000000 { | ||
198 | compatible = "ibm,iic-476gtr", "ibm,iic"; | ||
199 | reg = <0x0 0x00000020>; | ||
200 | interrupt-parent = <&MPIC>; | ||
201 | interrupts = <37 2>; | ||
202 | #address-cells = <1>; | ||
203 | #size-cells = <0>; | ||
204 | rtc@68 { | ||
205 | compatible = "stm,m41t80", "m41st85"; | ||
206 | reg = <0x68>; | ||
207 | }; | ||
208 | }; | ||
209 | |||
210 | IIC1: i2c@00000100 { | ||
211 | compatible = "ibm,iic-476gtr", "ibm,iic"; | ||
212 | reg = <0x100 0x00000020>; | ||
213 | interrupt-parent = <&MPIC>; | ||
214 | interrupts = <38 2>; | ||
215 | #address-cells = <1>; | ||
216 | #size-cells = <0>; | ||
217 | avr@58 { | ||
218 | compatible = "ibm,akebono-avr"; | ||
219 | reg = <0x58>; | ||
220 | }; | ||
221 | }; | ||
222 | |||
223 | FPGA0: fpga@ebc00000 { | ||
224 | compatible = "ibm,akebono-fpga"; | ||
225 | reg = <0xebc00000 0x8>; | ||
226 | }; | ||
227 | }; | ||
228 | |||
229 | PCIE0: pciex@10100000000 { | ||
230 | device_type = "pci"; | ||
231 | #interrupt-cells = <1>; | ||
232 | #size-cells = <2>; | ||
233 | #address-cells = <3>; | ||
234 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
235 | primary; | ||
236 | port = <0x0>; /* port number */ | ||
237 | reg = <0x00000101 0x00000000 0x0 0x10000000 /* Config space access */ | ||
238 | 0x00000100 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
239 | dcr-reg = <0xc0 0x20>; | ||
240 | |||
241 | // pci_space < pci_addr > < cpu_addr > < size > | ||
242 | ranges = <0x02000000 0x00000000 0x80000000 0x00000110 0x80000000 0x0 0x80000000 | ||
243 | 0x01000000 0x0 0x0 0x00000140 0x0 0x0 0x00010000>; | ||
244 | |||
245 | /* Inbound starting at 0 to memsize filled in by zImage */ | ||
246 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>; | ||
247 | |||
248 | /* This drives busses 0 to 0xf */ | ||
249 | bus-range = <0x0 0xf>; | ||
250 | |||
251 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
252 | * to invert PCIe legacy interrupts). | ||
253 | * We are de-swizzling here because the numbers are actually for | ||
254 | * port of the root complex virtual P2P bridge. But I want | ||
255 | * to avoid putting a node for it in the tree, so the numbers | ||
256 | * below are basically de-swizzled numbers. | ||
257 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
258 | */ | ||
259 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
260 | interrupt-map = < | ||
261 | 0x0 0x0 0x0 0x1 &MPIC 45 0x2 /* int A */ | ||
262 | 0x0 0x0 0x0 0x2 &MPIC 46 0x2 /* int B */ | ||
263 | 0x0 0x0 0x0 0x3 &MPIC 47 0x2 /* int C */ | ||
264 | 0x0 0x0 0x0 0x4 &MPIC 48 0x2 /* int D */>; | ||
265 | }; | ||
266 | |||
267 | PCIE1: pciex@20100000000 { | ||
268 | device_type = "pci"; | ||
269 | #interrupt-cells = <1>; | ||
270 | #size-cells = <2>; | ||
271 | #address-cells = <3>; | ||
272 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
273 | primary; | ||
274 | port = <0x1>; /* port number */ | ||
275 | reg = <0x00000201 0x00000000 0x0 0x10000000 /* Config space access */ | ||
276 | 0x00000200 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
277 | dcr-reg = <0x100 0x20>; | ||
278 | |||
279 | // pci_space < pci_addr > < cpu_addr > < size > | ||
280 | ranges = <0x02000000 0x00000000 0x80000000 0x00000210 0x80000000 0x0 0x80000000 | ||
281 | 0x01000000 0x0 0x0 0x00000240 0x0 0x0 0x00010000>; | ||
282 | |||
283 | /* Inbound starting at 0 to memsize filled in by zImage */ | ||
284 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>; | ||
285 | |||
286 | /* This drives busses 0 to 0xf */ | ||
287 | bus-range = <0x0 0xf>; | ||
288 | |||
289 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
290 | * to invert PCIe legacy interrupts). | ||
291 | * We are de-swizzling here because the numbers are actually for | ||
292 | * port of the root complex virtual P2P bridge. But I want | ||
293 | * to avoid putting a node for it in the tree, so the numbers | ||
294 | * below are basically de-swizzled numbers. | ||
295 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
296 | */ | ||
297 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
298 | interrupt-map = < | ||
299 | 0x0 0x0 0x0 0x1 &MPIC 53 0x2 /* int A */ | ||
300 | 0x0 0x0 0x0 0x2 &MPIC 54 0x2 /* int B */ | ||
301 | 0x0 0x0 0x0 0x3 &MPIC 55 0x2 /* int C */ | ||
302 | 0x0 0x0 0x0 0x4 &MPIC 56 0x2 /* int D */>; | ||
303 | }; | ||
304 | |||
305 | PCIE2: pciex@18100000000 { | ||
306 | device_type = "pci"; | ||
307 | #interrupt-cells = <1>; | ||
308 | #size-cells = <2>; | ||
309 | #address-cells = <3>; | ||
310 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
311 | primary; | ||
312 | port = <0x2>; /* port number */ | ||
313 | reg = <0x00000181 0x00000000 0x0 0x10000000 /* Config space access */ | ||
314 | 0x00000180 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
315 | dcr-reg = <0xe0 0x20>; | ||
316 | |||
317 | // pci_space < pci_addr > < cpu_addr > < size > | ||
318 | ranges = <0x02000000 0x00000000 0x80000000 0x00000190 0x80000000 0x0 0x80000000 | ||
319 | 0x01000000 0x0 0x0 0x000001c0 0x0 0x0 0x00010000>; | ||
320 | |||
321 | /* Inbound starting at 0 to memsize filled in by zImage */ | ||
322 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>; | ||
323 | |||
324 | /* This drives busses 0 to 0xf */ | ||
325 | bus-range = <0x0 0xf>; | ||
326 | |||
327 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
328 | * to invert PCIe legacy interrupts). | ||
329 | * We are de-swizzling here because the numbers are actually for | ||
330 | * port of the root complex virtual P2P bridge. But I want | ||
331 | * to avoid putting a node for it in the tree, so the numbers | ||
332 | * below are basically de-swizzled numbers. | ||
333 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
334 | */ | ||
335 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
336 | interrupt-map = < | ||
337 | 0x0 0x0 0x0 0x1 &MPIC 61 0x2 /* int A */ | ||
338 | 0x0 0x0 0x0 0x2 &MPIC 62 0x2 /* int B */ | ||
339 | 0x0 0x0 0x0 0x3 &MPIC 63 0x2 /* int C */ | ||
340 | 0x0 0x0 0x0 0x4 &MPIC 64 0x2 /* int D */>; | ||
341 | }; | ||
342 | |||
343 | PCIE3: pciex@28100000000 { | ||
344 | device_type = "pci"; | ||
345 | #interrupt-cells = <1>; | ||
346 | #size-cells = <2>; | ||
347 | #address-cells = <3>; | ||
348 | compatible = "ibm,plb-pciex-476fpe", "ibm,plb-pciex"; | ||
349 | primary; | ||
350 | port = <0x3>; /* port number */ | ||
351 | reg = <0x00000281 0x00000000 0x0 0x10000000 /* Config space access */ | ||
352 | 0x00000280 0x00000000 0x0 0x00001000>; /* UTL Registers space access */ | ||
353 | dcr-reg = <0x120 0x20>; | ||
354 | |||
355 | // pci_space < pci_addr > < cpu_addr > < size > | ||
356 | ranges = <0x02000000 0x00000000 0x80000000 0x00000290 0x80000000 0x0 0x80000000 | ||
357 | 0x01000000 0x0 0x0 0x000002c0 0x0 0x0 0x00010000>; | ||
358 | |||
359 | /* Inbound starting at 0 to memsize filled in by zImage */ | ||
360 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x0>; | ||
361 | |||
362 | /* This drives busses 0 to 0xf */ | ||
363 | bus-range = <0x0 0xf>; | ||
364 | |||
365 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
366 | * to invert PCIe legacy interrupts). | ||
367 | * We are de-swizzling here because the numbers are actually for | ||
368 | * port of the root complex virtual P2P bridge. But I want | ||
369 | * to avoid putting a node for it in the tree, so the numbers | ||
370 | * below are basically de-swizzled numbers. | ||
371 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
372 | */ | ||
373 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
374 | interrupt-map = < | ||
375 | 0x0 0x0 0x0 0x1 &MPIC 69 0x2 /* int A */ | ||
376 | 0x0 0x0 0x0 0x2 &MPIC 70 0x2 /* int B */ | ||
377 | 0x0 0x0 0x0 0x3 &MPIC 71 0x2 /* int C */ | ||
378 | 0x0 0x0 0x0 0x4 &MPIC 72 0x2 /* int D */>; | ||
379 | }; | ||
380 | }; | ||
381 | |||
382 | chosen { | ||
383 | linux,stdout-path = &UART0; | ||
384 | }; | ||
385 | }; | ||
386 |
arch/powerpc/boot/treeboot-akebono.c
File was created | 1 | /* | |
2 | * Copyright ยฉ 2013 Tony Breeds IBM Corporation | ||
3 | * Copyright ยฉ 2013 Alistair Popple IBM Corporation | ||
4 | * | ||
5 | * Based on earlier code: | ||
6 | * Copyright (C) Paul Mackerras 1997. | ||
7 | * | ||
8 | * Matt Porter <mporter@kernel.crashing.org> | ||
9 | * Copyright 2002-2005 MontaVista Software Inc. | ||
10 | * | ||
11 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | ||
12 | * Copyright (c) 2003, 2004 Zultys Technologies | ||
13 | * | ||
14 | * Copyright 2007 David Gibson, IBM Corporation. | ||
15 | * Copyright 2010 Ben. Herrenschmidt, IBM Corporation. | ||
16 | * Copyright ยฉ 2011 David Kleikamp IBM Corporation | ||
17 | * | ||
18 | * This program is free software; you can redistribute it and/or | ||
19 | * modify it under the terms of the GNU General Public License | ||
20 | * as published by the Free Software Foundation; either version | ||
21 | * 2 of the License, or (at your option) any later version. | ||
22 | */ | ||
23 | #include <stdarg.h> | ||
24 | #include <stddef.h> | ||
25 | #include "types.h" | ||
26 | #include "elf.h" | ||
27 | #include "string.h" | ||
28 | #include "stdlib.h" | ||
29 | #include "stdio.h" | ||
30 | #include "page.h" | ||
31 | #include "ops.h" | ||
32 | #include "reg.h" | ||
33 | #include "io.h" | ||
34 | #include "dcr.h" | ||
35 | #include "4xx.h" | ||
36 | #include "44x.h" | ||
37 | #include "libfdt.h" | ||
38 | |||
39 | BSS_STACK(4096); | ||
40 | |||
41 | #define SPRN_PIR 0x11E /* Processor Indentification Register */ | ||
42 | #define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */ | ||
43 | #define MAX_RANKS 0x4 | ||
44 | #define DDR3_MR0CF 0x80010011U | ||
45 | #define CCTL0_MCO2 0x8000080FU | ||
46 | #define CCTL0_MCO3 0x80000810U | ||
47 | #define CCTL0_MCO4 0x80000811U | ||
48 | #define CCTL0_MCO5 0x80000812U | ||
49 | #define CCTL0_MCO6 0x80000813U | ||
50 | |||
51 | static unsigned long long ibm_akebono_memsize; | ||
52 | static long long unsigned mac_addr; | ||
53 | |||
54 | static unsigned long long ibm_akebono_detect_memsize(void) | ||
55 | { | ||
56 | u32 reg; | ||
57 | unsigned i; | ||
58 | unsigned long long memsize = 0; | ||
59 | |||
60 | for (i = 0; i < MAX_RANKS; i++) { | ||
61 | reg = mfdcrx(DDR3_MR0CF + i); | ||
62 | |||
63 | if (!(reg & 1)) | ||
64 | continue; | ||
65 | |||
66 | reg &= 0x0000f000; | ||
67 | reg >>= 12; | ||
68 | memsize += (0x800000ULL << reg); | ||
69 | } | ||
70 | |||
71 | return memsize; | ||
72 | } | ||
73 | |||
74 | static void ibm_akebono_fixups(void) | ||
75 | { | ||
76 | void *emac; | ||
77 | u32 reg; | ||
78 | void *devp = finddevice("/"); | ||
79 | u32 dma_ranges[7]; | ||
80 | |||
81 | dt_fixup_memory(0x0ULL, ibm_akebono_memsize); | ||
82 | |||
83 | while ((devp = find_node_by_devtype(devp, "pci"))) { | ||
84 | if (getprop(devp, "dma-ranges", dma_ranges, | ||
85 | sizeof(dma_ranges)) < 0) { | ||
86 | printf("%s: Failed to get dma-ranges\r\n", __func__); | ||
87 | continue; | ||
88 | } | ||
89 | |||
90 | dma_ranges[5] = ibm_akebono_memsize >> 32; | ||
91 | dma_ranges[6] = ibm_akebono_memsize & 0xffffffffUL; | ||
92 | |||
93 | setprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges)); | ||
94 | } | ||
95 | |||
96 | /* Fixup the SD timeout frequency */ | ||
97 | mtdcrx(CCTL0_MCO4, 0x1); | ||
98 | |||
99 | /* Disable SD high-speed mode (which seems to be broken) */ | ||
100 | reg = mfdcrx(CCTL0_MCO2) & ~0x2; | ||
101 | mtdcrx(CCTL0_MCO2, reg); | ||
102 | |||
103 | /* Set the MAC address */ | ||
104 | emac = finddevice("/plb/opb/ethernet"); | ||
105 | if (emac > 0) { | ||
106 | if (mac_addr) | ||
107 | setprop(emac, "local-mac-address", | ||
108 | ((u8 *) &mac_addr) + 2 , 6); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | void platform_init(char *userdata) | ||
113 | { | ||
114 | unsigned long end_of_ram, avail_ram; | ||
115 | u32 pir_reg; | ||
116 | int node, size; | ||
117 | const u32 *timebase; | ||
118 | int len, i, userdata_len; | ||
119 | char *end; | ||
120 | |||
121 | userdata[USERDATA_LEN - 1] = '\0'; | ||
122 | userdata_len = strlen(userdata); | ||
123 | for (i = 0; i < userdata_len - 15; i++) { | ||
124 | if (strncmp(&userdata[i], "local-mac-addr=", 15) == 0) { | ||
125 | if (i > 0 && userdata[i - 1] != ' ') { | ||
126 | /* We've only found a substring ending | ||
127 | * with local-mac-addr so this isn't | ||
128 | * our mac address. */ | ||
129 | continue; | ||
130 | } | ||
131 | |||
132 | mac_addr = strtoull(&userdata[i + 15], &end, 16); | ||
133 | |||
134 | /* Remove the "local-mac-addr=<...>" from the kernel | ||
135 | * command line, including the tailing space if | ||
136 | * present. */ | ||
137 | if (*end == ' ') | ||
138 | end++; | ||
139 | |||
140 | len = ((int) end) - ((int) &userdata[i]); | ||
141 | memmove(&userdata[i], end, | ||
142 | userdata_len - (len + i) + 1); | ||
143 | break; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | loader_info.cmdline = userdata; | ||
148 | loader_info.cmdline_len = 256; | ||
149 | |||
150 | ibm_akebono_memsize = ibm_akebono_detect_memsize(); | ||
151 | if (ibm_akebono_memsize >> 32) | ||
152 | end_of_ram = ~0UL; | ||
153 | else | ||
154 | end_of_ram = ibm_akebono_memsize; | ||
155 | avail_ram = end_of_ram - (unsigned long)_end; | ||
156 | |||
157 | simple_alloc_init(_end, avail_ram, 128, 64); | ||
158 | platform_ops.fixups = ibm_akebono_fixups; | ||
159 | platform_ops.exit = ibm44x_dbcr_reset; | ||
160 | pir_reg = mfspr(SPRN_PIR); | ||
161 | |||
162 | /* Make sure FDT blob is sane */ | ||
163 | if (fdt_check_header(_dtb_start) != 0) | ||
164 | fatal("Invalid device tree blob\n"); | ||
165 | |||
166 | node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type", | ||
167 | "cpu", sizeof("cpu")); | ||
168 | if (!node) | ||
169 | fatal("Cannot find cpu node\n"); | ||
170 | timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size); | ||
171 | if (timebase && (size == 4)) | ||
172 | timebase_period_ns = 1000000000 / *timebase; | ||
173 | |||
174 | fdt_set_boot_cpuid_phys(_dtb_start, pir_reg); | ||
175 | fdt_init(_dtb_start); | ||
176 | |||
177 | serial_console_init(); | ||
178 | } | ||
179 |
arch/powerpc/boot/wrapper
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | # Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus@samba.org> | 3 | # Copyright (C) 2006 Paul Mackerras, IBM Corporation <paulus@samba.org> |
4 | # This program may be used under the terms of version 2 of the GNU | 4 | # This program may be used under the terms of version 2 of the GNU |
5 | # General Public License. | 5 | # General Public License. |
6 | 6 | ||
7 | # This script takes a kernel binary and optionally an initrd image | 7 | # This script takes a kernel binary and optionally an initrd image |
8 | # and/or a device-tree blob, and creates a bootable zImage for a | 8 | # and/or a device-tree blob, and creates a bootable zImage for a |
9 | # given platform. | 9 | # given platform. |
10 | 10 | ||
11 | # Options: | 11 | # Options: |
12 | # -o zImage specify output file | 12 | # -o zImage specify output file |
13 | # -p platform specify platform (links in $platform.o) | 13 | # -p platform specify platform (links in $platform.o) |
14 | # -i initrd specify initrd file | 14 | # -i initrd specify initrd file |
15 | # -d devtree specify device-tree blob | 15 | # -d devtree specify device-tree blob |
16 | # -s tree.dts specify device-tree source file (needs dtc installed) | 16 | # -s tree.dts specify device-tree source file (needs dtc installed) |
17 | # -c cache $kernel.strip.gz (use if present & newer, else make) | 17 | # -c cache $kernel.strip.gz (use if present & newer, else make) |
18 | # -C prefix specify command prefix for cross-building tools | 18 | # -C prefix specify command prefix for cross-building tools |
19 | # (strip, objcopy, ld) | 19 | # (strip, objcopy, ld) |
20 | # -D dir specify directory containing data files used by script | 20 | # -D dir specify directory containing data files used by script |
21 | # (default ./arch/powerpc/boot) | 21 | # (default ./arch/powerpc/boot) |
22 | # -W dir specify working directory for temporary files (default .) | 22 | # -W dir specify working directory for temporary files (default .) |
23 | 23 | ||
24 | # Stop execution if any command fails | 24 | # Stop execution if any command fails |
25 | set -e | 25 | set -e |
26 | 26 | ||
27 | # Allow for verbose output | 27 | # Allow for verbose output |
28 | if [ "$V" = 1 ]; then | 28 | if [ "$V" = 1 ]; then |
29 | set -x | 29 | set -x |
30 | fi | 30 | fi |
31 | 31 | ||
32 | # defaults | 32 | # defaults |
33 | kernel= | 33 | kernel= |
34 | ofile=zImage | 34 | ofile=zImage |
35 | platform=of | 35 | platform=of |
36 | initrd= | 36 | initrd= |
37 | dtb= | 37 | dtb= |
38 | dts= | 38 | dts= |
39 | cacheit= | 39 | cacheit= |
40 | binary= | 40 | binary= |
41 | gzip=.gz | 41 | gzip=.gz |
42 | pie= | 42 | pie= |
43 | format= | 43 | format= |
44 | 44 | ||
45 | # cross-compilation prefix | 45 | # cross-compilation prefix |
46 | CROSS= | 46 | CROSS= |
47 | 47 | ||
48 | # mkimage wrapper script | 48 | # mkimage wrapper script |
49 | MKIMAGE=$srctree/scripts/mkuboot.sh | 49 | MKIMAGE=$srctree/scripts/mkuboot.sh |
50 | 50 | ||
51 | # directory for object and other files used by this script | 51 | # directory for object and other files used by this script |
52 | object=arch/powerpc/boot | 52 | object=arch/powerpc/boot |
53 | objbin=$object | 53 | objbin=$object |
54 | dtc=scripts/dtc/dtc | 54 | dtc=scripts/dtc/dtc |
55 | 55 | ||
56 | # directory for working files | 56 | # directory for working files |
57 | tmpdir=. | 57 | tmpdir=. |
58 | 58 | ||
59 | usage() { | 59 | usage() { |
60 | echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2 | 60 | echo 'Usage: wrapper [-o output] [-p platform] [-i initrd]' >&2 |
61 | echo ' [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2 | 61 | echo ' [-d devtree] [-s tree.dts] [-c] [-C cross-prefix]' >&2 |
62 | echo ' [-D datadir] [-W workingdir] [--no-gzip] [vmlinux]' >&2 | 62 | echo ' [-D datadir] [-W workingdir] [--no-gzip] [vmlinux]' >&2 |
63 | exit 1 | 63 | exit 1 |
64 | } | 64 | } |
65 | 65 | ||
66 | while [ "$#" -gt 0 ]; do | 66 | while [ "$#" -gt 0 ]; do |
67 | case "$1" in | 67 | case "$1" in |
68 | -o) | 68 | -o) |
69 | shift | 69 | shift |
70 | [ "$#" -gt 0 ] || usage | 70 | [ "$#" -gt 0 ] || usage |
71 | ofile="$1" | 71 | ofile="$1" |
72 | ;; | 72 | ;; |
73 | -p) | 73 | -p) |
74 | shift | 74 | shift |
75 | [ "$#" -gt 0 ] || usage | 75 | [ "$#" -gt 0 ] || usage |
76 | platform="$1" | 76 | platform="$1" |
77 | ;; | 77 | ;; |
78 | -i) | 78 | -i) |
79 | shift | 79 | shift |
80 | [ "$#" -gt 0 ] || usage | 80 | [ "$#" -gt 0 ] || usage |
81 | initrd="$1" | 81 | initrd="$1" |
82 | ;; | 82 | ;; |
83 | -d) | 83 | -d) |
84 | shift | 84 | shift |
85 | [ "$#" -gt 0 ] || usage | 85 | [ "$#" -gt 0 ] || usage |
86 | dtb="$1" | 86 | dtb="$1" |
87 | ;; | 87 | ;; |
88 | -s) | 88 | -s) |
89 | shift | 89 | shift |
90 | [ "$#" -gt 0 ] || usage | 90 | [ "$#" -gt 0 ] || usage |
91 | dts="$1" | 91 | dts="$1" |
92 | ;; | 92 | ;; |
93 | -c) | 93 | -c) |
94 | cacheit=y | 94 | cacheit=y |
95 | ;; | 95 | ;; |
96 | -C) | 96 | -C) |
97 | shift | 97 | shift |
98 | [ "$#" -gt 0 ] || usage | 98 | [ "$#" -gt 0 ] || usage |
99 | CROSS="$1" | 99 | CROSS="$1" |
100 | ;; | 100 | ;; |
101 | -D) | 101 | -D) |
102 | shift | 102 | shift |
103 | [ "$#" -gt 0 ] || usage | 103 | [ "$#" -gt 0 ] || usage |
104 | object="$1" | 104 | object="$1" |
105 | objbin="$1" | 105 | objbin="$1" |
106 | ;; | 106 | ;; |
107 | -W) | 107 | -W) |
108 | shift | 108 | shift |
109 | [ "$#" -gt 0 ] || usage | 109 | [ "$#" -gt 0 ] || usage |
110 | tmpdir="$1" | 110 | tmpdir="$1" |
111 | ;; | 111 | ;; |
112 | --no-gzip) | 112 | --no-gzip) |
113 | gzip= | 113 | gzip= |
114 | ;; | 114 | ;; |
115 | -?) | 115 | -?) |
116 | usage | 116 | usage |
117 | ;; | 117 | ;; |
118 | *) | 118 | *) |
119 | [ -z "$kernel" ] || usage | 119 | [ -z "$kernel" ] || usage |
120 | kernel="$1" | 120 | kernel="$1" |
121 | ;; | 121 | ;; |
122 | esac | 122 | esac |
123 | shift | 123 | shift |
124 | done | 124 | done |
125 | 125 | ||
126 | if [ -n "$dts" ]; then | 126 | if [ -n "$dts" ]; then |
127 | if [ ! -r "$dts" -a -r "$object/dts/$dts" ]; then | 127 | if [ ! -r "$dts" -a -r "$object/dts/$dts" ]; then |
128 | dts="$object/dts/$dts" | 128 | dts="$object/dts/$dts" |
129 | fi | 129 | fi |
130 | if [ -z "$dtb" ]; then | 130 | if [ -z "$dtb" ]; then |
131 | dtb="$platform.dtb" | 131 | dtb="$platform.dtb" |
132 | fi | 132 | fi |
133 | $dtc -O dtb -o "$dtb" -b 0 "$dts" | 133 | $dtc -O dtb -o "$dtb" -b 0 "$dts" |
134 | fi | 134 | fi |
135 | 135 | ||
136 | if [ -z "$kernel" ]; then | 136 | if [ -z "$kernel" ]; then |
137 | kernel=vmlinux | 137 | kernel=vmlinux |
138 | fi | 138 | fi |
139 | 139 | ||
140 | elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" | 140 | elfformat="`${CROSS}objdump -p "$kernel" | grep 'file format' | awk '{print $4}'`" |
141 | case "$elfformat" in | 141 | case "$elfformat" in |
142 | elf64-powerpcle) format=elf64lppc ;; | 142 | elf64-powerpcle) format=elf64lppc ;; |
143 | elf64-powerpc) format=elf32ppc ;; | 143 | elf64-powerpc) format=elf32ppc ;; |
144 | elf32-powerpc) format=elf32ppc ;; | 144 | elf32-powerpc) format=elf32ppc ;; |
145 | esac | 145 | esac |
146 | 146 | ||
147 | 147 | ||
148 | platformo=$object/"$platform".o | 148 | platformo=$object/"$platform".o |
149 | lds=$object/zImage.lds | 149 | lds=$object/zImage.lds |
150 | ext=strip | 150 | ext=strip |
151 | objflags=-S | 151 | objflags=-S |
152 | tmp=$tmpdir/zImage.$$.o | 152 | tmp=$tmpdir/zImage.$$.o |
153 | ksection=.kernel:vmlinux.strip | 153 | ksection=.kernel:vmlinux.strip |
154 | isection=.kernel:initrd | 154 | isection=.kernel:initrd |
155 | link_address='0x400000' | 155 | link_address='0x400000' |
156 | make_space=y | 156 | make_space=y |
157 | 157 | ||
158 | case "$platform" in | 158 | case "$platform" in |
159 | of) | 159 | of) |
160 | platformo="$object/of.o $object/epapr.o" | 160 | platformo="$object/of.o $object/epapr.o" |
161 | make_space=n | 161 | make_space=n |
162 | ;; | 162 | ;; |
163 | pseries) | 163 | pseries) |
164 | platformo="$object/pseries-head.o $object/of.o $object/epapr.o" | 164 | platformo="$object/pseries-head.o $object/of.o $object/epapr.o" |
165 | link_address='0x4000000' | 165 | link_address='0x4000000' |
166 | if [ "$format" != "elf32ppc" ]; then | 166 | if [ "$format" != "elf32ppc" ]; then |
167 | link_address= | 167 | link_address= |
168 | pie=-pie | 168 | pie=-pie |
169 | fi | 169 | fi |
170 | make_space=n | 170 | make_space=n |
171 | ;; | 171 | ;; |
172 | maple) | 172 | maple) |
173 | platformo="$object/of.o $object/epapr.o" | 173 | platformo="$object/of.o $object/epapr.o" |
174 | link_address='0x400000' | 174 | link_address='0x400000' |
175 | make_space=n | 175 | make_space=n |
176 | ;; | 176 | ;; |
177 | pmac|chrp) | 177 | pmac|chrp) |
178 | platformo="$object/of.o $object/epapr.o" | 178 | platformo="$object/of.o $object/epapr.o" |
179 | make_space=n | 179 | make_space=n |
180 | ;; | 180 | ;; |
181 | coff) | 181 | coff) |
182 | platformo="$object/crt0.o $object/of.o $object/epapr.o" | 182 | platformo="$object/crt0.o $object/of.o $object/epapr.o" |
183 | lds=$object/zImage.coff.lds | 183 | lds=$object/zImage.coff.lds |
184 | link_address='0x500000' | 184 | link_address='0x500000' |
185 | make_space=n | 185 | make_space=n |
186 | pie= | 186 | pie= |
187 | ;; | 187 | ;; |
188 | miboot|uboot*) | 188 | miboot|uboot*) |
189 | # miboot and U-boot want just the bare bits, not an ELF binary | 189 | # miboot and U-boot want just the bare bits, not an ELF binary |
190 | ext=bin | 190 | ext=bin |
191 | objflags="-O binary" | 191 | objflags="-O binary" |
192 | tmp="$ofile" | 192 | tmp="$ofile" |
193 | ksection=image | 193 | ksection=image |
194 | isection=initrd | 194 | isection=initrd |
195 | ;; | 195 | ;; |
196 | cuboot*) | 196 | cuboot*) |
197 | binary=y | 197 | binary=y |
198 | gzip= | 198 | gzip= |
199 | case "$platform" in | 199 | case "$platform" in |
200 | *-mpc866ads|*-mpc885ads|*-adder875*|*-ep88xc) | 200 | *-mpc866ads|*-mpc885ads|*-adder875*|*-ep88xc) |
201 | platformo=$object/cuboot-8xx.o | 201 | platformo=$object/cuboot-8xx.o |
202 | ;; | 202 | ;; |
203 | *5200*|*-motionpro) | 203 | *5200*|*-motionpro) |
204 | platformo=$object/cuboot-52xx.o | 204 | platformo=$object/cuboot-52xx.o |
205 | ;; | 205 | ;; |
206 | *-pq2fads|*-ep8248e|*-mpc8272*|*-storcenter) | 206 | *-pq2fads|*-ep8248e|*-mpc8272*|*-storcenter) |
207 | platformo=$object/cuboot-pq2.o | 207 | platformo=$object/cuboot-pq2.o |
208 | ;; | 208 | ;; |
209 | *-mpc824*) | 209 | *-mpc824*) |
210 | platformo=$object/cuboot-824x.o | 210 | platformo=$object/cuboot-824x.o |
211 | ;; | 211 | ;; |
212 | *-mpc83*|*-asp834x*) | 212 | *-mpc83*|*-asp834x*) |
213 | platformo=$object/cuboot-83xx.o | 213 | platformo=$object/cuboot-83xx.o |
214 | ;; | 214 | ;; |
215 | *-tqm8541|*-mpc8560*|*-tqm8560|*-tqm8555|*-ksi8560*) | 215 | *-tqm8541|*-mpc8560*|*-tqm8560|*-tqm8555|*-ksi8560*) |
216 | platformo=$object/cuboot-85xx-cpm2.o | 216 | platformo=$object/cuboot-85xx-cpm2.o |
217 | ;; | 217 | ;; |
218 | *-mpc85*|*-tqm85*|*-sbc85*) | 218 | *-mpc85*|*-tqm85*|*-sbc85*) |
219 | platformo=$object/cuboot-85xx.o | 219 | platformo=$object/cuboot-85xx.o |
220 | ;; | 220 | ;; |
221 | *-amigaone) | 221 | *-amigaone) |
222 | link_address='0x800000' | 222 | link_address='0x800000' |
223 | ;; | 223 | ;; |
224 | esac | 224 | esac |
225 | ;; | 225 | ;; |
226 | ps3) | 226 | ps3) |
227 | platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o" | 227 | platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o" |
228 | lds=$object/zImage.ps3.lds | 228 | lds=$object/zImage.ps3.lds |
229 | gzip= | 229 | gzip= |
230 | ext=bin | 230 | ext=bin |
231 | objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data" | 231 | objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data" |
232 | ksection=.kernel:vmlinux.bin | 232 | ksection=.kernel:vmlinux.bin |
233 | isection=.kernel:initrd | 233 | isection=.kernel:initrd |
234 | link_address='' | 234 | link_address='' |
235 | make_space=n | 235 | make_space=n |
236 | pie= | 236 | pie= |
237 | ;; | 237 | ;; |
238 | ep88xc|ep405|ep8248e) | 238 | ep88xc|ep405|ep8248e) |
239 | platformo="$object/fixed-head.o $object/$platform.o" | 239 | platformo="$object/fixed-head.o $object/$platform.o" |
240 | binary=y | 240 | binary=y |
241 | ;; | 241 | ;; |
242 | adder875-redboot) | 242 | adder875-redboot) |
243 | platformo="$object/fixed-head.o $object/redboot-8xx.o" | 243 | platformo="$object/fixed-head.o $object/redboot-8xx.o" |
244 | binary=y | 244 | binary=y |
245 | ;; | 245 | ;; |
246 | simpleboot-virtex405-*) | 246 | simpleboot-virtex405-*) |
247 | platformo="$object/virtex405-head.o $object/simpleboot.o $object/virtex.o" | 247 | platformo="$object/virtex405-head.o $object/simpleboot.o $object/virtex.o" |
248 | binary=y | 248 | binary=y |
249 | ;; | 249 | ;; |
250 | simpleboot-virtex440-*) | 250 | simpleboot-virtex440-*) |
251 | platformo="$object/fixed-head.o $object/simpleboot.o $object/virtex.o" | 251 | platformo="$object/fixed-head.o $object/simpleboot.o $object/virtex.o" |
252 | binary=y | 252 | binary=y |
253 | ;; | 253 | ;; |
254 | simpleboot-*) | 254 | simpleboot-*) |
255 | platformo="$object/fixed-head.o $object/simpleboot.o" | 255 | platformo="$object/fixed-head.o $object/simpleboot.o" |
256 | binary=y | 256 | binary=y |
257 | ;; | 257 | ;; |
258 | asp834x-redboot) | 258 | asp834x-redboot) |
259 | platformo="$object/fixed-head.o $object/redboot-83xx.o" | 259 | platformo="$object/fixed-head.o $object/redboot-83xx.o" |
260 | binary=y | 260 | binary=y |
261 | ;; | 261 | ;; |
262 | xpedite52*) | 262 | xpedite52*) |
263 | link_address='0x1400000' | 263 | link_address='0x1400000' |
264 | platformo=$object/cuboot-85xx.o | 264 | platformo=$object/cuboot-85xx.o |
265 | ;; | 265 | ;; |
266 | gamecube|wii) | 266 | gamecube|wii) |
267 | link_address='0x600000' | 267 | link_address='0x600000' |
268 | platformo="$object/$platform-head.o $object/$platform.o" | 268 | platformo="$object/$platform-head.o $object/$platform.o" |
269 | ;; | 269 | ;; |
270 | treeboot-currituck) | 270 | treeboot-currituck) |
271 | link_address='0x1000000' | 271 | link_address='0x1000000' |
272 | ;; | 272 | ;; |
273 | treeboot-akebono) | ||
274 | link_address='0x1000000' | ||
275 | ;; | ||
273 | treeboot-iss4xx-mpic) | 276 | treeboot-iss4xx-mpic) |
274 | platformo="$object/treeboot-iss4xx.o" | 277 | platformo="$object/treeboot-iss4xx.o" |
275 | ;; | 278 | ;; |
276 | epapr) | 279 | epapr) |
277 | platformo="$object/epapr.o $object/epapr-wrapper.o" | 280 | platformo="$object/epapr.o $object/epapr-wrapper.o" |
278 | link_address='0x20000000' | 281 | link_address='0x20000000' |
279 | pie=-pie | 282 | pie=-pie |
280 | ;; | 283 | ;; |
281 | mvme5100) | 284 | mvme5100) |
282 | platformo="$object/fixed-head.o $object/mvme5100.o" | 285 | platformo="$object/fixed-head.o $object/mvme5100.o" |
283 | binary=y | 286 | binary=y |
284 | ;; | 287 | ;; |
285 | esac | 288 | esac |
286 | 289 | ||
287 | vmz="$tmpdir/`basename \"$kernel\"`.$ext" | 290 | vmz="$tmpdir/`basename \"$kernel\"`.$ext" |
288 | if [ -z "$cacheit" -o ! -f "$vmz$gzip" -o "$vmz$gzip" -ot "$kernel" ]; then | 291 | if [ -z "$cacheit" -o ! -f "$vmz$gzip" -o "$vmz$gzip" -ot "$kernel" ]; then |
289 | ${CROSS}objcopy $objflags "$kernel" "$vmz.$$" | 292 | ${CROSS}objcopy $objflags "$kernel" "$vmz.$$" |
290 | 293 | ||
291 | strip_size=$(stat -c %s $vmz.$$) | 294 | strip_size=$(stat -c %s $vmz.$$) |
292 | 295 | ||
293 | if [ -n "$gzip" ]; then | 296 | if [ -n "$gzip" ]; then |
294 | gzip -n -f -9 "$vmz.$$" | 297 | gzip -n -f -9 "$vmz.$$" |
295 | fi | 298 | fi |
296 | 299 | ||
297 | if [ -n "$cacheit" ]; then | 300 | if [ -n "$cacheit" ]; then |
298 | mv -f "$vmz.$$$gzip" "$vmz$gzip" | 301 | mv -f "$vmz.$$$gzip" "$vmz$gzip" |
299 | else | 302 | else |
300 | vmz="$vmz.$$" | 303 | vmz="$vmz.$$" |
301 | fi | 304 | fi |
302 | else | 305 | else |
303 | # Calculate the vmlinux.strip size | 306 | # Calculate the vmlinux.strip size |
304 | ${CROSS}objcopy $objflags "$kernel" "$vmz.$$" | 307 | ${CROSS}objcopy $objflags "$kernel" "$vmz.$$" |
305 | strip_size=$(stat -c %s $vmz.$$) | 308 | strip_size=$(stat -c %s $vmz.$$) |
306 | rm -f $vmz.$$ | 309 | rm -f $vmz.$$ |
307 | fi | 310 | fi |
308 | 311 | ||
309 | if [ "$make_space" = "y" ]; then | 312 | if [ "$make_space" = "y" ]; then |
310 | # Round the size to next higher MB limit | 313 | # Round the size to next higher MB limit |
311 | round_size=$(((strip_size + 0xfffff) & 0xfff00000)) | 314 | round_size=$(((strip_size + 0xfffff) & 0xfff00000)) |
312 | 315 | ||
313 | round_size=0x$(printf "%x" $round_size) | 316 | round_size=0x$(printf "%x" $round_size) |
314 | link_addr=$(printf "%d" $link_address) | 317 | link_addr=$(printf "%d" $link_address) |
315 | 318 | ||
316 | if [ $link_addr -lt $strip_size ]; then | 319 | if [ $link_addr -lt $strip_size ]; then |
317 | echo "INFO: Uncompressed kernel (size 0x$(printf "%x\n" $strip_size))" \ | 320 | echo "INFO: Uncompressed kernel (size 0x$(printf "%x\n" $strip_size))" \ |
318 | "overlaps the address of the wrapper($link_address)" | 321 | "overlaps the address of the wrapper($link_address)" |
319 | echo "INFO: Fixing the link_address of wrapper to ($round_size)" | 322 | echo "INFO: Fixing the link_address of wrapper to ($round_size)" |
320 | link_address=$round_size | 323 | link_address=$round_size |
321 | fi | 324 | fi |
322 | fi | 325 | fi |
323 | 326 | ||
324 | vmz="$vmz$gzip" | 327 | vmz="$vmz$gzip" |
325 | 328 | ||
326 | # Extract kernel version information, some platforms want to include | 329 | # Extract kernel version information, some platforms want to include |
327 | # it in the image header | 330 | # it in the image header |
328 | version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \ | 331 | version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \ |
329 | cut -d' ' -f3` | 332 | cut -d' ' -f3` |
330 | if [ -n "$version" ]; then | 333 | if [ -n "$version" ]; then |
331 | uboot_version="-n Linux-$version" | 334 | uboot_version="-n Linux-$version" |
332 | fi | 335 | fi |
333 | 336 | ||
334 | # physical offset of kernel image | 337 | # physical offset of kernel image |
335 | membase=`${CROSS}objdump -p "$kernel" | grep -m 1 LOAD | awk '{print $7}'` | 338 | membase=`${CROSS}objdump -p "$kernel" | grep -m 1 LOAD | awk '{print $7}'` |
336 | 339 | ||
337 | case "$platform" in | 340 | case "$platform" in |
338 | uboot) | 341 | uboot) |
339 | rm -f "$ofile" | 342 | rm -f "$ofile" |
340 | ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a $membase -e $membase \ | 343 | ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a $membase -e $membase \ |
341 | $uboot_version -d "$vmz" "$ofile" | 344 | $uboot_version -d "$vmz" "$ofile" |
342 | if [ -z "$cacheit" ]; then | 345 | if [ -z "$cacheit" ]; then |
343 | rm -f "$vmz" | 346 | rm -f "$vmz" |
344 | fi | 347 | fi |
345 | exit 0 | 348 | exit 0 |
346 | ;; | 349 | ;; |
347 | uboot-obs600) | 350 | uboot-obs600) |
348 | rm -f "$ofile" | 351 | rm -f "$ofile" |
349 | # obs600 wants a multi image with an initrd, so we need to put a fake | 352 | # obs600 wants a multi image with an initrd, so we need to put a fake |
350 | # one in even when building a "normal" image. | 353 | # one in even when building a "normal" image. |
351 | if [ -n "$initrd" ]; then | 354 | if [ -n "$initrd" ]; then |
352 | real_rd="$initrd" | 355 | real_rd="$initrd" |
353 | else | 356 | else |
354 | real_rd=`mktemp` | 357 | real_rd=`mktemp` |
355 | echo "\0" >>"$real_rd" | 358 | echo "\0" >>"$real_rd" |
356 | fi | 359 | fi |
357 | ${MKIMAGE} -A ppc -O linux -T multi -C gzip -a $membase -e $membase \ | 360 | ${MKIMAGE} -A ppc -O linux -T multi -C gzip -a $membase -e $membase \ |
358 | $uboot_version -d "$vmz":"$real_rd":"$dtb" "$ofile" | 361 | $uboot_version -d "$vmz":"$real_rd":"$dtb" "$ofile" |
359 | if [ -z "$initrd" ]; then | 362 | if [ -z "$initrd" ]; then |
360 | rm -f "$real_rd" | 363 | rm -f "$real_rd" |
361 | fi | 364 | fi |
362 | if [ -z "$cacheit" ]; then | 365 | if [ -z "$cacheit" ]; then |
363 | rm -f "$vmz" | 366 | rm -f "$vmz" |
364 | fi | 367 | fi |
365 | exit 0 | 368 | exit 0 |
366 | ;; | 369 | ;; |
367 | esac | 370 | esac |
368 | 371 | ||
369 | addsec() { | 372 | addsec() { |
370 | ${CROSS}objcopy $4 $1 \ | 373 | ${CROSS}objcopy $4 $1 \ |
371 | --add-section=$3="$2" \ | 374 | --add-section=$3="$2" \ |
372 | --set-section-flags=$3=contents,alloc,load,readonly,data | 375 | --set-section-flags=$3=contents,alloc,load,readonly,data |
373 | } | 376 | } |
374 | 377 | ||
375 | addsec $tmp "$vmz" $ksection $object/empty.o | 378 | addsec $tmp "$vmz" $ksection $object/empty.o |
376 | if [ -z "$cacheit" ]; then | 379 | if [ -z "$cacheit" ]; then |
377 | rm -f "$vmz" | 380 | rm -f "$vmz" |
378 | fi | 381 | fi |
379 | 382 | ||
380 | if [ -n "$initrd" ]; then | 383 | if [ -n "$initrd" ]; then |
381 | addsec $tmp "$initrd" $isection | 384 | addsec $tmp "$initrd" $isection |
382 | fi | 385 | fi |
383 | 386 | ||
384 | if [ -n "$dtb" ]; then | 387 | if [ -n "$dtb" ]; then |
385 | addsec $tmp "$dtb" .kernel:dtb | 388 | addsec $tmp "$dtb" .kernel:dtb |
386 | if [ -n "$dts" ]; then | 389 | if [ -n "$dts" ]; then |
387 | rm $dtb | 390 | rm $dtb |
388 | fi | 391 | fi |
389 | fi | 392 | fi |
390 | 393 | ||
391 | if [ "$platform" != "miboot" ]; then | 394 | if [ "$platform" != "miboot" ]; then |
392 | if [ -n "$link_address" ] ; then | 395 | if [ -n "$link_address" ] ; then |
393 | text_start="-Ttext $link_address" | 396 | text_start="-Ttext $link_address" |
394 | fi | 397 | fi |
395 | ${CROSS}ld -m $format -T $lds $text_start $pie -o "$ofile" \ | 398 | ${CROSS}ld -m $format -T $lds $text_start $pie -o "$ofile" \ |
396 | $platformo $tmp $object/wrapper.a | 399 | $platformo $tmp $object/wrapper.a |
397 | rm $tmp | 400 | rm $tmp |
398 | fi | 401 | fi |
399 | 402 | ||
400 | # Some platforms need the zImage's entry point and base address | 403 | # Some platforms need the zImage's entry point and base address |
401 | base=0x`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1` | 404 | base=0x`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1` |
402 | entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3` | 405 | entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3` |
403 | 406 | ||
404 | if [ -n "$binary" ]; then | 407 | if [ -n "$binary" ]; then |
405 | mv "$ofile" "$ofile".elf | 408 | mv "$ofile" "$ofile".elf |
406 | ${CROSS}objcopy -O binary "$ofile".elf "$ofile" | 409 | ${CROSS}objcopy -O binary "$ofile".elf "$ofile" |
407 | fi | 410 | fi |
408 | 411 | ||
409 | # post-processing needed for some platforms | 412 | # post-processing needed for some platforms |
410 | case "$platform" in | 413 | case "$platform" in |
411 | pseries|chrp|maple) | 414 | pseries|chrp|maple) |
412 | $objbin/addnote "$ofile" | 415 | $objbin/addnote "$ofile" |
413 | ;; | 416 | ;; |
414 | coff) | 417 | coff) |
415 | ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" | 418 | ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" |
416 | $objbin/hack-coff "$ofile" | 419 | $objbin/hack-coff "$ofile" |
417 | ;; | 420 | ;; |
418 | cuboot*) | 421 | cuboot*) |
419 | gzip -n -f -9 "$ofile" | 422 | gzip -n -f -9 "$ofile" |
420 | ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \ | 423 | ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \ |
421 | $uboot_version -d "$ofile".gz "$ofile" | 424 | $uboot_version -d "$ofile".gz "$ofile" |
422 | ;; | 425 | ;; |
423 | treeboot*) | 426 | treeboot*) |
424 | mv "$ofile" "$ofile.elf" | 427 | mv "$ofile" "$ofile.elf" |
425 | $objbin/mktree "$ofile.elf" "$ofile" "$base" "$entry" | 428 | $objbin/mktree "$ofile.elf" "$ofile" "$base" "$entry" |
426 | if [ -z "$cacheit" ]; then | 429 | if [ -z "$cacheit" ]; then |
427 | rm -f "$ofile.elf" | 430 | rm -f "$ofile.elf" |
428 | fi | 431 | fi |
429 | exit 0 | 432 | exit 0 |
430 | ;; | 433 | ;; |
431 | ps3) | 434 | ps3) |
432 | # The ps3's loader supports loading a gzipped binary image from flash | 435 | # The ps3's loader supports loading a gzipped binary image from flash |
433 | # rom to ram addr zero. The loader then enters the system reset | 436 | # rom to ram addr zero. The loader then enters the system reset |
434 | # vector at addr 0x100. A bootwrapper overlay is used to arrange for | 437 | # vector at addr 0x100. A bootwrapper overlay is used to arrange for |
435 | # a binary image of the kernel to be at addr zero, and yet have a | 438 | # a binary image of the kernel to be at addr zero, and yet have a |
436 | # suitable bootwrapper entry at 0x100. To construct the final rom | 439 | # suitable bootwrapper entry at 0x100. To construct the final rom |
437 | # image 512 bytes from offset 0x100 is copied to the bootwrapper | 440 | # image 512 bytes from offset 0x100 is copied to the bootwrapper |
438 | # place holder at symbol __system_reset_kernel. The 512 bytes of the | 441 | # place holder at symbol __system_reset_kernel. The 512 bytes of the |
439 | # bootwrapper entry code at symbol __system_reset_overlay is then | 442 | # bootwrapper entry code at symbol __system_reset_overlay is then |
440 | # copied to offset 0x100. At runtime the bootwrapper program copies | 443 | # copied to offset 0x100. At runtime the bootwrapper program copies |
441 | # the data at __system_reset_kernel back to addr 0x100. | 444 | # the data at __system_reset_kernel back to addr 0x100. |
442 | 445 | ||
443 | system_reset_overlay=0x`${CROSS}nm "$ofile" \ | 446 | system_reset_overlay=0x`${CROSS}nm "$ofile" \ |
444 | | grep ' __system_reset_overlay$' \ | 447 | | grep ' __system_reset_overlay$' \ |
445 | | cut -d' ' -f1` | 448 | | cut -d' ' -f1` |
446 | system_reset_overlay=`printf "%d" $system_reset_overlay` | 449 | system_reset_overlay=`printf "%d" $system_reset_overlay` |
447 | system_reset_kernel=0x`${CROSS}nm "$ofile" \ | 450 | system_reset_kernel=0x`${CROSS}nm "$ofile" \ |
448 | | grep ' __system_reset_kernel$' \ | 451 | | grep ' __system_reset_kernel$' \ |
449 | | cut -d' ' -f1` | 452 | | cut -d' ' -f1` |
450 | system_reset_kernel=`printf "%d" $system_reset_kernel` | 453 | system_reset_kernel=`printf "%d" $system_reset_kernel` |
451 | overlay_dest="256" | 454 | overlay_dest="256" |
452 | overlay_size="512" | 455 | overlay_size="512" |
453 | 456 | ||
454 | ${CROSS}objcopy -O binary "$ofile" "$ofile.bin" | 457 | ${CROSS}objcopy -O binary "$ofile" "$ofile.bin" |
455 | 458 | ||
456 | dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ | 459 | dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ |
457 | skip=$overlay_dest seek=$system_reset_kernel \ | 460 | skip=$overlay_dest seek=$system_reset_kernel \ |
458 | count=$overlay_size bs=1 | 461 | count=$overlay_size bs=1 |
459 | 462 | ||
460 | dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ | 463 | dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ |
461 | skip=$system_reset_overlay seek=$overlay_dest \ | 464 | skip=$system_reset_overlay seek=$overlay_dest \ |
462 | count=$overlay_size bs=1 | 465 | count=$overlay_size bs=1 |
463 | 466 | ||
464 | odir="$(dirname "$ofile.bin")" | 467 | odir="$(dirname "$ofile.bin")" |
465 | rm -f "$odir/otheros.bld" | 468 | rm -f "$odir/otheros.bld" |
466 | gzip -n --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld" | 469 | gzip -n --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld" |
467 | ;; | 470 | ;; |
468 | esac | 471 | esac |
469 | 472 |
arch/powerpc/configs/44x/akebono_defconfig
File was created | 1 | CONFIG_44x=y | |
2 | CONFIG_SMP=y | ||
3 | CONFIG_SYSVIPC=y | ||
4 | CONFIG_POSIX_MQUEUE=y | ||
5 | CONFIG_LOG_BUF_SHIFT=14 | ||
6 | CONFIG_BLK_DEV_INITRD=y | ||
7 | CONFIG_RD_BZIP2=y | ||
8 | CONFIG_RD_LZMA=y | ||
9 | CONFIG_RD_XZ=y | ||
10 | CONFIG_EXPERT=y | ||
11 | CONFIG_KALLSYMS_ALL=y | ||
12 | # CONFIG_SLUB_CPU_PARTIAL is not set | ||
13 | CONFIG_PROFILING=y | ||
14 | CONFIG_OPROFILE=y | ||
15 | CONFIG_MODULES=y | ||
16 | CONFIG_MODULE_UNLOAD=y | ||
17 | # CONFIG_BLK_DEV_BSG is not set | ||
18 | # CONFIG_POWERNV_MSI is not set | ||
19 | CONFIG_PPC_47x=y | ||
20 | # CONFIG_EBONY is not set | ||
21 | CONFIG_AKEBONO=y | ||
22 | CONFIG_HIGHMEM=y | ||
23 | CONFIG_HZ_100=y | ||
24 | CONFIG_IRQ_ALL_CPUS=y | ||
25 | # CONFIG_COMPACTION is not set | ||
26 | CONFIG_CMDLINE_BOOL=y | ||
27 | CONFIG_CMDLINE="" | ||
28 | # CONFIG_SUSPEND is not set | ||
29 | CONFIG_PCI_MSI=y | ||
30 | CONFIG_NET=y | ||
31 | CONFIG_PACKET=y | ||
32 | CONFIG_UNIX=y | ||
33 | CONFIG_INET=y | ||
34 | CONFIG_IP_PNP=y | ||
35 | CONFIG_IP_PNP_DHCP=y | ||
36 | CONFIG_IP_PNP_BOOTP=y | ||
37 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
38 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
39 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
40 | # CONFIG_INET_LRO is not set | ||
41 | # CONFIG_IPV6 is not set | ||
42 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
43 | CONFIG_DEVTMPFS=y | ||
44 | CONFIG_DEVTMPFS_MOUNT=y | ||
45 | CONFIG_CONNECTOR=y | ||
46 | CONFIG_MTD=y | ||
47 | CONFIG_MTD_BLOCK=y | ||
48 | CONFIG_MTD_JEDECPROBE=y | ||
49 | CONFIG_MTD_CFI_AMDSTD=y | ||
50 | CONFIG_MTD_PHYSMAP_OF=y | ||
51 | CONFIG_PROC_DEVICETREE=y | ||
52 | CONFIG_BLK_DEV_RAM=y | ||
53 | CONFIG_BLK_DEV_RAM_SIZE=35000 | ||
54 | # CONFIG_SCSI_PROC_FS is not set | ||
55 | CONFIG_BLK_DEV_SD=y | ||
56 | # CONFIG_SCSI_LOWLEVEL is not set | ||
57 | # CONFIG_SATA_PMP is not set | ||
58 | # CONFIG_ATA_SFF is not set | ||
59 | # CONFIG_NET_VENDOR_3COM is not set | ||
60 | # CONFIG_NET_VENDOR_ADAPTEC is not set | ||
61 | # CONFIG_NET_VENDOR_ALTEON is not set | ||
62 | # CONFIG_NET_VENDOR_AMD is not set | ||
63 | # CONFIG_NET_VENDOR_ARC is not set | ||
64 | # CONFIG_NET_VENDOR_ATHEROS is not set | ||
65 | # CONFIG_NET_CADENCE is not set | ||
66 | # CONFIG_NET_VENDOR_BROADCOM is not set | ||
67 | # CONFIG_NET_VENDOR_BROCADE is not set | ||
68 | # CONFIG_NET_VENDOR_CHELSIO is not set | ||
69 | # CONFIG_NET_VENDOR_CISCO is not set | ||
70 | # CONFIG_NET_VENDOR_DEC is not set | ||
71 | # CONFIG_NET_VENDOR_DLINK is not set | ||
72 | # CONFIG_NET_VENDOR_EMULEX is not set | ||
73 | # CONFIG_NET_VENDOR_EXAR is not set | ||
74 | # CONFIG_NET_VENDOR_HP is not set | ||
75 | CONFIG_IBM_EMAC=y | ||
76 | # CONFIG_NET_VENDOR_MARVELL is not set | ||
77 | # CONFIG_NET_VENDOR_MELLANOX is not set | ||
78 | # CONFIG_NET_VENDOR_MICREL is not set | ||
79 | # CONFIG_NET_VENDOR_MYRI is not set | ||
80 | # CONFIG_NET_VENDOR_NATSEMI is not set | ||
81 | # CONFIG_NET_VENDOR_NVIDIA is not set | ||
82 | # CONFIG_NET_VENDOR_OKI is not set | ||
83 | # CONFIG_NET_VENDOR_QLOGIC is not set | ||
84 | # CONFIG_NET_VENDOR_REALTEK is not set | ||
85 | # CONFIG_NET_VENDOR_RDC is not set | ||
86 | # CONFIG_NET_VENDOR_SEEQ is not set | ||
87 | # CONFIG_NET_VENDOR_SILAN is not set | ||
88 | # CONFIG_NET_VENDOR_SIS is not set | ||
89 | # CONFIG_NET_VENDOR_SMSC is not set | ||
90 | # CONFIG_NET_VENDOR_STMICRO is not set | ||
91 | # CONFIG_NET_VENDOR_SUN is not set | ||
92 | # CONFIG_NET_VENDOR_TEHUTI is not set | ||
93 | # CONFIG_NET_VENDOR_TI is not set | ||
94 | # CONFIG_NET_VENDOR_VIA is not set | ||
95 | # CONFIG_NET_VENDOR_WIZNET is not set | ||
96 | # CONFIG_NET_VENDOR_XILINX is not set | ||
97 | # CONFIG_KEYBOARD_ATKBD is not set | ||
98 | # CONFIG_MOUSE_PS2 is not set | ||
99 | # CONFIG_SERIO is not set | ||
100 | # CONFIG_VT is not set | ||
101 | CONFIG_SERIAL_8250=y | ||
102 | # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set | ||
103 | CONFIG_SERIAL_8250_CONSOLE=y | ||
104 | CONFIG_SERIAL_8250_EXTENDED=y | ||
105 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
106 | CONFIG_SERIAL_OF_PLATFORM=y | ||
107 | # CONFIG_HW_RANDOM is not set | ||
108 | CONFIG_I2C_CHARDEV=y | ||
109 | # CONFIG_HWMON is not set | ||
110 | CONFIG_THERMAL=y | ||
111 | # CONFIG_USB_DEFAULT_PERSIST is not set | ||
112 | CONFIG_USB_EHCI_HCD=y | ||
113 | CONFIG_USB_OHCI_HCD=y | ||
114 | # CONFIG_USB_OHCI_HCD_PCI is not set | ||
115 | CONFIG_USB_STORAGE=y | ||
116 | CONFIG_MMC=y | ||
117 | CONFIG_RTC_CLASS=y | ||
118 | CONFIG_RTC_DRV_M41T80=y | ||
119 | CONFIG_EXT2_FS=y | ||
120 | CONFIG_EXT3_FS=y | ||
121 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
122 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
123 | CONFIG_EXT3_FS_SECURITY=y | ||
124 | # CONFIG_DNOTIFY is not set | ||
125 | # CONFIG_INOTIFY_USER is not set | ||
126 | CONFIG_VFAT_FS=y | ||
127 | CONFIG_PROC_KCORE=y | ||
128 | CONFIG_TMPFS=y | ||
129 | CONFIG_CRAMFS=y | ||
130 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
131 | CONFIG_NLS_DEFAULT="n" | ||
132 | CONFIG_NLS_CODEPAGE_437=y | ||
133 | CONFIG_NLS_ISO8859_1=y | ||
134 | CONFIG_DEBUG_INFO=y | ||
135 | CONFIG_DEBUG_FS=y | ||
136 | CONFIG_MAGIC_SYSRQ=y | ||
137 | CONFIG_DETECT_HUNG_TASK=y | ||
138 | CONFIG_XMON=y | ||
139 | CONFIG_XMON_DEFAULT=y | ||
140 | CONFIG_PPC_EARLY_DEBUG=y | ||
141 | CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0x00010000 | ||
142 | CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x33f | ||
143 | CONFIG_CRYPTO_PCBC=y | ||
144 | CONFIG_CRYPTO_MD5=y | ||
145 | CONFIG_CRYPTO_SHA1_PPC=y | ||
146 | CONFIG_CRYPTO_DES=y | ||
147 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
148 | # CONFIG_CRYPTO_HW is not set | ||
149 |
arch/powerpc/platforms/44x/Kconfig
1 | config PPC_47x | 1 | config PPC_47x |
2 | bool "Support for 47x variant" | 2 | bool "Support for 47x variant" |
3 | depends on 44x | 3 | depends on 44x |
4 | default n | 4 | default n |
5 | select MPIC | 5 | select MPIC |
6 | help | 6 | help |
7 | This option enables support for the 47x family of processors and is | 7 | This option enables support for the 47x family of processors and is |
8 | not currently compatible with other 44x or 46x varients | 8 | not currently compatible with other 44x or 46x varients |
9 | 9 | ||
10 | config BAMBOO | 10 | config BAMBOO |
11 | bool "Bamboo" | 11 | bool "Bamboo" |
12 | depends on 44x | 12 | depends on 44x |
13 | default n | 13 | default n |
14 | select PPC44x_SIMPLE | 14 | select PPC44x_SIMPLE |
15 | select 440EP | 15 | select 440EP |
16 | select PCI | 16 | select PCI |
17 | help | 17 | help |
18 | This option enables support for the IBM PPC440EP evaluation board. | 18 | This option enables support for the IBM PPC440EP evaluation board. |
19 | 19 | ||
20 | config BLUESTONE | 20 | config BLUESTONE |
21 | bool "Bluestone" | 21 | bool "Bluestone" |
22 | depends on 44x | 22 | depends on 44x |
23 | default n | 23 | default n |
24 | select PPC44x_SIMPLE | 24 | select PPC44x_SIMPLE |
25 | select APM821xx | 25 | select APM821xx |
26 | select PCI_MSI | 26 | select PCI_MSI |
27 | select PPC4xx_MSI | 27 | select PPC4xx_MSI |
28 | select PPC4xx_PCI_EXPRESS | 28 | select PPC4xx_PCI_EXPRESS |
29 | select IBM_EMAC_RGMII | 29 | select IBM_EMAC_RGMII |
30 | help | 30 | help |
31 | This option enables support for the APM APM821xx Evaluation board. | 31 | This option enables support for the APM APM821xx Evaluation board. |
32 | 32 | ||
33 | config EBONY | 33 | config EBONY |
34 | bool "Ebony" | 34 | bool "Ebony" |
35 | depends on 44x | 35 | depends on 44x |
36 | default y | 36 | default y |
37 | select 440GP | 37 | select 440GP |
38 | select PCI | 38 | select PCI |
39 | select OF_RTC | 39 | select OF_RTC |
40 | help | 40 | help |
41 | This option enables support for the IBM PPC440GP evaluation board. | 41 | This option enables support for the IBM PPC440GP evaluation board. |
42 | 42 | ||
43 | config SAM440EP | 43 | config SAM440EP |
44 | bool "Sam440ep" | 44 | bool "Sam440ep" |
45 | depends on 44x | 45 | depends on 44x |
46 | default n | 46 | default n |
47 | select 440EP | 47 | select 440EP |
48 | select PCI | 48 | select PCI |
49 | help | 49 | help |
50 | This option enables support for the ACube Sam440ep board. | 50 | This option enables support for the ACube Sam440ep board. |
51 | 51 | ||
52 | config SEQUOIA | 52 | config SEQUOIA |
53 | bool "Sequoia" | 53 | bool "Sequoia" |
54 | depends on 44x | 54 | depends on 44x |
55 | default n | 55 | default n |
56 | select PPC44x_SIMPLE | 56 | select PPC44x_SIMPLE |
57 | select 440EPX | 57 | select 440EPX |
58 | help | 58 | help |
59 | This option enables support for the AMCC PPC440EPX evaluation board. | 59 | This option enables support for the AMCC PPC440EPX evaluation board. |
60 | 60 | ||
61 | config TAISHAN | 61 | config TAISHAN |
62 | bool "Taishan" | 62 | bool "Taishan" |
63 | depends on 44x | 63 | depends on 44x |
64 | default n | 64 | default n |
65 | select PPC44x_SIMPLE | 65 | select PPC44x_SIMPLE |
66 | select 440GX | 66 | select 440GX |
67 | select PCI | 67 | select PCI |
68 | help | 68 | help |
69 | This option enables support for the AMCC PPC440GX "Taishan" | 69 | This option enables support for the AMCC PPC440GX "Taishan" |
70 | evaluation board. | 70 | evaluation board. |
71 | 71 | ||
72 | config KATMAI | 72 | config KATMAI |
73 | bool "Katmai" | 73 | bool "Katmai" |
74 | depends on 44x | 74 | depends on 44x |
75 | default n | 75 | default n |
76 | select PPC44x_SIMPLE | 76 | select PPC44x_SIMPLE |
77 | select 440SPe | 77 | select 440SPe |
78 | select PCI | 78 | select PCI |
79 | select PPC4xx_PCI_EXPRESS | 79 | select PPC4xx_PCI_EXPRESS |
80 | select PCI_MSI | 80 | select PCI_MSI |
81 | select PPC4xx_MSI | 81 | select PPC4xx_MSI |
82 | help | 82 | help |
83 | This option enables support for the AMCC PPC440SPe evaluation board. | 83 | This option enables support for the AMCC PPC440SPe evaluation board. |
84 | 84 | ||
85 | config RAINIER | 85 | config RAINIER |
86 | bool "Rainier" | 86 | bool "Rainier" |
87 | depends on 44x | 87 | depends on 44x |
88 | default n | 88 | default n |
89 | select PPC44x_SIMPLE | 89 | select PPC44x_SIMPLE |
90 | select 440GRX | 90 | select 440GRX |
91 | select PCI | 91 | select PCI |
92 | help | 92 | help |
93 | This option enables support for the AMCC PPC440GRX evaluation board. | 93 | This option enables support for the AMCC PPC440GRX evaluation board. |
94 | 94 | ||
95 | config WARP | 95 | config WARP |
96 | bool "PIKA Warp" | 96 | bool "PIKA Warp" |
97 | depends on 44x | 97 | depends on 44x |
98 | default n | 98 | default n |
99 | select 440EP | 99 | select 440EP |
100 | help | 100 | help |
101 | This option enables support for the PIKA Warp(tm) Appliance. The Warp | 101 | This option enables support for the PIKA Warp(tm) Appliance. The Warp |
102 | is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP | 102 | is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP |
103 | stations and trunks. | 103 | stations and trunks. |
104 | 104 | ||
105 | See http://www.pikatechnologies.com/ and follow the "PIKA for Computer | 105 | See http://www.pikatechnologies.com/ and follow the "PIKA for Computer |
106 | Telephony Developers" link for more information. | 106 | Telephony Developers" link for more information. |
107 | 107 | ||
108 | config ARCHES | 108 | config ARCHES |
109 | bool "Arches" | 109 | bool "Arches" |
110 | depends on 44x | 110 | depends on 44x |
111 | default n | 111 | default n |
112 | select PPC44x_SIMPLE | 112 | select PPC44x_SIMPLE |
113 | select 460EX # Odd since it uses 460GT but the effects are the same | 113 | select 460EX # Odd since it uses 460GT but the effects are the same |
114 | select PCI | 114 | select PCI |
115 | select PPC4xx_PCI_EXPRESS | 115 | select PPC4xx_PCI_EXPRESS |
116 | help | 116 | help |
117 | This option enables support for the AMCC Dual PPC460GT evaluation board. | 117 | This option enables support for the AMCC Dual PPC460GT evaluation board. |
118 | 118 | ||
119 | config CANYONLANDS | 119 | config CANYONLANDS |
120 | bool "Canyonlands" | 120 | bool "Canyonlands" |
121 | depends on 44x | 121 | depends on 44x |
122 | default n | 122 | default n |
123 | select 460EX | 123 | select 460EX |
124 | select PCI | 124 | select PCI |
125 | select PPC4xx_PCI_EXPRESS | 125 | select PPC4xx_PCI_EXPRESS |
126 | select PCI_MSI | 126 | select PCI_MSI |
127 | select PPC4xx_MSI | 127 | select PPC4xx_MSI |
128 | select IBM_EMAC_RGMII | 128 | select IBM_EMAC_RGMII |
129 | select IBM_EMAC_ZMII | 129 | select IBM_EMAC_ZMII |
130 | help | 130 | help |
131 | This option enables support for the AMCC PPC460EX evaluation board. | 131 | This option enables support for the AMCC PPC460EX evaluation board. |
132 | 132 | ||
133 | config GLACIER | 133 | config GLACIER |
134 | bool "Glacier" | 134 | bool "Glacier" |
135 | depends on 44x | 135 | depends on 44x |
136 | default n | 136 | default n |
137 | select PPC44x_SIMPLE | 137 | select PPC44x_SIMPLE |
138 | select 460EX # Odd since it uses 460GT but the effects are the same | 138 | select 460EX # Odd since it uses 460GT but the effects are the same |
139 | select PCI | 139 | select PCI |
140 | select PPC4xx_PCI_EXPRESS | 140 | select PPC4xx_PCI_EXPRESS |
141 | select IBM_EMAC_RGMII | 141 | select IBM_EMAC_RGMII |
142 | select IBM_EMAC_ZMII | 142 | select IBM_EMAC_ZMII |
143 | help | 143 | help |
144 | This option enables support for the AMCC PPC460GT evaluation board. | 144 | This option enables support for the AMCC PPC460GT evaluation board. |
145 | 145 | ||
146 | config REDWOOD | 146 | config REDWOOD |
147 | bool "Redwood" | 147 | bool "Redwood" |
148 | depends on 44x | 148 | depends on 44x |
149 | default n | 149 | default n |
150 | select PPC44x_SIMPLE | 150 | select PPC44x_SIMPLE |
151 | select 460SX | 151 | select 460SX |
152 | select PCI | 152 | select PCI |
153 | select PPC4xx_PCI_EXPRESS | 153 | select PPC4xx_PCI_EXPRESS |
154 | select PCI_MSI | 154 | select PCI_MSI |
155 | select PPC4xx_MSI | 155 | select PPC4xx_MSI |
156 | help | 156 | help |
157 | This option enables support for the AMCC PPC460SX Redwood board. | 157 | This option enables support for the AMCC PPC460SX Redwood board. |
158 | 158 | ||
159 | config EIGER | 159 | config EIGER |
160 | bool "Eiger" | 160 | bool "Eiger" |
161 | depends on 44x | 161 | depends on 44x |
162 | default n | 162 | default n |
163 | select PPC44x_SIMPLE | 163 | select PPC44x_SIMPLE |
164 | select 460SX | 164 | select 460SX |
165 | select PCI | 165 | select PCI |
166 | select PPC4xx_PCI_EXPRESS | 166 | select PPC4xx_PCI_EXPRESS |
167 | select IBM_EMAC_RGMII | 167 | select IBM_EMAC_RGMII |
168 | help | 168 | help |
169 | This option enables support for the AMCC PPC460SX evaluation board. | 169 | This option enables support for the AMCC PPC460SX evaluation board. |
170 | 170 | ||
171 | config YOSEMITE | 171 | config YOSEMITE |
172 | bool "Yosemite" | 172 | bool "Yosemite" |
173 | depends on 44x | 173 | depends on 44x |
174 | default n | 174 | default n |
175 | select PPC44x_SIMPLE | 175 | select PPC44x_SIMPLE |
176 | select 440EP | 176 | select 440EP |
177 | select PCI | 177 | select PCI |
178 | help | 178 | help |
179 | This option enables support for the AMCC PPC440EP evaluation board. | 179 | This option enables support for the AMCC PPC440EP evaluation board. |
180 | 180 | ||
181 | config ISS4xx | 181 | config ISS4xx |
182 | bool "ISS 4xx Simulator" | 182 | bool "ISS 4xx Simulator" |
183 | depends on (44x || 40x) | 183 | depends on (44x || 40x) |
184 | default n | 184 | default n |
185 | select 405GP if 40x | 185 | select 405GP if 40x |
186 | select 440GP if 44x && !PPC_47x | 186 | select 440GP if 44x && !PPC_47x |
187 | select PPC_FPU | 187 | select PPC_FPU |
188 | select OF_RTC | 188 | select OF_RTC |
189 | help | 189 | help |
190 | This option enables support for the IBM ISS simulation environment | 190 | This option enables support for the IBM ISS simulation environment |
191 | 191 | ||
192 | config CURRITUCK | 192 | config CURRITUCK |
193 | bool "IBM Currituck (476fpe) Support" | 193 | bool "IBM Currituck (476fpe) Support" |
194 | depends on PPC_47x | 194 | depends on PPC_47x |
195 | default n | 195 | default n |
196 | select SWIOTLB | 196 | select SWIOTLB |
197 | select 476FPE | 197 | select 476FPE |
198 | select PPC4xx_PCI_EXPRESS | 198 | select PPC4xx_PCI_EXPRESS |
199 | help | 199 | help |
200 | This option enables support for the IBM Currituck (476fpe) evaluation board | 200 | This option enables support for the IBM Currituck (476fpe) evaluation board |
201 | 201 | ||
202 | config AKEBONO | ||
203 | bool "IBM Akebono (476gtr) Support" | ||
204 | depends on PPC_47x | ||
205 | default n | ||
206 | select SWIOTLB | ||
207 | select 476FPE | ||
208 | select PPC4xx_PCI_EXPRESS | ||
209 | select I2C | ||
210 | select I2C_IBM_IIC | ||
211 | select NETDEVICES | ||
212 | select ETHERNET | ||
213 | select NET_VENDOR_IBM | ||
214 | select IBM_EMAC_EMAC4 | ||
215 | select IBM_EMAC_RGMII_WOL | ||
216 | select USB | ||
217 | select USB_OHCI_HCD_PLATFORM | ||
218 | select USB_EHCI_HCD_PLATFORM | ||
219 | select MMC_SDHCI | ||
220 | select MMC_SDHCI_PLTFM | ||
221 | select MMC_SDHCI_OF_476GTR | ||
222 | select ATA | ||
223 | select SATA_AHCI_PLATFORM | ||
224 | help | ||
225 | This option enables support for the IBM Akebono (476gtr) evaluation board | ||
226 | |||
227 | |||
202 | config ICON | 228 | config ICON |
203 | bool "Icon" | 229 | bool "Icon" |
204 | depends on 44x | 230 | depends on 44x |
205 | default n | 231 | default n |
206 | select PPC44x_SIMPLE | 232 | select PPC44x_SIMPLE |
207 | select 440SPe | 233 | select 440SPe |
208 | select PCI | 234 | select PCI |
209 | select PPC4xx_PCI_EXPRESS | 235 | select PPC4xx_PCI_EXPRESS |
210 | help | 236 | help |
211 | This option enables support for the AMCC PPC440SPe evaluation board. | 237 | This option enables support for the AMCC PPC440SPe evaluation board. |
212 | 238 | ||
213 | config XILINX_VIRTEX440_GENERIC_BOARD | 239 | config XILINX_VIRTEX440_GENERIC_BOARD |
214 | bool "Generic Xilinx Virtex 5 FXT board support" | 240 | bool "Generic Xilinx Virtex 5 FXT board support" |
215 | depends on 44x | 241 | depends on 44x |
216 | default n | 242 | default n |
217 | select XILINX_VIRTEX_5_FXT | 243 | select XILINX_VIRTEX_5_FXT |
218 | help | 244 | help |
219 | This option enables generic support for Xilinx Virtex based boards | 245 | This option enables generic support for Xilinx Virtex based boards |
220 | that use a 440 based processor in the Virtex 5 FXT FPGA architecture. | 246 | that use a 440 based processor in the Virtex 5 FXT FPGA architecture. |
221 | 247 | ||
222 | The generic virtex board support matches any device tree which | 248 | The generic virtex board support matches any device tree which |
223 | specifies 'xlnx,virtex440' in its compatible field. This includes | 249 | specifies 'xlnx,virtex440' in its compatible field. This includes |
224 | the Xilinx ML5xx reference designs using the powerpc core. | 250 | the Xilinx ML5xx reference designs using the powerpc core. |
225 | 251 | ||
226 | Most Virtex 5 designs should use this unless it needs to do some | 252 | Most Virtex 5 designs should use this unless it needs to do some |
227 | special configuration at board probe time. | 253 | special configuration at board probe time. |
228 | 254 | ||
229 | config XILINX_ML510 | 255 | config XILINX_ML510 |
230 | bool "Xilinx ML510 extra support" | 256 | bool "Xilinx ML510 extra support" |
231 | depends on XILINX_VIRTEX440_GENERIC_BOARD | 257 | depends on XILINX_VIRTEX440_GENERIC_BOARD |
232 | select PPC_PCI_CHOICE | 258 | select PPC_PCI_CHOICE |
233 | select XILINX_PCI if PCI | 259 | select XILINX_PCI if PCI |
234 | select PPC_INDIRECT_PCI if PCI | 260 | select PPC_INDIRECT_PCI if PCI |
235 | select PPC_I8259 if PCI | 261 | select PPC_I8259 if PCI |
236 | help | 262 | help |
237 | This option enables extra support for features on the Xilinx ML510 | 263 | This option enables extra support for features on the Xilinx ML510 |
238 | board. The ML510 has a PCI bus with ALI south bridge. | 264 | board. The ML510 has a PCI bus with ALI south bridge. |
239 | 265 | ||
240 | config PPC44x_SIMPLE | 266 | config PPC44x_SIMPLE |
241 | bool "Simple PowerPC 44x board support" | 267 | bool "Simple PowerPC 44x board support" |
242 | depends on 44x | 268 | depends on 44x |
243 | default n | 269 | default n |
244 | help | 270 | help |
245 | This option enables the simple PowerPC 44x platform support. | 271 | This option enables the simple PowerPC 44x platform support. |
246 | 272 | ||
247 | config PPC4xx_GPIO | 273 | config PPC4xx_GPIO |
248 | bool "PPC4xx GPIO support" | 274 | bool "PPC4xx GPIO support" |
249 | depends on 44x | 275 | depends on 44x |
250 | select ARCH_REQUIRE_GPIOLIB | 276 | select ARCH_REQUIRE_GPIOLIB |
251 | help | 277 | help |
252 | Enable gpiolib support for ppc440 based boards | 278 | Enable gpiolib support for ppc440 based boards |
253 | 279 | ||
254 | config PPC4xx_OCM | 280 | config PPC4xx_OCM |
255 | bool "PPC4xx On Chip Memory (OCM) support" | 281 | bool "PPC4xx On Chip Memory (OCM) support" |
256 | depends on 4xx | 282 | depends on 4xx |
257 | select PPC_LIB_RHEAP | 283 | select PPC_LIB_RHEAP |
258 | help | 284 | help |
259 | Enable OCM support for PowerPC 4xx platforms with on chip memory, | 285 | Enable OCM support for PowerPC 4xx platforms with on chip memory, |
260 | OCM provides the fast place for memory access to improve performance. | 286 | OCM provides the fast place for memory access to improve performance. |
261 | 287 | ||
262 | # 44x specific CPU modules, selected based on the board above. | 288 | # 44x specific CPU modules, selected based on the board above. |
263 | config 440EP | 289 | config 440EP |
264 | bool | 290 | bool |
265 | select PPC_FPU | 291 | select PPC_FPU |
266 | select IBM440EP_ERR42 | 292 | select IBM440EP_ERR42 |
267 | select IBM_EMAC_ZMII | 293 | select IBM_EMAC_ZMII |
268 | 294 | ||
269 | config 440EPX | 295 | config 440EPX |
270 | bool | 296 | bool |
271 | select PPC_FPU | 297 | select PPC_FPU |
272 | select IBM_EMAC_EMAC4 | 298 | select IBM_EMAC_EMAC4 |
273 | select IBM_EMAC_RGMII | 299 | select IBM_EMAC_RGMII |
274 | select IBM_EMAC_ZMII | 300 | select IBM_EMAC_ZMII |
275 | select USB_EHCI_BIG_ENDIAN_MMIO | 301 | select USB_EHCI_BIG_ENDIAN_MMIO |
276 | select USB_EHCI_BIG_ENDIAN_DESC | 302 | select USB_EHCI_BIG_ENDIAN_DESC |
277 | 303 | ||
278 | config 440GRX | 304 | config 440GRX |
279 | bool | 305 | bool |
280 | select IBM_EMAC_EMAC4 | 306 | select IBM_EMAC_EMAC4 |
281 | select IBM_EMAC_RGMII | 307 | select IBM_EMAC_RGMII |
282 | select IBM_EMAC_ZMII | 308 | select IBM_EMAC_ZMII |
283 | 309 | ||
284 | config 440GP | 310 | config 440GP |
285 | bool | 311 | bool |
286 | select IBM_EMAC_ZMII | 312 | select IBM_EMAC_ZMII |
287 | 313 | ||
288 | config 440GX | 314 | config 440GX |
289 | bool | 315 | bool |
290 | select IBM_EMAC_EMAC4 | 316 | select IBM_EMAC_EMAC4 |
291 | select IBM_EMAC_RGMII | 317 | select IBM_EMAC_RGMII |
292 | select IBM_EMAC_ZMII #test only | 318 | select IBM_EMAC_ZMII #test only |
293 | select IBM_EMAC_TAH #test only | 319 | select IBM_EMAC_TAH #test only |
294 | 320 | ||
295 | config 440SP | 321 | config 440SP |
296 | bool | 322 | bool |
297 | 323 | ||
298 | config 440SPe | 324 | config 440SPe |
299 | bool | 325 | bool |
300 | select IBM_EMAC_EMAC4 | 326 | select IBM_EMAC_EMAC4 |
301 | 327 | ||
302 | config 460EX | 328 | config 460EX |
303 | bool | 329 | bool |
304 | select PPC_FPU | 330 | select PPC_FPU |
305 | select IBM_EMAC_EMAC4 | 331 | select IBM_EMAC_EMAC4 |
306 | select IBM_EMAC_TAH | 332 | select IBM_EMAC_TAH |
307 | 333 | ||
308 | config 460SX | 334 | config 460SX |
309 | bool | 335 | bool |
310 | select PPC_FPU | 336 | select PPC_FPU |
311 | select IBM_EMAC_EMAC4 | 337 | select IBM_EMAC_EMAC4 |
312 | select IBM_EMAC_RGMII | 338 | select IBM_EMAC_RGMII |
313 | select IBM_EMAC_ZMII | 339 | select IBM_EMAC_ZMII |
314 | select IBM_EMAC_TAH | 340 | select IBM_EMAC_TAH |
315 | 341 | ||
316 | config 476FPE | 342 | config 476FPE |
317 | bool | 343 | bool |
318 | select PPC_FPU | 344 | select PPC_FPU |
319 | 345 | ||
320 | config APM821xx | 346 | config APM821xx |
321 | bool | 347 | bool |
322 | select PPC_FPU | 348 | select PPC_FPU |
323 | select IBM_EMAC_EMAC4 | 349 | select IBM_EMAC_EMAC4 |
324 | select IBM_EMAC_TAH | 350 | select IBM_EMAC_TAH |
325 | 351 | ||
326 | # 44x errata/workaround config symbols, selected by the CPU models above | 352 | # 44x errata/workaround config symbols, selected by the CPU models above |
327 | config IBM440EP_ERR42 | 353 | config IBM440EP_ERR42 |
328 | bool | 354 | bool |
329 | 355 | ||
330 | # Xilinx specific config options. | 356 | # Xilinx specific config options. |
331 | config XILINX_VIRTEX | 357 | config XILINX_VIRTEX |
332 | bool | 358 | bool |
333 | select DEFAULT_UIMAGE | 359 | select DEFAULT_UIMAGE |
334 | 360 | ||
335 | # Xilinx Virtex 5 FXT FPGA architecture, selected by a Xilinx board above | 361 | # Xilinx Virtex 5 FXT FPGA architecture, selected by a Xilinx board above |
336 | config XILINX_VIRTEX_5_FXT | 362 | config XILINX_VIRTEX_5_FXT |
337 | bool | 363 | bool |
338 | select XILINX_VIRTEX | 364 | select XILINX_VIRTEX |
339 | 365 | ||
340 | 366 |
arch/powerpc/platforms/44x/Makefile
1 | obj-$(CONFIG_44x) += misc_44x.o | 1 | obj-$(CONFIG_44x) += misc_44x.o |
2 | ifneq ($(CONFIG_PPC4xx_CPM),y) | 2 | ifneq ($(CONFIG_PPC4xx_CPM),y) |
3 | obj-$(CONFIG_44x) += idle.o | 3 | obj-$(CONFIG_44x) += idle.o |
4 | endif | 4 | endif |
5 | obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o | 5 | obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o |
6 | obj-$(CONFIG_EBONY) += ebony.o | 6 | obj-$(CONFIG_EBONY) += ebony.o |
7 | obj-$(CONFIG_SAM440EP) += sam440ep.o | 7 | obj-$(CONFIG_SAM440EP) += sam440ep.o |
8 | obj-$(CONFIG_WARP) += warp.o | 8 | obj-$(CONFIG_WARP) += warp.o |
9 | obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o | 9 | obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o |
10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o | 10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o |
11 | obj-$(CONFIG_ISS4xx) += iss4xx.o | 11 | obj-$(CONFIG_ISS4xx) += iss4xx.o |
12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o | 12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o |
13 | obj-$(CONFIG_CURRITUCK) += ppc476.o | 13 | obj-$(CONFIG_CURRITUCK) += ppc476.o |
14 | obj-$(CONFIG_AKEBONO) += ppc476.o | ||
14 | 15 |
arch/powerpc/platforms/44x/ppc476.c
1 | /* | 1 | /* |
2 | * PowerPC 476FPE board specific routines | 2 | * PowerPC 476FPE board specific routines |
3 | * | 3 | * |
4 | * Copyright ยฉ 2011 Tony Breeds IBM Corporation | 4 | * Copyright ยฉ 2013 Tony Breeds IBM Corporation |
5 | * Copyright ยฉ 2013 Alistair Popple IBM Corporation | ||
5 | * | 6 | * |
6 | * Based on earlier code: | 7 | * Based on earlier code: |
7 | * Matt Porter <mporter@kernel.crashing.org> | 8 | * Matt Porter <mporter@kernel.crashing.org> |
8 | * Copyright 2002-2005 MontaVista Software Inc. | 9 | * Copyright 2002-2005 MontaVista Software Inc. |
9 | * | 10 | * |
10 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | 11 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> |
11 | * Copyright (c) 2003-2005 Zultys Technologies | 12 | * Copyright (c) 2003-2005 Zultys Technologies |
12 | * | 13 | * |
13 | * Rewritten and ported to the merged powerpc tree: | 14 | * Rewritten and ported to the merged powerpc tree: |
14 | * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation. | 15 | * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation. |
15 | * Copyright ยฉ 2011 David Kliekamp IBM Corporation | 16 | * Copyright ยฉ 2011 David Kliekamp IBM Corporation |
16 | * | 17 | * |
17 | * This program is free software; you can redistribute it and/or modify it | 18 | * This program is free software; you can redistribute it and/or modify it |
18 | * under the terms of the GNU General Public License as published by the | 19 | * under the terms of the GNU General Public License as published by the |
19 | * Free Software Foundation; either version 2 of the License, or (at your | 20 | * Free Software Foundation; either version 2 of the License, or (at your |
20 | * option) any later version. | 21 | * option) any later version. |
21 | */ | 22 | */ |
22 | 23 | ||
23 | #include <linux/init.h> | 24 | #include <linux/init.h> |
24 | #include <linux/of.h> | 25 | #include <linux/of.h> |
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
26 | #include <linux/rtc.h> | 27 | #include <linux/rtc.h> |
27 | 28 | ||
28 | #include <asm/machdep.h> | 29 | #include <asm/machdep.h> |
29 | #include <asm/prom.h> | 30 | #include <asm/prom.h> |
30 | #include <asm/udbg.h> | 31 | #include <asm/udbg.h> |
31 | #include <asm/time.h> | 32 | #include <asm/time.h> |
32 | #include <asm/uic.h> | 33 | #include <asm/uic.h> |
33 | #include <asm/ppc4xx.h> | 34 | #include <asm/ppc4xx.h> |
34 | #include <asm/mpic.h> | 35 | #include <asm/mpic.h> |
35 | #include <asm/mmu.h> | 36 | #include <asm/mmu.h> |
36 | 37 | ||
37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/i2c.h> | ||
38 | 40 | ||
39 | static struct of_device_id ppc47x_of_bus[] __initdata = { | 41 | static struct of_device_id ppc47x_of_bus[] __initdata = { |
40 | { .compatible = "ibm,plb4", }, | 42 | { .compatible = "ibm,plb4", }, |
41 | { .compatible = "ibm,plb6", }, | 43 | { .compatible = "ibm,plb6", }, |
42 | { .compatible = "ibm,opb", }, | 44 | { .compatible = "ibm,opb", }, |
43 | { .compatible = "ibm,ebc", }, | 45 | { .compatible = "ibm,ebc", }, |
44 | {}, | 46 | {}, |
45 | }; | 47 | }; |
46 | 48 | ||
47 | /* The EEPROM is missing and the default values are bogus. This forces USB in | 49 | /* The EEPROM is missing and the default values are bogus. This forces USB in |
48 | * to EHCI mode */ | 50 | * to EHCI mode */ |
49 | static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) | 51 | static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) |
50 | { | 52 | { |
51 | if (of_machine_is_compatible("ibm,currituck")) { | 53 | if (of_machine_is_compatible("ibm,currituck")) { |
52 | pci_write_config_dword(dev, 0xe0, 0x0114231f); | 54 | pci_write_config_dword(dev, 0xe0, 0x0114231f); |
53 | pci_write_config_dword(dev, 0xe4, 0x00006c40); | 55 | pci_write_config_dword(dev, 0xe4, 0x00006c40); |
54 | } | 56 | } |
55 | } | 57 | } |
56 | DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup); | 58 | DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup); |
57 | 59 | ||
60 | /* Akebono has an AVR microcontroller attached to the I2C bus | ||
61 | * which is used to power off/reset the system. */ | ||
62 | |||
63 | /* AVR I2C Commands */ | ||
64 | #define AVR_PWRCTL_CMD (0x26) | ||
65 | |||
66 | /* Flags for the power control I2C commands */ | ||
67 | #define AVR_PWRCTL_PWROFF (0x01) | ||
68 | #define AVR_PWRCTL_RESET (0x02) | ||
69 | |||
70 | static struct i2c_client *avr_i2c_client; | ||
71 | static void avr_halt_system(int pwrctl_flags) | ||
72 | { | ||
73 | /* Request the AVR to reset the system */ | ||
74 | i2c_smbus_write_byte_data(avr_i2c_client, | ||
75 | AVR_PWRCTL_CMD, pwrctl_flags); | ||
76 | |||
77 | /* Wait for system to be reset */ | ||
78 | while (1) | ||
79 | ; | ||
80 | } | ||
81 | |||
82 | static void avr_power_off_system(void) | ||
83 | { | ||
84 | avr_halt_system(AVR_PWRCTL_PWROFF); | ||
85 | } | ||
86 | |||
87 | static void avr_reset_system(char *cmd) | ||
88 | { | ||
89 | avr_halt_system(AVR_PWRCTL_RESET); | ||
90 | } | ||
91 | |||
92 | static int avr_probe(struct i2c_client *client, | ||
93 | const struct i2c_device_id *id) | ||
94 | { | ||
95 | avr_i2c_client = client; | ||
96 | ppc_md.restart = avr_reset_system; | ||
97 | ppc_md.power_off = avr_power_off_system; | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static const struct i2c_device_id avr_id[] = { | ||
102 | { "akebono-avr", 0 }, | ||
103 | { } | ||
104 | }; | ||
105 | |||
106 | static struct i2c_driver avr_driver = { | ||
107 | .driver = { | ||
108 | .name = "akebono-avr", | ||
109 | }, | ||
110 | .probe = avr_probe, | ||
111 | .id_table = avr_id, | ||
112 | }; | ||
113 | |||
58 | static int __init ppc47x_device_probe(void) | 114 | static int __init ppc47x_device_probe(void) |
59 | { | 115 | { |
116 | i2c_add_driver(&avr_driver); | ||
60 | of_platform_bus_probe(NULL, ppc47x_of_bus, NULL); | 117 | of_platform_bus_probe(NULL, ppc47x_of_bus, NULL); |
61 | 118 | ||
62 | return 0; | 119 | return 0; |
63 | } | 120 | } |
64 | machine_device_initcall(ppc47x, ppc47x_device_probe); | 121 | machine_device_initcall(ppc47x, ppc47x_device_probe); |
65 | 122 | ||
66 | /* We can have either UICs or MPICs */ | ||
67 | static void __init ppc47x_init_irq(void) | 123 | static void __init ppc47x_init_irq(void) |
68 | { | 124 | { |
69 | struct device_node *np; | 125 | struct device_node *np; |
70 | 126 | ||
71 | /* Find top level interrupt controller */ | 127 | /* Find top level interrupt controller */ |
72 | for_each_node_with_property(np, "interrupt-controller") { | 128 | for_each_node_with_property(np, "interrupt-controller") { |
73 | if (of_get_property(np, "interrupts", NULL) == NULL) | 129 | if (of_get_property(np, "interrupts", NULL) == NULL) |
74 | break; | 130 | break; |
75 | } | 131 | } |
76 | if (np == NULL) | 132 | if (np == NULL) |
77 | panic("Can't find top level interrupt controller"); | 133 | panic("Can't find top level interrupt controller"); |
78 | 134 | ||
79 | /* Check type and do appropriate initialization */ | 135 | /* Check type and do appropriate initialization */ |
80 | if (of_device_is_compatible(np, "chrp,open-pic")) { | 136 | if (of_device_is_compatible(np, "chrp,open-pic")) { |
81 | /* The MPIC driver will get everything it needs from the | 137 | /* The MPIC driver will get everything it needs from the |
82 | * device-tree, just pass 0 to all arguments | 138 | * device-tree, just pass 0 to all arguments |
83 | */ | 139 | */ |
84 | struct mpic *mpic = | 140 | struct mpic *mpic = |
85 | mpic_alloc(np, 0, MPIC_NO_RESET, 0, 0, " MPIC "); | 141 | mpic_alloc(np, 0, MPIC_NO_RESET, 0, 0, " MPIC "); |
86 | BUG_ON(mpic == NULL); | 142 | BUG_ON(mpic == NULL); |
87 | mpic_init(mpic); | 143 | mpic_init(mpic); |
88 | ppc_md.get_irq = mpic_get_irq; | 144 | ppc_md.get_irq = mpic_get_irq; |
89 | } else | 145 | } else |
90 | panic("Unrecognized top level interrupt controller"); | 146 | panic("Unrecognized top level interrupt controller"); |
91 | } | 147 | } |
92 | 148 | ||
93 | #ifdef CONFIG_SMP | 149 | #ifdef CONFIG_SMP |
94 | static void smp_ppc47x_setup_cpu(int cpu) | 150 | static void smp_ppc47x_setup_cpu(int cpu) |
95 | { | 151 | { |
96 | mpic_setup_this_cpu(); | 152 | mpic_setup_this_cpu(); |
97 | } | 153 | } |
98 | 154 | ||
99 | static int smp_ppc47x_kick_cpu(int cpu) | 155 | static int smp_ppc47x_kick_cpu(int cpu) |
100 | { | 156 | { |
101 | struct device_node *cpunode = of_get_cpu_node(cpu, NULL); | 157 | struct device_node *cpunode = of_get_cpu_node(cpu, NULL); |
102 | const u64 *spin_table_addr_prop; | 158 | const u64 *spin_table_addr_prop; |
103 | u32 *spin_table; | 159 | u32 *spin_table; |
104 | extern void start_secondary_47x(void); | 160 | extern void start_secondary_47x(void); |
105 | 161 | ||
106 | BUG_ON(cpunode == NULL); | 162 | BUG_ON(cpunode == NULL); |
107 | 163 | ||
108 | /* Assume spin table. We could test for the enable-method in | 164 | /* Assume spin table. We could test for the enable-method in |
109 | * the device-tree but currently there's little point as it's | 165 | * the device-tree but currently there's little point as it's |
110 | * our only supported method | 166 | * our only supported method |
111 | */ | 167 | */ |
112 | spin_table_addr_prop = | 168 | spin_table_addr_prop = |
113 | of_get_property(cpunode, "cpu-release-addr", NULL); | 169 | of_get_property(cpunode, "cpu-release-addr", NULL); |
114 | 170 | ||
115 | if (spin_table_addr_prop == NULL) { | 171 | if (spin_table_addr_prop == NULL) { |
116 | pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", | 172 | pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", |
117 | cpu); | 173 | cpu); |
118 | return 1; | 174 | return 1; |
119 | } | 175 | } |
120 | 176 | ||
121 | /* Assume it's mapped as part of the linear mapping. This is a bit | 177 | /* Assume it's mapped as part of the linear mapping. This is a bit |
122 | * fishy but will work fine for now | 178 | * fishy but will work fine for now |
123 | * | 179 | * |
124 | * XXX: Is there any reason to assume differently? | 180 | * XXX: Is there any reason to assume differently? |
125 | */ | 181 | */ |
126 | spin_table = (u32 *)__va(*spin_table_addr_prop); | 182 | spin_table = (u32 *)__va(*spin_table_addr_prop); |
127 | pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table); | 183 | pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table); |
128 | 184 | ||
129 | spin_table[3] = cpu; | 185 | spin_table[3] = cpu; |
130 | smp_wmb(); | 186 | smp_wmb(); |
131 | spin_table[1] = __pa(start_secondary_47x); | 187 | spin_table[1] = __pa(start_secondary_47x); |
132 | mb(); | 188 | mb(); |
133 | 189 | ||
134 | return 0; | 190 | return 0; |
135 | } | 191 | } |
136 | 192 | ||
137 | static struct smp_ops_t ppc47x_smp_ops = { | 193 | static struct smp_ops_t ppc47x_smp_ops = { |
138 | .probe = smp_mpic_probe, | 194 | .probe = smp_mpic_probe, |
139 | .message_pass = smp_mpic_message_pass, | 195 | .message_pass = smp_mpic_message_pass, |
140 | .setup_cpu = smp_ppc47x_setup_cpu, | 196 | .setup_cpu = smp_ppc47x_setup_cpu, |
141 | .kick_cpu = smp_ppc47x_kick_cpu, | 197 | .kick_cpu = smp_ppc47x_kick_cpu, |
142 | .give_timebase = smp_generic_give_timebase, | 198 | .give_timebase = smp_generic_give_timebase, |
143 | .take_timebase = smp_generic_take_timebase, | 199 | .take_timebase = smp_generic_take_timebase, |
144 | }; | 200 | }; |
145 | 201 | ||
146 | static void __init ppc47x_smp_init(void) | 202 | static void __init ppc47x_smp_init(void) |
147 | { | 203 | { |
148 | if (mmu_has_feature(MMU_FTR_TYPE_47x)) | 204 | if (mmu_has_feature(MMU_FTR_TYPE_47x)) |
149 | smp_ops = &ppc47x_smp_ops; | 205 | smp_ops = &ppc47x_smp_ops; |
150 | } | 206 | } |
151 | 207 | ||
152 | #else /* CONFIG_SMP */ | 208 | #else /* CONFIG_SMP */ |
153 | static void __init ppc47x_smp_init(void) { } | 209 | static void __init ppc47x_smp_init(void) { } |
154 | #endif /* CONFIG_SMP */ | 210 | #endif /* CONFIG_SMP */ |
155 | 211 | ||
156 | static void __init ppc47x_setup_arch(void) | 212 | static void __init ppc47x_setup_arch(void) |
157 | { | 213 | { |
158 | 214 | ||
159 | /* No need to check the DMA config as we /know/ our windows are all of | 215 | /* No need to check the DMA config as we /know/ our windows are all of |
160 | * RAM. Lets hope that doesn't change */ | 216 | * RAM. Lets hope that doesn't change */ |
161 | swiotlb_detect_4g(); | 217 | swiotlb_detect_4g(); |
162 | 218 | ||
163 | ppc47x_smp_init(); | 219 | ppc47x_smp_init(); |
164 | } | 220 | } |
165 | 221 | ||
166 | /* | ||
167 | * Called very early, MMU is off, device-tree isn't unflattened | ||
168 | */ | ||
169 | static int __init ppc47x_probe(void) | ||
170 | { | ||
171 | unsigned long root = of_get_flat_dt_root(); | ||
172 | |||
173 | if (!of_flat_dt_is_compatible(root, "ibm,currituck")) | ||
174 | return 0; | ||
175 | |||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | static int board_rev = -1; | 222 | static int board_rev = -1; |
180 | static int __init ppc47x_get_board_rev(void) | 223 | static int __init ppc47x_get_board_rev(void) |
181 | { | 224 | { |
182 | u8 fpga_reg0; | 225 | int reg; |
183 | void *fpga; | 226 | u8 *fpga; |
184 | struct device_node *np; | 227 | struct device_node *np = NULL; |
185 | 228 | ||
186 | np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga"); | 229 | if (of_machine_is_compatible("ibm,currituck")) { |
230 | np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga"); | ||
231 | reg = 0; | ||
232 | } else if (of_machine_is_compatible("ibm,akebono")) { | ||
233 | np = of_find_compatible_node(NULL, NULL, "ibm,akebono-fpga"); | ||
234 | reg = 2; | ||
235 | } | ||
236 | |||
187 | if (!np) | 237 | if (!np) |
188 | goto fail; | 238 | goto fail; |
189 | 239 | ||
190 | fpga = of_iomap(np, 0); | 240 | fpga = (u8 *) of_iomap(np, 0); |
191 | of_node_put(np); | 241 | of_node_put(np); |
192 | if (!fpga) | 242 | if (!fpga) |
193 | goto fail; | 243 | goto fail; |
194 | 244 | ||
195 | fpga_reg0 = ioread8(fpga); | 245 | board_rev = ioread8(fpga + reg) & 0x03; |
196 | board_rev = fpga_reg0 & 0x03; | ||
197 | pr_info("%s: Found board revision %d\n", __func__, board_rev); | 246 | pr_info("%s: Found board revision %d\n", __func__, board_rev); |
198 | iounmap(fpga); | 247 | iounmap(fpga); |
199 | return 0; | 248 | return 0; |
200 | 249 | ||
201 | fail: | 250 | fail: |
202 | pr_info("%s: Unable to find board revision\n", __func__); | 251 | pr_info("%s: Unable to find board revision\n", __func__); |
203 | return 0; | 252 | return 0; |
204 | } | 253 | } |
205 | machine_arch_initcall(ppc47x, ppc47x_get_board_rev); | 254 | machine_arch_initcall(ppc47x, ppc47x_get_board_rev); |
206 | 255 | ||
207 | /* Use USB controller should have been hardware swizzled but it wasn't :( */ | 256 | /* Use USB controller should have been hardware swizzled but it wasn't :( */ |
208 | static void ppc47x_pci_irq_fixup(struct pci_dev *dev) | 257 | static void ppc47x_pci_irq_fixup(struct pci_dev *dev) |
209 | { | 258 | { |
210 | if (dev->vendor == 0x1033 && (dev->device == 0x0035 || | 259 | if (dev->vendor == 0x1033 && (dev->device == 0x0035 || |
211 | dev->device == 0x00e0)) { | 260 | dev->device == 0x00e0)) { |
212 | if (board_rev == 0) { | 261 | if (board_rev == 0) { |
213 | dev->irq = irq_create_mapping(NULL, 47); | 262 | dev->irq = irq_create_mapping(NULL, 47); |
214 | pr_info("%s: Mapping irq %d\n", __func__, dev->irq); | 263 | pr_info("%s: Mapping irq %d\n", __func__, dev->irq); |
215 | } else if (board_rev == 2) { | 264 | } else if (board_rev == 2) { |
216 | dev->irq = irq_create_mapping(NULL, 49); | 265 | dev->irq = irq_create_mapping(NULL, 49); |
217 | pr_info("%s: Mapping irq %d\n", __func__, dev->irq); | 266 | pr_info("%s: Mapping irq %d\n", __func__, dev->irq); |
218 | } else { | 267 | } else { |
219 | pr_alert("%s: Unknown board revision\n", __func__); | 268 | pr_alert("%s: Unknown board revision\n", __func__); |
220 | } | 269 | } |
221 | } | 270 | } |
222 | } | 271 | } |
223 | 272 | ||
273 | /* | ||
274 | * Called very early, MMU is off, device-tree isn't unflattened | ||
275 | */ | ||
276 | static int __init ppc47x_probe(void) | ||
277 | { | ||
278 | unsigned long root = of_get_flat_dt_root(); | ||
279 | |||
280 | if (of_flat_dt_is_compatible(root, "ibm,akebono")) | ||
281 | return 1; | ||
282 | |||
283 | if (of_flat_dt_is_compatible(root, "ibm,currituck")) { | ||
284 | ppc_md.pci_irq_fixup = ppc47x_pci_irq_fixup; | ||
285 | return 1; |
arch/powerpc/sysdev/ppc4xx_pci.c
1 | /* | 1 | /* |
2 | * PCI / PCI-X / PCI-Express support for 4xx parts | 2 | * PCI / PCI-X / PCI-Express support for 4xx parts |
3 | * | 3 | * |
4 | * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. | 4 | * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. |
5 | * | 5 | * |
6 | * Most PCI Express code is coming from Stefan Roese implementation for | 6 | * Most PCI Express code is coming from Stefan Roese implementation for |
7 | * arch/ppc in the Denx tree, slightly reworked by me. | 7 | * arch/ppc in the Denx tree, slightly reworked by me. |
8 | * | 8 | * |
9 | * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de> | 9 | * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de> |
10 | * | 10 | * |
11 | * Some of that comes itself from a previous implementation for 440SPE only | 11 | * Some of that comes itself from a previous implementation for 440SPE only |
12 | * by Roland Dreier: | 12 | * by Roland Dreier: |
13 | * | 13 | * |
14 | * Copyright (c) 2005 Cisco Systems. All rights reserved. | 14 | * Copyright (c) 2005 Cisco Systems. All rights reserved. |
15 | * Roland Dreier <rolandd@cisco.com> | 15 | * Roland Dreier <rolandd@cisco.com> |
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #undef DEBUG | 19 | #undef DEBUG |
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | #include <asm/pci-bridge.h> | 30 | #include <asm/pci-bridge.h> |
31 | #include <asm/machdep.h> | 31 | #include <asm/machdep.h> |
32 | #include <asm/dcr.h> | 32 | #include <asm/dcr.h> |
33 | #include <asm/dcr-regs.h> | 33 | #include <asm/dcr-regs.h> |
34 | #include <mm/mmu_decl.h> | 34 | #include <mm/mmu_decl.h> |
35 | 35 | ||
36 | #include "ppc4xx_pci.h" | 36 | #include "ppc4xx_pci.h" |
37 | 37 | ||
38 | static int dma_offset_set; | 38 | static int dma_offset_set; |
39 | 39 | ||
40 | #define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL)) | 40 | #define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL)) |
41 | #define U64_TO_U32_HIGH(val) ((u32)((val) >> 32)) | 41 | #define U64_TO_U32_HIGH(val) ((u32)((val) >> 32)) |
42 | 42 | ||
43 | #define RES_TO_U32_LOW(val) \ | 43 | #define RES_TO_U32_LOW(val) \ |
44 | ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_LOW(val) : (val)) | 44 | ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_LOW(val) : (val)) |
45 | #define RES_TO_U32_HIGH(val) \ | 45 | #define RES_TO_U32_HIGH(val) \ |
46 | ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_HIGH(val) : (0)) | 46 | ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_HIGH(val) : (0)) |
47 | 47 | ||
48 | static inline int ppc440spe_revA(void) | 48 | static inline int ppc440spe_revA(void) |
49 | { | 49 | { |
50 | /* Catch both 440SPe variants, with and without RAID6 support */ | 50 | /* Catch both 440SPe variants, with and without RAID6 support */ |
51 | if ((mfspr(SPRN_PVR) & 0xffefffff) == 0x53421890) | 51 | if ((mfspr(SPRN_PVR) & 0xffefffff) == 0x53421890) |
52 | return 1; | 52 | return 1; |
53 | else | 53 | else |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev) | 57 | static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev) |
58 | { | 58 | { |
59 | struct pci_controller *hose; | 59 | struct pci_controller *hose; |
60 | int i; | 60 | int i; |
61 | 61 | ||
62 | if (dev->devfn != 0 || dev->bus->self != NULL) | 62 | if (dev->devfn != 0 || dev->bus->self != NULL) |
63 | return; | 63 | return; |
64 | 64 | ||
65 | hose = pci_bus_to_host(dev->bus); | 65 | hose = pci_bus_to_host(dev->bus); |
66 | if (hose == NULL) | 66 | if (hose == NULL) |
67 | return; | 67 | return; |
68 | 68 | ||
69 | if (!of_device_is_compatible(hose->dn, "ibm,plb-pciex") && | 69 | if (!of_device_is_compatible(hose->dn, "ibm,plb-pciex") && |
70 | !of_device_is_compatible(hose->dn, "ibm,plb-pcix") && | 70 | !of_device_is_compatible(hose->dn, "ibm,plb-pcix") && |
71 | !of_device_is_compatible(hose->dn, "ibm,plb-pci")) | 71 | !of_device_is_compatible(hose->dn, "ibm,plb-pci")) |
72 | return; | 72 | return; |
73 | 73 | ||
74 | if (of_device_is_compatible(hose->dn, "ibm,plb440epx-pci") || | 74 | if (of_device_is_compatible(hose->dn, "ibm,plb440epx-pci") || |
75 | of_device_is_compatible(hose->dn, "ibm,plb440grx-pci")) { | 75 | of_device_is_compatible(hose->dn, "ibm,plb440grx-pci")) { |
76 | hose->indirect_type |= PPC_INDIRECT_TYPE_BROKEN_MRM; | 76 | hose->indirect_type |= PPC_INDIRECT_TYPE_BROKEN_MRM; |
77 | } | 77 | } |
78 | 78 | ||
79 | /* Hide the PCI host BARs from the kernel as their content doesn't | 79 | /* Hide the PCI host BARs from the kernel as their content doesn't |
80 | * fit well in the resource management | 80 | * fit well in the resource management |
81 | */ | 81 | */ |
82 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 82 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
83 | dev->resource[i].start = dev->resource[i].end = 0; | 83 | dev->resource[i].start = dev->resource[i].end = 0; |
84 | dev->resource[i].flags = 0; | 84 | dev->resource[i].flags = 0; |
85 | } | 85 | } |
86 | 86 | ||
87 | printk(KERN_INFO "PCI: Hiding 4xx host bridge resources %s\n", | 87 | printk(KERN_INFO "PCI: Hiding 4xx host bridge resources %s\n", |
88 | pci_name(dev)); | 88 | pci_name(dev)); |
89 | } | 89 | } |
90 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_ppc4xx_pci_bridge); | 90 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_ppc4xx_pci_bridge); |
91 | 91 | ||
92 | static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, | 92 | static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, |
93 | void __iomem *reg, | 93 | void __iomem *reg, |
94 | struct resource *res) | 94 | struct resource *res) |
95 | { | 95 | { |
96 | u64 size; | 96 | u64 size; |
97 | const u32 *ranges; | 97 | const u32 *ranges; |
98 | int rlen; | 98 | int rlen; |
99 | int pna = of_n_addr_cells(hose->dn); | 99 | int pna = of_n_addr_cells(hose->dn); |
100 | int np = pna + 5; | 100 | int np = pna + 5; |
101 | 101 | ||
102 | /* Default */ | 102 | /* Default */ |
103 | res->start = 0; | 103 | res->start = 0; |
104 | size = 0x80000000; | 104 | size = 0x80000000; |
105 | res->end = size - 1; | 105 | res->end = size - 1; |
106 | res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; | 106 | res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; |
107 | 107 | ||
108 | /* Get dma-ranges property */ | 108 | /* Get dma-ranges property */ |
109 | ranges = of_get_property(hose->dn, "dma-ranges", &rlen); | 109 | ranges = of_get_property(hose->dn, "dma-ranges", &rlen); |
110 | if (ranges == NULL) | 110 | if (ranges == NULL) |
111 | goto out; | 111 | goto out; |
112 | 112 | ||
113 | /* Walk it */ | 113 | /* Walk it */ |
114 | while ((rlen -= np * 4) >= 0) { | 114 | while ((rlen -= np * 4) >= 0) { |
115 | u32 pci_space = ranges[0]; | 115 | u32 pci_space = ranges[0]; |
116 | u64 pci_addr = of_read_number(ranges + 1, 2); | 116 | u64 pci_addr = of_read_number(ranges + 1, 2); |
117 | u64 cpu_addr = of_translate_dma_address(hose->dn, ranges + 3); | 117 | u64 cpu_addr = of_translate_dma_address(hose->dn, ranges + 3); |
118 | size = of_read_number(ranges + pna + 3, 2); | 118 | size = of_read_number(ranges + pna + 3, 2); |
119 | ranges += np; | 119 | ranges += np; |
120 | if (cpu_addr == OF_BAD_ADDR || size == 0) | 120 | if (cpu_addr == OF_BAD_ADDR || size == 0) |
121 | continue; | 121 | continue; |
122 | 122 | ||
123 | /* We only care about memory */ | 123 | /* We only care about memory */ |
124 | if ((pci_space & 0x03000000) != 0x02000000) | 124 | if ((pci_space & 0x03000000) != 0x02000000) |
125 | continue; | 125 | continue; |
126 | 126 | ||
127 | /* We currently only support memory at 0, and pci_addr | 127 | /* We currently only support memory at 0, and pci_addr |
128 | * within 32 bits space | 128 | * within 32 bits space |
129 | */ | 129 | */ |
130 | if (cpu_addr != 0 || pci_addr > 0xffffffff) { | 130 | if (cpu_addr != 0 || pci_addr > 0xffffffff) { |
131 | printk(KERN_WARNING "%s: Ignored unsupported dma range" | 131 | printk(KERN_WARNING "%s: Ignored unsupported dma range" |
132 | " 0x%016llx...0x%016llx -> 0x%016llx\n", | 132 | " 0x%016llx...0x%016llx -> 0x%016llx\n", |
133 | hose->dn->full_name, | 133 | hose->dn->full_name, |
134 | pci_addr, pci_addr + size - 1, cpu_addr); | 134 | pci_addr, pci_addr + size - 1, cpu_addr); |
135 | continue; | 135 | continue; |
136 | } | 136 | } |
137 | 137 | ||
138 | /* Check if not prefetchable */ | 138 | /* Check if not prefetchable */ |
139 | if (!(pci_space & 0x40000000)) | 139 | if (!(pci_space & 0x40000000)) |
140 | res->flags &= ~IORESOURCE_PREFETCH; | 140 | res->flags &= ~IORESOURCE_PREFETCH; |
141 | 141 | ||
142 | 142 | ||
143 | /* Use that */ | 143 | /* Use that */ |
144 | res->start = pci_addr; | 144 | res->start = pci_addr; |
145 | /* Beware of 32 bits resources */ | 145 | /* Beware of 32 bits resources */ |
146 | if (sizeof(resource_size_t) == sizeof(u32) && | 146 | if (sizeof(resource_size_t) == sizeof(u32) && |
147 | (pci_addr + size) > 0x100000000ull) | 147 | (pci_addr + size) > 0x100000000ull) |
148 | res->end = 0xffffffff; | 148 | res->end = 0xffffffff; |
149 | else | 149 | else |
150 | res->end = res->start + size - 1; | 150 | res->end = res->start + size - 1; |
151 | break; | 151 | break; |
152 | } | 152 | } |
153 | 153 | ||
154 | /* We only support one global DMA offset */ | 154 | /* We only support one global DMA offset */ |
155 | if (dma_offset_set && pci_dram_offset != res->start) { | 155 | if (dma_offset_set && pci_dram_offset != res->start) { |
156 | printk(KERN_ERR "%s: dma-ranges(s) mismatch\n", | 156 | printk(KERN_ERR "%s: dma-ranges(s) mismatch\n", |
157 | hose->dn->full_name); | 157 | hose->dn->full_name); |
158 | return -ENXIO; | 158 | return -ENXIO; |
159 | } | 159 | } |
160 | 160 | ||
161 | /* Check that we can fit all of memory as we don't support | 161 | /* Check that we can fit all of memory as we don't support |
162 | * DMA bounce buffers | 162 | * DMA bounce buffers |
163 | */ | 163 | */ |
164 | if (size < total_memory) { | 164 | if (size < total_memory) { |
165 | printk(KERN_ERR "%s: dma-ranges too small " | 165 | printk(KERN_ERR "%s: dma-ranges too small " |
166 | "(size=%llx total_memory=%llx)\n", | 166 | "(size=%llx total_memory=%llx)\n", |
167 | hose->dn->full_name, size, (u64)total_memory); | 167 | hose->dn->full_name, size, (u64)total_memory); |
168 | return -ENXIO; | 168 | return -ENXIO; |
169 | } | 169 | } |
170 | 170 | ||
171 | /* Check we are a power of 2 size and that base is a multiple of size*/ | 171 | /* Check we are a power of 2 size and that base is a multiple of size*/ |
172 | if ((size & (size - 1)) != 0 || | 172 | if ((size & (size - 1)) != 0 || |
173 | (res->start & (size - 1)) != 0) { | 173 | (res->start & (size - 1)) != 0) { |
174 | printk(KERN_ERR "%s: dma-ranges unaligned\n", | 174 | printk(KERN_ERR "%s: dma-ranges unaligned\n", |
175 | hose->dn->full_name); | 175 | hose->dn->full_name); |
176 | return -ENXIO; | 176 | return -ENXIO; |
177 | } | 177 | } |
178 | 178 | ||
179 | /* Check that we are fully contained within 32 bits space */ | 179 | /* Check that we are fully contained within 32 bits space */ |
180 | if (res->end > 0xffffffff) { | 180 | if (res->end > 0xffffffff) { |
181 | printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n", | 181 | printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n", |
182 | hose->dn->full_name); | 182 | hose->dn->full_name); |
183 | return -ENXIO; | 183 | return -ENXIO; |
184 | } | 184 | } |
185 | out: | 185 | out: |
186 | dma_offset_set = 1; | 186 | dma_offset_set = 1; |
187 | pci_dram_offset = res->start; | 187 | pci_dram_offset = res->start; |
188 | hose->dma_window_base_cur = res->start; | 188 | hose->dma_window_base_cur = res->start; |
189 | hose->dma_window_size = resource_size(res); | 189 | hose->dma_window_size = resource_size(res); |
190 | 190 | ||
191 | printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n", | 191 | printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n", |
192 | pci_dram_offset); | 192 | pci_dram_offset); |
193 | printk(KERN_INFO "4xx PCI DMA window base to 0x%016llx\n", | 193 | printk(KERN_INFO "4xx PCI DMA window base to 0x%016llx\n", |
194 | (unsigned long long)hose->dma_window_base_cur); | 194 | (unsigned long long)hose->dma_window_base_cur); |
195 | printk(KERN_INFO "DMA window size 0x%016llx\n", | 195 | printk(KERN_INFO "DMA window size 0x%016llx\n", |
196 | (unsigned long long)hose->dma_window_size); | 196 | (unsigned long long)hose->dma_window_size); |
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | /* | 200 | /* |
201 | * 4xx PCI 2.x part | 201 | * 4xx PCI 2.x part |
202 | */ | 202 | */ |
203 | 203 | ||
204 | static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, | 204 | static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, |
205 | void __iomem *reg, | 205 | void __iomem *reg, |
206 | u64 plb_addr, | 206 | u64 plb_addr, |
207 | u64 pci_addr, | 207 | u64 pci_addr, |
208 | u64 size, | 208 | u64 size, |
209 | unsigned int flags, | 209 | unsigned int flags, |
210 | int index) | 210 | int index) |
211 | { | 211 | { |
212 | u32 ma, pcila, pciha; | 212 | u32 ma, pcila, pciha; |
213 | 213 | ||
214 | /* Hack warning ! The "old" PCI 2.x cell only let us configure the low | 214 | /* Hack warning ! The "old" PCI 2.x cell only let us configure the low |
215 | * 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit | 215 | * 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit |
216 | * address are actually hard wired to a value that appears to depend | 216 | * address are actually hard wired to a value that appears to depend |
217 | * on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx. | 217 | * on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx. |
218 | * | 218 | * |
219 | * The trick here is we just crop those top bits and ignore them when | 219 | * The trick here is we just crop those top bits and ignore them when |
220 | * programming the chip. That means the device-tree has to be right | 220 | * programming the chip. That means the device-tree has to be right |
221 | * for the specific part used (we don't print a warning if it's wrong | 221 | * for the specific part used (we don't print a warning if it's wrong |
222 | * but on the other hand, you'll crash quickly enough), but at least | 222 | * but on the other hand, you'll crash quickly enough), but at least |
223 | * this code should work whatever the hard coded value is | 223 | * this code should work whatever the hard coded value is |
224 | */ | 224 | */ |
225 | plb_addr &= 0xffffffffull; | 225 | plb_addr &= 0xffffffffull; |
226 | 226 | ||
227 | /* Note: Due to the above hack, the test below doesn't actually test | 227 | /* Note: Due to the above hack, the test below doesn't actually test |
228 | * if you address is above 4G, but it tests that address and | 228 | * if you address is above 4G, but it tests that address and |
229 | * (address + size) are both contained in the same 4G | 229 | * (address + size) are both contained in the same 4G |
230 | */ | 230 | */ |
231 | if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || | 231 | if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || |
232 | size < 0x1000 || (plb_addr & (size - 1)) != 0) { | 232 | size < 0x1000 || (plb_addr & (size - 1)) != 0) { |
233 | printk(KERN_WARNING "%s: Resource out of range\n", | 233 | printk(KERN_WARNING "%s: Resource out of range\n", |
234 | hose->dn->full_name); | 234 | hose->dn->full_name); |
235 | return -1; | 235 | return -1; |
236 | } | 236 | } |
237 | ma = (0xffffffffu << ilog2(size)) | 1; | 237 | ma = (0xffffffffu << ilog2(size)) | 1; |
238 | if (flags & IORESOURCE_PREFETCH) | 238 | if (flags & IORESOURCE_PREFETCH) |
239 | ma |= 2; | 239 | ma |= 2; |
240 | 240 | ||
241 | pciha = RES_TO_U32_HIGH(pci_addr); | 241 | pciha = RES_TO_U32_HIGH(pci_addr); |
242 | pcila = RES_TO_U32_LOW(pci_addr); | 242 | pcila = RES_TO_U32_LOW(pci_addr); |
243 | 243 | ||
244 | writel(plb_addr, reg + PCIL0_PMM0LA + (0x10 * index)); | 244 | writel(plb_addr, reg + PCIL0_PMM0LA + (0x10 * index)); |
245 | writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * index)); | 245 | writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * index)); |
246 | writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * index)); | 246 | writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * index)); |
247 | writel(ma, reg + PCIL0_PMM0MA + (0x10 * index)); | 247 | writel(ma, reg + PCIL0_PMM0MA + (0x10 * index)); |
248 | 248 | ||
249 | return 0; | 249 | return 0; |
250 | } | 250 | } |
251 | 251 | ||
252 | static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, | 252 | static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, |
253 | void __iomem *reg) | 253 | void __iomem *reg) |
254 | { | 254 | { |
255 | int i, j, found_isa_hole = 0; | 255 | int i, j, found_isa_hole = 0; |
256 | 256 | ||
257 | /* Setup outbound memory windows */ | 257 | /* Setup outbound memory windows */ |
258 | for (i = j = 0; i < 3; i++) { | 258 | for (i = j = 0; i < 3; i++) { |
259 | struct resource *res = &hose->mem_resources[i]; | 259 | struct resource *res = &hose->mem_resources[i]; |
260 | resource_size_t offset = hose->mem_offset[i]; | 260 | resource_size_t offset = hose->mem_offset[i]; |
261 | 261 | ||
262 | /* we only care about memory windows */ | 262 | /* we only care about memory windows */ |
263 | if (!(res->flags & IORESOURCE_MEM)) | 263 | if (!(res->flags & IORESOURCE_MEM)) |
264 | continue; | 264 | continue; |
265 | if (j > 2) { | 265 | if (j > 2) { |
266 | printk(KERN_WARNING "%s: Too many ranges\n", | 266 | printk(KERN_WARNING "%s: Too many ranges\n", |
267 | hose->dn->full_name); | 267 | hose->dn->full_name); |
268 | break; | 268 | break; |
269 | } | 269 | } |
270 | 270 | ||
271 | /* Configure the resource */ | 271 | /* Configure the resource */ |
272 | if (ppc4xx_setup_one_pci_PMM(hose, reg, | 272 | if (ppc4xx_setup_one_pci_PMM(hose, reg, |
273 | res->start, | 273 | res->start, |
274 | res->start - offset, | 274 | res->start - offset, |
275 | resource_size(res), | 275 | resource_size(res), |
276 | res->flags, | 276 | res->flags, |
277 | j) == 0) { | 277 | j) == 0) { |
278 | j++; | 278 | j++; |
279 | 279 | ||
280 | /* If the resource PCI address is 0 then we have our | 280 | /* If the resource PCI address is 0 then we have our |
281 | * ISA memory hole | 281 | * ISA memory hole |
282 | */ | 282 | */ |
283 | if (res->start == offset) | 283 | if (res->start == offset) |
284 | found_isa_hole = 1; | 284 | found_isa_hole = 1; |
285 | } | 285 | } |
286 | } | 286 | } |
287 | 287 | ||
288 | /* Handle ISA memory hole if not already covered */ | 288 | /* Handle ISA memory hole if not already covered */ |
289 | if (j <= 2 && !found_isa_hole && hose->isa_mem_size) | 289 | if (j <= 2 && !found_isa_hole && hose->isa_mem_size) |
290 | if (ppc4xx_setup_one_pci_PMM(hose, reg, hose->isa_mem_phys, 0, | 290 | if (ppc4xx_setup_one_pci_PMM(hose, reg, hose->isa_mem_phys, 0, |
291 | hose->isa_mem_size, 0, j) == 0) | 291 | hose->isa_mem_size, 0, j) == 0) |
292 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", | 292 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", |
293 | hose->dn->full_name); | 293 | hose->dn->full_name); |
294 | } | 294 | } |
295 | 295 | ||
296 | static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, | 296 | static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, |
297 | void __iomem *reg, | 297 | void __iomem *reg, |
298 | const struct resource *res) | 298 | const struct resource *res) |
299 | { | 299 | { |
300 | resource_size_t size = resource_size(res); | 300 | resource_size_t size = resource_size(res); |
301 | u32 sa; | 301 | u32 sa; |
302 | 302 | ||
303 | /* Calculate window size */ | 303 | /* Calculate window size */ |
304 | sa = (0xffffffffu << ilog2(size)) | 1; | 304 | sa = (0xffffffffu << ilog2(size)) | 1; |
305 | sa |= 0x1; | 305 | sa |= 0x1; |
306 | 306 | ||
307 | /* RAM is always at 0 local for now */ | 307 | /* RAM is always at 0 local for now */ |
308 | writel(0, reg + PCIL0_PTM1LA); | 308 | writel(0, reg + PCIL0_PTM1LA); |
309 | writel(sa, reg + PCIL0_PTM1MS); | 309 | writel(sa, reg + PCIL0_PTM1MS); |
310 | 310 | ||
311 | /* Map on PCI side */ | 311 | /* Map on PCI side */ |
312 | early_write_config_dword(hose, hose->first_busno, 0, | 312 | early_write_config_dword(hose, hose->first_busno, 0, |
313 | PCI_BASE_ADDRESS_1, res->start); | 313 | PCI_BASE_ADDRESS_1, res->start); |
314 | early_write_config_dword(hose, hose->first_busno, 0, | 314 | early_write_config_dword(hose, hose->first_busno, 0, |
315 | PCI_BASE_ADDRESS_2, 0x00000000); | 315 | PCI_BASE_ADDRESS_2, 0x00000000); |
316 | early_write_config_word(hose, hose->first_busno, 0, | 316 | early_write_config_word(hose, hose->first_busno, 0, |
317 | PCI_COMMAND, 0x0006); | 317 | PCI_COMMAND, 0x0006); |
318 | } | 318 | } |
319 | 319 | ||
320 | static void __init ppc4xx_probe_pci_bridge(struct device_node *np) | 320 | static void __init ppc4xx_probe_pci_bridge(struct device_node *np) |
321 | { | 321 | { |
322 | /* NYI */ | 322 | /* NYI */ |
323 | struct resource rsrc_cfg; | 323 | struct resource rsrc_cfg; |
324 | struct resource rsrc_reg; | 324 | struct resource rsrc_reg; |
325 | struct resource dma_window; | 325 | struct resource dma_window; |
326 | struct pci_controller *hose = NULL; | 326 | struct pci_controller *hose = NULL; |
327 | void __iomem *reg = NULL; | 327 | void __iomem *reg = NULL; |
328 | const int *bus_range; | 328 | const int *bus_range; |
329 | int primary = 0; | 329 | int primary = 0; |
330 | 330 | ||
331 | /* Check if device is enabled */ | 331 | /* Check if device is enabled */ |
332 | if (!of_device_is_available(np)) { | 332 | if (!of_device_is_available(np)) { |
333 | printk(KERN_INFO "%s: Port disabled via device-tree\n", | 333 | printk(KERN_INFO "%s: Port disabled via device-tree\n", |
334 | np->full_name); | 334 | np->full_name); |
335 | return; | 335 | return; |
336 | } | 336 | } |
337 | 337 | ||
338 | /* Fetch config space registers address */ | 338 | /* Fetch config space registers address */ |
339 | if (of_address_to_resource(np, 0, &rsrc_cfg)) { | 339 | if (of_address_to_resource(np, 0, &rsrc_cfg)) { |
340 | printk(KERN_ERR "%s: Can't get PCI config register base !", | 340 | printk(KERN_ERR "%s: Can't get PCI config register base !", |
341 | np->full_name); | 341 | np->full_name); |
342 | return; | 342 | return; |
343 | } | 343 | } |
344 | /* Fetch host bridge internal registers address */ | 344 | /* Fetch host bridge internal registers address */ |
345 | if (of_address_to_resource(np, 3, &rsrc_reg)) { | 345 | if (of_address_to_resource(np, 3, &rsrc_reg)) { |
346 | printk(KERN_ERR "%s: Can't get PCI internal register base !", | 346 | printk(KERN_ERR "%s: Can't get PCI internal register base !", |
347 | np->full_name); | 347 | np->full_name); |
348 | return; | 348 | return; |
349 | } | 349 | } |
350 | 350 | ||
351 | /* Check if primary bridge */ | 351 | /* Check if primary bridge */ |
352 | if (of_get_property(np, "primary", NULL)) | 352 | if (of_get_property(np, "primary", NULL)) |
353 | primary = 1; | 353 | primary = 1; |
354 | 354 | ||
355 | /* Get bus range if any */ | 355 | /* Get bus range if any */ |
356 | bus_range = of_get_property(np, "bus-range", NULL); | 356 | bus_range = of_get_property(np, "bus-range", NULL); |
357 | 357 | ||
358 | /* Map registers */ | 358 | /* Map registers */ |
359 | reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); | 359 | reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); |
360 | if (reg == NULL) { | 360 | if (reg == NULL) { |
361 | printk(KERN_ERR "%s: Can't map registers !", np->full_name); | 361 | printk(KERN_ERR "%s: Can't map registers !", np->full_name); |
362 | goto fail; | 362 | goto fail; |
363 | } | 363 | } |
364 | 364 | ||
365 | /* Allocate the host controller data structure */ | 365 | /* Allocate the host controller data structure */ |
366 | hose = pcibios_alloc_controller(np); | 366 | hose = pcibios_alloc_controller(np); |
367 | if (!hose) | 367 | if (!hose) |
368 | goto fail; | 368 | goto fail; |
369 | 369 | ||
370 | hose->first_busno = bus_range ? bus_range[0] : 0x0; | 370 | hose->first_busno = bus_range ? bus_range[0] : 0x0; |
371 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 371 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
372 | 372 | ||
373 | /* Setup config space */ | 373 | /* Setup config space */ |
374 | setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0); | 374 | setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0); |
375 | 375 | ||
376 | /* Disable all windows */ | 376 | /* Disable all windows */ |
377 | writel(0, reg + PCIL0_PMM0MA); | 377 | writel(0, reg + PCIL0_PMM0MA); |
378 | writel(0, reg + PCIL0_PMM1MA); | 378 | writel(0, reg + PCIL0_PMM1MA); |
379 | writel(0, reg + PCIL0_PMM2MA); | 379 | writel(0, reg + PCIL0_PMM2MA); |
380 | writel(0, reg + PCIL0_PTM1MS); | 380 | writel(0, reg + PCIL0_PTM1MS); |
381 | writel(0, reg + PCIL0_PTM2MS); | 381 | writel(0, reg + PCIL0_PTM2MS); |
382 | 382 | ||
383 | /* Parse outbound mapping resources */ | 383 | /* Parse outbound mapping resources */ |
384 | pci_process_bridge_OF_ranges(hose, np, primary); | 384 | pci_process_bridge_OF_ranges(hose, np, primary); |
385 | 385 | ||
386 | /* Parse inbound mapping resources */ | 386 | /* Parse inbound mapping resources */ |
387 | if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) | 387 | if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) |
388 | goto fail; | 388 | goto fail; |
389 | 389 | ||
390 | /* Configure outbound ranges POMs */ | 390 | /* Configure outbound ranges POMs */ |
391 | ppc4xx_configure_pci_PMMs(hose, reg); | 391 | ppc4xx_configure_pci_PMMs(hose, reg); |
392 | 392 | ||
393 | /* Configure inbound ranges PIMs */ | 393 | /* Configure inbound ranges PIMs */ |
394 | ppc4xx_configure_pci_PTMs(hose, reg, &dma_window); | 394 | ppc4xx_configure_pci_PTMs(hose, reg, &dma_window); |
395 | 395 | ||
396 | /* We don't need the registers anymore */ | 396 | /* We don't need the registers anymore */ |
397 | iounmap(reg); | 397 | iounmap(reg); |
398 | return; | 398 | return; |
399 | 399 | ||
400 | fail: | 400 | fail: |
401 | if (hose) | 401 | if (hose) |
402 | pcibios_free_controller(hose); | 402 | pcibios_free_controller(hose); |
403 | if (reg) | 403 | if (reg) |
404 | iounmap(reg); | 404 | iounmap(reg); |
405 | } | 405 | } |
406 | 406 | ||
407 | /* | 407 | /* |
408 | * 4xx PCI-X part | 408 | * 4xx PCI-X part |
409 | */ | 409 | */ |
410 | 410 | ||
411 | static int __init ppc4xx_setup_one_pcix_POM(struct pci_controller *hose, | 411 | static int __init ppc4xx_setup_one_pcix_POM(struct pci_controller *hose, |
412 | void __iomem *reg, | 412 | void __iomem *reg, |
413 | u64 plb_addr, | 413 | u64 plb_addr, |
414 | u64 pci_addr, | 414 | u64 pci_addr, |
415 | u64 size, | 415 | u64 size, |
416 | unsigned int flags, | 416 | unsigned int flags, |
417 | int index) | 417 | int index) |
418 | { | 418 | { |
419 | u32 lah, lal, pciah, pcial, sa; | 419 | u32 lah, lal, pciah, pcial, sa; |
420 | 420 | ||
421 | if (!is_power_of_2(size) || size < 0x1000 || | 421 | if (!is_power_of_2(size) || size < 0x1000 || |
422 | (plb_addr & (size - 1)) != 0) { | 422 | (plb_addr & (size - 1)) != 0) { |
423 | printk(KERN_WARNING "%s: Resource out of range\n", | 423 | printk(KERN_WARNING "%s: Resource out of range\n", |
424 | hose->dn->full_name); | 424 | hose->dn->full_name); |
425 | return -1; | 425 | return -1; |
426 | } | 426 | } |
427 | 427 | ||
428 | /* Calculate register values */ | 428 | /* Calculate register values */ |
429 | lah = RES_TO_U32_HIGH(plb_addr); | 429 | lah = RES_TO_U32_HIGH(plb_addr); |
430 | lal = RES_TO_U32_LOW(plb_addr); | 430 | lal = RES_TO_U32_LOW(plb_addr); |
431 | pciah = RES_TO_U32_HIGH(pci_addr); | 431 | pciah = RES_TO_U32_HIGH(pci_addr); |
432 | pcial = RES_TO_U32_LOW(pci_addr); | 432 | pcial = RES_TO_U32_LOW(pci_addr); |
433 | sa = (0xffffffffu << ilog2(size)) | 0x1; | 433 | sa = (0xffffffffu << ilog2(size)) | 0x1; |
434 | 434 | ||
435 | /* Program register values */ | 435 | /* Program register values */ |
436 | if (index == 0) { | 436 | if (index == 0) { |
437 | writel(lah, reg + PCIX0_POM0LAH); | 437 | writel(lah, reg + PCIX0_POM0LAH); |
438 | writel(lal, reg + PCIX0_POM0LAL); | 438 | writel(lal, reg + PCIX0_POM0LAL); |
439 | writel(pciah, reg + PCIX0_POM0PCIAH); | 439 | writel(pciah, reg + PCIX0_POM0PCIAH); |
440 | writel(pcial, reg + PCIX0_POM0PCIAL); | 440 | writel(pcial, reg + PCIX0_POM0PCIAL); |
441 | writel(sa, reg + PCIX0_POM0SA); | 441 | writel(sa, reg + PCIX0_POM0SA); |
442 | } else { | 442 | } else { |
443 | writel(lah, reg + PCIX0_POM1LAH); | 443 | writel(lah, reg + PCIX0_POM1LAH); |
444 | writel(lal, reg + PCIX0_POM1LAL); | 444 | writel(lal, reg + PCIX0_POM1LAL); |
445 | writel(pciah, reg + PCIX0_POM1PCIAH); | 445 | writel(pciah, reg + PCIX0_POM1PCIAH); |
446 | writel(pcial, reg + PCIX0_POM1PCIAL); | 446 | writel(pcial, reg + PCIX0_POM1PCIAL); |
447 | writel(sa, reg + PCIX0_POM1SA); | 447 | writel(sa, reg + PCIX0_POM1SA); |
448 | } | 448 | } |
449 | 449 | ||
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | 452 | ||
453 | static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, | 453 | static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, |
454 | void __iomem *reg) | 454 | void __iomem *reg) |
455 | { | 455 | { |
456 | int i, j, found_isa_hole = 0; | 456 | int i, j, found_isa_hole = 0; |
457 | 457 | ||
458 | /* Setup outbound memory windows */ | 458 | /* Setup outbound memory windows */ |
459 | for (i = j = 0; i < 3; i++) { | 459 | for (i = j = 0; i < 3; i++) { |
460 | struct resource *res = &hose->mem_resources[i]; | 460 | struct resource *res = &hose->mem_resources[i]; |
461 | resource_size_t offset = hose->mem_offset[i]; | 461 | resource_size_t offset = hose->mem_offset[i]; |
462 | 462 | ||
463 | /* we only care about memory windows */ | 463 | /* we only care about memory windows */ |
464 | if (!(res->flags & IORESOURCE_MEM)) | 464 | if (!(res->flags & IORESOURCE_MEM)) |
465 | continue; | 465 | continue; |
466 | if (j > 1) { | 466 | if (j > 1) { |
467 | printk(KERN_WARNING "%s: Too many ranges\n", | 467 | printk(KERN_WARNING "%s: Too many ranges\n", |
468 | hose->dn->full_name); | 468 | hose->dn->full_name); |
469 | break; | 469 | break; |
470 | } | 470 | } |
471 | 471 | ||
472 | /* Configure the resource */ | 472 | /* Configure the resource */ |
473 | if (ppc4xx_setup_one_pcix_POM(hose, reg, | 473 | if (ppc4xx_setup_one_pcix_POM(hose, reg, |
474 | res->start, | 474 | res->start, |
475 | res->start - offset, | 475 | res->start - offset, |
476 | resource_size(res), | 476 | resource_size(res), |
477 | res->flags, | 477 | res->flags, |
478 | j) == 0) { | 478 | j) == 0) { |
479 | j++; | 479 | j++; |
480 | 480 | ||
481 | /* If the resource PCI address is 0 then we have our | 481 | /* If the resource PCI address is 0 then we have our |
482 | * ISA memory hole | 482 | * ISA memory hole |
483 | */ | 483 | */ |
484 | if (res->start == offset) | 484 | if (res->start == offset) |
485 | found_isa_hole = 1; | 485 | found_isa_hole = 1; |
486 | } | 486 | } |
487 | } | 487 | } |
488 | 488 | ||
489 | /* Handle ISA memory hole if not already covered */ | 489 | /* Handle ISA memory hole if not already covered */ |
490 | if (j <= 1 && !found_isa_hole && hose->isa_mem_size) | 490 | if (j <= 1 && !found_isa_hole && hose->isa_mem_size) |
491 | if (ppc4xx_setup_one_pcix_POM(hose, reg, hose->isa_mem_phys, 0, | 491 | if (ppc4xx_setup_one_pcix_POM(hose, reg, hose->isa_mem_phys, 0, |
492 | hose->isa_mem_size, 0, j) == 0) | 492 | hose->isa_mem_size, 0, j) == 0) |
493 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", | 493 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", |
494 | hose->dn->full_name); | 494 | hose->dn->full_name); |
495 | } | 495 | } |
496 | 496 | ||
497 | static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, | 497 | static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, |
498 | void __iomem *reg, | 498 | void __iomem *reg, |
499 | const struct resource *res, | 499 | const struct resource *res, |
500 | int big_pim, | 500 | int big_pim, |
501 | int enable_msi_hole) | 501 | int enable_msi_hole) |
502 | { | 502 | { |
503 | resource_size_t size = resource_size(res); | 503 | resource_size_t size = resource_size(res); |
504 | u32 sa; | 504 | u32 sa; |
505 | 505 | ||
506 | /* RAM is always at 0 */ | 506 | /* RAM is always at 0 */ |
507 | writel(0x00000000, reg + PCIX0_PIM0LAH); | 507 | writel(0x00000000, reg + PCIX0_PIM0LAH); |
508 | writel(0x00000000, reg + PCIX0_PIM0LAL); | 508 | writel(0x00000000, reg + PCIX0_PIM0LAL); |
509 | 509 | ||
510 | /* Calculate window size */ | 510 | /* Calculate window size */ |
511 | sa = (0xffffffffu << ilog2(size)) | 1; | 511 | sa = (0xffffffffu << ilog2(size)) | 1; |
512 | sa |= 0x1; | 512 | sa |= 0x1; |
513 | if (res->flags & IORESOURCE_PREFETCH) | 513 | if (res->flags & IORESOURCE_PREFETCH) |
514 | sa |= 0x2; | 514 | sa |= 0x2; |
515 | if (enable_msi_hole) | 515 | if (enable_msi_hole) |
516 | sa |= 0x4; | 516 | sa |= 0x4; |
517 | writel(sa, reg + PCIX0_PIM0SA); | 517 | writel(sa, reg + PCIX0_PIM0SA); |
518 | if (big_pim) | 518 | if (big_pim) |
519 | writel(0xffffffff, reg + PCIX0_PIM0SAH); | 519 | writel(0xffffffff, reg + PCIX0_PIM0SAH); |
520 | 520 | ||
521 | /* Map on PCI side */ | 521 | /* Map on PCI side */ |
522 | writel(0x00000000, reg + PCIX0_BAR0H); | 522 | writel(0x00000000, reg + PCIX0_BAR0H); |
523 | writel(res->start, reg + PCIX0_BAR0L); | 523 | writel(res->start, reg + PCIX0_BAR0L); |
524 | writew(0x0006, reg + PCIX0_COMMAND); | 524 | writew(0x0006, reg + PCIX0_COMMAND); |
525 | } | 525 | } |
526 | 526 | ||
527 | static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) | 527 | static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) |
528 | { | 528 | { |
529 | struct resource rsrc_cfg; | 529 | struct resource rsrc_cfg; |
530 | struct resource rsrc_reg; | 530 | struct resource rsrc_reg; |
531 | struct resource dma_window; | 531 | struct resource dma_window; |
532 | struct pci_controller *hose = NULL; | 532 | struct pci_controller *hose = NULL; |
533 | void __iomem *reg = NULL; | 533 | void __iomem *reg = NULL; |
534 | const int *bus_range; | 534 | const int *bus_range; |
535 | int big_pim = 0, msi = 0, primary = 0; | 535 | int big_pim = 0, msi = 0, primary = 0; |
536 | 536 | ||
537 | /* Fetch config space registers address */ | 537 | /* Fetch config space registers address */ |
538 | if (of_address_to_resource(np, 0, &rsrc_cfg)) { | 538 | if (of_address_to_resource(np, 0, &rsrc_cfg)) { |
539 | printk(KERN_ERR "%s:Can't get PCI-X config register base !", | 539 | printk(KERN_ERR "%s:Can't get PCI-X config register base !", |
540 | np->full_name); | 540 | np->full_name); |
541 | return; | 541 | return; |
542 | } | 542 | } |
543 | /* Fetch host bridge internal registers address */ | 543 | /* Fetch host bridge internal registers address */ |
544 | if (of_address_to_resource(np, 3, &rsrc_reg)) { | 544 | if (of_address_to_resource(np, 3, &rsrc_reg)) { |
545 | printk(KERN_ERR "%s: Can't get PCI-X internal register base !", | 545 | printk(KERN_ERR "%s: Can't get PCI-X internal register base !", |
546 | np->full_name); | 546 | np->full_name); |
547 | return; | 547 | return; |
548 | } | 548 | } |
549 | 549 | ||
550 | /* Check if it supports large PIMs (440GX) */ | 550 | /* Check if it supports large PIMs (440GX) */ |
551 | if (of_get_property(np, "large-inbound-windows", NULL)) | 551 | if (of_get_property(np, "large-inbound-windows", NULL)) |
552 | big_pim = 1; | 552 | big_pim = 1; |
553 | 553 | ||
554 | /* Check if we should enable MSIs inbound hole */ | 554 | /* Check if we should enable MSIs inbound hole */ |
555 | if (of_get_property(np, "enable-msi-hole", NULL)) | 555 | if (of_get_property(np, "enable-msi-hole", NULL)) |
556 | msi = 1; | 556 | msi = 1; |
557 | 557 | ||
558 | /* Check if primary bridge */ | 558 | /* Check if primary bridge */ |
559 | if (of_get_property(np, "primary", NULL)) | 559 | if (of_get_property(np, "primary", NULL)) |
560 | primary = 1; | 560 | primary = 1; |
561 | 561 | ||
562 | /* Get bus range if any */ | 562 | /* Get bus range if any */ |
563 | bus_range = of_get_property(np, "bus-range", NULL); | 563 | bus_range = of_get_property(np, "bus-range", NULL); |
564 | 564 | ||
565 | /* Map registers */ | 565 | /* Map registers */ |
566 | reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); | 566 | reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); |
567 | if (reg == NULL) { | 567 | if (reg == NULL) { |
568 | printk(KERN_ERR "%s: Can't map registers !", np->full_name); | 568 | printk(KERN_ERR "%s: Can't map registers !", np->full_name); |
569 | goto fail; | 569 | goto fail; |
570 | } | 570 | } |
571 | 571 | ||
572 | /* Allocate the host controller data structure */ | 572 | /* Allocate the host controller data structure */ |
573 | hose = pcibios_alloc_controller(np); | 573 | hose = pcibios_alloc_controller(np); |
574 | if (!hose) | 574 | if (!hose) |
575 | goto fail; | 575 | goto fail; |
576 | 576 | ||
577 | hose->first_busno = bus_range ? bus_range[0] : 0x0; | 577 | hose->first_busno = bus_range ? bus_range[0] : 0x0; |
578 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 578 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
579 | 579 | ||
580 | /* Setup config space */ | 580 | /* Setup config space */ |
581 | setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, | 581 | setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, |
582 | PPC_INDIRECT_TYPE_SET_CFG_TYPE); | 582 | PPC_INDIRECT_TYPE_SET_CFG_TYPE); |
583 | 583 | ||
584 | /* Disable all windows */ | 584 | /* Disable all windows */ |
585 | writel(0, reg + PCIX0_POM0SA); | 585 | writel(0, reg + PCIX0_POM0SA); |
586 | writel(0, reg + PCIX0_POM1SA); | 586 | writel(0, reg + PCIX0_POM1SA); |
587 | writel(0, reg + PCIX0_POM2SA); | 587 | writel(0, reg + PCIX0_POM2SA); |
588 | writel(0, reg + PCIX0_PIM0SA); | 588 | writel(0, reg + PCIX0_PIM0SA); |
589 | writel(0, reg + PCIX0_PIM1SA); | 589 | writel(0, reg + PCIX0_PIM1SA); |
590 | writel(0, reg + PCIX0_PIM2SA); | 590 | writel(0, reg + PCIX0_PIM2SA); |
591 | if (big_pim) { | 591 | if (big_pim) { |
592 | writel(0, reg + PCIX0_PIM0SAH); | 592 | writel(0, reg + PCIX0_PIM0SAH); |
593 | writel(0, reg + PCIX0_PIM2SAH); | 593 | writel(0, reg + PCIX0_PIM2SAH); |
594 | } | 594 | } |
595 | 595 | ||
596 | /* Parse outbound mapping resources */ | 596 | /* Parse outbound mapping resources */ |
597 | pci_process_bridge_OF_ranges(hose, np, primary); | 597 | pci_process_bridge_OF_ranges(hose, np, primary); |
598 | 598 | ||
599 | /* Parse inbound mapping resources */ | 599 | /* Parse inbound mapping resources */ |
600 | if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) | 600 | if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) |
601 | goto fail; | 601 | goto fail; |
602 | 602 | ||
603 | /* Configure outbound ranges POMs */ | 603 | /* Configure outbound ranges POMs */ |
604 | ppc4xx_configure_pcix_POMs(hose, reg); | 604 | ppc4xx_configure_pcix_POMs(hose, reg); |
605 | 605 | ||
606 | /* Configure inbound ranges PIMs */ | 606 | /* Configure inbound ranges PIMs */ |
607 | ppc4xx_configure_pcix_PIMs(hose, reg, &dma_window, big_pim, msi); | 607 | ppc4xx_configure_pcix_PIMs(hose, reg, &dma_window, big_pim, msi); |
608 | 608 | ||
609 | /* We don't need the registers anymore */ | 609 | /* We don't need the registers anymore */ |
610 | iounmap(reg); | 610 | iounmap(reg); |
611 | return; | 611 | return; |
612 | 612 | ||
613 | fail: | 613 | fail: |
614 | if (hose) | 614 | if (hose) |
615 | pcibios_free_controller(hose); | 615 | pcibios_free_controller(hose); |
616 | if (reg) | 616 | if (reg) |
617 | iounmap(reg); | 617 | iounmap(reg); |
618 | } | 618 | } |
619 | 619 | ||
620 | #ifdef CONFIG_PPC4xx_PCI_EXPRESS | 620 | #ifdef CONFIG_PPC4xx_PCI_EXPRESS |
621 | 621 | ||
622 | /* | 622 | /* |
623 | * 4xx PCI-Express part | 623 | * 4xx PCI-Express part |
624 | * | 624 | * |
625 | * We support 3 parts currently based on the compatible property: | 625 | * We support 3 parts currently based on the compatible property: |
626 | * | 626 | * |
627 | * ibm,plb-pciex-440spe | 627 | * ibm,plb-pciex-440spe |
628 | * ibm,plb-pciex-405ex | 628 | * ibm,plb-pciex-405ex |
629 | * ibm,plb-pciex-460ex | 629 | * ibm,plb-pciex-460ex |
630 | * | 630 | * |
631 | * Anything else will be rejected for now as they are all subtly | 631 | * Anything else will be rejected for now as they are all subtly |
632 | * different unfortunately. | 632 | * different unfortunately. |
633 | * | 633 | * |
634 | */ | 634 | */ |
635 | 635 | ||
636 | #define MAX_PCIE_BUS_MAPPED 0x40 | 636 | #define MAX_PCIE_BUS_MAPPED 0x40 |
637 | 637 | ||
638 | struct ppc4xx_pciex_port | 638 | struct ppc4xx_pciex_port |
639 | { | 639 | { |
640 | struct pci_controller *hose; | 640 | struct pci_controller *hose; |
641 | struct device_node *node; | 641 | struct device_node *node; |
642 | unsigned int index; | 642 | unsigned int index; |
643 | int endpoint; | 643 | int endpoint; |
644 | int link; | 644 | int link; |
645 | int has_ibpre; | 645 | int has_ibpre; |
646 | unsigned int sdr_base; | 646 | unsigned int sdr_base; |
647 | dcr_host_t dcrs; | 647 | dcr_host_t dcrs; |
648 | struct resource cfg_space; | 648 | struct resource cfg_space; |
649 | struct resource utl_regs; | 649 | struct resource utl_regs; |
650 | void __iomem *utl_base; | 650 | void __iomem *utl_base; |
651 | }; | 651 | }; |
652 | 652 | ||
653 | static struct ppc4xx_pciex_port *ppc4xx_pciex_ports; | 653 | static struct ppc4xx_pciex_port *ppc4xx_pciex_ports; |
654 | static unsigned int ppc4xx_pciex_port_count; | 654 | static unsigned int ppc4xx_pciex_port_count; |
655 | 655 | ||
656 | struct ppc4xx_pciex_hwops | 656 | struct ppc4xx_pciex_hwops |
657 | { | 657 | { |
658 | bool want_sdr; | 658 | bool want_sdr; |
659 | int (*core_init)(struct device_node *np); | 659 | int (*core_init)(struct device_node *np); |
660 | int (*port_init_hw)(struct ppc4xx_pciex_port *port); | 660 | int (*port_init_hw)(struct ppc4xx_pciex_port *port); |
661 | int (*setup_utl)(struct ppc4xx_pciex_port *port); | 661 | int (*setup_utl)(struct ppc4xx_pciex_port *port); |
662 | void (*check_link)(struct ppc4xx_pciex_port *port); | 662 | void (*check_link)(struct ppc4xx_pciex_port *port); |
663 | }; | 663 | }; |
664 | 664 | ||
665 | static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops; | 665 | static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops; |
666 | 666 | ||
667 | static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port, | 667 | static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port, |
668 | unsigned int sdr_offset, | 668 | unsigned int sdr_offset, |
669 | unsigned int mask, | 669 | unsigned int mask, |
670 | unsigned int value, | 670 | unsigned int value, |
671 | int timeout_ms) | 671 | int timeout_ms) |
672 | { | 672 | { |
673 | u32 val; | 673 | u32 val; |
674 | 674 | ||
675 | while(timeout_ms--) { | 675 | while(timeout_ms--) { |
676 | val = mfdcri(SDR0, port->sdr_base + sdr_offset); | 676 | val = mfdcri(SDR0, port->sdr_base + sdr_offset); |
677 | if ((val & mask) == value) { | 677 | if ((val & mask) == value) { |
678 | pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n", | 678 | pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n", |
679 | port->index, sdr_offset, timeout_ms, val); | 679 | port->index, sdr_offset, timeout_ms, val); |
680 | return 0; | 680 | return 0; |
681 | } | 681 | } |
682 | msleep(1); | 682 | msleep(1); |
683 | } | 683 | } |
684 | return -1; | 684 | return -1; |
685 | } | 685 | } |
686 | 686 | ||
687 | static int __init ppc4xx_pciex_port_reset_sdr(struct ppc4xx_pciex_port *port) | 687 | static int __init ppc4xx_pciex_port_reset_sdr(struct ppc4xx_pciex_port *port) |
688 | { | 688 | { |
689 | /* Wait for reset to complete */ | 689 | /* Wait for reset to complete */ |
690 | if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) { | 690 | if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) { |
691 | printk(KERN_WARNING "PCIE%d: PGRST failed\n", | 691 | printk(KERN_WARNING "PCIE%d: PGRST failed\n", |
692 | port->index); | 692 | port->index); |
693 | return -1; | 693 | return -1; |
694 | } | 694 | } |
695 | return 0; | 695 | return 0; |
696 | } | 696 | } |
697 | 697 | ||
698 | 698 | ||
699 | static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port) | 699 | static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port) |
700 | { | 700 | { |
701 | printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); | 701 | printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); |
702 | 702 | ||
703 | /* Check for card presence detect if supported, if not, just wait for | 703 | /* Check for card presence detect if supported, if not, just wait for |
704 | * link unconditionally. | 704 | * link unconditionally. |
705 | * | 705 | * |
706 | * note that we don't fail if there is no link, we just filter out | 706 | * note that we don't fail if there is no link, we just filter out |
707 | * config space accesses. That way, it will be easier to implement | 707 | * config space accesses. That way, it will be easier to implement |
708 | * hotplug later on. | 708 | * hotplug later on. |
709 | */ | 709 | */ |
710 | if (!port->has_ibpre || | 710 | if (!port->has_ibpre || |
711 | !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, | 711 | !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, |
712 | 1 << 28, 1 << 28, 100)) { | 712 | 1 << 28, 1 << 28, 100)) { |
713 | printk(KERN_INFO | 713 | printk(KERN_INFO |
714 | "PCIE%d: Device detected, waiting for link...\n", | 714 | "PCIE%d: Device detected, waiting for link...\n", |
715 | port->index); | 715 | port->index); |
716 | if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, | 716 | if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, |
717 | 0x1000, 0x1000, 2000)) | 717 | 0x1000, 0x1000, 2000)) |
718 | printk(KERN_WARNING | 718 | printk(KERN_WARNING |
719 | "PCIE%d: Link up failed\n", port->index); | 719 | "PCIE%d: Link up failed\n", port->index); |
720 | else { | 720 | else { |
721 | printk(KERN_INFO | 721 | printk(KERN_INFO |
722 | "PCIE%d: link is up !\n", port->index); | 722 | "PCIE%d: link is up !\n", port->index); |
723 | port->link = 1; | 723 | port->link = 1; |
724 | } | 724 | } |
725 | } else | 725 | } else |
726 | printk(KERN_INFO "PCIE%d: No device detected.\n", port->index); | 726 | printk(KERN_INFO "PCIE%d: No device detected.\n", port->index); |
727 | } | 727 | } |
728 | 728 | ||
729 | #ifdef CONFIG_44x | 729 | #ifdef CONFIG_44x |
730 | 730 | ||
731 | /* Check various reset bits of the 440SPe PCIe core */ | 731 | /* Check various reset bits of the 440SPe PCIe core */ |
732 | static int __init ppc440spe_pciex_check_reset(struct device_node *np) | 732 | static int __init ppc440spe_pciex_check_reset(struct device_node *np) |
733 | { | 733 | { |
734 | u32 valPE0, valPE1, valPE2; | 734 | u32 valPE0, valPE1, valPE2; |
735 | int err = 0; | 735 | int err = 0; |
736 | 736 | ||
737 | /* SDR0_PEGPLLLCT1 reset */ | 737 | /* SDR0_PEGPLLLCT1 reset */ |
738 | if (!(mfdcri(SDR0, PESDR0_PLLLCT1) & 0x01000000)) { | 738 | if (!(mfdcri(SDR0, PESDR0_PLLLCT1) & 0x01000000)) { |
739 | /* | 739 | /* |
740 | * the PCIe core was probably already initialised | 740 | * the PCIe core was probably already initialised |
741 | * by firmware - let's re-reset RCSSET regs | 741 | * by firmware - let's re-reset RCSSET regs |
742 | * | 742 | * |
743 | * -- Shouldn't we also re-reset the whole thing ? -- BenH | 743 | * -- Shouldn't we also re-reset the whole thing ? -- BenH |
744 | */ | 744 | */ |
745 | pr_debug("PCIE: SDR0_PLLLCT1 already reset.\n"); | 745 | pr_debug("PCIE: SDR0_PLLLCT1 already reset.\n"); |
746 | mtdcri(SDR0, PESDR0_440SPE_RCSSET, 0x01010000); | 746 | mtdcri(SDR0, PESDR0_440SPE_RCSSET, 0x01010000); |
747 | mtdcri(SDR0, PESDR1_440SPE_RCSSET, 0x01010000); | 747 | mtdcri(SDR0, PESDR1_440SPE_RCSSET, 0x01010000); |
748 | mtdcri(SDR0, PESDR2_440SPE_RCSSET, 0x01010000); | 748 | mtdcri(SDR0, PESDR2_440SPE_RCSSET, 0x01010000); |
749 | } | 749 | } |
750 | 750 | ||
751 | valPE0 = mfdcri(SDR0, PESDR0_440SPE_RCSSET); | 751 | valPE0 = mfdcri(SDR0, PESDR0_440SPE_RCSSET); |
752 | valPE1 = mfdcri(SDR0, PESDR1_440SPE_RCSSET); | 752 | valPE1 = mfdcri(SDR0, PESDR1_440SPE_RCSSET); |
753 | valPE2 = mfdcri(SDR0, PESDR2_440SPE_RCSSET); | 753 | valPE2 = mfdcri(SDR0, PESDR2_440SPE_RCSSET); |
754 | 754 | ||
755 | /* SDR0_PExRCSSET rstgu */ | 755 | /* SDR0_PExRCSSET rstgu */ |
756 | if (!(valPE0 & 0x01000000) || | 756 | if (!(valPE0 & 0x01000000) || |
757 | !(valPE1 & 0x01000000) || | 757 | !(valPE1 & 0x01000000) || |
758 | !(valPE2 & 0x01000000)) { | 758 | !(valPE2 & 0x01000000)) { |
759 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n"); | 759 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n"); |
760 | err = -1; | 760 | err = -1; |
761 | } | 761 | } |
762 | 762 | ||
763 | /* SDR0_PExRCSSET rstdl */ | 763 | /* SDR0_PExRCSSET rstdl */ |
764 | if (!(valPE0 & 0x00010000) || | 764 | if (!(valPE0 & 0x00010000) || |
765 | !(valPE1 & 0x00010000) || | 765 | !(valPE1 & 0x00010000) || |
766 | !(valPE2 & 0x00010000)) { | 766 | !(valPE2 & 0x00010000)) { |
767 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n"); | 767 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n"); |
768 | err = -1; | 768 | err = -1; |
769 | } | 769 | } |
770 | 770 | ||
771 | /* SDR0_PExRCSSET rstpyn */ | 771 | /* SDR0_PExRCSSET rstpyn */ |
772 | if ((valPE0 & 0x00001000) || | 772 | if ((valPE0 & 0x00001000) || |
773 | (valPE1 & 0x00001000) || | 773 | (valPE1 & 0x00001000) || |
774 | (valPE2 & 0x00001000)) { | 774 | (valPE2 & 0x00001000)) { |
775 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n"); | 775 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n"); |
776 | err = -1; | 776 | err = -1; |
777 | } | 777 | } |
778 | 778 | ||
779 | /* SDR0_PExRCSSET hldplb */ | 779 | /* SDR0_PExRCSSET hldplb */ |
780 | if ((valPE0 & 0x10000000) || | 780 | if ((valPE0 & 0x10000000) || |
781 | (valPE1 & 0x10000000) || | 781 | (valPE1 & 0x10000000) || |
782 | (valPE2 & 0x10000000)) { | 782 | (valPE2 & 0x10000000)) { |
783 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n"); | 783 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n"); |
784 | err = -1; | 784 | err = -1; |
785 | } | 785 | } |
786 | 786 | ||
787 | /* SDR0_PExRCSSET rdy */ | 787 | /* SDR0_PExRCSSET rdy */ |
788 | if ((valPE0 & 0x00100000) || | 788 | if ((valPE0 & 0x00100000) || |
789 | (valPE1 & 0x00100000) || | 789 | (valPE1 & 0x00100000) || |
790 | (valPE2 & 0x00100000)) { | 790 | (valPE2 & 0x00100000)) { |
791 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n"); | 791 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n"); |
792 | err = -1; | 792 | err = -1; |
793 | } | 793 | } |
794 | 794 | ||
795 | /* SDR0_PExRCSSET shutdown */ | 795 | /* SDR0_PExRCSSET shutdown */ |
796 | if ((valPE0 & 0x00000100) || | 796 | if ((valPE0 & 0x00000100) || |
797 | (valPE1 & 0x00000100) || | 797 | (valPE1 & 0x00000100) || |
798 | (valPE2 & 0x00000100)) { | 798 | (valPE2 & 0x00000100)) { |
799 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n"); | 799 | printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n"); |
800 | err = -1; | 800 | err = -1; |
801 | } | 801 | } |
802 | 802 | ||
803 | return err; | 803 | return err; |
804 | } | 804 | } |
805 | 805 | ||
806 | /* Global PCIe core initializations for 440SPe core */ | 806 | /* Global PCIe core initializations for 440SPe core */ |
807 | static int __init ppc440spe_pciex_core_init(struct device_node *np) | 807 | static int __init ppc440spe_pciex_core_init(struct device_node *np) |
808 | { | 808 | { |
809 | int time_out = 20; | 809 | int time_out = 20; |
810 | 810 | ||
811 | /* Set PLL clock receiver to LVPECL */ | 811 | /* Set PLL clock receiver to LVPECL */ |
812 | dcri_clrset(SDR0, PESDR0_PLLLCT1, 0, 1 << 28); | 812 | dcri_clrset(SDR0, PESDR0_PLLLCT1, 0, 1 << 28); |
813 | 813 | ||
814 | /* Shouldn't we do all the calibration stuff etc... here ? */ | 814 | /* Shouldn't we do all the calibration stuff etc... here ? */ |
815 | if (ppc440spe_pciex_check_reset(np)) | 815 | if (ppc440spe_pciex_check_reset(np)) |
816 | return -ENXIO; | 816 | return -ENXIO; |
817 | 817 | ||
818 | if (!(mfdcri(SDR0, PESDR0_PLLLCT2) & 0x10000)) { | 818 | if (!(mfdcri(SDR0, PESDR0_PLLLCT2) & 0x10000)) { |
819 | printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration " | 819 | printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration " |
820 | "failed (0x%08x)\n", | 820 | "failed (0x%08x)\n", |
821 | mfdcri(SDR0, PESDR0_PLLLCT2)); | 821 | mfdcri(SDR0, PESDR0_PLLLCT2)); |
822 | return -1; | 822 | return -1; |
823 | } | 823 | } |
824 | 824 | ||
825 | /* De-assert reset of PCIe PLL, wait for lock */ | 825 | /* De-assert reset of PCIe PLL, wait for lock */ |
826 | dcri_clrset(SDR0, PESDR0_PLLLCT1, 1 << 24, 0); | 826 | dcri_clrset(SDR0, PESDR0_PLLLCT1, 1 << 24, 0); |
827 | udelay(3); | 827 | udelay(3); |
828 | 828 | ||
829 | while (time_out) { | 829 | while (time_out) { |
830 | if (!(mfdcri(SDR0, PESDR0_PLLLCT3) & 0x10000000)) { | 830 | if (!(mfdcri(SDR0, PESDR0_PLLLCT3) & 0x10000000)) { |
831 | time_out--; | 831 | time_out--; |
832 | udelay(1); | 832 | udelay(1); |
833 | } else | 833 | } else |
834 | break; | 834 | break; |
835 | } | 835 | } |
836 | if (!time_out) { | 836 | if (!time_out) { |
837 | printk(KERN_INFO "PCIE: VCO output not locked\n"); | 837 | printk(KERN_INFO "PCIE: VCO output not locked\n"); |
838 | return -1; | 838 | return -1; |
839 | } | 839 | } |
840 | 840 | ||
841 | pr_debug("PCIE initialization OK\n"); | 841 | pr_debug("PCIE initialization OK\n"); |
842 | 842 | ||
843 | return 3; | 843 | return 3; |
844 | } | 844 | } |
845 | 845 | ||
846 | static int __init ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 846 | static int __init ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
847 | { | 847 | { |
848 | u32 val = 1 << 24; | 848 | u32 val = 1 << 24; |
849 | 849 | ||
850 | if (port->endpoint) | 850 | if (port->endpoint) |
851 | val = PTYPE_LEGACY_ENDPOINT << 20; | 851 | val = PTYPE_LEGACY_ENDPOINT << 20; |
852 | else | 852 | else |
853 | val = PTYPE_ROOT_PORT << 20; | 853 | val = PTYPE_ROOT_PORT << 20; |
854 | 854 | ||
855 | if (port->index == 0) | 855 | if (port->index == 0) |
856 | val |= LNKW_X8 << 12; | 856 | val |= LNKW_X8 << 12; |
857 | else | 857 | else |
858 | val |= LNKW_X4 << 12; | 858 | val |= LNKW_X4 << 12; |
859 | 859 | ||
860 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); | 860 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); |
861 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x20222222); | 861 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x20222222); |
862 | if (ppc440spe_revA()) | 862 | if (ppc440spe_revA()) |
863 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x11000000); | 863 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x11000000); |
864 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL0SET1, 0x35000000); | 864 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL0SET1, 0x35000000); |
865 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL1SET1, 0x35000000); | 865 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL1SET1, 0x35000000); |
866 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL2SET1, 0x35000000); | 866 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL2SET1, 0x35000000); |
867 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL3SET1, 0x35000000); | 867 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL3SET1, 0x35000000); |
868 | if (port->index == 0) { | 868 | if (port->index == 0) { |
869 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL4SET1, | 869 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL4SET1, |
870 | 0x35000000); | 870 | 0x35000000); |
871 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL5SET1, | 871 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL5SET1, |
872 | 0x35000000); | 872 | 0x35000000); |
873 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL6SET1, | 873 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL6SET1, |
874 | 0x35000000); | 874 | 0x35000000); |
875 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1, | 875 | mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1, |
876 | 0x35000000); | 876 | 0x35000000); |
877 | } | 877 | } |
878 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, | 878 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, |
879 | (1 << 24) | (1 << 16), 1 << 12); | 879 | (1 << 24) | (1 << 16), 1 << 12); |
880 | 880 | ||
881 | return ppc4xx_pciex_port_reset_sdr(port); | 881 | return ppc4xx_pciex_port_reset_sdr(port); |
882 | } | 882 | } |
883 | 883 | ||
884 | static int __init ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 884 | static int __init ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
885 | { | 885 | { |
886 | return ppc440spe_pciex_init_port_hw(port); | 886 | return ppc440spe_pciex_init_port_hw(port); |
887 | } | 887 | } |
888 | 888 | ||
889 | static int __init ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 889 | static int __init ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
890 | { | 890 | { |
891 | int rc = ppc440spe_pciex_init_port_hw(port); | 891 | int rc = ppc440spe_pciex_init_port_hw(port); |
892 | 892 | ||
893 | port->has_ibpre = 1; | 893 | port->has_ibpre = 1; |
894 | 894 | ||
895 | return rc; | 895 | return rc; |
896 | } | 896 | } |
897 | 897 | ||
898 | static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port) | 898 | static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port) |
899 | { | 899 | { |
900 | /* XXX Check what that value means... I hate magic */ | 900 | /* XXX Check what that value means... I hate magic */ |
901 | dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x68782800); | 901 | dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x68782800); |
902 | 902 | ||
903 | /* | 903 | /* |
904 | * Set buffer allocations and then assert VRB and TXE. | 904 | * Set buffer allocations and then assert VRB and TXE. |
905 | */ | 905 | */ |
906 | out_be32(port->utl_base + PEUTL_OUTTR, 0x08000000); | 906 | out_be32(port->utl_base + PEUTL_OUTTR, 0x08000000); |
907 | out_be32(port->utl_base + PEUTL_INTR, 0x02000000); | 907 | out_be32(port->utl_base + PEUTL_INTR, 0x02000000); |
908 | out_be32(port->utl_base + PEUTL_OPDBSZ, 0x10000000); | 908 | out_be32(port->utl_base + PEUTL_OPDBSZ, 0x10000000); |
909 | out_be32(port->utl_base + PEUTL_PBBSZ, 0x53000000); | 909 | out_be32(port->utl_base + PEUTL_PBBSZ, 0x53000000); |
910 | out_be32(port->utl_base + PEUTL_IPHBSZ, 0x08000000); | 910 | out_be32(port->utl_base + PEUTL_IPHBSZ, 0x08000000); |
911 | out_be32(port->utl_base + PEUTL_IPDBSZ, 0x10000000); | 911 | out_be32(port->utl_base + PEUTL_IPDBSZ, 0x10000000); |
912 | out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000); | 912 | out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000); |
913 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); | 913 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); |
914 | 914 | ||
915 | return 0; | 915 | return 0; |
916 | } | 916 | } |
917 | 917 | ||
918 | static int ppc440speB_pciex_init_utl(struct ppc4xx_pciex_port *port) | 918 | static int ppc440speB_pciex_init_utl(struct ppc4xx_pciex_port *port) |
919 | { | 919 | { |
920 | /* Report CRS to the operating system */ | 920 | /* Report CRS to the operating system */ |
921 | out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000); | 921 | out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000); |
922 | 922 | ||
923 | return 0; | 923 | return 0; |
924 | } | 924 | } |
925 | 925 | ||
926 | static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata = | 926 | static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata = |
927 | { | 927 | { |
928 | .want_sdr = true, | 928 | .want_sdr = true, |
929 | .core_init = ppc440spe_pciex_core_init, | 929 | .core_init = ppc440spe_pciex_core_init, |
930 | .port_init_hw = ppc440speA_pciex_init_port_hw, | 930 | .port_init_hw = ppc440speA_pciex_init_port_hw, |
931 | .setup_utl = ppc440speA_pciex_init_utl, | 931 | .setup_utl = ppc440speA_pciex_init_utl, |
932 | .check_link = ppc4xx_pciex_check_link_sdr, | 932 | .check_link = ppc4xx_pciex_check_link_sdr, |
933 | }; | 933 | }; |
934 | 934 | ||
935 | static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = | 935 | static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = |
936 | { | 936 | { |
937 | .want_sdr = true, | 937 | .want_sdr = true, |
938 | .core_init = ppc440spe_pciex_core_init, | 938 | .core_init = ppc440spe_pciex_core_init, |
939 | .port_init_hw = ppc440speB_pciex_init_port_hw, | 939 | .port_init_hw = ppc440speB_pciex_init_port_hw, |
940 | .setup_utl = ppc440speB_pciex_init_utl, | 940 | .setup_utl = ppc440speB_pciex_init_utl, |
941 | .check_link = ppc4xx_pciex_check_link_sdr, | 941 | .check_link = ppc4xx_pciex_check_link_sdr, |
942 | }; | 942 | }; |
943 | 943 | ||
944 | static int __init ppc460ex_pciex_core_init(struct device_node *np) | 944 | static int __init ppc460ex_pciex_core_init(struct device_node *np) |
945 | { | 945 | { |
946 | /* Nothing to do, return 2 ports */ | 946 | /* Nothing to do, return 2 ports */ |
947 | return 2; | 947 | return 2; |
948 | } | 948 | } |
949 | 949 | ||
950 | static int __init ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 950 | static int __init ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
951 | { | 951 | { |
952 | u32 val; | 952 | u32 val; |
953 | u32 utlset1; | 953 | u32 utlset1; |
954 | 954 | ||
955 | if (port->endpoint) | 955 | if (port->endpoint) |
956 | val = PTYPE_LEGACY_ENDPOINT << 20; | 956 | val = PTYPE_LEGACY_ENDPOINT << 20; |
957 | else | 957 | else |
958 | val = PTYPE_ROOT_PORT << 20; | 958 | val = PTYPE_ROOT_PORT << 20; |
959 | 959 | ||
960 | if (port->index == 0) { | 960 | if (port->index == 0) { |
961 | val |= LNKW_X1 << 12; | 961 | val |= LNKW_X1 << 12; |
962 | utlset1 = 0x20000000; | 962 | utlset1 = 0x20000000; |
963 | } else { | 963 | } else { |
964 | val |= LNKW_X4 << 12; | 964 | val |= LNKW_X4 << 12; |
965 | utlset1 = 0x20101101; | 965 | utlset1 = 0x20101101; |
966 | } | 966 | } |
967 | 967 | ||
968 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); | 968 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); |
969 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, utlset1); | 969 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, utlset1); |
970 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01210000); | 970 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01210000); |
971 | 971 | ||
972 | switch (port->index) { | 972 | switch (port->index) { |
973 | case 0: | 973 | case 0: |
974 | mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230); | 974 | mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230); |
975 | mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130); | 975 | mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130); |
976 | mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006); | 976 | mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006); |
977 | 977 | ||
978 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST,0x10000000); | 978 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST,0x10000000); |
979 | break; | 979 | break; |
980 | 980 | ||
981 | case 1: | 981 | case 1: |
982 | mtdcri(SDR0, PESDR1_460EX_L0CDRCTL, 0x00003230); | 982 | mtdcri(SDR0, PESDR1_460EX_L0CDRCTL, 0x00003230); |
983 | mtdcri(SDR0, PESDR1_460EX_L1CDRCTL, 0x00003230); | 983 | mtdcri(SDR0, PESDR1_460EX_L1CDRCTL, 0x00003230); |
984 | mtdcri(SDR0, PESDR1_460EX_L2CDRCTL, 0x00003230); | 984 | mtdcri(SDR0, PESDR1_460EX_L2CDRCTL, 0x00003230); |
985 | mtdcri(SDR0, PESDR1_460EX_L3CDRCTL, 0x00003230); | 985 | mtdcri(SDR0, PESDR1_460EX_L3CDRCTL, 0x00003230); |
986 | mtdcri(SDR0, PESDR1_460EX_L0DRV, 0x00000130); | 986 | mtdcri(SDR0, PESDR1_460EX_L0DRV, 0x00000130); |
987 | mtdcri(SDR0, PESDR1_460EX_L1DRV, 0x00000130); | 987 | mtdcri(SDR0, PESDR1_460EX_L1DRV, 0x00000130); |
988 | mtdcri(SDR0, PESDR1_460EX_L2DRV, 0x00000130); | 988 | mtdcri(SDR0, PESDR1_460EX_L2DRV, 0x00000130); |
989 | mtdcri(SDR0, PESDR1_460EX_L3DRV, 0x00000130); | 989 | mtdcri(SDR0, PESDR1_460EX_L3DRV, 0x00000130); |
990 | mtdcri(SDR0, PESDR1_460EX_L0CLK, 0x00000006); | 990 | mtdcri(SDR0, PESDR1_460EX_L0CLK, 0x00000006); |
991 | mtdcri(SDR0, PESDR1_460EX_L1CLK, 0x00000006); | 991 | mtdcri(SDR0, PESDR1_460EX_L1CLK, 0x00000006); |
992 | mtdcri(SDR0, PESDR1_460EX_L2CLK, 0x00000006); | 992 | mtdcri(SDR0, PESDR1_460EX_L2CLK, 0x00000006); |
993 | mtdcri(SDR0, PESDR1_460EX_L3CLK, 0x00000006); | 993 | mtdcri(SDR0, PESDR1_460EX_L3CLK, 0x00000006); |
994 | 994 | ||
995 | mtdcri(SDR0, PESDR1_460EX_PHY_CTL_RST,0x10000000); | 995 | mtdcri(SDR0, PESDR1_460EX_PHY_CTL_RST,0x10000000); |
996 | break; | 996 | break; |
997 | } | 997 | } |
998 | 998 | ||
999 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, | 999 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, |
1000 | mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | | 1000 | mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | |
1001 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN)); | 1001 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN)); |
1002 | 1002 | ||
1003 | /* Poll for PHY reset */ | 1003 | /* Poll for PHY reset */ |
1004 | /* XXX FIXME add timeout */ | 1004 | /* XXX FIXME add timeout */ |
1005 | switch (port->index) { | 1005 | switch (port->index) { |
1006 | case 0: | 1006 | case 0: |
1007 | while (!(mfdcri(SDR0, PESDR0_460EX_RSTSTA) & 0x1)) | 1007 | while (!(mfdcri(SDR0, PESDR0_460EX_RSTSTA) & 0x1)) |
1008 | udelay(10); | 1008 | udelay(10); |
1009 | break; | 1009 | break; |
1010 | case 1: | 1010 | case 1: |
1011 | while (!(mfdcri(SDR0, PESDR1_460EX_RSTSTA) & 0x1)) | 1011 | while (!(mfdcri(SDR0, PESDR1_460EX_RSTSTA) & 0x1)) |
1012 | udelay(10); | 1012 | udelay(10); |
1013 | break; | 1013 | break; |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, | 1016 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, |
1017 | (mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) & | 1017 | (mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) & |
1018 | ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) | | 1018 | ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) | |
1019 | PESDRx_RCSSET_RSTPYN); | 1019 | PESDRx_RCSSET_RSTPYN); |
1020 | 1020 | ||
1021 | port->has_ibpre = 1; | 1021 | port->has_ibpre = 1; |
1022 | 1022 | ||
1023 | return ppc4xx_pciex_port_reset_sdr(port); | 1023 | return ppc4xx_pciex_port_reset_sdr(port); |
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port) | 1026 | static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port) |
1027 | { | 1027 | { |
1028 | dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0); | 1028 | dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0); |
1029 | 1029 | ||
1030 | /* | 1030 | /* |
1031 | * Set buffer allocations and then assert VRB and TXE. | 1031 | * Set buffer allocations and then assert VRB and TXE. |
1032 | */ | 1032 | */ |
1033 | out_be32(port->utl_base + PEUTL_PBCTL, 0x0800000c); | 1033 | out_be32(port->utl_base + PEUTL_PBCTL, 0x0800000c); |
1034 | out_be32(port->utl_base + PEUTL_OUTTR, 0x08000000); | 1034 | out_be32(port->utl_base + PEUTL_OUTTR, 0x08000000); |
1035 | out_be32(port->utl_base + PEUTL_INTR, 0x02000000); | 1035 | out_be32(port->utl_base + PEUTL_INTR, 0x02000000); |
1036 | out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000); | 1036 | out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000); |
1037 | out_be32(port->utl_base + PEUTL_PBBSZ, 0x00000000); | 1037 | out_be32(port->utl_base + PEUTL_PBBSZ, 0x00000000); |
1038 | out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000); | 1038 | out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000); |
1039 | out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000); | 1039 | out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000); |
1040 | out_be32(port->utl_base + PEUTL_RCIRQEN,0x00f00000); | 1040 | out_be32(port->utl_base + PEUTL_RCIRQEN,0x00f00000); |
1041 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); | 1041 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); |
1042 | 1042 | ||
1043 | return 0; | 1043 | return 0; |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = | 1046 | static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = |
1047 | { | 1047 | { |
1048 | .want_sdr = true, | 1048 | .want_sdr = true, |
1049 | .core_init = ppc460ex_pciex_core_init, | 1049 | .core_init = ppc460ex_pciex_core_init, |
1050 | .port_init_hw = ppc460ex_pciex_init_port_hw, | 1050 | .port_init_hw = ppc460ex_pciex_init_port_hw, |
1051 | .setup_utl = ppc460ex_pciex_init_utl, | 1051 | .setup_utl = ppc460ex_pciex_init_utl, |
1052 | .check_link = ppc4xx_pciex_check_link_sdr, | 1052 | .check_link = ppc4xx_pciex_check_link_sdr, |
1053 | }; | 1053 | }; |
1054 | 1054 | ||
1055 | static int __init apm821xx_pciex_core_init(struct device_node *np) | 1055 | static int __init apm821xx_pciex_core_init(struct device_node *np) |
1056 | { | 1056 | { |
1057 | /* Return the number of pcie port */ | 1057 | /* Return the number of pcie port */ |
1058 | return 1; | 1058 | return 1; |
1059 | } | 1059 | } |
1060 | 1060 | ||
1061 | static int __init apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1061 | static int __init apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1062 | { | 1062 | { |
1063 | u32 val; | 1063 | u32 val; |
1064 | 1064 | ||
1065 | /* | 1065 | /* |
1066 | * Do a software reset on PCIe ports. | 1066 | * Do a software reset on PCIe ports. |
1067 | * This code is to fix the issue that pci drivers doesn't re-assign | 1067 | * This code is to fix the issue that pci drivers doesn't re-assign |
1068 | * bus number for PCIE devices after Uboot | 1068 | * bus number for PCIE devices after Uboot |
1069 | * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000 | 1069 | * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000 |
1070 | * PT quad port, SAS LSI 1064E) | 1070 | * PT quad port, SAS LSI 1064E) |
1071 | */ | 1071 | */ |
1072 | 1072 | ||
1073 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0); | 1073 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0); |
1074 | mdelay(10); | 1074 | mdelay(10); |
1075 | 1075 | ||
1076 | if (port->endpoint) | 1076 | if (port->endpoint) |
1077 | val = PTYPE_LEGACY_ENDPOINT << 20; | 1077 | val = PTYPE_LEGACY_ENDPOINT << 20; |
1078 | else | 1078 | else |
1079 | val = PTYPE_ROOT_PORT << 20; | 1079 | val = PTYPE_ROOT_PORT << 20; |
1080 | 1080 | ||
1081 | val |= LNKW_X1 << 12; | 1081 | val |= LNKW_X1 << 12; |
1082 | 1082 | ||
1083 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); | 1083 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); |
1084 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000); | 1084 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000); |
1085 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000); | 1085 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000); |
1086 | 1086 | ||
1087 | mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230); | 1087 | mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230); |
1088 | mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130); | 1088 | mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130); |
1089 | mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006); | 1089 | mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006); |
1090 | 1090 | ||
1091 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000); | 1091 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000); |
1092 | mdelay(50); | 1092 | mdelay(50); |
1093 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000); | 1093 | mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000); |
1094 | 1094 | ||
1095 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, | 1095 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, |
1096 | mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | | 1096 | mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | |
1097 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN)); | 1097 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN)); |
1098 | 1098 | ||
1099 | /* Poll for PHY reset */ | 1099 | /* Poll for PHY reset */ |
1100 | val = PESDR0_460EX_RSTSTA - port->sdr_base; | 1100 | val = PESDR0_460EX_RSTSTA - port->sdr_base; |
1101 | if (ppc4xx_pciex_wait_on_sdr(port, val, 0x1, 1, 100)) { | 1101 | if (ppc4xx_pciex_wait_on_sdr(port, val, 0x1, 1, 100)) { |
1102 | printk(KERN_WARNING "%s: PCIE: Can't reset PHY\n", __func__); | 1102 | printk(KERN_WARNING "%s: PCIE: Can't reset PHY\n", __func__); |
1103 | return -EBUSY; | 1103 | return -EBUSY; |
1104 | } else { | 1104 | } else { |
1105 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, | 1105 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, |
1106 | (mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) & | 1106 | (mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) & |
1107 | ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) | | 1107 | ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) | |
1108 | PESDRx_RCSSET_RSTPYN); | 1108 | PESDRx_RCSSET_RSTPYN); |
1109 | 1109 | ||
1110 | port->has_ibpre = 1; | 1110 | port->has_ibpre = 1; |
1111 | return 0; | 1111 | return 0; |
1112 | } | 1112 | } |
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | static struct ppc4xx_pciex_hwops apm821xx_pcie_hwops __initdata = { | 1115 | static struct ppc4xx_pciex_hwops apm821xx_pcie_hwops __initdata = { |
1116 | .want_sdr = true, | 1116 | .want_sdr = true, |
1117 | .core_init = apm821xx_pciex_core_init, | 1117 | .core_init = apm821xx_pciex_core_init, |
1118 | .port_init_hw = apm821xx_pciex_init_port_hw, | 1118 | .port_init_hw = apm821xx_pciex_init_port_hw, |
1119 | .setup_utl = ppc460ex_pciex_init_utl, | 1119 | .setup_utl = ppc460ex_pciex_init_utl, |
1120 | .check_link = ppc4xx_pciex_check_link_sdr, | 1120 | .check_link = ppc4xx_pciex_check_link_sdr, |
1121 | }; | 1121 | }; |
1122 | 1122 | ||
1123 | static int __init ppc460sx_pciex_core_init(struct device_node *np) | 1123 | static int __init ppc460sx_pciex_core_init(struct device_node *np) |
1124 | { | 1124 | { |
1125 | /* HSS drive amplitude */ | 1125 | /* HSS drive amplitude */ |
1126 | mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211); | 1126 | mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211); |
1127 | mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211); | 1127 | mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211); |
1128 | mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211); | 1128 | mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211); |
1129 | mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211); | 1129 | mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211); |
1130 | mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211); | 1130 | mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211); |
1131 | mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211); | 1131 | mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211); |
1132 | mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211); | 1132 | mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211); |
1133 | mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211); | 1133 | mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211); |
1134 | 1134 | ||
1135 | mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211); | 1135 | mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211); |
1136 | mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211); | 1136 | mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211); |
1137 | mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211); | 1137 | mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211); |
1138 | mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211); | 1138 | mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211); |
1139 | 1139 | ||
1140 | mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211); | 1140 | mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211); |
1141 | mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211); | 1141 | mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211); |
1142 | mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211); | 1142 | mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211); |
1143 | mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211); | 1143 | mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211); |
1144 | 1144 | ||
1145 | /* HSS TX pre-emphasis */ | 1145 | /* HSS TX pre-emphasis */ |
1146 | mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987); | 1146 | mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987); |
1147 | mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987); | 1147 | mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987); |
1148 | mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987); | 1148 | mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987); |
1149 | mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987); | 1149 | mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987); |
1150 | mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987); | 1150 | mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987); |
1151 | mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987); | 1151 | mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987); |
1152 | mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987); | 1152 | mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987); |
1153 | mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987); | 1153 | mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987); |
1154 | 1154 | ||
1155 | mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987); | 1155 | mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987); |
1156 | mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987); | 1156 | mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987); |
1157 | mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987); | 1157 | mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987); |
1158 | mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987); | 1158 | mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987); |
1159 | 1159 | ||
1160 | mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987); | 1160 | mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987); |
1161 | mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987); | 1161 | mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987); |
1162 | mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987); | 1162 | mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987); |
1163 | mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987); | 1163 | mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987); |
1164 | 1164 | ||
1165 | /* HSS TX calibration control */ | 1165 | /* HSS TX calibration control */ |
1166 | mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222); | 1166 | mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222); |
1167 | mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000); | 1167 | mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000); |
1168 | mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000); | 1168 | mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000); |
1169 | 1169 | ||
1170 | /* HSS TX slew control */ | 1170 | /* HSS TX slew control */ |
1171 | mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF); | 1171 | mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF); |
1172 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); | 1172 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); |
1173 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); | 1173 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); |
1174 | 1174 | ||
1175 | /* Set HSS PRBS enabled */ | 1175 | /* Set HSS PRBS enabled */ |
1176 | mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130); | 1176 | mtdcri(SDR0, PESDR0_460SX_HSSCTLSET, 0x00001130); |
1177 | mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130); | 1177 | mtdcri(SDR0, PESDR2_460SX_HSSCTLSET, 0x00001130); |
1178 | 1178 | ||
1179 | udelay(100); | 1179 | udelay(100); |
1180 | 1180 | ||
1181 | /* De-assert PLLRESET */ | 1181 | /* De-assert PLLRESET */ |
1182 | dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0); | 1182 | dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0); |
1183 | 1183 | ||
1184 | /* Reset DL, UTL, GPL before configuration */ | 1184 | /* Reset DL, UTL, GPL before configuration */ |
1185 | mtdcri(SDR0, PESDR0_460SX_RCSSET, | 1185 | mtdcri(SDR0, PESDR0_460SX_RCSSET, |
1186 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | 1186 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); |
1187 | mtdcri(SDR0, PESDR1_460SX_RCSSET, | 1187 | mtdcri(SDR0, PESDR1_460SX_RCSSET, |
1188 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | 1188 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); |
1189 | mtdcri(SDR0, PESDR2_460SX_RCSSET, | 1189 | mtdcri(SDR0, PESDR2_460SX_RCSSET, |
1190 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | 1190 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); |
1191 | 1191 | ||
1192 | udelay(100); | 1192 | udelay(100); |
1193 | 1193 | ||
1194 | /* | 1194 | /* |
1195 | * If bifurcation is not enabled, u-boot would have disabled the | 1195 | * If bifurcation is not enabled, u-boot would have disabled the |
1196 | * third PCIe port | 1196 | * third PCIe port |
1197 | */ | 1197 | */ |
1198 | if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) == | 1198 | if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) == |
1199 | 0x00000001)) { | 1199 | 0x00000001)) { |
1200 | printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n"); | 1200 | printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n"); |
1201 | printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n"); | 1201 | printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n"); |
1202 | return 3; | 1202 | return 3; |
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n"); | 1205 | printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n"); |
1206 | return 2; | 1206 | return 2; |
1207 | } | 1207 | } |
1208 | 1208 | ||
1209 | static int __init ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1209 | static int __init ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1210 | { | 1210 | { |
1211 | 1211 | ||
1212 | if (port->endpoint) | 1212 | if (port->endpoint) |
1213 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | 1213 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, |
1214 | 0x01000000, 0); | 1214 | 0x01000000, 0); |
1215 | else | 1215 | else |
1216 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | 1216 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, |
1217 | 0, 0x01000000); | 1217 | 0, 0x01000000); |
1218 | 1218 | ||
1219 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, | 1219 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, |
1220 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), | 1220 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), |
1221 | PESDRx_RCSSET_RSTPYN); | 1221 | PESDRx_RCSSET_RSTPYN); |
1222 | 1222 | ||
1223 | port->has_ibpre = 1; | 1223 | port->has_ibpre = 1; |
1224 | 1224 | ||
1225 | return ppc4xx_pciex_port_reset_sdr(port); | 1225 | return ppc4xx_pciex_port_reset_sdr(port); |
1226 | } | 1226 | } |
1227 | 1227 | ||
1228 | static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) | 1228 | static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) |
1229 | { | 1229 | { |
1230 | /* Max 128 Bytes */ | 1230 | /* Max 128 Bytes */ |
1231 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); | 1231 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); |
1232 | /* Assert VRB and TXE - per datasheet turn off addr validation */ | 1232 | /* Assert VRB and TXE - per datasheet turn off addr validation */ |
1233 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800000); | 1233 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800000); |
1234 | return 0; | 1234 | return 0; |
1235 | } | 1235 | } |
1236 | 1236 | ||
1237 | static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port) | 1237 | static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port) |
1238 | { | 1238 | { |
1239 | void __iomem *mbase; | 1239 | void __iomem *mbase; |
1240 | int attempt = 50; | 1240 | int attempt = 50; |
1241 | 1241 | ||
1242 | port->link = 0; | 1242 | port->link = 0; |
1243 | 1243 | ||
1244 | mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); | 1244 | mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); |
1245 | if (mbase == NULL) { | 1245 | if (mbase == NULL) { |
1246 | printk(KERN_ERR "%s: Can't map internal config space !", | 1246 | printk(KERN_ERR "%s: Can't map internal config space !", |
1247 | port->node->full_name); | 1247 | port->node->full_name); |
1248 | goto done; | 1248 | goto done; |
1249 | } | 1249 | } |
1250 | 1250 | ||
1251 | while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA) | 1251 | while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA) |
1252 | & PECFG_460SX_DLLSTA_LINKUP))) { | 1252 | & PECFG_460SX_DLLSTA_LINKUP))) { |
1253 | attempt--; | 1253 | attempt--; |
1254 | mdelay(10); | 1254 | mdelay(10); |
1255 | } | 1255 | } |
1256 | if (attempt) | 1256 | if (attempt) |
1257 | port->link = 1; | 1257 | port->link = 1; |
1258 | done: | 1258 | done: |
1259 | iounmap(mbase); | 1259 | iounmap(mbase); |
1260 | 1260 | ||
1261 | } | 1261 | } |
1262 | 1262 | ||
1263 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { | 1263 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { |
1264 | .want_sdr = true, | 1264 | .want_sdr = true, |
1265 | .core_init = ppc460sx_pciex_core_init, | 1265 | .core_init = ppc460sx_pciex_core_init, |
1266 | .port_init_hw = ppc460sx_pciex_init_port_hw, | 1266 | .port_init_hw = ppc460sx_pciex_init_port_hw, |
1267 | .setup_utl = ppc460sx_pciex_init_utl, | 1267 | .setup_utl = ppc460sx_pciex_init_utl, |
1268 | .check_link = ppc460sx_pciex_check_link, | 1268 | .check_link = ppc460sx_pciex_check_link, |
1269 | }; | 1269 | }; |
1270 | 1270 | ||
1271 | #endif /* CONFIG_44x */ | 1271 | #endif /* CONFIG_44x */ |
1272 | 1272 | ||
1273 | #ifdef CONFIG_40x | 1273 | #ifdef CONFIG_40x |
1274 | 1274 | ||
1275 | static int __init ppc405ex_pciex_core_init(struct device_node *np) | 1275 | static int __init ppc405ex_pciex_core_init(struct device_node *np) |
1276 | { | 1276 | { |
1277 | /* Nothing to do, return 2 ports */ | 1277 | /* Nothing to do, return 2 ports */ |
1278 | return 2; | 1278 | return 2; |
1279 | } | 1279 | } |
1280 | 1280 | ||
1281 | static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port) | 1281 | static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port) |
1282 | { | 1282 | { |
1283 | /* Assert the PE0_PHY reset */ | 1283 | /* Assert the PE0_PHY reset */ |
1284 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01010000); | 1284 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01010000); |
1285 | msleep(1); | 1285 | msleep(1); |
1286 | 1286 | ||
1287 | /* deassert the PE0_hotreset */ | 1287 | /* deassert the PE0_hotreset */ |
1288 | if (port->endpoint) | 1288 | if (port->endpoint) |
1289 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01111000); | 1289 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01111000); |
1290 | else | 1290 | else |
1291 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01101000); | 1291 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01101000); |
1292 | 1292 | ||
1293 | /* poll for phy !reset */ | 1293 | /* poll for phy !reset */ |
1294 | /* XXX FIXME add timeout */ | 1294 | /* XXX FIXME add timeout */ |
1295 | while (!(mfdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSTA) & 0x00001000)) | 1295 | while (!(mfdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSTA) & 0x00001000)) |
1296 | ; | 1296 | ; |
1297 | 1297 | ||
1298 | /* deassert the PE0_gpl_utl_reset */ | 1298 | /* deassert the PE0_gpl_utl_reset */ |
1299 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); | 1299 | mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | 1302 | static int __init ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) |
1303 | { | 1303 | { |
1304 | u32 val; | 1304 | u32 val; |
1305 | 1305 | ||
1306 | if (port->endpoint) | 1306 | if (port->endpoint) |
1307 | val = PTYPE_LEGACY_ENDPOINT; | 1307 | val = PTYPE_LEGACY_ENDPOINT; |
1308 | else | 1308 | else |
1309 | val = PTYPE_ROOT_PORT; | 1309 | val = PTYPE_ROOT_PORT; |
1310 | 1310 | ||
1311 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, | 1311 | mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, |
1312 | 1 << 24 | val << 20 | LNKW_X1 << 12); | 1312 | 1 << 24 | val << 20 | LNKW_X1 << 12); |
1313 | 1313 | ||
1314 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000); | 1314 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000); |
1315 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000); | 1315 | mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000); |
1316 | mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET1, 0x720F0000); | 1316 | mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET1, 0x720F0000); |
1317 | mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET2, 0x70600003); | 1317 | mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET2, 0x70600003); |
1318 | 1318 | ||
1319 | /* | 1319 | /* |
1320 | * Only reset the PHY when no link is currently established. | 1320 | * Only reset the PHY when no link is currently established. |
1321 | * This is for the Atheros PCIe board which has problems to establish | 1321 | * This is for the Atheros PCIe board which has problems to establish |
1322 | * the link (again) after this PHY reset. All other currently tested | 1322 | * the link (again) after this PHY reset. All other currently tested |
1323 | * PCIe boards don't show this problem. | 1323 | * PCIe boards don't show this problem. |
1324 | * This has to be re-tested and fixed in a later release! | 1324 | * This has to be re-tested and fixed in a later release! |
1325 | */ | 1325 | */ |
1326 | val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP); | 1326 | val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP); |
1327 | if (!(val & 0x00001000)) | 1327 | if (!(val & 0x00001000)) |
1328 | ppc405ex_pcie_phy_reset(port); | 1328 | ppc405ex_pcie_phy_reset(port); |
1329 | 1329 | ||
1330 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, 0x10000000); /* guarded on */ | 1330 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, 0x10000000); /* guarded on */ |
1331 | 1331 | ||
1332 | port->has_ibpre = 1; | 1332 | port->has_ibpre = 1; |
1333 | 1333 | ||
1334 | return ppc4xx_pciex_port_reset_sdr(port); | 1334 | return ppc4xx_pciex_port_reset_sdr(port); |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port) | 1337 | static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port) |
1338 | { | 1338 | { |
1339 | dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0); | 1339 | dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0); |
1340 | 1340 | ||
1341 | /* | 1341 | /* |
1342 | * Set buffer allocations and then assert VRB and TXE. | 1342 | * Set buffer allocations and then assert VRB and TXE. |
1343 | */ | 1343 | */ |
1344 | out_be32(port->utl_base + PEUTL_OUTTR, 0x02000000); | 1344 | out_be32(port->utl_base + PEUTL_OUTTR, 0x02000000); |
1345 | out_be32(port->utl_base + PEUTL_INTR, 0x02000000); | 1345 | out_be32(port->utl_base + PEUTL_INTR, 0x02000000); |
1346 | out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000); | 1346 | out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000); |
1347 | out_be32(port->utl_base + PEUTL_PBBSZ, 0x21000000); | 1347 | out_be32(port->utl_base + PEUTL_PBBSZ, 0x21000000); |
1348 | out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000); | 1348 | out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000); |
1349 | out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000); | 1349 | out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000); |
1350 | out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000); | 1350 | out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000); |
1351 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); | 1351 | out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); |
1352 | 1352 | ||
1353 | out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000); | 1353 | out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000); |
1354 | 1354 | ||
1355 | return 0; | 1355 | return 0; |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata = | 1358 | static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata = |
1359 | { | 1359 | { |
1360 | .want_sdr = true, | 1360 | .want_sdr = true, |
1361 | .core_init = ppc405ex_pciex_core_init, | 1361 | .core_init = ppc405ex_pciex_core_init, |
1362 | .port_init_hw = ppc405ex_pciex_init_port_hw, | 1362 | .port_init_hw = ppc405ex_pciex_init_port_hw, |
1363 | .setup_utl = ppc405ex_pciex_init_utl, | 1363 | .setup_utl = ppc405ex_pciex_init_utl, |
1364 | .check_link = ppc4xx_pciex_check_link_sdr, | 1364 | .check_link = ppc4xx_pciex_check_link_sdr, |
1365 | }; | 1365 | }; |
1366 | 1366 | ||
1367 | #endif /* CONFIG_40x */ | 1367 | #endif /* CONFIG_40x */ |
1368 | 1368 | ||
1369 | #ifdef CONFIG_476FPE | 1369 | #ifdef CONFIG_476FPE |
1370 | static int __init ppc_476fpe_pciex_core_init(struct device_node *np) | 1370 | static int __init ppc_476fpe_pciex_core_init(struct device_node *np) |
1371 | { | 1371 | { |
1372 | return 4; | 1372 | return 4; |
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port) | 1375 | static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port) |
1376 | { | 1376 | { |
1377 | u32 timeout_ms = 20; | 1377 | u32 timeout_ms = 20; |
1378 | u32 val = 0, mask = (PECFG_TLDLP_LNKUP|PECFG_TLDLP_PRESENT); | 1378 | u32 val = 0, mask = (PECFG_TLDLP_LNKUP|PECFG_TLDLP_PRESENT); |
1379 | void __iomem *mbase = ioremap(port->cfg_space.start + 0x10000000, | 1379 | void __iomem *mbase = ioremap(port->cfg_space.start + 0x10000000, |
1380 | 0x1000); | 1380 | 0x1000); |
1381 | 1381 | ||
1382 | printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); | 1382 | printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); |
1383 | 1383 | ||
1384 | if (mbase == NULL) { | 1384 | if (mbase == NULL) { |
1385 | printk(KERN_WARNING "PCIE%d: failed to get cfg space\n", | 1385 | printk(KERN_WARNING "PCIE%d: failed to get cfg space\n", |
1386 | port->index); | 1386 | port->index); |
1387 | return; | 1387 | return; |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | while (timeout_ms--) { | 1390 | while (timeout_ms--) { |
1391 | val = in_le32(mbase + PECFG_TLDLP); | 1391 | val = in_le32(mbase + PECFG_TLDLP); |
1392 | 1392 | ||
1393 | if ((val & mask) == mask) | 1393 | if ((val & mask) == mask) |
1394 | break; | 1394 | break; |
1395 | msleep(10); | 1395 | msleep(10); |
1396 | } | 1396 | } |
1397 | 1397 | ||
1398 | if (val & PECFG_TLDLP_PRESENT) { | 1398 | if (val & PECFG_TLDLP_PRESENT) { |
1399 | printk(KERN_INFO "PCIE%d: link is up !\n", port->index); | 1399 | printk(KERN_INFO "PCIE%d: link is up !\n", port->index); |
1400 | port->link = 1; | 1400 | port->link = 1; |
1401 | } else | 1401 | } else |
1402 | printk(KERN_WARNING "PCIE%d: Link up failed\n", port->index); | 1402 | printk(KERN_WARNING "PCIE%d: Link up failed\n", port->index); |
1403 | 1403 | ||
1404 | iounmap(mbase); | 1404 | iounmap(mbase); |
1405 | return; | 1405 | return; |
1406 | } | 1406 | } |
1407 | 1407 | ||
1408 | static struct ppc4xx_pciex_hwops ppc_476fpe_pcie_hwops __initdata = | 1408 | static struct ppc4xx_pciex_hwops ppc_476fpe_pcie_hwops __initdata = |
1409 | { | 1409 | { |
1410 | .core_init = ppc_476fpe_pciex_core_init, | 1410 | .core_init = ppc_476fpe_pciex_core_init, |
1411 | .check_link = ppc_476fpe_pciex_check_link, | 1411 | .check_link = ppc_476fpe_pciex_check_link, |
1412 | }; | 1412 | }; |
1413 | #endif /* CONFIG_476FPE */ | 1413 | #endif /* CONFIG_476FPE */ |
1414 | 1414 | ||
1415 | /* Check that the core has been initied and if not, do it */ | 1415 | /* Check that the core has been initied and if not, do it */ |
1416 | static int __init ppc4xx_pciex_check_core_init(struct device_node *np) | 1416 | static int __init ppc4xx_pciex_check_core_init(struct device_node *np) |
1417 | { | 1417 | { |
1418 | static int core_init; | 1418 | static int core_init; |
1419 | int count = -ENODEV; | 1419 | int count = -ENODEV; |
1420 | 1420 | ||
1421 | if (core_init++) | 1421 | if (core_init++) |
1422 | return 0; | 1422 | return 0; |
1423 | 1423 | ||
1424 | #ifdef CONFIG_44x | 1424 | #ifdef CONFIG_44x |
1425 | if (of_device_is_compatible(np, "ibm,plb-pciex-440spe")) { | 1425 | if (of_device_is_compatible(np, "ibm,plb-pciex-440spe")) { |
1426 | if (ppc440spe_revA()) | 1426 | if (ppc440spe_revA()) |
1427 | ppc4xx_pciex_hwops = &ppc440speA_pcie_hwops; | 1427 | ppc4xx_pciex_hwops = &ppc440speA_pcie_hwops; |
1428 | else | 1428 | else |
1429 | ppc4xx_pciex_hwops = &ppc440speB_pcie_hwops; | 1429 | ppc4xx_pciex_hwops = &ppc440speB_pcie_hwops; |
1430 | } | 1430 | } |
1431 | if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) | 1431 | if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) |
1432 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; | 1432 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; |
1433 | if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) | 1433 | if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) |
1434 | ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; | 1434 | ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; |
1435 | if (of_device_is_compatible(np, "ibm,plb-pciex-apm821xx")) | 1435 | if (of_device_is_compatible(np, "ibm,plb-pciex-apm821xx")) |
1436 | ppc4xx_pciex_hwops = &apm821xx_pcie_hwops; | 1436 | ppc4xx_pciex_hwops = &apm821xx_pcie_hwops; |
1437 | #endif /* CONFIG_44x */ | 1437 | #endif /* CONFIG_44x */ |
1438 | #ifdef CONFIG_40x | 1438 | #ifdef CONFIG_40x |
1439 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) | 1439 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) |
1440 | ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops; | 1440 | ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops; |
1441 | #endif | 1441 | #endif |
1442 | #ifdef CONFIG_476FPE | 1442 | #ifdef CONFIG_476FPE |
1443 | if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe")) | 1443 | if (of_device_is_compatible(np, "ibm,plb-pciex-476fpe") |
1444 | || of_device_is_compatible(np, "ibm,plb-pciex-476gtr")) | ||
1444 | ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops; | 1445 | ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops; |
1445 | #endif | 1446 | #endif |
1446 | if (ppc4xx_pciex_hwops == NULL) { | 1447 | if (ppc4xx_pciex_hwops == NULL) { |
1447 | printk(KERN_WARNING "PCIE: unknown host type %s\n", | 1448 | printk(KERN_WARNING "PCIE: unknown host type %s\n", |
1448 | np->full_name); | 1449 | np->full_name); |
1449 | return -ENODEV; | 1450 | return -ENODEV; |
1450 | } | 1451 | } |
1451 | 1452 | ||
1452 | count = ppc4xx_pciex_hwops->core_init(np); | 1453 | count = ppc4xx_pciex_hwops->core_init(np); |
1453 | if (count > 0) { | 1454 | if (count > 0) { |
1454 | ppc4xx_pciex_ports = | 1455 | ppc4xx_pciex_ports = |
1455 | kzalloc(count * sizeof(struct ppc4xx_pciex_port), | 1456 | kzalloc(count * sizeof(struct ppc4xx_pciex_port), |
1456 | GFP_KERNEL); | 1457 | GFP_KERNEL); |
1457 | if (ppc4xx_pciex_ports) { | 1458 | if (ppc4xx_pciex_ports) { |
1458 | ppc4xx_pciex_port_count = count; | 1459 | ppc4xx_pciex_port_count = count; |
1459 | return 0; | 1460 | return 0; |
1460 | } | 1461 | } |
1461 | printk(KERN_WARNING "PCIE: failed to allocate ports array\n"); | 1462 | printk(KERN_WARNING "PCIE: failed to allocate ports array\n"); |
1462 | return -ENOMEM; | 1463 | return -ENOMEM; |
1463 | } | 1464 | } |
1464 | return -ENODEV; | 1465 | return -ENODEV; |
1465 | } | 1466 | } |
1466 | 1467 | ||
1467 | static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port) | 1468 | static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port) |
1468 | { | 1469 | { |
1469 | /* We map PCI Express configuration based on the reg property */ | 1470 | /* We map PCI Express configuration based on the reg property */ |
1470 | dcr_write(port->dcrs, DCRO_PEGPL_CFGBAH, | 1471 | dcr_write(port->dcrs, DCRO_PEGPL_CFGBAH, |
1471 | RES_TO_U32_HIGH(port->cfg_space.start)); | 1472 | RES_TO_U32_HIGH(port->cfg_space.start)); |
1472 | dcr_write(port->dcrs, DCRO_PEGPL_CFGBAL, | 1473 | dcr_write(port->dcrs, DCRO_PEGPL_CFGBAL, |
1473 | RES_TO_U32_LOW(port->cfg_space.start)); | 1474 | RES_TO_U32_LOW(port->cfg_space.start)); |
1474 | 1475 | ||
1475 | /* XXX FIXME: Use size from reg property. For now, map 512M */ | 1476 | /* XXX FIXME: Use size from reg property. For now, map 512M */ |
1476 | dcr_write(port->dcrs, DCRO_PEGPL_CFGMSK, 0xe0000001); | 1477 | dcr_write(port->dcrs, DCRO_PEGPL_CFGMSK, 0xe0000001); |
1477 | 1478 | ||
1478 | /* We map UTL registers based on the reg property */ | 1479 | /* We map UTL registers based on the reg property */ |
1479 | dcr_write(port->dcrs, DCRO_PEGPL_REGBAH, | 1480 | dcr_write(port->dcrs, DCRO_PEGPL_REGBAH, |
1480 | RES_TO_U32_HIGH(port->utl_regs.start)); | 1481 | RES_TO_U32_HIGH(port->utl_regs.start)); |
1481 | dcr_write(port->dcrs, DCRO_PEGPL_REGBAL, | 1482 | dcr_write(port->dcrs, DCRO_PEGPL_REGBAL, |
1482 | RES_TO_U32_LOW(port->utl_regs.start)); | 1483 | RES_TO_U32_LOW(port->utl_regs.start)); |
1483 | 1484 | ||
1484 | /* XXX FIXME: Use size from reg property */ | 1485 | /* XXX FIXME: Use size from reg property */ |
1485 | dcr_write(port->dcrs, DCRO_PEGPL_REGMSK, 0x00007001); | 1486 | dcr_write(port->dcrs, DCRO_PEGPL_REGMSK, 0x00007001); |
1486 | 1487 | ||
1487 | /* Disable all other outbound windows */ | 1488 | /* Disable all other outbound windows */ |
1488 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, 0); | 1489 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, 0); |
1489 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, 0); | 1490 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, 0); |
1490 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0); | 1491 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0); |
1491 | dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0); | 1492 | dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0); |
1492 | } | 1493 | } |
1493 | 1494 | ||
1494 | static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) | 1495 | static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) |
1495 | { | 1496 | { |
1496 | int rc = 0; | 1497 | int rc = 0; |
1497 | 1498 | ||
1498 | /* Init HW */ | 1499 | /* Init HW */ |
1499 | if (ppc4xx_pciex_hwops->port_init_hw) | 1500 | if (ppc4xx_pciex_hwops->port_init_hw) |
1500 | rc = ppc4xx_pciex_hwops->port_init_hw(port); | 1501 | rc = ppc4xx_pciex_hwops->port_init_hw(port); |
1501 | if (rc != 0) | 1502 | if (rc != 0) |
1502 | return rc; | 1503 | return rc; |
1503 | 1504 | ||
1504 | /* | 1505 | /* |
1505 | * Initialize mapping: disable all regions and configure | 1506 | * Initialize mapping: disable all regions and configure |
1506 | * CFG and REG regions based on resources in the device tree | 1507 | * CFG and REG regions based on resources in the device tree |
1507 | */ | 1508 | */ |
1508 | ppc4xx_pciex_port_init_mapping(port); | 1509 | ppc4xx_pciex_port_init_mapping(port); |
1509 | 1510 | ||
1510 | if (ppc4xx_pciex_hwops->check_link) | 1511 | if (ppc4xx_pciex_hwops->check_link) |
1511 | ppc4xx_pciex_hwops->check_link(port); | 1512 | ppc4xx_pciex_hwops->check_link(port); |
1512 | 1513 | ||
1513 | /* | 1514 | /* |
1514 | * Map UTL | 1515 | * Map UTL |
1515 | */ | 1516 | */ |
1516 | port->utl_base = ioremap(port->utl_regs.start, 0x100); | 1517 | port->utl_base = ioremap(port->utl_regs.start, 0x100); |
1517 | BUG_ON(port->utl_base == NULL); | 1518 | BUG_ON(port->utl_base == NULL); |
1518 | 1519 | ||
1519 | /* | 1520 | /* |
1520 | * Setup UTL registers --BenH. | 1521 | * Setup UTL registers --BenH. |
1521 | */ | 1522 | */ |
1522 | if (ppc4xx_pciex_hwops->setup_utl) | 1523 | if (ppc4xx_pciex_hwops->setup_utl) |
1523 | ppc4xx_pciex_hwops->setup_utl(port); | 1524 | ppc4xx_pciex_hwops->setup_utl(port); |
1524 | 1525 | ||
1525 | /* | 1526 | /* |
1526 | * Check for VC0 active or PLL Locked and assert RDY. | 1527 | * Check for VC0 active or PLL Locked and assert RDY. |
1527 | */ | 1528 | */ |
1528 | if (port->sdr_base) { | 1529 | if (port->sdr_base) { |
1529 | if (of_device_is_compatible(port->node, | 1530 | if (of_device_is_compatible(port->node, |
1530 | "ibm,plb-pciex-460sx")){ | 1531 | "ibm,plb-pciex-460sx")){ |
1531 | if (port->link && ppc4xx_pciex_wait_on_sdr(port, | 1532 | if (port->link && ppc4xx_pciex_wait_on_sdr(port, |
1532 | PESDRn_RCSSTS, | 1533 | PESDRn_RCSSTS, |
1533 | 1 << 12, 1 << 12, 5000)) { | 1534 | 1 << 12, 1 << 12, 5000)) { |
1534 | printk(KERN_INFO "PCIE%d: PLL not locked\n", | 1535 | printk(KERN_INFO "PCIE%d: PLL not locked\n", |
1535 | port->index); | 1536 | port->index); |
1536 | port->link = 0; | 1537 | port->link = 0; |
1537 | } | 1538 | } |
1538 | } else if (port->link && | 1539 | } else if (port->link && |
1539 | ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, | 1540 | ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, |
1540 | 1 << 16, 1 << 16, 5000)) { | 1541 | 1 << 16, 1 << 16, 5000)) { |
1541 | printk(KERN_INFO "PCIE%d: VC0 not active\n", | 1542 | printk(KERN_INFO "PCIE%d: VC0 not active\n", |
1542 | port->index); | 1543 | port->index); |
1543 | port->link = 0; | 1544 | port->link = 0; |
1544 | } | 1545 | } |
1545 | 1546 | ||
1546 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20); | 1547 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20); |
1547 | } | 1548 | } |
1548 | 1549 | ||
1549 | msleep(100); | 1550 | msleep(100); |
1550 | 1551 | ||
1551 | return 0; | 1552 | return 0; |
1552 | } | 1553 | } |
1553 | 1554 | ||
1554 | static int ppc4xx_pciex_validate_bdf(struct ppc4xx_pciex_port *port, | 1555 | static int ppc4xx_pciex_validate_bdf(struct ppc4xx_pciex_port *port, |
1555 | struct pci_bus *bus, | 1556 | struct pci_bus *bus, |
1556 | unsigned int devfn) | 1557 | unsigned int devfn) |
1557 | { | 1558 | { |
1558 | static int message; | 1559 | static int message; |
1559 | 1560 | ||
1560 | /* Endpoint can not generate upstream(remote) config cycles */ | 1561 | /* Endpoint can not generate upstream(remote) config cycles */ |
1561 | if (port->endpoint && bus->number != port->hose->first_busno) | 1562 | if (port->endpoint && bus->number != port->hose->first_busno) |
1562 | return PCIBIOS_DEVICE_NOT_FOUND; | 1563 | return PCIBIOS_DEVICE_NOT_FOUND; |
1563 | 1564 | ||
1564 | /* Check we are within the mapped range */ | 1565 | /* Check we are within the mapped range */ |
1565 | if (bus->number > port->hose->last_busno) { | 1566 | if (bus->number > port->hose->last_busno) { |
1566 | if (!message) { | 1567 | if (!message) { |
1567 | printk(KERN_WARNING "Warning! Probing bus %u" | 1568 | printk(KERN_WARNING "Warning! Probing bus %u" |
1568 | " out of range !\n", bus->number); | 1569 | " out of range !\n", bus->number); |
1569 | message++; | 1570 | message++; |
1570 | } | 1571 | } |
1571 | return PCIBIOS_DEVICE_NOT_FOUND; | 1572 | return PCIBIOS_DEVICE_NOT_FOUND; |
1572 | } | 1573 | } |
1573 | 1574 | ||
1574 | /* The root complex has only one device / function */ | 1575 | /* The root complex has only one device / function */ |
1575 | if (bus->number == port->hose->first_busno && devfn != 0) | 1576 | if (bus->number == port->hose->first_busno && devfn != 0) |
1576 | return PCIBIOS_DEVICE_NOT_FOUND; | 1577 | return PCIBIOS_DEVICE_NOT_FOUND; |
1577 | 1578 | ||
1578 | /* The other side of the RC has only one device as well */ | 1579 | /* The other side of the RC has only one device as well */ |
1579 | if (bus->number == (port->hose->first_busno + 1) && | 1580 | if (bus->number == (port->hose->first_busno + 1) && |
1580 | PCI_SLOT(devfn) != 0) | 1581 | PCI_SLOT(devfn) != 0) |
1581 | return PCIBIOS_DEVICE_NOT_FOUND; | 1582 | return PCIBIOS_DEVICE_NOT_FOUND; |
1582 | 1583 | ||
1583 | /* Check if we have a link */ | 1584 | /* Check if we have a link */ |
1584 | if ((bus->number != port->hose->first_busno) && !port->link) | 1585 | if ((bus->number != port->hose->first_busno) && !port->link) |
1585 | return PCIBIOS_DEVICE_NOT_FOUND; | 1586 | return PCIBIOS_DEVICE_NOT_FOUND; |
1586 | 1587 | ||
1587 | return 0; | 1588 | return 0; |
1588 | } | 1589 | } |
1589 | 1590 | ||
1590 | static void __iomem *ppc4xx_pciex_get_config_base(struct ppc4xx_pciex_port *port, | 1591 | static void __iomem *ppc4xx_pciex_get_config_base(struct ppc4xx_pciex_port *port, |
1591 | struct pci_bus *bus, | 1592 | struct pci_bus *bus, |
1592 | unsigned int devfn) | 1593 | unsigned int devfn) |
1593 | { | 1594 | { |
1594 | int relbus; | 1595 | int relbus; |
1595 | 1596 | ||
1596 | /* Remove the casts when we finally remove the stupid volatile | 1597 | /* Remove the casts when we finally remove the stupid volatile |
1597 | * in struct pci_controller | 1598 | * in struct pci_controller |
1598 | */ | 1599 | */ |
1599 | if (bus->number == port->hose->first_busno) | 1600 | if (bus->number == port->hose->first_busno) |
1600 | return (void __iomem *)port->hose->cfg_addr; | 1601 | return (void __iomem *)port->hose->cfg_addr; |
1601 | 1602 | ||
1602 | relbus = bus->number - (port->hose->first_busno + 1); | 1603 | relbus = bus->number - (port->hose->first_busno + 1); |
1603 | return (void __iomem *)port->hose->cfg_data + | 1604 | return (void __iomem *)port->hose->cfg_data + |
1604 | ((relbus << 20) | (devfn << 12)); | 1605 | ((relbus << 20) | (devfn << 12)); |
1605 | } | 1606 | } |
1606 | 1607 | ||
1607 | static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn, | 1608 | static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn, |
1608 | int offset, int len, u32 *val) | 1609 | int offset, int len, u32 *val) |
1609 | { | 1610 | { |
1610 | struct pci_controller *hose = pci_bus_to_host(bus); | 1611 | struct pci_controller *hose = pci_bus_to_host(bus); |
1611 | struct ppc4xx_pciex_port *port = | 1612 | struct ppc4xx_pciex_port *port = |
1612 | &ppc4xx_pciex_ports[hose->indirect_type]; | 1613 | &ppc4xx_pciex_ports[hose->indirect_type]; |
1613 | void __iomem *addr; | 1614 | void __iomem *addr; |
1614 | u32 gpl_cfg; | 1615 | u32 gpl_cfg; |
1615 | 1616 | ||
1616 | BUG_ON(hose != port->hose); | 1617 | BUG_ON(hose != port->hose); |
1617 | 1618 | ||
1618 | if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) | 1619 | if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) |
1619 | return PCIBIOS_DEVICE_NOT_FOUND; | 1620 | return PCIBIOS_DEVICE_NOT_FOUND; |
1620 | 1621 | ||
1621 | addr = ppc4xx_pciex_get_config_base(port, bus, devfn); | 1622 | addr = ppc4xx_pciex_get_config_base(port, bus, devfn); |
1622 | 1623 | ||
1623 | /* | 1624 | /* |
1624 | * Reading from configuration space of non-existing device can | 1625 | * Reading from configuration space of non-existing device can |
1625 | * generate transaction errors. For the read duration we suppress | 1626 | * generate transaction errors. For the read duration we suppress |
1626 | * assertion of machine check exceptions to avoid those. | 1627 | * assertion of machine check exceptions to avoid those. |
1627 | */ | 1628 | */ |
1628 | gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); | 1629 | gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); |
1629 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); | 1630 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); |
1630 | 1631 | ||
1631 | /* Make sure no CRS is recorded */ | 1632 | /* Make sure no CRS is recorded */ |
1632 | out_be32(port->utl_base + PEUTL_RCSTA, 0x00040000); | 1633 | out_be32(port->utl_base + PEUTL_RCSTA, 0x00040000); |
1633 | 1634 | ||
1634 | switch (len) { | 1635 | switch (len) { |
1635 | case 1: | 1636 | case 1: |
1636 | *val = in_8((u8 *)(addr + offset)); | 1637 | *val = in_8((u8 *)(addr + offset)); |
1637 | break; | 1638 | break; |
1638 | case 2: | 1639 | case 2: |
1639 | *val = in_le16((u16 *)(addr + offset)); | 1640 | *val = in_le16((u16 *)(addr + offset)); |
1640 | break; | 1641 | break; |
1641 | default: | 1642 | default: |
1642 | *val = in_le32((u32 *)(addr + offset)); | 1643 | *val = in_le32((u32 *)(addr + offset)); |
1643 | break; | 1644 | break; |
1644 | } | 1645 | } |
1645 | 1646 | ||
1646 | pr_debug("pcie-config-read: bus=%3d [%3d..%3d] devfn=0x%04x" | 1647 | pr_debug("pcie-config-read: bus=%3d [%3d..%3d] devfn=0x%04x" |
1647 | " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", | 1648 | " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", |
1648 | bus->number, hose->first_busno, hose->last_busno, | 1649 | bus->number, hose->first_busno, hose->last_busno, |
1649 | devfn, offset, len, addr + offset, *val); | 1650 | devfn, offset, len, addr + offset, *val); |
1650 | 1651 | ||
1651 | /* Check for CRS (440SPe rev B does that for us but heh ..) */ | 1652 | /* Check for CRS (440SPe rev B does that for us but heh ..) */ |
1652 | if (in_be32(port->utl_base + PEUTL_RCSTA) & 0x00040000) { | 1653 | if (in_be32(port->utl_base + PEUTL_RCSTA) & 0x00040000) { |
1653 | pr_debug("Got CRS !\n"); | 1654 | pr_debug("Got CRS !\n"); |
1654 | if (len != 4 || offset != 0) | 1655 | if (len != 4 || offset != 0) |
1655 | return PCIBIOS_DEVICE_NOT_FOUND; | 1656 | return PCIBIOS_DEVICE_NOT_FOUND; |
1656 | *val = 0xffff0001; | 1657 | *val = 0xffff0001; |
1657 | } | 1658 | } |
1658 | 1659 | ||
1659 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); | 1660 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); |
1660 | 1661 | ||
1661 | return PCIBIOS_SUCCESSFUL; | 1662 | return PCIBIOS_SUCCESSFUL; |
1662 | } | 1663 | } |
1663 | 1664 | ||
1664 | static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn, | 1665 | static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn, |
1665 | int offset, int len, u32 val) | 1666 | int offset, int len, u32 val) |
1666 | { | 1667 | { |
1667 | struct pci_controller *hose = pci_bus_to_host(bus); | 1668 | struct pci_controller *hose = pci_bus_to_host(bus); |
1668 | struct ppc4xx_pciex_port *port = | 1669 | struct ppc4xx_pciex_port *port = |
1669 | &ppc4xx_pciex_ports[hose->indirect_type]; | 1670 | &ppc4xx_pciex_ports[hose->indirect_type]; |
1670 | void __iomem *addr; | 1671 | void __iomem *addr; |
1671 | u32 gpl_cfg; | 1672 | u32 gpl_cfg; |
1672 | 1673 | ||
1673 | if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) | 1674 | if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) |
1674 | return PCIBIOS_DEVICE_NOT_FOUND; | 1675 | return PCIBIOS_DEVICE_NOT_FOUND; |
1675 | 1676 | ||
1676 | addr = ppc4xx_pciex_get_config_base(port, bus, devfn); | 1677 | addr = ppc4xx_pciex_get_config_base(port, bus, devfn); |
1677 | 1678 | ||
1678 | /* | 1679 | /* |
1679 | * Reading from configuration space of non-existing device can | 1680 | * Reading from configuration space of non-existing device can |
1680 | * generate transaction errors. For the read duration we suppress | 1681 | * generate transaction errors. For the read duration we suppress |
1681 | * assertion of machine check exceptions to avoid those. | 1682 | * assertion of machine check exceptions to avoid those. |
1682 | */ | 1683 | */ |
1683 | gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); | 1684 | gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); |
1684 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); | 1685 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); |
1685 | 1686 | ||
1686 | pr_debug("pcie-config-write: bus=%3d [%3d..%3d] devfn=0x%04x" | 1687 | pr_debug("pcie-config-write: bus=%3d [%3d..%3d] devfn=0x%04x" |
1687 | " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", | 1688 | " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", |
1688 | bus->number, hose->first_busno, hose->last_busno, | 1689 | bus->number, hose->first_busno, hose->last_busno, |
1689 | devfn, offset, len, addr + offset, val); | 1690 | devfn, offset, len, addr + offset, val); |
1690 | 1691 | ||
1691 | switch (len) { | 1692 | switch (len) { |
1692 | case 1: | 1693 | case 1: |
1693 | out_8((u8 *)(addr + offset), val); | 1694 | out_8((u8 *)(addr + offset), val); |
1694 | break; | 1695 | break; |
1695 | case 2: | 1696 | case 2: |
1696 | out_le16((u16 *)(addr + offset), val); | 1697 | out_le16((u16 *)(addr + offset), val); |
1697 | break; | 1698 | break; |
1698 | default: | 1699 | default: |
1699 | out_le32((u32 *)(addr + offset), val); | 1700 | out_le32((u32 *)(addr + offset), val); |
1700 | break; | 1701 | break; |
1701 | } | 1702 | } |
1702 | 1703 | ||
1703 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); | 1704 | dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); |
1704 | 1705 | ||
1705 | return PCIBIOS_SUCCESSFUL; | 1706 | return PCIBIOS_SUCCESSFUL; |
1706 | } | 1707 | } |
1707 | 1708 | ||
1708 | static struct pci_ops ppc4xx_pciex_pci_ops = | 1709 | static struct pci_ops ppc4xx_pciex_pci_ops = |
1709 | { | 1710 | { |
1710 | .read = ppc4xx_pciex_read_config, | 1711 | .read = ppc4xx_pciex_read_config, |
1711 | .write = ppc4xx_pciex_write_config, | 1712 | .write = ppc4xx_pciex_write_config, |
1712 | }; | 1713 | }; |
1713 | 1714 | ||
1714 | static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, | 1715 | static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, |
1715 | struct pci_controller *hose, | 1716 | struct pci_controller *hose, |
1716 | void __iomem *mbase, | 1717 | void __iomem *mbase, |
1717 | u64 plb_addr, | 1718 | u64 plb_addr, |
1718 | u64 pci_addr, | 1719 | u64 pci_addr, |
1719 | u64 size, | 1720 | u64 size, |
1720 | unsigned int flags, | 1721 | unsigned int flags, |
1721 | int index) | 1722 | int index) |
1722 | { | 1723 | { |
1723 | u32 lah, lal, pciah, pcial, sa; | 1724 | u32 lah, lal, pciah, pcial, sa; |
1724 | 1725 | ||
1725 | if (!is_power_of_2(size) || | 1726 | if (!is_power_of_2(size) || |
1726 | (index < 2 && size < 0x100000) || | 1727 | (index < 2 && size < 0x100000) || |
1727 | (index == 2 && size < 0x100) || | 1728 | (index == 2 && size < 0x100) || |
1728 | (plb_addr & (size - 1)) != 0) { | 1729 | (plb_addr & (size - 1)) != 0) { |
1729 | printk(KERN_WARNING "%s: Resource out of range\n", | 1730 | printk(KERN_WARNING "%s: Resource out of range\n", |
1730 | hose->dn->full_name); | 1731 | hose->dn->full_name); |
1731 | return -1; | 1732 | return -1; |
1732 | } | 1733 | } |
1733 | 1734 | ||
1734 | /* Calculate register values */ | 1735 | /* Calculate register values */ |
1735 | lah = RES_TO_U32_HIGH(plb_addr); | 1736 | lah = RES_TO_U32_HIGH(plb_addr); |
1736 | lal = RES_TO_U32_LOW(plb_addr); | 1737 | lal = RES_TO_U32_LOW(plb_addr); |
1737 | pciah = RES_TO_U32_HIGH(pci_addr); | 1738 | pciah = RES_TO_U32_HIGH(pci_addr); |
1738 | pcial = RES_TO_U32_LOW(pci_addr); | 1739 | pcial = RES_TO_U32_LOW(pci_addr); |
1739 | sa = (0xffffffffu << ilog2(size)) | 0x1; | 1740 | sa = (0xffffffffu << ilog2(size)) | 0x1; |
1740 | 1741 | ||
1741 | /* Program register values */ | 1742 | /* Program register values */ |
1742 | switch (index) { | 1743 | switch (index) { |
1743 | case 0: | 1744 | case 0: |
1744 | out_le32(mbase + PECFG_POM0LAH, pciah); | 1745 | out_le32(mbase + PECFG_POM0LAH, pciah); |
1745 | out_le32(mbase + PECFG_POM0LAL, pcial); | 1746 | out_le32(mbase + PECFG_POM0LAL, pcial); |
1746 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); | 1747 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); |
1747 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); | 1748 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); |
1748 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); | 1749 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); |
1749 | /*Enabled and single region */ | 1750 | /*Enabled and single region */ |
1750 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) | 1751 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) |
1751 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | 1752 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, |
1752 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT | 1753 | sa | DCRO_PEGPL_460SX_OMR1MSKL_UOT |
1753 | | DCRO_PEGPL_OMRxMSKL_VAL); | 1754 | | DCRO_PEGPL_OMRxMSKL_VAL); |
1754 | else if (of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe")) | 1755 | else if (of_device_is_compatible( |
1756 | port->node, "ibm,plb-pciex-476fpe") || | ||
1757 | of_device_is_compatible( | ||
1758 | port->node, "ibm,plb-pciex-476gtr")) | ||
1755 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | 1759 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, |
1756 | sa | DCRO_PEGPL_476FPE_OMR1MSKL_UOT | 1760 | sa | DCRO_PEGPL_476FPE_OMR1MSKL_UOT |
1757 | | DCRO_PEGPL_OMRxMSKL_VAL); | 1761 | | DCRO_PEGPL_OMRxMSKL_VAL); |
1758 | else | 1762 | else |
1759 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, | 1763 | dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, |
1760 | sa | DCRO_PEGPL_OMR1MSKL_UOT | 1764 | sa | DCRO_PEGPL_OMR1MSKL_UOT |
1761 | | DCRO_PEGPL_OMRxMSKL_VAL); | 1765 | | DCRO_PEGPL_OMRxMSKL_VAL); |
1762 | break; | 1766 | break; |
1763 | case 1: | 1767 | case 1: |
1764 | out_le32(mbase + PECFG_POM1LAH, pciah); | 1768 | out_le32(mbase + PECFG_POM1LAH, pciah); |
1765 | out_le32(mbase + PECFG_POM1LAL, pcial); | 1769 | out_le32(mbase + PECFG_POM1LAL, pcial); |
1766 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); | 1770 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); |
1767 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); | 1771 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); |
1768 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); | 1772 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); |
1769 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, | 1773 | dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, |
1770 | sa | DCRO_PEGPL_OMRxMSKL_VAL); | 1774 | sa | DCRO_PEGPL_OMRxMSKL_VAL); |
1771 | break; | 1775 | break; |
1772 | case 2: | 1776 | case 2: |
1773 | out_le32(mbase + PECFG_POM2LAH, pciah); | 1777 | out_le32(mbase + PECFG_POM2LAH, pciah); |
1774 | out_le32(mbase + PECFG_POM2LAL, pcial); | 1778 | out_le32(mbase + PECFG_POM2LAL, pcial); |
1775 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah); | 1779 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah); |
1776 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); | 1780 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); |
1777 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); | 1781 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); |
1778 | /* Note that 3 here means enabled | IO space !!! */ | 1782 | /* Note that 3 here means enabled | IO space !!! */ |
1779 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, | 1783 | dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, |
1780 | sa | DCRO_PEGPL_OMR3MSKL_IO | 1784 | sa | DCRO_PEGPL_OMR3MSKL_IO |
1781 | | DCRO_PEGPL_OMRxMSKL_VAL); | 1785 | | DCRO_PEGPL_OMRxMSKL_VAL); |
1782 | break; | 1786 | break; |
1783 | } | 1787 | } |
1784 | 1788 | ||
1785 | return 0; | 1789 | return 0; |
1786 | } | 1790 | } |
1787 | 1791 | ||
1788 | static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, | 1792 | static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, |
1789 | struct pci_controller *hose, | 1793 | struct pci_controller *hose, |
1790 | void __iomem *mbase) | 1794 | void __iomem *mbase) |
1791 | { | 1795 | { |
1792 | int i, j, found_isa_hole = 0; | 1796 | int i, j, found_isa_hole = 0; |
1793 | 1797 | ||
1794 | /* Setup outbound memory windows */ | 1798 | /* Setup outbound memory windows */ |
1795 | for (i = j = 0; i < 3; i++) { | 1799 | for (i = j = 0; i < 3; i++) { |
1796 | struct resource *res = &hose->mem_resources[i]; | 1800 | struct resource *res = &hose->mem_resources[i]; |
1797 | resource_size_t offset = hose->mem_offset[i]; | 1801 | resource_size_t offset = hose->mem_offset[i]; |
1798 | 1802 | ||
1799 | /* we only care about memory windows */ | 1803 | /* we only care about memory windows */ |
1800 | if (!(res->flags & IORESOURCE_MEM)) | 1804 | if (!(res->flags & IORESOURCE_MEM)) |
1801 | continue; | 1805 | continue; |
1802 | if (j > 1) { | 1806 | if (j > 1) { |
1803 | printk(KERN_WARNING "%s: Too many ranges\n", | 1807 | printk(KERN_WARNING "%s: Too many ranges\n", |
1804 | port->node->full_name); | 1808 | port->node->full_name); |
1805 | break; | 1809 | break; |
1806 | } | 1810 | } |
1807 | 1811 | ||
1808 | /* Configure the resource */ | 1812 | /* Configure the resource */ |
1809 | if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, | 1813 | if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, |
1810 | res->start, | 1814 | res->start, |
1811 | res->start - offset, | 1815 | res->start - offset, |
1812 | resource_size(res), | 1816 | resource_size(res), |
1813 | res->flags, | 1817 | res->flags, |
1814 | j) == 0) { | 1818 | j) == 0) { |
1815 | j++; | 1819 | j++; |
1816 | 1820 | ||
1817 | /* If the resource PCI address is 0 then we have our | 1821 | /* If the resource PCI address is 0 then we have our |
1818 | * ISA memory hole | 1822 | * ISA memory hole |
1819 | */ | 1823 | */ |
1820 | if (res->start == offset) | 1824 | if (res->start == offset) |
1821 | found_isa_hole = 1; | 1825 | found_isa_hole = 1; |
1822 | } | 1826 | } |
1823 | } | 1827 | } |
1824 | 1828 | ||
1825 | /* Handle ISA memory hole if not already covered */ | 1829 | /* Handle ISA memory hole if not already covered */ |
1826 | if (j <= 1 && !found_isa_hole && hose->isa_mem_size) | 1830 | if (j <= 1 && !found_isa_hole && hose->isa_mem_size) |
1827 | if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, | 1831 | if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, |
1828 | hose->isa_mem_phys, 0, | 1832 | hose->isa_mem_phys, 0, |
1829 | hose->isa_mem_size, 0, j) == 0) | 1833 | hose->isa_mem_size, 0, j) == 0) |
1830 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", | 1834 | printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", |
1831 | hose->dn->full_name); | 1835 | hose->dn->full_name); |
1832 | 1836 | ||
1833 | /* Configure IO, always 64K starting at 0. We hard wire it to 64K ! | 1837 | /* Configure IO, always 64K starting at 0. We hard wire it to 64K ! |
1834 | * Note also that it -has- to be region index 2 on this HW | 1838 | * Note also that it -has- to be region index 2 on this HW |
1835 | */ | 1839 | */ |
1836 | if (hose->io_resource.flags & IORESOURCE_IO) | 1840 | if (hose->io_resource.flags & IORESOURCE_IO) |
1837 | ppc4xx_setup_one_pciex_POM(port, hose, mbase, | 1841 | ppc4xx_setup_one_pciex_POM(port, hose, mbase, |
1838 | hose->io_base_phys, 0, | 1842 | hose->io_base_phys, 0, |
1839 | 0x10000, IORESOURCE_IO, 2); | 1843 | 0x10000, IORESOURCE_IO, 2); |
1840 | } | 1844 | } |
1841 | 1845 | ||
1842 | static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, | 1846 | static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, |
1843 | struct pci_controller *hose, | 1847 | struct pci_controller *hose, |
1844 | void __iomem *mbase, | 1848 | void __iomem *mbase, |
1845 | struct resource *res) | 1849 | struct resource *res) |
1846 | { | 1850 | { |
1847 | resource_size_t size = resource_size(res); | 1851 | resource_size_t size = resource_size(res); |
1848 | u64 sa; | 1852 | u64 sa; |
1849 | 1853 | ||
1850 | if (port->endpoint) { | 1854 | if (port->endpoint) { |
1851 | resource_size_t ep_addr = 0; | 1855 | resource_size_t ep_addr = 0; |
1852 | resource_size_t ep_size = 32 << 20; | 1856 | resource_size_t ep_size = 32 << 20; |
1853 | 1857 | ||
1854 | /* Currently we map a fixed 64MByte window to PLB address | 1858 | /* Currently we map a fixed 64MByte window to PLB address |
1855 | * 0 (SDRAM). This should probably be configurable via a dts | 1859 | * 0 (SDRAM). This should probably be configurable via a dts |
1856 | * property. | 1860 | * property. |
1857 | */ | 1861 | */ |
1858 | 1862 | ||
1859 | /* Calculate window size */ | 1863 | /* Calculate window size */ |
1860 | sa = (0xffffffffffffffffull << ilog2(ep_size)); | 1864 | sa = (0xffffffffffffffffull << ilog2(ep_size)); |
1861 | 1865 | ||
1862 | /* Setup BAR0 */ | 1866 | /* Setup BAR0 */ |
1863 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); | 1867 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); |
1864 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa) | | 1868 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa) | |
1865 | PCI_BASE_ADDRESS_MEM_TYPE_64); | 1869 | PCI_BASE_ADDRESS_MEM_TYPE_64); |
1866 | 1870 | ||
1867 | /* Disable BAR1 & BAR2 */ | 1871 | /* Disable BAR1 & BAR2 */ |
1868 | out_le32(mbase + PECFG_BAR1MPA, 0); | 1872 | out_le32(mbase + PECFG_BAR1MPA, 0); |
1869 | out_le32(mbase + PECFG_BAR2HMPA, 0); | 1873 | out_le32(mbase + PECFG_BAR2HMPA, 0); |
1870 | out_le32(mbase + PECFG_BAR2LMPA, 0); | 1874 | out_le32(mbase + PECFG_BAR2LMPA, 0); |
1871 | 1875 | ||
1872 | out_le32(mbase + PECFG_PIM01SAH, RES_TO_U32_HIGH(sa)); | 1876 | out_le32(mbase + PECFG_PIM01SAH, RES_TO_U32_HIGH(sa)); |
1873 | out_le32(mbase + PECFG_PIM01SAL, RES_TO_U32_LOW(sa)); | 1877 | out_le32(mbase + PECFG_PIM01SAL, RES_TO_U32_LOW(sa)); |
1874 | 1878 | ||
1875 | out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(ep_addr)); | 1879 | out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(ep_addr)); |
1876 | out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(ep_addr)); | 1880 | out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(ep_addr)); |
1877 | } else { | 1881 | } else { |
1878 | /* Calculate window size */ | 1882 | /* Calculate window size */ |
1879 | sa = (0xffffffffffffffffull << ilog2(size)); | 1883 | sa = (0xffffffffffffffffull << ilog2(size)); |
1880 | if (res->flags & IORESOURCE_PREFETCH) | 1884 | if (res->flags & IORESOURCE_PREFETCH) |
1881 | sa |= PCI_BASE_ADDRESS_MEM_PREFETCH; | 1885 | sa |= PCI_BASE_ADDRESS_MEM_PREFETCH; |
1882 | 1886 | ||
1883 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx") || | 1887 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx") || |
1884 | of_device_is_compatible(port->node, "ibm,plb-pciex-476fpe")) | 1888 | of_device_is_compatible( |
1889 | port->node, "ibm,plb-pciex-476fpe") || | ||
1890 | of_device_is_compatible( | ||
1891 | port->node, "ibm,plb-pciex-476gtr")) | ||
1885 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; | 1892 | sa |= PCI_BASE_ADDRESS_MEM_TYPE_64; |
1886 | 1893 | ||
1887 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); | 1894 | out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); |
1888 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); | 1895 | out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); |
1889 | 1896 | ||
1890 | /* The setup of the split looks weird to me ... let's see | 1897 | /* The setup of the split looks weird to me ... let's see |
1891 | * if it works | 1898 | * if it works |
1892 | */ | 1899 | */ |
1893 | out_le32(mbase + PECFG_PIM0LAL, 0x00000000); | 1900 | out_le32(mbase + PECFG_PIM0LAL, 0x00000000); |
1894 | out_le32(mbase + PECFG_PIM0LAH, 0x00000000); | 1901 | out_le32(mbase + PECFG_PIM0LAH, 0x00000000); |
1895 | out_le32(mbase + PECFG_PIM1LAL, 0x00000000); | 1902 | out_le32(mbase + PECFG_PIM1LAL, 0x00000000); |
1896 | out_le32(mbase + PECFG_PIM1LAH, 0x00000000); | 1903 | out_le32(mbase + PECFG_PIM1LAH, 0x00000000); |
1897 | out_le32(mbase + PECFG_PIM01SAH, 0xffff0000); | 1904 | out_le32(mbase + PECFG_PIM01SAH, 0xffff0000); |
1898 | out_le32(mbase + PECFG_PIM01SAL, 0x00000000); | 1905 | out_le32(mbase + PECFG_PIM01SAL, 0x00000000); |
1899 | 1906 | ||
1900 | out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start)); | 1907 | out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start)); |
1901 | out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start)); | 1908 | out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start)); |
1902 | } | 1909 | } |
1903 | 1910 | ||
1904 | /* Enable inbound mapping */ | 1911 | /* Enable inbound mapping */ |
1905 | out_le32(mbase + PECFG_PIMEN, 0x1); | 1912 | out_le32(mbase + PECFG_PIMEN, 0x1); |
1906 | 1913 | ||
1907 | /* Enable I/O, Mem, and Busmaster cycles */ | 1914 | /* Enable I/O, Mem, and Busmaster cycles */ |
1908 | out_le16(mbase + PCI_COMMAND, | 1915 | out_le16(mbase + PCI_COMMAND, |
1909 | in_le16(mbase + PCI_COMMAND) | | 1916 | in_le16(mbase + PCI_COMMAND) | |
1910 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); | 1917 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); |
1911 | } | 1918 | } |
1912 | 1919 | ||
1913 | static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) | 1920 | static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) |
1914 | { | 1921 | { |
1915 | struct resource dma_window; | 1922 | struct resource dma_window; |
1916 | struct pci_controller *hose = NULL; | 1923 | struct pci_controller *hose = NULL; |
1917 | const int *bus_range; | 1924 | const int *bus_range; |
1918 | int primary = 0, busses; | 1925 | int primary = 0, busses; |
1919 | void __iomem *mbase = NULL, *cfg_data = NULL; | 1926 | void __iomem *mbase = NULL, *cfg_data = NULL; |
1920 | const u32 *pval; | 1927 | const u32 *pval; |
1921 | u32 val; | 1928 | u32 val; |
1922 | 1929 | ||
1923 | /* Check if primary bridge */ | 1930 | /* Check if primary bridge */ |
1924 | if (of_get_property(port->node, "primary", NULL)) | 1931 | if (of_get_property(port->node, "primary", NULL)) |
1925 | primary = 1; | 1932 | primary = 1; |
1926 | 1933 | ||
1927 | /* Get bus range if any */ | 1934 | /* Get bus range if any */ |
1928 | bus_range = of_get_property(port->node, "bus-range", NULL); | 1935 | bus_range = of_get_property(port->node, "bus-range", NULL); |
1929 | 1936 | ||
1930 | /* Allocate the host controller data structure */ | 1937 | /* Allocate the host controller data structure */ |
1931 | hose = pcibios_alloc_controller(port->node); | 1938 | hose = pcibios_alloc_controller(port->node); |
1932 | if (!hose) | 1939 | if (!hose) |
1933 | goto fail; | 1940 | goto fail; |
1934 | 1941 | ||
1935 | /* We stick the port number in "indirect_type" so the config space | 1942 | /* We stick the port number in "indirect_type" so the config space |
1936 | * ops can retrieve the port data structure easily | 1943 | * ops can retrieve the port data structure easily |
1937 | */ | 1944 | */ |
1938 | hose->indirect_type = port->index; | 1945 | hose->indirect_type = port->index; |
1939 | 1946 | ||
1940 | /* Get bus range */ | 1947 | /* Get bus range */ |
1941 | hose->first_busno = bus_range ? bus_range[0] : 0x0; | 1948 | hose->first_busno = bus_range ? bus_range[0] : 0x0; |
1942 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 1949 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
1943 | 1950 | ||
1944 | /* Because of how big mapping the config space is (1M per bus), we | 1951 | /* Because of how big mapping the config space is (1M per bus), we |
1945 | * limit how many busses we support. In the long run, we could replace | 1952 | * limit how many busses we support. In the long run, we could replace |
1946 | * that with something akin to kmap_atomic instead. We set aside 1 bus | 1953 | * that with something akin to kmap_atomic instead. We set aside 1 bus |
1947 | * for the host itself too. | 1954 | * for the host itself too. |
1948 | */ | 1955 | */ |
1949 | busses = hose->last_busno - hose->first_busno; /* This is off by 1 */ | 1956 | busses = hose->last_busno - hose->first_busno; /* This is off by 1 */ |
1950 | if (busses > MAX_PCIE_BUS_MAPPED) { | 1957 | if (busses > MAX_PCIE_BUS_MAPPED) { |
1951 | busses = MAX_PCIE_BUS_MAPPED; | 1958 | busses = MAX_PCIE_BUS_MAPPED; |
1952 | hose->last_busno = hose->first_busno + busses; | 1959 | hose->last_busno = hose->first_busno + busses; |
1953 | } | 1960 | } |
1954 | 1961 | ||
1955 | if (!port->endpoint) { | 1962 | if (!port->endpoint) { |
1956 | /* Only map the external config space in cfg_data for | 1963 | /* Only map the external config space in cfg_data for |
1957 | * PCIe root-complexes. External space is 1M per bus | 1964 | * PCIe root-complexes. External space is 1M per bus |
1958 | */ | 1965 | */ |
1959 | cfg_data = ioremap(port->cfg_space.start + | 1966 | cfg_data = ioremap(port->cfg_space.start + |
1960 | (hose->first_busno + 1) * 0x100000, | 1967 | (hose->first_busno + 1) * 0x100000, |
1961 | busses * 0x100000); | 1968 | busses * 0x100000); |
1962 | if (cfg_data == NULL) { | 1969 | if (cfg_data == NULL) { |
1963 | printk(KERN_ERR "%s: Can't map external config space !", | 1970 | printk(KERN_ERR "%s: Can't map external config space !", |
1964 | port->node->full_name); | 1971 | port->node->full_name); |
1965 | goto fail; | 1972 | goto fail; |
1966 | } | 1973 | } |
1967 | hose->cfg_data = cfg_data; | 1974 | hose->cfg_data = cfg_data; |
1968 | } | 1975 | } |
1969 | 1976 | ||
1970 | /* Always map the host config space in cfg_addr. | 1977 | /* Always map the host config space in cfg_addr. |
1971 | * Internal space is 4K | 1978 | * Internal space is 4K |
1972 | */ | 1979 | */ |
1973 | mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); | 1980 | mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); |
1974 | if (mbase == NULL) { | 1981 | if (mbase == NULL) { |
1975 | printk(KERN_ERR "%s: Can't map internal config space !", | 1982 | printk(KERN_ERR "%s: Can't map internal config space !", |
1976 | port->node->full_name); | 1983 | port->node->full_name); |
1977 | goto fail; | 1984 | goto fail; |
1978 | } | 1985 | } |
1979 | hose->cfg_addr = mbase; | 1986 | hose->cfg_addr = mbase; |
1980 | 1987 | ||
1981 | pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name, | 1988 | pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name, |
1982 | hose->first_busno, hose->last_busno); | 1989 | hose->first_busno, hose->last_busno); |
1983 | pr_debug(" config space mapped at: root @0x%p, other @0x%p\n", | 1990 | pr_debug(" config space mapped at: root @0x%p, other @0x%p\n", |
1984 | hose->cfg_addr, hose->cfg_data); | 1991 | hose->cfg_addr, hose->cfg_data); |
1985 | 1992 | ||
1986 | /* Setup config space */ | 1993 | /* Setup config space */ |
1987 | hose->ops = &ppc4xx_pciex_pci_ops; | 1994 | hose->ops = &ppc4xx_pciex_pci_ops; |
1988 | port->hose = hose; | 1995 | port->hose = hose; |
1989 | mbase = (void __iomem *)hose->cfg_addr; | 1996 | mbase = (void __iomem *)hose->cfg_addr; |
1990 | 1997 | ||
1991 | if (!port->endpoint) { | 1998 | if (!port->endpoint) { |
1992 | /* | 1999 | /* |
1993 | * Set bus numbers on our root port | 2000 | * Set bus numbers on our root port |
1994 | */ | 2001 | */ |
1995 | out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno); | 2002 | out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno); |
1996 | out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1); | 2003 | out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1); |
1997 | out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno); | 2004 | out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno); |
1998 | } | 2005 | } |
1999 | 2006 | ||
2000 | /* | 2007 | /* |
2001 | * OMRs are already reset, also disable PIMs | 2008 | * OMRs are already reset, also disable PIMs |
2002 | */ | 2009 | */ |
2003 | out_le32(mbase + PECFG_PIMEN, 0); | 2010 | out_le32(mbase + PECFG_PIMEN, 0); |
2004 | 2011 | ||
2005 | /* Parse outbound mapping resources */ | 2012 | /* Parse outbound mapping resources */ |
2006 | pci_process_bridge_OF_ranges(hose, port->node, primary); | 2013 | pci_process_bridge_OF_ranges(hose, port->node, primary); |
2007 | 2014 | ||
2008 | /* Parse inbound mapping resources */ | 2015 | /* Parse inbound mapping resources */ |
2009 | if (ppc4xx_parse_dma_ranges(hose, mbase, &dma_window) != 0) | 2016 | if (ppc4xx_parse_dma_ranges(hose, mbase, &dma_window) != 0) |
2010 | goto fail; | 2017 | goto fail; |
2011 | 2018 | ||
2012 | /* Configure outbound ranges POMs */ | 2019 | /* Configure outbound ranges POMs */ |
2013 | ppc4xx_configure_pciex_POMs(port, hose, mbase); | 2020 | ppc4xx_configure_pciex_POMs(port, hose, mbase); |
2014 | 2021 | ||
2015 | /* Configure inbound ranges PIMs */ | 2022 | /* Configure inbound ranges PIMs */ |
2016 | ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window); | 2023 | ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window); |
2017 | 2024 | ||
2018 | /* The root complex doesn't show up if we don't set some vendor | 2025 | /* The root complex doesn't show up if we don't set some vendor |
2019 | * and device IDs into it. The defaults below are the same bogus | 2026 | * and device IDs into it. The defaults below are the same bogus |
2020 | * one that the initial code in arch/ppc had. This can be | 2027 | * one that the initial code in arch/ppc had. This can be |
2021 | * overwritten by setting the "vendor-id/device-id" properties | 2028 | * overwritten by setting the "vendor-id/device-id" properties |
2022 | * in the pciex node. | 2029 | * in the pciex node. |
2023 | */ | 2030 | */ |
2024 | 2031 | ||
2025 | /* Get the (optional) vendor-/device-id from the device-tree */ | 2032 | /* Get the (optional) vendor-/device-id from the device-tree */ |
2026 | pval = of_get_property(port->node, "vendor-id", NULL); | 2033 | pval = of_get_property(port->node, "vendor-id", NULL); |
2027 | if (pval) { | 2034 | if (pval) { |
2028 | val = *pval; | 2035 | val = *pval; |
2029 | } else { | 2036 | } else { |
2030 | if (!port->endpoint) | 2037 | if (!port->endpoint) |
2031 | val = 0xaaa0 + port->index; | 2038 | val = 0xaaa0 + port->index; |
2032 | else | 2039 | else |
2033 | val = 0xeee0 + port->index; | 2040 | val = 0xeee0 + port->index; |
2034 | } | 2041 | } |
2035 | out_le16(mbase + 0x200, val); | 2042 | out_le16(mbase + 0x200, val); |
2036 | 2043 | ||
2037 | pval = of_get_property(port->node, "device-id", NULL); | 2044 | pval = of_get_property(port->node, "device-id", NULL); |
2038 | if (pval) { | 2045 | if (pval) { |
2039 | val = *pval; | 2046 | val = *pval; |
2040 | } else { | 2047 | } else { |
2041 | if (!port->endpoint) | 2048 | if (!port->endpoint) |
2042 | val = 0xbed0 + port->index; | 2049 | val = 0xbed0 + port->index; |
2043 | else | 2050 | else |
2044 | val = 0xfed0 + port->index; | 2051 | val = 0xfed0 + port->index; |
2045 | } | 2052 | } |
2046 | out_le16(mbase + 0x202, val); | 2053 | out_le16(mbase + 0x202, val); |
2047 | 2054 | ||
2048 | /* Enable Bus master, memory, and io space */ | 2055 | /* Enable Bus master, memory, and io space */ |
2049 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) | 2056 | if (of_device_is_compatible(port->node, "ibm,plb-pciex-460sx")) |
2050 | out_le16(mbase + 0x204, 0x7); | 2057 | out_le16(mbase + 0x204, 0x7); |
2051 | 2058 | ||
2052 | if (!port->endpoint) { | 2059 | if (!port->endpoint) { |
2053 | /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ | 2060 | /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ |
2054 | out_le32(mbase + 0x208, 0x06040001); | 2061 | out_le32(mbase + 0x208, 0x06040001); |
2055 | 2062 | ||
2056 | printk(KERN_INFO "PCIE%d: successfully set as root-complex\n", | 2063 | printk(KERN_INFO "PCIE%d: successfully set as root-complex\n", |
2057 | port->index); | 2064 | port->index); |
2058 | } else { | 2065 | } else { |
2059 | /* Set Class Code to Processor/PPC */ | 2066 | /* Set Class Code to Processor/PPC */ |
2060 | out_le32(mbase + 0x208, 0x0b200001); | 2067 | out_le32(mbase + 0x208, 0x0b200001); |
2061 | 2068 | ||
2062 | printk(KERN_INFO "PCIE%d: successfully set as endpoint\n", | 2069 | printk(KERN_INFO "PCIE%d: successfully set as endpoint\n", |
2063 | port->index); | 2070 | port->index); |
2064 | } | 2071 | } |
2065 | 2072 | ||
2066 | return; | 2073 | return; |
2067 | fail: | 2074 | fail: |
2068 | if (hose) | 2075 | if (hose) |
2069 | pcibios_free_controller(hose); | 2076 | pcibios_free_controller(hose); |
2070 | if (cfg_data) | 2077 | if (cfg_data) |
2071 | iounmap(cfg_data); | 2078 | iounmap(cfg_data); |
2072 | if (mbase) | 2079 | if (mbase) |
2073 | iounmap(mbase); | 2080 | iounmap(mbase); |
2074 | } | 2081 | } |
2075 | 2082 | ||
2076 | static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) | 2083 | static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) |
2077 | { | 2084 | { |
2078 | struct ppc4xx_pciex_port *port; | 2085 | struct ppc4xx_pciex_port *port; |
2079 | const u32 *pval; | 2086 | const u32 *pval; |
2080 | int portno; | 2087 | int portno; |
2081 | unsigned int dcrs; | 2088 | unsigned int dcrs; |
2082 | const char *val; | 2089 | const char *val; |
2083 | 2090 | ||
2084 | /* First, proceed to core initialization as we assume there's | 2091 | /* First, proceed to core initialization as we assume there's |
2085 | * only one PCIe core in the system | 2092 | * only one PCIe core in the system |
2086 | */ | 2093 | */ |
2087 | if (ppc4xx_pciex_check_core_init(np)) | 2094 | if (ppc4xx_pciex_check_core_init(np)) |
2088 | return; | 2095 | return; |
2089 | 2096 | ||
2090 | /* Get the port number from the device-tree */ | 2097 | /* Get the port number from the device-tree */ |
2091 | pval = of_get_property(np, "port", NULL); | 2098 | pval = of_get_property(np, "port", NULL); |
2092 | if (pval == NULL) { | 2099 | if (pval == NULL) { |
2093 | printk(KERN_ERR "PCIE: Can't find port number for %s\n", | 2100 | printk(KERN_ERR "PCIE: Can't find port number for %s\n", |
2094 | np->full_name); | 2101 | np->full_name); |
2095 | return; | 2102 | return; |
2096 | } | 2103 | } |
2097 | portno = *pval; | 2104 | portno = *pval; |
2098 | if (portno >= ppc4xx_pciex_port_count) { | 2105 | if (portno >= ppc4xx_pciex_port_count) { |
2099 | printk(KERN_ERR "PCIE: port number out of range for %s\n", | 2106 | printk(KERN_ERR "PCIE: port number out of range for %s\n", |
2100 | np->full_name); | 2107 | np->full_name); |
2101 | return; | 2108 | return; |
2102 | } | 2109 | } |
2103 | port = &ppc4xx_pciex_ports[portno]; | 2110 | port = &ppc4xx_pciex_ports[portno]; |
2104 | port->index = portno; | 2111 | port->index = portno; |
2105 | 2112 | ||
2106 | /* | 2113 | /* |
2107 | * Check if device is enabled | 2114 | * Check if device is enabled |
2108 | */ | 2115 | */ |
2109 | if (!of_device_is_available(np)) { | 2116 | if (!of_device_is_available(np)) { |
2110 | printk(KERN_INFO "PCIE%d: Port disabled via device-tree\n", port->index); | 2117 | printk(KERN_INFO "PCIE%d: Port disabled via device-tree\n", port->index); |
2111 | return; | 2118 | return; |
2112 | } | 2119 | } |
2113 | 2120 | ||
2114 | port->node = of_node_get(np); | 2121 | port->node = of_node_get(np); |
2115 | if (ppc4xx_pciex_hwops->want_sdr) { | 2122 | if (ppc4xx_pciex_hwops->want_sdr) { |
2116 | pval = of_get_property(np, "sdr-base", NULL); | 2123 | pval = of_get_property(np, "sdr-base", NULL); |
2117 | if (pval == NULL) { | 2124 | if (pval == NULL) { |
2118 | printk(KERN_ERR "PCIE: missing sdr-base for %s\n", | 2125 | printk(KERN_ERR "PCIE: missing sdr-base for %s\n", |
2119 | np->full_name); | 2126 | np->full_name); |
2120 | return; | 2127 | return; |
2121 | } | 2128 | } |
2122 | port->sdr_base = *pval; | 2129 | port->sdr_base = *pval; |
2123 | } | 2130 | } |
2124 | 2131 | ||
2125 | /* Check if device_type property is set to "pci" or "pci-endpoint". | 2132 | /* Check if device_type property is set to "pci" or "pci-endpoint". |
2126 | * Resulting from this setup this PCIe port will be configured | 2133 | * Resulting from this setup this PCIe port will be configured |
2127 | * as root-complex or as endpoint. | 2134 | * as root-complex or as endpoint. |
2128 | */ | 2135 | */ |
2129 | val = of_get_property(port->node, "device_type", NULL); | 2136 | val = of_get_property(port->node, "device_type", NULL); |
2130 | if (!strcmp(val, "pci-endpoint")) { | 2137 | if (!strcmp(val, "pci-endpoint")) { |
2131 | port->endpoint = 1; | 2138 | port->endpoint = 1; |
2132 | } else if (!strcmp(val, "pci")) { | 2139 | } else if (!strcmp(val, "pci")) { |
2133 | port->endpoint = 0; | 2140 | port->endpoint = 0; |
2134 | } else { | 2141 | } else { |
2135 | printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n", | 2142 | printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n", |
2136 | np->full_name); | 2143 | np->full_name); |
2137 | return; | 2144 | return; |
2138 | } | 2145 | } |
2139 | 2146 | ||
2140 | /* Fetch config space registers address */ | 2147 | /* Fetch config space registers address */ |
2141 | if (of_address_to_resource(np, 0, &port->cfg_space)) { | 2148 | if (of_address_to_resource(np, 0, &port->cfg_space)) { |
2142 | printk(KERN_ERR "%s: Can't get PCI-E config space !", | 2149 | printk(KERN_ERR "%s: Can't get PCI-E config space !", |
2143 | np->full_name); | 2150 | np->full_name); |
2144 | return; | 2151 | return; |
2145 | } | 2152 | } |
2146 | /* Fetch host bridge internal registers address */ | 2153 | /* Fetch host bridge internal registers address */ |
2147 | if (of_address_to_resource(np, 1, &port->utl_regs)) { | 2154 | if (of_address_to_resource(np, 1, &port->utl_regs)) { |
2148 | printk(KERN_ERR "%s: Can't get UTL register base !", | 2155 | printk(KERN_ERR "%s: Can't get UTL register base !", |
2149 | np->full_name); | 2156 | np->full_name); |
2150 | return; | 2157 | return; |
2151 | } | 2158 | } |
2152 | 2159 | ||
2153 | /* Map DCRs */ | 2160 | /* Map DCRs */ |
2154 | dcrs = dcr_resource_start(np, 0); | 2161 | dcrs = dcr_resource_start(np, 0); |
2155 | if (dcrs == 0) { | 2162 | if (dcrs == 0) { |
2156 | printk(KERN_ERR "%s: Can't get DCR register base !", | 2163 | printk(KERN_ERR "%s: Can't get DCR register base !", |
2157 | np->full_name); | 2164 | np->full_name); |
2158 | return; | 2165 | return; |
2159 | } | 2166 | } |
2160 | port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); | 2167 | port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); |
2161 | 2168 | ||
2162 | /* Initialize the port specific registers */ | 2169 | /* Initialize the port specific registers */ |
2163 | if (ppc4xx_pciex_port_init(port)) { | 2170 | if (ppc4xx_pciex_port_init(port)) { |
2164 | printk(KERN_WARNING "PCIE%d: Port init failed\n", port->index); | 2171 | printk(KERN_WARNING "PCIE%d: Port init failed\n", port->index); |
2165 | return; | 2172 | return; |
2166 | } | 2173 | } |
2167 | 2174 | ||
2168 | /* Setup the linux hose data structure */ | 2175 | /* Setup the linux hose data structure */ |
2169 | ppc4xx_pciex_port_setup_hose(port); | 2176 | ppc4xx_pciex_port_setup_hose(port); |
2170 | } | 2177 | } |
2171 | 2178 | ||
2172 | #endif /* CONFIG_PPC4xx_PCI_EXPRESS */ | 2179 | #endif /* CONFIG_PPC4xx_PCI_EXPRESS */ |
2173 | 2180 | ||
2174 | static int __init ppc4xx_pci_find_bridges(void) | 2181 | static int __init ppc4xx_pci_find_bridges(void) |
2175 | { | 2182 | { |
2176 | struct device_node *np; | 2183 | struct device_node *np; |
2177 | 2184 | ||
2178 | pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0); | 2185 | pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0); |
2179 | 2186 | ||
2180 | #ifdef CONFIG_PPC4xx_PCI_EXPRESS | 2187 | #ifdef CONFIG_PPC4xx_PCI_EXPRESS |
2181 | for_each_compatible_node(np, NULL, "ibm,plb-pciex") | 2188 | for_each_compatible_node(np, NULL, "ibm,plb-pciex") |
2182 | ppc4xx_probe_pciex_bridge(np); | 2189 | ppc4xx_probe_pciex_bridge(np); |
2183 | #endif | 2190 | #endif |
2184 | for_each_compatible_node(np, NULL, "ibm,plb-pcix") | 2191 | for_each_compatible_node(np, NULL, "ibm,plb-pcix") |
2185 | ppc4xx_probe_pcix_bridge(np); | 2192 | ppc4xx_probe_pcix_bridge(np); |
2186 | for_each_compatible_node(np, NULL, "ibm,plb-pci") | 2193 | for_each_compatible_node(np, NULL, "ibm,plb-pci") |
2187 | ppc4xx_probe_pci_bridge(np); | 2194 | ppc4xx_probe_pci_bridge(np); |
2188 | 2195 | ||
2189 | return 0; | 2196 | return 0; |
2190 | } | 2197 | } |
2191 | arch_initcall(ppc4xx_pci_find_bridges); | 2198 | arch_initcall(ppc4xx_pci_find_bridges); |
2192 | 2199 | ||
2193 | 2200 |
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145
-
mentioned in commit 01b145