diff options
Diffstat (limited to 'arch/powerpc/sysdev')
24 files changed, 751 insertions, 935 deletions
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 15f3e8527d7..6d386d0071a 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o +obj-$(CONFIG_FSL_LBC) += fsl_lbc.o obj-$(CONFIG_RAPIDIO) += fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ @@ -27,6 +28,7 @@ obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_IPIC) += ipic.o obj-$(CONFIG_4xx) += uic.o +obj-$(CONFIG_4xx_SOC) += ppc4xx_soc.o obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o obj-$(CONFIG_OF_RTC) += of_rtc.o ifeq ($(CONFIG_PCI),y) diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index d359d6e9297..7f59188cd9a 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -143,7 +143,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio) */ static int axon_ram_direct_access(struct block_device *device, sector_t sector, - unsigned long *data) + void **kaddr, unsigned long *pfn) { struct axon_ram_bank *bank = device->bd_disk->private_data; loff_t offset; @@ -154,7 +154,8 @@ axon_ram_direct_access(struct block_device *device, sector_t sector, return -ERANGE; } - *data = bank->ph_addr + offset; + *kaddr = (void *)(bank->ph_addr + offset); + *pfn = virt_to_phys(kaddr) >> PAGE_SHIFT; return 0; } diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index df8bd2b6479..58292a086c1 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -44,9 +44,6 @@ #define CPM_MAP_SIZE (0x4000) -#ifndef CONFIG_PPC_CPM_NEW_BINDING -static void m8xx_cpm_dpinit(void); -#endif cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */ immap_t __iomem *mpc8xx_immr; static cpic8xx_t __iomem *cpic_reg; @@ -229,12 +226,7 @@ void __init cpm_reset(void) out_be32(&siu_conf->sc_sdcr, 1); immr_unmap(siu_conf); -#ifdef CONFIG_PPC_CPM_NEW_BINDING cpm_muram_init(); -#else - /* Reclaim the DP memory for our use. */ - m8xx_cpm_dpinit(); -#endif } static DEFINE_SPINLOCK(cmd_lock); @@ -257,7 +249,7 @@ int cpm_command(u32 command, u8 opcode) if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0) goto out; - printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__); + printk(KERN_ERR "%s(): Not able to issue CPM command\n", __func__); ret = -EIO; out: spin_unlock_irqrestore(&cmd_lock, flags); @@ -293,110 +285,6 @@ cpm_setbrg(uint brg, uint rate) CPM_BRG_EN | CPM_BRG_DIV16); } -#ifndef CONFIG_PPC_CPM_NEW_BINDING -/* - * dpalloc / dpfree bits. - */ -static spinlock_t cpm_dpmem_lock; -/* - * 16 blocks should be enough to satisfy all requests - * until the memory subsystem goes up... - */ -static rh_block_t cpm_boot_dpmem_rh_block[16]; -static rh_info_t cpm_dpmem_info; - -#define CPM_DPMEM_ALIGNMENT 8 -static u8 __iomem *dpram_vbase; -static phys_addr_t dpram_pbase; - -static void m8xx_cpm_dpinit(void) -{ - spin_lock_init(&cpm_dpmem_lock); - - dpram_vbase = cpmp->cp_dpmem; - dpram_pbase = get_immrbase() + offsetof(immap_t, im_cpm.cp_dpmem); - - /* Initialize the info header */ - rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT, - sizeof(cpm_boot_dpmem_rh_block) / - sizeof(cpm_boot_dpmem_rh_block[0]), - cpm_boot_dpmem_rh_block); - - /* - * Attach the usable dpmem area. - * XXX: This is actually crap. CPM_DATAONLY_BASE and - * CPM_DATAONLY_SIZE are a subset of the available dparm. It varies - * with the processor and the microcode patches applied / activated. - * But the following should be at least safe. - */ - rh_attach_region(&cpm_dpmem_info, CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE); -} - -/* - * Allocate the requested size worth of DP memory. - * This function returns an offset into the DPRAM area. - * Use cpm_dpram_addr() to get the virtual address of the area. - */ -unsigned long cpm_dpalloc(uint size, uint align) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - cpm_dpmem_info.alignment = align; - start = rh_alloc(&cpm_dpmem_info, size, "commproc"); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return (uint)start; -} -EXPORT_SYMBOL(cpm_dpalloc); - -int cpm_dpfree(unsigned long offset) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - ret = rh_free(&cpm_dpmem_info, offset); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return ret; -} -EXPORT_SYMBOL(cpm_dpfree); - -unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - cpm_dpmem_info.alignment = align; - start = rh_alloc_fixed(&cpm_dpmem_info, offset, size, "commproc"); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return start; -} -EXPORT_SYMBOL(cpm_dpalloc_fixed); - -void cpm_dpdump(void) -{ - rh_dump(&cpm_dpmem_info); -} -EXPORT_SYMBOL(cpm_dpdump); - -void *cpm_dpram_addr(unsigned long offset) -{ - return (void *)(dpram_vbase + offset); -} -EXPORT_SYMBOL(cpm_dpram_addr); - -uint cpm_dpram_phys(u8 *addr) -{ - return (dpram_pbase + (uint)(addr - dpram_vbase)); -} -EXPORT_SYMBOL(cpm_dpram_phys); -#endif /* !CONFIG_PPC_CPM_NEW_BINDING */ - struct cpm_ioport16 { __be16 dir, par, odr_sor, dat, intr; __be16 res[3]; diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c index dd066bb1d56..5a6c5dfc53e 100644 --- a/arch/powerpc/sysdev/cpm2.c +++ b/arch/powerpc/sysdev/cpm2.c @@ -46,10 +46,6 @@ #include <sysdev/fsl_soc.h> -#ifndef CONFIG_PPC_CPM_NEW_BINDING -static void cpm2_dpinit(void); -#endif - cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */ /* We allocate this here because it is used almost exclusively for @@ -71,15 +67,17 @@ void __init cpm2_reset(void) /* Reclaim the DP memory for our use. */ -#ifdef CONFIG_PPC_CPM_NEW_BINDING cpm_muram_init(); -#else - cpm2_dpinit(); -#endif /* Tell everyone where the comm processor resides. */ cpmp = &cpm2_immr->im_cpm; + +#ifndef CONFIG_PPC_EARLY_DEBUG_CPM + /* Reset the CPM. + */ + cpm_command(CPM_CR_RST, 0); +#endif } static DEFINE_SPINLOCK(cmd_lock); @@ -99,7 +97,7 @@ int cpm_command(u32 command, u8 opcode) if ((in_be32(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0) goto out; - printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__); + printk(KERN_ERR "%s(): Not able to issue CPM command\n", __func__); ret = -EIO; out: spin_unlock_irqrestore(&cmd_lock, flags); @@ -347,95 +345,6 @@ int cpm2_smc_clk_setup(enum cpm_clk_target target, int clock) return ret; } -#ifndef CONFIG_PPC_CPM_NEW_BINDING -/* - * dpalloc / dpfree bits. - */ -static spinlock_t cpm_dpmem_lock; -/* 16 blocks should be enough to satisfy all requests - * until the memory subsystem goes up... */ -static rh_block_t cpm_boot_dpmem_rh_block[16]; -static rh_info_t cpm_dpmem_info; -static u8 __iomem *im_dprambase; - -static void cpm2_dpinit(void) -{ - spin_lock_init(&cpm_dpmem_lock); - - /* initialize the info header */ - rh_init(&cpm_dpmem_info, 1, - sizeof(cpm_boot_dpmem_rh_block) / - sizeof(cpm_boot_dpmem_rh_block[0]), - cpm_boot_dpmem_rh_block); - - im_dprambase = cpm2_immr; - - /* Attach the usable dpmem area */ - /* XXX: This is actually crap. CPM_DATAONLY_BASE and - * CPM_DATAONLY_SIZE is only a subset of the available dpram. It - * varies with the processor and the microcode patches activated. - * But the following should be at least safe. - */ - rh_attach_region(&cpm_dpmem_info, CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE); -} - -/* This function returns an index into the DPRAM area. - */ -unsigned long cpm_dpalloc(uint size, uint align) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - cpm_dpmem_info.alignment = align; - start = rh_alloc(&cpm_dpmem_info, size, "commproc"); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return (uint)start; -} -EXPORT_SYMBOL(cpm_dpalloc); - -int cpm_dpfree(unsigned long offset) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - ret = rh_free(&cpm_dpmem_info, offset); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return ret; -} -EXPORT_SYMBOL(cpm_dpfree); - -/* not sure if this is ever needed */ -unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&cpm_dpmem_lock, flags); - cpm_dpmem_info.alignment = align; - start = rh_alloc_fixed(&cpm_dpmem_info, offset, size, "commproc"); - spin_unlock_irqrestore(&cpm_dpmem_lock, flags); - - return start; -} -EXPORT_SYMBOL(cpm_dpalloc_fixed); - -void cpm_dpdump(void) -{ - rh_dump(&cpm_dpmem_info); -} -EXPORT_SYMBOL(cpm_dpdump); - -void *cpm_dpram_addr(unsigned long offset) -{ - return (void *)(im_dprambase + offset); -} -EXPORT_SYMBOL(cpm_dpram_addr); -#endif /* !CONFIG_PPC_CPM_NEW_BINDING */ - struct cpm2_ioports { u32 dir, par, sor, odr, dat; u32 res[3]; diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 165981c8778..cb7df2dce44 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -58,7 +58,6 @@ void __init udbg_init_cpm(void) } #endif -#ifdef CONFIG_PPC_CPM_NEW_BINDING static spinlock_t cpm_muram_lock; static rh_block_t cpm_boot_muram_rh_block[16]; static rh_info_t cpm_muram_info; @@ -199,5 +198,3 @@ dma_addr_t cpm_muram_dma(void __iomem *addr) return muram_pbase + ((u8 __iomem *)addr - muram_vbase); } EXPORT_SYMBOL(cpm_muram_dma); - -#endif /* CONFIG_PPC_CPM_NEW_BINDING */ diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index e0e24b01e3a..005c2ecf976 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -37,6 +37,7 @@ #include <linux/dma-mapping.h> #include <linux/vmalloc.h> #include <linux/suspend.h> +#include <linux/lmb.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/iommu.h> @@ -44,7 +45,6 @@ #include <asm/machdep.h> #include <asm/abs_addr.h> #include <asm/cacheflush.h> -#include <asm/lmb.h> #include <asm/ppc-pci.h> #include "dart.h" diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c new file mode 100644 index 00000000000..422c8faef59 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_lbc.c @@ -0,0 +1,129 @@ +/* + * Freescale LBC and UPM routines. + * + * Copyright (c) 2007-2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov <avorontsov@ru.mvista.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/of.h> +#include <asm/fsl_lbc.h> + +spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock); + +struct fsl_lbc_regs __iomem *fsl_lbc_regs; +EXPORT_SYMBOL(fsl_lbc_regs); + +static char __initdata *compat_lbc[] = { + "fsl,pq2-localbus", + "fsl,pq2pro-localbus", + "fsl,pq3-localbus", + "fsl,elbc", +}; + +static int __init fsl_lbc_init(void) +{ + struct device_node *lbus; + int i; + + for (i = 0; i < ARRAY_SIZE(compat_lbc); i++) { + lbus = of_find_compatible_node(NULL, NULL, compat_lbc[i]); + if (lbus) + goto found; + } + return -ENODEV; + +found: + fsl_lbc_regs = of_iomap(lbus, 0); + of_node_put(lbus); + if (!fsl_lbc_regs) + return -ENOMEM; + return 0; +} +arch_initcall(fsl_lbc_init); + +/** + * fsl_lbc_find - find Localbus bank + * @addr_base: base address of the memory bank + * + * This function walks LBC banks comparing "Base address" field of the BR + * registers with the supplied addr_base argument. When bases match this + * function returns bank number (starting with 0), otherwise it returns + * appropriate errno value. + */ +int fsl_lbc_find(phys_addr_t addr_base) +{ + int i; + + if (!fsl_lbc_regs) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(fsl_lbc_regs->bank); i++) { + __be32 br = in_be32(&fsl_lbc_regs->bank[i].br); + __be32 or = in_be32(&fsl_lbc_regs->bank[i].or); + + if (br & BR_V && (br & or & BR_BA) == addr_base) + return i; + } + + return -ENOENT; +} +EXPORT_SYMBOL(fsl_lbc_find); + +/** + * fsl_upm_find - find pre-programmed UPM via base address + * @addr_base: base address of the memory bank controlled by the UPM + * @upm: pointer to the allocated fsl_upm structure + * + * This function fills fsl_upm structure so you can use it with the rest of + * UPM API. On success this function returns 0, otherwise it returns + * appropriate errno value. + */ +int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm) +{ + int bank; + __be32 br; + + bank = fsl_lbc_find(addr_base); + if (bank < 0) + return bank; + + br = in_be32(&fsl_lbc_regs->bank[bank].br); + + switch (br & BR_MSEL) { + case BR_MS_UPMA: + upm->mxmr = &fsl_lbc_regs->mamr; + break; + case BR_MS_UPMB: + upm->mxmr = &fsl_lbc_regs->mbmr; + break; + case BR_MS_UPMC: + upm->mxmr = &fsl_lbc_regs->mcmr; + break; + default: + return -EINVAL; + } + + switch (br & BR_PS) { + case BR_PS_8: + upm->width = 8; + break; + case BR_PS_16: + upm->width = 16; + break; + case BR_PS_32: + upm->width = 32; + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(fsl_upm_find); diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 2c5388ce902..7b45670c7af 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -75,6 +75,33 @@ phys_addr_t get_immrbase(void) EXPORT_SYMBOL(get_immrbase); +static u32 sysfreq = -1; + +u32 fsl_get_sys_freq(void) +{ + struct device_node *soc; + const u32 *prop; + int size; + + if (sysfreq != -1) + return sysfreq; + + soc = of_find_node_by_type(NULL, "soc"); + if (!soc) + return -1; + + prop = of_get_property(soc, "clock-frequency", &size); + if (!prop || size != sizeof(*prop) || *prop == 0) + prop = of_get_property(soc, "bus-frequency", &size); + + if (prop && size == sizeof(*prop)) + sysfreq = *prop; + + of_node_put(soc); + return sysfreq; +} +EXPORT_SYMBOL(fsl_get_sys_freq); + #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) static u32 brgfreq = -1; @@ -341,7 +368,7 @@ static int __init gfar_of_init(void) goto unreg; } - gfar_data.bus_id = 0; + snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "0"); gfar_data.phy_id = fixed_link[0]; } else { phy = of_find_node_by_phandle(*ph); @@ -362,7 +389,8 @@ static int __init gfar_of_init(void) } gfar_data.phy_id = *id; - gfar_data.bus_id = res.start; + snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%x", + res.start); of_node_put(phy); of_node_put(mdio); @@ -516,9 +544,9 @@ arch_initcall(fsl_i2c_of_init); static int __init mpc83xx_wdt_init(void) { struct resource r; - struct device_node *soc, *np; + struct device_node *np; struct platform_device *dev; - const unsigned int *freq; + u32 freq = fsl_get_sys_freq(); int ret; np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); @@ -528,19 +556,6 @@ static int __init mpc83xx_wdt_init(void) goto nodev; } - soc = of_find_node_by_type(NULL, "soc"); - - if (!soc) { - ret = -ENODEV; - goto nosoc; - } - - freq = of_get_property(soc, "bus-frequency", NULL); - if (!freq) { - ret = -ENODEV; - goto err; - } - memset(&r, 0, sizeof(r)); ret = of_address_to_resource(np, 0, &r); @@ -553,20 +568,16 @@ static int __init mpc83xx_wdt_init(void) goto err; } - ret = platform_device_add_data(dev, freq, sizeof(int)); + ret = platform_device_add_data(dev, &freq, sizeof(freq)); if (ret) goto unreg; - of_node_put(soc); of_node_put(np); - return 0; unreg: platform_device_unregister(dev); err: - of_node_put(soc); -nosoc: of_node_put(np); nodev: return ret; @@ -735,547 +746,6 @@ err: arch_initcall(fsl_usb_of_init); -#ifndef CONFIG_PPC_CPM_NEW_BINDING -#ifdef CONFIG_CPM2 - -extern void init_scc_ioports(struct fs_uart_platform_info*); - -static const char fcc_regs[] = "fcc_regs"; -static const char fcc_regs_c[] = "fcc_regs_c"; -static const char fcc_pram[] = "fcc_pram"; -static char bus_id[9][BUS_ID_SIZE]; - -static int __init fs_enet_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *fs_enet_dev; - struct resource res; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; - i++) { - struct resource r[4]; - struct device_node *phy, *mdio; - struct fs_platform_info fs_enet_data; - const unsigned int *id, *phy_addr, *phy_irq; - const void *mac_addr; - const phandle *ph; - const char *model; - - memset(r, 0, sizeof(r)); - memset(&fs_enet_data, 0, sizeof(fs_enet_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - r[0].name = fcc_regs; - - ret = of_address_to_resource(np, 1, &r[1]); - if (ret) - goto err; - r[1].name = fcc_pram; - - ret = of_address_to_resource(np, 2, &r[2]); - if (ret) - goto err; - r[2].name = fcc_regs_c; - fs_enet_data.fcc_regs_c = r[2].start; - - of_irq_to_resource(np, 0, &r[3]); - - fs_enet_dev = - platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); - - if (IS_ERR(fs_enet_dev)) { - ret = PTR_ERR(fs_enet_dev); - goto err; - } - - model = of_get_property(np, "model", NULL); - if (model == NULL) { - ret = -ENODEV; - goto unreg; - } - - mac_addr = of_get_mac_address(np); - if (mac_addr) - memcpy(fs_enet_data.macaddr, mac_addr, 6); - - ph = of_get_property(np, "phy-handle", NULL); - phy = of_find_node_by_phandle(*ph); - - if (phy == NULL) { - ret = -ENODEV; - goto unreg; - } - - phy_addr = of_get_property(phy, "reg", NULL); - fs_enet_data.phy_addr = *phy_addr; - - phy_irq = of_get_property(phy, "interrupts", NULL); - - id = of_get_property(np, "device-id", NULL); - fs_enet_data.fs_no = *id; - strcpy(fs_enet_data.fs_type, model); - - mdio = of_get_parent(phy); - ret = of_address_to_resource(mdio, 0, &res); - if (ret) { - of_node_put(phy); - of_node_put(mdio); - goto unreg; - } - - fs_enet_data.clk_rx = *((u32 *)of_get_property(np, - "rx-clock", NULL)); - fs_enet_data.clk_tx = *((u32 *)of_get_property(np, - "tx-clock", NULL)); - - if (strstr(model, "FCC")) { - int fcc_index = *id - 1; - const unsigned char *mdio_bb_prop; - - fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0); - fs_enet_data.rx_ring = 32; - fs_enet_data.tx_ring = 32; - fs_enet_data.rx_copybreak = 240; - fs_enet_data.use_napi = 0; - fs_enet_data.napi_weight = 17; - fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index); - fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index); - fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index); - - snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x", - (u32)res.start, fs_enet_data.phy_addr); - fs_enet_data.bus_id = (char*)&bus_id[(*id)]; - fs_enet_data.init_ioports = init_fcc_ioports; - - mdio_bb_prop = of_get_property(phy, "bitbang", NULL); - if (mdio_bb_prop) { - struct platform_device *fs_enet_mdio_bb_dev; - struct fs_mii_bb_platform_info fs_enet_mdio_bb_data; - - fs_enet_mdio_bb_dev = - platform_device_register_simple("fsl-bb-mdio", - i, NULL, 0); - memset(&fs_enet_mdio_bb_data, 0, - sizeof(struct fs_mii_bb_platform_info)); - fs_enet_mdio_bb_data.mdio_dat.bit = - mdio_bb_prop[0]; - fs_enet_mdio_bb_data.mdio_dir.bit = - mdio_bb_prop[1]; - fs_enet_mdio_bb_data.mdc_dat.bit = - mdio_bb_prop[2]; - fs_enet_mdio_bb_data.mdio_port = - mdio_bb_prop[3]; - fs_enet_mdio_bb_data.mdc_port = - mdio_bb_prop[4]; - fs_enet_mdio_bb_data.delay = - mdio_bb_prop[5]; - - fs_enet_mdio_bb_data.irq[0] = phy_irq[0]; - fs_enet_mdio_bb_data.irq[1] = -1; - fs_enet_mdio_bb_data.irq[2] = -1; - fs_enet_mdio_bb_data.irq[3] = phy_irq[0]; - fs_enet_mdio_bb_data.irq[31] = -1; - - fs_enet_mdio_bb_data.mdio_dat.offset = - (u32)&cpm2_immr->im_ioport.iop_pdatc; - fs_enet_mdio_bb_data.mdio_dir.offset = - (u32)&cpm2_immr->im_ioport.iop_pdirc; - fs_enet_mdio_bb_data.mdc_dat.offset = - (u32)&cpm2_immr->im_ioport.iop_pdatc; - - ret = platform_device_add_data( - fs_enet_mdio_bb_dev, - &fs_enet_mdio_bb_data, - sizeof(struct fs_mii_bb_platform_info)); - if (ret) - goto unreg; - } - - of_node_put(phy); - of_node_put(mdio); - - ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, - sizeof(struct - fs_platform_info)); - if (ret) - goto unreg; - } - } - return 0; - -unreg: - platform_device_unregister(fs_enet_dev); -err: - return ret; -} - -arch_initcall(fs_enet_of_init); - -static const char scc_regs[] = "regs"; -static const char scc_pram[] = "pram"; - -static int __init cpm_uart_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *cpm_uart_dev; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL; - i++) { - struct resource r[3]; - struct fs_uart_platform_info cpm_uart_data; - const int *id; - const char *model; - - memset(r, 0, sizeof(r)); - memset(&cpm_uart_data, 0, sizeof(cpm_uart_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - - r[0].name = scc_regs; - - ret = of_address_to_resource(np, 1, &r[1]); - if (ret) - goto err; - r[1].name = scc_pram; - - of_irq_to_resource(np, 0, &r[2]); - - cpm_uart_dev = - platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3); - - if (IS_ERR(cpm_uart_dev)) { - ret = PTR_ERR(cpm_uart_dev); - goto err; - } - - id = of_get_property(np, "device-id", NULL); - cpm_uart_data.fs_no = *id; - - model = of_get_property(np, "model", NULL); - strcpy(cpm_uart_data.fs_type, model); - - cpm_uart_data.uart_clk = ppc_proc_freq; - - cpm_uart_data.tx_num_fifo = 4; - cpm_uart_data.tx_buf_size = 32; - cpm_uart_data.rx_num_fifo = 4; - cpm_uart_data.rx_buf_size = 32; - cpm_uart_data.clk_rx = *((u32 *)of_get_property(np, - "rx-clock", NULL)); - cpm_uart_data.clk_tx = *((u32 *)of_get_property(np, - "tx-clock", NULL)); - - ret = - platform_device_add_data(cpm_uart_dev, &cpm_uart_data, - sizeof(struct - fs_uart_platform_info)); - if (ret) - goto unreg; - } - - return 0; - -unreg: - platform_device_unregister(cpm_uart_dev); -err: - return ret; -} - -arch_initcall(cpm_uart_of_init); -#endif /* CONFIG_CPM2 */ - -#ifdef CONFIG_8xx - -extern void init_scc_ioports(struct fs_platform_info*); -extern int platform_device_skip(const char *model, int id); - -static int __init fs_enet_mdio_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *mdio_dev; - struct resource res; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "mdio", "fs_enet")) != NULL; - i++) { - struct fs_mii_fec_platform_info mdio_data; - - memset(&res, 0, sizeof(res)); - memset(&mdio_data, 0, sizeof(mdio_data)); - - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto err; - - mdio_dev = - platform_device_register_simple("fsl-cpm-fec-mdio", - res.start, &res, 1); - if (IS_ERR(mdio_dev)) { - ret = PTR_ERR(mdio_dev); - goto err; - } - - mdio_data.mii_speed = ((((ppc_proc_freq + 4999999) / 2500000) / 2) & 0x3F) << 1; - - ret = - platform_device_add_data(mdio_dev, &mdio_data, - sizeof(struct fs_mii_fec_platform_info)); - if (ret) - goto unreg; - } - return 0; - -unreg: - platform_device_unregister(mdio_dev); -err: - return ret; -} - -arch_initcall(fs_enet_mdio_of_init); - -static const char *enet_regs = "regs"; -static const char *enet_pram = "pram"; -static const char *enet_irq = "interrupt"; -static char bus_id[9][BUS_ID_SIZE]; - -static int __init fs_enet_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *fs_enet_dev = NULL; - struct resource res; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; - i++) { - struct resource r[4]; - struct device_node *phy = NULL, *mdio = NULL; - struct fs_platform_info fs_enet_data; - const unsigned int *id; - const unsigned int *phy_addr; - const void *mac_addr; - const phandle *ph; - const char *model; - - memset(r, 0, sizeof(r)); - memset(&fs_enet_data, 0, sizeof(fs_enet_data)); - - model = of_get_property(np, "model", NULL); - if (model == NULL) { - ret = -ENODEV; - goto unreg; - } - - id = of_get_property(np, "device-id", NULL); - fs_enet_data.fs_no = *id; - - if (platform_device_skip(model, *id)) - continue; - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - r[0].name = enet_regs; - - mac_addr = of_get_mac_address(np); - if (mac_addr) - memcpy(fs_enet_data.macaddr, mac_addr, 6); - - ph = of_get_property(np, "phy-handle", NULL); - if (ph != NULL) - phy = of_find_node_by_phandle(*ph); - - if (phy != NULL) { - phy_addr = of_get_property(phy, "reg", NULL); - fs_enet_data.phy_addr = *phy_addr; - fs_enet_data.has_phy = 1; - - mdio = of_get_parent(phy); - ret = of_address_to_resource(mdio, 0, &res); - if (ret) { - of_node_put(phy); - of_node_put(mdio); - goto unreg; - } - } - - model = of_get_property(np, "model", NULL); - strcpy(fs_enet_data.fs_type, model); - - if (strstr(model, "FEC")) { - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); - r[1].flags = IORESOURCE_IRQ; - r[1].name = enet_irq; - - fs_enet_dev = - platform_device_register_simple("fsl-cpm-fec", i, &r[0], 2); - - if (IS_ERR(fs_enet_dev)) { - ret = PTR_ERR(fs_enet_dev); - goto err; - } - - fs_enet_data.rx_ring = 128; - fs_enet_data.tx_ring = 16; - fs_enet_data.rx_copybreak = 240; - fs_enet_data.use_napi = 1; - fs_enet_data.napi_weight = 17; - - snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%x:%02x", - (u32)res.start, fs_enet_data.phy_addr); - fs_enet_data.bus_id = (char*)&bus_id[i]; - fs_enet_data.init_ioports = init_fec_ioports; - } - if (strstr(model, "SCC")) { - ret = of_address_to_resource(np, 1, &r[1]); - if (ret) - goto err; - r[1].name = enet_pram; - - r[2].start = r[2].end = irq_of_parse_and_map(np, 0); - r[2].flags = IORESOURCE_IRQ; - r[2].name = enet_irq; - - fs_enet_dev = - platform_device_register_simple("fsl-cpm-scc", i, &r[0], 3); - - if (IS_ERR(fs_enet_dev)) { - ret = PTR_ERR(fs_enet_dev); - goto err; - } - - fs_enet_data.rx_ring = 64; - fs_enet_data.tx_ring = 8; - fs_enet_data.rx_copybreak = 240; - fs_enet_data.use_napi = 1; - fs_enet_data.napi_weight = 17; - - snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%s", "fixed@10:1"); - fs_enet_data.bus_id = (char*)&bus_id[i]; - fs_enet_data.init_ioports = init_scc_ioports; - } - - of_node_put(phy); - of_node_put(mdio); - - ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, - sizeof(struct - fs_platform_info)); - if (ret) - goto unreg; - } - return 0; - -unreg: - platform_device_unregister(fs_enet_dev); -err: - return ret; -} - -arch_initcall(fs_enet_of_init); - -static int __init fsl_pcmcia_of_init(void) -{ - struct device_node *np; - /* - * Register all the devices which type is "pcmcia" - */ - for_each_compatible_node(np, "pcmcia", "fsl,pq-pcmcia") - of_platform_device_create(np, "m8xx-pcmcia", NULL); - return 0; -} - -arch_initcall(fsl_pcmcia_of_init); - -static const char *smc_regs = "regs"; -static const char *smc_pram = "pram"; - -static int __init cpm_smc_uart_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *cpm_uart_dev; - int ret; - - for (np = NULL, i = 0; - (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL; - i++) { - struct resource r[3]; - struct fs_uart_platform_info cpm_uart_data; - const int *id; - const char *model; - - memset(r, 0, sizeof(r)); - memset(&cpm_uart_data, 0, sizeof(cpm_uart_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - - r[0].name = smc_regs; - - ret = of_address_to_resource(np, 1, &r[1]); - if (ret) - goto err; - r[1].name = smc_pram; - - r[2].start = r[2].end = irq_of_parse_and_map(np, 0); - r[2].flags = IORESOURCE_IRQ; - - cpm_uart_dev = - platform_device_register_simple("fsl-cpm-smc:uart", i, &r[0], 3); - - if (IS_ERR(cpm_uart_dev)) { - ret = PTR_ERR(cpm_uart_dev); - goto err; - } - - model = of_get_property(np, "model", NULL); - strcpy(cpm_uart_data.fs_type, model); - - id = of_get_property(np, "device-id", NULL); - cpm_uart_data.fs_no = *id; - cpm_uart_data.uart_clk = ppc_proc_freq; - - cpm_uart_data.tx_num_fifo = 4; - cpm_uart_data.tx_buf_size = 32; - cpm_uart_data.rx_num_fifo = 4; - cpm_uart_data.rx_buf_size = 32; - - ret = - platform_device_add_data(cpm_uart_dev, &cpm_uart_data, - sizeof(struct - fs_uart_platform_info)); - if (ret) - goto unreg; - } - - return 0; - -unreg: - platform_device_unregister(cpm_uart_dev); -err: - return ret; -} - -arch_initcall(cpm_smc_uart_of_init); - -#endif /* CONFIG_8xx */ -#endif /* CONFIG_PPC_CPM_NEW_BINDING */ - static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, struct spi_board_info *board_infos, unsigned int num_board_infos, @@ -1371,25 +841,9 @@ int __init fsl_spi_init(struct spi_board_info *board_infos, sysclk = get_brgfreq(); #endif if (sysclk == -1) { - struct device_node *np; - const u32 *freq; - int size; - - np = of_find_node_by_type(NULL, "soc"); - if (!np) + sysclk = fsl_get_sys_freq(); + if (sysclk == -1) return -ENODEV; - - freq = of_get_property(np, "clock-frequency", &size); - if (!freq || size != sizeof(*freq) || *freq == 0) { - freq = of_get_property(np, "bus-frequency", &size); - if (!freq || size != sizeof(*freq) || *freq == 0) { - of_node_put(np); - return -ENODEV; - } - } - - sysclk = *freq; - of_node_put(np); } ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos, @@ -1438,3 +892,44 @@ void fsl_rstcr_restart(char *cmd) while (1) ; } #endif + +#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) +struct platform_diu_data_ops diu_ops = { + .diu_size = 1280 * 1024 * 4, /* default one 1280x1024 buffer */ +}; +EXPORT_SYMBOL(diu_ops); + +int __init preallocate_diu_videomemory(void) +{ + pr_debug("diu_size=%lu\n", diu_ops.diu_size); + + diu_ops.diu_mem = __alloc_bootmem(diu_ops.diu_size, 8, 0); + if (!diu_ops.diu_mem) { + printk(KERN_ERR "fsl-diu: cannot allocate %lu bytes\n", + diu_ops.diu_size); + return -ENOMEM; + } + + pr_debug("diu_mem=%p\n", diu_ops.diu_mem); + + rh_init(&diu_ops.diu_rh_info, 4096, ARRAY_SIZE(diu_ops.diu_rh_block), + diu_ops.diu_rh_block); + return rh_attach_region(&diu_ops.diu_rh_info, + (unsigned long) diu_ops.diu_mem, + diu_ops.diu_size); +} + +static int __init early_parse_diufb(char *p) +{ + if (!p) + return 1; + + diu_ops.diu_size = _ALIGN_UP(memparse(p, &p), 8); + + pr_debug("diu_size=%lu\n", diu_ops.diu_size); + + return 0; +} +early_param("diufb", early_parse_diufb); + +#endif diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index 63e7db30a4c..52c831fa188 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -7,6 +7,7 @@ extern phys_addr_t get_immrbase(void); extern u32 get_brgfreq(void); extern u32 get_baudrate(void); +extern u32 fsl_get_sys_freq(void); struct spi_board_info; @@ -16,5 +17,28 @@ extern int fsl_spi_init(struct spi_board_info *board_infos, void (*deactivate_cs)(u8 cs, u8 polarity)); extern void fsl_rstcr_restart(char *cmd); + +#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) +#include <linux/bootmem.h> +#include <asm/rheap.h> +struct platform_diu_data_ops { + rh_block_t diu_rh_block[16]; + rh_info_t diu_rh_info; + unsigned long diu_size; + void *diu_mem; + + unsigned int (*get_pixel_format) (unsigned int bits_per_pixel, + int monitor_port); + void (*set_gamma_table) (int monitor_port, char *gamma_table_base); + void (*set_monitor_port) (int monitor_port); + void (*set_pixel_clock) (unsigned int pixclock); + ssize_t (*show_monitor_port) (int monitor_port, char *buf); + int (*set_sysfs_monitor_port) (int val); +}; + +extern struct platform_diu_data_ops diu_ops; +int __init preallocate_diu_videomemory(void); +#endif + #endif #endif diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 6ffdda244bb..8619f2a3f1f 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -175,13 +175,16 @@ static inline void _mpic_write(enum mpic_reg_type type, switch(type) { #ifdef CONFIG_PPC_DCR case mpic_access_dcr: - return dcr_write(rb->dhost, reg, value); + dcr_write(rb->dhost, reg, value); + break; #endif case mpic_access_mmio_be: - return out_be32(rb->base + (reg >> 2), value); + out_be32(rb->base + (reg >> 2), value); + break; case mpic_access_mmio_le: default: - return out_le32(rb->base + (reg >> 2), value); + out_le32(rb->base + (reg >> 2), value); + break; } } @@ -1000,7 +1003,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, const char *name) { struct mpic *mpic; - u32 reg; + u32 greg_feature; const char *vers; int i; int intvec_top; @@ -1064,7 +1067,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Look for protected sources */ if (node) { - unsigned int psize, bits, mapsize; + int psize; + unsigned int bits, mapsize; const u32 *psrc = of_get_property(node, "protected-sources", &psize); if (psrc) { @@ -1107,8 +1111,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, * in, try to obtain one */ if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) { - const u32 *reg; - reg = of_get_property(node, "reg", NULL); + const u32 *reg = of_get_property(node, "reg", NULL); BUG_ON(reg == NULL); paddr = of_translate_address(node, reg); BUG_ON(paddr == OF_BAD_ADDR); @@ -1137,12 +1140,13 @@ struct mpic * __init mpic_alloc(struct device_node *node, * MPICs, num sources as well. On ISU MPICs, sources are counted * as ISUs are added */ - reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); - mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK) + greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); + mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK) >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; if (isu_size == 0) - mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK) - >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; + mpic->num_sources = + ((greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) + >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { @@ -1161,7 +1165,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->isu_mask = (1 << mpic->isu_shift) - 1; /* Display version */ - switch (reg & MPIC_GREG_FEATURE_VERSION_MASK) { + switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) { case 1: vers = "1.0"; break; @@ -1321,7 +1325,7 @@ void __init mpic_set_serial_int(struct mpic *mpic, int enable) void mpic_irq_set_priority(unsigned int irq, unsigned int pri) { - int is_ipi; + unsigned int is_ipi; struct mpic *mpic = mpic_find(irq, &is_ipi); unsigned int src = mpic_irq_to_hw(irq); unsigned long flags; @@ -1344,7 +1348,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) unsigned int mpic_irq_get_priority(unsigned int irq) { - int is_ipi; + unsigned int is_ipi; struct mpic *mpic = mpic_find(irq, &is_ipi); unsigned int src = mpic_irq_to_hw(irq); unsigned long flags; @@ -1406,11 +1410,6 @@ void mpic_cpu_set_priority(int prio) mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio); } -/* - * XXX: someone who knows mpic should check this. - * do we need to eoi the ipi including for kexec cpu here (see xics comments)? - * or can we reset the mpic in the new kernel? - */ void mpic_teardown_this_cpu(int secondary) { struct mpic *mpic = mpic_primary; @@ -1430,6 +1429,10 @@ void mpic_teardown_this_cpu(int secondary) /* Set current processor priority to max */ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); + /* We need to EOI the IPI since not all platforms reset the MPIC + * on boot and new interrupts wouldn't get delivered otherwise. + */ + mpic_eoi(mpic); spin_unlock_irqrestore(&mpic_lock, flags); } diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index efda0028909..41af1223e2a 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -127,7 +127,7 @@ static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id) if (err) return err; - prop = of_get_property(np, "block-index", NULL); + prop = of_get_property(np, "cell-index", NULL); if (!prop) return -ENODEV; port_number = *(int *)prop; @@ -136,6 +136,7 @@ static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id) pdata.cache_mgmt = 1; /* All current revs need this set */ + pdata.max_idle = 40; /* default */ prop = of_get_property(np, "max_idle", NULL); if (prop) pdata.max_idle = *prop; @@ -205,30 +206,24 @@ error: /* * Create mv64x60_eth platform devices */ -static int __init eth_register_shared_pdev(struct device_node *np) +static struct platform_device * __init mv64x60_eth_register_shared_pdev( + struct device_node *np, int id) { struct platform_device *pdev; struct resource r[1]; int err; - np = of_get_parent(np); - if (!np) - return -ENODEV; - err = of_address_to_resource(np, 0, &r[0]); - of_node_put(np); if (err) - return err; + return ERR_PTR(err); - pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, 0, + pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id, r, 1); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - return 0; + return pdev; } -static int __init mv64x60_eth_device_setup(struct device_node *np, int id) +static int __init mv64x60_eth_device_setup(struct device_node *np, int id, + struct platform_device *shared_pdev) { struct resource r[1]; struct mv643xx_eth_platform_data pdata; @@ -239,16 +234,12 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id) const phandle *ph; int err; - /* only register the shared platform device the first time through */ - if (id == 0 && (err = eth_register_shared_pdev(np))) - return err; - memset(r, 0, sizeof(r)); of_irq_to_resource(np, 0, &r[0]); memset(&pdata, 0, sizeof(pdata)); - prop = of_get_property(np, "block-index", NULL); + prop = of_get_property(np, "reg", NULL); if (!prop) return -ENODEV; pdata.port_number = *prop; @@ -301,7 +292,7 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id) of_node_put(phy); - pdev = platform_device_alloc(MV643XX_ETH_NAME, pdata.port_number); + pdev = platform_device_alloc(MV643XX_ETH_NAME, id); if (!pdev) return -ENOMEM; @@ -345,21 +336,17 @@ static int __init mv64x60_i2c_device_setup(struct device_node *np, int id) memset(&pdata, 0, sizeof(pdata)); + pdata.freq_m = 8; /* default */ prop = of_get_property(np, "freq_m", NULL); - if (!prop) - return -ENODEV; - pdata.freq_m = *prop; + if (prop) + pdata.freq_m = *prop; + pdata.freq_m = 3; /* default */ prop = of_get_property(np, "freq_n", NULL); - if (!prop) - return -ENODEV; - pdata.freq_n = *prop; - - prop = of_get_property(np, "timeout", NULL); if (prop) - pdata.timeout = *prop; - else - pdata.timeout = 1000; /* 1 second */ + pdata.freq_n = *prop; + + pdata.timeout = 1000; /* default: 1 second */ pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id); if (!pdev) @@ -401,10 +388,7 @@ static int __init mv64x60_wdt_device_setup(struct device_node *np, int id) memset(&pdata, 0, sizeof(pdata)); - prop = of_get_property(np, "timeout", NULL); - if (!prop) - return -ENODEV; - pdata.timeout = *prop; + pdata.timeout = 10; /* Default: 10 seconds */ np = of_get_parent(np); if (!np) @@ -441,38 +425,64 @@ error: static int __init mv64x60_device_setup(void) { - struct device_node *np = NULL; - int id; + struct device_node *np, *np2; + struct platform_device *pdev; + int id, id2; int err; id = 0; - for_each_compatible_node(np, "serial", "marvell,mpsc") - if ((err = mv64x60_mpsc_device_setup(np, id++))) - goto error; + for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc") { + err = mv64x60_mpsc_device_setup(np, id++); + if (err) + printk(KERN_ERR "Failed to initialize MV64x60 " + "serial device %s: error %d.\n", + np->full_name, err); + } id = 0; - for_each_compatible_node(np, "network", "marvell,mv64x60-eth") - if ((err = mv64x60_eth_device_setup(np, id++))) - goto error; + id2 = 0; + for_each_compatible_node(np, NULL, "marvell,mv64360-eth-group") { + pdev = mv64x60_eth_register_shared_pdev(np, id++); + if (IS_ERR(pdev)) { + err = PTR_ERR(pdev); + printk(KERN_ERR "Failed to initialize MV64x60 " + "network block %s: error %d.\n", + np->full_name, err); + continue; + } + for_each_child_of_node(np, np2) { + if (!of_device_is_compatible(np2, + "marvell,mv64360-eth")) + continue; + err = mv64x60_eth_device_setup(np2, id2++, pdev); + if (err) + printk(KERN_ERR "Failed to initialize " + "MV64x60 network device %s: " + "error %d.\n", + np2->full_name, err); + } + } id = 0; - for_each_compatible_node(np, "i2c", "marvell,mv64x60-i2c") - if ((err = mv64x60_i2c_device_setup(np, id++))) - goto error; + for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c") { + err = mv64x60_i2c_device_setup(np, id++); + if (err) + printk(KERN_ERR "Failed to initialize MV64x60 I2C " + "bus %s: error %d.\n", + np->full_name, err); + } /* support up to one watchdog timer */ - np = of_find_compatible_node(np, NULL, "marvell,mv64x60-wdt"); + np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt"); if (np) { if ((err = mv64x60_wdt_device_setup(np, id))) - goto error; + printk(KERN_ERR "Failed to initialize MV64x60 " + "Watchdog %s: error %d.\n", + np->full_name, err); of_node_put(np); } return 0; - -error: - of_node_put(np); - return err; } arch_initcall(mv64x60_device_setup); @@ -489,10 +499,10 @@ static int __init mv64x60_add_mpsc_console(void) if (!np) goto not_mpsc; - if (!of_device_is_compatible(np, "marvell,mpsc")) + if (!of_device_is_compatible(np, "marvell,mv64360-mpsc")) goto not_mpsc; - prop = of_get_property(np, "block-index", NULL); + prop = of_get_property(np, "cell-index", NULL); if (!prop) goto not_mpsc; diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index d21ab8fa499..1456015a22d 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c @@ -86,14 +86,14 @@ static int __init mv64x60_sysfs_init(void) struct platform_device *pdev; const unsigned int *prop; - np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60"); + np = of_find_compatible_node(NULL, NULL, "marvell,mv64360"); if (!np) return 0; prop = of_get_property(np, "hs_reg_valid", NULL); of_node_put(np); - pdev = platform_device_register_simple("marvell,mv64x60", 0, NULL, 0); + pdev = platform_device_register_simple("marvell,mv64360", 0, NULL, 0); if (IS_ERR(pdev)) return PTR_ERR(pdev); @@ -166,6 +166,6 @@ void __init mv64x60_pci_init(void) { struct device_node *np; - for_each_compatible_node(np, "pci", "marvell,mv64x60-pci") + for_each_compatible_node(np, "pci", "marvell,mv64360-pci") mv64x60_add_bridge(np); } diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c index 19e6ef26379..2aa4ed066db 100644 --- a/arch/powerpc/sysdev/mv64x60_pic.c +++ b/arch/powerpc/sysdev/mv64x60_pic.c @@ -238,13 +238,13 @@ void __init mv64x60_init_irq(void) const unsigned int *reg; unsigned long flags; - np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-gpp"); + np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp"); reg = of_get_property(np, "reg", &size); paddr = of_translate_address(np, reg); mv64x60_gpp_reg_base = ioremap(paddr, reg[1]); of_node_put(np); - np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-pic"); + np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-pic"); reg = of_get_property(np, "reg", &size); paddr = of_translate_address(np, reg); mv64x60_irq_reg_base = ioremap(paddr, reg[1]); diff --git a/arch/powerpc/sysdev/mv64x60_udbg.c b/arch/powerpc/sysdev/mv64x60_udbg.c index 35c77c7d061..2792dc8b038 100644 --- a/arch/powerpc/sysdev/mv64x60_udbg.c +++ b/arch/powerpc/sysdev/mv64x60_udbg.c @@ -85,7 +85,7 @@ static void mv64x60_udbg_init(void) if (!stdout) return; - for_each_compatible_node(np, "serial", "marvell,mpsc") { + for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc") { if (np == stdout) break; } @@ -94,7 +94,7 @@ static void mv64x60_udbg_init(void) if (!np) return; - block_index = of_get_property(np, "block-index", NULL); + block_index = of_get_property(np, "cell-index", NULL); if (!block_index) goto error; diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 5abfcd15748..1814adbd223 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -527,6 +527,7 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) * * ibm,plb-pciex-440spe * ibm,plb-pciex-405ex + * ibm,plb-pciex-460ex * * Anything else will be rejected for now as they are all subtly * different unfortunately. @@ -645,7 +646,7 @@ static int __init ppc440spe_pciex_core_init(struct device_node *np) int time_out = 20; /* Set PLL clock receiver to LVPECL */ - mtdcri(SDR0, PESDR0_PLLLCT1, mfdcri(SDR0, PESDR0_PLLLCT1) | 1 << 28); + dcri_clrset(SDR0, PESDR0_PLLLCT1, 0, 1 << 28); /* Shouldn't we do all the calibration stuff etc... here ? */ if (ppc440spe_pciex_check_reset(np)) @@ -659,8 +660,7 @@ static int __init ppc440spe_pciex_core_init(struct device_node *np) } /* De-assert reset of PCIe PLL, wait for lock */ - mtdcri(SDR0, PESDR0_PLLLCT1, - mfdcri(SDR0, PESDR0_PLLLCT1) & ~(1 << 24)); + dcri_clrset(SDR0, PESDR0_PLLLCT1, 1 << 24, 0); udelay(3); while (time_out) { @@ -712,9 +712,8 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1, 0x35000000); } - val = mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET); - mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, - (val & ~(1 << 24 | 1 << 16)) | 1 << 12); + dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, + (1 << 24) | (1 << 16), 1 << 12); return 0; } @@ -775,6 +774,115 @@ static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = .setup_utl = ppc440speB_pciex_init_utl, }; +static int __init ppc460ex_pciex_core_init(struct device_node *np) +{ + /* Nothing to do, return 2 ports */ + return 2; +} + +static int ppc460ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) +{ + u32 val; + u32 utlset1; + + if (port->endpoint) + val = PTYPE_LEGACY_ENDPOINT << 20; + else + val = PTYPE_ROOT_PORT << 20; + + if (port->index == 0) { + val |= LNKW_X1 << 12; + utlset1 = 0x20000000; + } else { + val |= LNKW_X4 << 12; + utlset1 = 0x20101101; + } + + mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); + mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, utlset1); + mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01210000); + + switch (port->index) { + case 0: + mtdcri(SDR0, PESDR0_460EX_L0CDRCTL, 0x00003230); + mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000136); + mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006); + + mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST,0x10000000); + break; + + case 1: + mtdcri(SDR0, PESDR1_460EX_L0CDRCTL, 0x00003230); + mtdcri(SDR0, PESDR1_460EX_L1CDRCTL, 0x00003230); + mtdcri(SDR0, PESDR1_460EX_L2CDRCTL, 0x00003230); + mtdcri(SDR0, PESDR1_460EX_L3CDRCTL, 0x00003230); + mtdcri(SDR0, PESDR1_460EX_L0DRV, 0x00000136); + mtdcri(SDR0, PESDR1_460EX_L1DRV, 0x00000136); + mtdcri(SDR0, PESDR1_460EX_L2DRV, 0x00000136); + mtdcri(SDR0, PESDR1_460EX_L3DRV, 0x00000136); + mtdcri(SDR0, PESDR1_460EX_L0CLK, 0x00000006); + mtdcri(SDR0, PESDR1_460EX_L1CLK, 0x00000006); + mtdcri(SDR0, PESDR1_460EX_L2CLK, 0x00000006); + mtdcri(SDR0, PESDR1_460EX_L3CLK, 0x00000006); + + mtdcri(SDR0, PESDR1_460EX_PHY_CTL_RST,0x10000000); + break; + } + + mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, + mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | + (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN)); + + /* Poll for PHY reset */ + /* XXX FIXME add timeout */ + switch (port->index) { + case 0: + while (!(mfdcri(SDR0, PESDR0_460EX_RSTSTA) & 0x1)) + udelay(10); + break; + case 1: + while (!(mfdcri(SDR0, PESDR1_460EX_RSTSTA) & 0x1)) + udelay(10); + break; + } + + mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, + (mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) & + ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) | + PESDRx_RCSSET_RSTPYN); + + port->has_ibpre = 1; + + return 0; +} + +static int ppc460ex_pciex_init_utl(struct ppc4xx_pciex_port *port) +{ + dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0); + + /* + * Set buffer allocations and then assert VRB and TXE. + */ + out_be32(port->utl_base + PEUTL_PBCTL, 0x0800000c); + out_be32(port->utl_base + PEUTL_OUTTR, 0x08000000); + out_be32(port->utl_base + PEUTL_INTR, 0x02000000); + out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000); + out_be32(port->utl_base + PEUTL_PBBSZ, 0x00000000); + out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000); + out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000); + out_be32(port->utl_base + PEUTL_RCIRQEN,0x00f00000); + out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); + + return 0; +} + +static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = +{ + .core_init = ppc460ex_pciex_core_init, + .port_init_hw = ppc460ex_pciex_init_port_hw, + .setup_utl = ppc460ex_pciex_init_utl, +}; + #endif /* CONFIG_44x */ #ifdef CONFIG_40x @@ -830,17 +938,9 @@ static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) * PCIe boards don't show this problem. * This has to be re-tested and fixed in a later release! */ -#if 0 /* XXX FIXME: Not resetting the PHY will leave all resources - * configured as done previously by U-Boot. Then Linux will currently - * not reassign them. So the PHY reset is now done always. This will - * lead to problems with the Atheros PCIe board again. - */ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP); if (!(val & 0x00001000)) ppc405ex_pcie_phy_reset(port); -#else - ppc405ex_pcie_phy_reset(port); -#endif dcr_write(port->dcrs, DCRO_PEGPL_CFG, 0x10000000); /* guarded on */ @@ -896,6 +996,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) else ppc4xx_pciex_hwops = &ppc440speB_pcie_hwops; } + if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) + ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; #endif /* CONFIG_44x */ #ifdef CONFIG_40x if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) @@ -1042,8 +1144,7 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) port->link = 0; } - mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, - mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | 1 << 20); + dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, 0, 1 << 20); msleep(100); return 0; diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index 1c07908dc6e..d04e40b306f 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h @@ -271,6 +271,59 @@ #define PESDR1_405EX_PHYSTA 0x044C /* + * 460EX additional DCRs + */ +#define PESDR0_460EX_L0BIST 0x0308 +#define PESDR0_460EX_L0BISTSTS 0x0309 +#define PESDR0_460EX_L0CDRCTL 0x030A +#define PESDR0_460EX_L0DRV 0x030B +#define PESDR0_460EX_L0REC 0x030C +#define PESDR0_460EX_L0LPB 0x030D +#define PESDR0_460EX_L0CLK 0x030E +#define PESDR0_460EX_PHY_CTL_RST 0x030F +#define PESDR0_460EX_RSTSTA 0x0310 +#define PESDR0_460EX_OBS 0x0311 +#define PESDR0_460EX_L0ERRC 0x0320 + +#define PESDR1_460EX_L0BIST 0x0348 +#define PESDR1_460EX_L1BIST 0x0349 +#define PESDR1_460EX_L2BIST 0x034A +#define PESDR1_460EX_L3BIST 0x034B +#define PESDR1_460EX_L0BISTSTS 0x034C +#define PESDR1_460EX_L1BISTSTS 0x034D +#define PESDR1_460EX_L2BISTSTS 0x034E +#define PESDR1_460EX_L3BISTSTS 0x034F +#define PESDR1_460EX_L0CDRCTL 0x0350 +#define PESDR1_460EX_L1CDRCTL 0x0351 +#define PESDR1_460EX_L2CDRCTL 0x0352 +#define PESDR1_460EX_L3CDRCTL 0x0353 +#define PESDR1_460EX_L0DRV 0x0354 +#define PESDR1_460EX_L1DRV 0x0355 +#define PESDR1_460EX_L2DRV 0x0356 +#define PESDR1_460EX_L3DRV 0x0357 +#define PESDR1_460EX_L0REC 0x0358 +#define PESDR1_460EX_L1REC 0x0359 +#define PESDR1_460EX_L2REC 0x035A +#define PESDR1_460EX_L3REC 0x035B +#define PESDR1_460EX_L0LPB 0x035C +#define PESDR1_460EX_L1LPB 0x035D +#define PESDR1_460EX_L2LPB 0x035E +#define PESDR1_460EX_L3LPB 0x035F +#define PESDR1_460EX_L0CLK 0x0360 +#define PESDR1_460EX_L1CLK 0x0361 +#define PESDR1_460EX_L2CLK 0x0362 +#define PESDR1_460EX_L3CLK 0x0363 +#define PESDR1_460EX_PHY_CTL_RST 0x0364 +#define PESDR1_460EX_RSTSTA 0x0365 +#define PESDR1_460EX_OBS 0x0366 +#define PESDR1_460EX_L0ERRC 0x0368 +#define PESDR1_460EX_L1ERRC 0x0369 +#define PESDR1_460EX_L2ERRC 0x036A +#define PESDR1_460EX_L3ERRC 0x036B +#define PESDR0_460EX_IHS1 0x036C +#define PESDR0_460EX_IHS2 0x036D + +/* * Of the above, some are common offsets from the base */ #define PESDRn_UTLSET1 0x00 @@ -353,6 +406,12 @@ #define PECFG_POM2LAL 0x390 #define PECFG_POM2LAH 0x394 +/* SDR Bit Mappings */ +#define PESDRx_RCSSET_HLDPLB 0x10000000 +#define PESDRx_RCSSET_RSTGU 0x01000000 +#define PESDRx_RCSSET_RDY 0x00100000 +#define PESDRx_RCSSET_RSTDL 0x00010000 +#define PESDRx_RCSSET_RSTPYN 0x00001000 enum { diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c new file mode 100644 index 00000000000..5b32adc9a9b --- /dev/null +++ b/arch/powerpc/sysdev/ppc4xx_soc.c @@ -0,0 +1,200 @@ +/* + * IBM/AMCC PPC4xx SoC setup code + * + * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de> + * + * L2 cache routines cloned from arch/ppc/syslib/ibm440gx_common.c which is: + * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> + * Copyright (c) 2003 - 2006 Zultys Technologies + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/of_platform.h> + +#include <asm/dcr.h> +#include <asm/dcr-regs.h> +#include <asm/reg.h> + +static u32 dcrbase_l2c; + +/* + * L2-cache + */ + +/* Issue L2C diagnostic command */ +static inline u32 l2c_diag(u32 addr) +{ + mtdcr(dcrbase_l2c + DCRN_L2C0_ADDR, addr); + mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_DIAG); + while (!(mfdcr(dcrbase_l2c + DCRN_L2C0_SR) & L2C_SR_CC)) + ; + + return mfdcr(dcrbase_l2c + DCRN_L2C0_DATA); +} + +static irqreturn_t l2c_error_handler(int irq, void *dev) +{ + u32 sr = mfdcr(dcrbase_l2c + DCRN_L2C0_SR); + + if (sr & L2C_SR_CPE) { + /* Read cache trapped address */ + u32 addr = l2c_diag(0x42000000); + printk(KERN_EMERG "L2C: Cache Parity Error, addr[16:26] = 0x%08x\n", + addr); + } + if (sr & L2C_SR_TPE) { + /* Read tag trapped address */ + u32 addr = l2c_diag(0x82000000) >> 16; + printk(KERN_EMERG "L2C: Tag Parity Error, addr[16:26] = 0x%08x\n", + addr); + } + + /* Clear parity errors */ + if (sr & (L2C_SR_CPE | L2C_SR_TPE)){ + mtdcr(dcrbase_l2c + DCRN_L2C0_ADDR, 0); + mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE); + } else { + printk(KERN_EMERG "L2C: LRU error\n"); + } + + return IRQ_HANDLED; +} + +static int __init ppc4xx_l2c_probe(void) +{ + struct device_node *np; + u32 r; + unsigned long flags; + int irq; + const u32 *dcrreg; + u32 dcrbase_isram; + int len; + const u32 *prop; + u32 l2_size; + + np = of_find_compatible_node(NULL, NULL, "ibm,l2-cache"); + if (!np) + return 0; + + /* Get l2 cache size */ + prop = of_get_property(np, "cache-size", NULL); + if (prop == NULL) { + printk(KERN_ERR "%s: Can't get cache-size!\n", np->full_name); + of_node_put(np); + return -ENODEV; + } + l2_size = prop[0]; + + /* Map DCRs */ + dcrreg = of_get_property(np, "dcr-reg", &len); + if (!dcrreg || (len != 4 * sizeof(u32))) { + printk(KERN_ERR "%s: Can't get DCR register base !", + np->full_name); + of_node_put(np); + return -ENODEV; + } + dcrbase_isram = dcrreg[0]; + dcrbase_l2c = dcrreg[2]; + + /* Get and map irq number from device tree */ + irq = irq_of_parse_and_map(np, 0); + if (irq == NO_IRQ) { + printk(KERN_ERR "irq_of_parse_and_map failed\n"); + of_node_put(np); + return -ENODEV; + } + + /* Install error handler */ + if (request_irq(irq, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0) { + printk(KERN_ERR "Cannot install L2C error handler" + ", cache is not enabled\n"); + of_node_put(np); + return -ENODEV; + } + + local_irq_save(flags); + asm volatile ("sync" ::: "memory"); + + /* Disable SRAM */ + mtdcr(dcrbase_isram + DCRN_SRAM0_DPC, + mfdcr(dcrbase_isram + DCRN_SRAM0_DPC) & ~SRAM_DPC_ENABLE); + mtdcr(dcrbase_isram + DCRN_SRAM0_SB0CR, + mfdcr(dcrbase_isram + DCRN_SRAM0_SB0CR) & ~SRAM_SBCR_BU_MASK); + mtdcr(dcrbase_isram + DCRN_SRAM0_SB1CR, + mfdcr(dcrbase_isram + DCRN_SRAM0_SB1CR) & ~SRAM_SBCR_BU_MASK); + mtdcr(dcrbase_isram + DCRN_SRAM0_SB2CR, + mfdcr(dcrbase_isram + DCRN_SRAM0_SB2CR) & ~SRAM_SBCR_BU_MASK); + mtdcr(dcrbase_isram + DCRN_SRAM0_SB3CR, + mfdcr(dcrbase_isram + DCRN_SRAM0_SB3CR) & ~SRAM_SBCR_BU_MASK); + + /* Enable L2_MODE without ICU/DCU */ + r = mfdcr(dcrbase_l2c + DCRN_L2C0_CFG) & + ~(L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_SS_MASK); + r |= L2C_CFG_L2M | L2C_CFG_SS_256; + mtdcr(dcrbase_l2c + DCRN_L2C0_CFG, r); + + mtdcr(dcrbase_l2c + DCRN_L2C0_ADDR, 0); + + /* Hardware Clear Command */ + mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_HCC); + while (!(mfdcr(dcrbase_l2c + DCRN_L2C0_SR) & L2C_SR_CC)) + ; + + /* Clear Cache Parity and Tag Errors */ + mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE); + + /* Enable 64G snoop region starting at 0 */ + r = mfdcr(dcrbase_l2c + DCRN_L2C0_SNP0) & + ~(L2C_SNP_BA_MASK | L2C_SNP_SSR_MASK); + r |= L2C_SNP_SSR_32G | L2C_SNP_ESR; + mtdcr(dcrbase_l2c + DCRN_L2C0_SNP0, r); + + r = mfdcr(dcrbase_l2c + DCRN_L2C0_SNP1) & + ~(L2C_SNP_BA_MASK | L2C_SNP_SSR_MASK); + r |= 0x80000000 | L2C_SNP_SSR_32G | L2C_SNP_ESR; + mtdcr(dcrbase_l2c + DCRN_L2C0_SNP1, r); + + asm volatile ("sync" ::: "memory"); + + /* Enable ICU/DCU ports */ + r = mfdcr(dcrbase_l2c + DCRN_L2C0_CFG); + r &= ~(L2C_CFG_DCW_MASK | L2C_CFG_PMUX_MASK | L2C_CFG_PMIM + | L2C_CFG_TPEI | L2C_CFG_CPEI | L2C_CFG_NAM | L2C_CFG_NBRM); + r |= L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_TPC | L2C_CFG_CPC | L2C_CFG_FRAN + | L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM; + + /* Check for 460EX/GT special handling */ + if (of_device_is_compatible(np, "ibm,l2-cache-460ex")) + r |= L2C_CFG_RDBW; + + mtdcr(dcrbase_l2c + DCRN_L2C0_CFG, r); + + asm volatile ("sync; isync" ::: "memory"); + local_irq_restore(flags); + + printk(KERN_INFO "%dk L2-cache enabled\n", l2_size >> 10); + + of_node_put(np); + return 0; +} +arch_initcall(ppc4xx_l2c_probe); + +/* + * At present, this routine just applies a system reset. + */ +void ppc4xx_reset_system(char *cmd) +{ + mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_RST_SYSTEM); + while (1) + ; /* Just in case the reset doesn't work */ +} diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index cc81fd1141b..cff550eec7e 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -55,7 +55,7 @@ struct qe_snum { /* We allocate this here because it is used almost exclusively for * the communication processor devices. */ -struct qe_immap *qe_immr = NULL; +struct qe_immap __iomem *qe_immr; EXPORT_SYMBOL(qe_immr); static struct qe_snum snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */ @@ -156,7 +156,7 @@ EXPORT_SYMBOL(qe_issue_cmd); */ static unsigned int brg_clk = 0; -unsigned int get_brg_clk(void) +unsigned int qe_get_brg_clk(void) { struct device_node *qe; unsigned int size; @@ -180,6 +180,7 @@ unsigned int get_brg_clk(void) return brg_clk; } +EXPORT_SYMBOL(qe_get_brg_clk); /* Program the BRG to the given sampling rate and multiplier * @@ -197,7 +198,7 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier) if ((brg < QE_BRG1) || (brg > QE_BRG16)) return -EINVAL; - divisor = get_brg_clk() / (rate * multiplier); + divisor = qe_get_brg_clk() / (rate * multiplier); if (divisor > QE_BRGC_DIVISOR_MAX + 1) { div16 = QE_BRGC_DIV16; @@ -415,12 +416,6 @@ void qe_muram_dump(void) } EXPORT_SYMBOL(qe_muram_dump); -void *qe_muram_addr(unsigned long offset) -{ - return (void *)&qe_immr->muram[offset]; -} -EXPORT_SYMBOL(qe_muram_addr); - /* The maximum number of RISCs we support */ #define MAX_QE_RISC 2 diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c index e53ea4d374a..93916a48afe 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_io.c +++ b/arch/powerpc/sysdev/qe_lib/qe_io.c @@ -22,6 +22,7 @@ #include <linux/ioport.h> #include <asm/io.h> +#include <asm/qe.h> #include <asm/prom.h> #include <sysdev/fsl_soc.h> @@ -41,7 +42,7 @@ struct port_regs { #endif }; -static struct port_regs *par_io = NULL; +static struct port_regs __iomem *par_io; static int num_par_io_ports = 0; int par_io_init(struct device_node *np) @@ -165,7 +166,7 @@ int par_io_of_config(struct device_node *np) } ph = of_get_property(np, "pio-handle", NULL); - if (ph == 0) { + if (ph == NULL) { printk(KERN_ERR "pio-handle not available \n"); return -1; } @@ -200,7 +201,7 @@ static void dump_par_io(void) { unsigned int i; - printk(KERN_INFO "%s: par_io=%p\n", __FUNCTION__, par_io); + printk(KERN_INFO "%s: par_io=%p\n", __func__, par_io); for (i = 0; i < num_par_io_ports; i++) { printk(KERN_INFO " cpodr[%u]=%08x\n", i, in_be32(&par_io[i].cpodr)); diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c index 3223acbc39e..bcf88e6ce96 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c @@ -148,57 +148,57 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc /* check if the UCC port number is in range. */ if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { - printk(KERN_ERR "%s: illegal UCC number\n", __FUNCTION__); + printk(KERN_ERR "%s: illegal UCC number\n", __func__); return -EINVAL; } /* Check that 'max_rx_buf_length' is properly aligned (4). */ if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) { printk(KERN_ERR "%s: max_rx_buf_length not aligned\n", - __FUNCTION__); + __func__); return -EINVAL; } /* Validate Virtual Fifo register values */ if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) { - printk(KERN_ERR "%s: urfs is too small\n", __FUNCTION__); + printk(KERN_ERR "%s: urfs is too small\n", __func__); return -EINVAL; } if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { - printk(KERN_ERR "%s: urfs is not aligned\n", __FUNCTION__); + printk(KERN_ERR "%s: urfs is not aligned\n", __func__); return -EINVAL; } if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { - printk(KERN_ERR "%s: urfet is not aligned.\n", __FUNCTION__); + printk(KERN_ERR "%s: urfet is not aligned.\n", __func__); return -EINVAL; } if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { - printk(KERN_ERR "%s: urfset is not aligned\n", __FUNCTION__); + printk(KERN_ERR "%s: urfset is not aligned\n", __func__); return -EINVAL; } if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { - printk(KERN_ERR "%s: utfs is not aligned\n", __FUNCTION__); + printk(KERN_ERR "%s: utfs is not aligned\n", __func__); return -EINVAL; } if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { - printk(KERN_ERR "%s: utfet is not aligned\n", __FUNCTION__); + printk(KERN_ERR "%s: utfet is not aligned\n", __func__); return -EINVAL; } if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { - printk(KERN_ERR "%s: utftt is not aligned\n", __FUNCTION__); + printk(KERN_ERR "%s: utftt is not aligned\n", __func__); return -EINVAL; } uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); if (!uccf) { printk(KERN_ERR "%s: Cannot allocate private data\n", - __FUNCTION__); + __func__); return -ENOMEM; } @@ -207,7 +207,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc /* Set the PHY base address */ uccf->uf_regs = ioremap(uf_info->regs, sizeof(struct ucc_fast)); if (uccf->uf_regs == NULL) { - printk(KERN_ERR "%s: Cannot map UCC registers\n", __FUNCTION__); + printk(KERN_ERR "%s: Cannot map UCC registers\n", __func__); return -ENOMEM; } @@ -230,7 +230,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc /* Set UCC to fast type */ ret = ucc_set_type(uf_info->ucc_num, UCC_SPEED_TYPE_FAST); if (ret) { - printk(KERN_ERR "%s: cannot set UCC type\n", __FUNCTION__); + printk(KERN_ERR "%s: cannot set UCC type\n", __func__); ucc_fast_free(uccf); return ret; } @@ -270,7 +270,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); if (IS_ERR_VALUE(uccf->ucc_fast_tx_virtual_fifo_base_offset)) { printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO\n", - __FUNCTION__); + __func__); uccf->ucc_fast_tx_virtual_fifo_base_offset = 0; ucc_fast_free(uccf); return -ENOMEM; @@ -283,7 +283,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); if (IS_ERR_VALUE(uccf->ucc_fast_rx_virtual_fifo_base_offset)) { printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO\n", - __FUNCTION__); + __func__); uccf->ucc_fast_rx_virtual_fifo_base_offset = 0; ucc_fast_free(uccf); return -ENOMEM; @@ -314,7 +314,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->rx_clock, COMM_DIR_RX)) { printk(KERN_ERR "%s: illegal value for RX clock\n", - __FUNCTION__); + __func__); ucc_fast_free(uccf); return -EINVAL; } @@ -323,7 +323,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->tx_clock, COMM_DIR_TX)) { printk(KERN_ERR "%s: illegal value for TX clock\n", - __FUNCTION__); + __func__); ucc_fast_free(uccf); return -EINVAL; } diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c index b2870b208dd..a578bc77b9d 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c @@ -142,7 +142,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc /* check if the UCC port number is in range. */ if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) { - printk(KERN_ERR "%s: illegal UCC number\n", __FUNCTION__); + printk(KERN_ERR "%s: illegal UCC number\n", __func__); return -EINVAL; } @@ -161,7 +161,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); if (!uccs) { printk(KERN_ERR "%s: Cannot allocate private data\n", - __FUNCTION__); + __func__); return -ENOMEM; } @@ -170,7 +170,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc /* Set the PHY base address */ uccs->us_regs = ioremap(us_info->regs, sizeof(struct ucc_slow)); if (uccs->us_regs == NULL) { - printk(KERN_ERR "%s: Cannot map UCC registers\n", __FUNCTION__); + printk(KERN_ERR "%s: Cannot map UCC registers\n", __func__); return -ENOMEM; } @@ -189,7 +189,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc uccs->us_pram_offset = qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM); if (IS_ERR_VALUE(uccs->us_pram_offset)) { - printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __FUNCTION__); + printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __func__); ucc_slow_free(uccs); return -ENOMEM; } @@ -202,7 +202,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc /* Set UCC to slow type */ ret = ucc_set_type(us_info->ucc_num, UCC_SPEED_TYPE_SLOW); if (ret) { - printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__); + printk(KERN_ERR "%s: cannot set UCC type", __func__); ucc_slow_free(uccs); return ret; } @@ -216,7 +216,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd), QE_ALIGNMENT_OF_BD); if (IS_ERR_VALUE(uccs->rx_base_offset)) { - printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __FUNCTION__, + printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __func__, us_info->rx_bd_ring_len); uccs->rx_base_offset = 0; ucc_slow_free(uccs); @@ -227,7 +227,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd), QE_ALIGNMENT_OF_BD); if (IS_ERR_VALUE(uccs->tx_base_offset)) { - printk(KERN_ERR "%s: cannot allocate TX BDs", __FUNCTION__); + printk(KERN_ERR "%s: cannot allocate TX BDs", __func__); uccs->tx_base_offset = 0; ucc_slow_free(uccs); return -ENOMEM; @@ -317,7 +317,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX)) { printk(KERN_ERR "%s: illegal value for RX clock\n", - __FUNCTION__); + __func__); ucc_slow_free(uccs); return -EINVAL; } @@ -325,7 +325,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->tx_clock, COMM_DIR_TX)) { printk(KERN_ERR "%s: illegal value for TX clock\n", - __FUNCTION__); + __func__); ucc_slow_free(uccs); return -EINVAL; } diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c index 0c9ac7ee08f..c09ddc0dbeb 100644 --- a/arch/powerpc/sysdev/rtc_cmos_setup.c +++ b/arch/powerpc/sysdev/rtc_cmos_setup.c @@ -56,3 +56,5 @@ static int __init add_rtc(void) return 0; } fs_initcall(add_rtc); + +MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c index be2808a292f..d4d15aaf18f 100644 --- a/arch/powerpc/sysdev/tsi108_dev.c +++ b/arch/powerpc/sysdev/tsi108_dev.c @@ -84,7 +84,7 @@ static int __init tsi108_eth_of_init(void) ret = of_address_to_resource(np, 0, &r[0]); DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", - __FUNCTION__,r[0].name, r[0].start, r[0].end); + __func__,r[0].name, r[0].start, r[0].end); if (ret) goto err; @@ -93,7 +93,7 @@ static int __init tsi108_eth_of_init(void) r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", - __FUNCTION__,r[1].name, r[1].start, r[1].end); + __func__,r[1].name, r[1].start, r[1].end); tsi_eth_dev = platform_device_register_simple("tsi-ethernet", i++, &r[0], diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 31d3d33d91f..ac1a72dc21e 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -207,7 +207,7 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary) /* PCI Config mapping */ tsi108_pci_cfg_base = (u32)ioremap(cfg_phys, TSI108_PCI_CFG_SIZE); tsi108_pci_cfg_phys = cfg_phys; - DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, + DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __func__, tsi108_pci_cfg_base); /* Fetch host bridge registers address */ @@ -395,7 +395,7 @@ static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct, static int pci_irq_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { unsigned int irq; - DBG("%s(%d, 0x%lx)\n", __FUNCTION__, virq, hw); + DBG("%s(%d, 0x%lx)\n", __func__, virq, hw); if ((virq >= 1) && (virq <= 4)){ irq = virq + IRQ_PCI_INTAD_BASE - 1; get_irq_desc(irq)->status |= IRQ_LEVEL; |