Ejemplo n.º 1
0
static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op)
{
	const struct fs_platform_info *fpi = fep->fpi;

	cpm2_map_t *immap = fs_enet_immap;
	cpm_cpm2_t *cpmp = &immap->im_cpm;
	u32 v;
	int i;

	/* Currently I don't know what feature call will look like. But 
	   I guess there'd be something like do_cpm_cmd() which will require page & sblock */
	v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op);
	W32(cpmp, cp_cpcr, v | CPM_CR_FLG);
	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
		if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
			break;

	if (i >= MAX_CR_CMD_LOOPS) {
		printk(KERN_ERR "%s(): Not able to issue CPM command\n",
		       __FUNCTION__);
		return 1;
	}

	return 0;
}
Ejemplo n.º 2
0
void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
{
	ushort val;
	int line = port - cpm_uart_ports;
	volatile cpm8xx_t *cp = cpmp;

	switch (line) {
	case UART_SMC1:
		val = mk_cr_cmd(CPM_CR_CH_SMC1, cmd) | CPM_CR_FLG;
		break;
	case UART_SMC2:
		val = mk_cr_cmd(CPM_CR_CH_SMC2, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC1:
		val = mk_cr_cmd(CPM_CR_CH_SCC1, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC2:
		val = mk_cr_cmd(CPM_CR_CH_SCC2, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC3:
		val = mk_cr_cmd(CPM_CR_CH_SCC3, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC4:
		val = mk_cr_cmd(CPM_CR_CH_SCC4, cmd) | CPM_CR_FLG;
		break;
	default:
		return;

	}
	cp->cp_cpcr = val;
	while (cp->cp_cpcr & CPM_CR_FLG) ;
}
Ejemplo n.º 3
0
void cpm_line_cr_cmd(int line, int cmd)
{
	ushort val;
	volatile cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm);

	switch (line) {
	case UART_SMC1:
		val = mk_cr_cmd(CPM_CR_CH_SMC1, cmd) | CPM_CR_FLG;
		break;
	case UART_SMC2:
		val = mk_cr_cmd(CPM_CR_CH_SMC2, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC1:
		val = mk_cr_cmd(CPM_CR_CH_SCC1, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC2:
		val = mk_cr_cmd(CPM_CR_CH_SCC2, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC3:
		val = mk_cr_cmd(CPM_CR_CH_SCC3, cmd) | CPM_CR_FLG;
		break;
	case UART_SCC4:
		val = mk_cr_cmd(CPM_CR_CH_SCC4, cmd) | CPM_CR_FLG;
		break;
	default:
		return;

	}
	cp->cp_cpcr = val;
	while (cp->cp_cpcr & CPM_CR_FLG) ;
}
Ejemplo n.º 4
0
static void end_break(ser_info_t *info)
{
	volatile QUICC *cp;
	ushort	chan;
	int idx;

	cp = pquicc;

	idx = PORT_NUM(info->state->smc_scc_num);
	if (info->state->smc_scc_num & NUM_IS_SCC)
		chan = scc_chan_map[idx];
	else
		chan = smc_chan_map[idx];

	cp->cp_cr = mk_cr_cmd(chan, CPM_CR_RESTART_TX) | CPM_CR_FLG;
	while (cp->cp_cr & CPM_CR_FLG);
}
Ejemplo n.º 5
0
static void __exit cpm_load_cleanup (void)
{
	int i;
	volatile immap_t *immap = (immap_t *) IMAP_ADDR;
	volatile cpm8xx_t *cp = &immap->im_cpm;
	volatile risc_timer_t *rtram =
			(risc_timer_t *) & cp->cp_dparam[PROFF_RTIMER];

	remove_proc_entry (PROC_NAME, NULL);

	/* Stop the general purpose timers.
	 */
	immap->im_cpmtimer.cpmt_tgcr |=
			CPMTIMER_TGCR_STP1 | CPMTIMER_TGCR_STP2;

	/* Stop the RISC timers.
	 */
#ifdef RCCR_BUG
	*(uint *) & (immap->im_cpm.cp_rccr) &= ~0x80000000;
#else
	immap->im_cpm.cp_rccr &= ~0x8000;
#endif

	/* Disable RISC timers.
	 */
	for (i = 0; i < RISC_TIMER_MAX; i++) {
		rtram->tm_cmd = (i << 16);

		/* Wait for a previous command to clear.
		 */
		while (cp->cp_cpcr & CPM_CR_FLG);

		/* Issue SET TIMER command.
		 */
		cp->cp_cpcr = mk_cr_cmd (CPM_CR_CH_TIMER, CPM_CR_SET_TIMER) |
					 CPM_CR_FLG;
#if 0
		while (cp->cp_cpcr & CPM_CR_FLG);
#endif
	}

	m8xx_cpm_dpfree (risc_dpram_timers);
}
Ejemplo n.º 6
0
/* Use the IDMA controller to transfer data from I/O memory to local RAM.
 * The dst address must be a physical address suitable for use by the DMA 
 * controller with no translation.  The src address must be a kernel virtual 
 * address.  The src address is translated to a physical address via 
 * virt_to_phys().
 * The dinc argument specifies whether or not the dest address is incremented
 * by the DMA controller.  The source address is incremented if and only if sinc
 * is non-zero.  The source address is always incremented since the 
 * source is always host RAM.
 */
static void 
idma_pci9_write(u8 *dst, u8 *src, int bytes, int unit_size, int dinc)
{
	unsigned long flags;
	volatile idma_t *pram = &idma_dpram->pram;
	volatile idma_bd_t *bd = &idma_dpram->bd;
	volatile cpm2_map_t *immap = cpm2_immr;

	local_irq_save(flags);

	/* initialize IDMA parameter RAM for this transfer */
	if (dinc)
		pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
			  | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
	else
		pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC 
			  | IDMA_DCM_SD_MEM2MEM;
	pram->ibdptr = pram->ibase;
	pram->sts = unit_size;
	pram->istate = 0;

	/* initialize the buffer descriptor */
	bd->dst = (uint) dst;
	bd->src = virt_to_phys(src);
	bd->len = bytes;
	bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL
		  | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB;

	/* issue the START_IDMA command to the CP */
	while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
	immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0,
					 CPM_CR_START_IDMA) | CPM_CR_FLG;
	while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);

	/* wait for transfer to complete */
	while(bd->flags & IDMA_BD_V);

	local_irq_restore(flags);

	return;
}
Ejemplo n.º 7
0
void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
{
    ulong val;
    int line = port - cpm_uart_ports;
    volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);


    switch (line) {
    case UART_SMC1:
        val = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0,
                cmd) | CPM_CR_FLG;
        break;
    case UART_SMC2:
        val = mk_cr_cmd(CPM_CR_SMC2_PAGE, CPM_CR_SMC2_SBLOCK, 0,
                cmd) | CPM_CR_FLG;
        break;
    case UART_SCC1:
        val = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0,
                cmd) | CPM_CR_FLG;
        break;
    case UART_SCC2:
        val = mk_cr_cmd(CPM_CR_SCC2_PAGE, CPM_CR_SCC2_SBLOCK, 0,
                cmd) | CPM_CR_FLG;
        break;
    case UART_SCC3:
        val = mk_cr_cmd(CPM_CR_SCC3_PAGE, CPM_CR_SCC3_SBLOCK, 0,
                cmd) | CPM_CR_FLG;
        break;
    case UART_SCC4:
        val = mk_cr_cmd(CPM_CR_SCC4_PAGE, CPM_CR_SCC4_SBLOCK, 0,
                cmd) | CPM_CR_FLG;
        break;
    default:
        return;

    }
    cp->cp_cpcr = val;
    while (cp->cp_cpcr & CPM_CR_FLG) ;

    cpm2_unmap(cp);
}
Ejemplo n.º 8
0
void cpm_line_cr_cmd(int line, int cmd)
{
	volatile cpm_cpm2_t *cp = cpmp;
	ulong val;

	switch (line) {
	case UART_SMC1:
		val = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0,
				cmd) | CPM_CR_FLG;
		break;
	case UART_SMC2:
		val = mk_cr_cmd(CPM_CR_SMC2_PAGE, CPM_CR_SMC2_SBLOCK, 0,
				cmd) | CPM_CR_FLG;
		break;
	case UART_SCC1:
		val = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0,
				cmd) | CPM_CR_FLG;
		break;
	case UART_SCC2:
		val = mk_cr_cmd(CPM_CR_SCC2_PAGE, CPM_CR_SCC2_SBLOCK, 0,
				cmd) | CPM_CR_FLG;
		break;
	case UART_SCC3:
		val = mk_cr_cmd(CPM_CR_SCC3_PAGE, CPM_CR_SCC3_SBLOCK, 0,
				cmd) | CPM_CR_FLG;
		break;
	case UART_SCC4:
		val = mk_cr_cmd(CPM_CR_SCC4_PAGE, CPM_CR_SCC4_SBLOCK, 0,
				cmd) | CPM_CR_FLG;
		break;
	default:
		return;

	}
	cp->cp_cpcr = val;
	while (cp->cp_cpcr & CPM_CR_FLG) ;
}
Ejemplo n.º 9
0
/* The interrupt handler.
 * This is called from the CPM handler, not the MPC core interrupt.
 */
static void
cpm_enet_interrupt(void *dev_id)
{
	struct	device *dev = dev_id;
	volatile struct	cpm_enet_private *cep;
	volatile cbd_t	*bdp;
	ushort	int_events;
	int	must_restart;

	cep = (struct cpm_enet_private *)dev->priv;
	if (dev->interrupt)
		printk("%s: Re-entering the interrupt handler.\n", dev->name);

	dev->interrupt = 1;

	/* Get the interrupt events that caused us to be here.
	*/
	int_events = cep->sccp->scc_scce;
	cep->sccp->scc_scce = int_events;
	must_restart = 0;

	/* Handle receive event in its own function.
	*/
	if (int_events & SCCE_ENET_RXF)
		cpm_enet_rx(dev_id);

	/* Check for a transmit error.  The manual is a little unclear
	 * about this, so the debug code until I get it figured out.  It
	 * appears that if TXE is set, then TXB is not set.  However,
	 * if carrier sense is lost during frame transmission, the TXE
	 * bit is set, "and continues the buffer transmission normally."
	 * I don't know if "normally" implies TXB is set when the buffer
	 * descriptor is closed.....trial and error :-).
	 */
#if 0
	if (int_events & SCCE_ENET_TXE) {

		/* Transmission errors.
		*/
		bdp = cep->dirty_tx;
#ifndef final_version
		printk("CPM ENET xmit error %x\n", bdp->cbd_sc);
		if (bdp->cbd_sc & BD_ENET_TX_READY)
			printk("HEY! Enet xmit interrupt and TX_READY.\n");
#endif
		if (bdp->cbd_sc & BD_ENET_TX_HB)	/* No heartbeat */
			cep->stats.tx_heartbeat_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_LC)	/* Late collision */
			cep->stats.tx_window_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_RL)	/* Retrans limit */
			cep->stats.tx_aborted_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_UN)	/* Underrun */
			cep->stats.tx_fifo_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_CSL)	/* Carrier lost */
			cep->stats.tx_carrier_errors++;

		cep->stats.tx_errors++;

		/* No heartbeat or Lost carrier are not really bad errors.
		 * The others require a restart transmit command.
		 */
		if (bdp->cbd_sc &
		    (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN))
			must_restart = 1;
	}
#endif

	/* Transmit OK, or non-fatal error.  Update the buffer descriptors.
	*/
	if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
