Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);

}
Beispiel #4
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
}
Beispiel #9
0
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)
{
}
Beispiel #10
0
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);
}
Beispiel #12
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;
}
Beispiel #13
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);
}
Beispiel #14
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);
}
Beispiel #15
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
}