blob: 5e4ceab664d3dc1e57bdf92dd500f3e3ccda25a9 [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>
38
39#define HS_PHY_COMMON_CTRL 0xEC
40#define USE_CORECLK BIT(14)
41#define PLLBTUNE BIT(15)
42#define FSEL (0x7 << 4)
43#define DIS_RETENTION BIT(18)
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070044#define QMP_PHY_MAX_TIMEOUT 1000
45#define PHYSTATUS BIT(6)
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080046
Channagoud Kadabi0b13ba52014-05-12 18:08:33 -070047__WEAK uint32_t target_override_pll()
48{
49 return 0;
50}
51
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080052/* USB3.0 QMP phy reset */
53void usb30_qmp_phy_reset(void)
54{
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070055 int ret = 0;
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080056 uint32_t val;
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070057 bool phy_com_reset = false;
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080058
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070059 struct clk *usb2b_clk = NULL;
60 struct clk *usb_pipe_clk = NULL;
61 struct clk *phy_com_clk = NULL;
62 struct clk *phy_clk = NULL;
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080063
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070064 /* Look if phy com clock is present */
65 phy_com_clk = clk_get("usb30_phy_com_reset");
66 if (phy_com_clk)
67 phy_com_reset = true;
68
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070069 usb2b_clk = clk_get("usb2b_phy_sleep_clk");
70 ASSERT(usb2b_clk);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -080071
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070072 phy_clk = clk_get("usb30_phy_reset");
73 ASSERT(phy_clk);
74
75 usb_pipe_clk = clk_get("usb30_pipe_clk");
76 ASSERT(usb_pipe_clk);
77
78 /* ASSERT */
79 ret = clk_reset(usb2b_clk, CLK_RESET_ASSERT);
80 if (ret)
81 {
82 dprintf(CRITICAL, "Failed to assert usb2b_phy_clk\n");
83 return;
84 }
85
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070086 if (phy_com_reset)
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070087 {
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -070088 ret = clk_reset(phy_com_clk, CLK_RESET_ASSERT);
89 if (ret)
90 {
91 dprintf(CRITICAL, "Failed to assert phy_com_clk\n");
92 goto deassert_usb2b_clk;
93 }
Channagoud Kadabia39da8b2014-04-03 15:34:43 -070094 }
95
96 ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
97 if (ret)
98 {
99 dprintf(CRITICAL, "Failed to assert phy_clk\n");
100 goto deassert_phy_com_clk;
101 }
102
103 ret = clk_reset(usb_pipe_clk, CLK_RESET_ASSERT);
104 if (ret)
105 {
106 dprintf(CRITICAL, "Failed to assert usb_pipe_clk\n");
107 goto deassert_phy_clk;
108 }
109
110 udelay(100);
111
112 /* DEASSERT */
113 ret = clk_reset(usb_pipe_clk, CLK_RESET_DEASSERT);
114 if (ret)
115 dprintf(CRITICAL, "Failed to deassert usb_pipe_clk\n");
116
117deassert_phy_clk:
118 ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
119 if (ret)
120 dprintf(CRITICAL, "Failed to deassert phy_clk\n");
121
122deassert_phy_com_clk:
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -0700123 if (phy_com_reset)
124 {
125 ret = clk_reset(phy_com_clk, CLK_RESET_DEASSERT);
126 if (ret)
127 dprintf(CRITICAL, "Failed to deassert phy_com_clk\n");
128 }
Channagoud Kadabia39da8b2014-04-03 15:34:43 -0700129
130deassert_usb2b_clk:
131 ret = clk_reset(usb2b_clk, CLK_RESET_DEASSERT);
132 if (ret)
133 dprintf(CRITICAL, "Failed to deassert usb2b_phy_clk\n");
134
135 /* Override the phy common control values */
136 val = readl(MSM_USB30_QSCRATCH_BASE + HS_PHY_COMMON_CTRL);
137 val |= USE_CORECLK | PLLBTUNE;
138 val &= ~FSEL;
139 val &= ~DIS_RETENTION;
140 writel(val, MSM_USB30_QSCRATCH_BASE + HS_PHY_COMMON_CTRL);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800141}
142
143/* USB 3.0 phy init: HPG for QMP phy*/
144void usb30_qmp_phy_init()
145{
Channagoud Kadabib3d7f1f2014-04-22 15:02:51 -0700146 int timeout = QMP_PHY_MAX_TIMEOUT;
147
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800148 /* Sequence as per HPG */
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800149
150 writel(0x01, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_DOWN_CONTROL);
151 writel(0x08, QMP_PHY_BASE + QSERDES_COM_SYSCLK_EN_SEL_TXBAND);
Channagoud Kadabi0b13ba52014-05-12 18:08:33 -0700152
153 if (target_override_pll())
154 writel(0xE1, QMP_PHY_BASE + QSERDES_COM_PLL_VCOTAIL_EN);
155
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800156 writel(0x82, QMP_PHY_BASE + QSERDES_COM_DEC_START1);
157 writel(0x03, QMP_PHY_BASE + QSERDES_COM_DEC_START2);
158 writel(0xD5, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START1);
159 writel(0xAA, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START2);
160 writel(0x4D, QMP_PHY_BASE + QSERDES_COM_DIV_FRAC_START3);
161 writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP_EN);
162 writel(0x2B, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP1);
163 writel(0x68, QMP_PHY_BASE + QSERDES_COM_PLLLOCK_CMP2);
164 writel(0x7C, QMP_PHY_BASE + QSERDES_COM_PLL_CRCTRL);
165 writel(0x02, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETI);
166 writel(0x1F, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETP);
167 writel(0x0F, QMP_PHY_BASE + QSERDES_COM_PLL_CP_SETP);
168 writel(0x01, QMP_PHY_BASE + QSERDES_COM_PLL_IP_SETI);
169 writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IE_TRIM);
170 writel(0x0F, QMP_PHY_BASE + QSERDES_COM_IP_TRIM);
171 writel(0x46, QMP_PHY_BASE + QSERDES_COM_PLL_CNTRL);
172
173 /* CDR Settings */
174 writel(0xDA, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL1);
175 writel(0x42, QMP_PHY_BASE + QSERDES_RX_CDR_CONTROL2);
176
177 /* Calibration Settings */
178 writel(0x90, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL);
Channagoud Kadabi0b13ba52014-05-12 18:08:33 -0700179 if (target_override_pll())
180 writel(0x07, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
181 else
182 writel(0x05, QMP_PHY_BASE + QSERDES_COM_RESETSM_CNTRL2);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800183
184 writel(0x20, QMP_PHY_BASE + QSERDES_COM_RES_CODE_START_SEG1);
185 writel(0x77, QMP_PHY_BASE + QSERDES_COM_RES_CODE_CAL_CSR);
186 writel(0x15, QMP_PHY_BASE + QSERDES_COM_RES_TRIM_CONTROL);
187 writel(0x03, QMP_PHY_BASE + QSERDES_TX_RCV_DETECT_LVL);
188 writel(0x02, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2);
189 writel(0x6C, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3);
190 writel(0xC7, QMP_PHY_BASE + QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4);
191 writel(0x40, QMP_PHY_BASE + QSERDES_RX_SIGDET_ENABLES);
Channagoud Kadabia39da8b2014-04-03 15:34:43 -0700192 writel(0x73, QMP_PHY_BASE + QSERDES_RX_SIGDET_CNTRL);
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800193 writel(0x06, QMP_PHY_BASE + QSERDES_RX_SIGDET_DEGLITCH_CNTRL);
194 writel(0x48, QMP_PHY_BASE + PCIE_USB3_PHY_RX_IDLE_DTCT_CNTRL);
195 writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_EN_CENTER);
196 writel(0x02, QMP_PHY_BASE + QSERDES_COM_SSC_ADJ_PER1);
197 writel(0x31, QMP_PHY_BASE + QSERDES_COM_SSC_PER1);
198 writel(0x01, QMP_PHY_BASE + QSERDES_COM_SSC_PER2);
199 writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE1);
200 writel(0x19, QMP_PHY_BASE + QSERDES_COM_SSC_STEP_SIZE2);
201 writel(0x08, QMP_PHY_BASE + PCIE_USB3_PHY_POWER_STATE_CONFIG2);
202
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800203 writel(0x00, QMP_PHY_BASE + PCIE_USB3_PHY_SW_RESET);
204 writel(0x03, QMP_PHY_BASE + PCIE_USB3_PHY_START);
205
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800206 clock_bumpup_pipe3_clk();
Channagoud Kadabi7bc9edb2014-06-01 19:01:12 -0700207
208 while ((readl(QMP_PHY_BASE + PCIE_USB3_PHY_PCS_STATUS) & PHYSTATUS))
209 {
210 udelay(1);
211 timeout--;
212 if (!timeout)
213 {
214 dprintf(CRITICAL, "QMP phy initialization failed\n");
215 return;
216 }
217 }
Channagoud Kadabiaab99d42014-02-04 15:45:56 -0800218}