Beispiel #1
0
void scc2_lineif(struct uart_cpm_port *pinfo)
{
    /*
     * STx GP3 uses the SCC2 secondary option pin assignment
     * which this driver doesn't account for in the static
     * pin assignments. This kind of board specific info
     * really has to get out of the driver so boards can
     * be supported in a sane fashion.
     */
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
#ifndef CONFIG_STX_GP3
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);

    io->iop_pparb |= 0x008b0000;
    io->iop_pdirb |= 0x00880000;
    io->iop_psorb |= 0x00880000;
    io->iop_pdirb &= ~0x00030000;
    io->iop_psorb &= ~0x00030000;
#endif
    cpmux->cmx_scr &= 0xff00ffff;
    cpmux->cmx_scr |= 0x00090000;
    pinfo->brg = 2;

    cpm2_unmap(cpmux);
    cpm2_unmap(io);
}
Beispiel #2
0
void scc3_lineif(struct uart_cpm_port *pinfo)
{
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);

    io->iop_pparb |= 0x008b0000;
    io->iop_pdirb |= 0x00880000;
    io->iop_psorb |= 0x00880000;
    io->iop_pdirb &= ~0x00030000;
    io->iop_psorb &= ~0x00030000;
    cpmux->cmx_scr &= 0xffff00ff;
    cpmux->cmx_scr |= 0x00001200;
    pinfo->brg = 3;

    cpm2_unmap(cpmux);
    cpm2_unmap(io);
}
Beispiel #3
0
void scc4_lineif(struct uart_cpm_port *pinfo)
{
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);

    io->iop_ppard |= 0x00000600;
    io->iop_psord &= ~0x00000600;    /* Tx/Rx */
    io->iop_pdird &= ~0x00000200;    /* Rx */
    io->iop_pdird |= 0x00000400;    /* Tx */

    cpmux->cmx_scr &= 0xffffff00;
    cpmux->cmx_scr |= 0x0000001b;
    pinfo->brg = 4;

    cpm2_unmap(cpmux);
    cpm2_unmap(io);
}
Beispiel #4
0
void smc2_lineif(struct uart_cpm_port *pinfo)
{
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);

    /* SMC2 is only on port A */
    io->iop_ppara |= 0x00c00000;
    io->iop_pdira |= 0x00400000;
    io->iop_pdira &= ~0x00800000;
    io->iop_psora &= ~0x00c00000;

    /* Wire BRG2 to SMC2 */
    cpmux->cmx_smr &= 0xf0;
    pinfo->brg = 2;

    cpm2_unmap(cpmux);
    cpm2_unmap(io);
}
Beispiel #5
0
void smc1_lineif(struct uart_cpm_port *pinfo)
{
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);

    /* SMC1 is only on port D */
    io->iop_ppard |= 0x00c00000;
    io->iop_pdird |= 0x00400000;
    io->iop_pdird &= ~0x00800000;
    io->iop_psord &= ~0x00c00000;

    /* Wire BRG1 to SMC1 */
    cpmux->cmx_smr &= 0x0f;
    pinfo->brg = 1;

    cpm2_unmap(cpmux);
    cpm2_unmap(io);
}
Beispiel #6
0
int cpm2_smc_clk_setup(enum cpm_clk_target target, int clock)
{
	int ret = 0;
	int shift;
	int i, bits = 0;
	cpmux_t __iomem *im_cpmux;
	u8 __iomem *reg;
	u8 mask = 3;

	u8 clk_map[][3] = {
		{CPM_CLK_SMC1, CPM_BRG1, 0},
		{CPM_CLK_SMC1, CPM_BRG7, 1},
		{CPM_CLK_SMC1, CPM_CLK7, 2},
		{CPM_CLK_SMC1, CPM_CLK9, 3},
		{CPM_CLK_SMC2, CPM_BRG2, 0},
		{CPM_CLK_SMC2, CPM_BRG8, 1},
		{CPM_CLK_SMC2, CPM_CLK4, 2},
		{CPM_CLK_SMC2, CPM_CLK15, 3},
	};

	im_cpmux = cpm2_map(im_cpmux);

	switch (target) {
	case CPM_CLK_SMC1:
		reg = &im_cpmux->cmx_smr;
		mask = 3;
		shift = 4;
		break;
	case CPM_CLK_SMC2:
		reg = &im_cpmux->cmx_smr;
		mask = 3;
		shift = 0;
		break;
	default:
		printk(KERN_ERR "cpm2_smc_clock_setup: invalid clock target\n");
		return -EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
		if (clk_map[i][0] == target && clk_map[i][1] == clock) {
			bits = clk_map[i][2];
			break;
		}
	}
	if (i == ARRAY_SIZE(clk_map))
	    ret = -EINVAL;

	bits <<= shift;
	mask <<= shift;

	out_8(reg, (in_8(reg) & ~mask) | bits);

	cpm2_unmap(im_cpmux);
	return ret;
}
Beispiel #7
0
void scc1_lineif(struct uart_cpm_port *pinfo)
{
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);

    /* Use Port D for SCC1 instead of other functions.  */
    io->iop_ppard |= 0x00000003;
    io->iop_psord &= ~0x00000001;    /* Rx */
    io->iop_psord |= 0x00000002;    /* Tx */
    io->iop_pdird &= ~0x00000001;    /* Rx */
    io->iop_pdird |= 0x00000002;    /* Tx */

    /* Wire BRG1 to SCC1 */
    cpmux->cmx_scr &= 0x00ffffff;
    cpmux->cmx_scr |= 0x00000000;
    pinfo->brg = 1;

    cpm2_unmap(cpmux);
    cpm2_unmap(io);
}
Beispiel #8
0
/* This function is used by UARTS, or anything else that uses a 16x
 * oversampled clock.
 */
