Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

POWERPC: overhaul with cpm2_map mechanism

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>

+227 -62
+52 -41
arch/powerpc/platforms/85xx/mpc85xx_ads.c
··· 33 33 #include "mpc85xx.h" 34 34 35 35 #ifdef CONFIG_CPM2 36 + #include <linux/fs_enet_pd.h> 36 37 #include <asm/cpm2.h> 37 38 #include <sysdev/cpm2_pic.h> 38 39 #include <asm/fs_pd.h> ··· 147 146 * Setup the architecture 148 147 */ 149 148 #ifdef CONFIG_CPM2 150 - static void init_fcc_ioports(void) 149 + void init_fcc_ioports(struct fs_platform_info *fpi) 151 150 { 152 - struct immap *immap; 153 - struct io_port *io; 151 + struct io_port *io = cpm2_map(im_ioport); 152 + int fcc_no = fs_get_fcc_index(fpi->fs_no); 153 + int target; 154 154 u32 tempval; 155 155 156 - immap = cpm2_immr; 156 + switch(fcc_no) { 157 + case 1: 158 + tempval = in_be32(&io->iop_pdirb); 159 + tempval &= ~PB2_DIRB0; 160 + tempval |= PB2_DIRB1; 161 + out_be32(&io->iop_pdirb, tempval); 157 162 158 - io = &immap->im_ioport; 159 - /* FCC2/3 are on the ports B/C. */ 160 - tempval = in_be32(&io->iop_pdirb); 161 - tempval &= ~PB2_DIRB0; 162 - tempval |= PB2_DIRB1; 163 - out_be32(&io->iop_pdirb, tempval); 163 + tempval = in_be32(&io->iop_psorb); 164 + tempval &= ~PB2_PSORB0; 165 + tempval |= PB2_PSORB1; 166 + out_be32(&io->iop_psorb, tempval); 164 167 165 - tempval = in_be32(&io->iop_psorb); 166 - tempval &= ~PB2_PSORB0; 167 - tempval |= PB2_PSORB1; 168 - out_be32(&io->iop_psorb, tempval); 168 + tempval = in_be32(&io->iop_pparb); 169 + tempval |= (PB2_DIRB0 | PB2_DIRB1); 170 + out_be32(&io->iop_pparb, tempval); 169 171 170 - tempval = in_be32(&io->iop_pparb); 171 - tempval |= (PB2_DIRB0 | PB2_DIRB1); 172 - out_be32(&io->iop_pparb, tempval); 172 + target = CPM_CLK_FCC2; 173 + break; 174 + case 2: 175 + tempval = in_be32(&io->iop_pdirb); 176 + tempval &= ~PB3_DIRB0; 177 + tempval |= PB3_DIRB1; 178 + out_be32(&io->iop_pdirb, tempval); 173 179 174 - tempval = in_be32(&io->iop_pdirb); 175 - tempval &= ~PB3_DIRB0; 176 - tempval |= PB3_DIRB1; 177 - out_be32(&io->iop_pdirb, tempval); 180 + tempval = in_be32(&io->iop_psorb); 181 + tempval &= ~PB3_PSORB0; 182 + tempval |= PB3_PSORB1; 183 + out_be32(&io->iop_psorb, tempval); 178 184 179 - tempval = in_be32(&io->iop_psorb); 180 - tempval &= ~PB3_PSORB0; 181 - tempval |= PB3_PSORB1; 182 - out_be32(&io->iop_psorb, tempval); 185 + tempval = in_be32(&io->iop_pparb); 186 + tempval |= (PB3_DIRB0 | PB3_DIRB1); 187 + out_be32(&io->iop_pparb, tempval); 183 188 184 - tempval = in_be32(&io->iop_pparb); 185 - tempval |= (PB3_DIRB0 | PB3_DIRB1); 186 - out_be32(&io->iop_pparb, tempval); 189 + tempval = in_be32(&io->iop_pdirc); 190 + tempval |= PC3_DIRC1; 191 + out_be32(&io->iop_pdirc, tempval); 187 192 188 - tempval = in_be32(&io->iop_pdirc); 189 - tempval |= PC3_DIRC1; 190 - out_be32(&io->iop_pdirc, tempval); 193 + tempval = in_be32(&io->iop_pparc); 194 + tempval |= PC3_DIRC1; 195 + out_be32(&io->iop_pparc, tempval); 191 196 192 - tempval = in_be32(&io->iop_pparc); 193 - tempval |= PC3_DIRC1; 194 - out_be32(&io->iop_pparc, tempval); 197 + target = CPM_CLK_FCC3; 198 + break; 199 + default: 200 + printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n"); 201 + return; 202 + } 195 203 196 204 /* Port C has clocks...... */ 197 205 tempval = in_be32(&io->iop_psorc); 198 - tempval &= ~(CLK_TRX); 206 + tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); 199 207 out_be32(&io->iop_psorc, tempval); 200 208 201 209 tempval = in_be32(&io->iop_pdirc); 202 - tempval &= ~(CLK_TRX); 210 + tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); 203 211 out_be32(&io->iop_pdirc, tempval); 204 212 tempval = in_be32(&io->iop_pparc); 205 - tempval |= (CLK_TRX); 213 + tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); 206 214 out_be32(&io->iop_pparc, tempval); 207 215 216 + cpm2_unmap(io); 217 + 208 218 /* Configure Serial Interface clock routing. 209 - * First, clear all FCC bits to zero, 219 + * First, clear FCC bits to zero, 210 220 * then set the ones we want. 211 221 */ 212 - immap->im_cpmux.cmx_fcr &= ~(CPMUX_CLK_MASK); 213 - immap->im_cpmux.cmx_fcr |= CPMUX_CLK_ROUTE; 222 + cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX); 223 + cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX); 214 224 } 215 225 #endif 216 226 ··· 249 237 250 238 #ifdef CONFIG_CPM2 251 239 cpm2_reset(); 252 - init_fcc_ioports(); 253 240 #endif 254 241 255 242 #ifdef CONFIG_PCI
+90
arch/powerpc/sysdev/cpm2_common.c
··· 130 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 224 * dpalloc / dpfree bits. 135 225 */
+7
arch/powerpc/sysdev/fsl_soc.c
··· 36 36 #include <mm/mmu_decl.h> 37 37 #include <asm/cpm2.h> 38 38 39 + extern void init_fcc_ioports(struct fs_platform_info*); 39 40 static phys_addr_t immrbase = -1; 40 41 41 42 phys_addr_t get_immrbase(void) ··· 631 630 goto unreg; 632 631 } 633 632 633 + fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); 634 + fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); 635 + 634 636 if (strstr(model, "FCC")) { 635 637 int fcc_index = fs_get_fcc_index(*id); 636 638 ··· 650 646 snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x", 651 647 (u32)res.start, fs_enet_data.phy_addr); 652 648 fs_enet_data.bus_id = (char*)&bus_id[(*id)]; 649 + fs_enet_data.init_ioports = init_fcc_ioports; 653 650 } 654 651 655 652 of_node_put(phy); ··· 722 717 cpm_uart_data.tx_buf_size = 32; 723 718 cpm_uart_data.rx_num_fifo = 4; 724 719 cpm_uart_data.rx_buf_size = 32; 720 + cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL)); 721 + cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL)); 725 722 726 723 ret = 727 724 platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
+4 -4
arch/ppc/platforms/mpc8272ads_setup.c
··· 103 103 }, 104 104 }; 105 105 106 - static void init_fcc1_ioports(void) 106 + static void init_fcc1_ioports(struct fs_platform_info*) 107 107 { 108 108 struct io_port *io; 109 109 u32 tempval; ··· 144 144 iounmap(immap); 145 145 } 146 146 147 - static void init_fcc2_ioports(void) 147 + static void init_fcc2_ioports(struct fs_platform_info*) 148 148 { 149 149 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); 150 150 u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32)); ··· 229 229 } 230 230 } 231 231 232 - static void init_scc1_uart_ioports(void) 232 + static void init_scc1_uart_ioports(struct fs_uart_platform_info*) 233 233 { 234 234 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); 235 235 ··· 246 246 iounmap(immap); 247 247 } 248 248 249 - static void init_scc4_uart_ioports(void) 249 + static void init_scc4_uart_ioports(struct fs_uart_platform_info*) 250 250 { 251 251 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t)); 252 252
+4 -4
arch/ppc/platforms/mpc866ads_setup.c
··· 137 137 iounmap(bcsr_io); 138 138 } 139 139 140 - static void setup_fec1_ioports(void) 140 + static void setup_fec1_ioports(struct fs_platform_info*) 141 141 { 142 142 immap_t *immap = (immap_t *) IMAP_ADDR; 143 143 ··· 145 145 setbits16(&immap->im_ioport.iop_pddir, 0x1fff); 146 146 } 147 147 148 - static void setup_scc1_ioports(void) 148 + static void setup_scc1_ioports(struct fs_platform_info*) 149 149 { 150 150 immap_t *immap = (immap_t *) IMAP_ADDR; 151 151 unsigned *bcsr_io; ··· 194 194 195 195 } 196 196 197 - static void setup_smc1_ioports(void) 197 + static void setup_smc1_ioports(struct fs_uart_platform_info*) 198 198 { 199 199 immap_t *immap = (immap_t *) IMAP_ADDR; 200 200 unsigned *bcsr_io; ··· 216 216 217 217 } 218 218 219 - static void setup_smc2_ioports(void) 219 + static void setup_smc2_ioports(struct fs_uart_platform_info*) 220 220 { 221 221 immap_t *immap = (immap_t *) IMAP_ADDR; 222 222 unsigned *bcsr_io;
+5 -5
arch/ppc/platforms/mpc885ads_setup.c
··· 161 161 #endif 162 162 } 163 163 164 - static void setup_fec1_ioports(void) 164 + static void setup_fec1_ioports(struct fs_platform_info*) 165 165 { 166 166 immap_t *immap = (immap_t *) IMAP_ADDR; 167 167 ··· 181 181 clrbits32(&immap->im_cpm.cp_cptr, 0x00000100); 182 182 } 183 183 184 - static void setup_fec2_ioports(void) 184 + static void setup_fec2_ioports(struct fs_platform_info*) 185 185 { 186 186 immap_t *immap = (immap_t *) IMAP_ADDR; 187 187 ··· 193 193 clrbits32(&immap->im_cpm.cp_cptr, 0x00000080); 194 194 } 195 195 196 - static void setup_scc3_ioports(void) 196 + static void setup_scc3_ioports(struct fs_platform_info*) 197 197 { 198 198 immap_t *immap = (immap_t *) IMAP_ADDR; 199 199 unsigned *bcsr_io; ··· 315 315 mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); 316 316 } 317 317 318 - static void setup_smc1_ioports(void) 318 + static void setup_smc1_ioports(struct fs_uart_platform_info*) 319 319 { 320 320 immap_t *immap = (immap_t *) IMAP_ADDR; 321 321 unsigned *bcsr_io; ··· 335 335 clrbits16(&immap->im_cpm.cp_pbodr, iobits); 336 336 } 337 337 338 - static void setup_smc2_ioports(void) 338 + static void setup_smc2_ioports(struct fs_uart_platform_info*) 339 339 { 340 340 immap_t *immap = (immap_t *) IMAP_ADDR; 341 341 unsigned *bcsr_io;
+1 -1
drivers/net/fs_enet/fs_enet-main.c
··· 971 971 dev_set_drvdata(dev, ndev); 972 972 fep->fpi = fpi; 973 973 if (fpi->init_ioports) 974 - fpi->init_ioports(); 974 + fpi->init_ioports((struct fs_platform_info *)fpi); 975 975 976 976 #ifdef CONFIG_FS_ENET_HAS_FEC 977 977 if (fs_get_fec_index(fpi->fs_no) >= 0)
+2 -2
drivers/serial/cpm_uart/cpm_uart_core.c
··· 1180 1180 pdata = pdev->dev.platform_data; 1181 1181 if (pdata) 1182 1182 if (pdata->init_ioports) 1183 - pdata->init_ioports(); 1183 + pdata->init_ioports(pdata); 1184 1184 1185 1185 cpm_uart_drv_get_platform_data(pdev, 1); 1186 1186 } ··· 1269 1269 return ret; 1270 1270 1271 1271 if (pdata->init_ioports) 1272 - pdata->init_ioports(); 1272 + pdata->init_ioports(pdata); 1273 1273 1274 1274 ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); 1275 1275
+53
include/asm-ppc/cpm2.h
··· 1196 1196 #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1) 1197 1197 #define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2) 1198 1198 1199 + /* Clocks and GRG's */ 1200 + 1201 + enum cpm_clk_dir { 1202 + CPM_CLK_RX, 1203 + CPM_CLK_TX, 1204 + CPM_CLK_RTX 1205 + }; 1206 + 1207 + enum cpm_clk_target { 1208 + CPM_CLK_SCC1, 1209 + CPM_CLK_SCC2, 1210 + CPM_CLK_SCC3, 1211 + CPM_CLK_SCC4, 1212 + CPM_CLK_FCC1, 1213 + CPM_CLK_FCC2, 1214 + CPM_CLK_FCC3 1215 + }; 1216 + 1217 + enum cpm_clk { 1218 + CPM_CLK_NONE = 0, 1219 + CPM_BRG1, /* Baud Rate Generator 1 */ 1220 + CPM_BRG2, /* Baud Rate Generator 2 */ 1221 + CPM_BRG3, /* Baud Rate Generator 3 */ 1222 + CPM_BRG4, /* Baud Rate Generator 4 */ 1223 + CPM_BRG5, /* Baud Rate Generator 5 */ 1224 + CPM_BRG6, /* Baud Rate Generator 6 */ 1225 + CPM_BRG7, /* Baud Rate Generator 7 */ 1226 + CPM_BRG8, /* Baud Rate Generator 8 */ 1227 + CPM_CLK1, /* Clock 1 */ 1228 + CPM_CLK2, /* Clock 2 */ 1229 + CPM_CLK3, /* Clock 3 */ 1230 + CPM_CLK4, /* Clock 4 */ 1231 + CPM_CLK5, /* Clock 5 */ 1232 + CPM_CLK6, /* Clock 6 */ 1233 + CPM_CLK7, /* Clock 7 */ 1234 + CPM_CLK8, /* Clock 8 */ 1235 + CPM_CLK9, /* Clock 9 */ 1236 + CPM_CLK10, /* Clock 10 */ 1237 + CPM_CLK11, /* Clock 11 */ 1238 + CPM_CLK12, /* Clock 12 */ 1239 + CPM_CLK13, /* Clock 13 */ 1240 + CPM_CLK14, /* Clock 14 */ 1241 + CPM_CLK15, /* Clock 15 */ 1242 + CPM_CLK16, /* Clock 16 */ 1243 + CPM_CLK17, /* Clock 17 */ 1244 + CPM_CLK18, /* Clock 18 */ 1245 + CPM_CLK19, /* Clock 19 */ 1246 + CPM_CLK20, /* Clock 20 */ 1247 + CPM_CLK_DUMMY 1248 + }; 1249 + 1250 + extern int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode); 1251 + 1199 1252 #endif /* __CPM2__ */ 1200 1253 #endif /* __KERNEL__ */
+6 -4
include/linux/fs_enet_pd.h
··· 87 87 }; 88 88 89 89 struct fs_platform_info { 90 - 91 - void(*init_ioports)(void); 90 + 91 + void(*init_ioports)(struct fs_platform_info *); 92 92 /* device specific information */ 93 93 int fs_no; /* controller index */ 94 94 95 95 u32 cp_page; /* CPM page */ 96 96 u32 cp_block; /* CPM sblock */ 97 - 97 + 98 98 u32 clk_trx; /* some stuff for pins & mux configuration*/ 99 + u32 clk_rx; 100 + u32 clk_tx; 99 101 u32 clk_route; 100 102 u32 clk_mask; 101 - 103 + 102 104 u32 mem_offset; 103 105 u32 dpram_offset; 104 106 u32 fcc_regs_c;
+3 -1
include/linux/fs_uart_pd.h
··· 46 46 } 47 47 48 48 struct fs_uart_platform_info { 49 - void(*init_ioports)(void); 49 + void(*init_ioports)(struct fs_uart_platform_info *); 50 50 /* device specific information */ 51 51 int fs_no; /* controller index */ 52 52 u32 uart_clk; ··· 55 55 u8 rx_num_fifo; 56 56 u8 rx_buf_size; 57 57 u8 brg; 58 + u8 clk_rx; 59 + u8 clk_tx; 58 60 }; 59 61 60 62 #endif