From 3dd0dcbe9dc5c116df96989c42a062951b644e04 Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Thu, 21 Sep 2006 17:27:15 +0400 Subject: cpm_uart: make it possible to utilize from powerpc Driver core has been updated to make use of the new powerpc OF-inspired platform devices, yet keeping compatibility to the vast board list from ppc. Signed-off-by: Vitaly Bordug --- drivers/serial/cpm_uart/cpm_uart_core.c | 11 ++++------- drivers/serial/cpm_uart/cpm_uart_cpm2.c | 13 +++++++------ 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers/serial') diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 90ff96e3339b..dfa06b644957 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -46,6 +46,7 @@ #include #include #include +#include #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ @@ -1044,11 +1045,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"))) return -EINVAL; - mem = r->start; + mem = (u32)ioremap(r->start, r->end - r->start + 1); if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"))) return -EINVAL; - pram = r->start; + pram = (u32)ioremap(r->start, r->end - r->start + 1); if(idx > fsid_smc2_uart) { pinfo->sccp = (scc_t *)mem; @@ -1189,11 +1190,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) if (options) { uart_parse_options(options, &baud, &parity, &bits, &flow); } else { - bd_t *bd = (bd_t *) __res; - - if (bd->bi_baudrate) - baud = bd->bi_baudrate; - else + if ((baud = uart_baudrate()) == -1) baud = 9600; } diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index ef3bb476c432..02b9ef9abd3f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -266,7 +267,7 @@ int cpm_uart_init_portdesc(void) (unsigned long)&cpm2_immr->im_smc[0]; cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1; #endif @@ -279,7 +280,7 @@ int cpm_uart_init_portdesc(void) (unsigned long)&cpm2_immr->im_smc[1]; cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2; #endif @@ -293,7 +294,7 @@ int cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock(); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1; #endif @@ -307,7 +308,7 @@ int cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock(); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2; #endif @@ -321,7 +322,7 @@ int cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock(); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3; #endif @@ -335,7 +336,7 @@ int cpm_uart_init_portdesc(void) ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq); + cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock(); cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4; #endif -- cgit v1.2.3 From fc8e50e349aa722d9f97ed9ba30e324ede8fa408 Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Thu, 21 Sep 2006 22:37:58 +0400 Subject: POWERPC: Get rid of remapping the whole immr The stuff below cleans up the code attempting to remap the whole cpm2_immr early, as well as places happily assuming that fact. This is more like the 2.4 legacy stuff, and is at least confusing and unclear now. To keep the world comfortable, a new mechanism is introduced: before accessing specific immr register/register set, one needs to map it, using cpm2_map(), for instance, access to CPM command register will look like volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); keeping the code clear, yet without "already defined somewhere" cpm2_immr. So far, unmapping code is not implemented, but it's not a big deal to add it, if the whole idea makes sense. Signed-off-by: Vitaly Bordug --- arch/powerpc/sysdev/cpm2_common.c | 19 +++-- arch/powerpc/sysdev/cpm2_pic.c | 34 ++++----- arch/powerpc/sysdev/cpm2_pic.h | 2 + arch/powerpc/sysdev/fsl_soc.c | 2 +- drivers/serial/cpm_uart/cpm_uart_cpm2.c | 130 +++++++++++++++++++++----------- drivers/serial/cpm_uart/cpm_uart_cpm2.h | 2 +- include/asm-powerpc/fs_pd.h | 18 +++++ include/asm-ppc/cpm2.h | 4 + include/asm-ppc/fs_pd.h | 4 + 9 files changed, 148 insertions(+), 67 deletions(-) (limited to 'drivers/serial') diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c index f7a04892400b..73376f9c1560 100644 --- a/arch/powerpc/sysdev/cpm2_common.c +++ b/arch/powerpc/sysdev/cpm2_common.c @@ -51,6 +51,7 @@ cpm_cpm2_t *cpmp; /* Pointer to comm processor space */ * the communication processor devices. */ cpm2_map_t *cpm2_immr; +intctl_cpm2_t *cpm2_intctl; #define CPM_MAP_SIZE (0x40000) /* 256k - the PQ3 reserve this amount of space for CPM as it is larger @@ -60,6 +61,7 @@ void cpm2_reset(void) { cpm2_immr = (cpm2_map_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE); + cpm2_intctl = cpm2_map(im_intctl); /* Reclaim the DP memory for our use. */ @@ -94,13 +96,15 @@ cpm_setbrg(uint brg, uint rate) /* This is good enough to get SMCs running..... */ if (brg < 4) { - bp = (uint *)&cpm2_immr->im_brgc1; + bp = cpm2_map_size(im_brgc1, 16); } else { - bp = (uint *)&cpm2_immr->im_brgc5; + bp = cpm2_map_size(im_brgc5, 16); brg -= 4; } bp += brg; *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN; + + cpm2_unmap(bp); } /* This function is used to set high speed synchronous baud rate @@ -112,16 +116,18 @@ cpm2_fastbrg(uint brg, uint rate, int div16) volatile uint *bp; if (brg < 4) { - bp = (uint *)&cpm2_immr->im_brgc1; + bp = cpm2_map_size(im_brgc1, 16); } else { - bp = (uint *)&cpm2_immr->im_brgc5; + bp = cpm2_map_size(im_brgc5, 16); brg -= 4; } bp += brg; *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN; if (div16) *bp |= CPM_BRG_DIV16; + + cpm2_unmap(bp); } /* @@ -132,11 +138,14 @@ static spinlock_t cpm_dpmem_lock; * 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* im_dprambase; static void cpm2_dpinit(void) { spin_lock_init(&cpm_dpmem_lock); + im_dprambase = ioremap(CPM_MAP_ADDR, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE); + /* initialize the info header */ rh_init(&cpm_dpmem_info, 1, sizeof(cpm_boot_dpmem_rh_block) / @@ -205,6 +214,6 @@ EXPORT_SYMBOL(cpm_dpdump); void *cpm_dpram_addr(uint offset) { - return (void *)&cpm2_immr->im_dprambase[offset]; + return (void *)(im_dprambase + offset); } EXPORT_SYMBOL(cpm_dpram_addr); diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index c804475c07d3..51752990f7b9 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -78,7 +78,7 @@ static void cpm2_mask_irq(unsigned int irq_nr) bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; - simr = &(cpm2_immr->im_intctl.ic_simrh); + simr = &(cpm2_intctl->ic_simrh); ppc_cached_irq_mask[word] &= ~(1 << bit); simr[word] = ppc_cached_irq_mask[word]; } @@ -93,7 +93,7 @@ static void cpm2_unmask_irq(unsigned int irq_nr) bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; - simr = &(cpm2_immr->im_intctl.ic_simrh); + simr = &(cpm2_intctl->ic_simrh); ppc_cached_irq_mask[word] |= 1 << bit; simr[word] = ppc_cached_irq_mask[word]; } @@ -108,8 +108,8 @@ static void cpm2_mask_and_ack(unsigned int irq_nr) bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; - simr = &(cpm2_immr->im_intctl.ic_simrh); - sipnr = &(cpm2_immr->im_intctl.ic_sipnrh); + simr = &(cpm2_intctl->ic_simrh); + sipnr = &(cpm2_intctl->ic_sipnrh); ppc_cached_irq_mask[word] &= ~(1 << bit); simr[word] = ppc_cached_irq_mask[word]; sipnr[word] = 1 << bit; @@ -127,7 +127,7 @@ static void cpm2_end_irq(unsigned int irq_nr) bit = irq_to_siubit[irq_nr]; word = irq_to_siureg[irq_nr]; - simr = &(cpm2_immr->im_intctl.ic_simrh); + simr = &(cpm2_intctl->ic_simrh); ppc_cached_irq_mask[word] |= 1 << bit; simr[word] = ppc_cached_irq_mask[word]; /* @@ -152,10 +152,10 @@ int cpm2_get_irq(struct pt_regs *regs) int irq; unsigned long bits; - /* For CPM2, read the SIVEC register and shift the bits down - * to get the irq number.*/ - bits = cpm2_immr->im_intctl.ic_sivec; - irq = bits >> 26; + /* For CPM2, read the SIVEC register and shift the bits down + * to get the irq number. */ + bits = cpm2_intctl->ic_sivec; + irq = bits >> 26; if (irq == 0) return(-1); @@ -223,26 +223,26 @@ void cpm2_pic_init(struct device_node *node) /* Mask out everything */ - cpm2_immr->im_intctl.ic_simrh = 0x00000000; - cpm2_immr->im_intctl.ic_simrl = 0x00000000; + cpm2_intctl->ic_simrh = 0x00000000; + cpm2_intctl->ic_simrl = 0x00000000; wmb(); /* Ack everything */ - cpm2_immr->im_intctl.ic_sipnrh = 0xffffffff; - cpm2_immr->im_intctl.ic_sipnrl = 0xffffffff; + cpm2_intctl->ic_sipnrh = 0xffffffff; + cpm2_intctl->ic_sipnrl = 0xffffffff; wmb(); /* Dummy read of the vector */ - i = cpm2_immr->im_intctl.ic_sivec; + i = cpm2_intctl->ic_sivec; rmb(); /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. */ - cpm2_immr->im_intctl.ic_sicr = 0; - cpm2_immr->im_intctl.ic_scprrh = 0x05309770; - cpm2_immr->im_intctl.ic_scprrl = 0x05309770; + cpm2_intctl->ic_sicr = 0; + cpm2_intctl->ic_scprrh = 0x05309770; + cpm2_intctl->ic_scprrl = 0x05309770; /* create a legacy host */ if (node) diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h index 436cca77db64..d63e45d4df58 100644 --- a/arch/powerpc/sysdev/cpm2_pic.h +++ b/arch/powerpc/sysdev/cpm2_pic.h @@ -1,6 +1,8 @@ #ifndef _PPC_KERNEL_CPM2_H #define _PPC_KERNEL_CPM2_H +extern intctl_cpm2_t *cpm2_intctl; + extern int cpm2_get_irq(struct pt_regs *regs); extern void cpm2_pic_init(struct device_node*); diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 0ed2aaee105c..0b8a03cc3042 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -633,7 +633,7 @@ static int __init fs_enet_of_init(void) if (strstr(model, "FCC")) { int fcc_index = fs_get_fcc_index(*id); - fs_enet_data.dpram_offset = (u32)cpm2_immr->im_dprambase; + 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; diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 02b9ef9abd3f..b691d3e14754 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -51,8 +51,9 @@ void cpm_line_cr_cmd(int line, int cmd) { - volatile cpm_cpm2_t *cp = cpmp; ulong val; + volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); + switch (line) { case UART_SMC1: @@ -85,11 +86,14 @@ void cpm_line_cr_cmd(int line, int cmd) } cp->cp_cpcr = val; while (cp->cp_cpcr & CPM_CR_FLG) ; + + cpm2_unmap(cp); } void smc1_lineif(struct uart_cpm_port *pinfo) { - volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + volatile iop_cpm2_t *io = cpm2_map(im_ioport); + volatile cpmux_t *cpmux = cpm2_map(im_cpmux); /* SMC1 is only on port D */ io->iop_ppard |= 0x00c00000; @@ -98,13 +102,17 @@ void smc1_lineif(struct uart_cpm_port *pinfo) io->iop_psord &= ~0x00c00000; /* Wire BRG1 to SMC1 */ - cpm2_immr->im_cpmux.cmx_smr &= 0x0f; + cpmux->cmx_smr &= 0x0f; pinfo->brg = 1; + + cpm2_unmap(cpmux); + cpm2_unmap(io); } void smc2_lineif(struct uart_cpm_port *pinfo) { - volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + volatile iop_cpm2_t *io = cpm2_map(im_ioport); + volatile cpmux_t *cpmux = cpm2_map(im_cpmux); /* SMC2 is only on port A */ io->iop_ppara |= 0x00c00000; @@ -113,13 +121,17 @@ void smc2_lineif(struct uart_cpm_port *pinfo) io->iop_psora &= ~0x00c00000; /* Wire BRG2 to SMC2 */ - cpm2_immr->im_cpmux.cmx_smr &= 0xf0; + cpmux->cmx_smr &= 0xf0; pinfo->brg = 2; + + cpm2_unmap(cpmux); + cpm2_unmap(io); } void scc1_lineif(struct uart_cpm_port *pinfo) { - volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + volatile iop_cpm2_t *io = cpm2_map(im_ioport); + volatile cpmux_t *cpmux = cpm2_map(im_cpmux); /* Use Port D for SCC1 instead of other functions. */ io->iop_ppard |= 0x00000003; @@ -129,9 +141,12 @@ void scc1_lineif(struct uart_cpm_port *pinfo) io->iop_pdird |= 0x00000002; /* Tx */ /* Wire BRG1 to SCC1 */ - cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff; - cpm2_immr->im_cpmux.cmx_scr |= 0x00000000; + cpmux->cmx_scr &= 0x00ffffff; + cpmux->cmx_scr |= 0x00000000; pinfo->brg = 1; + + cpm2_unmap(cpmux); + cpm2_unmap(io); } void scc2_lineif(struct uart_cpm_port *pinfo) @@ -144,43 +159,57 @@ void scc2_lineif(struct uart_cpm_port *pinfo) * be supported in a sane fashion. */ #ifndef CONFIG_STX_GP3 - volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + volatile iop_cpm2_t *io = cpm2_map(im_ioport); + volatile cpmux_t *cpmux = cpm2_map(im_cpmux); + io->iop_pparb |= 0x008b0000; io->iop_pdirb |= 0x00880000; io->iop_psorb |= 0x00880000; io->iop_pdirb &= ~0x00030000; io->iop_psorb &= ~0x00030000; #endif - cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff; - cpm2_immr->im_cpmux.cmx_scr |= 0x00090000; + cpmux->cmx_scr &= 0xff00ffff; + cpmux->cmx_scr |= 0x00090000; pinfo->brg = 2; + + cpm2_unmap(cpmux); + cpm2_unmap(io); } void scc3_lineif(struct uart_cpm_port *pinfo) { - volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + volatile iop_cpm2_t *io = cpm2_map(im_ioport); + volatile cpmux_t *cpmux = cpm2_map(im_cpmux); + io->iop_pparb |= 0x008b0000; io->iop_pdirb |= 0x00880000; io->iop_psorb |= 0x00880000; io->iop_pdirb &= ~0x00030000; io->iop_psorb &= ~0x00030000; - cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff; - cpm2_immr->im_cpmux.cmx_scr |= 0x00001200; + cpmux->cmx_scr &= 0xffff00ff; + cpmux->cmx_scr |= 0x00001200; pinfo->brg = 3; + + cpm2_unmap(cpmux); + cpm2_unmap(io); } void scc4_lineif(struct uart_cpm_port *pinfo) { - volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; + volatile iop_cpm2_t *io = cpm2_map(im_ioport); + volatile cpmux_t *cpmux = cpm2_map(im_cpmux); io->iop_ppard |= 0x00000600; io->iop_psord &= ~0x00000600; /* Tx/Rx */ io->iop_pdird &= ~0x00000200; /* Rx */ io->iop_pdird |= 0x00000400; /* Tx */ - cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00; - cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b; + cpmux->cmx_scr &= 0xffffff00; + cpmux->cmx_scr |= 0x0000001b; pinfo->brg = 4; + + cpm2_unmap(cpmux); + cpm2_unmap(io); } /* @@ -255,16 +284,23 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) /* Setup any dynamic params in the uart desc */ int cpm_uart_init_portdesc(void) { +#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2) + u32 addr; +#endif pr_debug("CPM uart[-]:init portdesc\n"); cpm_uart_nr = 0; #ifdef CONFIG_SERIAL_CPM_SMC1 - cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0]; - cpm_uart_ports[UART_SMC1].smcup = - (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1]; - *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; + cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]); cpm_uart_ports[UART_SMC1].port.mapbase = - (unsigned long)&cpm2_immr->im_smc[0]; + (unsigned long)cpm_uart_ports[UART_SMC1].smcp; + + cpm_uart_ports[UART_SMC1].smcup = + (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE); + addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2); + *addr = PROFF_SMC1; + cpm2_unmap(addr); + cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock(); @@ -272,12 +308,16 @@ int cpm_uart_init_portdesc(void) #endif #ifdef CONFIG_SERIAL_CPM_SMC2 - cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1]; - cpm_uart_ports[UART_SMC2].smcup = - (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2]; - *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2; + cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]); cpm_uart_ports[UART_SMC2].port.mapbase = - (unsigned long)&cpm2_immr->im_smc[1]; + (unsigned long)cpm_uart_ports[UART_SMC2].smcp; + + cpm_uart_ports[UART_SMC2].smcup = + (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE); + addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2); + *addr = PROFF_SMC2; + cpm2_unmap(addr); + cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX); cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock(); @@ -285,11 +325,12 @@ int cpm_uart_init_portdesc(void) #endif #ifdef CONFIG_SERIAL_CPM_SCC1 - cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0]; - cpm_uart_ports[UART_SCC1].sccup = - (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1]; + cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]); cpm_uart_ports[UART_SCC1].port.mapbase = - (unsigned long)&cpm2_immr->im_scc[0]; + (unsigned long)cpm_uart_ports[UART_SCC1].sccp; + cpm_uart_ports[UART_SCC1].sccup = + (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE); + cpm_uart_ports[UART_SCC1].sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &= @@ -299,11 +340,12 @@ int cpm_uart_init_portdesc(void) #endif #ifdef CONFIG_SERIAL_CPM_SCC2 - cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1]; - cpm_uart_ports[UART_SCC2].sccup = - (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2]; + cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]); cpm_uart_ports[UART_SCC2].port.mapbase = - (unsigned long)&cpm2_immr->im_scc[1]; + (unsigned long)cpm_uart_ports[UART_SCC2].sccp; + cpm_uart_ports[UART_SCC2].sccup = + (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE); + cpm_uart_ports[UART_SCC2].sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &= @@ -313,11 +355,12 @@ int cpm_uart_init_portdesc(void) #endif #ifdef CONFIG_SERIAL_CPM_SCC3 - cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2]; - cpm_uart_ports[UART_SCC3].sccup = - (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3]; + cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]); cpm_uart_ports[UART_SCC3].port.mapbase = - (unsigned long)&cpm2_immr->im_scc[2]; + (unsigned long)cpm_uart_ports[UART_SCC3].sccp; + cpm_uart_ports[UART_SCC3].sccup = + (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE); + cpm_uart_ports[UART_SCC3].sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &= @@ -327,11 +370,12 @@ int cpm_uart_init_portdesc(void) #endif #ifdef CONFIG_SERIAL_CPM_SCC4 - cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3]; - cpm_uart_ports[UART_SCC4].sccup = - (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4]; + cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]); cpm_uart_ports[UART_SCC4].port.mapbase = - (unsigned long)&cpm2_immr->im_scc[3]; + (unsigned long)cpm_uart_ports[UART_SCC4].sccp; + cpm_uart_ports[UART_SCC4].sccup = + (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE); + cpm_uart_ports[UART_SCC4].sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &= diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h index 4793fecf8ece..a663300d3476 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h @@ -40,6 +40,6 @@ static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; } -#define DPRAM_BASE ((unsigned char *)&cpm2_immr->im_dprambase[0]) +#define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0)) #endif diff --git a/include/asm-powerpc/fs_pd.h b/include/asm-powerpc/fs_pd.h index d530f68b4eef..3d0e819d37f1 100644 --- a/include/asm-powerpc/fs_pd.h +++ b/include/asm-powerpc/fs_pd.h @@ -11,6 +11,7 @@ #ifndef FS_PD_H #define FS_PD_H +#include #include #include @@ -24,4 +25,21 @@ static inline int uart_clock(void) return ppc_proc_freq; } +#define cpm2_map(member) \ +({ \ + u32 offset = offsetof(cpm2_map_t, member); \ + void *addr = ioremap (CPM_MAP_ADDR + offset, \ + sizeof( ((cpm2_map_t*)0)->member)); \ + addr; \ +}) + +#define cpm2_map_size(member, size) \ +({ \ + u32 offset = offsetof(cpm2_map_t, member); \ + void *addr = ioremap (CPM_MAP_ADDR + offset, size); \ + addr; \ +}) + +#define cpm2_unmap(addr) iounmap(addr) + #endif diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h index 876974e5412f..bd6623aed383 100644 --- a/include/asm-ppc/cpm2.h +++ b/include/asm-ppc/cpm2.h @@ -177,6 +177,10 @@ typedef struct cpm_buf_desc { #define PROFF_I2C_BASE ((uint)0x8afc) #define PROFF_IDMA4_BASE ((uint)0x8afe) +#define PROFF_SCC_SIZE ((uint)0x100) +#define PROFF_FCC_SIZE ((uint)0x100) +#define PROFF_SMC_SIZE ((uint)64) + /* The SMCs are relocated to any of the first eight DPRAM pages. * We will fix these at the first locations of DPRAM, until we * get some microcode patches :-). diff --git a/include/asm-ppc/fs_pd.h b/include/asm-ppc/fs_pd.h index eed777834121..8691327653af 100644 --- a/include/asm-ppc/fs_pd.h +++ b/include/asm-ppc/fs_pd.h @@ -29,4 +29,8 @@ static inline int uart_clock(void) return (((bd_t *) __res)->bi_intfreq); } +#define cpm2_map(member) (&cpm2_immr->member) +#define cpm2_map_size(member, size) (&cpm2_immr->member) +#define cpm2_unmap(addr) do {} while(0) + #endif -- cgit v1.2.3 From d3465c921f79cfef0a4a8ceeeef9a3721bbbb57d Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Thu, 21 Sep 2006 22:38:05 +0400 Subject: POWERPC: overhaul with cpm2_map mechanism Incorporating the new way of cpm2 immr access, introduced in the previous patch, into CPM2 peripheral devices (fs_enet and cpm_uart). Both ppc and powerpc approved working( real actions taken in powerpc only, ppc just has a wrapper to keep init stuff consistent). Signed-off-by: Vitaly Bordug --- arch/powerpc/platforms/85xx/mpc85xx_ads.c | 109 ++++++++++++++++-------------- arch/powerpc/sysdev/cpm2_common.c | 90 ++++++++++++++++++++++++ arch/powerpc/sysdev/fsl_soc.c | 7 ++ arch/ppc/platforms/mpc8272ads_setup.c | 8 +-- arch/ppc/platforms/mpc866ads_setup.c | 8 +-- arch/ppc/platforms/mpc885ads_setup.c | 10 +-- drivers/net/fs_enet/fs_enet-main.c | 2 +- drivers/serial/cpm_uart/cpm_uart_core.c | 4 +- include/asm-ppc/cpm2.h | 53 +++++++++++++++ include/linux/fs_enet_pd.h | 10 +-- include/linux/fs_uart_pd.h | 4 +- 11 files changed, 235 insertions(+), 70 deletions(-) (limited to 'drivers/serial') diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 7ebfe74bde40..28070e7ae507 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -33,6 +33,7 @@ #include "mpc85xx.h" #ifdef CONFIG_CPM2 +#include #include #include #include @@ -146,70 +147,81 @@ void __init mpc85xx_ads_pic_init(void) * Setup the architecture */ #ifdef CONFIG_CPM2 -static void init_fcc_ioports(void) +void init_fcc_ioports(struct fs_platform_info *fpi) { - struct immap *immap; - struct io_port *io; + struct io_port *io = cpm2_map(im_ioport); + int fcc_no = fs_get_fcc_index(fpi->fs_no); + int target; u32 tempval; - immap = cpm2_immr; - - io = &immap->im_ioport; - /* FCC2/3 are on the ports B/C. */ - tempval = in_be32(&io->iop_pdirb); - tempval &= ~PB2_DIRB0; - tempval |= PB2_DIRB1; - out_be32(&io->iop_pdirb, tempval); - - tempval = in_be32(&io->iop_psorb); - tempval &= ~PB2_PSORB0; - tempval |= PB2_PSORB1; - out_be32(&io->iop_psorb, tempval); - - tempval = in_be32(&io->iop_pparb); - tempval |= (PB2_DIRB0 | PB2_DIRB1); - out_be32(&io->iop_pparb, tempval); - - tempval = in_be32(&io->iop_pdirb); - tempval &= ~PB3_DIRB0; - tempval |= PB3_DIRB1; - out_be32(&io->iop_pdirb, tempval); - - tempval = in_be32(&io->iop_psorb); - tempval &= ~PB3_PSORB0; - tempval |= PB3_PSORB1; - out_be32(&io->iop_psorb, tempval); - - tempval = in_be32(&io->iop_pparb); - tempval |= (PB3_DIRB0 | PB3_DIRB1); - out_be32(&io->iop_pparb, tempval); - - tempval = in_be32(&io->iop_pdirc); - tempval |= PC3_DIRC1; - out_be32(&io->iop_pdirc, tempval); - - tempval = in_be32(&io->iop_pparc); - tempval |= PC3_DIRC1; - out_be32(&io->iop_pparc, tempval); + switch(fcc_no) { + case 1: + tempval = in_be32(&io->iop_pdirb); + tempval &= ~PB2_DIRB0; + tempval |= PB2_DIRB1; + out_be32(&io->iop_pdirb, tempval); + + tempval = in_be32(&io->iop_psorb); + tempval &= ~PB2_PSORB0; + tempval |= PB2_PSORB1; + out_be32(&io->iop_psorb, tempval); + + tempval = in_be32(&io->iop_pparb); + tempval |= (PB2_DIRB0 | PB2_DIRB1); + out_be32(&io->iop_pparb, tempval); + + target = CPM_CLK_FCC2; + break; + case 2: + tempval = in_be32(&io->iop_pdirb); + tempval &= ~PB3_DIRB0; + tempval |= PB3_DIRB1; + out_be32(&io->iop_pdirb, tempval); + + tempval = in_be32(&io->iop_psorb); + tempval &= ~PB3_PSORB0; + tempval |= PB3_PSORB1; + out_be32(&io->iop_psorb, tempval); + + tempval = in_be32(&io->iop_pparb); + tempval |= (PB3_DIRB0 | PB3_DIRB1); + out_be32(&io->iop_pparb, tempval); + + tempval = in_be32(&io->iop_pdirc); + tempval |= PC3_DIRC1; + out_be32(&io->iop_pdirc, tempval); + + tempval = in_be32(&io->iop_pparc); + tempval |= PC3_DIRC1; + out_be32(&io->iop_pparc, tempval); + + target = CPM_CLK_FCC3; + break; + default: + printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n"); + return; + } /* Port C has clocks...... */ tempval = in_be32(&io->iop_psorc); - tempval &= ~(CLK_TRX); + tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); out_be32(&io->iop_psorc, tempval); tempval = in_be32(&io->iop_pdirc); - tempval &= ~(CLK_TRX); + tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); out_be32(&io->iop_pdirc, tempval); tempval = in_be32(&io->iop_pparc); - tempval |= (CLK_TRX); + tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); out_be32(&io->iop_pparc, tempval); + cpm2_unmap(io); + /* Configure Serial Interface clock routing. - * First, clear all FCC bits to zero, + * First, clear FCC bits to zero, * then set the ones we want. */ - immap->im_cpmux.cmx_fcr &= ~(CPMUX_CLK_MASK); - immap->im_cpmux.cmx_fcr |= CPMUX_CLK_ROUTE; + cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX); + cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX); } #endif @@ -237,7 +249,6 @@ static void __init mpc85xx_ads_setup_arch(void) #ifdef CONFIG_CPM2 cpm2_reset(); - init_fcc_ioports(); #endif #ifdef CONFIG_PCI diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c index 73376f9c1560..ec265995d5d8 100644 --- a/arch/powerpc/sysdev/cpm2_common.c +++ b/arch/powerpc/sysdev/cpm2_common.c @@ -130,6 +130,96 @@ cpm2_fastbrg(uint brg, uint rate, int div16) cpm2_unmap(bp); } +int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) +{ + int ret = 0; + int shift; + int i, bits = 0; + cpmux_t *im_cpmux; + u32 *reg; + u32 mask = 7; + u8 clk_map [24][3] = { + {CPM_CLK_FCC1, CPM_BRG5, 0}, + {CPM_CLK_FCC1, CPM_BRG6, 1}, + {CPM_CLK_FCC1, CPM_BRG7, 2}, + {CPM_CLK_FCC1, CPM_BRG8, 3}, + {CPM_CLK_FCC1, CPM_CLK9, 4}, + {CPM_CLK_FCC1, CPM_CLK10, 5}, + {CPM_CLK_FCC1, CPM_CLK11, 6}, + {CPM_CLK_FCC1, CPM_CLK12, 7}, + {CPM_CLK_FCC2, CPM_BRG5, 0}, + {CPM_CLK_FCC2, CPM_BRG6, 1}, + {CPM_CLK_FCC2, CPM_BRG7, 2}, + {CPM_CLK_FCC2, CPM_BRG8, 3}, + {CPM_CLK_FCC2, CPM_CLK13, 4}, + {CPM_CLK_FCC2, CPM_CLK14, 5}, + {CPM_CLK_FCC2, CPM_CLK15, 6}, + {CPM_CLK_FCC2, CPM_CLK16, 7}, + {CPM_CLK_FCC3, CPM_BRG5, 0}, + {CPM_CLK_FCC3, CPM_BRG6, 1}, + {CPM_CLK_FCC3, CPM_BRG7, 2}, + {CPM_CLK_FCC3, CPM_BRG8, 3}, + {CPM_CLK_FCC3, CPM_CLK13, 4}, + {CPM_CLK_FCC3, CPM_CLK14, 5}, + {CPM_CLK_FCC3, CPM_CLK15, 6}, + {CPM_CLK_FCC3, CPM_CLK16, 7} + }; + + im_cpmux = cpm2_map(im_cpmux); + + switch (target) { + case CPM_CLK_SCC1: + reg = &im_cpmux->cmx_scr; + shift = 24; + case CPM_CLK_SCC2: + reg = &im_cpmux->cmx_scr; + shift = 16; + break; + case CPM_CLK_SCC3: + reg = &im_cpmux->cmx_scr; + shift = 8; + break; + case CPM_CLK_SCC4: + reg = &im_cpmux->cmx_scr; + shift = 0; + break; + case CPM_CLK_FCC1: + reg = &im_cpmux->cmx_fcr; + shift = 24; + break; + case CPM_CLK_FCC2: + reg = &im_cpmux->cmx_fcr; + shift = 16; + break; + case CPM_CLK_FCC3: + reg = &im_cpmux->cmx_fcr; + shift = 8; + break; + default: + printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n"); + return -EINVAL; + } + + if (mode == CPM_CLK_RX) + shift +=3; + + for (i=0; i<24; i++) { + if (clk_map[i][0] == target && clk_map[i][1] == clock) { + bits = clk_map[i][2]; + break; + } + } + if (i == sizeof(clk_map)/3) + ret = -EINVAL; + + bits <<= shift; + mask <<= shift; + out_be32(reg, (in_be32(reg) & ~mask) | bits); + + cpm2_unmap(im_cpmux); + return ret; +} + /* * dpalloc / dpfree bits. */ diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 0b8a03cc3042..4e72bb983636 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -36,6 +36,7 @@ #include #include +extern void init_fcc_ioports(struct fs_platform_info*); static phys_addr_t immrbase = -1; phys_addr_t get_immrbase(void) @@ -630,6 +631,9 @@ static int __init fs_enet_of_init(void) goto unreg; } + fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); + fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); + if (strstr(model, "FCC")) { int fcc_index = fs_get_fcc_index(*id); @@ -646,6 +650,7 @@ static int __init fs_enet_of_init(void) 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; } of_node_put(phy); @@ -717,6 +722,8 @@ static int __init cpm_uart_of_init(void) 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 *) get_property(np, "rx-clock", NULL)); + cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); ret = platform_device_add_data(cpm_uart_dev, &cpm_uart_data, diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c index 2a35fe2b9b96..d5d36c372c8e 100644 --- a/arch/ppc/platforms/mpc8272ads_setup.c +++ b/arch/ppc/platforms/mpc8272ads_setup.c @@ -103,7 +103,7 @@ static struct fs_platform_info mpc82xx_enet_pdata[] = { }, }; -static void init_fcc1_ioports(void) +static void init_fcc1_ioports(struct fs_platform_info*) { struct io_port *io; u32 tempval; @@ -144,7 +144,7 @@ static void init_fcc1_ioports(void) iounmap(immap); } -static void init_fcc2_ioports(void) +static void init_fcc2_ioports(struct fs_platform_info*) { cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32)); @@ -229,7 +229,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev, } } -static void init_scc1_uart_ioports(void) +static void init_scc1_uart_ioports(struct fs_uart_platform_info*) { cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); @@ -246,7 +246,7 @@ static void init_scc1_uart_ioports(void) iounmap(immap); } -static void init_scc4_uart_ioports(void) +static void init_scc4_uart_ioports(struct fs_uart_platform_info*) { cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c index e12cece4c9fd..5f130dca3770 100644 --- a/arch/ppc/platforms/mpc866ads_setup.c +++ b/arch/ppc/platforms/mpc866ads_setup.c @@ -137,7 +137,7 @@ void __init board_init(void) iounmap(bcsr_io); } -static void setup_fec1_ioports(void) +static void setup_fec1_ioports(struct fs_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -145,7 +145,7 @@ static void setup_fec1_ioports(void) setbits16(&immap->im_ioport.iop_pddir, 0x1fff); } -static void setup_scc1_ioports(void) +static void setup_scc1_ioports(struct fs_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -194,7 +194,7 @@ static void setup_scc1_ioports(void) } -static void setup_smc1_ioports(void) +static void setup_smc1_ioports(struct fs_uart_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -216,7 +216,7 @@ static void setup_smc1_ioports(void) } -static void setup_smc2_ioports(void) +static void setup_smc2_ioports(struct fs_uart_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c index 5dfa4e6c2af0..bf388ed04d46 100644 --- a/arch/ppc/platforms/mpc885ads_setup.c +++ b/arch/ppc/platforms/mpc885ads_setup.c @@ -161,7 +161,7 @@ void __init board_init(void) #endif } -static void setup_fec1_ioports(void) +static void setup_fec1_ioports(struct fs_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -181,7 +181,7 @@ static void setup_fec1_ioports(void) clrbits32(&immap->im_cpm.cp_cptr, 0x00000100); } -static void setup_fec2_ioports(void) +static void setup_fec2_ioports(struct fs_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; @@ -193,7 +193,7 @@ static void setup_fec2_ioports(void) clrbits32(&immap->im_cpm.cp_cptr, 0x00000080); } -static void setup_scc3_ioports(void) +static void setup_scc3_ioports(struct fs_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -315,7 +315,7 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev, mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); } -static void setup_smc1_ioports(void) +static void setup_smc1_ioports(struct fs_uart_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; @@ -335,7 +335,7 @@ static void setup_smc1_ioports(void) clrbits16(&immap->im_cpm.cp_pbodr, iobits); } -static void setup_smc2_ioports(void) +static void setup_smc2_ioports(struct fs_uart_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index df62506a1787..f358ee61d9b9 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -971,7 +971,7 @@ static struct net_device *fs_init_instance(struct device *dev, dev_set_drvdata(dev, ndev); fep->fpi = fpi; if (fpi->init_ioports) - fpi->init_ioports(); + fpi->init_ioports((struct fs_platform_info *)fpi); #ifdef CONFIG_FS_ENET_HAS_FEC if (fs_get_fec_index(fpi->fs_no) >= 0) diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index dfa06b644957..24613a68f5cc 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1180,7 +1180,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) pdata = pdev->dev.platform_data; if (pdata) if (pdata->init_ioports) - pdata->init_ioports(); + pdata->init_ioports(pdata); cpm_uart_drv_get_platform_data(pdev, 1); } @@ -1269,7 +1269,7 @@ static int cpm_uart_drv_probe(struct device *dev) return ret; if (pdata->init_ioports) - pdata->init_ioports(); + pdata->init_ioports(pdata); ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h index bd6623aed383..220cc2debe08 100644 --- a/include/asm-ppc/cpm2.h +++ b/include/asm-ppc/cpm2.h @@ -1196,5 +1196,58 @@ typedef struct im_idma { #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1) #define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2) +/* Clocks and GRG's */ + +enum cpm_clk_dir { + CPM_CLK_RX, + CPM_CLK_TX, + CPM_CLK_RTX +}; + +enum cpm_clk_target { + CPM_CLK_SCC1, + CPM_CLK_SCC2, + CPM_CLK_SCC3, + CPM_CLK_SCC4, + CPM_CLK_FCC1, + CPM_CLK_FCC2, + CPM_CLK_FCC3 +}; + +enum cpm_clk { + CPM_CLK_NONE = 0, + CPM_BRG1, /* Baud Rate Generator 1 */ + CPM_BRG2, /* Baud Rate Generator 2 */ + CPM_BRG3, /* Baud Rate Generator 3 */ + CPM_BRG4, /* Baud Rate Generator 4 */ + CPM_BRG5, /* Baud Rate Generator 5 */ + CPM_BRG6, /* Baud Rate Generator 6 */ + CPM_BRG7, /* Baud Rate Generator 7 */ + CPM_BRG8, /* Baud Rate Generator 8 */ + CPM_CLK1, /* Clock 1 */ + CPM_CLK2, /* Clock 2 */ + CPM_CLK3, /* Clock 3 */ + CPM_CLK4, /* Clock 4 */ + CPM_CLK5, /* Clock 5 */ + CPM_CLK6, /* Clock 6 */ + CPM_CLK7, /* Clock 7 */ + CPM_CLK8, /* Clock 8 */ + CPM_CLK9, /* Clock 9 */ + CPM_CLK10, /* Clock 10 */ + CPM_CLK11, /* Clock 11 */ + CPM_CLK12, /* Clock 12 */ + CPM_CLK13, /* Clock 13 */ + CPM_CLK14, /* Clock 14 */ + CPM_CLK15, /* Clock 15 */ + CPM_CLK16, /* Clock 16 */ + CPM_CLK17, /* Clock 17 */ + CPM_CLK18, /* Clock 18 */ + CPM_CLK19, /* Clock 19 */ + CPM_CLK20, /* Clock 20 */ + CPM_CLK_DUMMY +}; + +extern int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode); + #endif /* __CPM2__ */ #endif /* __KERNEL__ */ diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 74ed35a00a94..932223550aca 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h @@ -87,18 +87,20 @@ struct fs_mii_bb_platform_info { }; struct fs_platform_info { - - void(*init_ioports)(void); + + void(*init_ioports)(struct fs_platform_info *); /* device specific information */ int fs_no; /* controller index */ u32 cp_page; /* CPM page */ u32 cp_block; /* CPM sblock */ - + u32 clk_trx; /* some stuff for pins & mux configuration*/ + u32 clk_rx; + u32 clk_tx; u32 clk_route; u32 clk_mask; - + u32 mem_offset; u32 dpram_offset; u32 fcc_regs_c; diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h index f5975126b712..a99a020f95c2 100644 --- a/include/linux/fs_uart_pd.h +++ b/include/linux/fs_uart_pd.h @@ -46,7 +46,7 @@ static inline int fs_uart_id_fsid2smc(int id) } struct fs_uart_platform_info { - void(*init_ioports)(void); + void(*init_ioports)(struct fs_uart_platform_info *); /* device specific information */ int fs_no; /* controller index */ u32 uart_clk; @@ -55,6 +55,8 @@ struct fs_uart_platform_info { u8 rx_num_fifo; u8 rx_buf_size; u8 brg; + u8 clk_rx; + u8 clk_tx; }; #endif -- cgit v1.2.3 From 611a15afcdaacec6efba984c7eb089b853564bdf Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Thu, 21 Sep 2006 22:38:05 +0400 Subject: POWERPC: Bring the fs_no calculation to the relevant SoC enumeration The fs_no mean used to be fs_enet driver driven, hence it was an enumeration across all the possible fs_enet "users" in the SoC. Now, with QE on the pipeline, and to make DTS descriptions more clear, fs_no features relevant SoC part number, with additional field to describe the SoC type. Another reason for that is now not only fs_enet is going to utilize those stuff. There might be UART, HLDC, and even USB, so to prevent confusion and be ready for upcoming OF_device transfer, fs_enet and cpm_uart drivers were updated in that concern, as well as the relevant DTS. Signed-off-by: Vitaly Bordug --- arch/powerpc/boot/dts/mpc8560ads.dts | 8 +++---- arch/powerpc/sysdev/fsl_soc.c | 8 ++++++- drivers/net/fs_enet/fs_enet-main.c | 3 ++- drivers/serial/cpm_uart/cpm_uart_core.c | 9 +++++--- include/linux/fs_enet_pd.h | 37 +++++++++++++++++++++++++++++++++ include/linux/fs_uart_pd.h | 10 +++++++++ 6 files changed, 66 insertions(+), 9 deletions(-) (limited to 'drivers/serial') diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts index ba5c943a6fe9..2b168486aeba 100644 --- a/arch/powerpc/boot/dts/mpc8560ads.dts +++ b/arch/powerpc/boot/dts/mpc8560ads.dts @@ -244,7 +244,7 @@ device_type = "serial"; compatible = "cpm_uart"; model = "SCC"; - device-id = <2>; + device-id = <1>; reg = <91a00 20 88000 100>; clock-setup = <00ffffff 0>; rx-clock = <1>; @@ -258,7 +258,7 @@ device_type = "serial"; compatible = "cpm_uart"; model = "SCC"; - device-id = <3>; + device-id = <2>; reg = <91a20 20 88100 100>; clock-setup = ; rx-clock = <2>; @@ -272,7 +272,7 @@ device_type = "network"; compatible = "fs_enet"; model = "FCC"; - device-id = <3>; + device-id = <2>; reg = <91320 20 88500 100 913a0 30>; mac-address = [ 00 00 0C 00 02 FD ]; clock-setup = ; @@ -287,7 +287,7 @@ device_type = "network"; compatible = "fs_enet"; model = "FCC"; - device-id = <4>; + device-id = <3>; reg = <91340 20 88600 100 913d0 30>; mac-address = [ 00 00 0C 00 03 FD ]; clock-setup = ; diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 4e72bb983636..022ed275ea68 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -622,6 +622,7 @@ static int __init fs_enet_of_init(void) id = 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); @@ -635,7 +636,7 @@ static int __init fs_enet_of_init(void) fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); if (strstr(model, "FCC")) { - int fcc_index = fs_get_fcc_index(*id); + int fcc_index = *id - 1; fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0); fs_enet_data.rx_ring = 32; @@ -688,6 +689,7 @@ static int __init cpm_uart_of_init(void) 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)); @@ -716,6 +718,10 @@ static int __init cpm_uart_of_init(void) id = get_property(np, "device-id", NULL); cpm_uart_data.fs_no = *id; + + model = (char*)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; diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index f358ee61d9b9..3e2a3a20d50a 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -944,12 +944,13 @@ extern int fs_mii_connect(struct net_device *dev); extern void fs_mii_disconnect(struct net_device *dev); static struct net_device *fs_init_instance(struct device *dev, - const struct fs_platform_info *fpi) + struct fs_platform_info *fpi) { struct net_device *ndev = NULL; struct fs_enet_private *fep = NULL; int privsize, i, r, err = 0, registered = 0; + fpi->fs_no = fs_get_id(fpi); /* guard */ if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX) return ERR_PTR(-EINVAL); diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 24613a68f5cc..a0d6136deb9b 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1023,15 +1023,17 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) { struct resource *r; struct fs_uart_platform_info *pdata = pdev->dev.platform_data; - int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */ + int idx; /* It is UART_SMCx or UART_SCCx index */ struct uart_cpm_port *pinfo; int line; u32 mem, pram; + idx = pdata->fs_no = fs_uart_get_id(pdata); + line = cpm_uart_id2nr(idx); if(line < 0) { printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx); - return -1; + return -EINVAL; } pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; @@ -1263,11 +1265,12 @@ static int cpm_uart_drv_probe(struct device *dev) } pdata = pdev->dev.platform_data; - pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) return ret; + pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); + if (pdata->init_ioports) pdata->init_ioports(pdata); diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 932223550aca..543cd3cd9e77 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h @@ -55,6 +55,30 @@ static inline int fs_get_scc_index(enum fs_id id) return -1; } +static inline int fs_fec_index2id(int index) +{ + int id = fsid_fec1 + index - 1; + if (id >= fsid_fec1 && id <= fsid_fec2) + return id; + return FS_MAX_INDEX; + } + +static inline int fs_fcc_index2id(int index) +{ + int id = fsid_fcc1 + index - 1; + if (id >= fsid_fcc1 && id <= fsid_fcc3) + return id; + return FS_MAX_INDEX; +} + +static inline int fs_scc_index2id(int index) +{ + int id = fsid_scc1 + index - 1; + if (id >= fsid_scc1 && id <= fsid_scc4) + return id; + return FS_MAX_INDEX; +} + enum fs_mii_method { fsmii_fixed, fsmii_fec, @@ -91,6 +115,7 @@ struct fs_platform_info { void(*init_ioports)(struct fs_platform_info *); /* device specific information */ int fs_no; /* controller index */ + char fs_type[4]; /* controller type */ u32 cp_page; /* CPM page */ u32 cp_block; /* CPM sblock */ @@ -126,4 +151,16 @@ struct fs_mii_fec_platform_info { u32 irq[32]; u32 mii_speed; }; + +static inline int fs_get_id(struct fs_platform_info *fpi) +{ + if(strstr(fpi->fs_type, "SCC")) + return fs_scc_index2id(fpi->fs_no); + if(strstr(fpi->fs_type, "FCC")) + return fs_fcc_index2id(fpi->fs_no); + if(strstr(fpi->fs_type, "FEC")) + return fs_fec_index2id(fpi->fs_no); + return fpi->fs_no; +} + #endif diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h index a99a020f95c2..809bb9ffc788 100644 --- a/include/linux/fs_uart_pd.h +++ b/include/linux/fs_uart_pd.h @@ -49,6 +49,7 @@ struct fs_uart_platform_info { void(*init_ioports)(struct fs_uart_platform_info *); /* device specific information */ int fs_no; /* controller index */ + char fs_type[4]; /* controller type */ u32 uart_clk; u8 tx_num_fifo; u8 tx_buf_size; @@ -59,4 +60,13 @@ struct fs_uart_platform_info { u8 clk_tx; }; +static inline int fs_uart_get_id(struct fs_uart_platform_info *fpi) +{ + if(strstr(fpi->fs_type, "SMC")) + return fs_uart_id_smc2fsid(fpi->fs_no); + if(strstr(fpi->fs_type, "SCC")) + return fs_uart_id_scc2fsid(fpi->fs_no); + return fpi->fs_no; +} + #endif -- cgit v1.2.3 From 9e84b60ed87f5fe2dce10be2db1bfbb926a49e66 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Sep 2006 01:39:45 +0100 Subject: [POWERPC] UPIO_TSI cleanup (le32_to_cpu(x) >> 8) & 0xff is a very odd way to spell (x >> 16) & 0xff, even if that code is hit only on ppc. The value is host-endian - we've got it from readl(), after all... Signed-off-by: Al Viro Signed-off-by: Paul Mackerras --- drivers/serial/8250.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/serial') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 0ae9ced00ed4..10c2daab99ac 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -320,8 +320,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) case UPIO_TSI: if (offset == UART_IIR) { - tmp = readl((u32 *)(up->port.membase + UART_RX)); - return (cpu_to_le32(tmp) >> 8) & 0xff; + tmp = readl(up->port.membase + (UART_IIR & ~3)); + return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ } else return readb(up->port.membase + offset); -- cgit v1.2.3