1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/driver.h>
6 #include <ddk/platform-defs.h>
7 #include <ddk/protocol/gpio.h>
8 #include <hw/reg.h>
9 #include <soc/hi3660/hi3660.h>
10 #include <soc/hi3660/hi3660-regs.h>
11 #include <zircon/syscalls.h>
12
13 #include <stdio.h>
14
hi3660_usb_init(hi3660_t * hi3660)15 zx_status_t hi3660_usb_init(hi3660_t* hi3660) {
16 volatile void* usb3otg_bc = hi3660->usb3otg_bc.vaddr;
17 volatile void* peri_crg = hi3660->peri_crg.vaddr;
18 volatile void* pctrl = hi3660->pctrl.vaddr;
19 uint32_t temp;
20
21 writel(PERI_CRG_ISODIS_REFCLK_ISO_EN, peri_crg + PERI_CRG_ISODIS);
22 writel(PCTRL_CTRL3_USB_TCXO_EN | (PCTRL_CTRL3_USB_TCXO_EN << PCTRL_CTRL3_MSK_START),
23 pctrl + PCTRL_CTRL3);
24
25 temp = readl(pctrl + PCTRL_CTRL24);
26 temp &= ~PCTRL_CTRL24_SC_CLK_USB3PHY_3MUX1_SEL;
27 writel(temp, pctrl + PCTRL_CTRL24);
28
29 writel(PERI_CRG_GT_CLK_USB3OTG_REF | PERI_CRG_GT_ACLK_USB3OTG, peri_crg + PERI_CRG_CLK_EN4);
30 writel(PERI_CRG_IP_RST_USB3OTG_MUX | PERI_CRG_IP_RST_USB3OTG_AHBIF
31 | PERI_CRG_IP_RST_USB3OTG_32K, peri_crg + PERI_CRG_RSTDIS4);
32
33 writel(PERI_CRG_IP_RST_USB3OTGPHY_POR | PERI_CRG_IP_RST_USB3OTG, peri_crg + PERI_CRG_RSTEN4);
34
35 // enable PHY REF CLK
36 temp = readl(usb3otg_bc + USB3OTG_CTRL0);
37 temp |= USB3OTG_CTRL0_ABB_GT_EN;
38 writel(temp, usb3otg_bc + USB3OTG_CTRL0);
39
40 temp = readl(usb3otg_bc + USB3OTG_CTRL7);
41 temp |= USB3OTG_CTRL7_REF_SSP_EN;
42 writel(temp, usb3otg_bc + USB3OTG_CTRL7);
43
44 // exit from IDDQ mode
45 temp = readl(usb3otg_bc + USB3OTG_CTRL2);
46 temp &= ~(USB3OTG_CTRL2_POWERDOWN_HSP | USB3OTG_CTRL2_POWERDOWN_SSP);
47 writel(temp, usb3otg_bc + USB3OTG_CTRL2);
48 zx_nanosleep(zx_deadline_after(ZX_USEC(100)));
49
50 writel(PERI_CRG_IP_RST_USB3OTGPHY_POR, peri_crg + PERI_CRG_RSTDIS4);
51 writel(PERI_CRG_IP_RST_USB3OTG, peri_crg + PERI_CRG_RSTDIS4);
52 zx_nanosleep(zx_deadline_after(ZX_MSEC(20)));
53
54 temp = readl(usb3otg_bc + USB3OTG_CTRL3);
55 temp |= (USB3OTG_CTRL3_VBUSVLDEXT | USB3OTG_CTRL3_VBUSVLDEXTSEL);
56 writel(temp, usb3otg_bc + USB3OTG_CTRL3);
57 zx_nanosleep(zx_deadline_after(ZX_USEC(100)));
58
59 return ZX_OK;
60 }
61