0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/stddef.h>
0011 #include <linux/kernel.h>
0012 #include <linux/errno.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015
0016 #include <asm/io.h>
0017 #include <sysdev/fsl_soc.h>
0018
0019 #include "mpc83xx.h"
0020
0021
0022 #ifdef CONFIG_PPC_MPC834x
0023 int __init mpc834x_usb_cfg(void)
0024 {
0025 unsigned long sccr, sicrl, sicrh;
0026 void __iomem *immap;
0027 struct device_node *np = NULL;
0028 int port0_is_dr = 0, port1_is_dr = 0;
0029 const void *prop, *dr_mode;
0030
0031 immap = ioremap(get_immrbase(), 0x1000);
0032 if (!immap)
0033 return -ENOMEM;
0034
0035
0036
0037 sccr = in_be32(immap + MPC83XX_SCCR_OFFS) & ~MPC83XX_SCCR_USB_MASK;
0038 sicrl = in_be32(immap + MPC83XX_SICRL_OFFS) & ~MPC834X_SICRL_USB_MASK;
0039 sicrh = in_be32(immap + MPC83XX_SICRH_OFFS) & ~MPC834X_SICRH_USB_UTMI;
0040
0041 np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
0042 if (np) {
0043 sccr |= MPC83XX_SCCR_USB_DRCM_11;
0044
0045 prop = of_get_property(np, "phy_type", NULL);
0046 port1_is_dr = 1;
0047 if (prop && (!strcmp(prop, "utmi") ||
0048 !strcmp(prop, "utmi_wide"))) {
0049 sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
0050 sicrh |= MPC834X_SICRH_USB_UTMI;
0051 port0_is_dr = 1;
0052 } else if (prop && !strcmp(prop, "serial")) {
0053 dr_mode = of_get_property(np, "dr_mode", NULL);
0054 if (dr_mode && !strcmp(dr_mode, "otg")) {
0055 sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
0056 port0_is_dr = 1;
0057 } else {
0058 sicrl |= MPC834X_SICRL_USB1;
0059 }
0060 } else if (prop && !strcmp(prop, "ulpi")) {
0061 sicrl |= MPC834X_SICRL_USB1;
0062 } else {
0063 printk(KERN_WARNING "834x USB PHY type not supported\n");
0064 }
0065 of_node_put(np);
0066 }
0067 np = of_find_compatible_node(NULL, NULL, "fsl-usb2-mph");
0068 if (np) {
0069 sccr |= MPC83XX_SCCR_USB_MPHCM_11;
0070
0071 prop = of_get_property(np, "port0", NULL);
0072 if (prop) {
0073 if (port0_is_dr)
0074 printk(KERN_WARNING
0075 "834x USB port0 can't be used by both DR and MPH!\n");
0076 sicrl &= ~MPC834X_SICRL_USB0;
0077 }
0078 prop = of_get_property(np, "port1", NULL);
0079 if (prop) {
0080 if (port1_is_dr)
0081 printk(KERN_WARNING
0082 "834x USB port1 can't be used by both DR and MPH!\n");
0083 sicrl &= ~MPC834X_SICRL_USB1;
0084 }
0085 of_node_put(np);
0086 }
0087
0088
0089 out_be32(immap + MPC83XX_SCCR_OFFS, sccr);
0090 out_be32(immap + MPC83XX_SICRL_OFFS, sicrl);
0091 out_be32(immap + MPC83XX_SICRH_OFFS, sicrh);
0092
0093 iounmap(immap);
0094 return 0;
0095 }
0096 #endif
0097
0098 #ifdef CONFIG_PPC_MPC831x
0099 int __init mpc831x_usb_cfg(void)
0100 {
0101 u32 temp;
0102 void __iomem *immap, *usb_regs;
0103 struct device_node *np = NULL;
0104 struct device_node *immr_node = NULL;
0105 const void *prop;
0106 struct resource res;
0107 int ret = 0;
0108 #ifdef CONFIG_USB_OTG
0109 const void *dr_mode;
0110 #endif
0111
0112 np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
0113 if (!np)
0114 return -ENODEV;
0115 prop = of_get_property(np, "phy_type", NULL);
0116
0117
0118 immap = ioremap(get_immrbase(), 0x1000);
0119 if (!immap) {
0120 of_node_put(np);
0121 return -ENOMEM;
0122 }
0123
0124
0125 immr_node = of_get_parent(np);
0126 if (immr_node && (of_device_is_compatible(immr_node, "fsl,mpc8315-immr") ||
0127 of_device_is_compatible(immr_node, "fsl,mpc8308-immr")))
0128 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
0129 MPC8315_SCCR_USB_MASK,
0130 MPC8315_SCCR_USB_DRCM_01);
0131 else
0132 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS,
0133 MPC83XX_SCCR_USB_MASK,
0134 MPC83XX_SCCR_USB_DRCM_11);
0135
0136
0137 if (prop && !strcmp(prop, "ulpi")) {
0138 if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
0139 clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
0140 MPC8308_SICRH_USB_MASK,
0141 MPC8308_SICRH_USB_ULPI);
0142 } else if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) {
0143 clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
0144 MPC8315_SICRL_USB_MASK,
0145 MPC8315_SICRL_USB_ULPI);
0146 clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
0147 MPC8315_SICRH_USB_MASK,
0148 MPC8315_SICRH_USB_ULPI);
0149 } else {
0150 clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
0151 MPC831X_SICRL_USB_MASK,
0152 MPC831X_SICRL_USB_ULPI);
0153 clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
0154 MPC831X_SICRH_USB_MASK,
0155 MPC831X_SICRH_USB_ULPI);
0156 }
0157 }
0158
0159 iounmap(immap);
0160
0161 of_node_put(immr_node);
0162
0163
0164 ret = of_address_to_resource(np, 0, &res);
0165 if (ret) {
0166 of_node_put(np);
0167 return ret;
0168 }
0169 usb_regs = ioremap(res.start, resource_size(&res));
0170
0171
0172 if (prop && (!strcmp(prop, "utmi_wide") ||
0173 !strcmp(prop, "utmi"))) {
0174 u32 refsel;
0175
0176 if (of_device_is_compatible(immr_node, "fsl,mpc8308-immr"))
0177 goto out;
0178
0179 if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr"))
0180 refsel = CONTROL_REFSEL_24MHZ;
0181 else
0182 refsel = CONTROL_REFSEL_48MHZ;
0183
0184 out_be32(usb_regs + FSL_USB2_CONTROL_OFFS,
0185 CONTROL_UTMI_PHY_EN | refsel);
0186
0187 } else if (prop && !strcmp(prop, "ulpi")) {
0188
0189 temp = CONTROL_PHY_CLK_SEL_ULPI;
0190 #ifdef CONFIG_USB_OTG
0191
0192 if (!of_device_is_compatible(immr_node, "fsl,mpc8308-immr")) {
0193 dr_mode = of_get_property(np, "dr_mode", NULL);
0194 if (dr_mode && !strcmp(dr_mode, "otg"))
0195 temp |= CONTROL_OTG_PORT;
0196 }
0197 #endif
0198 out_be32(usb_regs + FSL_USB2_CONTROL_OFFS, temp);
0199 } else {
0200 printk(KERN_WARNING "831x USB PHY type not supported\n");
0201 ret = -EINVAL;
0202 }
0203
0204 out:
0205 iounmap(usb_regs);
0206 of_node_put(np);
0207 return ret;
0208 }
0209 #endif
0210
0211 #ifdef CONFIG_PPC_MPC837x
0212 int __init mpc837x_usb_cfg(void)
0213 {
0214 void __iomem *immap;
0215 struct device_node *np = NULL;
0216 const void *prop;
0217 int ret = 0;
0218
0219 np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
0220 if (!np || !of_device_is_available(np)) {
0221 of_node_put(np);
0222 return -ENODEV;
0223 }
0224 prop = of_get_property(np, "phy_type", NULL);
0225
0226 if (!prop || (strcmp(prop, "ulpi") && strcmp(prop, "serial"))) {
0227 printk(KERN_WARNING "837x USB PHY type not supported\n");
0228 of_node_put(np);
0229 return -EINVAL;
0230 }
0231
0232
0233 immap = ioremap(get_immrbase(), 0x1000);
0234 if (!immap) {
0235 of_node_put(np);
0236 return -ENOMEM;
0237 }
0238
0239
0240 clrsetbits_be32(immap + MPC83XX_SCCR_OFFS, MPC837X_SCCR_USB_DRCM_11,
0241 MPC837X_SCCR_USB_DRCM_11);
0242
0243
0244 clrsetbits_be32(immap + MPC83XX_SICRL_OFFS, MPC837X_SICRL_USB_MASK,
0245 MPC837X_SICRL_USB_ULPI);
0246
0247 iounmap(immap);
0248 of_node_put(np);
0249 return ret;
0250 }
0251 #endif