blob: 40a536af485ce3790be63f15c0c8f670c8806cbe [file] [log] [blame]
Channagoud Kadabiaab99d42014-02-04 15:45:56 -08001/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
2
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 */
28
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070029#include <sys/types.h>
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080030#include <stdint.h>
31#include <platform/clock.h>
32#include <platform/iomap.h>
33#include <qmp_phy.h>
34#include <reg.h>
35#include <bits.h>
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070036#include <clock.h>
37#include <debug.h>
Veera Sundaram Sankaran00181512014-12-09 11:23:39 -080038#include <qtimer.h>
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070039
40#define HS_PHY_COMMON_CTRL 0xEC
41#define USE_CORECLK BIT(14)
42#define PLLBTUNE BIT(15)
43#define FSEL (0x7 << 4)
44#define DIS_RETENTION BIT(18)
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070045#define QMP_PHY_MAX_TIMEOUT 1000
46#define PHYSTATUS BIT(6)
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080047
Channagoud Kadabi0b13ba52014-05-12 18:08:33 -070048__WEAK uint32_t target_override_pll()
49{
50 return 0;
51}
52
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080053/* USB3.0 QMP phy reset */
54void usb30_qmp_phy_reset(void)
55{
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070056 int ret = 0;
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080057 uint32_t val;
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070058 bool phy_com_reset = false;
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080059
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070060 struct clk *usb2b_clk = NULL;
61 struct clk *usb_pipe_clk = NULL;
62 struct clk *phy_com_clk = NULL;
63 struct clk *phy_clk = NULL;
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080064
Channagoud Kadabi6dba1c52014-06-27 15:35:09 -070065#if USB_RESET_FROM_CLK
66 clock_reset_usb_phy();
67#else
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070068 /* Look if phy com clock is present */
69 phy_com_clk = clk_get("usb30_phy_com_reset");
70 if (phy_com_clk)
71 phy_com_reset = true;
72
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070073 usb2b_clk = clk_get("usb2b_phy_sleep_clk");
74 ASSERT(usb2b_clk);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080075
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070076 phy_clk = clk_get("usb30_phy_reset");
77 ASSERT(phy_clk);
78
79 usb_pipe_clk = clk_get("usb30_pipe_clk");
80 ASSERT(usb_pipe_clk);
81
82 /* ASSERT */
83 ret = clk_reset(usb2b_clk, CLK_RESET_ASSERT);
84 if (ret)
85 {
86 dprintf(CRITICAL, "Failed to assert usb2b_phy_clk\n");
87 return;
88 }
89
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070090 if (phy_com_reset)
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070091 {
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070092 ret = clk_reset(phy_com_clk, CLK_RESET_ASSERT);
93 if (ret)
94 {
95 dprintf(CRITICAL, "Failed to assert phy_com_clk\n");
96 goto deassert_usb2b_clk;
97 }
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070098 }
99
100 ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
101 if (ret)
102 {
103 dprintf(CRITICAL, "Failed to assert phy_clk\n");
104 goto deassert_phy_com_clk;
105 }
106
107 ret = clk_reset(usb_pipe_clk, CLK_RESET_ASSERT);
108 if (ret)
109 {
110 dprintf(CRITICAL, "Failed to assert usb_pipe_clk\n");
111 goto deassert_phy_clk;
112 }
113
114 udelay(100);
115
116 /* DEASSERT */
117 ret = clk_reset(usb_pipe_clk, CLK_RESET_DEASSERT);
118 if (ret)
119 dprintf(CRITICAL, "Failed to deassert usb_pipe_clk\n");
120
121deassert_phy_clk:
122 ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
123 if (ret)
124 dprintf(CRITICAL, "Failed to deassert phy_clk\n");
125
126deassert_phy_com_clk:
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -0700127 if (phy_com_reset)
128 {
129 ret = clk_reset(phy_com_clk, CLK_RESET_DEASSERT);
130 if (ret)
131 dprintf(CRITICAL, "Failed to deassert phy_com_clk\n");
132 }
Channagoud Kadabia39da8b2014-04-03 15:34:43 -0700133
134deassert_usb2b_clk:
135 ret = clk_reset(usb2b_clk, CLK_RESET_DEASSERT);
136 if (ret)
137 dprintf(CRITICAL, "Failed to deassert usb2b_phy_clk\n");
Channagoud Kadabi6dba1c52014-06-27 15:35:09 -0700138#endif
Channagoud Kadabia39da8b2014-04-03 15:34:43 -0700139
140 /* Override the phy common control values */
141 val = readl(MSM_USB30_QSCRATCH_BASE + HS_PHY_COMMON_CTRL);
142 val |= USE_CORECLK | PLLBTUNE;
143 val &= ~FSEL;
144 val &= ~DIS_RETENTION;
145 writel(val, MSM_USB30_QSCRATCH_BASE + HS_PHY_COMMON_CTRL);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800146}
147
148/* USB 3.0 phy init: HPG for QMP phy*/
149void usb30_qmp_phy_init()
150{
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -0700151 int timeout = QMP_PHY_MAX_TIMEOUT;
152
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800153 /* Sequence as per HPG */
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800154
155 writel(0x01, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_DOWN_CONTROL);
156 writel(0x08, QMP_PHY_BASE + QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
Channagoud Kadabi0b13ba52014-05-12 18:08:33 -0700157
158 if (target_override_pll())
159 writel(0xE1, QMP_PHY_BASE + QSERDES_COM_PLL_VCOTAIL_EN);
160
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800161 writel(0x82, QMP_PHY_BASE + QSERDES_COM_DEC_START1);
162 writel(0x03, QMP_PHY_BASE + QSERDES_COM_DEC_START2);
163 writel(0xD5, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START1);
164 writel(0xAA, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START2);
165 writel(0x4D, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START3);
166 writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP_EN);
167 writel(0x2B, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP1);
168 writel(0x68, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP2);
169 writel(0x7C, QMP_PHY_BASE + QSERDES_COM_PLL_CRCTRL);
170 writel(0x02, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETI);
171 writel(0x1F, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETP);
172 writel(0x0F, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETP);
173 writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETI);
174 writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IE_TRIM);
175 writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IP_TRIM);
176 writel(0x46, QMP_PHY_BASE + QSERDES_COM_PLL_CNTRL);
177
178 /* CDR Settings */
179 writel(0xDA, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL1);
180 writel(0x42, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL2);
181
182 /* Calibration Settings */
183 writel(0x90, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL);
Channagoud Kadabi0b13ba52014-05-12 18:08:33 -0700184 if (target_override_pll())
185 writel(0x07, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
186 else
187 writel(0x05, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800188
189 writel(0x20, QMP_PHY_BASE + QSERDES_COM_RES_CODE_START_SEG1);
190 writel(0x77, QMP_PHY_BASE + QSERDES_COM_RES_CODE_CAL_CSR);
191 writel(0x15, QMP_PHY_BASE + QSERDES_COM_RES_TRIM_CONTROL);
192 writel(0x03, QMP_PHY_BASE + QSERDES_TX_RCV_DETECT_LVL);
193 writel(0x02, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2);
194 writel(0x6C, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3);
195 writel(0xC7, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4);
196 writel(0x40, QMP_PHY_BASE + QSERDES_RX_SIGDET_ENABLES);
Channagoud Kadabia39da8b2014-04-03 15:34:43 -0700197 writel(0x73, QMP_PHY_BASE + QSERDES_RX_SIGDET_CNTRL);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800198 writel(0x06, QMP_PHY_BASE + QSERDES_RX_SIGDET_DEGLITCH_CNTRL);
199 writel(0x48, QMP_PHY_BASE + PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL);
200 writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_EN_CENTER);
201 writel(0x02, QMP_PHY_BASE + QSERDES_COM_SSC_ADJ_PER1);
202 writel(0x31, QMP_PHY_BASE + QSERDES_COM_SSC_PER1);
203 writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_PER2);
204 writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE1);
205 writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE2);
206 writel(0x08, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_STATE_CONFIG2);
207
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800208 writel(0x00, QMP_PHY_BASE + PCIE_USB3_PHY_SW_RESET);
209 writel(0x03, QMP_PHY_BASE + PCIE_USB3_PHY_START);
210
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800211 clock_bumpup_pipe3_clk();
Channagoud Kadabi7bc9edb2014-06-01 19:01:12 -0700212
213 while ((readl(QMP_PHY_BASE + PCIE_USB3_PHY_PCS_STATUS) & PHYSTATUS))
214 {
215 udelay(1);
216 timeout--;
217 if (!timeout)
218 {
219 dprintf(CRITICAL, "QMP phy initialization failed\n");
220 return;
221 }
222 }
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800223}