blob: 14aa4252b271fb690fa3d97a9ae73b1468f0baff [file] [log] [blame]
Jeevan Shriramf27525d2017-01-10 15:53:12 -08001/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
Joonwoo Park8ef69192014-06-09 16:54:15 -07002
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
Channagoud Kadabi4517eb12015-09-02 18:43:13 -070028#include <arch/defines.h>
Joonwoo Park8ef69192014-06-09 16:54:15 -070029#include <platform/iomap.h>
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -070030#include <qusb2_phy.h>
Joonwoo Park8ef69192014-06-09 16:54:15 -070031#include <reg.h>
32#include <bits.h>
33#include <debug.h>
Veera Sundaram Sankaran00181512014-12-09 11:23:39 -080034#include <qtimer.h>
Channagoud Kadabi0a98d002015-10-07 11:57:53 -070035#include <platform.h>
Joonwoo Park8ef69192014-06-09 16:54:15 -070036
Channagoud Kadabi12b96932014-09-23 15:18:11 -070037__WEAK int platform_is_msm8994()
38{
39 return 0;
40}
41
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -070042__WEAK int platform_is_msm8996()
43{
44 return 0;
45}
46
Parth Dixitadf539f2016-09-16 23:26:16 +053047__WEAK int platform_is_msm8996sg()
48{
49 return 0;
50}
51
Karthik Jadala8e6b2192017-02-08 12:59:16 +053052__WEAK int platform_is_mdm9650()
Channagoud Kadabi0a98d002015-10-07 11:57:53 -070053{
54 return 0;
55}
56
Gaurav Nebhwanie0e4ed92016-03-21 12:52:28 +053057__WEAK int platform_is_msm8953()
58{
59 return 0;
60}
61
Runmin Wangdc8e9732016-10-06 11:14:08 -070062__WEAK int platform_is_sdxhedgehog()
63{
64 return 0;
65}
66
Joonwoo Park8ef69192014-06-09 16:54:15 -070067void qusb2_phy_reset(void)
68{
69 uint32_t val;
Channagoud Kadabid1e2cc22015-08-13 12:48:37 -070070 /* Default tune value */
71 uint8_t tune2 = 0xB3;
Channagoud Kadabi0a98d002015-10-07 11:57:53 -070072 int retry = 100;
73 int se_clock = 1;
Runmin Wangdc8e9732016-10-06 11:14:08 -070074 int status_reg = 0;
Joonwoo Park8ef69192014-06-09 16:54:15 -070075
Channagoud Kadabid33824f2015-09-24 15:17:53 -070076 /* Disable the ref clock before phy reset */
77#if GCC_RX2_USB2_CLKREF_EN
78 writel((readl(GCC_RX2_USB2_CLKREF_EN) & ~0x1), GCC_RX2_USB2_CLKREF_EN);
79 dmb();
80#endif
Joonwoo Park8ef69192014-06-09 16:54:15 -070081 /* Block Reset */
82 val = readl(GCC_QUSB2_PHY_BCR) | BIT(0);
83 writel(val, GCC_QUSB2_PHY_BCR);
84 udelay(10);
85 writel(val & ~BIT(0), GCC_QUSB2_PHY_BCR);
86
Channagoud Kadabi4517eb12015-09-02 18:43:13 -070087 /* configure the abh2 phy to wait state */
88 writel(0x11, PERIPH_SS_AHB2PHY_TOP_CFG);
89 dmb();
90
Tanya Finkele7aa4272014-08-08 23:41:34 +030091 /* set CLAMP_N_EN and stay with disabled USB PHY */
Jeevan Shriramf27525d2017-01-10 15:53:12 -080092 if(platform_is_sdxhedgehog())
93 writel(0x23, QUSB2PHY_PWR_CTRL1_SDXHEDGEHOG);
94 else
95 writel(0x23, QUSB2PHY_PORT_POWERDOWN);
Tanya Finkele7aa4272014-08-08 23:41:34 +030096
Jeevan Shriramf27525d2017-01-10 15:53:12 -080097 /* TCSR register bit 0 indicates whether single ended clock
98 * or differential clock configuration is enabled. Based on the
99 * configuration set the PLL_TEST register.
100 */
101#if TCSR_PHY_CLK_SCHEME_SEL
102 se_clock = readl(TCSR_PHY_CLK_SCHEME_SEL) & 0x1;
103#endif
Karthik Jadala8e6b2192017-02-08 12:59:16 +0530104 if (platform_is_msm8996() || platform_is_mdm9650() || platform_is_msm8953())
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700105 {
Parth Dixitadf539f2016-09-16 23:26:16 +0530106 if(platform_is_msm8996sg())
107 writel(0xD0, QUSB2PHY_PORT_TUNE1);
108 else
109 writel(0xF8, QUSB2PHY_PORT_TUNE1);
110
Channagoud Kadabid1e2cc22015-08-13 12:48:37 -0700111 /* Upper nibble of tune2 register should be updated based on the fuse value.
112 * Read the bits 21..24 from fuse and update the upper nibble with this value
113 */
114#if QFPROM_CORR_CALIB_ROW12_MSB
115 uint8_t fuse_val = (readl(QFPROM_CORR_CALIB_ROW12_MSB) & 0x1E00000) >> 21;
116 /* If fuse value is non zero then update the upper nibble with the fuse value
117 * otherwise use the default value
118 */
119 if (fuse_val)
120 tune2 = (tune2 & 0x0f) | (fuse_val << 4);
121#endif
122 writel(tune2, QUSB2PHY_PORT_TUNE2);
Channagoud Kadabif0d9ef02015-09-24 14:52:02 -0700123 writel(0x83, QUSB2PHY_PORT_TUNE3);
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700124 writel(0xC0, QUSB2PHY_PORT_TUNE4);
Parth Dixitadf539f2016-09-16 23:26:16 +0530125 if(platform_is_msm8996sg())
126 writel(0x02, QUSB2PHY_PORT_TUNE5);
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700127 writel(0x30, QUSB2PHY_PLL_TUNE);
128 writel(0x79, QUSB2PHY_PLL_USER_CTL1);
129 writel(0x21, QUSB2PHY_PLL_USER_CTL2);
130 writel(0x14, QUSB2PHY_PORT_TEST2);
Channagoud Kadabif0d9ef02015-09-24 14:52:02 -0700131 writel(0x9F, QUSB2PHY_PLL_AUTOPGM_CTL1);
132 writel(0x00, QUSB2PHY_PLL_PWR_CTL);
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700133 }
Runmin Wangdc8e9732016-10-06 11:14:08 -0700134 else if (platform_is_sdxhedgehog())
135 {
Jeevan Shriramf27525d2017-01-10 15:53:12 -0800136 /* HPG init sequence 0x13 for CML and 0x03 for CMOS */
137 if (se_clock)
138 writel(0x03, QUSB2PHY_PLL_ANALOG_CONTROLS_TWO_SDXHEDGEHOG);
139 else
140 writel(0x13, QUSB2PHY_PLL_ANALOG_CONTROLS_TWO_SDXHEDGEHOG);
141
Runmin Wangdc8e9732016-10-06 11:14:08 -0700142 writel(0x7C, QUSB2PHY_PLL_CLOCK_INVERTERS_SDXHEDGEHOG);
143 writel(0x80, QUSB2PHY_PLL_CMODE_SDXHEDGEHOG);
144 writel(0x0a, QUSB2PHY_PLL_LOCK_DELAY_SDXHEDGEHOG);
Jeevan Shriramf27525d2017-01-10 15:53:12 -0800145 writel(0x19, QUSB2PHY_PLL_DIGITAL_TIMERS_TWO_SDXHEDGEHOG);
Runmin Wangdc8e9732016-10-06 11:14:08 -0700146 writel(0xa5, QUSB2PHY_TUNE1_SDXHEDGEHOG);
147 writel(0x09, QUSB2PHY_TUNE2_SDXHEDGEHOG);
148 writel(0x00, QUSB2PHY_IMP_CTRL1_SDXHEDGEHOG);
149 writel(0x22, QUSB2PHY_PWR_CTRL1_SDXHEDGEHOG);
150 }
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700151 else
152 {
153 /* Set HS impedance to 42ohms */
154 writel(0xA0, QUSB2PHY_PORT_TUNE1);
Tanya Finkele7aa4272014-08-08 23:41:34 +0300155
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700156 /* Set TX current to 19mA, TX SR and TX bias current to 1, 1 */
157 writel(0xA5, QUSB2PHY_PORT_TUNE2);
Tanya Finkele7aa4272014-08-08 23:41:34 +0300158
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700159 /* Increase autocalibration bias circuit settling time
160 * and enable utocalibration */
161 writel(0x81, QUSB2PHY_PORT_TUNE3);
Tanya Finkele7aa4272014-08-08 23:41:34 +0300162
Channagoud Kadabi7164ddf2015-04-09 16:27:36 -0700163 writel(0x85, QUSB2PHY_PORT_TUNE4);
164 }
165
Tanya Finkele7aa4272014-08-08 23:41:34 +0300166 /* Enable ULPI mode */
Channagoud Kadabi12b96932014-09-23 15:18:11 -0700167 if (platform_is_msm8994())
168 writel(0x0, QUSB2PHY_PORT_UTMI_CTRL2);
Channagoud Kadabid33824f2015-09-24 15:17:53 -0700169
Runmin Wangdc8e9732016-10-06 11:14:08 -0700170 /* set CLAMP_N_EN and USB PHY is enabled*/
171 if (platform_is_sdxhedgehog()){
172 writel(0x22, QUSB2PHY_PWR_CTRL1_SDXHEDGEHOG);
173 writel(0x04, QUSB2PHY_DEBUG_CTRL2_SDXHEDGEHOG);
174 udelay(88);
175 }
176 else{
177 writel(0x22, QUSB2PHY_PORT_POWERDOWN);
178 udelay(150);
179 }
Jeevan Shriramf27525d2017-01-10 15:53:12 -0800180
Channagoud Kadabie80224a2015-10-15 21:55:07 -0700181 /* By default consider differential clock configuration and if TCSR
182 * register bit 0 is not set then use single ended setting
183 */
184 if (se_clock)
185 {
Jeevan Shriramf27525d2017-01-10 15:53:12 -0800186 /* PLL TEST is not valid for sdxhedgehog */
187 if(!platform_is_sdxhedgehog())
188 writel(0x80, QUSB2PHY_PLL_TEST);
Channagoud Kadabie80224a2015-10-15 21:55:07 -0700189 }
190 else
191 {
192 /* turn the ref clock on for differential clocks */
193#if GCC_RX2_USB2_CLKREF_EN
194 writel((readl(GCC_RX2_USB2_CLKREF_EN) | 0x1), GCC_RX2_USB2_CLKREF_EN);
195 dmb();
196#endif
197 }
198 udelay(100);
Channagoud Kadabi0a98d002015-10-07 11:57:53 -0700199
200 /* Check PLL status */
Runmin Wangdc8e9732016-10-06 11:14:08 -0700201 if (platform_is_sdxhedgehog()){
202 status_reg = QUSB2PHY_DEBUG_STAT5_SDXHEDGEHOG;
203 }
204 else{
205 status_reg = QUSB2PHY_PLL_STATUS;
206 }
207
208 while (!(readl(status_reg) & QUSB2PHY_PLL_LOCK))
Channagoud Kadabi0a98d002015-10-07 11:57:53 -0700209 {
210 retry--;
Channagoud Kadabi0a98d002015-10-07 11:57:53 -0700211 if (!retry)
212 {
213 dprintf(CRITICAL, "QUSB2PHY failed to lock: %d", readl(QUSB2PHY_PLL_STATUS));
214 break;
215 }
Channagoud Kadabie80224a2015-10-15 21:55:07 -0700216 /* As per recommendation form hw team wait for 5 us before reading the status */
217 udelay(5);
Channagoud Kadabi0a98d002015-10-07 11:57:53 -0700218 }
Joonwoo Park8ef69192014-06-09 16:54:15 -0700219}