1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12#include <platsupport/clock.h> 13#include <usb/usb_host.h> 14#include "../usb_otg.h" 15#include "../../ehci/ehci.h" 16#include "../../services.h" 17#include <stdio.h> 18#include <stddef.h> 19 20#define USB_PHY1_PADDR 0x20C9000 21#define USB_PHY2_PADDR 0x20CA000 22#define USB_PADDR 0x2184000 23 24#define USB_HOST1_IRQ 72 25#define USB_HOST2_IRQ 73 26#define USB_HOST3_IRQ 74 27#define USB_OTG_IRQ 75 28 29#define USB_PHY1_SIZE 0x0001000 30#define USB_PHY2_SIZE 0x0001000 31#define USB_SIZE 0x0001000 32 33#define IMX6_PORTSC_PTS_MASK ((3UL << 30) | (1UL << 25)) 34#define IMX6_PORTSC_PTS_UTMI ((0UL << 30) | (0UL << 25)) 35#define IMX6_PORTSC_PTS_ULPI ((2UL << 30) | (0UL << 25)) 36#define IMX6_PORTSC_PTS_ICUSB ((3UL << 30) | (0UL << 25)) 37#define IMX6_PORTSC_PTS_HSIC ((4UL << 30) | (1UL << 25)) 38#define IMX6_PORTSC_STS (1UL << 29) 39#define IMX6_PORTSC_PTW (1UL << 28) 40 41struct usb_sct { 42 uint32_t val; 43 uint32_t set; 44 uint32_t clr; 45 uint32_t tog; 46}; 47 48 49//USB_PHY1_PADDR 50//USB_PHY2_PADDR 51struct usb_phy_regs { 52 struct usb_sct pwd; /* 0x00 */ 53 struct usb_sct tx; /* 0x10 */ 54 struct usb_sct rx; /* 0x20 */ 55#define PHYCTRL_SFTRST BIT(31) 56#define PHYCTRL_CLKGATE BIT(30) 57#define PHYCTRL_UTMI_SUSPENDM BIT(29) 58#define PHYCTRL_HOST_FORCE_LS_SE0 BIT(28) 59#define PHYCTRL_OTG_ID_VALUE BIT(27) 60#define PHYCTRL_FSDLL_RST_EN BIT(24) 61#define PHYCTRL_ENVBUSCHG_WKUP BIT(23) 62#define PHYCTRL_ENIDCHG_WKUP BIT(22) 63#define PHYCTRL_ENDPDMCHG_WKUP BIT(21) 64#define PHYCTRL_ENAUTOCLR_PHY_PWD BIT(20) 65#define PHYCTRL_ENAUTOCLR_CLKGATE BIT(19) 66#define PHYCTRL_WAKEUP_IRQ BIT(17) 67#define PHYCTRL_ENIRQWAKEUP BIT(16) 68#define PHYCTRL_ENUTMIL3 BIT(15) 69#define PHYCTRL_ENUTMIL2 BIT(14) 70#define PHYCTRL_DATA_ON_LRADC BIT(13) 71#define PHYCTRL_DEVPLUGIN_IRQ BIT(12) 72#define PHYCTRL_ENIRQDEVPLUGIN BIT(11) 73#define PHYCTRL_RESUME_IRQ BIT(10) 74#define PHYCTRL_ENIRQRESUMEDETECT BIT( 9) 75#define PHYCTRL_RESUMEIRQSTICKY BIT( 8) 76#define PHYCTRL_ENOTGIDDETECT BIT( 7) 77#define PHYCTRL_OTG_ID_CHG_IRQ BIT( 6) 78#define PHYCTRL_DEVPLUGIN_POLARITY BIT( 5) 79#define PHYCTRL_ENDEVPLUGINDETECT BIT( 4) 80#define PHYCTRL_HOSTDISCONDETECT_IRQ BIT( 3) 81#define PHYCTRL_ENIRQHOSTDISCON BIT( 2) 82#define PHYCTRL_ENHOSTDISCONDETECT BIT( 1) 83#define PHYCTRL_ENOTG_ID_CHG_IRQ BIT( 0) 84 struct usb_sct ctrl; /* 0x30 */ 85 uint32_t status; /* 0x40 */ 86 uint32_t res0[3]; 87 struct usb_sct debug; /* 0x50 */ 88 uint32_t debug0_status; /* 0x60 */ 89 uint32_t res1[3]; 90 struct usb_sct debug1; /* 0x70 */ 91 uint32_t version; /* 0x80 */ 92}; 93 94 95 96 97struct usb_otg_regs { 98 uint32_t id; /* +0x000 */ 99 uint32_t hwgeneral; /* +0x004 */ 100 uint32_t hwhost; /* +0x008 */ 101 uint32_t otg_hwdevice; /* +0x00C */ 102 uint32_t hwtxbuf; /* +0x010 */ 103 uint32_t hwrxbuf; /* +0x014 */ 104 uint32_t res02[26]; 105 uint32_t gptimer0ld; /* +0x080 */ 106 uint32_t gptimer0ctrl; /* +0x084 */ 107 uint32_t gptimer1ld; /* +0x088 */ 108 uint32_t gptimer1ctrl; /* +0x08C */ 109 uint32_t sbuscfg; /* +0x090 */ 110 uint32_t res03[27]; 111 112 /* capability registers */ 113 uint8_t caplength; /* +0x100 */ 114 uint8_t res05[1]; 115 uint16_t hciversion; /* +0x102 */ 116 uint32_t hcsparams; /* +0x104 */ 117 uint32_t hccparams; /* +0x108 */ 118 uint32_t res06[5]; 119 uint32_t otg_dciversion; /* +0x120 */ 120 uint32_t otg_dccparams; /* +0x124 */ 121 uint32_t res08[6]; 122 123 /* operational registers */ 124 uint32_t usbcmd; /* +0x140 */ 125 uint32_t usbsts; /* +0x144 */ 126 uint32_t usbintr; /* +0x148 */ 127 uint32_t frindex; /* +0x14C */ 128 uint32_t res09[1]; 129 uint32_t otg_deviceaddr; /* +0x154 */ 130 uint32_t otg_endptlistaddr; /* +0x158 */ 131 uint32_t res10[1]; 132 uint32_t burstsize; /* +0x160 */ 133 uint32_t txfilltuning; /* +0x164 */ 134 uint32_t res11[4]; 135 uint32_t otg_endptnak; /* +0x178 */ 136 uint32_t otg_endptnaken; /* +0x17C */ 137 uint32_t configflag; /* +0x180 */ 138 uint32_t portsc1; /* +0x184 */ 139 140 uint32_t res13[7]; 141 uint32_t otg_otgsc; /* +0x1A4 */ 142#define USBMODE_HOST (0x3 << 0) 143#define USBMODE_DEV (0x2 << 0) 144#define USBMODE_IDLE (0x0 << 0) 145 uint32_t usbmode; /* +0x1A8 */ 146 uint32_t otg_endptsetupstat; /* +0x1AC */ 147 uint32_t otg_endptprime; /* +0x1B0 */ 148 uint32_t otg_endptflush; /* +0x1B4 */ 149 uint32_t otg_endptstat; /* +0x1B8 */ 150 uint32_t otg_endptcomplete; /* +0x1BC */ 151 uint32_t otg_endptctrl0; /* +0x1C0 */ 152 uint32_t otg_endptctrl1; /* +0x1C4 */ 153 uint32_t otg_endptctrl2; /* +0x1C8 */ 154 uint32_t otg_endptctrl3; /* +0x1CC */ 155 uint32_t otg_endptctrl4; /* +0x1D0 */ 156 uint32_t otg_endptctrl5; /* +0x1D4 */ 157 uint32_t otg_endptctrl6; /* +0x1D8 */ 158 uint32_t otg_endptctrl7; /* +0x1DC */ 159 uint32_t res16[8]; 160}; 161 162struct usb_host_regs { 163 uint32_t id; /* +0x000 */ 164 uint32_t hwgeneral; /* +0x004 */ 165 uint32_t hwhost; /* +0x008 */ 166 uint32_t res01[1]; 167 uint32_t hwtxbuf; /* +0x010 */ 168 uint32_t hwrxbuf; /* +0x014 */ 169 uint32_t res02[26]; 170 uint32_t gptimer0ld; /* +0x080 */ 171 uint32_t gptimer0ctrl; /* +0x084 */ 172 uint32_t gptimer1ld; /* +0x088 */ 173 uint32_t gptimer1ctrl; /* +0x08C */ 174 uint32_t sbuscfg; /* +0x090 */ 175 uint32_t res03[27]; 176 177 /* capability registers */ 178 uint8_t caplength; /* +0x100 */ 179 uint8_t res05[1]; 180 uint16_t hciversion; /* +0x102 */ 181 uint32_t hcsparams; /* +0x104 */ 182 uint32_t hccparams; /* +0x108 */ 183 uint32_t res06[5]; 184 uint32_t res07[2]; 185 uint32_t res08[6]; 186 187 /* operational registers */ 188 uint32_t usbcmd; /* +0x140 */ 189 uint32_t usbsts; /* +0x144 */ 190 uint32_t usbintr; /* +0x148 */ 191 uint32_t frindex; /* +0x14C */ 192 uint32_t res09[1]; 193 uint32_t host_periodiclistbase; /* +0x154 */ 194 uint32_t host_asynclistaddr; /* +0x158 */ 195 uint32_t res10[1]; 196 uint32_t burstsize; /* +0x160 */ 197 uint32_t txfilltuning; /* +0x164 */ 198 uint32_t res11[4]; 199 uint32_t res12[2]; 200 uint32_t configflag; /* +0x180 */ 201 uint32_t portsc1; /* +0x184 */ 202 203 uint32_t res13[7]; 204 uint32_t res14[1]; 205 206 uint32_t usbmode; /* +0x1A8 */ 207 uint32_t res15[13]; 208 uint32_t res16[8]; 209}; 210 211struct usb_regs { 212 /* Core */ 213 struct usb_otg_regs otg; /* +0x000 */ 214 struct usb_host_regs host1; /* +0x200 */ 215 struct usb_host_regs host2; /* +0x400 */ 216 struct usb_host_regs host3; /* +0x600 */ 217 /* Non-core */ 218#define USBCTRL_WIR BIT(31) 219#define USBCTRL_WKUP_VBUS_EN BIT(17) 220#define USBCTRL_WKUP_ID_EN BIT(16) 221#define USBCTRL_WKUP_SW BIT(15) 222#define USBCTRL_WKUP_SW_EN BIT(14) 223#define USBCTRL_UTMI_ON_CLOCK BIT(13) 224#define USBCTRL_SUSPENDM BIT(12) 225#define USBCTRL_RESET BIT(11) 226#define USBCTRL_WIE BIT(10) 227#define USBCTRL_PWR_POL BIT( 9) 228#define USBCTRL_OVER_CUR_POL BIT( 8) 229#define USBCTRL_OVER_CUR_DIS BIT( 7) 230 uint32_t otg_ctrl; /* +0x800 */ 231 uint32_t host1_ctrl; /* +0x804 */ 232 uint32_t host2_ctrl; /* +0x808 */ 233 uint32_t host3_ctrl; /* +0x80C */ 234 uint32_t host2_hsic_ctrl; /* +0x810 */ 235 uint32_t host3_hsic_ctrl; /* +0x814 */ 236 uint32_t otg_phy_ctrl_0; /* +0x818 */ 237 uint32_t host1_phy_ctrl_0; /* +0x81C */ 238}; 239 240 241static volatile struct usb_phy_regs *_usb_phy1_regs = NULL; 242static volatile struct usb_phy_regs *_usb_phy2_regs = NULL; 243static volatile struct usb_regs *_usb_regs = NULL; 244 245static const int _usb_irqs[] = { 246 [USB_OTG0] = USB_OTG_IRQ, 247 [USB_HOST1] = USB_HOST1_IRQ, 248 [USB_HOST2] = USB_HOST2_IRQ, 249 [USB_HOST3] = USB_HOST3_IRQ 250}; 251 252static void 253phy_enable(int devid, ps_io_ops_t* o) 254{ 255 volatile struct usb_phy_regs* phy_regs; 256 clk_t* clk; 257 258 clock_sys_init(o, &o->clock_sys); 259 switch (devid) { 260 case 0: 261 clk = clk_get_clock(&o->clock_sys, CLK_USB1); 262 if (_usb_phy1_regs == NULL) { 263 _usb_phy1_regs = GET_RESOURCE(o, USB_PHY1); 264 } 265 phy_regs = _usb_phy1_regs; 266 if (!clk || !phy_regs) { 267 ZF_LOGF("Clock error\n"); 268 } 269 break; 270 case 1: 271 clk = clk_get_clock(&o->clock_sys, CLK_USB2); 272 if (_usb_phy2_regs == NULL) { 273 _usb_phy2_regs = GET_RESOURCE(o, USB_PHY2); 274 } 275 phy_regs = _usb_phy2_regs; 276 if (!clk || !phy_regs) { 277 ZF_LOGF("Clock error\n"); 278 } 279 break; 280 default: 281 phy_regs = NULL; 282 clk = NULL; 283 break; 284 } 285 286 287 if (phy_regs) { 288 if (clk == NULL) { 289 ZF_LOGD("Failed to initialise USB PHY clock\n"); 290 } 291 /* Enable clocks */ 292 phy_regs->ctrl.clr = PHYCTRL_CLKGATE; 293 /* Reset PHY */ 294 phy_regs->ctrl.set = PHYCTRL_SFTRST; 295 dsb(); 296 ps_udelay(10); 297 phy_regs->ctrl.clr = PHYCTRL_SFTRST; 298 dsb(); 299 ps_udelay(10); 300 /* Enable PHY and FS/LS */ 301 phy_regs->pwd.val = 0; 302 phy_regs->ctrl.set = PHYCTRL_ENUTMIL3 | PHYCTRL_ENUTMIL2; 303 dsb(); 304 ps_mdelay(10); 305 } 306} 307 308static int 309imx6_usb_generic_init(int id, ps_io_ops_t* ioops) 310{ 311 struct usb_host_regs * hc_regs = NULL; 312 volatile uint32_t* hc_ctrl; 313 314 if (id < 0 || id > USB_NHOSTS) { 315 ZF_LOGF("Invalid host id\n"); 316 } 317 /* Check device mappings */ 318 if (_usb_regs == NULL) { 319 _usb_regs = GET_RESOURCE(ioops, USB); 320 } 321 if (_usb_regs == NULL) { 322 return -1; 323 } 324 hc_regs = (struct usb_host_regs*)_usb_regs + id; 325 hc_ctrl = &_usb_regs->otg_ctrl + id; 326 327 /* Reset the EHCI controller */ 328 hc_regs->usbcmd |= EHCICMD_HCRESET; 329 /* Disable over-current */ 330 *hc_ctrl |= USBCTRL_OVER_CUR_POL; 331 *hc_ctrl |= USBCTRL_OVER_CUR_DIS; 332 /* Enable the PHY */ 333 phy_enable(id, ioops); 334 return 0; 335} 336 337 338int 339usb_host_init(enum usb_host_id id, ps_io_ops_t* ioops, ps_mutex_ops_t *sync, 340 usb_host_t* hdev) 341{ 342 struct usb_host_regs * hc_regs = NULL; 343 int err; 344 if (id < 0 || id > USB_NHOSTS) { 345 return -1; 346 } 347 348 if (!ioops || !hdev) { 349 ZF_LOGF("Invalid arguments\n"); 350 } 351 352 hdev->id = id; 353 hdev->dman = &ioops->dma_manager; 354 hdev->sync = sync; 355 356 err = imx6_usb_generic_init(hdev->id, ioops); 357 if (err) { 358 return -1; 359 } 360 /* Pass control to EHCI initialisation */ 361 hc_regs = (struct usb_host_regs*)_usb_regs + hdev->id; 362 hc_regs->usbmode = USBMODE_HOST; 363 err = ehci_host_init(hdev, (uintptr_t)&hc_regs->caplength, NULL); 364 /* Configure ports */ 365 hc_regs->portsc1 = IMX6_PORTSC_PTS_UTMI | IMX6_PORTSC_PTW; 366 return err; 367} 368 369const int* 370usb_host_irqs(usb_host_t* host, int* nirqs) 371{ 372 if (host->id < 0 || host->id > USB_NHOSTS) { 373 return NULL; 374 } 375 376 if (nirqs) { 377 *nirqs = 1; 378 } 379 host->irqs = &_usb_irqs[host->id]; 380 381 return host->irqs; 382} 383 384int 385usb_plat_otg_init(usb_otg_t odev, ps_io_ops_t* ioops) 386{ 387 struct usb_otg_regs* otg_regs; 388 int err; 389 390 if (!odev->dman || !odev->id) { 391 ZF_LOGF("Invalid arguments\n"); 392 } 393 err = imx6_usb_generic_init(odev->id, ioops); 394 if (err) { 395 return -1; 396 } 397 otg_regs = (struct usb_otg_regs*)_usb_regs + odev->id; 398 otg_regs->usbmode = USBMODE_DEV; 399 err = ehci_otg_init(odev, (uintptr_t)&otg_regs->caplength); 400 if (otg_regs->usbmode != USBMODE_DEV) { 401 ZF_LOGF("Set the hardware to device mode\n"); 402 } 403 404 return err; 405} 406 407 408