Skip to content

Commit

Permalink
POWERPC: overhaul with cpm2_map mechanism
Browse files Browse the repository at this point in the history
Incorporating the new way of cpm2 immr access, introduced in the previous
patch, into CPM2 peripheral devices (fs_enet and cpm_uart). Both ppc and
powerpc approved working( real actions taken in powerpc only, ppc just
has a wrapper to keep init stuff consistent).

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
  • Loading branch information
Vitaly Bordug committed Sep 21, 2006
1 parent fc8e50e commit d3465c9
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 70 deletions.
109 changes: 60 additions & 49 deletions arch/powerpc/platforms/85xx/mpc85xx_ads.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "mpc85xx.h"

#ifdef CONFIG_CPM2
#include <linux/fs_enet_pd.h>
#include <asm/cpm2.h>
#include <sysdev/cpm2_pic.h>
#include <asm/fs_pd.h>
Expand Down Expand Up @@ -146,70 +147,81 @@ void __init mpc85xx_ads_pic_init(void)
* Setup the architecture
*/
#ifdef CONFIG_CPM2
static void init_fcc_ioports(void)
void init_fcc_ioports(struct fs_platform_info *fpi)
{
struct immap *immap;
struct io_port *io;
struct io_port *io = cpm2_map(im_ioport);
int fcc_no = fs_get_fcc_index(fpi->fs_no);
int target;
u32 tempval;

immap = cpm2_immr;

io = &immap->im_ioport;
/* FCC2/3 are on the ports B/C. */
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);

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);
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 &= ~(CLK_TRX);
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 &= ~(CLK_TRX);
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 |= (CLK_TRX);
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 all FCC bits to zero,
* First, clear FCC bits to zero,
* then set the ones we want.
*/
immap->im_cpmux.cmx_fcr &= ~(CPMUX_CLK_MASK);
immap->im_cpmux.cmx_fcr |= CPMUX_CLK_ROUTE;
cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX);
cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX);
}
#endif

Expand Down Expand Up @@ -237,7 +249,6 @@ static void __init mpc85xx_ads_setup_arch(void)

#ifdef CONFIG_CPM2
cpm2_reset();
init_fcc_ioports();
#endif

#ifdef CONFIG_PCI
Expand Down
90 changes: 90 additions & 0 deletions arch/powerpc/sysdev/cpm2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,96 @@ cpm2_fastbrg(uint brg, uint rate, int div16)
cpm2_unmap(bp);
}

int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
{
int ret = 0;
int shift;
int i, bits = 0;
cpmux_t *im_cpmux;
u32 *reg;
u32 mask = 7;
u8 clk_map [24][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}
};

im_cpmux = cpm2_map(im_cpmux);

switch (target) {
case CPM_CLK_SCC1:
reg = &im_cpmux->cmx_scr;
shift = 24;
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<24; i++) {
if (clk_map[i][0] == target && clk_map[i][1] == clock) {
bits = clk_map[i][2];
break;
}
}
if (i == sizeof(clk_map)/3)
ret = -EINVAL;

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

cpm2_unmap(im_cpmux);
return ret;
}

/*
* dpalloc / dpfree bits.
*/
Expand Down
7 changes: 7 additions & 0 deletions arch/powerpc/sysdev/fsl_soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <mm/mmu_decl.h>
#include <asm/cpm2.h>

extern void init_fcc_ioports(struct fs_platform_info*);
static phys_addr_t immrbase = -1;

phys_addr_t get_immrbase(void)
Expand Down Expand Up @@ -630,6 +631,9 @@ static int __init fs_enet_of_init(void)
goto unreg;
}

fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));

if (strstr(model, "FCC")) {
int fcc_index = fs_get_fcc_index(*id);

Expand All @@ -646,6 +650,7 @@ static int __init fs_enet_of_init(void)
snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x",
(u32)res.start, fs_enet_data.phy_addr);
fs_enet_data.bus_id = (char*)&bus_id[(*id)];
fs_enet_data.init_ioports = init_fcc_ioports;
}

of_node_put(phy);
Expand Down Expand Up @@ -717,6 +722,8 @@ static int __init cpm_uart_of_init(void)
cpm_uart_data.tx_buf_size = 32;
cpm_uart_data.rx_num_fifo = 4;
cpm_uart_data.rx_buf_size = 32;
cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));

ret =
platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
Expand Down
8 changes: 4 additions & 4 deletions arch/ppc/platforms/mpc8272ads_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ static struct fs_platform_info mpc82xx_enet_pdata[] = {
},
};

static void init_fcc1_ioports(void)
static void init_fcc1_ioports(struct fs_platform_info*)
{
struct io_port *io;
u32 tempval;
Expand Down Expand Up @@ -144,7 +144,7 @@ static void init_fcc1_ioports(void)
iounmap(immap);
}

static void init_fcc2_ioports(void)
static void init_fcc2_ioports(struct fs_platform_info*)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
Expand Down Expand Up @@ -229,7 +229,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
}
}

static void init_scc1_uart_ioports(void)
static void init_scc1_uart_ioports(struct fs_uart_platform_info*)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));

Expand All @@ -246,7 +246,7 @@ static void init_scc1_uart_ioports(void)
iounmap(immap);
}

static void init_scc4_uart_ioports(void)
static void init_scc4_uart_ioports(struct fs_uart_platform_info*)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));

Expand Down
8 changes: 4 additions & 4 deletions arch/ppc/platforms/mpc866ads_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,15 @@ void __init board_init(void)
iounmap(bcsr_io);
}

static void setup_fec1_ioports(void)
static void setup_fec1_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;

setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
}

static void setup_scc1_ioports(void)
static void setup_scc1_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
Expand Down Expand Up @@ -194,7 +194,7 @@ static void setup_scc1_ioports(void)

}

static void setup_smc1_ioports(void)
static void setup_smc1_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
Expand All @@ -216,7 +216,7 @@ static void setup_smc1_ioports(void)

}

static void setup_smc2_ioports(void)
static void setup_smc2_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
Expand Down
10 changes: 5 additions & 5 deletions arch/ppc/platforms/mpc885ads_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ void __init board_init(void)
#endif
}

static void setup_fec1_ioports(void)
static void setup_fec1_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;

Expand All @@ -181,7 +181,7 @@ static void setup_fec1_ioports(void)
clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
}

static void setup_fec2_ioports(void)
static void setup_fec2_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;

Expand All @@ -193,7 +193,7 @@ static void setup_fec2_ioports(void)
clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
}

static void setup_scc3_ioports(void)
static void setup_scc3_ioports(struct fs_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
Expand Down Expand Up @@ -315,7 +315,7 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev,
mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
}

static void setup_smc1_ioports(void)
static void setup_smc1_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
Expand All @@ -335,7 +335,7 @@ static void setup_smc1_ioports(void)
clrbits16(&immap->im_cpm.cp_pbodr, iobits);
}

static void setup_smc2_ioports(void)
static void setup_smc2_ioports(struct fs_uart_platform_info*)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
Expand Down
Loading

0 comments on commit d3465c9

Please sign in to comment.