#if 1
	    bdp = cep->dirty_tx;
	    while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
		if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
		    break;

		if (bdp->cbd_sc & BD_ENET_TX_HB)	/* No heartbeat */
			cep->stats.tx_heartbeat_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_LC)	/* Late collision */
			cep->stats.tx_window_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_RL)	/* Retrans limit */
			cep->stats.tx_aborted_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_UN)	/* Underrun */
			cep->stats.tx_fifo_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_CSL)	/* Carrier lost */
			cep->stats.tx_carrier_errors++;


		/* No heartbeat or Lost carrier are not really bad errors.
		 * The others require a restart transmit command.
		 */
		if (bdp->cbd_sc &
		    (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
			must_restart = 1;
			cep->stats.tx_errors++;
		}

		cep->stats.tx_packets++;
#else
		bdp = cep->dirty_tx;
#if 1
		if (bdp->cbd_sc & BD_ENET_TX_READY)
			printk("HEY! Enet xmit interrupt and TX_READY.\n");
#endif
#endif
		/* Deferred means some collisions occurred during transmit,
		 * but we eventually sent the packet OK.
		 */
		if (bdp->cbd_sc & BD_ENET_TX_DEF)
			cep->stats.collisions++;

		/* Free the sk buffer associated with this last transmit.
		*/
		dev_kfree_skb(cep->tx_skbuff[cep->skb_dirty]/*, FREE_WRITE*/);
		cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;

		/* Update pointer to next buffer descriptor to be transmitted.
		*/
		if (bdp->cbd_sc & BD_ENET_TX_WRAP)
			bdp = cep->tx_bd_base;
		else
			bdp++;

		/* I don't know if we can be held off from processing these
		 * interrupts for more than one frame time.  I really hope
		 * not.  In such a case, we would now want to check the
		 * currently available BD (cur_tx) and determine if any
		 * buffers between the dirty_tx and cur_tx have also been
		 * sent.  We would want to process anything in between that
		 * does not have BD_ENET_TX_READY set.
		 */

		/* Since we have freed up a buffer, the ring is no longer
		 * full.
		 */
		if (cep->tx_full && dev->tbusy) {
			cep->tx_full = 0;
			dev->tbusy = 0;
			mark_bh(NET_BH);
		}

		cep->dirty_tx = (cbd_t *)bdp;
	    }

	    if (must_restart) {
		volatile cpm8xx_t *cp;

		/* Some transmit errors cause the transmitter to shut
		 * down.  We now issue a restart transmit.  Since the
		 * errors close the BD and update the pointers, the restart
		 * _should_ pick up without having to reset any of our
		 * pointers either.
		 */
		cp = cpmp;
		cp->cp_cpcr =
		    mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
		while (cp->cp_cpcr & CPM_CR_FLG);
	    }
	}

	/* Check for receive busy, i.e. packets coming but no place to
	 * put them.  This "can't happen" because the receive interrupt
	 * is tossing previous frames.
	 */
	if (int_events & SCCE_ENET_BSY) {
		cep->stats.rx_dropped++;
		printk("CPM ENET: BSY can't happen.\n");
	}

	dev->interrupt = 0;

	return;
}
Ejemplo n.º 10
0
int __init m8xx_enet_init(void)
{
	struct device *dev;
	struct cpm_enet_private *cep;
	int i, j;
	unsigned char	*eap;
	unsigned long	mem_addr;
	pte_t		*pte;
	bd_t		*bd;
	volatile	cbd_t		*bdp;
	volatile	cpm8xx_t	*cp;
	volatile	scc_t		*sccp;
	volatile	scc_enet_t	*ep;
	volatile	immap_t		*immap;

	cp = cpmp;	/* Get pointer to Communication Processor */

	immap = (immap_t *)IMAP_ADDR;	/* and to internal registers */

	bd = (bd_t *)res;

	/* Allocate some private information.
	*/
	cep = (struct cpm_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
	/*memset(cep, 0, sizeof(*cep));*/
	__clear_user(cep,sizeof(*cep));

	/* Create an Ethernet device instance.
	*/
	dev = init_etherdev(0, 0);

	/* Get pointer to SCC area in parameter RAM.
	*/
	ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);

	/* And another to the SCC register area.
	*/
	sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]);
	cep->sccp = (scc_t *)sccp;		/* Keep the pointer handy */

	/* Disable receive and transmit in case EPPC-Bug started it.
	*/
	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	/* Cookbook style from the MPC860 manual.....
	 * Not all of this is necessary if EPPC-Bug has initialized
	 * the network.
	 * So far we are lucky, all board configurations use the same
	 * pins, or at least the same I/O Port for these functions.....
	 * It can't last though......
	 */

	/* Configure port A pins for Txd and Rxd.
	*/
	immap->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_paodr &= ~PA_ENET_TXD;

	/* Configure port C pins to enable CLSN and RENA.
	*/
	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);

	/* Configure port A for TCLK and RCLK.
	*/
	immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);

	/* Configure Serial Interface clock routing.
	 * First, clear all SCC bits to zero, then set the ones we want.
	 */
	cp->cp_sicr &= ~SICR_ENET_MASK;
	cp->cp_sicr |= SICR_ENET_CLKRT;

	/* Manual says set SDDR, but I can't find anything with that
	 * name.  I think it is a misprint, and should be SDCR.  This
	 * has already been set by the communication processor initialization.
	 */

	/* Allocate space for the buffer descriptors in the DP ram.
	 * These are relative offsets in the DP ram address space.
	 * Initialize base addresses for the buffer descriptors.
	 */
	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE);
	ep->sen_genscc.scc_rbase = i;
	cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE);
	ep->sen_genscc.scc_tbase = i;
	cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
	cep->cur_rx = cep->rx_bd_base;

	/* Issue init Rx BD command for SCC.
	 * Manual says to perform an Init Rx parameters here.  We have
	 * to perform both Rx and Tx because the SCC may have been
	 * already running.
	 * In addition, we have to do it later because we don't yet have
	 * all of the BD control/status set properly.
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);
	 */

	/* Initialize function code registers for big-endian.
	*/
	ep->sen_genscc.scc_rfcr = SCC_EB;
	ep->sen_genscc.scc_tfcr = SCC_EB;

	/* Set maximum bytes per receive buffer.
	 * This appears to be an Ethernet frame size, not the buffer
	 * fragment size.  It must be a multiple of four.
	 */
	ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;

	/* Set CRC preset and mask.
	*/
	ep->sen_cpres = 0xffffffff;
	ep->sen_cmask = 0xdebb20e3;

	ep->sen_crcec = 0;	/* CRC Error counter */
	ep->sen_alec = 0;	/* alignment error counter */
	ep->sen_disfc = 0;	/* discard frame counter */

	ep->sen_pads = 0x8888;	/* Tx short frame pad character */
	ep->sen_retlim = 15;	/* Retry limit threshold */

	ep->sen_maxflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
	ep->sen_minflr = PKT_MINBUF_SIZE;  /* minimum frame length register */

	ep->sen_maxd1 = PKT_MAXBUF_SIZE;	/* maximum DMA1 length */
	ep->sen_maxd2 = PKT_MAXBUF_SIZE;	/* maximum DMA2 length */

	/* Clear hash tables.
	*/
	ep->sen_gaddr1 = 0;
	ep->sen_gaddr2 = 0;
	ep->sen_gaddr3 = 0;
	ep->sen_gaddr4 = 0;
	ep->sen_iaddr1 = 0;
	ep->sen_iaddr2 = 0;
	ep->sen_iaddr3 = 0;
	ep->sen_iaddr4 = 0;

	/* Set Ethernet station address.
	 *
	 * If we performed a MBX diskless boot, the Ethernet controller
	 * has been initialized and we copy the address out into our
	 * own structure.
	 */
	eap = (unsigned char *)&(ep->sen_paddrh);
#ifndef CONFIG_MBX
	for (i=5; i>=0; i--)
		*eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
#else
	for (i=5; i>=0; i--)
		dev->dev_addr[i] = *eap++;
#endif

	ep->sen_pper = 0;	/* 'cause the book says so */
	ep->sen_taddrl = 0;	/* temp address (LSB) */
	ep->sen_taddrm = 0;
	ep->sen_taddrh = 0;	/* temp address (MSB) */

	/* Now allocate the host memory pages and initialize the
	 * buffer descriptors.
	 */
	bdp = cep->tx_bd_base;
	for (i=0; i<TX_RING_SIZE; i++) {

		/* Initialize the BD for every fragment in the page.
		*/
		bdp->cbd_sc = 0;
		bdp->cbd_bufaddr = 0;
		bdp++;
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	bdp = cep->rx_bd_base;
	for (i=0; i<CPM_ENET_RX_PAGES; i++) {

		/* Allocate a page.
		*/
		mem_addr = __get_free_page(GFP_KERNEL);

		/* Make it uncached.
		*/
		pte = va_to_pte(&init_task, mem_addr);
		pte_val(*pte) |= _PAGE_NO_CACHE;
		flush_tlb_page(current->mm->mmap, mem_addr);

		/* Initialize the BD for every fragment in the page.
		*/
		for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
			bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
			bdp->cbd_bufaddr = __pa(mem_addr);
			mem_addr += CPM_ENET_RX_FRSIZE;
			bdp++;
		}
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	/* Let's re-initialize the channel now.  We have to do it later
	 * than the manual describes because we have just now finished
	 * the BD initialization.
	 */
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);

	cep->skb_cur = cep->skb_dirty = 0;

	sccp->scc_scce = 0xffff;	/* Clear any pending events */

	/* Enable interrupts for transmit error, complete frame
	 * received, and any transmit buffer we have also set the
	 * interrupt flag.
	 */
	sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);

	/* Install our interrupt handler.
	*/
	cpm_install_handler(CPMVEC_ENET, cpm_enet_interrupt, dev);

	/* Set GSMR_H to enable all normal operating modes.
	 * Set GSMR_L to enable Ethernet to MC68160.
	 */
	sccp->scc_gsmrh = 0;
	sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);

	/* Set sync/delimiters.
	*/
	sccp->scc_dsr = 0xd555;

	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
	 * start frame search 22 bit times after RENA.
	 */
	sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);

	/* It is now OK to enable the Ethernet transmitter.
	 * Unfortunately, there are board implementation differences here.
	 */
#ifdef CONFIG_MBX
	immap->im_ioport.iop_pcpar |= PC_ENET_TENA;
	immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
#endif