void
cpm_setbrg(uint brg, uint rate)
{
    u32 __iomem *bp;

    /* This is good enough to get SMCs running.....
    */
    if (brg < 4) {
        bp = cpm2_map_size(im_brgc1, 16);
    } else {
        bp = cpm2_map_size(im_brgc5, 16);
        brg -= 4;
    }
    bp += brg;
    out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN);

    cpm2_unmap(bp);
}
/* This function is used by UARTS, or anything else that uses a 16x
 * oversampled clock.
 */
void
cpm_setbrg(uint brg, uint rate)
{
	volatile uint	*bp;

	/* This is good enough to get SMCs running.....
	*/
	if (brg < 4) {
		bp = cpm2_map_size(im_brgc1, 16);
	} else {
		bp = cpm2_map_size(im_brgc5, 16);
		brg -= 4;
	}
	bp += brg;
	*bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN;

	cpm2_unmap(bp);
}
/* This function is used to set high speed synchronous baud rate
 * clocks.
 */
void
cpm2_fastbrg(uint brg, uint rate, int div16)
{
	volatile uint	*bp;

	if (brg < 4) {
		bp = cpm2_map_size(im_brgc1, 16);
	}
	else {
		bp = cpm2_map_size(im_brgc5, 16);
		brg -= 4;
	}
	bp += brg;
	*bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
	if (div16)
		*bp |= CPM_BRG_DIV16;

	cpm2_unmap(bp);
}
Beispiel #11
0
/* This function is used to set high speed synchronous baud rate
 * clocks.
 */
void
cpm2_fastbrg(uint brg, uint rate, int div16)
{
    u32 __iomem *bp;
    u32 val;

    if (brg < 4) {
        bp = cpm2_map_size(im_brgc1, 16);
    } else {
        bp = cpm2_map_size(im_brgc5, 16);
        brg -= 4;
    }
    bp += brg;
    val = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
    if (div16)
        val |= CPM_BRG_DIV16;

    out_be32(bp, val);
    cpm2_unmap(bp);
}
Beispiel #12
0
void __cpm2_setbrg(uint brg, uint rate, uint clk, int div16, int src)
{
	u32 __iomem *bp;
	u32 val;

	if (brg < 4) {
		bp = cpm2_map_size(im_brgc1, 16);
	} else {
		bp = cpm2_map_size(im_brgc5, 16);
		brg -= 4;
	}
	bp += brg;
	
	val = (((clk * 2 / rate) - 1) & ~1) | CPM_BRG_EN | src;
	if (div16)
		val |= CPM_BRG_DIV16;

	out_be32(bp, val);
	cpm2_unmap(bp);
}
Beispiel #13
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);
}
Beispiel #14
0
/* Set a baud rate generator.  This needs lots of work.  There are
 * eight BRGs, which can be connected to the CPM channels or output
 * as clocks.  The BRGs are in two different block of internal
 * memory mapped space.
 * The baud rate clock is the system clock divided by something.
 * It was set up long ago during the initial boot phase and is
 * is given to us.
 * Baud rate clocks are zero-based in the driver code (as that maps
 * to port numbers).  Documentation uses 1-based numbering.
 */
