ref: e1a95f5630d7f29cf01303b996622a5e6a81db51
parent: c3e1346bbcc2f737ff69fdc353125714ec937ddb
parent: f1f5045b2e3c0ce6540abad3cad88f5e69a59a3c
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jun 12 10:43:50 EDT 2022
merge
--- 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;