#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;

	/* And while we are here, set the configuration to enable ethernet.
	*/
	*((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK;
	*((volatile uint *)RPX_CSR_ADDR) |=
			(BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS);
#endif

#ifdef CONFIG_BSEIP
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;

	/* BSE uses port B and C for PHY control.
	*/
	cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);

	immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
#endif

	dev->base_addr = (unsigned long)ep;
	dev->priv = cep;
	dev->name = "CPM_ENET";

	/* The CPM Ethernet specific entries in the device structure. */
	dev->open = cpm_enet_open;
	dev->hard_start_xmit = cpm_enet_start_xmit;
	dev->stop = cpm_enet_close;
	dev->get_stats = cpm_enet_get_stats;
	dev->set_multicast_list = set_multicast_list;

	/* And last, enable the transmit and receive processing.
	*/
	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	printk("CPM ENET Version 0.1, ");
	for (i=0; i<5; i++)
		printk("%02x:", dev->dev_addr[i]);
	printk("%02x\n", dev->dev_addr[5]);

	return 0;
}
Ejemplo n.º 11
0
static int sec_init(struct eth_device *dev, bd_t *bis)
{
    int i;
    volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
    scc_enet_t *pram_ptr;
    uint dpaddr;
    uchar ea[6];

    rxIdx = 0;
    txIdx = 0;

    /*
     * Assign static pointer to BD area.
     * Avoid exhausting DPRAM, which would cause a panic.
     */
    if (rtx == NULL) {
	    dpaddr = m8260_cpm_dpalloc(sizeof(RTXBD) + 2, 16);
	    rtx = (RTXBD *)&immr->im_dprambase[dpaddr];
    }

    /* 24.21 - (1-3): ioports have been set up already */

    /* 24.21 - (4,5): connect SCC's tx and rx clocks, use NMSI for SCC */
    immr->im_cpmux.cmx_uar = 0;
    immr->im_cpmux.cmx_scr = ( (immr->im_cpmux.cmx_scr & ~CMXSCR_MASK) |
			       CONFIG_SYS_CMXSCR_VALUE);


    /* 24.21 (6) write RBASE and TBASE to parameter RAM */
    pram_ptr = (scc_enet_t *)&(immr->im_dprambase[PROFF_ENET]);
    pram_ptr->sen_genscc.scc_rbase = (unsigned int)(&rtx->rxbd[0]);
    pram_ptr->sen_genscc.scc_tbase = (unsigned int)(&rtx->txbd[0]);

    pram_ptr->sen_genscc.scc_rfcr = 0x18;  /* Nrml Ops and Mot byte ordering */
    pram_ptr->sen_genscc.scc_tfcr = 0x18;  /* Mot byte ordering, Nrml access */

    pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. package len 1520 */

    pram_ptr->sen_cpres  = ~(0x0);        /* Preset CRC */
    pram_ptr->sen_cmask  = 0xdebb20e3;    /* Constant Mask for CRC */


    /* 24.21 - (7): Write INIT RX AND TX PARAMETERS to CPCR */
    while(immr->im_cpm.cp_cpcr & CPM_CR_FLG);
    immr->im_cpm.cp_cpcr = mk_cr_cmd(CPM_CR_ENET_PAGE,
				     CPM_CR_ENET_SBLOCK,
				     0x0c,
				     CPM_CR_INIT_TRX) | CPM_CR_FLG;

    /* 24.21 - (8-18): Set up parameter RAM */
    pram_ptr->sen_crcec  = 0x0;           /* Error Counter CRC (unused) */
    pram_ptr->sen_alec   = 0x0;           /* Align Error Counter (unused) */
    pram_ptr->sen_disfc  = 0x0;           /* Discard Frame Counter (unused) */

    pram_ptr->sen_pads   = 0x8888;        /* Short Frame PAD Characters */

    pram_ptr->sen_retlim = 15;            /* Retry Limit Threshold */

    pram_ptr->sen_maxflr = 1518;  /* MAX Frame Length Register */
    pram_ptr->sen_minflr = 64;            /* MIN Frame Length Register */

    pram_ptr->sen_maxd1  = DBUF_LENGTH;   /* MAX DMA1 Length Register */
    pram_ptr->sen_maxd2  = DBUF_LENGTH;   /* MAX DMA2 Length Register */

    pram_ptr->sen_gaddr1 = 0x0;   /* Group Address Filter 1 (unused) */
    pram_ptr->sen_gaddr2 = 0x0;   /* Group Address Filter 2 (unused) */
    pram_ptr->sen_gaddr3 = 0x0;   /* Group Address Filter 3 (unused) */
    pram_ptr->sen_gaddr4 = 0x0;   /* Group Address Filter 4 (unused) */

    eth_getenv_enetaddr("ethaddr", ea);
    pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
    pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
    pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];

    pram_ptr->sen_pper   = 0x0;   /* Persistence (unused) */

    pram_ptr->sen_iaddr1 = 0x0;   /* Individual Address Filter 1 (unused) */
    pram_ptr->sen_iaddr2 = 0x0;   /* Individual Address Filter 2 (unused) */
    pram_ptr->sen_iaddr3 = 0x0;   /* Individual Address Filter 3 (unused) */
    pram_ptr->sen_iaddr4 = 0x0;   /* Individual Address Filter 4 (unused) */

    pram_ptr->sen_taddrh = 0x0;   /* Tmp Address (MSB) (unused) */
    pram_ptr->sen_taddrm = 0x0;   /* Tmp Address (unused) */
    pram_ptr->sen_taddrl = 0x0;   /* Tmp Address (LSB) (unused) */

    /* 24.21 - (19): Initialize RxBD */
    for (i = 0; i < PKTBUFSRX; i++)
    {
	rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
	rtx->rxbd[i].cbd_datlen = 0;                  /* Reset */
	rtx->rxbd[i].cbd_bufaddr = (uint)net_rx_packets[i];
    }

    rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;

    /* 24.21 - (20): Initialize TxBD */
    for (i = 0; i < TX_BUF_CNT; i++)
    {
	rtx->txbd[i].cbd_sc = (BD_ENET_TX_PAD  |
			       BD_ENET_TX_LAST |
			       BD_ENET_TX_TC);
	rtx->txbd[i].cbd_datlen = 0;                  /* Reset */
	rtx->txbd[i].cbd_bufaddr = (uint)&txbuf[i][0];
    }

    rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;

    /* 24.21 - (21): Write 0xffff to SCCE */
    immr->im_scc[CONFIG_ETHER_INDEX-1].scc_scce = ~(0x0);

    /* 24.21 - (22): Write to SCCM to enable TXE, RXF, TXB events */
    immr->im_scc[CONFIG_ETHER_INDEX-1].scc_sccm = (SCCE_ENET_TXE |
						   SCCE_ENET_RXF |
						   SCCE_ENET_TXB);

    /* 24.21 - (23): we don't use ethernet interrupts */

    /* 24.21 - (24): Clear GSMR_H to enable normal operations */
    immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrh = 0;

    /* 24.21 - (25): Clear GSMR_L to enable normal operations */
    immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl = (SCC_GSMRL_TCI        |
						    SCC_GSMRL_TPL_48     |
						    SCC_GSMRL_TPP_10     |
						    SCC_GSMRL_MODE_ENET);

    /* 24.21 - (26): Initialize DSR */
    immr->im_scc[CONFIG_ETHER_INDEX-1].scc_dsr = 0xd555;

    /* 24.21 - (27): Initialize PSMR2
     *
     * Settings:
     *	CRC = 32-Bit CCITT
     *	NIB = Begin searching for SFD 22 bits after RENA
     *	FDE = Full Duplex Enable
     *	BRO = Reject broadcast packets
     *	PROMISCOUS = Catch all packets regardless of dest. MAC adress
     */
    immr->im_scc[CONFIG_ETHER_INDEX-1].scc_psmr   =	SCC_PSMR_ENCRC	|
							SCC_PSMR_NIB22	|
#if defined(CONFIG_SCC_ENET_FULL_DUPLEX)
							SCC_PSMR_FDE	|
#endif
#if defined(CONFIG_SCC_ENET_NO_BROADCAST)
							SCC_PSMR_BRO	|
#endif
#if defined(CONFIG_SCC_ENET_PROMISCOUS)
							SCC_PSMR_PRO	|
#endif
							0;

    /* 24.21 - (28): Write to GSMR_L to enable SCC */
    immr->im_scc[CONFIG_ETHER_INDEX-1].scc_gsmrl |= (SCC_GSMRL_ENR |
						     SCC_GSMRL_ENT);

    return 0;
}
Ejemplo n.º 12
0
/* Initialize the CPM Ethernet on SCC.  If EPPC-Bug loaded us, or performed
 * some other network I/O, a whole bunch of this has already been set up.
 * It is no big deal if we do it again, we just have to disable the
 * transmit and receive to make sure we don't catch the CPM with some
 * inconsistent control information.
 */
static int __init scc_enet_init(void)
{
	struct net_device *dev;
	struct scc_enet_private *cep;
	int i, j, k, err;
	uint dp_offset;
	unsigned char	*eap, *ba;
	dma_addr_t	mem_addr;
	bd_t		*bd;
	volatile	cbd_t		*bdp;
	volatile	cpm8xx_t	*cp;
	volatile	scc_t		*sccp;
	volatile	scc_enet_t	*ep;
	volatile	immap_t		*immap;

	cp = cpmp;	/* Get pointer to Communication Processor */

	immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000);	/* and to internal registers */

	bd = (bd_t *)__res;

	dev = alloc_etherdev(sizeof(*cep));
	if (!dev)
		return -ENOMEM;

	cep = dev->priv;
	spin_lock_init(&cep->lock);

	/* Get pointer to SCC area in parameter RAM.
	*/
	ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);

	/* And another to the SCC register area.
	*/
	sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]);
	cep->sccp = (scc_t *)sccp;		/* Keep the pointer handy */

	/* Disable receive and transmit in case EPPC-Bug started it.
	*/
	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	/* Cookbook style from the MPC860 manual.....
	 * Not all of this is necessary if EPPC-Bug has initialized
	 * the network.
	 * So far we are lucky, all board configurations use the same
	 * pins, or at least the same I/O Port for these functions.....
	 * It can't last though......
	 */

#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
	/* Configure port A pins for Txd and Rxd.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_paodr &=                ~PA_ENET_TXD;
#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
	/* Configure port B pins for Txd and Rxd.
	*/
	immap->im_cpm.cp_pbpar |=  (PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbodr &=		 ~PB_ENET_TXD;
#else
#error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
#endif

#if defined(PC_ENET_LBK)
	/* Configure port C pins to disable External Loopback
	 */
	immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdir |=  PC_ENET_LBK;
	immap->im_ioport.iop_pcso  &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK;	/* Disable Loopback */
#endif	/* PC_ENET_LBK */

#ifdef PE_ENET_TCLK
	/* Configure port E for TCLK and RCLK.
	*/
	cp->cp_pepar |=  (PE_ENET_TCLK | PE_ENET_RCLK);
	cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
	cp->cp_peso  &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
#else
	/* Configure port A for TCLK and RCLK.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
#endif

	/* Configure port C pins to enable CLSN and RENA.
	*/
	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);

	/* Configure Serial Interface clock routing.
	 * First, clear all SCC bits to zero, then set the ones we want.
	 */
	cp->cp_sicr &= ~SICR_ENET_MASK;
	cp->cp_sicr |=  SICR_ENET_CLKRT;

	/* Manual says set SDDR, but I can't find anything with that
	 * name.  I think it is a misprint, and should be SDCR.  This
	 * has already been set by the communication processor initialization.
	 */

	/* Allocate space for the buffer descriptors in the DP ram.
	 * These are relative offsets in the DP ram address space.
	 * Initialize base addresses for the buffer descriptors.
	 */
	dp_offset = cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8);
	ep->sen_genscc.scc_rbase = dp_offset;
	cep->rx_bd_base = cpm_dpram_addr(dp_offset);

	dp_offset = cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8);
	ep->sen_genscc.scc_tbase = dp_offset;
	cep->tx_bd_base = cpm_dpram_addr(dp_offset);

	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
	cep->cur_rx = cep->rx_bd_base;

	/* Issue init Rx BD command for SCC.
	 * Manual says to perform an Init Rx parameters here.  We have
	 * to perform both Rx and Tx because the SCC may have been
	 * already running.
	 * In addition, we have to do it later because we don't yet have
	 * all of the BD control/status set properly.
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);
	 */

	/* Initialize function code registers for big-endian.
	*/
	ep->sen_genscc.scc_rfcr = SCC_EB;
	ep->sen_genscc.scc_tfcr = SCC_EB;

	/* Set maximum bytes per receive buffer.
	 * This appears to be an Ethernet frame size, not the buffer
	 * fragment size.  It must be a multiple of four.
	 */
	ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;

	/* Set CRC preset and mask.
	*/
	ep->sen_cpres = 0xffffffff;
	ep->sen_cmask = 0xdebb20e3;

	ep->sen_crcec = 0;	/* CRC Error counter */
	ep->sen_alec = 0;	/* alignment error counter */
	ep->sen_disfc = 0;	/* discard frame counter */

	ep->sen_pads = 0x8888;	/* Tx short frame pad character */
	ep->sen_retlim = 15;	/* Retry limit threshold */

	ep->sen_maxflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
	ep->sen_minflr = PKT_MINBUF_SIZE;  /* minimum frame length register */

	ep->sen_maxd1 = PKT_MAXBLR_SIZE;	/* maximum DMA1 length */
	ep->sen_maxd2 = PKT_MAXBLR_SIZE;	/* maximum DMA2 length */

	/* Clear hash tables.
	*/
	ep->sen_gaddr1 = 0;
	ep->sen_gaddr2 = 0;
	ep->sen_gaddr3 = 0;
	ep->sen_gaddr4 = 0;
	ep->sen_iaddr1 = 0;
	ep->sen_iaddr2 = 0;
	ep->sen_iaddr3 = 0;
	ep->sen_iaddr4 = 0;

	/* Set Ethernet station address.
	 */
	eap = (unsigned char *)&(ep->sen_paddrh);
	for (i=5; i>=0; i--)
		*eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];

	ep->sen_pper = 0;	/* 'cause the book says so */
	ep->sen_taddrl = 0;	/* temp address (LSB) */
	ep->sen_taddrm = 0;
	ep->sen_taddrh = 0;	/* temp address (MSB) */

	/* Now allocate the host memory pages and initialize the
	 * buffer descriptors.
	 */
	bdp = cep->tx_bd_base;
	for (i=0; i<TX_RING_SIZE; i++) {

		/* Initialize the BD for every fragment in the page.
		*/
		bdp->cbd_sc = 0;
		bdp->cbd_bufaddr = 0;
		bdp++;
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	bdp = cep->rx_bd_base;
	k = 0;
	for (i=0; i<CPM_ENET_RX_PAGES; i++) {

		/* Allocate a page.
		*/
		ba = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE,
				&mem_addr, GFP_KERNEL);
		/* BUG: no check for failure */

		/* Initialize the BD for every fragment in the page.
		*/
		for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
			bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
			bdp->cbd_bufaddr = mem_addr;
			cep->rx_vaddr[k++] = ba;
			mem_addr += CPM_ENET_RX_FRSIZE;
			ba += CPM_ENET_RX_FRSIZE;
			bdp++;
		}
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	/* Let's re-initialize the channel now.  We have to do it later
	 * than the manual describes because we have just now finished
	 * the BD initialization.
	 */
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);

	cep->skb_cur = cep->skb_dirty = 0;

	sccp->scc_scce = 0xffff;	/* Clear any pending events */

	/* Enable interrupts for transmit error, complete frame
	 * received, and any transmit buffer we have also set the
	 * interrupt flag.
	 */
	sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);

	/* Install our interrupt handler.
	*/
	cpm_install_handler(CPMVEC_ENET, scc_enet_interrupt, dev);

	/* Set GSMR_H to enable all normal operating modes.
	 * Set GSMR_L to enable Ethernet to MC68160.
	 */
	sccp->scc_gsmrh = 0;
	sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);

	/* Set sync/delimiters.
	*/
	sccp->scc_dsr = 0xd555;

	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
	 * start frame search 22 bit times after RENA.
	 */
	sccp->scc_psmr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22);

	/* It is now OK to enable the Ethernet transmitter.
	 * Unfortunately, there are board implementation differences here.
	 */
