1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (C) 2019 MediaTek Inc. |
4 | */ |
5 | |
6 | #ifndef _UFS_MEDIATEK_H |
7 | #define _UFS_MEDIATEK_H |
8 | |
9 | #include <linux/bitops.h> |
10 | #include <linux/soc/mediatek/mtk_sip_svc.h> |
11 | |
12 | /* |
13 | * MCQ define and struct |
14 | */ |
15 | #define UFSHCD_MAX_Q_NR 8 |
16 | #define MTK_MCQ_INVALID_IRQ 0xFFFF |
17 | |
18 | /* REG_UFS_MMIO_OPT_CTRL_0 160h */ |
19 | #define EHS_EN BIT(0) |
20 | #define PFM_IMPV BIT(1) |
21 | #define MCQ_MULTI_INTR_EN BIT(2) |
22 | #define MCQ_CMB_INTR_EN BIT(3) |
23 | #define MCQ_AH8 BIT(4) |
24 | |
25 | #define MCQ_INTR_EN_MSK (MCQ_MULTI_INTR_EN | MCQ_CMB_INTR_EN) |
26 | |
27 | /* |
28 | * Vendor specific UFSHCI Registers |
29 | */ |
30 | #define REG_UFS_XOUFS_CTRL 0x140 |
31 | #define REG_UFS_REFCLK_CTRL 0x144 |
32 | #define REG_UFS_MMIO_OPT_CTRL_0 0x160 |
33 | #define REG_UFS_EXTREG 0x2100 |
34 | #define REG_UFS_MPHYCTRL 0x2200 |
35 | #define REG_UFS_MTK_IP_VER 0x2240 |
36 | #define REG_UFS_REJECT_MON 0x22AC |
37 | #define REG_UFS_DEBUG_SEL 0x22C0 |
38 | #define REG_UFS_PROBE 0x22C8 |
39 | #define REG_UFS_DEBUG_SEL_B0 0x22D0 |
40 | #define REG_UFS_DEBUG_SEL_B1 0x22D4 |
41 | #define REG_UFS_DEBUG_SEL_B2 0x22D8 |
42 | #define REG_UFS_DEBUG_SEL_B3 0x22DC |
43 | |
44 | #define REG_UFS_MTK_SQD 0x2800 |
45 | #define REG_UFS_MTK_SQIS 0x2814 |
46 | #define REG_UFS_MTK_CQD 0x281C |
47 | #define REG_UFS_MTK_CQIS 0x2824 |
48 | |
49 | #define REG_UFS_MCQ_STRIDE 0x30 |
50 | |
51 | /* |
52 | * Ref-clk control |
53 | * |
54 | * Values for register REG_UFS_REFCLK_CTRL |
55 | */ |
56 | #define REFCLK_RELEASE 0x0 |
57 | #define REFCLK_REQUEST BIT(0) |
58 | #define REFCLK_ACK BIT(1) |
59 | |
60 | #define REFCLK_REQ_TIMEOUT_US 3000 |
61 | #define REFCLK_DEFAULT_WAIT_US 32 |
62 | |
63 | /* |
64 | * Other attributes |
65 | */ |
66 | #define VS_DEBUGCLOCKENABLE 0xD0A1 |
67 | #define VS_SAVEPOWERCONTROL 0xD0A6 |
68 | #define VS_UNIPROPOWERDOWNCONTROL 0xD0A8 |
69 | |
70 | /* |
71 | * Vendor specific link state |
72 | */ |
73 | enum { |
74 | VS_LINK_DISABLED = 0, |
75 | VS_LINK_DOWN = 1, |
76 | VS_LINK_UP = 2, |
77 | VS_LINK_HIBERN8 = 3, |
78 | VS_LINK_LOST = 4, |
79 | VS_LINK_CFG = 5, |
80 | }; |
81 | |
82 | /* |
83 | * Vendor specific host controller state |
84 | */ |
85 | enum { |
86 | VS_HCE_RESET = 0, |
87 | VS_HCE_BASE = 1, |
88 | VS_HCE_OOCPR_WAIT = 2, |
89 | VS_HCE_DME_RESET = 3, |
90 | VS_HCE_MIDDLE = 4, |
91 | VS_HCE_DME_ENABLE = 5, |
92 | VS_HCE_DEFAULTS = 6, |
93 | VS_HIB_IDLEEN = 7, |
94 | VS_HIB_ENTER = 8, |
95 | VS_HIB_ENTER_CONF = 9, |
96 | VS_HIB_MIDDLE = 10, |
97 | VS_HIB_WAITTIMER = 11, |
98 | VS_HIB_EXIT_CONF = 12, |
99 | VS_HIB_EXIT = 13, |
100 | }; |
101 | |
102 | /* |
103 | * SiP commands |
104 | */ |
105 | #define MTK_SIP_UFS_CONTROL MTK_SIP_SMC_CMD(0x276) |
106 | #define UFS_MTK_SIP_VA09_PWR_CTRL BIT(0) |
107 | #define UFS_MTK_SIP_DEVICE_RESET BIT(1) |
108 | #define UFS_MTK_SIP_CRYPTO_CTRL BIT(2) |
109 | #define UFS_MTK_SIP_REF_CLK_NOTIFICATION BIT(3) |
110 | #define UFS_MTK_SIP_HOST_PWR_CTRL BIT(5) |
111 | #define UFS_MTK_SIP_GET_VCC_NUM BIT(6) |
112 | #define UFS_MTK_SIP_DEVICE_PWR_CTRL BIT(7) |
113 | |
114 | /* |
115 | * VS_DEBUGCLOCKENABLE |
116 | */ |
117 | enum { |
118 | TX_SYMBOL_CLK_REQ_FORCE = 5, |
119 | }; |
120 | |
121 | /* |
122 | * VS_SAVEPOWERCONTROL |
123 | */ |
124 | enum { |
125 | RX_SYMBOL_CLK_GATE_EN = 0, |
126 | SYS_CLK_GATE_EN = 2, |
127 | TX_CLK_GATE_EN = 3, |
128 | }; |
129 | |
130 | /* |
131 | * Host capability |
132 | */ |
133 | enum ufs_mtk_host_caps { |
134 | UFS_MTK_CAP_BOOST_CRYPT_ENGINE = 1 << 0, |
135 | UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1, |
136 | UFS_MTK_CAP_DISABLE_AH8 = 1 << 2, |
137 | UFS_MTK_CAP_BROKEN_VCC = 1 << 3, |
138 | UFS_MTK_CAP_PMC_VIA_FASTAUTO = 1 << 6, |
139 | }; |
140 | |
141 | struct ufs_mtk_crypt_cfg { |
142 | struct regulator *reg_vcore; |
143 | struct clk *clk_crypt_perf; |
144 | struct clk *clk_crypt_mux; |
145 | struct clk *clk_crypt_lp; |
146 | int vcore_volt; |
147 | }; |
148 | |
149 | struct ufs_mtk_clk { |
150 | struct ufs_clk_info *ufs_sel_clki; /* Mux */ |
151 | struct ufs_clk_info *ufs_sel_max_clki; /* Max src */ |
152 | struct ufs_clk_info *ufs_sel_min_clki; /* Min src */ |
153 | }; |
154 | |
155 | struct ufs_mtk_hw_ver { |
156 | u8 step; |
157 | u8 minor; |
158 | u8 major; |
159 | }; |
160 | |
161 | struct ufs_mtk_mcq_intr_info { |
162 | struct ufs_hba *hba; |
163 | u32 irq; |
164 | u8 qid; |
165 | }; |
166 | |
167 | struct ufs_mtk_host { |
168 | struct phy *mphy; |
169 | struct regulator *reg_va09; |
170 | struct reset_control *hci_reset; |
171 | struct reset_control *unipro_reset; |
172 | struct reset_control *crypto_reset; |
173 | struct ufs_hba *hba; |
174 | struct ufs_mtk_crypt_cfg *crypt; |
175 | struct ufs_mtk_clk mclk; |
176 | struct ufs_mtk_hw_ver hw_ver; |
177 | enum ufs_mtk_host_caps caps; |
178 | bool mphy_powered_on; |
179 | bool unipro_lpm; |
180 | bool ref_clk_enabled; |
181 | u16 ref_clk_ungating_wait_us; |
182 | u16 ref_clk_gating_wait_us; |
183 | u32 ip_ver; |
184 | |
185 | bool mcq_set_intr; |
186 | bool is_mcq_intr_enabled; |
187 | int mcq_nr_intr; |
188 | struct ufs_mtk_mcq_intr_info mcq_intr_info[UFSHCD_MAX_Q_NR]; |
189 | }; |
190 | |
191 | /* MTK delay of autosuspend: 500 ms */ |
192 | #define MTK_RPM_AUTOSUSPEND_DELAY_MS 500 |
193 | |
194 | /* |
195 | * Multi-VCC by Numbering |
196 | */ |
197 | enum ufs_mtk_vcc_num { |
198 | UFS_VCC_NONE = 0, |
199 | UFS_VCC_1, |
200 | UFS_VCC_2, |
201 | UFS_VCC_MAX |
202 | }; |
203 | |
204 | /* |
205 | * Host Power Control options |
206 | */ |
207 | enum { |
208 | HOST_PWR_HCI = 0, |
209 | HOST_PWR_MPHY |
210 | }; |
211 | |
212 | /* |
213 | * SMC call wrapper function |
214 | */ |
215 | struct ufs_mtk_smc_arg { |
216 | unsigned long cmd; |
217 | struct arm_smccc_res *res; |
218 | unsigned long v1; |
219 | unsigned long v2; |
220 | unsigned long v3; |
221 | unsigned long v4; |
222 | unsigned long v5; |
223 | unsigned long v6; |
224 | unsigned long v7; |
225 | }; |
226 | |
227 | static void _ufs_mtk_smc(struct ufs_mtk_smc_arg s) |
228 | { |
229 | arm_smccc_smc(MTK_SIP_UFS_CONTROL, |
230 | s.cmd, s.v1, s.v2, s.v3, s.v4, s.v5, s.v6, s.res); |
231 | } |
232 | |
233 | #define ufs_mtk_smc(...) \ |
234 | _ufs_mtk_smc((struct ufs_mtk_smc_arg) {__VA_ARGS__}) |
235 | |
236 | /* |
237 | * SMC call interface |
238 | */ |
239 | #define ufs_mtk_va09_pwr_ctrl(res, on) \ |
240 | ufs_mtk_smc(UFS_MTK_SIP_VA09_PWR_CTRL, &(res), on) |
241 | |
242 | #define ufs_mtk_crypto_ctrl(res, enable) \ |
243 | ufs_mtk_smc(UFS_MTK_SIP_CRYPTO_CTRL, &(res), enable) |
244 | |
245 | #define ufs_mtk_ref_clk_notify(on, stage, res) \ |
246 | ufs_mtk_smc(UFS_MTK_SIP_REF_CLK_NOTIFICATION, &(res), on, stage) |
247 | |
248 | #define ufs_mtk_device_reset_ctrl(high, res) \ |
249 | ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, &(res), high) |
250 | |
251 | #define ufs_mtk_host_pwr_ctrl(opt, on, res) \ |
252 | ufs_mtk_smc(UFS_MTK_SIP_HOST_PWR_CTRL, &(res), opt, on) |
253 | |
254 | #define ufs_mtk_get_vcc_num(res) \ |
255 | ufs_mtk_smc(UFS_MTK_SIP_GET_VCC_NUM, &(res)) |
256 | |
257 | #define ufs_mtk_device_pwr_ctrl(on, ufs_ver, res) \ |
258 | ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_ver) |
259 | |
260 | #endif /* !_UFS_MEDIATEK_H */ |
261 | |