5 * Texas Instruments, <www.ti.com>
7 * Author: Dan Murphy <dmurphy@ti.com>
9 * SPDX-License-Identifier: GPL-2.0+
14 #include <asm-generic/errno.h>
15 #include <asm/omap_common.h>
16 #include <asm/arch/cpu.h>
17 #include <asm/arch/sys_proto.h>
19 #include <linux/compat.h>
20 #include <linux/usb/dwc3.h>
21 #include <linux/usb/xhci-omap.h>
23 #include "../host/xhci.h"
25 #ifdef CONFIG_OMAP_USB3PHY1_HOST
26 struct usb_dpll_params
{
34 #define NUM_USB_CLKS 6
36 static struct usb_dpll_params omap_usb3_dpll_params
[NUM_USB_CLKS
] = {
37 {1250, 5, 4, 20, 0}, /* 12 MHz */
38 {3125, 20, 4, 20, 0}, /* 16.8 MHz */
39 {1172, 8, 4, 20, 65537}, /* 19.2 MHz */
40 {1250, 12, 4, 20, 0}, /* 26 MHz */
41 {3125, 47, 4, 20, 92843}, /* 38.4 MHz */
42 {1000, 7, 4, 10, 0}, /* 20 MHz */
45 static void omap_usb_dpll_relock(struct omap_usb3_phy
*phy_regs
)
49 writel(SET_PLL_GO
, &phy_regs
->pll_go
);
51 val
= readl(&phy_regs
->pll_status
);
57 static void omap_usb_dpll_lock(struct omap_usb3_phy
*phy_regs
)
59 u32 clk_index
= get_sys_clk_index();
62 val
= readl(&phy_regs
->pll_config_1
);
63 val
&= ~PLL_REGN_MASK
;
64 val
|= omap_usb3_dpll_params
[clk_index
].n
<< PLL_REGN_SHIFT
;
65 writel(val
, &phy_regs
->pll_config_1
);
67 val
= readl(&phy_regs
->pll_config_2
);
68 val
&= ~PLL_SELFREQDCO_MASK
;
69 val
|= omap_usb3_dpll_params
[clk_index
].freq
<< PLL_SELFREQDCO_SHIFT
;
70 writel(val
, &phy_regs
->pll_config_2
);
72 val
= readl(&phy_regs
->pll_config_1
);
73 val
&= ~PLL_REGM_MASK
;
74 val
|= omap_usb3_dpll_params
[clk_index
].m
<< PLL_REGM_SHIFT
;
75 writel(val
, &phy_regs
->pll_config_1
);
77 val
= readl(&phy_regs
->pll_config_4
);
78 val
&= ~PLL_REGM_F_MASK
;
79 val
|= omap_usb3_dpll_params
[clk_index
].mf
<< PLL_REGM_F_SHIFT
;
80 writel(val
, &phy_regs
->pll_config_4
);
82 val
= readl(&phy_regs
->pll_config_3
);
84 val
|= omap_usb3_dpll_params
[clk_index
].sd
<< PLL_SD_SHIFT
;
85 writel(val
, &phy_regs
->pll_config_3
);
87 omap_usb_dpll_relock(phy_regs
);
90 static void usb3_phy_partial_powerup(struct omap_usb3_phy
*phy_regs
)
92 u32 rate
= get_sys_clk_freq()/1000000;
95 val
= readl((*ctrl
)->control_phy_power_usb
);
96 val
&= ~(USB3_PWRCTL_CLK_CMD_MASK
| USB3_PWRCTL_CLK_FREQ_MASK
);
97 val
|= (USB3_PHY_PARTIAL_RX_POWERON
| USB3_PHY_TX_RX_POWERON
);
98 val
|= rate
<< USB3_PWRCTL_CLK_FREQ_SHIFT
;
100 writel(val
, (*ctrl
)->control_phy_power_usb
);
103 void usb_phy_power(int on
)
107 val
= readl((*ctrl
)->control_phy_power_usb
);
109 val
&= ~USB3_PWRCTL_CLK_CMD_MASK
;
110 val
|= USB3_PHY_TX_RX_POWERON
;
112 val
&= (~USB3_PWRCTL_CLK_CMD_MASK
& ~USB3_PHY_TX_RX_POWERON
);
115 writel(val
, (*ctrl
)->control_phy_power_usb
);
118 void omap_usb3_phy_init(struct omap_usb3_phy
*phy_regs
)
120 omap_usb_dpll_lock(phy_regs
);
122 usb3_phy_partial_powerup(phy_regs
);
124 * Give enough time for the PHY to partially power-up before
125 * powering it up completely. delay value suggested by the HW
132 static void omap_enable_usb3_phy(struct omap_xhci
*omap
)
136 /* Setting OCP2SCP1 register */
137 setbits_le32((*prcm
)->cm_l3init_ocp2scp1_clkctrl
,
138 OCP2SCP1_CLKCTRL_MODULEMODE_HW
);
140 /* Turn on 32K AON clk */
141 setbits_le32((*prcm
)->cm_coreaon_usb_phy_core_clkctrl
,
142 USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K
);
144 /* Setting CM_L3INIT_CLKSTCTRL to 0x0 i.e NO sleep */
145 writel(0x0, (*prcm
)->cm_l3init_clkstctrl
);
147 val
= (USBOTGSS_DMADISABLE
|
148 USBOTGSS_STANDBYMODE_SMRT_WKUP
|
149 USBOTGSS_IDLEMODE_NOIDLE
);
150 writel(val
, &omap
->otg_wrapper
->sysconfig
);
152 /* Clear the utmi OTG status */
153 val
= readl(&omap
->otg_wrapper
->utmi_otg_status
);
154 writel(val
, &omap
->otg_wrapper
->utmi_otg_status
);
156 /* Enable interrupts */
157 writel(USBOTGSS_COREIRQ_EN
, &omap
->otg_wrapper
->irqenable_set_0
);
158 val
= (USBOTGSS_IRQ_SET_1_IDPULLUP_FALL_EN
|
159 USBOTGSS_IRQ_SET_1_DISCHRGVBUS_FALL_EN
|
160 USBOTGSS_IRQ_SET_1_CHRGVBUS_FALL_EN
|
161 USBOTGSS_IRQ_SET_1_DRVVBUS_FALL_EN
|
162 USBOTGSS_IRQ_SET_1_IDPULLUP_RISE_EN
|
163 USBOTGSS_IRQ_SET_1_DISCHRGVBUS_RISE_EN
|
164 USBOTGSS_IRQ_SET_1_CHRGVBUS_RISE_EN
|
165 USBOTGSS_IRQ_SET_1_DRVVBUS_RISE_EN
|
166 USBOTGSS_IRQ_SET_1_OEVT_EN
);
167 writel(val
, &omap
->otg_wrapper
->irqenable_set_1
);
169 /* Clear the IRQ status */
170 val
= readl(&omap
->otg_wrapper
->irqstatus_1
);
171 writel(val
, &omap
->otg_wrapper
->irqstatus_1
);
172 val
= readl(&omap
->otg_wrapper
->irqstatus_0
);
173 writel(val
, &omap
->otg_wrapper
->irqstatus_0
);
175 /* Enable the USB OTG Super speed clocks */
176 val
= (OPTFCLKEN_REFCLK960M
| OTG_SS_CLKCTRL_MODULEMODE_HW
);
177 setbits_le32((*prcm
)->cm_l3init_usb_otg_ss_clkctrl
, val
);
180 #endif /* CONFIG_OMAP_USB3PHY1_HOST */
182 #ifdef CONFIG_OMAP_USB2PHY2_HOST
183 static void omap_enable_usb2_phy2(struct omap_xhci
*omap
)
187 val
= (~USB2PHY_AUTORESUME_EN
& USB2PHY_DISCHGDET
);
188 writel(val
, (*ctrl
)->control_srcomp_north_side
);
190 setbits_le32((*prcm
)->cm_coreaon_usb_phy2_core_clkctrl
,
191 USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K
);
193 setbits_le32((*prcm
)->cm_l3init_hsusbhost_clkctrl
,
194 (USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K
|
195 OTG_SS_CLKCTRL_MODULEMODE_HW
));
197 /* This is an undocumented Reserved register */
201 setbits_le32(reg
, val
);
204 void usb_phy_power(int on
)
208 #endif /* CONFIG_OMAP_USB2PHY2_HOST */
210 #ifdef CONFIG_AM437X_USB2PHY2_HOST
211 static void am437x_enable_usb2_phy2(struct omap_xhci
*omap
)
213 const u32 usb_otg_ss_clk_val
= (USBOTGSSX_CLKCTRL_MODULE_EN
|
214 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960
);
216 writel(usb_otg_ss_clk_val
, PRM_PER_USB_OTG_SS0_CLKCTRL
);
217 writel(usb_otg_ss_clk_val
, PRM_PER_USB_OTG_SS1_CLKCTRL
);
219 writel(USBPHYOCPSCP_MODULE_EN
, PRM_PER_USBPHYOCP2SCP0_CLKCTRL
);
220 writel(USBPHYOCPSCP_MODULE_EN
, PRM_PER_USBPHYOCP2SCP1_CLKCTRL
);
223 void usb_phy_power(int on
)
227 #endif /* CONFIG_AM437X_USB2PHY2_HOST */
229 void omap_reset_usb_phy(struct dwc3
*dwc3_reg
)
231 /* Assert USB3 PHY reset */
232 setbits_le32(&dwc3_reg
->g_usb3pipectl
[0], DWC3_GUSB3PIPECTL_PHYSOFTRST
);
234 /* Assert USB2 PHY reset */
235 setbits_le32(&dwc3_reg
->g_usb2phycfg
, DWC3_GUSB2PHYCFG_PHYSOFTRST
);
239 /* Clear USB3 PHY reset */
240 clrbits_le32(&dwc3_reg
->g_usb3pipectl
[0], DWC3_GUSB3PIPECTL_PHYSOFTRST
);
242 /* Clear USB2 PHY reset */
243 clrbits_le32(&dwc3_reg
->g_usb2phycfg
, DWC3_GUSB2PHYCFG_PHYSOFTRST
);
247 void omap_enable_phy(struct omap_xhci
*omap
)
249 #ifdef CONFIG_OMAP_USB2PHY2_HOST
250 omap_enable_usb2_phy2(omap
);
253 #ifdef CONFIG_AM437X_USB2PHY2_HOST
254 am437x_enable_usb2_phy2(omap
);
257 #ifdef CONFIG_OMAP_USB3PHY1_HOST
258 omap_enable_usb3_phy(omap
);
259 omap_usb3_phy_init(omap
->usb3_phy
);