void __cpm2_setbrg(uint brg, uint rate, uint clk, int div16, int src)
{
	u32 __iomem *bp;
	u32 val;

	/* This is good enough to get SMCs running.....
	*/
	if (brg < 4) {
		bp = cpm2_map_size(im_brgc1, 16);
	} else {
		bp = cpm2_map_size(im_brgc5, 16);
		brg -= 4;
	}
	bp += brg;
	val = (((clk / rate) - 1) << 1) | CPM_BRG_EN | src;
	if (div16)
		val |= CPM_BRG_DIV16;

	out_be32(bp, val);
	cpm2_unmap(bp);
}
Beispiel #15
0
int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
{
	int ret = 0;
	int shift;
	int i, bits = 0;
	cpmux_t __iomem *im_cpmux;
	u32 __iomem *reg;
	u32 mask = 7;

	u8 clk_map[][3] = {
		{CPM_CLK_FCC1, CPM_BRG5, 0},
		{CPM_CLK_FCC1, CPM_BRG6, 1},
		{CPM_CLK_FCC1, CPM_BRG7, 2},
		{CPM_CLK_FCC1, CPM_BRG8, 3},
		{CPM_CLK_FCC1, CPM_CLK9, 4},
		{CPM_CLK_FCC1, CPM_CLK10, 5},
		{CPM_CLK_FCC1, CPM_CLK11, 6},
		{CPM_CLK_FCC1, CPM_CLK12, 7},
		{CPM_CLK_FCC2, CPM_BRG5, 0},
		{CPM_CLK_FCC2, CPM_BRG6, 1},
		{CPM_CLK_FCC2, CPM_BRG7, 2},
		{CPM_CLK_FCC2, CPM_BRG8, 3},
		{CPM_CLK_FCC2, CPM_CLK13, 4},
		{CPM_CLK_FCC2, CPM_CLK14, 5},
		{CPM_CLK_FCC2, CPM_CLK15, 6},
		{CPM_CLK_FCC2, CPM_CLK16, 7},
		{CPM_CLK_FCC3, CPM_BRG5, 0},
		{CPM_CLK_FCC3, CPM_BRG6, 1},
		{CPM_CLK_FCC3, CPM_BRG7, 2},
		{CPM_CLK_FCC3, CPM_BRG8, 3},
		{CPM_CLK_FCC3, CPM_CLK13, 4},
		{CPM_CLK_FCC3, CPM_CLK14, 5},
		{CPM_CLK_FCC3, CPM_CLK15, 6},
		{CPM_CLK_FCC3, CPM_CLK16, 7},
		{CPM_CLK_SCC1, CPM_BRG1, 0},
		{CPM_CLK_SCC1, CPM_BRG2, 1},
		{CPM_CLK_SCC1, CPM_BRG3, 2},
		{CPM_CLK_SCC1, CPM_BRG4, 3},
		{CPM_CLK_SCC1, CPM_CLK11, 4},
		{CPM_CLK_SCC1, CPM_CLK12, 5},
		{CPM_CLK_SCC1, CPM_CLK3, 6},
		{CPM_CLK_SCC1, CPM_CLK4, 7},
		{CPM_CLK_SCC2, CPM_BRG1, 0},
		{CPM_CLK_SCC2, CPM_BRG2, 1},
		{CPM_CLK_SCC2, CPM_BRG3, 2},
		{CPM_CLK_SCC2, CPM_BRG4, 3},
		{CPM_CLK_SCC2, CPM_CLK11, 4},
		{CPM_CLK_SCC2, CPM_CLK12, 5},
		{CPM_CLK_SCC2, CPM_CLK3, 6},
		{CPM_CLK_SCC2, CPM_CLK4, 7},
		{CPM_CLK_SCC3, CPM_BRG1, 0},
		{CPM_CLK_SCC3, CPM_BRG2, 1},
		{CPM_CLK_SCC3, CPM_BRG3, 2},
		{CPM_CLK_SCC3, CPM_BRG4, 3},
		{CPM_CLK_SCC3, CPM_CLK5, 4},
		{CPM_CLK_SCC3, CPM_CLK6, 5},
		{CPM_CLK_SCC3, CPM_CLK7, 6},
		{CPM_CLK_SCC3, CPM_CLK8, 7},
		{CPM_CLK_SCC4, CPM_BRG1, 0},
		{CPM_CLK_SCC4, CPM_BRG2, 1},
		{CPM_CLK_SCC4, CPM_BRG3, 2},
		{CPM_CLK_SCC4, CPM_BRG4, 3},
		{CPM_CLK_SCC4, CPM_CLK5, 4},
		{CPM_CLK_SCC4, CPM_CLK6, 5},
		{CPM_CLK_SCC4, CPM_CLK7, 6},
		{CPM_CLK_SCC4, CPM_CLK8, 7},
	};

	im_cpmux = cpm2_map(im_cpmux);

	switch (target) {
	case CPM_CLK_SCC1:
		reg = &im_cpmux->cmx_scr;
		shift = 24;
		break;
	case CPM_CLK_SCC2:
		reg = &im_cpmux->cmx_scr;
		shift = 16;
		break;
	case CPM_CLK_SCC3:
		reg = &im_cpmux->cmx_scr;
		shift = 8;
		break;
	case CPM_CLK_SCC4:
		reg = &im_cpmux->cmx_scr;
		shift = 0;
		break;
	case CPM_CLK_FCC1:
		reg = &im_cpmux->cmx_fcr;
		shift = 24;
		break;
	case CPM_CLK_FCC2:
		reg = &im_cpmux->cmx_fcr;
		shift = 16;
		break;
	case CPM_CLK_FCC3:
		reg = &im_cpmux->cmx_fcr;
		shift = 8;
		break;
	default:
		printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n");
		return -EINVAL;
	}

	if (mode == CPM_CLK_RX)
		shift += 3;

	for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
		if (clk_map[i][0] == target && clk_map[i][1] == clock) {
			bits = clk_map[i][2];
			break;
		}
	}
	if (i == ARRAY_SIZE(clk_map))
	    ret = -EINVAL;

	bits <<= shift;
	mask <<= shift;

	out_be32(reg, (in_be32(reg) & ~mask) | bits);

	cpm2_unmap(im_cpmux);
	return ret;
}
Beispiel #16
0
/* Setup any dynamic params in the uart desc */
int cpm_uart_init_portdesc(void)
{
#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
    u16 *addr;
#endif
    pr_debug("CPM uart[-]:init portdesc\n");

    cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
    cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
    cpm_uart_ports[UART_SMC1].port.mapbase =
        (unsigned long)cpm_uart_ports[UART_SMC1].smcp;

    cpm_uart_ports[UART_SMC1].smcup =
        (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE);
    addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2);
    *addr = PROFF_SMC1;
    cpm2_unmap(addr);

    cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
    cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
    cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
    cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
