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