#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
	immap->im_ioport.iop_pcpar |=  PC_ENET_TENA;
	immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;
#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA))
	cp->cp_pepar |=  PE_ENET_TENA;
	cp->cp_pedir &= ~PE_ENET_TENA;
	cp->cp_peso  |=  PE_ENET_TENA;
#else
#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA
#endif

#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
	/* And while we are here, set the configuration to enable ethernet.
	*/
	*((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK;
	*((volatile uint *)RPX_CSR_ADDR) |=
			(BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS);
#endif

#ifdef CONFIG_BSEIP
	/* BSE uses port B and C for PHY control.
	*/
	cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);

	immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
#endif

#ifdef CONFIG_FADS
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;

	/* Enable the EEST PHY.
	*/
	*((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
#endif

#ifdef CONFIG_MPC885ADS

	/* Deassert PHY reset and enable the PHY.
	 */
	{
		volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE);
		uint tmp;

		tmp = in_be32(bcsr + 1 /* BCSR1 */);
		tmp |= BCSR1_ETHEN;
		out_be32(bcsr + 1, tmp);
		tmp = in_be32(bcsr + 4 /* BCSR4 */);
		tmp |= BCSR4_ETH10_RST;
		out_be32(bcsr + 4, tmp);
		iounmap(bcsr);
	}

	/* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode
	 * upon reset. SCC is set to half duplex by default. So this
	 * inconsistency should be better fixed by the software.
	 */
#endif

	dev->base_addr = (unsigned long)ep;
#if 0
	dev->name = "CPM_ENET";
#endif

	/* The CPM Ethernet specific entries in the device structure. */
	dev->open = scc_enet_open;
	dev->hard_start_xmit = scc_enet_start_xmit;
	dev->tx_timeout = scc_enet_timeout;
	dev->watchdog_timeo = TX_TIMEOUT;
	dev->stop = scc_enet_close;
	dev->get_stats = scc_enet_get_stats;
	dev->set_multicast_list = set_multicast_list;

	err = register_netdev(dev);
	if (err) {
		free_netdev(dev);
		return err;
	}

	/* And last, enable the transmit and receive processing.
	*/
	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	printk("%s: CPM ENET Version 0.2 on SCC%d, ", dev->name, SCC_ENET+1);
	for (i=0; i<5; i++)
		printk("%02x:", dev->dev_addr[i]);
	printk("%02x\n", dev->dev_addr[5]);

	return 0;
}
Ejemplo n.º 13
0
static int __init cpm_load_init (void)
{
	int i;
	struct proc_dir_entry *entry;
	ulong timep, flags;
	volatile immap_t *immap = (immap_t *) IMAP_ADDR;
	volatile cpm8xx_t *cp = &immap->im_cpm;
	volatile risc_timer_t *rtram =
			(risc_timer_t *) & cp->cp_dparam[PROFF_RTIMER];


	entry = create_proc_entry (PROC_NAME,
				   S_IFREG | S_IRUGO | S_IWUGO,
				   NULL);
	if (entry == NULL) {
		printk ("Unable to create /proc/%s entry\n", PROC_NAME);
		return -EINVAL;
	}
	entry->read_proc = cpm_load_proc_read;
	entry->write_proc = cpm_load_proc_write;

	/* Make sure the RISC Timer tick clock is disabled.
	 */
#ifdef RCCR_BUG
	*(uint *) & (immap->im_cpm.cp_rccr) &= ~0x80000000;
#else
	immap->im_cpm.cp_rccr &= ~0x8000;
#endif

	timep = 15;

	/* Write the timep value to the rccr register.
	 */
#ifdef RCCR_BUG
	*(uint *) & (immap->im_cpm.cp_rccr) &= ~(0x3f << 24);
	*(uint *) & (immap->im_cpm.cp_rccr) |= timep << 24;
#else
	immap->im_cpm.cp_rccr &= ~(0x3f << 8);
	immap->im_cpm.cp_rccr |= timep << 8;
#endif

	/* Allocate DPRAM for the timers.
	 */
	risc_dpram_timers = m8xx_cpm_dpalloc (sizeof (ulong) * RISC_TIMER_MAX);
	rtram->tm_base = risc_dpram_timers;

	/* Clear number of ticks elapsed.
	 */
	rtram->tm_cnt = 0;

	/* Clear all RISC Timer events.
	 */
	immap->im_cpm.cp_rter = 0xffff;

	/* Disable all RISC Timer interrupts.
	 */
	immap->im_cpm.cp_rtmr = 0x0000;

	for (i = 0; i < RISC_TIMER_MAX; i++) {
		int timeout = 0;

		rtram->tm_cmd = (i << 16) | timeout;
		rtram->tm_cmd |= 0xC0000000;	/* periodic */

		/* Wait for a previous command to clear.
		 */
		while (cp->cp_cpcr & CPM_CR_FLG);

		/* Issue SET TIMER command.
		 */
		cp->cp_cpcr = mk_cr_cmd (CPM_CR_CH_TIMER, CPM_CR_SET_TIMER) |
				CPM_CR_FLG;
#if 0
		while (cp->cp_cpcr & CPM_CR_FLG);
#endif
	}


	/* Initialize a general purpose timer.
	 * We have to use both Timer 1 and Timer 2 to get the desired
	 * clock of 1/16384 system clock, which the MPC860 manual
	 * suggests.
	 */

	/* reset timer1 and timer2 */
	immap->im_cpmtimer.cpmt_tgcr &= ~(CPMTIMER_TGCR_GM1 |
					  CPMTIMER_TGCR_FRZ1 |
					  CPMTIMER_TGCR_STP1 |
					  CPMTIMER_TGCR_CAS2 |
					  CPMTIMER_TGCR_FRZ2 |
					  CPMTIMER_TGCR_STP2);

	immap->im_cpmtimer.cpmt_tmr1 = 0x0;	/* timer2 is the clock source */
	immap->im_cpmtimer.cpmt_trr1 = 0xffff;
	immap->im_cpmtimer.cpmt_tcr1 = 0;
	immap->im_cpmtimer.cpmt_tcn1 = 0;
	immap->im_cpmtimer.cpmt_ter1 = 0xffff;

	immap->im_cpmtimer.cpmt_tmr2 = 0xff04 | 0x8;
	immap->im_cpmtimer.cpmt_trr2 = 0x3;
	immap->im_cpmtimer.cpmt_tcr2 = 0;
	immap->im_cpmtimer.cpmt_tcn2 = 0;
	immap->im_cpmtimer.cpmt_ter2 = 0xffff;

	save_flags (flags);
	cli ();

	/* Start the RISC Timers.
	 */
#ifdef RCCR_BUG
	*(uint *) & (immap->im_cpm.cp_rccr) |= 0x80000000;
#else
	immap->im_cpm.cp_rccr |= 0x8000;
#endif

	/* Start the general purpose timers.
	 */
	immap->im_cpmtimer.cpmt_tgcr |=
			CPMTIMER_TGCR_RST1 | CPMTIMER_TGCR_RST2;

	restore_flags (flags);

	printk (KERN_INFO "CPM load tracking driver " DRIVER_VERSION "\n");
	return 0;
}
Ejemplo n.º 14
0
static int fec_init(struct eth_device* dev, bd_t *bis)
{
    struct ether_fcc_info_s * info = dev->priv;
    int i;
    volatile immap_t *immr = (immap_t *)CFG_IMMR;
    volatile ccsr_cpm_cp_t *cp = &(immr->im_cpm.im_cpm_cp);
    fcc_enet_t *pram_ptr;
    unsigned long mem_addr;

#if 0
    mii_discover_phy();
#endif

    /* 28.9 - (1-2): ioports have been set up already */

    /* 28.9 - (3): connect FCC's tx and rx clocks */
    immr->im_cpm.im_cpm_mux.cmxuar = 0; /* ATM */
    immr->im_cpm.im_cpm_mux.cmxfcr = (immr->im_cpm.im_cpm_mux.cmxfcr & ~info->cmxfcr_mask) |
							info->cmxfcr_value;

    /* 28.9 - (4): GFMR: disable tx/rx, CCITT CRC, set Mode Ethernet */
    if(info->ether_index == 0) {
	immr->im_cpm.im_cpm_fcc1.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
    } else if (info->ether_index == 1) {
	immr->im_cpm.im_cpm_fcc2.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
    } else if (info->ether_index == 2) {
	immr->im_cpm.im_cpm_fcc3.gfmr = FCC_GFMR_MODE_ENET | FCC_GFMR_TCRC_32;
    }

    /* 28.9 - (5): FPSMR: enable full duplex, select CCITT CRC for Ethernet,MII */
    if(info->ether_index == 0) {
	immr->im_cpm.im_cpm_fcc1.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
    } else if (info->ether_index == 1){
	immr->im_cpm.im_cpm_fcc2.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
    } else if (info->ether_index == 2){
	immr->im_cpm.im_cpm_fcc3.fpsmr = CFG_FCC_PSMR | FCC_PSMR_ENCRC;
    }

    /* 28.9 - (6): FDSR: Ethernet Syn */
    if(info->ether_index == 0) {
	immr->im_cpm.im_cpm_fcc1.fdsr = 0xD555;
    } else if (info->ether_index == 1) {
	immr->im_cpm.im_cpm_fcc2.fdsr = 0xD555;
    } else if (info->ether_index == 2) {
	immr->im_cpm.im_cpm_fcc3.fdsr = 0xD555;
    }

    /* reset indeces to current rx/tx bd (see eth_send()/eth_rx()) */
    rxIdx = 0;
    txIdx = 0;

    /* Setup Receiver Buffer Descriptors */
    for (i = 0; i < PKTBUFSRX; i++)
    {
      rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
      rtx.rxbd[i].cbd_datlen = 0;
      rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
    }
    rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;

    /* Setup Ethernet Transmitter Buffer Descriptors */
    for (i = 0; i < TX_BUF_CNT; i++)
    {
      rtx.txbd[i].cbd_sc = 0;
      rtx.txbd[i].cbd_datlen = 0;
      rtx.txbd[i].cbd_bufaddr = 0;
    }
    rtx.txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;

    /* 28.9 - (7): initialize parameter ram */
    pram_ptr = (fcc_enet_t *)&(immr->im_cpm.im_dprambase[info->proff_enet]);

    /* clear whole structure to make sure all reserved fields are zero */
    memset((void*)pram_ptr, 0, sizeof(fcc_enet_t));

    /*
     * common Parameter RAM area
     *
     * Allocate space in the reserved FCC area of DPRAM for the
     * internal buffers.  No one uses this space (yet), so we
     * can do this.  Later, we will add resource management for
     * this area. CPM_FCC_SPECIAL_BASE: 0xb000.
     */
    mem_addr = CPM_FCC_SPECIAL_BASE + ((info->ether_index) * 64);
    pram_ptr->fen_genfcc.fcc_riptr = mem_addr;
    pram_ptr->fen_genfcc.fcc_tiptr = mem_addr+32;
    /*
     * Set maximum bytes per receive buffer.
     * It must be a multiple of 32.
     */
    pram_ptr->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE; /* 1536 */
    /* localbus SDRAM should be preferred */
    pram_ptr->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB |
				       CFG_CPMFCR_RAMTYPE) << 24;
    pram_ptr->fen_genfcc.fcc_rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
    pram_ptr->fen_genfcc.fcc_rbdstat = 0;
    pram_ptr->fen_genfcc.fcc_rbdlen = 0;
    pram_ptr->fen_genfcc.fcc_rdptr = 0;
    /* localbus SDRAM should be preferred */
    pram_ptr->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB |
				       CFG_CPMFCR_RAMTYPE) << 24;
    pram_ptr->fen_genfcc.fcc_tbase = (unsigned int)(&rtx.txbd[txIdx]);
    pram_ptr->fen_genfcc.fcc_tbdstat = 0;
    pram_ptr->fen_genfcc.fcc_tbdlen = 0;
    pram_ptr->fen_genfcc.fcc_tdptr = 0;

    /* protocol-specific area */
    pram_ptr->fen_statbuf = 0x0;
    pram_ptr->fen_cmask = 0xdebb20e3;	/* CRC mask */
    pram_ptr->fen_cpres = 0xffffffff;	/* CRC preset */
    pram_ptr->fen_crcec = 0;
    pram_ptr->fen_alec = 0;
    pram_ptr->fen_disfc = 0;
    pram_ptr->fen_retlim = 15;		/* Retry limit threshold */
    pram_ptr->fen_retcnt = 0;
    pram_ptr->fen_pper = 0;
    pram_ptr->fen_boffcnt = 0;
    pram_ptr->fen_gaddrh = 0;
    pram_ptr->fen_gaddrl = 0;
    pram_ptr->fen_mflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
    /*
     * Set Ethernet station address.
     *
     * This is supplied in the board information structure, so we
     * copy that into the controller.
     * So far we have only been given one Ethernet address. We make
     * it unique by setting a few bits in the upper byte of the
     * non-static part of the address.
     */