#endif

#ifdef CONFIG_SERIAL_CPM_SMC2
    cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]);
    cpm_uart_ports[UART_SMC2].port.mapbase =
        (unsigned long)cpm_uart_ports[UART_SMC2].smcp;

    cpm_uart_ports[UART_SMC2].smcup =
        (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE);
    addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2);
    *addr = PROFF_SMC2;
    cpm2_unmap(addr);

    cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
    cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
    cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
    cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
#endif

#ifdef CONFIG_SERIAL_CPM_SCC1
    cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]);
    cpm_uart_ports[UART_SCC1].port.mapbase =
        (unsigned long)cpm_uart_ports[UART_SCC1].sccp;
    cpm_uart_ports[UART_SCC1].sccup =
        (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE);

    cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
        ~(UART_SCCM_TX | UART_SCCM_RX);
    cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
        ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
    cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
    cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
#endif

#ifdef CONFIG_SERIAL_CPM_SCC2
    cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]);
    cpm_uart_ports[UART_SCC2].port.mapbase =
        (unsigned long)cpm_uart_ports[UART_SCC2].sccp;
    cpm_uart_ports[UART_SCC2].sccup =
        (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE);

    cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
        ~(UART_SCCM_TX | UART_SCCM_RX);
    cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
        ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
    cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
    cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
