diff options
Diffstat (limited to 'arch/powerpc/platforms/44x')
| -rw-r--r-- | arch/powerpc/platforms/44x/Kconfig | 54 | ||||
| -rw-r--r-- | arch/powerpc/platforms/44x/Makefile | 3 | ||||
| -rw-r--r-- | arch/powerpc/platforms/44x/iss4xx.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/platforms/44x/ppc476.c (renamed from arch/powerpc/platforms/44x/currituck.c) | 151 | ||||
| -rw-r--r-- | arch/powerpc/platforms/44x/ppc476_modules.lds | 15 | ||||
| -rw-r--r-- | arch/powerpc/platforms/44x/virtex_ml510.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/44x/warp.c | 1 |
7 files changed, 195 insertions, 35 deletions
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 8abf6fb8f41..4d88f6a1905 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -199,6 +199,34 @@ config CURRITUCK help This option enables support for the IBM Currituck (476fpe) evaluation board +config AKEBONO + bool "IBM Akebono (476gtr) Support" + depends on PPC_47x + default n + select SWIOTLB + select 476FPE + select PPC4xx_PCI_EXPRESS + select PCI_MSI + select PPC4xx_HSTA_MSI + select I2C + select I2C_IBM_IIC + select NETDEVICES + select ETHERNET + select NET_VENDOR_IBM + select IBM_EMAC_EMAC4 + select IBM_EMAC_RGMII_WOL + select USB + select USB_OHCI_HCD_PLATFORM + select USB_EHCI_HCD_PLATFORM + select MMC_SDHCI + select MMC_SDHCI_PLTFM + select MMC_SDHCI_OF_476GTR + select ATA + select SATA_AHCI_PLATFORM + help + This option enables support for the IBM Akebono (476gtr) evaluation board + + config ICON bool "Icon" depends on 44x @@ -248,17 +276,23 @@ config PPC4xx_GPIO bool "PPC4xx GPIO support" depends on 44x select ARCH_REQUIRE_GPIOLIB - select GENERIC_GPIO help Enable gpiolib support for ppc440 based boards +config PPC4xx_OCM + bool "PPC4xx On Chip Memory (OCM) support" + depends on 4xx + select PPC_LIB_RHEAP + help + Enable OCM support for PowerPC 4xx platforms with on chip memory, + OCM provides the fast place for memory access to improve performance. + # 44x specific CPU modules, selected based on the board above. config 440EP bool select PPC_FPU select IBM440EP_ERR42 select IBM_EMAC_ZMII - select USB_ARCH_HAS_OHCI config 440EPX bool @@ -266,6 +300,8 @@ config 440EPX select IBM_EMAC_EMAC4 select IBM_EMAC_RGMII select IBM_EMAC_ZMII + select USB_EHCI_BIG_ENDIAN_MMIO + select USB_EHCI_BIG_ENDIAN_DESC config 440GRX bool @@ -315,6 +351,20 @@ config APM821xx select IBM_EMAC_EMAC4 select IBM_EMAC_TAH +config 476FPE_ERR46 + depends on 476FPE + bool "Enable linker work around for PPC476FPE errata #46" + help + This option enables a work around for an icache bug on 476 + that can cause execution of stale instructions when falling + through pages (IBM errata #46). It requires a recent version + of binutils which supports the --ppc476-workaround option. + + The work around enables the appropriate linker options and + ensures that all module output sections are aligned to 4K + page boundaries. The work around is only required when + building modules. + # 44x errata/workaround config symbols, selected by the CPU models above config IBM440EP_ERR42 bool diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index d03833abec0..26d35b5941f 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -10,4 +10,5 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o obj-$(CONFIG_ISS4xx) += iss4xx.o obj-$(CONFIG_CANYONLANDS)+= canyonlands.o -obj-$(CONFIG_CURRITUCK) += currituck.o +obj-$(CONFIG_CURRITUCK) += ppc476.o +obj-$(CONFIG_AKEBONO) += ppc476.o diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c index a28a8629727..4241bc82580 100644 --- a/arch/powerpc/platforms/44x/iss4xx.c +++ b/arch/powerpc/platforms/44x/iss4xx.c @@ -81,12 +81,12 @@ static void __init iss4xx_init_irq(void) } #ifdef CONFIG_SMP -static void __cpuinit smp_iss4xx_setup_cpu(int cpu) +static void smp_iss4xx_setup_cpu(int cpu) { mpic_setup_this_cpu(); } -static int __cpuinit smp_iss4xx_kick_cpu(int cpu) +static int smp_iss4xx_kick_cpu(int cpu) { struct device_node *cpunode = of_get_cpu_node(cpu, NULL); const u64 *spin_table_addr_prop; diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/ppc476.c index 583e67fee37..33986c1a05d 100644 --- a/arch/powerpc/platforms/44x/currituck.c +++ b/arch/powerpc/platforms/44x/ppc476.c @@ -1,7 +1,8 @@ /* - * Currituck board specific routines + * PowerPC 476FPE board specific routines * - * Copyright © 2011 Tony Breeds IBM Corporation + * Copyright © 2013 Tony Breeds IBM Corporation + * Copyright © 2013 Alistair Popple IBM Corporation * * Based on earlier code: * Matt Porter <mporter@kernel.crashing.org> @@ -21,7 +22,6 @@ */ #include <linux/init.h> -#include <linux/memblock.h> #include <linux/of.h> #include <linux/of_platform.h> #include <linux/rtc.h> @@ -36,8 +36,9 @@ #include <asm/mmu.h> #include <linux/pci.h> +#include <linux/i2c.h> -static __initdata struct of_device_id ppc47x_of_bus[] = { +static struct of_device_id ppc47x_of_bus[] __initdata = { { .compatible = "ibm,plb4", }, { .compatible = "ibm,plb6", }, { .compatible = "ibm,opb", }, @@ -47,7 +48,7 @@ static __initdata struct of_device_id ppc47x_of_bus[] = { /* The EEPROM is missing and the default values are bogus. This forces USB in * to EHCI mode */ -static void __devinit quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) +static void quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) { if (of_machine_is_compatible("ibm,currituck")) { pci_write_config_dword(dev, 0xe0, 0x0114231f); @@ -56,15 +57,69 @@ static void __devinit quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup); +/* Akebono has an AVR microcontroller attached to the I2C bus + * which is used to power off/reset the system. */ + +/* AVR I2C Commands */ +#define AVR_PWRCTL_CMD (0x26) + +/* Flags for the power control I2C commands */ +#define AVR_PWRCTL_PWROFF (0x01) +#define AVR_PWRCTL_RESET (0x02) + +static struct i2c_client *avr_i2c_client; +static void avr_halt_system(int pwrctl_flags) +{ + /* Request the AVR to reset the system */ + i2c_smbus_write_byte_data(avr_i2c_client, + AVR_PWRCTL_CMD, pwrctl_flags); + + /* Wait for system to be reset */ + while (1) + ; +} + +static void avr_power_off_system(void) +{ + avr_halt_system(AVR_PWRCTL_PWROFF); +} + +static void avr_reset_system(char *cmd) +{ + avr_halt_system(AVR_PWRCTL_RESET); +} + +static int avr_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + avr_i2c_client = client; + ppc_md.restart = avr_reset_system; + ppc_md.power_off = avr_power_off_system; + return 0; +} + +static const struct i2c_device_id avr_id[] = { + { "akebono-avr", 0 }, + { } +}; + +static struct i2c_driver avr_driver = { + .driver = { + .name = "akebono-avr", + }, + .probe = avr_probe, + .id_table = avr_id, +}; + static int __init ppc47x_device_probe(void) { + i2c_add_driver(&avr_driver); of_platform_bus_probe(NULL, ppc47x_of_bus, NULL); return 0; } machine_device_initcall(ppc47x, ppc47x_device_probe); -/* We can have either UICs or MPICs */ static void __init ppc47x_init_irq(void) { struct device_node *np; @@ -92,12 +147,12 @@ static void __init ppc47x_init_irq(void) } #ifdef CONFIG_SMP -static void __cpuinit smp_ppc47x_setup_cpu(int cpu) +static void smp_ppc47x_setup_cpu(int cpu) { mpic_setup_this_cpu(); } -static int __cpuinit smp_ppc47x_kick_cpu(int cpu) +static int smp_ppc47x_kick_cpu(int cpu) { struct device_node *cpunode = of_get_cpu_node(cpu, NULL); const u64 *spin_table_addr_prop; @@ -158,47 +213,87 @@ static void __init ppc47x_setup_arch(void) { /* No need to check the DMA config as we /know/ our windows are all of - * RAM. Lets hope that doesn't change */ -#ifdef CONFIG_SWIOTLB - if (memblock_end_of_DRAM() > 0xffffffff) { - ppc_swiotlb_enable = 1; - set_pci_dma_ops(&swiotlb_dma_ops); - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; - } -#endif + * RAM. Lets hope that doesn't change */ + swiotlb_detect_4g(); + ppc47x_smp_init(); } -/* - * Called very early, MMU is off, device-tree isn't unflattened - */ -static int __init ppc47x_probe(void) +static int board_rev = -1; +static int __init ppc47x_get_board_rev(void) { - unsigned long root = of_get_flat_dt_root(); + int reg; + u8 *fpga; + struct device_node *np = NULL; + + if (of_machine_is_compatible("ibm,currituck")) { + np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga"); + reg = 0; + } else if (of_machine_is_compatible("ibm,akebono")) { + np = of_find_compatible_node(NULL, NULL, "ibm,akebono-fpga"); + reg = 2; + } + + if (!np) + goto fail; - if (!of_flat_dt_is_compatible(root, "ibm,currituck")) - return 0; + fpga = (u8 *) of_iomap(np, 0); + of_node_put(np); + if (!fpga) + goto fail; - return 1; + board_rev = ioread8(fpga + reg) & 0x03; + pr_info("%s: Found board revision %d\n", __func__, board_rev); + iounmap(fpga); + return 0; + +fail: + pr_info("%s: Unable to find board revision\n", __func__); + return 0; } +machine_arch_initcall(ppc47x, ppc47x_get_board_rev); /* Use USB controller should have been hardware swizzled but it wasn't :( */ static void ppc47x_pci_irq_fixup(struct pci_dev *dev) { if (dev->vendor == 0x1033 && (dev->device == 0x0035 || - dev->device == 0x00e0)) { - dev->irq = irq_create_mapping(NULL, 47); - pr_info("%s: Mapping irq 47 %d\n", __func__, dev->irq); + dev->device == 0x00e0)) { + if (board_rev == 0) { + dev->irq = irq_create_mapping(NULL, 47); + pr_info("%s: Mapping irq %d\n", __func__, dev->irq); + } else if (board_rev == 2) { + dev->irq = irq_create_mapping(NULL, 49); + pr_info("%s: Mapping irq %d\n", __func__, dev->irq); + } else { + pr_alert("%s: Unknown board revision\n", __func__); + } } } +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init ppc47x_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (of_flat_dt_is_compatible(root, "ibm,akebono")) + return 1; + + if (of_flat_dt_is_compatible(root, "ibm,currituck")) { + ppc_md.pci_irq_fixup = ppc47x_pci_irq_fixup; + return 1; + } + + return 0; +} + define_machine(ppc47x) { .name = "PowerPC 47x", .probe = ppc47x_probe, .progress = udbg_progress, .init_IRQ = ppc47x_init_irq, .setup_arch = ppc47x_setup_arch, - .pci_irq_fixup = ppc47x_pci_irq_fixup, .restart = ppc4xx_reset_system, .calibrate_decr = generic_calibrate_decr, }; diff --git a/arch/powerpc/platforms/44x/ppc476_modules.lds b/arch/powerpc/platforms/44x/ppc476_modules.lds new file mode 100644 index 00000000000..9fec5d34ba8 --- /dev/null +++ b/arch/powerpc/platforms/44x/ppc476_modules.lds @@ -0,0 +1,15 @@ +SECTIONS +{ + .text : ALIGN(4096) + { + *(.text .text.* .fixup) + } + .init.text : ALIGN(4096) + { + *(.init.text .init.text.*) + } + .exit.text : ALIGN(4096) + { + *(.exit.text .exit.text.*) + } +} diff --git a/arch/powerpc/platforms/44x/virtex_ml510.c b/arch/powerpc/platforms/44x/virtex_ml510.c index ba4a6e388a4..1fdb8748638 100644 --- a/arch/powerpc/platforms/44x/virtex_ml510.c +++ b/arch/powerpc/platforms/44x/virtex_ml510.c @@ -5,7 +5,7 @@ /** * ml510_ail_quirk */ -static void __devinit ml510_ali_quirk(struct pci_dev *dev) +static void ml510_ali_quirk(struct pci_dev *dev) { /* Enable the IDE controller */ pci_write_config_byte(dev, 0x58, 0x4c); diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c index 4cfa49901c0..534574a97ec 100644 --- a/arch/powerpc/platforms/44x/warp.c +++ b/arch/powerpc/platforms/44x/warp.c @@ -16,7 +16,6 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/of_gpio.h> -#include <linux/of_i2c.h> #include <linux/slab.h> #include <linux/export.h> |