#define ea eth_get_dev()->enetaddr
    pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
    pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
    pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
#undef ea
    pram_ptr->fen_ibdcount = 0;
    pram_ptr->fen_ibdstart = 0;
    pram_ptr->fen_ibdend = 0;
    pram_ptr->fen_txlen = 0;
    pram_ptr->fen_iaddrh = 0;  /* disable hash */
    pram_ptr->fen_iaddrl = 0;
    pram_ptr->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register: 64 */
    /* pad pointer. use tiptr since we don't need a specific padding char */
    pram_ptr->fen_padptr = pram_ptr->fen_genfcc.fcc_tiptr;
    pram_ptr->fen_maxd1 = PKT_MAXDMA_SIZE;	/* maximum DMA1 length:1520 */
    pram_ptr->fen_maxd2 = PKT_MAXDMA_SIZE;	/* maximum DMA2 length:1520 */

#if defined(ET_DEBUG)
    printf("parm_ptr(0xff788500) = %p\n",pram_ptr);
    printf("pram_ptr->fen_genfcc.fcc_rbase %08x\n",
	pram_ptr->fen_genfcc.fcc_rbase);
    printf("pram_ptr->fen_genfcc.fcc_tbase %08x\n",
	pram_ptr->fen_genfcc.fcc_tbase);
#endif

    /* 28.9 - (8)(9): clear out events in FCCE */
    /* 28.9 - (9): FCCM: mask all events */
    if(info->ether_index == 0) {
	immr->im_cpm.im_cpm_fcc1.fcce = ~0x0;
	immr->im_cpm.im_cpm_fcc1.fccm = 0;
    } else if (info->ether_index == 1) {
	immr->im_cpm.im_cpm_fcc2.fcce = ~0x0;
	immr->im_cpm.im_cpm_fcc2.fccm = 0;
    } else if (info->ether_index == 2) {
	immr->im_cpm.im_cpm_fcc3.fcce = ~0x0;
	immr->im_cpm.im_cpm_fcc3.fccm = 0;
    }

    /* 28.9 - (10-12): we don't use ethernet interrupts */

    /* 28.9 - (13)
     *
     * Let's re-initialize the channel now.  We have to do it later
     * than the manual describes because we have just now finished
     * the BD initialization.
     */
    cp->cpcr = mk_cr_cmd(info->cpm_cr_enet_page,
			    info->cpm_cr_enet_sblock,
			    0x0c,
			    CPM_CR_INIT_TRX) | CPM_CR_FLG;
    do {
	__asm__ __volatile__ ("eieio");
    } while (cp->cpcr & CPM_CR_FLG);

    /* 28.9 - (14): enable tx/rx in gfmr */
    if(info->ether_index == 0) {
	immr->im_cpm.im_cpm_fcc1.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
    } else if (info->ether_index == 1) {
	immr->im_cpm.im_cpm_fcc2.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
    } else if (info->ether_index == 2) {
	immr->im_cpm.im_cpm_fcc3.gfmr |= FCC_GFMR_ENT | FCC_GFMR_ENR;
    }

    return 1;
}
Ejemplo n.º 15
0
/* Initialize the CPM Ethernet on SCC.  If EPPC-Bug loaded us, or performed
 * some other network I/O, a whole bunch of this has already been set up.
 * It is no big deal if we do it again, we just have to disable the
 * transmit and receive to make sure we don't catch the CPM with some
 * inconsistent control information.
 */
int __init scc_enet_init(void)
{
	struct rtnet_device *rtdev = NULL;
	struct scc_enet_private *cep;
	int i, j, k;
	unsigned char	*eap, *ba;
	dma_addr_t	mem_addr;
	bd_t		*bd;
	volatile	cbd_t		*bdp;
	volatile	cpm8xx_t	*cp;
	volatile	scc_t		*sccp;
	volatile	scc_enet_t	*ep;
	volatile	immap_t		*immap;

	cp = cpmp;	/* Get pointer to Communication Processor */

	immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000);	/* and to internal registers */

	bd = (bd_t *)__res;

	/* Configure the SCC parameters (this has formerly be done 
	 * by macro definitions).
	 */
	switch (rtnet_scc) {
	case 3:
		CPM_CR_ENET = CPM_CR_CH_SCC3;
		PROFF_ENET  = PROFF_SCC3;
		SCC_ENET    = 2;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC3;
		break;
	case 2:
		CPM_CR_ENET = CPM_CR_CH_SCC2;
		PROFF_ENET  = PROFF_SCC2;
		SCC_ENET    = 1;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC2;
		break;
	case 1:
		CPM_CR_ENET = CPM_CR_CH_SCC1;
		PROFF_ENET  = PROFF_SCC1;
		SCC_ENET    = 0;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC1;
		break;
	default:
		printk(KERN_ERR "enet: SCC%d doesn't exit (check rtnet_scc)\n", rtnet_scc);
		return -1;
	}

	/* Allocate some private information and create an Ethernet device instance.
	*/
	rtdev = rtdev_root = rt_alloc_etherdev(sizeof(struct scc_enet_private));
	if (rtdev == NULL) {
		printk(KERN_ERR "enet: Could not allocate ethernet device.\n");
		return -1;
	}
	rtdev_alloc_name(rtdev, "rteth%d");
	rt_rtdev_connect(rtdev, &RTDEV_manager);
	RTNET_SET_MODULE_OWNER(rtdev);
	rtdev->vers = RTDEV_VERS_2_0;

	cep = (struct scc_enet_private *)rtdev->priv;
	rtdm_lock_init(&cep->lock);

	/* Get pointer to SCC area in parameter RAM.
	*/
	ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);

	/* And another to the SCC register area.
	*/
	sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]);
	cep->sccp = (scc_t *)sccp;		/* Keep the pointer handy */

	/* Disable receive and transmit in case EPPC-Bug started it.
	*/
	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	/* Cookbook style from the MPC860 manual.....
	 * Not all of this is necessary if EPPC-Bug has initialized
	 * the network.
	 * So far we are lucky, all board configurations use the same
	 * pins, or at least the same I/O Port for these functions.....
	 * It can't last though......
	 */

#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
	/* Configure port A pins for Txd and Rxd.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_paodr &=                ~PA_ENET_TXD;
#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
	/* Configure port B pins for Txd and Rxd.
	*/
	immap->im_cpm.cp_pbpar |=  (PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbodr &=		 ~PB_ENET_TXD;
#else
#error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
#endif

#if defined(PC_ENET_LBK)
	/* Configure port C pins to disable External Loopback
	 */
	immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdir |=  PC_ENET_LBK;
	immap->im_ioport.iop_pcso  &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK;	/* Disable Loopback */
#endif	/* PC_ENET_LBK */

	/* Configure port C pins to enable CLSN and RENA.
	*/
	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);

	/* Configure port A for TCLK and RCLK.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);

	/* Configure Serial Interface clock routing.
	 * First, clear all SCC bits to zero, then set the ones we want.
	 */
	cp->cp_sicr &= ~SICR_ENET_MASK;
	cp->cp_sicr |=  SICR_ENET_CLKRT;

	/* Manual says set SDDR, but I can't find anything with that
	 * name.  I think it is a misprint, and should be SDCR.  This
	 * has already been set by the communication processor initialization.
	 */

	/* Allocate space for the buffer descriptors in the DP ram.
	 * These are relative offsets in the DP ram address space.
	 * Initialize base addresses for the buffer descriptors.
	 */
	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE);
	ep->sen_genscc.scc_rbase = i;
	cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE);
	ep->sen_genscc.scc_tbase = i;
	cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
	cep->cur_rx = cep->rx_bd_base;

	/* Issue init Rx BD command for SCC.
	 * Manual says to perform an Init Rx parameters here.  We have
	 * to perform both Rx and Tx because the SCC may have been
	 * already running.
	 * In addition, we have to do it later because we don't yet have
	 * all of the BD control/status set properly.
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);
	 */

	/* Initialize function code registers for big-endian.
	*/
	ep->sen_genscc.scc_rfcr = SCC_EB;
	ep->sen_genscc.scc_tfcr = SCC_EB;

	/* Set maximum bytes per receive buffer.
	 * This appears to be an Ethernet frame size, not the buffer
	 * fragment size.  It must be a multiple of four.
	 */
	ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;

	/* Set CRC preset and mask.
	*/
	ep->sen_cpres = 0xffffffff;
	ep->sen_cmask = 0xdebb20e3;

	ep->sen_crcec = 0;	/* CRC Error counter */
	ep->sen_alec = 0;	/* alignment error counter */
	ep->sen_disfc = 0;	/* discard frame counter */

	ep->sen_pads = 0x8888;	/* Tx short frame pad character */
	ep->sen_retlim = 15;	/* Retry limit threshold */

	ep->sen_maxflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
	ep->sen_minflr = PKT_MINBUF_SIZE;  /* minimum frame length register */

	ep->sen_maxd1 = PKT_MAXBLR_SIZE;	/* maximum DMA1 length */
	ep->sen_maxd2 = PKT_MAXBLR_SIZE;	/* maximum DMA2 length */

	/* Clear hash tables.
	*/
	ep->sen_gaddr1 = 0;
	ep->sen_gaddr2 = 0;
	ep->sen_gaddr3 = 0;
	ep->sen_gaddr4 = 0;
	ep->sen_iaddr1 = 0;
	ep->sen_iaddr2 = 0;
	ep->sen_iaddr3 = 0;
	ep->sen_iaddr4 = 0;

	/* Set Ethernet station address.
	 */
	eap = (unsigned char *)&(ep->sen_paddrh);
#ifdef CONFIG_FEC_ENET
	/* We need a second MAC address if FEC is used by Linux */
	for (i=5; i>=0; i--)
		*eap++ = rtdev->dev_addr[i] = (bd->bi_enetaddr[i] | 
					     (i==3 ? 0x80 : 0));
#else
	for (i=5; i>=0; i--)
		*eap++ = rtdev->dev_addr[i] = bd->bi_enetaddr[i];