#endif

#ifdef CONFIG_SERIAL_CPM_SCC3
    cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]);
    cpm_uart_ports[UART_SCC3].port.mapbase =
        (unsigned long)cpm_uart_ports[UART_SCC3].sccp;
    cpm_uart_ports[UART_SCC3].sccup =
        (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE);

    cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
        ~(UART_SCCM_TX | UART_SCCM_RX);
    cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
        ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
    cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
    cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
#endif

#ifdef CONFIG_SERIAL_CPM_SCC4
    cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]);
    cpm_uart_ports[UART_SCC4].port.mapbase =
        (unsigned long)cpm_uart_ports[UART_SCC4].sccp;
    cpm_uart_ports[UART_SCC4].sccup =
        (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE);

    cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
        ~(UART_SCCM_TX | UART_SCCM_RX);
    cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
        ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
    cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
    cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
#endif

    return 0;
}
Beispiel #17
0
void init_fcc_ioports(struct fs_platform_info *fpi)
{
    struct io_port *io = cpm2_map(im_ioport);
    int fcc_no = fs_get_fcc_index(fpi->fs_no);
    int target;
    u32 tempval;

    switch(fcc_no) {
    case 1:
        tempval = in_be32(&io->iop_pdirb);
        tempval &= ~PB2_DIRB0;
        tempval |= PB2_DIRB1;
        out_be32(&io->iop_pdirb, tempval);

        tempval = in_be32(&io->iop_psorb);
        tempval &= ~PB2_PSORB0;
        tempval |= PB2_PSORB1;
        out_be32(&io->iop_psorb, tempval);

        tempval = in_be32(&io->iop_pparb);
        tempval |= (PB2_DIRB0 | PB2_DIRB1);
        out_be32(&io->iop_pparb, tempval);

        target = CPM_CLK_FCC2;
        break;
    case 2:
        tempval = in_be32(&io->iop_pdirb);
        tempval &= ~PB3_DIRB0;
        tempval |= PB3_DIRB1;
        out_be32(&io->iop_pdirb, tempval);

        tempval = in_be32(&io->iop_psorb);
        tempval &= ~PB3_PSORB0;
        tempval |= PB3_PSORB1;
        out_be32(&io->iop_psorb, tempval);

        tempval = in_be32(&io->iop_pparb);
        tempval |= (PB3_DIRB0 | PB3_DIRB1);
        out_be32(&io->iop_pparb, tempval);

        tempval = in_be32(&io->iop_pdirc);
        tempval |= PC3_DIRC1;
        out_be32(&io->iop_pdirc, tempval);

        tempval = in_be32(&io->iop_pparc);
        tempval |= PC3_DIRC1;
        out_be32(&io->iop_pparc, tempval);

        target = CPM_CLK_FCC3;
        break;
    default:
        printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
        return;
    }

    /* Port C has clocks......  */
    tempval = in_be32(&io->iop_psorc);
    tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
    out_be32(&io->iop_psorc, tempval);

    tempval = in_be32(&io->iop_pdirc);
    tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
    out_be32(&io->iop_pdirc, tempval);
    tempval = in_be32(&io->iop_pparc);
    tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8));
    out_be32(&io->iop_pparc, tempval);

    cpm2_unmap(io);

    /* Configure Serial Interface clock routing.
     * First,  clear FCC bits to zero,
     * then set the ones we want.
     */
    cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX);
    cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX);
}