diff options
Diffstat (limited to 'arch/powerpc/sysdev/cpm2.c')
| -rw-r--r-- | arch/powerpc/sysdev/cpm2.c | 165 |
1 files changed, 33 insertions, 132 deletions
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c index dd066bb1d56..8dc1e24f3c2 100644 --- a/arch/powerpc/sysdev/cpm2.c +++ b/arch/powerpc/sysdev/cpm2.c @@ -46,16 +46,13 @@ #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 * the communication processor devices. */ cpm2_map_t __iomem *cpm2_immr; +EXPORT_SYMBOL(cpm2_immr); #define CPM_MAP_SIZE (0x40000) /* 256k - the PQ3 reserve this amount of space for CPM as it is larger @@ -64,22 +61,24 @@ cpm2_map_t __iomem *cpm2_immr; void __init cpm2_reset(void) { #ifdef CONFIG_PPC_85xx - cpm2_immr = ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE); + cpm2_immr = ioremap(get_immrbase() + 0x80000, CPM_MAP_SIZE); #else cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE); #endif /* 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 +98,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); @@ -117,16 +116,10 @@ EXPORT_SYMBOL(cpm_command); * Baud rate clocks are zero-based in the driver code (as that maps * to port numbers). Documentation uses 1-based numbering. */ -#define BRG_INT_CLK (get_brgfreq()) -#define BRG_UART_CLK (BRG_INT_CLK/16) - -/* This function is used by UARTS, or anything else that uses a 16x - * oversampled clock. - */ -void -cpm_setbrg(uint brg, uint rate) +void __cpm2_setbrg(uint brg, uint rate, uint clk, int div16, int src) { u32 __iomem *bp; + u32 val; /* This is good enough to get SMCs running..... */ @@ -137,34 +130,15 @@ cpm_setbrg(uint brg, uint rate) brg -= 4; } bp += brg; - out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN); - - cpm2_unmap(bp); -} - -/* This function is used to set high speed synchronous baud rate - * clocks. - */ -void -cpm2_fastbrg(uint brg, uint rate, int div16) -{ - u32 __iomem *bp; - u32 val; - - if (brg < 4) { - bp = cpm2_map_size(im_brgc1, 16); - } else { - bp = cpm2_map_size(im_brgc5, 16); - brg -= 4; - } - bp += brg; - val = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN; + /* Round the clock divider to the nearest integer. */ + val = (((clk * 2 / rate) - 1) & ~1) | CPM_BRG_EN | src; if (div16) val |= CPM_BRG_DIV16; out_be32(bp, val); cpm2_unmap(bp); } +EXPORT_SYMBOL(__cpm2_setbrg); int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) { @@ -270,9 +244,6 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) return -EINVAL; } - if (mode == CPM_CLK_RX) - shift += 3; - for (i = 0; i < ARRAY_SIZE(clk_map); i++) { if (clk_map[i][0] == target && clk_map[i][1] == clock) { bits = clk_map[i][2]; @@ -285,6 +256,14 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) bits <<= shift; mask <<= shift; + if (mode == CPM_CLK_RTX) { + bits |= bits << 3; + mask |= mask << 3; + } else if (mode == CPM_CLK_RX) { + bits <<= 3; + mask <<= 3; + } + out_be32(reg, (in_be32(reg) & ~mask) | bits); cpm2_unmap(im_cpmux); @@ -347,95 +326,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]; @@ -468,3 +358,14 @@ void cpm2_set_pin(int port, int pin, int flags) else clrbits32(&iop[port].odr, pin); } + +static int cpm_init_par_io(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "fsl,cpm2-pario-bank") + cpm2_gpiochip_add32(np); + return 0; +} +arch_initcall(cpm_init_par_io); + |