#endif

	ep->sen_pper = 0;	/* 'cause the book says so */
	ep->sen_taddrl = 0;	/* temp address (LSB) */
	ep->sen_taddrm = 0;
	ep->sen_taddrh = 0;	/* temp address (MSB) */

	/* Now allocate the host memory pages and initialize the
	 * buffer descriptors.
	 */
	bdp = cep->tx_bd_base;
	for (i=0; i<TX_RING_SIZE; i++) {

		/* Initialize the BD for every fragment in the page.
		*/
		bdp->cbd_sc = 0;
		bdp->cbd_bufaddr = 0;
		bdp++;
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	bdp = cep->rx_bd_base;
	k = 0;
	for (i=0; i<CPM_ENET_RX_PAGES; i++) {

		/* Allocate a page.
		*/
		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);

		/* Initialize the BD for every fragment in the page.
		*/
		for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
			bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
			bdp->cbd_bufaddr = mem_addr;
			cep->rx_vaddr[k++] = ba;
			mem_addr += CPM_ENET_RX_FRSIZE;
			ba += CPM_ENET_RX_FRSIZE;
			bdp++;
		}
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	/* Let's re-initialize the channel now.  We have to do it later
	 * than the manual describes because we have just now finished
	 * the BD initialization.
	 */
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);

	cep->skb_cur = cep->skb_dirty = 0;

	sccp->scc_scce = 0xffff;	/* Clear any pending events */

	/* Enable interrupts for transmit error, complete frame
	 * received, and any transmit buffer we have also set the
	 * interrupt flag.
	 */
	sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);

	/* Install our interrupt handler.
	*/
	rtdev->irq = CPM_IRQ_OFFSET + CPMVEC_ENET;
	rt_stack_connect(rtdev, &STACK_manager);
	if ((i = rtdm_irq_request(&cep->irq_handle, rtdev->irq,
				  scc_enet_interrupt, 0, "rt_mpc8xx_enet", rtdev))) {
		printk(KERN_ERR "Couldn't request IRQ %d\n", rtdev->irq);
		rtdev_free(rtdev);
		return i;
	}
	

	/* Set GSMR_H to enable all normal operating modes.
	 * Set GSMR_L to enable Ethernet to MC68160.
	 */
	sccp->scc_gsmrh = 0;
	sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);

	/* Set sync/delimiters.
	*/
	sccp->scc_dsr = 0xd555;

	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
	 * start frame search 22 bit times after RENA.
	 */
	sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);

	/* It is now OK to enable the Ethernet transmitter.
	 * Unfortunately, there are board implementation differences here.
	 */
#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA))
	immap->im_ioport.iop_pcpar |=  PC_ENET_TENA;
	immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;
#else
#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
#endif

