diff options
author | Alistair Popple <alistair@popple.id.au> | 2014-03-05 22:52:27 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-04-30 18:26:26 -0400 |
commit | 2a2c74b2efcb1a0ca3fdcb5fbb96ad8de6a29177 (patch) | |
tree | 46f41ff197ece8795b6c11ca5eeb2782163b4427 /arch/powerpc/platforms/44x | |
parent | 6b11930f726c1d8a7c054f7a293621bce4c684c5 (diff) |
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>
Diffstat (limited to 'arch/powerpc/platforms/44x')
-rw-r--r-- | arch/powerpc/platforms/44x/Kconfig | 26 | ||||
-rw-r--r-- | arch/powerpc/platforms/44x/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/44x/ppc476.c | 112 |
3 files changed, 116 insertions, 23 deletions
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index dc1a264ec6e6..b0202d83063e 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
@@ -199,6 +199,32 @@ config CURRITUCK | |||
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 |
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index f896b896b64e..26d35b5941f7 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile | |||
@@ -11,3 +11,4 @@ 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 | ||
diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c index c6c5a6f28ff5..33986c1a05da 100644 --- a/arch/powerpc/platforms/44x/ppc476.c +++ b/arch/powerpc/platforms/44x/ppc476.c | |||
@@ -1,7 +1,8 @@ | |||
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> |
@@ -35,6 +36,7 @@ | |||
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", }, |
@@ -55,15 +57,69 @@ static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) | |||
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; |
@@ -163,37 +219,30 @@ static void __init ppc47x_setup_arch(void) | |||
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; |
228 | |||
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 | } | ||
185 | 236 | ||
186 | np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga"); | ||
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; |
@@ -221,13 +270,30 @@ static void ppc47x_pci_irq_fixup(struct pci_dev *dev) | |||
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; | ||
286 | } | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
224 | define_machine(ppc47x) { | 291 | define_machine(ppc47x) { |
225 | .name = "PowerPC 47x", | 292 | .name = "PowerPC 47x", |
226 | .probe = ppc47x_probe, | 293 | .probe = ppc47x_probe, |
227 | .progress = udbg_progress, | 294 | .progress = udbg_progress, |
228 | .init_IRQ = ppc47x_init_irq, | 295 | .init_IRQ = ppc47x_init_irq, |
229 | .setup_arch = ppc47x_setup_arch, | 296 | .setup_arch = ppc47x_setup_arch, |
230 | .pci_irq_fixup = ppc47x_pci_irq_fixup, | ||
231 | .restart = ppc4xx_reset_system, | 297 | .restart = ppc4xx_reset_system, |
232 | .calibrate_decr = generic_calibrate_decr, | 298 | .calibrate_decr = generic_calibrate_decr, |
233 | }; | 299 | }; |