summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2022-06-12 14:43:50 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2022-06-12 14:43:50 +0000
commite1a95f5630d7f29cf01303b996622a5e6a81db51 (patch)
tree54629765a6f2440589b7c69a29bcc65d9e766153 /sys
parentc3e1346bbcc2f737ff69fdc353125714ec937ddb (diff)
parentf1f5045b2e3c0ce6540abad3cad88f5e69a59a3c (diff)
merge
Diffstat (limited to 'sys')
-rw-r--r--sys/src/9/imx8/usbxhciimx.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/sys/src/9/imx8/usbxhciimx.c b/sys/src/9/imx8/usbxhciimx.c
index 6eebb3dfe..18b6efc00 100644
--- a/sys/src/9/imx8/usbxhciimx.c
+++ b/sys/src/9/imx8/usbxhciimx.c
@@ -1785,6 +1785,92 @@ clkenable(int i, int on)
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,13 +1894,31 @@ reset(Hci *hp)
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);
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;