#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
	/* And while we are here, set the configuration to enable ethernet.
	*/
	*((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK;
	*((volatile uint *)RPX_CSR_ADDR) |=
			(BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS);
#endif

#ifdef CONFIG_BSEIP
	/* BSE uses port B and C for PHY control.
	*/
	cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);

	immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
#endif

#ifdef CONFIG_FADS
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;

	/* Enable the EEST PHY.
	*/
	*((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
#endif

	rtdev->base_addr = (unsigned long)ep;

	/* The CPM Ethernet specific entries in the device structure. */
	rtdev->open = scc_enet_open;
	rtdev->hard_start_xmit = scc_enet_start_xmit;
	rtdev->stop = scc_enet_close;
	rtdev->hard_header = &rt_eth_header;
	rtdev->get_stats = scc_enet_get_stats;

	if (!rx_pool_size)
		rx_pool_size = RX_RING_SIZE * 2;
	if (rtskb_pool_init(&cep->skb_pool, rx_pool_size) < rx_pool_size) {
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		return -ENOMEM;
	}

	if ((i = rt_register_rtnetdev(rtdev))) {
		printk(KERN_ERR "Couldn't register rtdev\n");
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		return i;
	}

	/* And last, enable the transmit and receive processing.
	*/
	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	printk("%s: CPM ENET Version 0.2 on SCC%d, irq %d, addr %02x:%02x:%02x:%02x:%02x:%02x\n", 
	       rtdev->name, SCC_ENET+1, rtdev->irq,
	       rtdev->dev_addr[0], rtdev->dev_addr[1], rtdev->dev_addr[2],
	       rtdev->dev_addr[3], rtdev->dev_addr[4], rtdev->dev_addr[5]);
	
	return 0;
}
Ejemplo n.º 16
0
/* Initialize the CPM Ethernet on SCC.
 */
static int __init scc_enet_init(void)
{
    struct net_device *dev;
    struct scc_enet_private *cep;
    int i, j, err;
    uint dp_offset;
    unsigned char	*eap;
    unsigned long	mem_addr;
    bd_t		*bd;
    volatile	cbd_t		*bdp;
    volatile	cpm_cpm2_t	*cp;
    volatile	scc_t		*sccp;
    volatile	scc_enet_t	*ep;
    volatile	cpm2_map_t		*immap;
    volatile	iop_cpm2_t	*io;

    cp = cpmp;	/* Get pointer to Communication Processor */

    immap = (cpm2_map_t *)CPM_MAP_ADDR;	/* and to internal registers */
    io = &immap->im_ioport;

    bd = (bd_t *)__res;

    /* Create an Ethernet device instance.
    */
    dev = alloc_etherdev(sizeof(*cep));
    if (!dev)
        return -ENOMEM;

    cep = dev->priv;
    spin_lock_init(&cep->lock);

    /* Get pointer to SCC area in parameter RAM.
    */
    ep = (scc_enet_t *)(&immap->im_dprambase[PROFF_ENET]);

    /* And another to the SCC register area.
    */
    sccp = (volatile scc_t *)(&immap->im_scc[SCC_ENET]);
    cep->sccp = (scc_t *)sccp;		/* Keep the pointer handy */

    /* Disable receive and transmit in case someone left it running.
    */
    sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

    /* Configure port C and D pins for SCC Ethernet.  This
     * won't work for all SCC possibilities....it will be
     * board/port specific.
     */
    io->iop_pparc |=
        (PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK);
    io->iop_pdirc &=
        ~(PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK);
    io->iop_psorc &=
        ~(PC_ENET_RENA | PC_ENET_TXCLK | PC_ENET_RXCLK);
    io->iop_psorc |= PC_ENET_CLSN;

    io->iop_ppard |= (PD_ENET_RXD | PD_ENET_TXD | PD_ENET_TENA);
    io->iop_pdird |= (PD_ENET_TXD | PD_ENET_TENA);
    io->iop_pdird &= ~PD_ENET_RXD;
    io->iop_psord |= PD_ENET_TXD;
    io->iop_psord &= ~(PD_ENET_RXD | PD_ENET_TENA);

    /* Configure Serial Interface clock routing.
     * First, clear all SCC bits to zero, then set the ones we want.
     */
    immap->im_cpmux.cmx_scr &= ~CMX_CLK_MASK;
    immap->im_cpmux.cmx_scr |= CMX_CLK_ROUTE;

    /* Allocate space for the buffer descriptors in the DP ram.
     * These are relative offsets in the DP ram address space.
     * Initialize base addresses for the buffer descriptors.
     */
    dp_offset = cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8);
    ep->sen_genscc.scc_rbase = dp_offset;
    cep->rx_bd_base = (cbd_t *)cpm_dpram_addr(dp_offset);

    dp_offset = cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8);
    ep->sen_genscc.scc_tbase = dp_offset;
    cep->tx_bd_base = (cbd_t *)cpm_dpram_addr(dp_offset);

    cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
    cep->cur_rx = cep->rx_bd_base;

    ep->sen_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB;
    ep->sen_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB;

    /* Set maximum bytes per receive buffer.
     * This appears to be an Ethernet frame size, not the buffer
     * fragment size.  It must be a multiple of four.
     */
    ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;

    /* Set CRC preset and mask.
    */
    ep->sen_cpres = 0xffffffff;
    ep->sen_cmask = 0xdebb20e3;

    ep->sen_crcec = 0;	/* CRC Error counter */
    ep->sen_alec = 0;	/* alignment error counter */
    ep->sen_disfc = 0;	/* discard frame counter */

    ep->sen_pads = 0x8888;	/* Tx short frame pad character */
    ep->sen_retlim = 15;	/* Retry limit threshold */

    ep->sen_maxflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
    ep->sen_minflr = PKT_MINBUF_SIZE;  /* minimum frame length register */

    ep->sen_maxd1 = PKT_MAXBLR_SIZE;	/* maximum DMA1 length */
    ep->sen_maxd2 = PKT_MAXBLR_SIZE;	/* maximum DMA2 length */

    /* Clear hash tables.
    */
    ep->sen_gaddr1 = 0;
    ep->sen_gaddr2 = 0;
    ep->sen_gaddr3 = 0;
    ep->sen_gaddr4 = 0;
    ep->sen_iaddr1 = 0;
    ep->sen_iaddr2 = 0;
    ep->sen_iaddr3 = 0;
    ep->sen_iaddr4 = 0;

    /* Set Ethernet station address.
     *
     * This is supplied in the board information structure, so we
     * copy that into the controller.
     */
    eap = (unsigned char *)&(ep->sen_paddrh);
    for (i=5; i>=0; i--)
        *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];

    ep->sen_pper = 0;	/* 'cause the book says so */
    ep->sen_taddrl = 0;	/* temp address (LSB) */
    ep->sen_taddrm = 0;
    ep->sen_taddrh = 0;	/* temp address (MSB) */

    /* Now allocate the host memory pages and initialize the
     * buffer descriptors.
     */
    bdp = cep->tx_bd_base;
    for (i=0; i<TX_RING_SIZE; i++) {

        /* Initialize the BD for every fragment in the page.
        */
        bdp->cbd_sc = 0;
        bdp->cbd_bufaddr = 0;
        bdp++;
    }

    /* Set the last buffer to wrap.
    */
    bdp--;
    bdp->cbd_sc |= BD_SC_WRAP;

    bdp = cep->rx_bd_base;
    for (i=0; i<CPM_ENET_RX_PAGES; i++) {

        /* Allocate a page.
        */
        mem_addr = __get_free_page(GFP_KERNEL);
        /* BUG: no check for failure */

        /* Initialize the BD for every fragment in the page.
        */
        for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
            bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
            bdp->cbd_bufaddr = __pa(mem_addr);
            mem_addr += CPM_ENET_RX_FRSIZE;
            bdp++;
        }
    }

    /* Set the last buffer to wrap.
    */
    bdp--;
    bdp->cbd_sc |= BD_SC_WRAP;

    /* Let's re-initialize the channel now.  We have to do it later
     * than the manual describes because we have just now finished
     * the BD initialization.
     */
    cpmp->cp_cpcr = mk_cr_cmd(CPM_ENET_PAGE, CPM_ENET_BLOCK, 0,
                              CPM_CR_INIT_TRX) | CPM_CR_FLG;
    while (cp->cp_cpcr & CPM_CR_FLG);

    cep->skb_cur = cep->skb_dirty = 0;

    sccp->scc_scce = 0xffff;	/* Clear any pending events */

    /* Enable interrupts for transmit error, complete frame
     * received, and any transmit buffer we have also set the
     * interrupt flag.
     */
    sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);

    /* Install our interrupt handler.
    */
    request_irq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev);
    /* BUG: no check for failure */

    /* Set GSMR_H to enable all normal operating modes.
     * Set GSMR_L to enable Ethernet to MC68160.
     */
    sccp->scc_gsmrh = 0;
    sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);

    /* Set sync/delimiters.
    */
    sccp->scc_dsr = 0xd555;

    /* Set processing mode.  Use Ethernet CRC, catch broadcast, and
     * start frame search 22 bit times after RENA.
     */
    sccp->scc_psmr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22);

    /* It is now OK to enable the Ethernet transmitter.
     * Unfortunately, there are board implementation differences here.
     */
    io->iop_pparc &= ~(PC_EST8260_ENET_LOOPBACK |
                       PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD);
    io->iop_psorc &= ~(PC_EST8260_ENET_LOOPBACK |
                       PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD);
    io->iop_pdirc |= (PC_EST8260_ENET_LOOPBACK |
                      PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD);
    io->iop_pdatc &= ~(PC_EST8260_ENET_LOOPBACK | PC_EST8260_ENET_SQE);
    io->iop_pdatc |= PC_EST8260_ENET_NOTFD;

    dev->base_addr = (unsigned long)ep;

    /* The CPM Ethernet specific entries in the device structure. */
    dev->open = scc_enet_open;
    dev->hard_start_xmit = scc_enet_start_xmit;
    dev->tx_timeout = scc_enet_timeout;
    dev->watchdog_timeo = TX_TIMEOUT;
    dev->stop = scc_enet_close;
    dev->get_stats = scc_enet_get_stats;
    dev->set_multicast_list = set_multicast_list;

    /* And last, enable the transmit and receive processing.
    */
    sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

    err = register_netdev(dev);
    if (err) {
        free_netdev(dev);
        return err;
    }

    printk("%s: SCC ENET Version 0.1, ", dev->name);
    for (i=0; i<5; i++)
        printk("%02x:", dev->dev_addr[i]);
    printk("%02x\n", dev->dev_addr[5]);

    return 0;
}
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
0
int serial_init (void)
{
	volatile immap_t *im = (immap_t *)CFG_IMMR;
	volatile ccsr_cpm_scc_t *sp;
	volatile scc_uart_t *up;
	volatile cbd_t *tbdf, *rbdf;
	volatile ccsr_cpm_cp_t *cp = &(im->im_cpm.im_cpm_cp);
	uint	dpaddr;

	/* initialize pointers to SCC */

	sp = (ccsr_cpm_scc_t *) &(im->im_cpm.im_cpm_scc[SCC_INDEX]);
	up = (scc_uart_t *)&(im->im_cpm.im_dprambase[PROFF_SCC]);

	/* Disable transmitter/receiver.
	*/
	sp->gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	/* put the SCC channel into NMSI (non multiplexd serial interface)
	 * mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15).
	 */
	im->im_cpm.im_cpm_mux.cmxscr = \
		(im->im_cpm.im_cpm_mux.cmxscr&~CMXSCR_MASK)|CMXSCR_VALUE;

	/* Set up the baud rate generator.
	*/
	serial_setbrg ();

	/* Allocate space for two buffer descriptors in the DP ram.
	 * damm: allocating space after the two buffers for rx/tx data
	 */

	dpaddr = m8560_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_cpm.im_dprambase[dpaddr]);
	rbdf->cbd_bufaddr = (uint) (rbdf+2);
	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
	tbdf = rbdf + 1;
	tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
	tbdf->cbd_sc = BD_SC_WRAP;

	/* Set up the uart parameters in the parameter ram.
	*/
	up->scc_genscc.scc_rbase = dpaddr;
	up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
	up->scc_genscc.scc_rfcr = CPMFCR_EB;
	up->scc_genscc.scc_tfcr = CPMFCR_EB;
	up->scc_genscc.scc_mrblr = 1;
	up->scc_maxidl = 0;
	up->scc_brkcr = 1;
	up->scc_parec = 0;
	up->scc_frmec = 0;
	up->scc_nosec = 0;
	up->scc_brkec = 0;
	up->scc_uaddr1 = 0;
	up->scc_uaddr2 = 0;
	up->scc_toseq = 0;
	up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000;
	up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000;
	up->scc_rccm = 0xc0ff;

	/* Mask all interrupts and remove anything pending.
	*/
	sp->sccm = 0;
	sp->scce = 0xffff;

	/* Set 8 bit FIFO, 16 bit oversampling and UART mode.
	*/
	sp->gsmrh = SCC_GSMRH_RFW;	/* 8 bit FIFO */
	sp->gsmrl = \
		SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART;

	/* Set CTS no flow control, 1 stop bit, 8 bit character length,
	 * normal async UART mode, no parity
	 */
	sp->psmr = SCU_PSMR_CL;

	/* execute the "Init Rx and Tx params" CP command.
	*/

	while (cp->cpcr & CPM_CR_FLG)  /* wait if cp is busy */
	  ;

	cp->cpcr = mk_cr_cmd(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK,
					0, CPM_CR_INIT_TRX) | CPM_CR_FLG;

	while (cp->cpcr & CPM_CR_FLG)  /* wait if cp is busy */
	  ;

	/* Enable transmitter/receiver.
	*/
	sp->gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT;

	return (0);
}
Ejemplo n.º 19
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)
{
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 21
0
/* The interrupt handler.
 * This is called from the CPM handler, not the MPC core interrupt.
 */
static int scc_enet_interrupt(rtdm_irq_t *irq_handle)
{
	struct rtnet_device *rtdev = rtdm_irq_get_arg(irq_handle, struct rtnet_device);
	int packets = 0;
	struct	scc_enet_private *cep;
	volatile cbd_t	*bdp;
	ushort	int_events;
	int	must_restart;
	nanosecs_abs_t time_stamp = rtdm_clock_read();


	cep = (struct scc_enet_private *)rtdev->priv;

	/* Get the interrupt events that caused us to be here.
	*/
	int_events = cep->sccp->scc_scce;
	cep->sccp->scc_scce = int_events;
	must_restart = 0;

	/* Handle receive event in its own function.
	*/
	if (int_events & SCCE_ENET_RXF) {
		scc_enet_rx(rtdev, &packets, &time_stamp);
	}

	/* Check for a transmit error.  The manual is a little unclear
	 * about this, so the debug code until I get it figured out.  It
	 * appears that if TXE is set, then TXB is not set.  However,
	 * if carrier sense is lost during frame transmission, the TXE
	 * bit is set, "and continues the buffer transmission normally."
	 * I don't know if "normally" implies TXB is set when the buffer
	 * descriptor is closed.....trial and error :-).
	 */

	/* Transmit OK, or non-fatal error.  Update the buffer descriptors.
	*/
	if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
	    rtdm_lock_get(&cep->lock);
	    bdp = cep->dirty_tx;
	    while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
		RT_DEBUG(__FUNCTION__": Tx ok\n");
		if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
		    break;

		if (bdp->cbd_sc & BD_ENET_TX_HB)	/* No heartbeat */
			cep->stats.tx_heartbeat_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_LC)	/* Late collision */
			cep->stats.tx_window_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_RL)	/* Retrans limit */
			cep->stats.tx_aborted_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_UN)	/* Underrun */
			cep->stats.tx_fifo_errors++;
		if (bdp->cbd_sc & BD_ENET_TX_CSL)	/* Carrier lost */
			cep->stats.tx_carrier_errors++;


		/* No heartbeat or Lost carrier are not really bad errors.
		 * The others require a restart transmit command.
		 */
		if (bdp->cbd_sc &
		    (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
			must_restart = 1;
			cep->stats.tx_errors++;
		}

		cep->stats.tx_packets++;

		/* Deferred means some collisions occurred during transmit,
		 * but we eventually sent the packet OK.
		 */
		if (bdp->cbd_sc & BD_ENET_TX_DEF)
			cep->stats.collisions++;

		/* Free the sk buffer associated with this last transmit.
		*/
		dev_kfree_rtskb(cep->tx_skbuff[cep->skb_dirty]);
		cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;

		/* Update pointer to next buffer descriptor to be transmitted.
		*/
		if (bdp->cbd_sc & BD_ENET_TX_WRAP)
			bdp = cep->tx_bd_base;
		else
			bdp++;

		/* I don't know if we can be held off from processing these
		 * interrupts for more than one frame time.  I really hope
		 * not.  In such a case, we would now want to check the
		 * currently available BD (cur_tx) and determine if any
		 * buffers between the dirty_tx and cur_tx have also been
		 * sent.  We would want to process anything in between that
		 * does not have BD_ENET_TX_READY set.
		 */

		/* Since we have freed up a buffer, the ring is no longer
		 * full.
		 */
		if (cep->tx_full) {
			cep->tx_full = 0;
			if (rtnetif_queue_stopped(rtdev))
				rtnetif_wake_queue(rtdev);
		}

		cep->dirty_tx = (cbd_t *)bdp;
	    }

	    if (must_restart) {
		volatile cpm8xx_t *cp;

		/* Some transmit errors cause the transmitter to shut
		 * down.  We now issue a restart transmit.  Since the
		 * errors close the BD and update the pointers, the restart
		 * _should_ pick up without having to reset any of our
		 * pointers either.
		 */
		cp = cpmp;
		cp->cp_cpcr =
		    mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
		while (cp->cp_cpcr & CPM_CR_FLG);
	    }
	    rtdm_lock_put(&cep->lock);
	}

	/* Check for receive busy, i.e. packets coming but no place to
	 * put them.  This "can't happen" because the receive interrupt
	 * is tossing previous frames.
	 */
	if (int_events & SCCE_ENET_BSY) {
		cep->stats.rx_dropped++;
		rtdm_printk("CPM ENET: BSY can't happen.\n");
	}

	if (packets > 0)
		rt_mark_stack_mgr(rtdev);
	return RTDM_IRQ_HANDLED;
}
Ejemplo n.º 22
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;
}
Ejemplo n.º 23
0
static void set_multicast_list(struct net_device *dev)
{
	struct	scc_enet_private *cep;
	struct	dev_mc_list *dmi;
	u_char	*mcptr, *tdptr;
	volatile scc_enet_t *ep;
	int	i, j;
	cep = (struct scc_enet_private *)dev->priv;

	/* Get pointer to SCC area in parameter RAM.
	*/
	ep = (scc_enet_t *)dev->base_addr;

	if (dev->flags&IFF_PROMISC) {
	  
		/* Log any net taps. */
		printk("%s: Promiscuous mode enabled.\n", dev->name);
		cep->sccp->scc_pmsr |= SCC_PMSR_PRO;
	} else {

		cep->sccp->scc_pmsr &= ~SCC_PMSR_PRO;

		if (dev->flags & IFF_ALLMULTI) {
			/* Catch all multicast addresses, so set the
			 * filter to all 1's.
			 */
			ep->sen_gaddr1 = 0xffff;
			ep->sen_gaddr2 = 0xffff;
			ep->sen_gaddr3 = 0xffff;
			ep->sen_gaddr4 = 0xffff;
		}
		else {
			/* Clear filter and add the addresses in the list.
			*/
			ep->sen_gaddr1 = 0;
			ep->sen_gaddr2 = 0;
			ep->sen_gaddr3 = 0;
			ep->sen_gaddr4 = 0;

			dmi = dev->mc_list;

			for (i=0; i<dev->mc_count; i++) {
				
				/* Only support group multicast for now.
				*/
				if (!(dmi->dmi_addr[0] & 1))
					continue;

				/* The address in dmi_addr is LSB first,
				 * and taddr is MSB first.  We have to
				 * copy bytes MSB first from dmi_addr.
				 */
				mcptr = (u_char *)dmi->dmi_addr + 5;
				tdptr = (u_char *)&ep->sen_taddrh;
				for (j=0; j<6; j++)
					*tdptr++ = *mcptr--;

				/* Ask CPM to run CRC and set bit in
				 * filter mask.
				 */
				cpmp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_SET_GADDR) | CPM_CR_FLG;
				/* this delay is necessary here -- Cort */
				udelay(10);
				while (cpmp->cp_cpcr & CPM_CR_FLG);
			}
		}
	}
}
Ejemplo n.º 24
0
static void scc_init (int scc_index)
{
	static int cpm_cr_ch[] = {
		CPM_CR_CH_SCC1,
		CPM_CR_CH_SCC2,
		CPM_CR_CH_SCC3,
		CPM_CR_CH_SCC4,
	};

	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile scc_t *sp;
	volatile scc_uart_t *up;
	volatile cbd_t *tbdf, *rbdf;
	volatile cpm8xx_t *cp = &(im->im_cpm);
	uint dpaddr;

	/* initialize pointers to SCC */

	sp = (scc_t *) & (cp->cp_scc[scc_index]);
	up = (scc_uart_t *) & cp->cp_dparam[proff_scc[scc_index]];

	/* Disable transmitter/receiver.
	 */
	sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);


	/* Allocate space for two buffer descriptors in the DP ram.
	 */

#ifdef CONFIG_SYS_ALLOC_DPRAM
	dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
#else
	dpaddr = CPM_POST_BASE;
