1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2015 Sanchayan Maity <sanchayan.maity@toradex.com> 4 * Copyright (C) 2015 Toradex AG 5 * 6 * Based on ehci-mx6 driver 7 */ 8 9#include <common.h> 10#include <dm.h> 11#include <log.h> 12#include <usb.h> 13#include <errno.h> 14#include <asm/global_data.h> 15#include <linux/compiler.h> 16#include <asm/io.h> 17#include <asm-generic/gpio.h> 18#include <asm/arch/clock.h> 19#include <asm/arch/imx-regs.h> 20#include <asm/arch/crm_regs.h> 21#include <asm/mach-imx/iomux-v3.h> 22#include <asm/mach-imx/regs-usbphy.h> 23#include <linux/delay.h> 24#include <usb/ehci-ci.h> 25#include <linux/libfdt.h> 26#include <fdtdec.h> 27 28#include "ehci.h" 29 30#define USB_NC_REG_OFFSET 0x00000800 31 32#define ANADIG_PLL_CTRL_EN_USB_CLKS (1 << 6) 33 34#define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */ 35#define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */ 36 37/* USBCMD */ 38#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */ 39#define UCMD_RESET (1 << 1) /* controller reset */ 40 41DECLARE_GLOBAL_DATA_PTR; 42 43static const unsigned phy_bases[] = { 44 USB_PHY0_BASE_ADDR, 45 USB_PHY1_BASE_ADDR, 46}; 47 48static const unsigned nc_reg_bases[] = { 49 USBC0_BASE_ADDR, 50 USBC1_BASE_ADDR, 51}; 52 53static void usb_internal_phy_clock_gate(int index) 54{ 55 void __iomem *phy_reg; 56 57 phy_reg = (void __iomem *)phy_bases[index]; 58 clrbits_le32(phy_reg + USBPHY_CTRL, USBPHY_CTRL_CLKGATE); 59} 60 61static void usb_power_config(int index) 62{ 63 struct anadig_reg __iomem *anadig = 64 (struct anadig_reg __iomem *)ANADIG_BASE_ADDR; 65 void __iomem *pll_ctrl; 66 67 switch (index) { 68 case 0: 69 pll_ctrl = &anadig->pll3_ctrl; 70 clrbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_BYPASS); 71 setbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_ENABLE 72 | ANADIG_PLL3_CTRL_POWERDOWN 73 | ANADIG_PLL_CTRL_EN_USB_CLKS); 74 break; 75 case 1: 76 pll_ctrl = &anadig->pll7_ctrl; 77 clrbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_BYPASS); 78 setbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_ENABLE 79 | ANADIG_PLL7_CTRL_POWERDOWN 80 | ANADIG_PLL_CTRL_EN_USB_CLKS); 81 break; 82 default: 83 return; 84 } 85} 86 87static void usb_phy_enable(int index, struct usb_ehci *ehci) 88{ 89 void __iomem *phy_reg; 90 void __iomem *phy_ctrl; 91 void __iomem *usb_cmd; 92 93 phy_reg = (void __iomem *)phy_bases[index]; 94 phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL); 95 usb_cmd = (void __iomem *)&ehci->usbcmd; 96 97 /* Stop then Reset */ 98 clrbits_le32(usb_cmd, UCMD_RUN_STOP); 99 while (readl(usb_cmd) & UCMD_RUN_STOP) 100 ; 101 102 setbits_le32(usb_cmd, UCMD_RESET); 103 while (readl(usb_cmd) & UCMD_RESET) 104 ; 105 106 /* Reset USBPHY module */ 107 setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST); 108 udelay(10); 109 110 /* Remove CLKGATE and SFTRST */ 111 clrbits_le32(phy_ctrl, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST); 112 udelay(10); 113 114 /* Power up the PHY */ 115 writel(0, phy_reg + USBPHY_PWD); 116 117 /* Enable FS/LS device */ 118 setbits_le32(phy_ctrl, USBPHY_CTRL_ENUTMILEVEL2 | 119 USBPHY_CTRL_ENUTMILEVEL3); 120} 121 122static void usb_oc_config(int index) 123{ 124 void __iomem *ctrl; 125 126 ctrl = (void __iomem *)(nc_reg_bases[index] + USB_NC_REG_OFFSET); 127 128 setbits_le32(ctrl, UCTRL_OVER_CUR_POL); 129 setbits_le32(ctrl, UCTRL_OVER_CUR_DIS); 130} 131 132int __weak board_usb_phy_mode(int port) 133{ 134 return 0; 135} 136 137int __weak board_ehci_hcd_init(int port) 138{ 139 return 0; 140} 141 142int ehci_vf_common_init(struct usb_ehci *ehci, int index) 143{ 144 int ret; 145 146 /* Do board specific initialisation */ 147 ret = board_ehci_hcd_init(index); 148 if (ret) 149 return ret; 150 151 usb_power_config(index); 152 usb_oc_config(index); 153 usb_internal_phy_clock_gate(index); 154 usb_phy_enable(index, ehci); 155 156 return 0; 157} 158 159#if !CONFIG_IS_ENABLED(DM_USB) 160int ehci_hcd_init(int index, enum usb_init_type init, 161 struct ehci_hccr **hccr, struct ehci_hcor **hcor) 162{ 163 struct usb_ehci *ehci; 164 enum usb_init_type type; 165 int ret; 166 167 if (index >= ARRAY_SIZE(nc_reg_bases)) 168 return -EINVAL; 169 170 ehci = (struct usb_ehci *)nc_reg_bases[index]; 171 172 ret = ehci_vf_common_init(index); 173 if (ret) 174 return ret; 175 176 *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); 177 *hcor = (struct ehci_hcor *)((uint32_t)*hccr + 178 HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); 179 180 type = board_usb_phy_mode(index); 181 if (type != init) 182 return -ENODEV; 183 184 if (init == USB_INIT_DEVICE) { 185 setbits_le32(&ehci->usbmode, CM_DEVICE); 186 writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); 187 setbits_le32(&ehci->portsc, USB_EN); 188 } else if (init == USB_INIT_HOST) { 189 setbits_le32(&ehci->usbmode, CM_HOST); 190 writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); 191 setbits_le32(&ehci->portsc, USB_EN); 192 } 193 194 return 0; 195} 196 197int ehci_hcd_stop(int index) 198{ 199 return 0; 200} 201#else 202/* Possible port types (dual role mode) */ 203enum dr_mode { 204 DR_MODE_NONE = 0, 205 DR_MODE_HOST, /* supports host operation */ 206 DR_MODE_DEVICE, /* supports device operation */ 207 DR_MODE_OTG, /* supports both */ 208}; 209 210struct ehci_vf_priv_data { 211 struct ehci_ctrl ctrl; 212 struct usb_ehci *ehci; 213 struct gpio_desc cdet_gpio; 214 enum usb_init_type init_type; 215 enum dr_mode dr_mode; 216 u32 portnr; 217}; 218 219static int vf_usb_of_to_plat(struct udevice *dev) 220{ 221 struct ehci_vf_priv_data *priv = dev_get_priv(dev); 222 const void *dt_blob = gd->fdt_blob; 223 int node = dev_of_offset(dev); 224 const char *mode; 225 226 priv->portnr = dev_seq(dev); 227 228 priv->ehci = dev_read_addr_ptr(dev); 229 mode = fdt_getprop(dt_blob, node, "dr_mode", NULL); 230 if (mode) { 231 if (0 == strcmp(mode, "host")) { 232 priv->dr_mode = DR_MODE_HOST; 233 priv->init_type = USB_INIT_HOST; 234 } else if (0 == strcmp(mode, "peripheral")) { 235 priv->dr_mode = DR_MODE_DEVICE; 236 priv->init_type = USB_INIT_DEVICE; 237 } else if (0 == strcmp(mode, "otg")) { 238 priv->dr_mode = DR_MODE_OTG; 239 /* 240 * We set init_type to device by default when OTG 241 * mode is requested. If a valid gpio is provided 242 * we will switch the init_type based on the state 243 * of the gpio pin. 244 */ 245 priv->init_type = USB_INIT_DEVICE; 246 } else { 247 debug("%s: Cannot decode dr_mode '%s'\n", 248 __func__, mode); 249 return -EINVAL; 250 } 251 } else { 252 priv->dr_mode = DR_MODE_HOST; 253 priv->init_type = USB_INIT_HOST; 254 } 255 256 if (priv->dr_mode == DR_MODE_OTG) { 257 gpio_request_by_name_nodev(offset_to_ofnode(node), 258 "fsl,cdet-gpio", 0, &priv->cdet_gpio, 259 GPIOD_IS_IN); 260 if (dm_gpio_is_valid(&priv->cdet_gpio)) { 261 if (dm_gpio_get_value(&priv->cdet_gpio)) 262 priv->init_type = USB_INIT_DEVICE; 263 else 264 priv->init_type = USB_INIT_HOST; 265 } 266 } 267 268 return 0; 269} 270 271static int vf_init_after_reset(struct ehci_ctrl *dev) 272{ 273 struct ehci_vf_priv_data *priv = dev->priv; 274 enum usb_init_type type = priv->init_type; 275 struct usb_ehci *ehci = priv->ehci; 276 int ret; 277 278 ret = ehci_vf_common_init(priv->ehci, priv->portnr); 279 if (ret) 280 return ret; 281 282 if (type == USB_INIT_DEVICE) 283 return 0; 284 285 setbits_le32(&ehci->usbmode, CM_HOST); 286 writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); 287 setbits_le32(&ehci->portsc, USB_EN); 288 289 mdelay(10); 290 291 return 0; 292} 293 294static const struct ehci_ops vf_ehci_ops = { 295 .init_after_reset = vf_init_after_reset 296}; 297 298static int vf_usb_bind(struct udevice *dev) 299{ 300 /* 301 * Without this hack, if we return ENODEV for USB Controller 0, on 302 * probe for the next controller, USB Controller 1 will be given a 303 * sequence number of 0. This conflicts with our requirement of 304 * sequence numbers while initialising the peripherals. 305 * 306 * FIXME: Check that this still works OK with the new sequence numbers 307 */ 308 309 return 0; 310} 311 312static int ehci_usb_probe(struct udevice *dev) 313{ 314 struct usb_plat *plat = dev_get_plat(dev); 315 struct ehci_vf_priv_data *priv = dev_get_priv(dev); 316 struct usb_ehci *ehci = priv->ehci; 317 struct ehci_hccr *hccr; 318 struct ehci_hcor *hcor; 319 int ret; 320 321 ret = ehci_vf_common_init(ehci, priv->portnr); 322 if (ret) 323 return ret; 324 325 if (priv->init_type != plat->init_type) 326 return -ENODEV; 327 328 if (priv->init_type == USB_INIT_HOST) { 329 setbits_le32(&ehci->usbmode, CM_HOST); 330 writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc); 331 setbits_le32(&ehci->portsc, USB_EN); 332 } 333 334 mdelay(10); 335 336 hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); 337 hcor = (struct ehci_hcor *)((uint32_t)hccr + 338 HC_LENGTH(ehci_readl(&hccr->cr_capbase))); 339 340 return ehci_register(dev, hccr, hcor, &vf_ehci_ops, 0, priv->init_type); 341} 342 343static const struct udevice_id vf_usb_ids[] = { 344 { .compatible = "fsl,vf610-usb" }, 345 { } 346}; 347 348U_BOOT_DRIVER(usb_ehci) = { 349 .name = "ehci_vf", 350 .id = UCLASS_USB, 351 .of_match = vf_usb_ids, 352 .bind = vf_usb_bind, 353 .probe = ehci_usb_probe, 354 .remove = ehci_deregister, 355 .ops = &ehci_usb_ops, 356 .of_to_plat = vf_usb_of_to_plat, 357 .plat_auto = sizeof(struct usb_plat), 358 .priv_auto = sizeof(struct ehci_vf_priv_data), 359 .flags = DM_FLAG_ALLOC_PRIV_DMA, 360}; 361#endif 362