static void setup_fec1_ioports(void) { immap_t *immap = (immap_t *) IMAP_ADDR; setbits16(&immap->im_ioport.iop_pdpar, 0x1fff); setbits16(&immap->im_ioport.iop_pddir, 0x1fff); }
static void cpm1_set_pin16(int port, int pin, int flags) { struct cpm_ioport16 __iomem *iop = (struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport; pin = 1 << (15 - pin); if (port != 0) iop += port - 1; if (flags & CPM_PIN_OUTPUT) setbits16(&iop->dir, pin); else clrbits16(&iop->dir, pin); if (!(flags & CPM_PIN_GPIO)) setbits16(&iop->par, pin); else clrbits16(&iop->par, pin); if (port == CPM_PORTA) { if (flags & CPM_PIN_OPENDRAIN) setbits16(&iop->odr_sor, pin); else clrbits16(&iop->odr_sor, pin); } if (port == CPM_PORTC) { if (flags & CPM_PIN_SECONDARY) setbits16(&iop->odr_sor, pin); else clrbits16(&iop->odr_sor, pin); } }
static void setup_fec1_ioports(struct fs_platform_info*) { immap_t *immap = (immap_t *) IMAP_ADDR; setbits16(&immap->im_ioport.iop_pdpar, 0x1fff); setbits16(&immap->im_ioport.iop_pddir, 0x1fff); }
static void setup_scc3_ioports(void) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE); if (bcsr_io == NULL) { printk(KERN_CRIT "Could not remap BCSR\n"); return; } /* Enable the PHY. */ setbits32(bcsr_io+4, BCSR4_ETH10_RST); /* Configure port A pins for Txd and Rxd. */ setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD); clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD); /* Configure port C pins to enable CLSN and RENA. */ clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA); clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA); setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA); /* Configure port E for TCLK and RCLK. */ setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TCLK | PE_ENET_RCLK); clrbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA); clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TCLK | PE_ENET_RCLK | PE_ENET_TENA); clrbits32(&immap->im_cpm.cp_peso, PE_ENET_TCLK | PE_ENET_RCLK); setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. */ clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK); setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT); /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are used. */ immap->im_cpm.cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* On the MPC885ADS SCC ethernet PHY is initialized in the full duplex mode * by H/W setting after reset. SCC ethernet controller support only half duplex. * This discrepancy of modes causes a lot of carrier lost errors. */ /* In the original SCC enet driver the following code is placed at the end of the initialization */ setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA); clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA); setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA); setbits32(bcsr_io+1, BCSR1_ETHEN); iounmap(bcsr_io); }
static void setup_scc1_ioports(struct fs_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); if (bcsr_io == NULL) { printk(KERN_CRIT "Could not remap BCSR1\n"); return; } /* Enable the PHY. */ clrbits32(bcsr_io,BCSR1_ETHEN); /* Configure port A pins for Txd and Rxd. */ /* Disable receive and transmit in case EPPC-Bug started it. */ setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD); clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD); clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD); /* Configure port C pins to enable CLSN and RENA. */ clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA); clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA); setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA); /* Configure port A for TCLK and RCLK. */ setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK); clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK); clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA); clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. */ clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK); setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT); /* In the original SCC enet driver the following code is placed at the end of the initialization */ setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA); setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA); }
static void setup_smc2_ioports(struct fs_uart_platform_info* pdata) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; unsigned int iobits = 0x00000c00; bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); if (bcsr_io == NULL) { printk(KERN_CRIT "Could not remap BCSR1\n"); return; } clrbits32(bcsr_io,BCSR1_RS232EN_2); iounmap(bcsr_io); #ifndef CONFIG_SERIAL_CPM_ALT_SMC2 setbits32(&immap->im_cpm.cp_pbpar, iobits); clrbits32(&immap->im_cpm.cp_pbdir, iobits); clrbits16(&immap->im_cpm.cp_pbodr, iobits); #else setbits16(&immap->im_ioport.iop_papar, iobits); clrbits16(&immap->im_ioport.iop_padir, iobits); clrbits16(&immap->im_ioport.iop_paodr, iobits); #endif }
static void mpc866ads_fixup_scc_irda_pdata(struct platform_device *pdev, int idx) { immap_t *immap = (immap_t *) IMAP_ADDR; unsigned *bcsr_io; /* This is for IRDA devices only */ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc:irda"))) return; bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); if (bcsr_io == NULL) { printk(KERN_CRIT "Could not remap BCSR1\n"); return; } /* Enable the IRDA. */ clrbits32(bcsr_io,BCSR1_IRDAEN); iounmap(bcsr_io); /* Configure port A pins. */ setbits16(&immap->im_ioport.iop_papar, 0x000c); clrbits16(&immap->im_ioport.iop_padir, 0x000c); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. */ clrbits32(&immap->im_cpm.cp_sicr, 0x0000ff00); setbits32(&immap->im_cpm.cp_sicr, 0x00001200); }
static void setup_fec1_ioports(void) { immap_t *immap = (immap_t *) IMAP_ADDR; /* configure FEC1 pins */ setbits16(&immap->im_ioport.iop_papar, 0xf830); setbits16(&immap->im_ioport.iop_padir, 0x0830); clrbits16(&immap->im_ioport.iop_padir, 0xf000); setbits32(&immap->im_cpm.cp_pbpar, 0x00001001); clrbits32(&immap->im_cpm.cp_pbdir, 0x00001001); setbits16(&immap->im_ioport.iop_pcpar, 0x000c); clrbits16(&immap->im_ioport.iop_pcdir, 0x000c); setbits32(&immap->im_cpm.cp_pepar, 0x00000003); setbits32(&immap->im_cpm.cp_pedir, 0x00000003); clrbits32(&immap->im_cpm.cp_peso, 0x00000003); clrbits32(&immap->im_cpm.cp_cptr, 0x00000100); }
init_internal_rtc(void) { sit8xx_t __iomem *sys_tmr = immr_map(im_sit); /* Disable the RTC one second and alarm interrupts. */ clrbits16(&sys_tmr->sit_rtcsc, (RTCSC_SIE | RTCSC_ALE)); /* Enable the RTC */ setbits16(&sys_tmr->sit_rtcsc, (RTCSC_RTF | RTCSC_RTE)); immr_unmap(sys_tmr); }
static void mpc866ads_fixup_i2c_pdata(struct platform_device *pdev, int idx) { immap_t *immap = (immap_t *) IMAP_ADDR; /* This is for I2C device only */ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-i2c"))) return; setbits32(&immap->im_cpm.cp_pbpar, 0x00000030); setbits32(&immap->im_cpm.cp_pbdir, 0x00000030); setbits16(&immap->im_cpm.cp_pbodr, 0x0030); }
static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) { smc_t __iomem *sp; smc_uart_t __iomem *up; pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); sp = pinfo->smcp; up = pinfo->smcup; /* Store address */ out_be16(&pinfo->smcup->smc_rbase, (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); out_be16(&pinfo->smcup->smc_tbase, (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); /* * In case SMC1 is being relocated... */ #if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); out_be32(&up->smc_rstate, 0); out_be32(&up->smc_tstate, 0); out_be16(&up->smc_brkcr, 1); /* number of break chars */ out_be16(&up->smc_brkec, 0); #endif /* Set up the uart parameters in the * parameter ram. */ cpm_set_smc_fcr(up); /* Using idle charater time requires some additional tuning. */ out_be16(&up->smc_mrblr, pinfo->rx_fifosize); out_be16(&up->smc_maxidl, pinfo->rx_fifosize); out_be16(&up->smc_brklen, 0); out_be16(&up->smc_brkec, 0); out_be16(&up->smc_brkcr, 1); cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART); /* Enable only rx interrupts clear all pending events. */ out_8(&sp->smc_smcm, 0); out_8(&sp->smc_smce, 0xff); setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); }
static int cpm_uart_startup(struct uart_port *port) { int retval; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; pr_debug("CPM uart[%d]:startup\n", port->line); /* If the port is not the console, make sure rx is disabled. */ if (!(pinfo->flags & FLAG_CONSOLE)) { /* Disable UART rx */ if (IS_SMC(pinfo)) { clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN); clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX); } else { clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR); clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); } cpm_uart_initbd(pinfo); cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); } /* Install interrupt handler. */ retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); if (retval) return retval; /* Startup rx-int */ if (IS_SMC(pinfo)) { setbits8(&pinfo->smcp->smc_smcm, SMCM_RX); setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN)); } else { setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT)); } return 0; }
static void init_fec1_ioports(struct fs_platform_info *ptr) { cpm8xx_t *cp = (cpm8xx_t *) immr_map(im_cpm); iop8xx_t *io_port = (iop8xx_t *) immr_map(im_ioport); /* configure FEC1 pins */ setbits16(&io_port->iop_papar, 0xf830); setbits16(&io_port->iop_padir, 0x0830); clrbits16(&io_port->iop_padir, 0xf000); setbits32(&cp->cp_pbpar, 0x00001001); clrbits32(&cp->cp_pbdir, 0x00001001); setbits16(&io_port->iop_pcpar, 0x000c); clrbits16(&io_port->iop_pcdir, 0x000c); setbits32(&cp->cp_pepar, 0x00000003); setbits32(&cp->cp_pedir, 0x00000003); clrbits32(&cp->cp_peso, 0x00000003); clrbits32(&cp->cp_cptr, 0x00000100); immr_unmap(io_port); immr_unmap(cp); }
static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); struct cpm_ioport16 __iomem *iop = mm_gc->regs; unsigned long flags; u16 pin_mask = 1 << (15 - gpio); spin_lock_irqsave(&cpm1_gc->lock, flags); setbits16(&iop->dir, pin_mask); __cpm1_gpio16_set(mm_gc, pin_mask, val); spin_unlock_irqrestore(&cpm1_gc->lock, flags); return 0; }
void __init board_init(void) { volatile cpm8xx_t *cp = cpmp; unsigned int *bcsr_io; #ifdef CONFIG_FS_ENET immap_t *immap = (immap_t *) IMAP_ADDR; #endif bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); if (bcsr_io == NULL) { printk(KERN_CRIT "Could not remap BCSR\n"); return; } #ifdef CONFIG_SERIAL_CPM_SMC1 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */ clrbits32(bcsr_io, BCSR1_RS232EN_1); cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX); cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); #else setbits32(bcsr_io,BCSR1_RS232EN_1); cp->cp_smc[0].smc_smcmr = 0; cp->cp_smc[0].smc_smce = 0; #endif #ifdef CONFIG_SERIAL_CPM_SMC2 cp->cp_simode &= ~(0xe0000000 >> 1); cp->cp_simode |= (0x20000000 >> 1); /* brg2 */ clrbits32(bcsr_io,BCSR1_RS232EN_2); cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX); cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); #else setbits32(bcsr_io,BCSR1_RS232EN_2); cp->cp_smc[1].smc_smcmr = 0; cp->cp_smc[1].smc_smce = 0; #endif iounmap(bcsr_io); #ifdef CONFIG_FS_ENET /* use MDC for MII (common) */ setbits16(&immap->im_ioport.iop_pdpar, 0x0080); clrbits16(&immap->im_ioport.iop_pddir, 0x0080); #endif }
static void cpm1_set_pin32(int port, int pin, int flags) { struct cpm_ioport32e __iomem *iop; pin = 1 << (31 - pin); if (port == CPM_PORTB) iop = (struct cpm_ioport32e __iomem *) &mpc8xx_immr->im_cpm.cp_pbdir; else iop = (struct cpm_ioport32e __iomem *) &mpc8xx_immr->im_cpm.cp_pedir; if (flags & CPM_PIN_OUTPUT) setbits32(&iop->dir, pin); else clrbits32(&iop->dir, pin); if (!(flags & CPM_PIN_GPIO)) setbits32(&iop->par, pin); else clrbits32(&iop->par, pin); if (port == CPM_PORTB) { if (flags & CPM_PIN_OPENDRAIN) setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); else clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); } if (port == CPM_PORTE) { if (flags & CPM_PIN_SECONDARY) setbits32(&iop->sor, pin); else clrbits32(&iop->sor, pin); if (flags & CPM_PIN_OPENDRAIN) setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin); else clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin); } }
static void mpc885ads_scc_phy_init(char phy_addr) { volatile immap_t *immap; volatile fec_t *fecp; bd_t *bd; bd = (bd_t *) __res; immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */ fecp = &(immap->im_cpm.cp_fec); /* Enable MII pins of the FEC1 */ setbits16(&immap->im_ioport.iop_pdpar, 0x0080); clrbits16(&immap->im_ioport.iop_pddir, 0x0080); /* Set MII speed to 2.5 MHz */ out_be32(&fecp->fec_mii_speed, ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1); /* Enable FEC pin MUX */ setbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX); setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); out_be32(&fecp->fec_mii_data, mk_mii_write(MII_BMCR, BMCR_ISOLATE, phy_addr)); udelay(100); out_be32(&fecp->fec_mii_data, mk_mii_write(MII_ADVERTISE, ADVERTISE_10HALF | ADVERTISE_CSMA, phy_addr)); udelay(100); /* Disable FEC MII settings */ clrbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX); clrbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); out_be32(&fecp->fec_mii_speed, 0); }
/* * Start transmitter */ static void cpm_uart_start_tx(struct uart_port *port) { struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; smc_t __iomem *smcp = pinfo->smcp; scc_t __iomem *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:start tx\n", port->line); if (IS_SMC(pinfo)) { if (in_8(&smcp->smc_smcm) & SMCM_TX) return; } else { if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX) return; } if (cpm_uart_tx_pump(port) != 0) { if (IS_SMC(pinfo)) { setbits8(&smcp->smc_smcm, SMCM_TX); } else { setbits16(&sccp->scc_sccm, UART_SCCM_TX); } } }
/* * Transmit characters, refill buffer descriptor, if possible */ static int cpm_uart_tx_pump(struct uart_port *port) { cbd_t __iomem *bdp; u8 *p; int count; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; struct circ_buf *xmit = &port->info->xmit; /* Handle xon/xoff */ if (port->x_char) { /* Pick next descriptor and fill from buffer */ bdp = pinfo->tx_cur; p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *p++ = port->x_char; out_be16(&bdp->cbd_datlen, 1); setbits16(&bdp->cbd_sc, BD_SC_READY); /* Get next BD. */ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = pinfo->tx_bd_base; else bdp++; pinfo->tx_cur = bdp; port->icount.tx++; port->x_char = 0; return 1; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { cpm_uart_stop_tx(port); return 0; } /* Pick next descriptor and fill from buffer */ bdp = pinfo->tx_cur; while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && xmit->tail != xmit->head) { count = 0; p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); while (count < pinfo->tx_fifosize) { *p++ = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; count++; if (xmit->head == xmit->tail) break; } out_be16(&bdp->cbd_datlen, count); setbits16(&bdp->cbd_sc, BD_SC_READY); /* Get next BD. */ if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = pinfo->tx_bd_base; else bdp++; } pinfo->tx_cur = bdp; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) { cpm_uart_stop_tx(port); return 0; } return 1; }
/* * Receive characters */ static void cpm_uart_int_rx(struct uart_port *port) { int i; unsigned char ch; u8 *cp; struct tty_struct *tty = port->info->port.tty; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; cbd_t __iomem *bdp; u16 status; unsigned int flg; pr_debug("CPM uart[%d]:RX INT\n", port->line); /* Just loop through the closed BDs and copy the characters into * the buffer. */ bdp = pinfo->rx_cur; for (;;) { #ifdef CONFIG_CONSOLE_POLL if (unlikely(serial_polled)) { serial_polled = 0; return; } #endif /* get status */ status = in_be16(&bdp->cbd_sc); /* If this one is empty, return happy */ if (status & BD_SC_EMPTY) break; /* get number of characters, and check spce in flip-buffer */ i = in_be16(&bdp->cbd_datlen); /* If we have not enough room in tty flip buffer, then we try * later, which will be the next rx-interrupt or a timeout */ if(tty_buffer_request_room(tty, i) < i) { printk(KERN_WARNING "No room in flip buffer\n"); return; } /* get pointer */ cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); /* loop through the buffer */ while (i-- > 0) { ch = *cp++; port->icount.rx++; flg = TTY_NORMAL; if (status & (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) goto handle_error; if (uart_handle_sysrq_char(port, ch)) continue; #ifdef CONFIG_CONSOLE_POLL if (unlikely(serial_polled)) { serial_polled = 0; return; } #endif error_return: tty_insert_flip_char(tty, ch, flg); } /* End while (i--) */ /* This BD is ready to be used again. Clear status. get next */ clrbits16(&bdp->cbd_sc, BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); setbits16(&bdp->cbd_sc, BD_SC_EMPTY); if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = pinfo->rx_bd_base; else bdp++; } /* End for (;;) */ /* Write back buffer pointer */ pinfo->rx_cur = bdp; /* activate BH processing */ tty_flip_buffer_push(tty); return; /* Error processing */ handle_error: /* Statistics */ if (status & BD_SC_BR) port->icount.brk++; if (status & BD_SC_PR) port->icount.parity++; if (status & BD_SC_FR) port->icount.frame++; if (status & BD_SC_OV) port->icount.overrun++; /* Mask out ignored conditions */ status &= port->read_status_mask; /* Handle the remaining ones */ if (status & BD_SC_BR) flg = TTY_BREAK; else if (status & BD_SC_PR) flg = TTY_PARITY; else if (status & BD_SC_FR) flg = TTY_FRAME; /* overrun does not affect the current character ! */ if (status & BD_SC_OV) { ch = 0; flg = TTY_OVERRUN; /* We skip this buffer */ /* CHECK: Is really nothing senseful there */ /* ASSUMPTION: it contains nothing valid */ i = 0; } #ifdef SUPPORT_SYSRQ port->sysrq = 0; #endif goto error_return; }
/* * Print a string to the serial port trying not to disturb * any possible real use of the port... * * Note that this is called with interrupts already disabled */ static void cpm_uart_console_write(struct console *co, const char *s, u_int count) { struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; unsigned int i; cbd_t __iomem *bdp, *bdbase; unsigned char *cp; unsigned long flags; int nolock = oops_in_progress; if (unlikely(nolock)) { local_irq_save(flags); } else { spin_lock_irqsave(&pinfo->port.lock, flags); } /* Get the address of the host memory buffer. */ bdp = pinfo->tx_cur; bdbase = pinfo->tx_bd_base; /* * Now, do each character. This is not as bad as it looks * since this is a holding FIFO and not a transmitting FIFO. * We could add the complexity of filling the entire transmit * buffer, but we would just wait longer between accesses...... */ for (i = 0; i < count; i++, s++) { /* Wait for transmitter fifo to empty. * Ready indicates output is ready, and xmt is doing * that, not that it is ready for us to send. */ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; /* Send the character out. * If the buffer address is in the CPM DPRAM, don't * convert it. */ cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *cp = *s; out_be16(&bdp->cbd_datlen, 1); setbits16(&bdp->cbd_sc, BD_SC_READY); if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = bdbase; else bdp++; /* if a LF, also do CR... */ if (*s == 10) { while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *cp = 13; out_be16(&bdp->cbd_datlen, 1); setbits16(&bdp->cbd_sc, BD_SC_READY); if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = bdbase; else bdp++; } } /* * Finally, Wait for transmitter & holding register to empty * and restore the IER */ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; pinfo->tx_cur = bdp; if (unlikely(nolock)) { local_irq_restore(flags); } else { spin_unlock_irqrestore(&pinfo->port.lock, flags); } }
/* * Upload a microcode to the I-RAM at a specific address. * * See Documentation/powerpc/qe-firmware.txt for information on QE microcode * uploading. * * Currently, only version 1 is supported, so the 'version' field must be * set to 1. * * The SOC model and revision are not validated, they are only displayed for * informational purposes. * * 'calc_size' is the calculated size, in bytes, of the firmware structure and * all of the microcode structures, minus the CRC. * * 'length' is the size that the structure says it is, including the CRC. */ int qe_upload_firmware(const struct qe_firmware *firmware) { unsigned int i; unsigned int j; u32 crc; size_t calc_size = sizeof(struct qe_firmware); size_t length; const struct qe_header *hdr; if (!firmware) { printk(KERN_ERR "qe-firmware: invalid pointer\n"); return -EINVAL; } hdr = &firmware->header; length = be32_to_cpu(hdr->length); /* Check the magic */ if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || (hdr->magic[2] != 'F')) { printk(KERN_ERR "qe-firmware: not a microcode\n"); return -EPERM; } /* Check the version */ if (hdr->version != 1) { printk(KERN_ERR "qe-firmware: unsupported version\n"); return -EPERM; } /* Validate some of the fields */ if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) { printk(KERN_ERR "qe-firmware: invalid data\n"); return -EINVAL; } /* Validate the length and check if there's a CRC */ calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); for (i = 0; i < firmware->count; i++) /* * For situations where the second RISC uses the same microcode * as the first, the 'code_offset' and 'count' fields will be * zero, so it's okay to add those. */ calc_size += sizeof(__be32) * be32_to_cpu(firmware->microcode[i].count); /* Validate the length */ if (length != calc_size + sizeof(__be32)) { printk(KERN_ERR "qe-firmware: invalid length\n"); return -EPERM; } /* Validate the CRC */ crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size)); if (crc != crc32(0, firmware, calc_size)) { printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n"); return -EIO; } /* * If the microcode calls for it, split the I-RAM. */ if (!firmware->split) setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR); if (firmware->soc.model) printk(KERN_INFO "qe-firmware: firmware '%s' for %u V%u.%u\n", firmware->id, be16_to_cpu(firmware->soc.model), firmware->soc.major, firmware->soc.minor); else printk(KERN_INFO "qe-firmware: firmware '%s'\n", firmware->id); /* * The QE only supports one microcode per RISC, so clear out all the * saved microcode information and put in the new. */ memset(&qe_firmware_info, 0, sizeof(qe_firmware_info)); strcpy(qe_firmware_info.id, firmware->id); qe_firmware_info.extended_modes = firmware->extended_modes; memcpy(qe_firmware_info.vtraps, firmware->vtraps, sizeof(firmware->vtraps)); /* Loop through each microcode. */ for (i = 0; i < firmware->count; i++) { const struct qe_microcode *ucode = &firmware->microcode[i]; /* Upload a microcode if it's present */ if (ucode->code_offset) qe_upload_microcode(firmware, ucode); /* Program the traps for this processor */ for (j = 0; j < 16; j++) { u32 trap = be32_to_cpu(ucode->traps[j]); if (trap) out_be32(&qe_immr->rsp[i].tibcr[j], trap); } /* Enable traps */ out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); } qe_firmware_uploaded = 1; return 0; }
/* * Write a string to the serial port * Note that this is called with interrupts already disabled */ static void cpm_uart_early_write(struct uart_cpm_port *pinfo, const char *string, u_int count) { unsigned int i; cbd_t __iomem *bdp, *bdbase; unsigned char *cpm_outp_addr; /* Get the address of the host memory buffer. */ bdp = pinfo->tx_cur; bdbase = pinfo->tx_bd_base; /* * Now, do each character. This is not as bad as it looks * since this is a holding FIFO and not a transmitting FIFO. * We could add the complexity of filling the entire transmit * buffer, but we would just wait longer between accesses...... */ for (i = 0; i < count; i++, string++) { /* Wait for transmitter fifo to empty. * Ready indicates output is ready, and xmt is doing * that, not that it is ready for us to send. */ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; /* Send the character out. * If the buffer address is in the CPM DPRAM, don't * convert it. */ cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *cpm_outp_addr = *string; out_be16(&bdp->cbd_datlen, 1); setbits16(&bdp->cbd_sc, BD_SC_READY); if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = bdbase; else bdp++; /* if a LF, also do CR... */ if (*string == 10) { while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *cpm_outp_addr = 13; out_be16(&bdp->cbd_datlen, 1); setbits16(&bdp->cbd_sc, BD_SC_READY); if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = bdbase; else bdp++; } } /* * Finally, Wait for transmitter & holding register to empty * and restore the IER */ while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; pinfo->tx_cur = bdp; }
void __init mpc885ads_board_setup(void) { cpm8xx_t *cp; unsigned int *bcsr_io; u8 tmpval8; #ifdef CONFIG_FS_ENET iop8xx_t *io_port; #endif bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); cp = (cpm8xx_t *) immr_map(im_cpm); if (bcsr_io == NULL) { printk(KERN_CRIT "Could not remap BCSR\n"); return; } #ifdef CONFIG_SERIAL_CPM_SMC1 clrbits32(bcsr_io, BCSR1_RS232EN_1); clrbits32(&cp->cp_simode, 0xe0000000 >> 17); /* brg1 */ tmpval8 = in_8(&(cp->cp_smc[0].smc_smcm)) | (SMCM_RX | SMCM_TX); out_8(&(cp->cp_smc[0].smc_smcm), tmpval8); clrbits16(&cp->cp_smc[0].smc_smcmr, SMCMR_REN | SMCMR_TEN); /* brg1 */ #else setbits32(bcsr_io, BCSR1_RS232EN_1); out_be16(&cp->cp_smc[0].smc_smcmr, 0); out_8(&cp->cp_smc[0].smc_smce, 0); #endif #ifdef CONFIG_SERIAL_CPM_SMC2 clrbits32(bcsr_io, BCSR1_RS232EN_2); clrbits32(&cp->cp_simode, 0xe0000000 >> 1); setbits32(&cp->cp_simode, 0x20000000 >> 1); /* brg2 */ tmpval8 = in_8(&(cp->cp_smc[1].smc_smcm)) | (SMCM_RX | SMCM_TX); out_8(&(cp->cp_smc[1].smc_smcm), tmpval8); clrbits16(&cp->cp_smc[1].smc_smcmr, SMCMR_REN | SMCMR_TEN); init_smc2_uart_ioports(0); #else setbits32(bcsr_io, BCSR1_RS232EN_2); out_be16(&cp->cp_smc[1].smc_smcmr, 0); out_8(&cp->cp_smc[1].smc_smce, 0); #endif immr_unmap(cp); iounmap(bcsr_io); #ifdef CONFIG_FS_ENET /* use MDC for MII (common) */ io_port = (iop8xx_t *) immr_map(im_ioport); setbits16(&io_port->iop_pdpar, 0x0080); clrbits16(&io_port->iop_pddir, 0x0080); bcsr_io = ioremap(BCSR5, sizeof(unsigned long)); clrbits32(bcsr_io, BCSR5_MII1_EN); clrbits32(bcsr_io, BCSR5_MII1_RST); #ifndef CONFIG_FC_ENET_HAS_SCC clrbits32(bcsr_io, BCSR5_MII2_EN); clrbits32(bcsr_io, BCSR5_MII2_RST); #endif iounmap(bcsr_io); immr_unmap(io_port); #endif #ifdef CONFIG_PCMCIA_M8XX /*Set up board specific hook-ups */ m8xx_pcmcia_ops.hw_ctrl = pcmcia_hw_setup; m8xx_pcmcia_ops.voltage_set = pcmcia_set_voltage; #endif }