ref: 07ddbc54292477168702e844c2c9641ac5a30968
parent: fbc0b1f63460fd0ff0ff9f5d7c06bf5c5fd48b82
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jun 12 10:31:55 EDT 2022
imx8/usbxhci: bring usb out of reset do all the magic dwc3 specific initalization as well as reset the hub and power on the phys. with this, "usb start" command is not needed anymore from u-boot.
--- a/sys/src/9/imx8/usbxhciimx.c
+++ b/sys/src/9/imx8/usbxhciimx.c
@@ -1785,6 +1785,92 @@
setclkgate(clk, on);
}
+static void
+hubreset(int on)
+{
+ /* gpio registers */
+ enum {
+ GPIO_DR = 0x00/4,
+ GPIO_GDIR = 0x04/4,
+ GPIO_PSR = 0x08/4,
+ GPIO_ICR1 = 0x0C/4,
+ GPIO_ICR2 = 0x10/4,
+ GPIO_IMR = 0x14/4,
+ GPIO_ISR = 0x18/4,
+ GPIO_EDGE_SEL = 0x1C/4,
+ };
+ static u32int *gpio1 = (u32int*)(VIRTIO + 0x200000);
+
+ gpio1[GPIO_GDIR] |= 1<<14; /* output */
+ if(on)
+ gpio1[GPIO_DR] |= 1<<14;
+ else
+ gpio1[GPIO_DR] &= ~(1<<14);
+}
+
+static void
+powerup(int i)
+{
+ /* power gating controller registers */
+ enum {
+ GPC_PGC_CPU_0_1_MAPPING = 0xEC/4,
+ GPC_PGC_PU_PGC_SW_PUP_REQ = 0xF8/4,
+ USB_OTG1_SW_PUP_REQ = 1<<2,
+ };
+ static u32int *gpc = (u32int*)(VIRTIO + 0x3A0000);
+
+ gpc[GPC_PGC_CPU_0_1_MAPPING] = 0x0000FFFF;
+
+ gpc[GPC_PGC_PU_PGC_SW_PUP_REQ] |= (USB_OTG1_SW_PUP_REQ<<i);
+ while(gpc[GPC_PGC_PU_PGC_SW_PUP_REQ] & (USB_OTG1_SW_PUP_REQ<<i))
+ ;
+
+ gpc[GPC_PGC_CPU_0_1_MAPPING] = 0;
+}
+
+static void
+phyinit(u32int *reg)
+{
+ enum {
+ PHY_CTRL0 = 0x0/4,
+ CTRL0_REF_SSP_EN = 1<<2,
+ PHY_CTRL1 = 0x4/4,
+ CTRL1_RESET = 1<<0,
+ CTRL1_ATERESET = 1<<3,
+ CTRL1_VDATSRCENB0 = 1<<19,
+ CTRL1_VDATDETEBB0 = 1<<20,
+ PHY_CTRL2 = 0x8/4,
+ CTRL2_TXENABLEN0 = 1<<8,
+ };
+ reg[PHY_CTRL1] = (reg[PHY_CTRL1] & ~(CTRL1_VDATSRCENB0 | CTRL1_VDATDETEBB0)) | CTRL1_RESET | CTRL1_ATERESET;
+ reg[PHY_CTRL0] |= CTRL0_REF_SSP_EN;
+ reg[PHY_CTRL2] |= CTRL2_TXENABLEN0;
+ reg[PHY_CTRL1] &= ~(CTRL1_RESET | CTRL1_ATERESET);
+}
+
+static void
+coreinit(u32int *reg)
+{
+ enum {
+ GCTL = 0xC110/4,
+ PWRDNSCALE_SHIFT = 19,
+ PWRDNSCALE_MASK = 0x3FFF << PWRDNSCALE_SHIFT,
+ PRTCAPDIR_SHIFT = 12,
+ PRTCAPDIR_MASK = 3 << PRTCAPDIR_SHIFT,
+ DISSCRAMBLE = 1<<3,
+ DSBLCLKGTNG = 1<<0,
+
+ GFLADJ = 0xC630/4,
+ GFLADJ_30MHZ_SDBND_SEL = 1<<7,
+ GFLADJ_30MHZ_SHIFT = 0,
+ GFLADJ_30MHZ_MASK = 0x3F << GFLADJ_30MHZ_SHIFT,
+
+ };
+ reg[GCTL] &= ~(PWRDNSCALE_MASK | DISSCRAMBLE | DSBLCLKGTNG | PRTCAPDIR_MASK);
+ reg[GCTL] |= 2<<PWRDNSCALE_SHIFT | 1<<PRTCAPDIR_SHIFT;
+ reg[GFLADJ] = (reg[GFLADJ] & ~GFLADJ_30MHZ_MASK) | 0x20<<GFLADJ_30MHZ_SHIFT | GFLADJ_30MHZ_SDBND_SEL;
+}
+
static int
reset(Hci *hp)
{
@@ -1808,6 +1894,21 @@
Found:
if(i == 0){
+ static u32int *iomuxc = (u32int*)(VIRTIO + 0x330000);
+ enum {
+ IOMUXC_CTL_PAD_GPIO1_IO13 = 0x5C/4, /* for gpio1 13 */
+ IOMUXC_CTL_PAD_GPIO1_IO14 = 0x60/4, /* for gpio1 14 */
+
+ IOMUXC_SW_PAD_CTRL_PAD_GPIO1_IO14 = 0x2C8/4,
+ };
+ iomuxc[IOMUXC_CTL_PAD_GPIO1_IO13] = 1;
+ iomuxc[IOMUXC_CTL_PAD_GPIO1_IO14] = 0;
+ iomuxc[IOMUXC_SW_PAD_CTRL_PAD_GPIO1_IO14] = 0x16;
+
+ hubreset(0);
+ microdelay(500);
+ hubreset(1);
+
for(i = 0; i < nelem(ctlrs); i++) clkenable(i, 0);
setclkrate("ccm_usb_bus_clk_root", "system_pll2_div2", 500*Mhz);
setclkrate("ccm_usb_core_ref_clk_root", "system_pll1_div8", 100*Mhz);
@@ -1814,7 +1915,10 @@
setclkrate("ccm_usb_phy_ref_clk_root", "system_pll1_div8", 100*Mhz);
i = 0;
}
+ powerup(i);
clkenable(i, 1);
+ phyinit(&ctlr->mmio[0xF0040/4]);
+ coreinit(ctlr->mmio);
hp->init = init;
hp->dump = dump;
--
⑨