#endif

	/* Enable SDMA.
	 */
	im->im_siu_conf.sc_sdcr = 0x0001;

	/* Set the physical address of the host memory buffers in
	 * the buffer descriptors.
	 */

	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 baud rate generator.
	 */
	cp->cp_sicr &= ~(0x000000FF << (8 * scc_index));
	/* no |= needed, since BRG1 is 000 */

	cp->cp_brgc1 =
			(((gd->cpu_clk / 16 / gd->baudrate) -
			  1) << 1) | CPM_BRG_EN;

	/* Set up the uart parameters in the parameter ram.
	 */
	up->scc_genscc.scc_rbase = dpaddr;
	up->scc_genscc.scc_tbase = dpaddr + sizeof (cbd_t);

	/* 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[scc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;

	while (cp->cp_cpcr & CPM_CR_FLG)	/* wait if cp is busy */
		;

	up->scc_genscc.scc_rfcr = SCC_EB | 0x05;
	up->scc_genscc.scc_tfcr = SCC_EB | 0x05;

	up->scc_genscc.scc_mrblr = 1;	/* Single character receive */
	up->scc_maxidl = 0;		/* disable max idle */
	up->scc_brkcr = 1;		/* send one break character on stop TX */
	up->scc_parec = 0;
	up->scc_frmec = 0;
	up->scc_nosec = 0;
	up->scc_brkec = 0;
	up->scc_uaddr1 = 0;
	up->scc_uaddr2 = 0;
	up->scc_toseq = 0;
	up->scc_char1 = 0x8000;
	up->scc_char2 = 0x8000;
	up->scc_char3 = 0x8000;
	up->scc_char4 = 0x8000;
	up->scc_char5 = 0x8000;
	up->scc_char6 = 0x8000;
	up->scc_char7 = 0x8000;
	up->scc_char8 = 0x8000;
	up->scc_rccm = 0xc0ff;

	/* Set low latency / small fifo.
	 */
	sp->scc_gsmrh = SCC_GSMRH_RFW;

	/* Set UART mode
	 */
	sp->scc_gsmrl &= ~0xF;
	sp->scc_gsmrl |= SCC_GSMRL_MODE_UART;

	/* Set local loopback mode.
	 */
	sp->scc_gsmrl &= ~SCC_GSMRL_DIAG_LE;
	sp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;

	/* Set clock divider 16 on Tx and Rx
	 */
	sp->scc_gsmrl |= (SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);

	sp->scc_psmr |= SCU_PSMR_CL;

	/* Mask all interrupts and remove anything pending.
	 */
	sp->scc_sccm = 0;
	sp->scc_scce = 0xffff;
	sp->scc_dsr = 0x7e7e;
	sp->scc_psmr = 0x3000;

	/* Make the first buffer the only buffer.
	 */
	tbdf->cbd_sc |= BD_SC_WRAP;
	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;

	/* Enable transmitter/receiver.
	 */
	sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
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);
}
Ejemplo n.º 28
0
static int scc_init (void)
{
	volatile immap_t *im = (immap_t *)CFG_IMMR;
	volatile scc_t *sp;
	volatile scc_uart_t *up;
	volatile cbd_t *tbdf, *rbdf;
	volatile cpm8xx_t *cp = &(im->im_cpm);
	uint	 dpaddr;
#if (SCC_INDEX != 2) || !defined(CONFIG_MPC850)
	volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
#endif

	/* initialize pointers to SCC */

	sp = (scc_t *) &(cp->cp_scc[SCC_INDEX]);
	up = (scc_uart_t *) &cp->cp_dparam[PROFF_SCC];

#if defined(CONFIG_LWMON) && defined(CONFIG_8xx_CONS_SCC2)
    {	/* Disable Ethernet, enable Serial */
	uchar c;

	c = pic_read  (0x61);
	c &= ~0x40;	/* enable COM3 */
	c |=  0x80;	/* disable Ethernet */
	pic_write (0x61, c);

	/* enable RTS2 */
	cp->cp_pbpar |=  0x2000;
	cp->cp_pbdat |=  0x2000;
	cp->cp_pbdir |=  0x2000;
    }
#endif	/* CONFIG_LWMON */

	/* Disable transmitter/receiver.
	*/
	sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

#if (SCC_INDEX == 2) && defined(CONFIG_MPC850)
	/*
	 * The MPC850 has SCC3 on Port B
	 */
	cp->cp_pbpar |=  0x06;
	cp->cp_pbdir &= ~0x06;
	cp->cp_pbodr &= ~0x06;

#elif (SCC_INDEX < 2) || !defined(CONFIG_IP860)
	/*
	 * Standard configuration for SCC's is on Part A
	 */
	ip->iop_papar |=  ((3 << (2 * SCC_INDEX)));
	ip->iop_padir &= ~((3 << (2 * SCC_INDEX)));
	ip->iop_paodr &= ~((3 << (2 * SCC_INDEX)));
#else
	/*
	 * The IP860 has SCC3 and SCC4 on Port D
	 */
	ip->iop_pdpar |=  ((3 << (2 * SCC_INDEX)));
#endif

	/* Allocate space for two buffer descriptors in the DP ram.
	 */

#ifdef CFG_ALLOC_DPRAM
	dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
#else
	dpaddr = CPM_SERIAL2_BASE ;
#endif

	/* Enable SDMA.
	*/
	im->im_siu_conf.sc_sdcr = 0x0001;

	/* Set the physical address of the host memory buffers in
	 * the buffer descriptors.
	 */

	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 baud rate generator.
	*/
	scc_setbrg ();

	/* Set up the uart parameters in the parameter ram.
	*/
	up->scc_genscc.scc_rbase = dpaddr;
	up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);

	/* 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_SCC, CPM_CR_INIT_TRX) | CPM_CR_FLG;

	while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
		;

	up->scc_genscc.scc_rfcr  = SCC_EB | 0x05;
	up->scc_genscc.scc_tfcr  = SCC_EB | 0x05;

	up->scc_genscc.scc_mrblr = 1;	/* Single character receive */
	up->scc_maxidl = 0;		/* disable max idle */
	up->scc_brkcr  = 1;		/* send one break character on stop TX */
	up->scc_parec  = 0;
	up->scc_frmec  = 0;
	up->scc_nosec  = 0;
	up->scc_brkec  = 0;
	up->scc_uaddr1 = 0;
	up->scc_uaddr2 = 0;
	up->scc_toseq  = 0;
	up->scc_char1  = 0x8000;
	up->scc_char2  = 0x8000;
	up->scc_char3  = 0x8000;
	up->scc_char4  = 0x8000;
	up->scc_char5  = 0x8000;
	up->scc_char6  = 0x8000;
	up->scc_char7  = 0x8000;
	up->scc_char8  = 0x8000;
	up->scc_rccm   = 0xc0ff;

	/* Set low latency / small fifo.
	 */
	sp->scc_gsmrh = SCC_GSMRH_RFW;

	/* Set SCC(x) clock mode to 16x
	 * See 8xx_io/commproc.c for details.
	 *
	 * Wire BRG1 to SCCn
	 */

	/* Set UART mode, clock divider 16 on Tx and Rx
	 */
	sp->scc_gsmrl &= ~0xF;
	sp->scc_gsmrl |=
		(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);

	sp->scc_psmr  = 0;
	sp->scc_psmr  |= SCU_PSMR_CL;

	/* Mask all interrupts and remove anything pending.
	*/
	sp->scc_sccm = 0;
	sp->scc_scce = 0xffff;
	sp->scc_dsr  = 0x7e7e;
	sp->scc_psmr = 0x3000;

	/* Make the first buffer the only buffer.
	*/
	tbdf->cbd_sc |= BD_SC_WRAP;
	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;

	/* Enable transmitter/receiver.
	*/
	sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	return (0);
}
Ejemplo n.º 29
0
void
idma_start (int sinc, int dinc, int sz, uint sbuf, uint dbuf, int ttype)
{
	/* ttype is for M-M, M-P, P-M or P-P: not used for now */

	piptr->pi_istate = 0;	/* manual says: clear it before every START_IDMA */
	piptr->pi_dcmbits.b.b_resv1 = 0;

	if (sinc == 1)
		piptr->pi_dcmbits.b.b_sinc = 1;
	else
		piptr->pi_dcmbits.b.b_sinc = 0;

	if (dinc == 1)
		piptr->pi_dcmbits.b.b_dinc = 1;
	else
		piptr->pi_dcmbits.b.b_dinc = 0;

	piptr->pi_dcmbits.b.b_erm = 0;
	piptr->pi_dcmbits.b.b_sd = 0x00;	/* M-M */

	bdf->ibd_sbuf = sbuf;
	bdf->ibd_dbuf = dbuf;
	bdf->ibd_bits.b.b_cm = 0;
	bdf->ibd_bits.b.b_interrupt = 1;
	bdf->ibd_bits.b.b_wrap = 1;
	bdf->ibd_bits.b.b_last = 1;
	bdf->ibd_bits.b.b_sdn = 0;
	bdf->ibd_bits.b.b_ddn = 0;
	bdf->ibd_bits.b.b_dgbl = 0;
	bdf->ibd_bits.b.b_ddtb = 0;
	bdf->ibd_bits.b.b_sgbl = 0;
	bdf->ibd_bits.b.b_sdtb = 0;
	bdf->ibd_bits.b.b_dbo = 1;
	bdf->ibd_bits.b.b_sbo = 1;
	bdf->ibd_bits.b.b_valid = 1;
	bdf->ibd_datlen = 512;

	*dmadonep = 0;

	immap->im_sdma.sdma_idmr2 = (uchar) 0xf;

	immap->im_cpm.cp_cpcr = mk_cr_cmd (CPM_CR_IDMA2_PAGE,
					   CPM_CR_IDMA2_SBLOCK, 0x0,
					   0x9) | 0x00010000;

	while (*dmadonep != 1) {
		if (ctrlc ()) {
			DEBUG ("\nInterrupted waiting for DMA interrupt.\n");
			goto done;
		}
		printf ("Waiting for DMA interrupt (dmadone=%d b_valid = %d)...\n",
			dmadone, bdf->ibd_bits.b.b_valid);
		udelay (1000000);
	}
	printf ("DMA complete notification received!\n");

  done:
	DEBUG ("memcmp(0x%08x, 0x%08x, 512) = %d\n",
		sbuf, dbuf, memcmp ((void *) sbuf, (void *) dbuf, 512));

	return;
}
void
kgdb_serial_init (void)
{
	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
	volatile scc_t *sp;
	volatile scc_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 SCC */

	sp = (scc_t *) &(im->im_scc[KGDB_SCC_INDEX]);
	up = (scc_uart_t *)&im->im_dprambase[KGDB_PROFF_SCC];

	/* Disable transmitter/receiver.
	*/
	sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	/* put the SCC channel into NMSI (non multiplexd serial interface)
	 * mode and wire the selected SCC Tx and Rx clocks to BRGx (15-15).
	 */
	im->im_cpmux.cmx_scr = \
		(im->im_cpmux.cmx_scr & ~KGDB_CMXSCR_MASK) | KGDB_CMXSCR_VALUE;

	/* Set up the baud rate generator.
	*/
#if defined(CONFIG_KGDB_USE_EXTC)
	m8260_cpm_extcbrg(KGDB_SCC_INDEX, speed,
		CONFIG_KGDB_EXTC_RATE, CONFIG_KGDB_EXTC_PINSEL);
#else
	m8260_cpm_setbrg(KGDB_SCC_INDEX, speed);
#endif

	/* 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 = BD_SC_EMPTY | BD_SC_WRAP;
	tbdf = rbdf + 1;
	tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
	tbdf->cbd_sc = BD_SC_WRAP;

	/* Set up the uart parameters in the parameter ram.
	*/
	up->scc_genscc.scc_rbase = dpaddr;
	up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
	up->scc_genscc.scc_rfcr = CPMFCR_EB;
	up->scc_genscc.scc_tfcr = CPMFCR_EB;
	up->scc_genscc.scc_mrblr = 1;
	up->scc_maxidl = 0;
	up->scc_brkcr = 1;
	up->scc_parec = 0;
	up->scc_frmec = 0;
	up->scc_nosec = 0;
	up->scc_brkec = 0;
	up->scc_uaddr1 = 0;
	up->scc_uaddr2 = 0;
	up->scc_toseq = 0;
	up->scc_char1 = up->scc_char2 = up->scc_char3 = up->scc_char4 = 0x8000;
	up->scc_char5 = up->scc_char6 = up->scc_char7 = up->scc_char8 = 0x8000;
	up->scc_rccm = 0xc0ff;

	/* Mask all interrupts and remove anything pending.
	*/
	sp->scc_sccm = 0;
	sp->scc_scce = 0xffff;

	/* Set 8 bit FIFO, 16 bit oversampling and UART mode.
	*/
	sp->scc_gsmrh = SCC_GSMRH_RFW;	/* 8 bit FIFO */
	sp->scc_gsmrl = \
		SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16 | SCC_GSMRL_MODE_UART;

	/* Set CTS flow control, 1 stop bit, 8 bit character length,
	 * normal async UART mode, no parity
	 */
	sp->scc_psmr = SCU_PSMR_FLC | SCU_PSMR_CL;

	/* execute the "Init Rx and Tx params" CP command.
	*/

	while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
	  ;

	cp->cp_cpcr = mk_cr_cmd(KGDB_CPM_CR_SCC_PAGE, KGDB_CPM_CR_SCC_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->scc_gsmrl |= SCC_GSMRL_ENR | SCC_GSMRL_ENT;

	printf("SCC%d at %dbps ", CONFIG_KGDB_INDEX, speed);
}