0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/init.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/fsl_devices.h>
0012 #include <linux/mdio-bitbang.h>
0013 #include <linux/of_mdio.h>
0014 #include <linux/slab.h>
0015 #include <linux/of_platform.h>
0016
0017 #include <asm/io.h>
0018 #include <asm/cpm2.h>
0019 #include <asm/udbg.h>
0020 #include <asm/machdep.h>
0021 #include <asm/time.h>
0022 #include <asm/mpc8260.h>
0023
0024 #include <sysdev/fsl_soc.h>
0025 #include <sysdev/cpm2_pic.h>
0026
0027 #include "pq2.h"
0028
0029 static u8 __iomem *ep8248e_bcsr;
0030 static struct device_node *ep8248e_bcsr_node;
0031
0032 #define BCSR7_SCC2_ENABLE 0x10
0033
0034 #define BCSR8_PHY1_ENABLE 0x80
0035 #define BCSR8_PHY1_POWER 0x40
0036 #define BCSR8_PHY2_ENABLE 0x20
0037 #define BCSR8_PHY2_POWER 0x10
0038 #define BCSR8_MDIO_READ 0x04
0039 #define BCSR8_MDIO_CLOCK 0x02
0040 #define BCSR8_MDIO_DATA 0x01
0041
0042 #define BCSR9_USB_ENABLE 0x80
0043 #define BCSR9_USB_POWER 0x40
0044 #define BCSR9_USB_HOST 0x20
0045 #define BCSR9_USB_FULL_SPEED_TARGET 0x10
0046
0047 static void __init ep8248e_pic_init(void)
0048 {
0049 struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,pq2-pic");
0050 if (!np) {
0051 printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
0052 return;
0053 }
0054
0055 cpm2_pic_init(np);
0056 of_node_put(np);
0057 }
0058
0059 static void ep8248e_set_mdc(struct mdiobb_ctrl *ctrl, int level)
0060 {
0061 if (level)
0062 setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_CLOCK);
0063 else
0064 clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_CLOCK);
0065
0066
0067 in_8(&ep8248e_bcsr[8]);
0068 }
0069
0070 static void ep8248e_set_mdio_dir(struct mdiobb_ctrl *ctrl, int output)
0071 {
0072 if (output)
0073 clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_READ);
0074 else
0075 setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_READ);
0076
0077
0078 in_8(&ep8248e_bcsr[8]);
0079 }
0080
0081 static void ep8248e_set_mdio_data(struct mdiobb_ctrl *ctrl, int data)
0082 {
0083 if (data)
0084 setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_DATA);
0085 else
0086 clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_DATA);
0087
0088
0089 in_8(&ep8248e_bcsr[8]);
0090 }
0091
0092 static int ep8248e_get_mdio_data(struct mdiobb_ctrl *ctrl)
0093 {
0094 return in_8(&ep8248e_bcsr[8]) & BCSR8_MDIO_DATA;
0095 }
0096
0097 static const struct mdiobb_ops ep8248e_mdio_ops = {
0098 .set_mdc = ep8248e_set_mdc,
0099 .set_mdio_dir = ep8248e_set_mdio_dir,
0100 .set_mdio_data = ep8248e_set_mdio_data,
0101 .get_mdio_data = ep8248e_get_mdio_data,
0102 .owner = THIS_MODULE,
0103 };
0104
0105 static struct mdiobb_ctrl ep8248e_mdio_ctrl = {
0106 .ops = &ep8248e_mdio_ops,
0107 };
0108
0109 static int ep8248e_mdio_probe(struct platform_device *ofdev)
0110 {
0111 struct mii_bus *bus;
0112 struct resource res;
0113 struct device_node *node;
0114 int ret;
0115
0116 node = of_get_parent(ofdev->dev.of_node);
0117 of_node_put(node);
0118 if (node != ep8248e_bcsr_node)
0119 return -ENODEV;
0120
0121 ret = of_address_to_resource(ofdev->dev.of_node, 0, &res);
0122 if (ret)
0123 return ret;
0124
0125 bus = alloc_mdio_bitbang(&ep8248e_mdio_ctrl);
0126 if (!bus)
0127 return -ENOMEM;
0128
0129 bus->name = "ep8248e-mdio-bitbang";
0130 bus->parent = &ofdev->dev;
0131 snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
0132
0133 ret = of_mdiobus_register(bus, ofdev->dev.of_node);
0134 if (ret)
0135 goto err_free_bus;
0136
0137 return 0;
0138 err_free_bus:
0139 free_mdio_bitbang(bus);
0140 return ret;
0141 }
0142
0143 static int ep8248e_mdio_remove(struct platform_device *ofdev)
0144 {
0145 BUG();
0146 return 0;
0147 }
0148
0149 static const struct of_device_id ep8248e_mdio_match[] = {
0150 {
0151 .compatible = "fsl,ep8248e-mdio-bitbang",
0152 },
0153 {},
0154 };
0155
0156 static struct platform_driver ep8248e_mdio_driver = {
0157 .driver = {
0158 .name = "ep8248e-mdio-bitbang",
0159 .of_match_table = ep8248e_mdio_match,
0160 },
0161 .probe = ep8248e_mdio_probe,
0162 .remove = ep8248e_mdio_remove,
0163 };
0164
0165 struct cpm_pin {
0166 int port, pin, flags;
0167 };
0168
0169 static __initdata struct cpm_pin ep8248e_pins[] = {
0170
0171 {2, 4, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0172 {2, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0173
0174
0175 {2, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0176 {2, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0177 {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0178 {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0179 {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0180
0181
0182 {0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0183 {0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0184 {0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0185 {0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0186 {0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0187 {0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0188 {0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0189 {0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0190 {0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
0191 {0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
0192 {0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0193 {0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0194 {0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
0195 {0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
0196 {2, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0197 {2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0198
0199
0200 {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0201 {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0202 {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0203 {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0204 {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0205 {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0206 {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0207 {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0208 {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0209 {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0210 {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0211 {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0212 {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0213 {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0214 {2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0215 {2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0216
0217
0218 {4, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
0219 {4, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
0220
0221
0222 {2, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0223 {2, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0224 {2, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0225 {2, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0226 {3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0227 {3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
0228 {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
0229 };
0230
0231 static void __init init_ioports(void)
0232 {
0233 int i;
0234
0235 for (i = 0; i < ARRAY_SIZE(ep8248e_pins); i++) {
0236 const struct cpm_pin *pin = &ep8248e_pins[i];
0237 cpm2_set_pin(pin->port, pin->pin, pin->flags);
0238 }
0239
0240 cpm2_smc_clk_setup(CPM_CLK_SMC1, CPM_BRG7);
0241 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
0242 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
0243 cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK8, CPM_CLK_TX);
0244 cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK11, CPM_CLK_RX);
0245 cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_TX);
0246 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);
0247 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
0248 }
0249
0250 static void __init ep8248e_setup_arch(void)
0251 {
0252 if (ppc_md.progress)
0253 ppc_md.progress("ep8248e_setup_arch()", 0);
0254
0255 cpm2_reset();
0256
0257
0258
0259
0260 clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
0261
0262 ep8248e_bcsr_node =
0263 of_find_compatible_node(NULL, NULL, "fsl,ep8248e-bcsr");
0264 if (!ep8248e_bcsr_node) {
0265 printk(KERN_ERR "No bcsr in device tree\n");
0266 return;
0267 }
0268
0269 ep8248e_bcsr = of_iomap(ep8248e_bcsr_node, 0);
0270 if (!ep8248e_bcsr) {
0271 printk(KERN_ERR "Cannot map BCSR registers\n");
0272 of_node_put(ep8248e_bcsr_node);
0273 ep8248e_bcsr_node = NULL;
0274 return;
0275 }
0276
0277 setbits8(&ep8248e_bcsr[7], BCSR7_SCC2_ENABLE);
0278 setbits8(&ep8248e_bcsr[8], BCSR8_PHY1_ENABLE | BCSR8_PHY1_POWER |
0279 BCSR8_PHY2_ENABLE | BCSR8_PHY2_POWER);
0280
0281 init_ioports();
0282
0283 if (ppc_md.progress)
0284 ppc_md.progress("ep8248e_setup_arch(), finish", 0);
0285 }
0286
0287 static const struct of_device_id of_bus_ids[] __initconst = {
0288 { .compatible = "simple-bus", },
0289 { .compatible = "fsl,ep8248e-bcsr", },
0290 {},
0291 };
0292
0293 static int __init declare_of_platform_devices(void)
0294 {
0295 of_platform_bus_probe(NULL, of_bus_ids, NULL);
0296
0297 if (IS_ENABLED(CONFIG_MDIO_BITBANG))
0298 platform_driver_register(&ep8248e_mdio_driver);
0299
0300 return 0;
0301 }
0302 machine_device_initcall(ep8248e, declare_of_platform_devices);
0303
0304
0305
0306
0307 static int __init ep8248e_probe(void)
0308 {
0309 return of_machine_is_compatible("fsl,ep8248e");
0310 }
0311
0312 define_machine(ep8248e)
0313 {
0314 .name = "Embedded Planet EP8248E",
0315 .probe = ep8248e_probe,
0316 .setup_arch = ep8248e_setup_arch,
0317 .init_IRQ = ep8248e_pic_init,
0318 .get_irq = cpm2_get_irq,
0319 .calibrate_decr = generic_calibrate_decr,
0320 .restart = pq2_restart,
0321 .progress = udbg_progress,
0322 };