diff options
Diffstat (limited to 'arch/powerpc')
| -rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_ads.c | 109 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/cpm2_common.c | 90 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/fsl_soc.c | 7 |
3 files changed, 157 insertions, 49 deletions
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 7ebfe74bde40..28070e7ae507 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include "mpc85xx.h" | 33 | #include "mpc85xx.h" |
| 34 | 34 | ||
| 35 | #ifdef CONFIG_CPM2 | 35 | #ifdef CONFIG_CPM2 |
| 36 | #include <linux/fs_enet_pd.h> | ||
| 36 | #include <asm/cpm2.h> | 37 | #include <asm/cpm2.h> |
| 37 | #include <sysdev/cpm2_pic.h> | 38 | #include <sysdev/cpm2_pic.h> |
| 38 | #include <asm/fs_pd.h> | 39 | #include <asm/fs_pd.h> |
| @@ -146,70 +147,81 @@ void __init mpc85xx_ads_pic_init(void) | |||
| 146 | * Setup the architecture | 147 | * Setup the architecture |
| 147 | */ | 148 | */ |
| 148 | #ifdef CONFIG_CPM2 | 149 | #ifdef CONFIG_CPM2 |
| 149 | static void init_fcc_ioports(void) | 150 | void init_fcc_ioports(struct fs_platform_info *fpi) |
| 150 | { | 151 | { |
| 151 | struct immap *immap; | 152 | struct io_port *io = cpm2_map(im_ioport); |
| 152 | struct io_port *io; | 153 | int fcc_no = fs_get_fcc_index(fpi->fs_no); |
| 154 | int target; | ||
| 153 | u32 tempval; | 155 | u32 tempval; |
| 154 | 156 | ||
| 155 | immap = cpm2_immr; | 157 | switch(fcc_no) { |
| 156 | 158 | case 1: | |
| 157 | io = &immap->im_ioport; | 159 | tempval = in_be32(&io->iop_pdirb); |
| 158 | /* FCC2/3 are on the ports B/C. */ | 160 | tempval &= ~PB2_DIRB0; |
| 159 | tempval = in_be32(&io->iop_pdirb); | 161 | tempval |= PB2_DIRB1; |
| 160 | tempval &= ~PB2_DIRB0; | 162 | out_be32(&io->iop_pdirb, tempval); |
| 161 | tempval |= PB2_DIRB1; | 163 | |
| 162 | out_be32(&io->iop_pdirb, tempval); | 164 | tempval = in_be32(&io->iop_psorb); |
| 163 | 165 | tempval &= ~PB2_PSORB0; | |
| 164 | tempval = in_be32(&io->iop_psorb); | 166 | tempval |= PB2_PSORB1; |
| 165 | tempval &= ~PB2_PSORB0; | 167 | out_be32(&io->iop_psorb, tempval); |
| 166 | tempval |= PB2_PSORB1; | 168 | |
| 167 | out_be32(&io->iop_psorb, tempval); | 169 | tempval = in_be32(&io->iop_pparb); |
| 168 | 170 | tempval |= (PB2_DIRB0 | PB2_DIRB1); | |
| 169 | tempval = in_be32(&io->iop_pparb); | 171 | out_be32(&io->iop_pparb, tempval); |
| 170 | tempval |= (PB2_DIRB0 | PB2_DIRB1); | 172 | |
| 171 | out_be32(&io->iop_pparb, tempval); | 173 | target = CPM_CLK_FCC2; |
| 172 | 174 | break; | |
| 173 | tempval = in_be32(&io->iop_pdirb); | 175 | case 2: |
| 174 | tempval &= ~PB3_DIRB0; | 176 | tempval = in_be32(&io->iop_pdirb); |
| 175 | tempval |= PB3_DIRB1; | 177 | tempval &= ~PB3_DIRB0; |
| 176 | out_be32(&io->iop_pdirb, tempval); | 178 | tempval |= PB3_DIRB1; |
| 177 | 179 | out_be32(&io->iop_pdirb, tempval); | |
| 178 | tempval = in_be32(&io->iop_psorb); | 180 | |
| 179 | tempval &= ~PB3_PSORB0; | 181 | tempval = in_be32(&io->iop_psorb); |
| 180 | tempval |= PB3_PSORB1; | 182 | tempval &= ~PB3_PSORB0; |
| 181 | out_be32(&io->iop_psorb, tempval); | 183 | tempval |= PB3_PSORB1; |
| 182 | 184 | out_be32(&io->iop_psorb, tempval); | |
| 183 | tempval = in_be32(&io->iop_pparb); | 185 | |
| 184 | tempval |= (PB3_DIRB0 | PB3_DIRB1); | 186 | tempval = in_be32(&io->iop_pparb); |
| 185 | out_be32(&io->iop_pparb, tempval); | 187 | tempval |= (PB3_DIRB0 | PB3_DIRB1); |
| 186 | 188 | out_be32(&io->iop_pparb, tempval); | |
| 187 | tempval = in_be32(&io->iop_pdirc); | 189 | |
| 188 | tempval |= PC3_DIRC1; | 190 | tempval = in_be32(&io->iop_pdirc); |
| 189 | out_be32(&io->iop_pdirc, tempval); | 191 | tempval |= PC3_DIRC1; |
| 190 | 192 | out_be32(&io->iop_pdirc, tempval); | |
| 191 | tempval = in_be32(&io->iop_pparc); | 193 | |
| 192 | tempval |= PC3_DIRC1; | 194 | tempval = in_be32(&io->iop_pparc); |
| 193 | out_be32(&io->iop_pparc, tempval); | 195 | tempval |= PC3_DIRC1; |
| 196 | out_be32(&io->iop_pparc, tempval); | ||
| 197 | |||
| 198 | target = CPM_CLK_FCC3; | ||
| 199 | break; | ||
| 200 | default: | ||
| 201 | printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n"); | ||
| 202 | return; | ||
| 203 | } | ||
| 194 | 204 | ||
| 195 | /* Port C has clocks...... */ | 205 | /* Port C has clocks...... */ |
| 196 | tempval = in_be32(&io->iop_psorc); | 206 | tempval = in_be32(&io->iop_psorc); |
| 197 | tempval &= ~(CLK_TRX); | 207 | tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); |
| 198 | out_be32(&io->iop_psorc, tempval); | 208 | out_be32(&io->iop_psorc, tempval); |
| 199 | 209 | ||
| 200 | tempval = in_be32(&io->iop_pdirc); | 210 | tempval = in_be32(&io->iop_pdirc); |
| 201 | tempval &= ~(CLK_TRX); | 211 | tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); |
| 202 | out_be32(&io->iop_pdirc, tempval); | 212 | out_be32(&io->iop_pdirc, tempval); |
| 203 | tempval = in_be32(&io->iop_pparc); | 213 | tempval = in_be32(&io->iop_pparc); |
| 204 | tempval |= (CLK_TRX); | 214 | tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); |
| 205 | out_be32(&io->iop_pparc, tempval); | 215 | out_be32(&io->iop_pparc, tempval); |
| 206 | 216 | ||
| 217 | cpm2_unmap(io); | ||
| 218 | |||
| 207 | /* Configure Serial Interface clock routing. | 219 | /* Configure Serial Interface clock routing. |
| 208 | * First, clear all FCC bits to zero, | 220 | * First, clear FCC bits to zero, |
| 209 | * then set the ones we want. | 221 | * then set the ones we want. |
| 210 | */ | 222 | */ |
| 211 | immap->im_cpmux.cmx_fcr &= ~(CPMUX_CLK_MASK); | 223 | cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX); |
| 212 | immap->im_cpmux.cmx_fcr |= CPMUX_CLK_ROUTE; | 224 | cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX); |
| 213 | } | 225 | } |
| 214 | #endif | 226 | #endif |
| 215 | 227 | ||
| @@ -237,7 +249,6 @@ static void __init mpc85xx_ads_setup_arch(void) | |||
| 237 | 249 | ||
| 238 | #ifdef CONFIG_CPM2 | 250 | #ifdef CONFIG_CPM2 |
| 239 | cpm2_reset(); | 251 | cpm2_reset(); |
| 240 | init_fcc_ioports(); | ||
| 241 | #endif | 252 | #endif |
| 242 | 253 | ||
| 243 | #ifdef CONFIG_PCI | 254 | #ifdef CONFIG_PCI |
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c index 73376f9c1560..ec265995d5d8 100644 --- a/arch/powerpc/sysdev/cpm2_common.c +++ b/arch/powerpc/sysdev/cpm2_common.c | |||
| @@ -130,6 +130,96 @@ cpm2_fastbrg(uint brg, uint rate, int div16) | |||
| 130 | cpm2_unmap(bp); | 130 | cpm2_unmap(bp); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) | ||
| 134 | { | ||
| 135 | int ret = 0; | ||
| 136 | int shift; | ||
| 137 | int i, bits = 0; | ||
| 138 | cpmux_t *im_cpmux; | ||
| 139 | u32 *reg; | ||
| 140 | u32 mask = 7; | ||
| 141 | u8 clk_map [24][3] = { | ||
| 142 | {CPM_CLK_FCC1, CPM_BRG5, 0}, | ||
| 143 | {CPM_CLK_FCC1, CPM_BRG6, 1}, | ||
| 144 | {CPM_CLK_FCC1, CPM_BRG7, 2}, | ||
| 145 | {CPM_CLK_FCC1, CPM_BRG8, 3}, | ||
| 146 | {CPM_CLK_FCC1, CPM_CLK9, 4}, | ||
| 147 | {CPM_CLK_FCC1, CPM_CLK10, 5}, | ||
| 148 | {CPM_CLK_FCC1, CPM_CLK11, 6}, | ||
| 149 | {CPM_CLK_FCC1, CPM_CLK12, 7}, | ||
| 150 | {CPM_CLK_FCC2, CPM_BRG5, 0}, | ||
| 151 | {CPM_CLK_FCC2, CPM_BRG6, 1}, | ||
| 152 | {CPM_CLK_FCC2, CPM_BRG7, 2}, | ||
| 153 | {CPM_CLK_FCC2, CPM_BRG8, 3}, | ||
| 154 | {CPM_CLK_FCC2, CPM_CLK13, 4}, | ||
| 155 | {CPM_CLK_FCC2, CPM_CLK14, 5}, | ||
| 156 | {CPM_CLK_FCC2, CPM_CLK15, 6}, | ||
| 157 | {CPM_CLK_FCC2, CPM_CLK16, 7}, | ||
| 158 | {CPM_CLK_FCC3, CPM_BRG5, 0}, | ||
| 159 | {CPM_CLK_FCC3, CPM_BRG6, 1}, | ||
| 160 | {CPM_CLK_FCC3, CPM_BRG7, 2}, | ||
| 161 | {CPM_CLK_FCC3, CPM_BRG8, 3}, | ||
| 162 | {CPM_CLK_FCC3, CPM_CLK13, 4}, | ||
| 163 | {CPM_CLK_FCC3, CPM_CLK14, 5}, | ||
| 164 | {CPM_CLK_FCC3, CPM_CLK15, 6}, | ||
| 165 | {CPM_CLK_FCC3, CPM_CLK16, 7} | ||
| 166 | }; | ||
| 167 | |||
| 168 | im_cpmux = cpm2_map(im_cpmux); | ||
| 169 | |||
| 170 | switch (target) { | ||
| 171 | case CPM_CLK_SCC1: | ||
| 172 | reg = &im_cpmux->cmx_scr; | ||
| 173 | shift = 24; | ||
| 174 | case CPM_CLK_SCC2: | ||
| 175 | reg = &im_cpmux->cmx_scr; | ||
| 176 | shift = 16; | ||
| 177 | break; | ||
| 178 | case CPM_CLK_SCC3: | ||
| 179 | reg = &im_cpmux->cmx_scr; | ||
| 180 | shift = 8; | ||
| 181 | break; | ||
| 182 | case CPM_CLK_SCC4: | ||
| 183 | reg = &im_cpmux->cmx_scr; | ||
| 184 | shift = 0; | ||
| 185 | break; | ||
| 186 | case CPM_CLK_FCC1: | ||
| 187 | reg = &im_cpmux->cmx_fcr; | ||
| 188 | shift = 24; | ||
| 189 | break; | ||
| 190 | case CPM_CLK_FCC2: | ||
| 191 | reg = &im_cpmux->cmx_fcr; | ||
| 192 | shift = 16; | ||
| 193 | break; | ||
| 194 | case CPM_CLK_FCC3: | ||
| 195 | reg = &im_cpmux->cmx_fcr; | ||
| 196 | shift = 8; | ||
| 197 | break; | ||
| 198 | default: | ||
| 199 | printk(KERN_ERR "cpm2_clock_setup: invalid clock target\n"); | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | |||
| 203 | if (mode == CPM_CLK_RX) | ||
| 204 | shift +=3; | ||
| 205 | |||
| 206 | for (i=0; i<24; i++) { | ||
| 207 | if (clk_map[i][0] == target && clk_map[i][1] == clock) { | ||
| 208 | bits = clk_map[i][2]; | ||
| 209 | break; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | if (i == sizeof(clk_map)/3) | ||
| 213 | ret = -EINVAL; | ||
| 214 | |||
| 215 | bits <<= shift; | ||
| 216 | mask <<= shift; | ||
| 217 | out_be32(reg, (in_be32(reg) & ~mask) | bits); | ||
| 218 | |||
| 219 | cpm2_unmap(im_cpmux); | ||
| 220 | return ret; | ||
| 221 | } | ||
| 222 | |||
| 133 | /* | 223 | /* |
| 134 | * dpalloc / dpfree bits. | 224 | * dpalloc / dpfree bits. |
| 135 | */ | 225 | */ |
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 0b8a03cc3042..4e72bb983636 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <mm/mmu_decl.h> | 36 | #include <mm/mmu_decl.h> |
| 37 | #include <asm/cpm2.h> | 37 | #include <asm/cpm2.h> |
| 38 | 38 | ||
| 39 | extern void init_fcc_ioports(struct fs_platform_info*); | ||
| 39 | static phys_addr_t immrbase = -1; | 40 | static phys_addr_t immrbase = -1; |
| 40 | 41 | ||
| 41 | phys_addr_t get_immrbase(void) | 42 | phys_addr_t get_immrbase(void) |
| @@ -630,6 +631,9 @@ static int __init fs_enet_of_init(void) | |||
| 630 | goto unreg; | 631 | goto unreg; |
| 631 | } | 632 | } |
| 632 | 633 | ||
| 634 | fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); | ||
| 635 | fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); | ||
| 636 | |||
| 633 | if (strstr(model, "FCC")) { | 637 | if (strstr(model, "FCC")) { |
| 634 | int fcc_index = fs_get_fcc_index(*id); | 638 | int fcc_index = fs_get_fcc_index(*id); |
| 635 | 639 | ||
| @@ -646,6 +650,7 @@ static int __init fs_enet_of_init(void) | |||
| 646 | snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x", | 650 | snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x", |
| 647 | (u32)res.start, fs_enet_data.phy_addr); | 651 | (u32)res.start, fs_enet_data.phy_addr); |
| 648 | fs_enet_data.bus_id = (char*)&bus_id[(*id)]; | 652 | fs_enet_data.bus_id = (char*)&bus_id[(*id)]; |
| 653 | fs_enet_data.init_ioports = init_fcc_ioports; | ||
| 649 | } | 654 | } |
| 650 | 655 | ||
| 651 | of_node_put(phy); | 656 | of_node_put(phy); |
| @@ -717,6 +722,8 @@ static int __init cpm_uart_of_init(void) | |||
| 717 | cpm_uart_data.tx_buf_size = 32; | 722 | cpm_uart_data.tx_buf_size = 32; |
| 718 | cpm_uart_data.rx_num_fifo = 4; | 723 | cpm_uart_data.rx_num_fifo = 4; |
| 719 | cpm_uart_data.rx_buf_size = 32; | 724 | cpm_uart_data.rx_buf_size = 32; |
| 725 | cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); | ||
| 726 | cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); | ||
| 720 | 727 | ||
| 721 | ret = | 728 | ret = |
| 722 | platform_device_add_data(cpm_uart_dev, &cpm_uart_data, | 729 | platform_device_add_data(cpm_uart_dev, &cpm_uart_data, |
