blob: b6ca7eaf946ecd9d280245b0a9ea9775792c8059 [file] [log] [blame]
Channagoud Kadabic14b2a52015-01-06 15:05:12 -08001/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
Amol Jadif3d5a892013-07-23 16:09:44 -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 */
28
29/*
30 * The USB 3.0 core wrapper in MSM chipset includes:
31 * - DWC core
32 * - PHY control and configuration
33 * - Configuration and buffers to be provided to the DWC core.
34 *
35 * This file implements the USB30 core wrapper configuration functions.
36 * Core wrapper glues the dwc usb controller into msm chip.
37*/
38
39
40#include <debug.h>
41#include <reg.h>
42#include <malloc.h>
43#include <assert.h>
44#include <board.h>
45#include <pm8x41.h>
46#include <platform/iomap.h>
47#include <platform/timer.h>
48#include <platform/iomap.h>
49#include <platform/clock.h>
50#include <usb30_wrapper.h>
51#include <usb30_wrapper_hwio.h>
Channagoud Kadabi1f24f8a2015-02-11 15:43:10 -080052#include <qmp_phy.h>
Amol Jadif3d5a892013-07-23 16:09:44 -070053
54
55/* Configure DBM mode: by-pass or DBM */
56void usb_wrapper_dbm_mode(usb_wrapper_dev_t *dev, dbm_mode_t mode)
57{
58 if (mode == DBM_MODE_BYPASS)
59 {
60 REG_WRITE_FIELD(dev, GENERAL_CFG, DBM_EN, 0);
61 }
62 else
63 {
64 REG_WRITE_FIELD(dev, GENERAL_CFG, DBM_EN, 1);
65 }
66}
67
68/* use config 0: all of RAM1 */
69void usb_wrapper_ram_configure(usb_wrapper_dev_t *dev)
70{
71 REG_WRITE(dev, RAM1_REG, 0x0);
72}
73
74/* reset SS phy */
75void usb_wrapper_ss_phy_reset(usb_wrapper_dev_t *dev)
76{
77 REG_WRITE_FIELD(dev, SS_PHY_CTRL, SS_PHY_RESET, 1);
78
79 /* per HPG */
80 udelay(10);
81
82 REG_WRITE_FIELD(dev, SS_PHY_CTRL, SS_PHY_RESET, 0);
83}
84
85/* configure SS phy as specified in HPG */
86void usb_wrapper_ss_phy_configure(usb_wrapper_dev_t *dev)
87{
88 /* 4.a */
89 REG_WRITE_FIELD(dev, SS_PHY_CTRL, REF_USE_PAD, 1);
90 /* .b */
91 REG_WRITE_FIELD(dev, SS_PHY_CTRL, LANE0_PWR_PRESENT, 1);
92 /* .c */
93 REG_WRITE_FIELD(dev, SS_PHY_CTRL, REF_SS_PHY_EN, 1);
94
95 /* For Aragorn V1, reset value fix is required.*/
96 if ( (board_platform_id() == MSM8974) &&
97 (board_soc_version() < BOARD_SOC_VERSION2))
98 {
99 REG_WRITE_FIELD(dev, SS_PHY_CTRL, SSC_REF_CLK_SEL, 0x108);
100 }
101}
102
103/* configure SS phy electrical params */
104void usb_wrapper_ss_phy_electrical_config(usb_wrapper_dev_t *dev)
105{
106 /* reset value seems to work just fine for now. */
107}
108
109/* Initialize HS phy */
110void usb_wrapper_hs_phy_init(usb_wrapper_dev_t *dev)
111{
112 /* 5.a */
113 REG_WRITE_FIELD(dev, HS_PHY_CTRL, FREECLK_SEL, 0x0);
114
115 /* 5.b */
116 REG_WRITE_FIELD(dev, HS_PHY_CTRL, COMMONONN, 0x1);
117}
118
119/* configure HS phy as specified in HPG */
120void usb_wrapper_hs_phy_configure(usb_wrapper_dev_t *dev)
121{
122 /* 6.a */
123 REG_WRITE(dev, PARAMETER_OVERRIDE_X, 0xD190E4);
124}
125
126void usb_wrapper_workaround_10(usb_wrapper_dev_t *dev)
127{
128 /* 10. */
129 if ( (board_platform_id() == MSM8974) &&
130 (board_soc_version() < BOARD_SOC_VERSION2))
131 {
Amol Jadif3d5a892013-07-23 16:09:44 -0700132 REG_WRITE(dev, GENERAL_CFG, 0x78);
133 }
134}
135
136void usb_wrapper_workaround_11(usb_wrapper_dev_t *dev)
137{
138 /*
139 * 11. Apply WA for QCTDD00335018 -
140 * a. Description: Enables the Tx for alt bus mode, powers up the pmos_bias block, and so on; required if manually running the alt bus features.
141 * b. Assert LANE0.TX_ALT_BLOCK (102D) EN_ALT_BUS (bit 7);
142 * c. To be replaced in V2 with other WA (which will be applied during suspend sequence)
143 *
144 */
145
146 /* Not implemented. required if manually running the alt bus features.*/
147}
148
149/* workaround #13 as described in HPG */
150void usb_wrapper_workaround_13(usb_wrapper_dev_t *dev)
151{
152 REG_WRITE_FIELD(dev, SS_PHY_PARAM_CTRL_1, LOS_BIAS, 0x5);
153}
154
Amol Jadi5418da32013-10-11 14:14:47 -0700155void usb_wrapper_vbus_override(usb_wrapper_dev_t *dev)
156{
157 /* set extenal vbus valid select */
158 REG_WRITE_FIELD(dev, HS_PHY_CTRL_COMMON, VBUSVLDEXTSEL0, 0x1);
159
160 /* enable D+ pullup */
161 REG_WRITE_FIELD(dev, HS_PHY_CTRL, VBUSVLDEXT0, 0x1);
162
163 /* set otg vbus valid from hs phy to controller */
164 REG_WRITE_FIELD(dev, HS_PHY_CTRL, UTMI_OTG_VBUS_VALID, 0x1);
165
166 /* Indicate value is driven by UTMI_OTG_VBUS_VALID bit */
167 REG_WRITE_FIELD(dev, HS_PHY_CTRL, SW_SESSVLD_SEL, 0x1);
168
169 /* Indicate power present to SS phy */
Channagoud Kadabi1f24f8a2015-02-11 15:43:10 -0800170 if (!use_hsonly_mode())
171 REG_WRITE_FIELD(dev, SS_PHY_CTRL, LANE0_PWR_PRESENT, 0x1);
Amol Jadi5418da32013-10-11 14:14:47 -0700172}
Amol Jadif3d5a892013-07-23 16:09:44 -0700173
174/* API to read SS PHY registers */
175uint16_t usb_wrapper_ss_phy_read(usb_wrapper_dev_t *dev, uint16_t addr)
176{
177 uint16_t data;
178
179 /* write address to be read */
180 REG_WRITE(dev, SS_CR_PROTOCOL_DATA_IN, addr);
181
182 /* trigger capture of address in addr reg and wait until done */
183 REG_WRITE(dev, SS_CR_PROTOCOL_CAP_ADDR, 0x1);
184 while(REG_READ(dev, SS_CR_PROTOCOL_CAP_ADDR) & 0x1);
185
186 /* read from referenced register */
187 REG_WRITE(dev, SS_CR_PROTOCOL_READ, 0x1);
188
189 /* wait until read is done */
190 while(REG_READ(dev, SS_CR_PROTOCOL_READ) & 0x1);
191 data = REG_READ(dev, SS_CR_PROTOCOL_DATA_OUT);
192
193 /* TODO: hpg 4.14.2 note: reading ss phy register must be performed twice.
194 * does this whole sequence need to be done twice or just the reading from
195 * data_out??
196 * QCTDD00516153
197 */
198 ASSERT(0);
199
200 return data;
201}
202
203/* API to write to SS PHY registers */
204void usb_wrapper_ss_phy_write(usb_wrapper_dev_t *dev, uint16_t addr, uint16_t data)
205{
206 /* write address to be read */
207 REG_WRITE(dev, SS_CR_PROTOCOL_DATA_IN, addr);
208
209 /* trigger capture of address in addr reg and wait until done */
210 REG_WRITE(dev, SS_CR_PROTOCOL_CAP_ADDR, 0x1);
211 while(REG_READ(dev, SS_CR_PROTOCOL_CAP_ADDR) & 0x1);
212
213 /* write address to be read */
214 REG_WRITE(dev, SS_CR_PROTOCOL_DATA_IN, data);
215
216 /* trigger capture of data in addr reg and wait until done */
217 REG_WRITE(dev, SS_CR_PROTOCOL_CAP_DATA, 0x1);
218 while(REG_READ(dev, SS_CR_PROTOCOL_CAP_DATA) & 0x1);
219
220 /* write to referenced register and wait until done */
221 REG_WRITE(dev, SS_CR_PROTOCOL_WRITE, 0x1);
222 while(REG_READ(dev, SS_CR_PROTOCOL_READ) & 0x1);
223
224 /* TODO: hpg 4.14.2 note: reading ss phy register must be performed twice.
225 * does this whole sequence need to be done twice or just the reading from
226 * data_out??
227 * QCTDD00516153
228 */
229 ASSERT(0);
230}
231
232/* initialize the wrapper core */
233usb_wrapper_dev_t * usb_wrapper_init(usb_wrapper_config_t *config)
234{
235 usb_wrapper_dev_t *wrapper;
236
237 /* create a wrapper device */
238 wrapper = (usb_wrapper_dev_t*) malloc(sizeof(usb_wrapper_dev_t));
239 ASSERT(wrapper);
240
241 /* save qscratch base */
242 wrapper->base = config->qscratch_base;
243
Amol Jadif3d5a892013-07-23 16:09:44 -0700244 /* HPG: section 4.4.1 Control sequence */
245 usb_wrapper_dbm_mode(wrapper, DBM_MODE_BYPASS);
246
247 /* HPG: section 4.4.1: use config 0 - all of RAM1 */
248 usb_wrapper_ram_configure(wrapper);
249
250 return wrapper;
251}
Channagoud Kadabi685337e2013-11-13 13:53:24 -0800252
253void usb_wrapper_hs_phy_ctrl_force_write(usb_wrapper_dev_t *dev)
254{
255 REG_WRITE(dev, HS_PHY_CTRL_COMMON, 0x00001CB8);
256}
Channagoud Kadabic14b2a52015-01-06 15:05:12 -0800257
258void usb_wrapper_hsonly_mode(usb_wrapper_dev_t *dev)
259{
260 REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE_UTMI_CLK_DIS, 0x1);
261 udelay(1);
262 REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE_UTMI_CLK_SEL, 0x1);
263 REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE3_PHYSTATUS_SW, 0x1);
264 udelay(1);
265 REG_WRITE_FIELD(dev, GENERAL_CFG, PIPE_UTMI_CLK_DIS, 0x0);
266}