Commit | Line | Data |
---|---|---|
81c0fc51 YG |
1 | /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. |
2 | * | |
3 | * This program is free software; you can redistribute it and/or modify | |
4 | * it under the terms of the GNU General Public License version 2 and | |
5 | * only version 2 as published by the Free Software Foundation. | |
6 | * | |
7 | * This program is distributed in the hope that it will be useful, | |
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | * GNU General Public License for more details. | |
11 | * | |
12 | */ | |
13 | ||
14 | #ifndef UFS_QCOM_H_ | |
15 | #define UFS_QCOM_H_ | |
16 | ||
17 | #define MAX_UFS_QCOM_HOSTS 1 | |
18 | #define MAX_U32 (~(u32)0) | |
19 | #define MPHY_TX_FSM_STATE 0x41 | |
20 | #define TX_FSM_HIBERN8 0x1 | |
21 | #define HBRN8_POLL_TOUT_MS 100 | |
22 | #define DEFAULT_CLK_RATE_HZ 1000000 | |
23 | #define BUS_VECTOR_NAME_LEN 32 | |
24 | ||
25 | #define UFS_HW_VER_MAJOR_SHFT (28) | |
26 | #define UFS_HW_VER_MAJOR_MASK (0x000F << UFS_HW_VER_MAJOR_SHFT) | |
27 | #define UFS_HW_VER_MINOR_SHFT (16) | |
28 | #define UFS_HW_VER_MINOR_MASK (0x0FFF << UFS_HW_VER_MINOR_SHFT) | |
29 | #define UFS_HW_VER_STEP_SHFT (0) | |
30 | #define UFS_HW_VER_STEP_MASK (0xFFFF << UFS_HW_VER_STEP_SHFT) | |
31 | ||
32 | /* vendor specific pre-defined parameters */ | |
33 | #define SLOW 1 | |
34 | #define FAST 2 | |
35 | ||
36 | #define UFS_QCOM_LIMIT_NUM_LANES_RX 2 | |
37 | #define UFS_QCOM_LIMIT_NUM_LANES_TX 2 | |
f06fcc71 YG |
38 | #define UFS_QCOM_LIMIT_HSGEAR_RX UFS_HS_G3 |
39 | #define UFS_QCOM_LIMIT_HSGEAR_TX UFS_HS_G3 | |
81c0fc51 YG |
40 | #define UFS_QCOM_LIMIT_PWMGEAR_RX UFS_PWM_G4 |
41 | #define UFS_QCOM_LIMIT_PWMGEAR_TX UFS_PWM_G4 | |
42 | #define UFS_QCOM_LIMIT_RX_PWR_PWM SLOW_MODE | |
43 | #define UFS_QCOM_LIMIT_TX_PWR_PWM SLOW_MODE | |
44 | #define UFS_QCOM_LIMIT_RX_PWR_HS FAST_MODE | |
45 | #define UFS_QCOM_LIMIT_TX_PWR_HS FAST_MODE | |
46 | #define UFS_QCOM_LIMIT_HS_RATE PA_HS_MODE_B | |
47 | #define UFS_QCOM_LIMIT_DESIRED_MODE FAST | |
48 | ||
49 | /* QCOM UFS host controller vendor specific registers */ | |
50 | enum { | |
51 | REG_UFS_SYS1CLK_1US = 0xC0, | |
52 | REG_UFS_TX_SYMBOL_CLK_NS_US = 0xC4, | |
53 | REG_UFS_LOCAL_PORT_ID_REG = 0xC8, | |
54 | REG_UFS_PA_ERR_CODE = 0xCC, | |
55 | REG_UFS_RETRY_TIMER_REG = 0xD0, | |
56 | REG_UFS_PA_LINK_STARTUP_TIMER = 0xD8, | |
57 | REG_UFS_CFG1 = 0xDC, | |
58 | REG_UFS_CFG2 = 0xE0, | |
59 | REG_UFS_HW_VERSION = 0xE4, | |
60 | ||
6e3fd44d YG |
61 | UFS_TEST_BUS = 0xE8, |
62 | UFS_TEST_BUS_CTRL_0 = 0xEC, | |
63 | UFS_TEST_BUS_CTRL_1 = 0xF0, | |
64 | UFS_TEST_BUS_CTRL_2 = 0xF4, | |
65 | UFS_UNIPRO_CFG = 0xF8, | |
66 | ||
f06fcc71 YG |
67 | /* |
68 | * QCOM UFS host controller vendor specific registers | |
69 | * added in HW Version 3.0.0 | |
70 | */ | |
71 | UFS_AH8_CFG = 0xFC, | |
6e3fd44d YG |
72 | }; |
73 | ||
74 | /* QCOM UFS host controller vendor specific debug registers */ | |
75 | enum { | |
81c0fc51 YG |
76 | UFS_DBG_RD_REG_UAWM = 0x100, |
77 | UFS_DBG_RD_REG_UARM = 0x200, | |
78 | UFS_DBG_RD_REG_TXUC = 0x300, | |
79 | UFS_DBG_RD_REG_RXUC = 0x400, | |
80 | UFS_DBG_RD_REG_DFC = 0x500, | |
81 | UFS_DBG_RD_REG_TRLUT = 0x600, | |
82 | UFS_DBG_RD_REG_TMRLUT = 0x700, | |
83 | UFS_UFS_DBG_RD_REG_OCSC = 0x800, | |
84 | ||
85 | UFS_UFS_DBG_RD_DESC_RAM = 0x1500, | |
86 | UFS_UFS_DBG_RD_PRDT_RAM = 0x1700, | |
87 | UFS_UFS_DBG_RD_RESP_RAM = 0x1800, | |
88 | UFS_UFS_DBG_RD_EDTL_RAM = 0x1900, | |
89 | }; | |
90 | ||
f06fcc71 YG |
91 | #define UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(x) (0x000 + x) |
92 | #define UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(x) (0x400 + x) | |
93 | ||
94 | /* bit definitions for REG_UFS_CFG1 register */ | |
95 | #define QUNIPRO_SEL UFS_BIT(0) | |
6e3fd44d YG |
96 | #define TEST_BUS_EN BIT(18) |
97 | #define TEST_BUS_SEL GENMASK(22, 19) | |
98 | ||
81c0fc51 YG |
99 | /* bit definitions for REG_UFS_CFG2 register */ |
100 | #define UAWM_HW_CGC_EN (1 << 0) | |
101 | #define UARM_HW_CGC_EN (1 << 1) | |
102 | #define TXUC_HW_CGC_EN (1 << 2) | |
103 | #define RXUC_HW_CGC_EN (1 << 3) | |
104 | #define DFC_HW_CGC_EN (1 << 4) | |
105 | #define TRLUT_HW_CGC_EN (1 << 5) | |
106 | #define TMRLUT_HW_CGC_EN (1 << 6) | |
107 | #define OCSC_HW_CGC_EN (1 << 7) | |
108 | ||
6e3fd44d YG |
109 | /* bit definition for UFS_UFS_TEST_BUS_CTRL_n */ |
110 | #define TEST_BUS_SUB_SEL_MASK 0x1F /* All XXX_SEL fields are 5 bits wide */ | |
111 | ||
81c0fc51 YG |
112 | #define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\ |
113 | TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\ | |
114 | DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\ | |
115 | TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN) | |
116 | ||
117 | /* bit offset */ | |
118 | enum { | |
119 | OFFSET_UFS_PHY_SOFT_RESET = 1, | |
120 | OFFSET_CLK_NS_REG = 10, | |
121 | }; | |
122 | ||
123 | /* bit masks */ | |
124 | enum { | |
125 | MASK_UFS_PHY_SOFT_RESET = 0x2, | |
126 | MASK_TX_SYMBOL_CLK_1US_REG = 0x3FF, | |
127 | MASK_CLK_NS_REG = 0xFFFC00, | |
128 | }; | |
129 | ||
130 | enum ufs_qcom_phy_init_type { | |
131 | UFS_PHY_INIT_FULL, | |
132 | UFS_PHY_INIT_CFG_RESTORE, | |
133 | }; | |
134 | ||
6e3fd44d YG |
135 | /* QCOM UFS debug print bit mask */ |
136 | #define UFS_QCOM_DBG_PRINT_REGS_EN BIT(0) | |
137 | #define UFS_QCOM_DBG_PRINT_ICE_REGS_EN BIT(1) | |
138 | #define UFS_QCOM_DBG_PRINT_TEST_BUS_EN BIT(2) | |
139 | ||
140 | #define UFS_QCOM_DBG_PRINT_ALL \ | |
141 | (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_ICE_REGS_EN | \ | |
142 | UFS_QCOM_DBG_PRINT_TEST_BUS_EN) | |
143 | ||
f06fcc71 YG |
144 | /* QUniPro Vendor specific attributes */ |
145 | #define DME_VS_CORE_CLK_CTRL 0xD002 | |
146 | /* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */ | |
147 | #define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT BIT(8) | |
148 | #define DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK 0xFF | |
149 | ||
81c0fc51 YG |
150 | static inline void |
151 | ufs_qcom_get_controller_revision(struct ufs_hba *hba, | |
152 | u8 *major, u16 *minor, u16 *step) | |
153 | { | |
154 | u32 ver = ufshcd_readl(hba, REG_UFS_HW_VERSION); | |
155 | ||
156 | *major = (ver & UFS_HW_VER_MAJOR_MASK) >> UFS_HW_VER_MAJOR_SHFT; | |
157 | *minor = (ver & UFS_HW_VER_MINOR_MASK) >> UFS_HW_VER_MINOR_SHFT; | |
158 | *step = (ver & UFS_HW_VER_STEP_MASK) >> UFS_HW_VER_STEP_SHFT; | |
159 | }; | |
160 | ||
161 | static inline void ufs_qcom_assert_reset(struct ufs_hba *hba) | |
162 | { | |
163 | ufshcd_rmwl(hba, MASK_UFS_PHY_SOFT_RESET, | |
164 | 1 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); | |
165 | ||
166 | /* | |
167 | * Make sure assertion of ufs phy reset is written to | |
168 | * register before returning | |
169 | */ | |
170 | mb(); | |
171 | } | |
172 | ||
173 | static inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) | |
174 | { | |
175 | ufshcd_rmwl(hba, MASK_UFS_PHY_SOFT_RESET, | |
176 | 0 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); | |
177 | ||
178 | /* | |
179 | * Make sure de-assertion of ufs phy reset is written to | |
180 | * register before returning | |
181 | */ | |
182 | mb(); | |
183 | } | |
184 | ||
185 | struct ufs_qcom_bus_vote { | |
186 | uint32_t client_handle; | |
187 | uint32_t curr_vote; | |
188 | int min_bw_vote; | |
189 | int max_bw_vote; | |
190 | int saved_vote; | |
191 | bool is_max_bw_needed; | |
192 | struct device_attribute max_bus_bw; | |
193 | }; | |
194 | ||
bfdbe8ba YG |
195 | /* Host controller hardware version: major.minor.step */ |
196 | struct ufs_hw_version { | |
197 | u16 step; | |
198 | u16 minor; | |
199 | u8 major; | |
200 | }; | |
cad2e03d | 201 | |
6e3fd44d YG |
202 | struct ufs_qcom_testbus { |
203 | u8 select_major; | |
204 | u8 select_minor; | |
205 | }; | |
206 | ||
207 | struct ufs_qcom_host { | |
cad2e03d YG |
208 | /* |
209 | * Set this capability if host controller supports the QUniPro mode | |
210 | * and if driver wants the Host controller to operate in QUniPro mode. | |
211 | * Note: By default this capability will be kept enabled if host | |
212 | * controller supports the QUniPro mode. | |
213 | */ | |
214 | #define UFS_QCOM_CAP_QUNIPRO UFS_BIT(0) | |
f06fcc71 YG |
215 | |
216 | /* | |
217 | * Set this capability if host controller can retain the secure | |
218 | * configuration even after UFS controller core power collapse. | |
219 | */ | |
220 | #define UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE UFS_BIT(1) | |
cad2e03d YG |
221 | u32 caps; |
222 | ||
81c0fc51 YG |
223 | struct phy *generic_phy; |
224 | struct ufs_hba *hba; | |
225 | struct ufs_qcom_bus_vote bus_vote; | |
226 | struct ufs_pa_layer_attr dev_req_params; | |
227 | struct clk *rx_l0_sync_clk; | |
228 | struct clk *tx_l0_sync_clk; | |
229 | struct clk *rx_l1_sync_clk; | |
230 | struct clk *tx_l1_sync_clk; | |
231 | bool is_lane_clks_enabled; | |
bfdbe8ba | 232 | |
f06fcc71 YG |
233 | void __iomem *dev_ref_clk_ctrl_mmio; |
234 | bool is_dev_ref_clk_enabled; | |
bfdbe8ba | 235 | struct ufs_hw_version hw_ver; |
f06fcc71 YG |
236 | |
237 | u32 dev_ref_clk_en_mask; | |
238 | ||
6e3fd44d YG |
239 | /* Bitmask for enabling debug prints */ |
240 | u32 dbg_print_en; | |
241 | struct ufs_qcom_testbus testbus; | |
81c0fc51 YG |
242 | }; |
243 | ||
eba5ed35 YG |
244 | static inline u32 |
245 | ufs_qcom_get_debug_reg_offset(struct ufs_qcom_host *host, u32 reg) | |
246 | { | |
247 | if (host->hw_ver.major <= 0x02) | |
248 | return UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(reg); | |
249 | ||
250 | return UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(reg); | |
251 | }; | |
252 | ||
81c0fc51 YG |
253 | #define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba) |
254 | #define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba) | |
255 | #define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba) | |
256 | ||
6e3fd44d YG |
257 | int ufs_qcom_testbus_config(struct ufs_qcom_host *host); |
258 | ||
cad2e03d YG |
259 | static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host) |
260 | { | |
261 | if (host->caps & UFS_QCOM_CAP_QUNIPRO) | |
262 | return true; | |
263 | else | |
264 | return false; | |
265 | } | |
266 | ||
81c0fc51 | 267 | #endif /* UFS_QCOM_H_ */ |