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 void cpm_uart_init_smc(struct uart_cpm_port *pinfo) { int line = pinfo - cpm_uart_ports; volatile smc_t *sp; volatile smc_uart_t *up; pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); sp = pinfo->smcp; up = pinfo->smcup; /* Store address */ pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE; pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE; /* * In case SMC1 is being relocated... */ #if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) up->smc_rbptr = pinfo->smcup->smc_rbase; up->smc_tbptr = pinfo->smcup->smc_tbase; up->smc_rstate = 0; up->smc_tstate = 0; up->smc_brkcr = 1; /* number of break chars */ 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. */ up->smc_mrblr = pinfo->rx_fifosize; up->smc_maxidl = pinfo->rx_fifosize; up->smc_brklen = 0; up->smc_brkec = 0; up->smc_brkcr = 1; cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Enable only rx interrupts clear all pending events. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); }
static void cpm_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { int baud; unsigned long flags; u16 cval, scval, prev_mode; int bits, sbits; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; volatile smc_t *smcp = pinfo->smcp; volatile scc_t *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:set_termios\n", port->line); baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); /* Character length programmed into the mode register is the * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, * 1 or 2 stop bits, minus 1. * The value 'bits' counts this for us. */ cval = 0; scval = 0; /* byte size */ switch (termios->c_cflag & CSIZE) { case CS5: bits = 5; break; case CS6: bits = 6; break; case CS7: bits = 7; break; case CS8: bits = 8; break; /* Never happens, but GCC is too dumb to figure it out */ default: bits = 8; break; } sbits = bits - 5; if (termios->c_cflag & CSTOPB) { cval |= SMCMR_SL; /* Two stops */ scval |= SCU_PSMR_SL; bits++; } if (termios->c_cflag & PARENB) { cval |= SMCMR_PEN; scval |= SCU_PSMR_PEN; bits++; if (!(termios->c_cflag & PARODD)) { cval |= SMCMR_PM_EVEN; scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); } } /* * Set up parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); if (termios->c_iflag & INPCK) port->read_status_mask |= BD_SC_FR | BD_SC_PR; if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) port->read_status_mask |= BD_SC_BR; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= BD_SC_BR; /* * If we're ignore parity and break indicators, ignore * overruns too. (For real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= BD_SC_OV; } /* * !!! ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) port->read_status_mask &= ~BD_SC_EMPTY; spin_lock_irqsave(&port->lock, flags); /* Start bit has not been added (so don't, because we would just * subtract it later), and we need to add one for the number of * stops bits (there is always at least one). */ bits++; if (IS_SMC(pinfo)) { /* Set the mode register. We want to keep a copy of the * enables, because we want to put them back if they were * present. */ prev_mode = smcp->smc_smcmr; smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); } else { sccp->scc_psmr = (sbits << 12) | scval; } cpm_set_brg(pinfo->brg - 1, baud); spin_unlock_irqrestore(&port->lock, flags); }
void serial_init(bd_t *bd) { volatile smc_t *sp; volatile smc_uart_t *up; volatile cbd_t *tbdf, *rbdf; volatile cpm8xx_t *cp; uint dpaddr, memaddr; cp = cpmp; sp = (smc_t*)&(cp->cp_smc[0]); up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); #ifdef CONFIG_MBX if (*MBX_CSR1 & CSR1_COMEN) { /* COM1 is enabled. Initialize SMC1 and use it for * the console port. */ /* Enable SDMA. */ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; /* Use Port B for SMCs instead of other functions. */ cp->cp_pbpar |= 0x00000cc0; cp->cp_pbdir &= ~0x00000cc0; cp->cp_pbodr &= ~0x00000cc0; /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. */ dpaddr = 0x0800; /* Grab a few bytes from the top of memory. EPPC-Bug isn't * running any more, so we can do this. */ memaddr = (bd->bi_memsize - 32) & ~15; /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; rbdf->cbd_bufaddr = memaddr; rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = memaddr+4; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. * See 8xx_io/commproc.c for details. */ cp->cp_simode = 0x10000000; cp->cp_brgc1 = ((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN; /* Enable SMC1 for console output. */ *MBX_CSR1 &= ~CSR1_COMEN; } else { #endif /* SMC1 is used as console port. */ tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; /* Issue a stop transmit, and wait for it. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_STOP_TX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); #ifdef CONFIG_MBX } #endif /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; /* Initialize Tx/Rx parameters. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; }
/* * This routine is called to set the UART divisor registers to match * the specified baud rate for a serial port. */ static void change_speed(ser_info_t *info) { int baud_rate; unsigned cflag, cval, scval, prev_mode; int i, bits, sbits, idx; unsigned long flags; struct serial_state *state; volatile struct smc_regs *smcp; volatile struct scc_regs *sccp; if (!info->port.tty || !info->port.tty->termios) return; cflag = info->port.tty->termios->c_cflag; state = info->state; /* Character length programmed into the mode register is the * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, * 1 or 2 stop bits, minus 1. * The value 'bits' counts this for us. */ cval = 0; scval = 0; /* byte size and parity */ switch (cflag & CSIZE) { case CS5: bits = 5; break; case CS6: bits = 6; break; case CS7: bits = 7; break; case CS8: bits = 8; break; /* Never happens, but GCC is too dumb to figure it out */ default: bits = 8; break; } sbits = bits - 5; if (cflag & CSTOPB) { cval |= SMCMR_SL; /* Two stops */ scval |= SCU_PMSR_SL; bits++; } if (cflag & PARENB) { cval |= SMCMR_PEN; scval |= SCU_PMSR_PEN; bits++; } if (!(cflag & PARODD)) { cval |= SMCMR_PM_EVEN; scval |= (SCU_PMSR_REVP | SCU_PMSR_TEVP); } /* Determine divisor based on baud rate */ i = cflag & CBAUD; if (i >= (sizeof(baud_table)/sizeof(int))) baud_rate = 9600; else baud_rate = baud_table[i]; info->timeout = (TX_BUF_SIZE*HZ*bits); info->timeout += HZ/50; /* Add .02 seconds of slop */ #ifdef modem_control /* CTS flow control flag and modem status interrupts */ info->IER &= ~UART_IER_MSI; if (info->flags & ASYNC_HARDPPS_CD) info->IER |= UART_IER_MSI; if (cflag & CRTSCTS) { info->flags |= ASYNC_CTS_FLOW; info->IER |= UART_IER_MSI; } else info->flags &= ~ASYNC_CTS_FLOW; if (cflag & CLOCAL) info->flags &= ~ASYNC_CHECK_CD; else { info->flags |= ASYNC_CHECK_CD; info->IER |= UART_IER_MSI; } serial_out(info, UART_IER, info->IER); #endif /* * Set up parity check flag */ info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); if (I_INPCK(info->port.tty)) info->read_status_mask |= BD_SC_FR | BD_SC_PR; if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) info->read_status_mask |= BD_SC_BR; /* * Characters to ignore */ info->ignore_status_mask = 0; if (I_IGNPAR(info->port.tty)) info->ignore_status_mask |= BD_SC_PR | BD_SC_FR; if (I_IGNBRK(info->port.tty)) { info->ignore_status_mask |= BD_SC_BR; /* * If we're ignore parity and break indicators, ignore * overruns too. (For real raw support). */ if (I_IGNPAR(info->port.tty)) info->ignore_status_mask |= BD_SC_OV; } /* * !!! ignore all characters if CREAD is not set */ if ((cflag & CREAD) == 0) info->read_status_mask &= ~BD_SC_EMPTY; local_irq_save(flags); /* Start bit has not been added (so don't, because we would just * subtract it later), and we need to add one for the number of * stops bits (there is always at least one). */ bits++; idx = PORT_NUM(state->smc_scc_num); if (state->smc_scc_num & NUM_IS_SCC) { sccp = &pquicc->scc_regs[idx]; sccp->scc_psmr = (sbits << 12) | scval; } else { smcp = &pquicc->smc_regs[idx]; /* Set the mode register. We want to keep a copy of the * enables, because we want to put them back if they were * present. */ prev_mode = smcp->smc_smcmr; smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); } m360_cpm_setbrg((state - rs_table), baud_rate); local_irq_restore(flags); }
static void cpm_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { int baud; unsigned long flags; u16 cval, scval, prev_mode; int bits, sbits; 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]:set_termios\n", port->line); baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); if (baud <= HW_BUF_SPD_THRESHOLD || (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) pinfo->rx_fifosize = 1; else pinfo->rx_fifosize = RX_BUF_SIZE; /* Character length programmed into the mode register is the * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, * 1 or 2 stop bits, minus 1. * The value 'bits' counts this for us. */ cval = 0; scval = 0; /* byte size */ switch (termios->c_cflag & CSIZE) { case CS5: bits = 5; break; case CS6: bits = 6; break; case CS7: bits = 7; break; case CS8: bits = 8; break; /* Never happens, but GCC is too dumb to figure it out */ default: bits = 8; break; } sbits = bits - 5; if (termios->c_cflag & CSTOPB) { cval |= SMCMR_SL; /* Two stops */ scval |= SCU_PSMR_SL; bits++; } if (termios->c_cflag & PARENB) { cval |= SMCMR_PEN; scval |= SCU_PSMR_PEN; bits++; if (!(termios->c_cflag & PARODD)) { cval |= SMCMR_PM_EVEN; scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); } } /* * Update the timeout */ uart_update_timeout(port, termios->c_cflag, baud); /* * Set up parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); if (termios->c_iflag & INPCK) port->read_status_mask |= BD_SC_FR | BD_SC_PR; if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) port->read_status_mask |= BD_SC_BR; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= BD_SC_BR; /* * If we're ignore parity and break indicators, ignore * overruns too. (For real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= BD_SC_OV; } /* * !!! ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) port->read_status_mask &= ~BD_SC_EMPTY; spin_lock_irqsave(&port->lock, flags); /* Start bit has not been added (so don't, because we would just * subtract it later), and we need to add one for the number of * stops bits (there is always at least one). */ bits++; if (IS_SMC(pinfo)) { /* * MRBLR can be changed while an SMC/SCC is operating only * if it is done in a single bus cycle with one 16-bit move * (not two 8-bit bus cycles back-to-back). This occurs when * the cp shifts control to the next RxBD, so the change does * not take effect immediately. To guarantee the exact RxBD * on which the change occurs, change MRBLR only while the * SMC/SCC receiver is disabled. */ out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize); /* Set the mode register. We want to keep a copy of the * enables, because we want to put them back if they were * present. */ prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN); /* Output in *one* operation, so we don't interrupt RX/TX if they * were already enabled. */ out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART | prev_mode); } else { out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); out_be16(&sccp->scc_psmr, (sbits << 12) | scval); } if (pinfo->clk) clk_set_rate(pinfo->clk, baud); else cpm_set_brg(pinfo->brg - 1, baud); spin_unlock_irqrestore(&port->lock, flags); }
static int mpc8260_smc_serial_init(void) { volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; volatile smc_t *sp; volatile smc_uart_t *up; volatile cpm8260_t *cp = &(im->im_cpm); uint dpaddr; volatile serialbuffer_t *rtx; /* initialize pointers to SMC */ sp = (smc_t *) &(im->im_smc[SMC_INDEX]); *(ushort *)(&im->im_dprambase[PROFF_SMC_BASE]) = PROFF_SMC; up = (smc_uart_t *)&im->im_dprambase[PROFF_SMC]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */ /* Allocate space for two buffer descriptors in the DP ram. * damm: allocating space after the two buffers for rx/tx data */ /* allocate size of struct serialbuffer with bd rx/tx, * buffer rx/tx and rx index */ dpaddr = m8260_cpm_dpalloc((sizeof(serialbuffer_t)), 16); rtx = (serialbuffer_t *)&im->im_dprambase[dpaddr]; /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rtx->rxbd.cbd_bufaddr = (uint) &rtx->rxbuf; rtx->rxbd.cbd_sc = 0; rtx->txbd.cbd_bufaddr = (uint) &rtx->txbuf; rtx->txbd.cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = CPMFCR_EB; up->smc_tfcr = CPMFCR_EB; up->smc_brklen = 0; up->smc_brkec = 0; up->smc_brkcr = 0; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* put the SMC channel into NMSI (non multiplexd serial interface) * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17). */ im->im_cpmux.cmx_smr = (im->im_cpmux.cmx_smr&~CMXSMR_MASK)|CMXSMR_VALUE; /* Set up the baud rate generator. */ serial_setbrg (); /* Make the first buffer the only buffer. */ rtx->txbd.cbd_sc |= BD_SC_WRAP; rtx->rxbd.cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* single/multi character receive. */ up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN; up->smc_maxidl = CONFIG_SYS_MAXIDLE; rtx->rxindex = 0; /* Initialize Tx/Rx parameters. */ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC_PAGE, CPM_CR_SMC_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; return (0); }
static void smc_init (int smc_index) { static int cpm_cr_ch[] = { CPM_CR_CH_SMC1, CPM_CR_CH_SMC2 }; volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; volatile smc_t *sp; volatile smc_uart_t *up; volatile cbd_t *tbdf, *rbdf; volatile cpm8xx_t *cp = &(im->im_cpm); uint dpaddr; /* initialize pointers to SMC */ sp = (smc_t *) & (cp->cp_smc[smc_index]); up = (smc_uart_t *) & cp->cp_dparam[proff_smc[smc_index]]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* Enable SDMA. */ im->im_siu_conf.sc_sdcr = 1; /* clear error conditions */ #ifdef CONFIG_SYS_SDSR im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR; #else im->im_sdma.sdma_sdsr = 0x83; #endif /* clear SDMA interrupt mask */ #ifdef CONFIG_SYS_SDMR im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR; #else im->im_sdma.sdma_sdmr = 0x00; #endif #if defined(CONFIG_FADS) /* Enable RS232 */ *((uint *) BCSR1) &= ~(smc_index == 1 ? BCSR1_RS232EN_1 : BCSR1_RS232EN_2); #endif #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) /* Enable Monitor Port Transceiver */ *((uchar *) BCSR0) |= BCSR0_ENMONXCVR; #endif /* Set the physical address of the host memory buffers in * the buffer descriptors. */ #ifdef CONFIG_SYS_ALLOC_DPRAM dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8); #else dpaddr = CPM_POST_BASE; #endif /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. * damm: allocating space after the two buffers for rx/tx data */ rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr]; rbdf->cbd_bufaddr = (uint) (rbdf + 2); rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr + sizeof (cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; #if defined(CONFIG_MBX) board_serial_init (); #endif /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. * Set local loopback mode. */ sp->smc_smcmr = smcr_mk_clen (9) | SMCMR_SM_UART | (ushort) 0x0004; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. */ cp->cp_simode = 0x00000000; cp->cp_brgc1 = (((gd->cpu_clk / 16 / gd->baudrate) - 1) << 1) | CPM_BRG_EN; /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; /* Initialize Tx/Rx parameters. */ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; cp->cp_cpcr = mk_cr_cmd (cpm_cr_ch[smc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; }
unsigned long serial_init(int ignored, bd_t *bd) { volatile smc_t *sp; volatile smc_uart_t *up; volatile cbd_t *tbdf, *rbdf; volatile cpm8xx_t *cp; uint dpaddr, memaddr; #ifndef CONFIG_MBX uint ui; #endif cp = cpmp; sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); #ifdef CONFIG_FADS /* Enable SMC1/2 transceivers. */ *((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2); #endif #ifndef CONFIG_MBX { /* Initialize SMCx and use it for the console port. */ /* Enable SDMA. */ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; #ifdef TQM_SMC2_CONSOLE /* Use Port A for SMC2 instead of other functions. */ iopp->iop_papar |= 0x00c0; iopp->iop_padir &= ~0x00c0; iopp->iop_paodr &= ~0x00c0; #else /* Use Port B for SMCs instead of other functions. */ cp->cp_pbpar |= 0x00000cc0; cp->cp_pbdir &= ~0x00000cc0; cp->cp_pbodr &= ~0x00000cc0; #endif /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. */ dpaddr = 0x0800; /* Grab a few bytes from the top of memory for SMC FIFOs. */ memaddr = (bd->bi_memsize - 32) & ~15; /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; rbdf->cbd_bufaddr = memaddr; rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = memaddr+4; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. * See 8xx_io/commproc.c for details. * This wires BRG1 to SMC1 and BRG2 to SMC2; */ cp->cp_simode = 0x10000000; ui = bd->bi_intfreq / 16 / bd->bi_baudrate; #ifdef TQM_SMC2_CONSOLE cp->cp_brgc2 = #else cp->cp_brgc1 = #endif ((ui - 1) < 4096) ? (((ui - 1) << 1) | CPM_BRG_EN) : ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16); #else /* CONFIG_MBX */ if (*MBX_CSR1 & CSR1_COMEN) { /* COM1 is enabled. Initialize SMC1 and use it for * the console port. */ /* Enable SDMA. */ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; /* Use Port B for SMCs instead of other functions. */ cp->cp_pbpar |= 0x00000cc0; cp->cp_pbdir &= ~0x00000cc0; cp->cp_pbodr &= ~0x00000cc0; /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. */ dpaddr = 0x0800; /* Grab a few bytes from the top of memory. EPPC-Bug isn't * running any more, so we can do this. */ memaddr = (bd->bi_memsize - 32) & ~15; /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; rbdf->cbd_bufaddr = memaddr; rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = memaddr+4; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. * See 8xx_io/commproc.c for details. */ cp->cp_simode = 0x10000000; cp->cp_brgc1 = (((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN; /* Enable SMC1 for console output. */ *MBX_CSR1 &= ~CSR1_COMEN; } else { #endif /* ndef CONFIG_MBX */ /* SMCx is used as console port. */ tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; /* Issue a stop transmit, and wait for it. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_STOP_TX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); } /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; /* Initialize Tx/Rx parameters. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; /* This is ignored. */ return 0; } void serial_putc(void *ignored, const char c) { volatile cbd_t *tbdf; volatile char *buf; volatile smc_uart_t *up; up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; /* Wait for last character to go. */ buf = (char *)tbdf->cbd_bufaddr; while (tbdf->cbd_sc & BD_SC_READY); *buf = c; tbdf->cbd_datlen = 1; tbdf->cbd_sc |= BD_SC_READY; } char serial_getc(void *ignored) { volatile cbd_t *rbdf; volatile char *buf; volatile smc_uart_t *up; char c; up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; /* Wait for character to show up. */ buf = (char *)rbdf->cbd_bufaddr; while (rbdf->cbd_sc & BD_SC_EMPTY); c = *buf; rbdf->cbd_sc |= BD_SC_EMPTY; return(c); } int serial_tstc(void *ignored) { volatile cbd_t *rbdf; volatile smc_uart_t *up; up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; return(!(rbdf->cbd_sc & BD_SC_EMPTY)); } void serial_close(unsigned long com_port) { }
void kgdb_serial_init (void) { volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; volatile smc_t *sp; volatile smc_uart_t *up; volatile cbd_t *tbdf, *rbdf; volatile cpm8260_t *cp = &(im->im_cpm); uint dpaddr, speed = CONFIG_KGDB_BAUDRATE; char *s, *e; if ((s = getenv("kgdbrate")) != NULL && *s != '\0') { ulong rate = simple_strtoul(s, &e, 10); if (e > s && *e == '\0') speed = rate; } /* initialize pointers to SMC */ sp = (smc_t *) &(im->im_smc[KGDB_SMC_INDEX]); *(ushort *)(&im->im_dprambase[KGDB_PROFF_SMC_BASE]) = KGDB_PROFF_SMC; up = (smc_uart_t *)&im->im_dprambase[KGDB_PROFF_SMC]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* NOTE: I/O port pins are set up via the iop_conf_tab[] table */ /* Allocate space for two buffer descriptors in the DP ram. * damm: allocating space after the two buffers for rx/tx data */ dpaddr = m8260_cpm_dpalloc((2 * sizeof (cbd_t)) + 2, 16); /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rbdf = (cbd_t *)&im->im_dprambase[dpaddr]; rbdf->cbd_bufaddr = (uint) (rbdf+2); rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = CPMFCR_EB; up->smc_tfcr = CPMFCR_EB; up->smc_brklen = 0; up->smc_brkec = 0; up->smc_brkcr = 0; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* put the SMC channel into NMSI (non multiplexd serial interface) * mode and wire either BRG7 to SMC1 or BRG8 to SMC2 (15-17). */ im->im_cpmux.cmx_smr = (im->im_cpmux.cmx_smr & ~KGDB_CMXSMR_MASK) | KGDB_CMXSMR_VALUE; /* Set up the baud rate generator. */ #if defined(CONFIG_KGDB_USE_EXTC) m8260_cpm_extcbrg(brg_map[KGDB_SMC_INDEX], speed, CONFIG_KGDB_EXTC_RATE, CONFIG_KGDB_EXTC_PINSEL); #else m8260_cpm_setbrg(brg_map[KGDB_SMC_INDEX], speed); #endif /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; /* Initialize Tx/Rx parameters. */ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; cp->cp_cpcr = mk_cr_cmd(KGDB_CPM_CR_SMC_PAGE, KGDB_CPM_CR_SMC_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; printf("SMC%d at %dbps ", CONFIG_KGDB_INDEX, speed); }
static int smc_init (void) { volatile immap_t *im = (immap_t *)CFG_IMMR; volatile smc_t *sp; volatile smc_uart_t *up; volatile cbd_t *tbdf, *rbdf; volatile cpm8xx_t *cp = &(im->im_cpm); #if (!defined(CONFIG_8xx_CONS_SMC1)) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850)) volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport); #endif uint dpaddr; /* initialize pointers to SMC */ sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]); up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* Enable SDMA. */ im->im_siu_conf.sc_sdcr = 1; /* clear error conditions */ #ifdef CFG_SDSR im->im_sdma.sdma_sdsr = CFG_SDSR; #else im->im_sdma.sdma_sdsr = 0x83; #endif /* clear SDMA interrupt mask */ #ifdef CFG_SDMR im->im_sdma.sdma_sdmr = CFG_SDMR; #else im->im_sdma.sdma_sdmr = 0x00; #endif #if defined(CONFIG_8xx_CONS_SMC1) /* Use Port B for SMC1 instead of other functions. */ cp->cp_pbpar |= 0x000000c0; cp->cp_pbdir &= ~0x000000c0; cp->cp_pbodr &= ~0x000000c0; #else /* CONFIG_8xx_CONS_SMC2 */ # if defined(CONFIG_MPC823) || defined(CONFIG_MPC850) /* Use Port A for SMC2 instead of other functions. */ ip->iop_papar |= 0x00c0; ip->iop_padir &= ~0x00c0; ip->iop_paodr &= ~0x00c0; # else /* must be a 860 then */ /* Use Port B for SMC2 instead of other functions. */ cp->cp_pbpar |= 0x00000c00; cp->cp_pbdir &= ~0x00000c00; cp->cp_pbodr &= ~0x00000c00; # endif #endif #if defined(CONFIG_FADS) || defined(CONFIG_ADS) /* Enable RS232 */ #if defined(CONFIG_8xx_CONS_SMC1) *((uint *) BCSR1) &= ~BCSR1_RS232EN_1; #else *((uint *) BCSR1) &= ~BCSR1_RS232EN_2; #endif #endif /* CONFIG_FADS */ #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) /* Enable Monitor Port Transceiver */ *((uchar *) BCSR0) |= BCSR0_ENMONXCVR ; #endif /* CONFIG_RPXLITE */ /* Set the physical address of the host memory buffers in * the buffer descriptors. */ #ifdef CFG_ALLOC_DPRAM dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ; #else dpaddr = CPM_SERIAL_BASE ; #endif /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. * damm: allocating space after the two buffers for rx/tx data */ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; rbdf->cbd_bufaddr = (uint) (rbdf+2); rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; #if defined(CONFIG_MBX) board_serial_init(); #endif /* CONFIG_MBX */ /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. */ smc_setbrg (); /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; /* Initialize Tx/Rx parameters. */ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; return (0); }
static int serial_mpc8xx_probe(struct udevice *dev) { immap_t __iomem *im = (immap_t __iomem *)CONFIG_SYS_IMMR; smc_t __iomem *sp; smc_uart_t __iomem *up; cpm8xx_t __iomem *cp = &(im->im_cpm); struct serialbuffer __iomem *rtx; /* initialize pointers to SMC */ sp = cp->cp_smc + SMC_INDEX; up = (smc_uart_t __iomem *)&cp->cp_dparam[PROFF_SMC]; /* Disable relocation */ out_be16(&up->smc_rpbase, 0); /* Disable transmitter/receiver. */ clrbits_be16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); /* Enable SDMA. */ out_be32(&im->im_siu_conf.sc_sdcr, 1); /* clear error conditions */ out_8(&im->im_sdma.sdma_sdsr, CONFIG_SYS_SDSR); /* clear SDMA interrupt mask */ out_8(&im->im_sdma.sdma_sdmr, CONFIG_SYS_SDMR); /* Use Port B for SMCx instead of other functions. */ setbits_be32(&cp->cp_pbpar, IOPINS); clrbits_be32(&cp->cp_pbdir, IOPINS); clrbits_be16(&cp->cp_pbodr, IOPINS); /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rtx = (struct serialbuffer __iomem *)&cp->cp_dpmem[CPM_SERIAL_BASE]; /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. * damm: allocating space after the two buffers for rx/tx data */ out_be32(&rtx->rxbd.cbd_bufaddr, (__force uint)&rtx->rxbuf); out_be16(&rtx->rxbd.cbd_sc, 0); out_be32(&rtx->txbd.cbd_bufaddr, (__force uint)&rtx->txbuf); out_be16(&rtx->txbd.cbd_sc, 0); /* Set up the uart parameters in the parameter ram. */ out_be16(&up->smc_rbase, CPM_SERIAL_BASE); out_be16(&up->smc_tbase, CPM_SERIAL_BASE + sizeof(cbd_t)); out_8(&up->smc_rfcr, SMC_EB); out_8(&up->smc_tfcr, SMC_EB); /* 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); /* Mask all interrupts and remove anything pending. */ out_8(&sp->smc_smcm, 0); out_8(&sp->smc_smce, 0xff); /* Set up the baud rate generator */ serial_mpc8xx_setbrg(dev, gd->baudrate); /* Make the first buffer the only buffer. */ setbits_be16(&rtx->txbd.cbd_sc, BD_SC_WRAP); setbits_be16(&rtx->rxbd.cbd_sc, BD_SC_EMPTY | BD_SC_WRAP); /* single/multi character receive. */ out_be16(&up->smc_mrblr, CONFIG_SYS_SMC_RXBUFLEN); out_be16(&up->smc_maxidl, CONFIG_SYS_MAXIDLE); out_be32(&rtx->rxindex, 0); /* Initialize Tx/Rx parameters. */ while (in_be16(&cp->cp_cpcr) & CPM_CR_FLG) /* wait if cp is busy */ ; out_be16(&cp->cp_cpcr, mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG); while (in_be16(&cp->cp_cpcr) & CPM_CR_FLG) /* wait if cp is busy */ ; /* Enable transmitter/receiver. */ setbits_be16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); return 0; }
int smc1_init (void) { volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; volatile smc_t *sp; volatile smc_uart_t *up; volatile cbd_t *tbdf, *rbdf; volatile cpm8xx_t *cp = &(im->im_cpm); uint dpaddr; /* initialize pointers to SMC */ sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]); up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* Enable SDMA. */ im->im_siu_conf.sc_sdcr = 1; /* clear error conditions */ #ifdef CONFIG_SYS_SDSR im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR; #else im->im_sdma.sdma_sdsr = 0x83; #endif /* clear SDMA interrupt mask */ #ifdef CONFIG_SYS_SDMR im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR; #else im->im_sdma.sdma_sdmr = 0x00; #endif /* Use Port B for SMC1 instead of other functions. */ cp->cp_pbpar |= 0x000000c0; cp->cp_pbdir &= ~0x000000c0; cp->cp_pbodr &= ~0x000000c0; /* Set the physical address of the host memory buffers in * the buffer descriptors. */ #ifdef CONFIG_SYS_ALLOC_DPRAM dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ; #else dpaddr = CPM_KEYBOARD_BASE ; #endif /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. * damm: allocating space after the two buffers for rx/tx data */ rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; rbdf->cbd_bufaddr = (uint) (rbdf+2); rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. */ smc1_setbrg (); /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Single character receive. */ up->smc_mrblr = 1; up->smc_maxidl = 0; /* Initialize Tx/Rx parameters. */ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; return (0); }
static int smc_init (void) { volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; volatile smc_t *sp; volatile smc_uart_t *up; volatile cpm8xx_t *cp = &(im->im_cpm); #if (!defined(CONFIG_8xx_CONS_SMC1)) && (defined(CONFIG_MPC823) || defined(CONFIG_MPC850)) volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport); #endif uint dpaddr; volatile serialbuffer_t *rtx; /* initialize pointers to SMC */ sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]); up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC]; #ifdef CONFIG_SYS_SMC_UCODE_PATCH up = (smc_uart_t *) &cp->cp_dpmem[up->smc_rpbase]; #else /* Disable relocation */ up->smc_rpbase = 0; #endif /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* Enable SDMA. */ im->im_siu_conf.sc_sdcr = 1; /* clear error conditions */ #ifdef CONFIG_SYS_SDSR im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR; #else im->im_sdma.sdma_sdsr = 0x83; #endif /* clear SDMA interrupt mask */ #ifdef CONFIG_SYS_SDMR im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR; #else im->im_sdma.sdma_sdmr = 0x00; #endif #if defined(CONFIG_8xx_CONS_SMC1) /* Use Port B for SMC1 instead of other functions. */ cp->cp_pbpar |= 0x000000c0; cp->cp_pbdir &= ~0x000000c0; cp->cp_pbodr &= ~0x000000c0; #else /* CONFIG_8xx_CONS_SMC2 */ # if defined(CONFIG_MPC823) || defined(CONFIG_MPC850) /* Use Port A for SMC2 instead of other functions. */ ip->iop_papar |= 0x00c0; ip->iop_padir &= ~0x00c0; ip->iop_paodr &= ~0x00c0; # else /* must be a 860 then */ /* Use Port B for SMC2 instead of other functions. */ cp->cp_pbpar |= 0x00000c00; cp->cp_pbdir &= ~0x00000c00; cp->cp_pbodr &= ~0x00000c00; # endif #endif #if defined(CONFIG_FADS) || defined(CONFIG_ADS) /* Enable RS232 */ #if defined(CONFIG_8xx_CONS_SMC1) *((uint *) BCSR1) &= ~BCSR1_RS232EN_1; #else *((uint *) BCSR1) &= ~BCSR1_RS232EN_2; #endif #endif /* CONFIG_FADS */ #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) /* Enable Monitor Port Transceiver */ *((uchar *) BCSR0) |= BCSR0_ENMONXCVR ; #endif /* CONFIG_RPXLITE */ /* Set the physical address of the host memory buffers in * the buffer descriptors. */ #ifdef CONFIG_SYS_ALLOC_DPRAM /* allocate * size of struct serialbuffer with bd rx/tx, buffer rx/tx and rx index */ dpaddr = dpram_alloc_align((sizeof(serialbuffer_t)), 8); #else dpaddr = CPM_SERIAL_BASE ; #endif rtx = (serialbuffer_t *)&cp->cp_dpmem[dpaddr]; /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. * damm: allocating space after the two buffers for rx/tx data */ rtx->rxbd.cbd_bufaddr = (uint) &rtx->rxbuf; rtx->rxbd.cbd_sc = 0; rtx->txbd.cbd_bufaddr = (uint) &rtx->txbuf; rtx->txbd.cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = SMC_EB; up->smc_tfcr = SMC_EB; #if defined (CONFIG_SYS_SMC_UCODE_PATCH) up->smc_rbptr = up->smc_rbase; up->smc_tbptr = up->smc_tbase; up->smc_rstate = 0; up->smc_tstate = 0; #endif #if defined(CONFIG_MBX) board_serial_init(); #endif /* CONFIG_MBX */ /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; #ifdef CONFIG_SYS_SPC1920_SMC1_CLK4 /* clock source is PLD */ /* set freq to 19200 Baud */ *((volatile uchar *) CONFIG_SYS_SPC1920_PLD_BASE+6) = 0x3; /* configure clk4 as input */ im->im_ioport.iop_pdpar |= 0x800; im->im_ioport.iop_pddir &= ~0x800; cp->cp_simode = ((cp->cp_simode & ~0xf000) | 0x7000); #else /* Set up the baud rate generator */ smc_setbrg (); #endif /* Make the first buffer the only buffer. */ rtx->txbd.cbd_sc |= BD_SC_WRAP; rtx->rxbd.cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* single/multi character receive. */ up->smc_mrblr = CONFIG_SYS_SMC_RXBUFLEN; up->smc_maxidl = CONFIG_SYS_MAXIDLE; rtx->rxindex = 0; /* Initialize Tx/Rx parameters. */ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */ ; /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; return (0); }
void serial_init(bd_t *bd) { volatile smc_t *sp; volatile smc_uart_t *up; volatile scc_t *sccp; volatile scc_uart_t *sup; volatile cbd_t *tbdf, *rbdf; volatile immap_t *ip; volatile iop8260_t *io; volatile cpm8260_t *cp; uint dpaddr, memaddr; ip = (immap_t *)IMAP_ADDR; cp = &ip->im_cpm; io = &ip->im_ioport; /* Perform a reset. */ cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); /* Wait for it. */ while (cp->cp_cpcr & CPM_CR_FLG); #ifdef CONFIG_ADS8260 /* Enable the RS-232 transceivers. */ *(volatile uint *)(BCSR_ADDR + 4) &= ~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2); #endif #ifdef SCC_CONSOLE sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]); sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); /* Use Port D for SCC1 instead of other functions. */ io->iop_ppard |= 0x00000003; io->iop_psord &= ~0x00000001; /* Rx */ io->iop_psord |= 0x00000002; /* Tx */ io->iop_pdird &= ~0x00000001; /* Rx */ io->iop_pdird |= 0x00000002; /* Tx */ #else sp = (smc_t*)&(ip->im_smc[0]); *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1]; /* Disable transmitter/receiver. */ sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); /* Use Port D for SMC1 instead of other functions. */ io->iop_ppard |= 0x00c00000; io->iop_pdird |= 0x00400000; io->iop_pdird &= ~0x00800000; io->iop_psord &= ~0x00c00000; #endif /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to * change with newer versions of the firmware. */ dpaddr = 0x0800; /* Grab a few bytes from the top of memory. */ memaddr = (bd->bi_memsize - 256) & ~15; /* Set the physical address of the host memory buffers in * the buffer descriptors. */ rbdf = (cbd_t *)&ip->im_dprambase[dpaddr]; rbdf->cbd_bufaddr = memaddr; rbdf->cbd_sc = 0; tbdf = rbdf + 1; tbdf->cbd_bufaddr = memaddr+128; tbdf->cbd_sc = 0; /* Set up the uart parameters in the parameter ram. */ #ifdef SCC_CONSOLE sup->scc_genscc.scc_rbase = dpaddr; sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t); /* Set up the uart parameters in the * parameter ram. */ sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; sup->scc_genscc.scc_mrblr = 128; sup->scc_maxidl = 8; sup->scc_brkcr = 1; sup->scc_parec = 0; sup->scc_frmec = 0; sup->scc_nosec = 0; sup->scc_brkec = 0; sup->scc_uaddr1 = 0; sup->scc_uaddr2 = 0; sup->scc_toseq = 0; sup->scc_char1 = 0x8000; sup->scc_char2 = 0x8000; sup->scc_char3 = 0x8000; sup->scc_char4 = 0x8000; sup->scc_char5 = 0x8000; sup->scc_char6 = 0x8000; sup->scc_char7 = 0x8000; sup->scc_char8 = 0x8000; sup->scc_rccm = 0xc0ff; /* Send the CPM an initialize command. */ cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sccp->scc_gsmrh = 0; sccp->scc_gsmrl = (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); /* Disable all interrupts and clear all pending * events. */ sccp->scc_sccm = 0; sccp->scc_scce = 0xffff; sccp->scc_dsr = 0x7e7e; sccp->scc_pmsr = 0x3000; /* Wire BRG1 to SCC1. The console driver will take care of * others. */ ip->im_cpmux.cmx_scr = 0; #else up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); up->smc_rfcr = CPMFCR_EB; up->smc_tfcr = CPMFCR_EB; up->smc_brklen = 0; up->smc_brkec = 0; up->smc_brkcr = 0; up->smc_mrblr = 128; up->smc_maxidl = 8; /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; /* Mask all interrupts and remove anything pending. */ sp->smc_smcm = 0; sp->smc_smce = 0xff; /* Set up the baud rate generator. */ ip->im_cpmux.cmx_smr = 0; #endif /* The baud rate divisor needs to be coordinated with clk_8260(). */ ip->im_brgc1 = (((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) | CPM_BRG_EN; /* Make the first buffer the only buffer. */ tbdf->cbd_sc |= BD_SC_WRAP; rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; /* Initialize Tx/Rx parameters. */ #ifdef SCC_CONSOLE sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); #else cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; #endif }