1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * drivers/ata/ahci_tegra.c |
4 | * |
5 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. |
6 | * |
7 | * Author: |
8 | * Mikko Perttunen <mperttunen@nvidia.com> |
9 | */ |
10 | |
11 | #include <linux/ahci_platform.h> |
12 | #include <linux/errno.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> |
15 | #include <linux/of.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/regulator/consumer.h> |
18 | #include <linux/reset.h> |
19 | |
20 | #include <soc/tegra/fuse.h> |
21 | #include <soc/tegra/pmc.h> |
22 | |
23 | #include "ahci.h" |
24 | |
25 | #define DRV_NAME "tegra-ahci" |
26 | |
27 | #define SATA_CONFIGURATION_0 0x180 |
28 | #define SATA_CONFIGURATION_0_EN_FPCI BIT(0) |
29 | #define SATA_CONFIGURATION_0_CLK_OVERRIDE BIT(31) |
30 | |
31 | #define SCFG_OFFSET 0x1000 |
32 | |
33 | #define T_SATA0_CFG_1 0x04 |
34 | #define T_SATA0_CFG_1_IO_SPACE BIT(0) |
35 | #define T_SATA0_CFG_1_MEMORY_SPACE BIT(1) |
36 | #define T_SATA0_CFG_1_BUS_MASTER BIT(2) |
37 | #define T_SATA0_CFG_1_SERR BIT(8) |
38 | |
39 | #define T_SATA0_CFG_9 0x24 |
40 | #define T_SATA0_CFG_9_BASE_ADDRESS 0x40020000 |
41 | |
42 | #define SATA_FPCI_BAR5 0x94 |
43 | #define SATA_FPCI_BAR5_START_MASK (0xfffffff << 4) |
44 | #define SATA_FPCI_BAR5_START (0x0040020 << 4) |
45 | #define SATA_FPCI_BAR5_ACCESS_TYPE (0x1) |
46 | |
47 | #define SATA_INTR_MASK 0x188 |
48 | #define SATA_INTR_MASK_IP_INT_MASK BIT(16) |
49 | |
50 | #define T_SATA0_CFG_35 0x94 |
51 | #define T_SATA0_CFG_35_IDP_INDEX_MASK (0x7ff << 2) |
52 | #define T_SATA0_CFG_35_IDP_INDEX (0x2a << 2) |
53 | |
54 | #define T_SATA0_AHCI_IDP1 0x98 |
55 | #define T_SATA0_AHCI_IDP1_DATA (0x400040) |
56 | |
57 | #define T_SATA0_CFG_PHY_1 0x12c |
58 | #define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN BIT(23) |
59 | #define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN BIT(22) |
60 | |
61 | #define T_SATA0_NVOOB 0x114 |
62 | #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK (0x3 << 24) |
63 | #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE (0x1 << 24) |
64 | #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK (0x3 << 26) |
65 | #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH (0x3 << 26) |
66 | |
67 | #define T_SATA_CFG_PHY_0 0x120 |
68 | #define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD BIT(11) |
69 | #define T_SATA_CFG_PHY_0_MASK_SQUELCH BIT(24) |
70 | |
71 | #define T_SATA0_CFG2NVOOB_2 0x134 |
72 | #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK (0x1ff << 18) |
73 | #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW (0xc << 18) |
74 | |
75 | #define T_SATA0_AHCI_HBA_CAP_BKDR 0x300 |
76 | #define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP BIT(13) |
77 | #define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP BIT(14) |
78 | #define T_SATA0_AHCI_HBA_CAP_BKDR_SALP BIT(26) |
79 | #define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM BIT(17) |
80 | #define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ BIT(30) |
81 | |
82 | #define T_SATA0_BKDOOR_CC 0x4a4 |
83 | #define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK (0xffff << 16) |
84 | #define T_SATA0_BKDOOR_CC_CLASS_CODE (0x0106 << 16) |
85 | #define T_SATA0_BKDOOR_CC_PROG_IF_MASK (0xff << 8) |
86 | #define T_SATA0_BKDOOR_CC_PROG_IF (0x01 << 8) |
87 | |
88 | #define T_SATA0_CFG_SATA 0x54c |
89 | #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN BIT(12) |
90 | |
91 | #define T_SATA0_CFG_MISC 0x550 |
92 | |
93 | #define T_SATA0_INDEX 0x680 |
94 | |
95 | #define T_SATA0_CHX_PHY_CTRL1_GEN1 0x690 |
96 | #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK 0xff |
97 | #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT 0 |
98 | #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK (0xff << 8) |
99 | #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT 8 |
100 | |
101 | #define T_SATA0_CHX_PHY_CTRL1_GEN2 0x694 |
102 | #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK 0xff |
103 | #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT 0 |
104 | #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK (0xff << 12) |
105 | #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT 12 |
106 | |
107 | #define T_SATA0_CHX_PHY_CTRL2 0x69c |
108 | #define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1 0x23 |
109 | |
110 | #define T_SATA0_CHX_PHY_CTRL11 0x6d0 |
111 | #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ (0x2800 << 16) |
112 | |
113 | #define T_SATA0_CHX_PHY_CTRL17_0 0x6e8 |
114 | #define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1 0x55010000 |
115 | #define T_SATA0_CHX_PHY_CTRL18_0 0x6ec |
116 | #define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2 0x55010000 |
117 | #define T_SATA0_CHX_PHY_CTRL20_0 0x6f4 |
118 | #define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1 0x1 |
119 | #define T_SATA0_CHX_PHY_CTRL21_0 0x6f8 |
120 | #define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2 0x1 |
121 | |
122 | /* AUX Registers */ |
123 | #define SATA_AUX_MISC_CNTL_1_0 0x8 |
124 | #define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE BIT(17) |
125 | #define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT BIT(13) |
126 | #define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT BIT(15) |
127 | |
128 | #define SATA_AUX_RX_STAT_INT_0 0xc |
129 | #define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP BIT(7) |
130 | |
131 | #define SATA_AUX_SPARE_CFG0_0 0x18 |
132 | #define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID BIT(14) |
133 | |
134 | #define FUSE_SATA_CALIB 0x124 |
135 | #define FUSE_SATA_CALIB_MASK 0x3 |
136 | |
137 | struct sata_pad_calibration { |
138 | u8 gen1_tx_amp; |
139 | u8 gen1_tx_peak; |
140 | u8 gen2_tx_amp; |
141 | u8 gen2_tx_peak; |
142 | }; |
143 | |
144 | static const struct sata_pad_calibration tegra124_pad_calibration[] = { |
145 | {0x18, 0x04, 0x18, 0x0a}, |
146 | {0x0e, 0x04, 0x14, 0x0a}, |
147 | {0x0e, 0x07, 0x1a, 0x0e}, |
148 | {0x14, 0x0e, 0x1a, 0x0e}, |
149 | }; |
150 | |
151 | struct tegra_ahci_ops { |
152 | int (*init)(struct ahci_host_priv *hpriv); |
153 | }; |
154 | |
155 | struct tegra_ahci_regs { |
156 | unsigned int nvoob_comma_cnt_mask; |
157 | unsigned int nvoob_comma_cnt_val; |
158 | }; |
159 | |
160 | struct tegra_ahci_soc { |
161 | const char *const *supply_names; |
162 | u32 num_supplies; |
163 | bool supports_devslp; |
164 | bool has_sata_oob_rst; |
165 | const struct tegra_ahci_ops *ops; |
166 | const struct tegra_ahci_regs *regs; |
167 | }; |
168 | |
169 | struct tegra_ahci_priv { |
170 | struct platform_device *pdev; |
171 | void __iomem *sata_regs; |
172 | void __iomem *sata_aux_regs; |
173 | struct reset_control *sata_rst; |
174 | struct reset_control *sata_oob_rst; |
175 | struct reset_control *sata_cold_rst; |
176 | /* Needs special handling, cannot use ahci_platform */ |
177 | struct clk *sata_clk; |
178 | struct regulator_bulk_data *supplies; |
179 | const struct tegra_ahci_soc *soc; |
180 | }; |
181 | |
182 | static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv) |
183 | { |
184 | struct tegra_ahci_priv *tegra = hpriv->plat_data; |
185 | u32 val; |
186 | |
187 | if (tegra->sata_aux_regs && !tegra->soc->supports_devslp) { |
188 | val = readl(addr: tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0); |
189 | val &= ~SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT; |
190 | writel(val, addr: tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0); |
191 | } |
192 | } |
193 | |
194 | static int tegra124_ahci_init(struct ahci_host_priv *hpriv) |
195 | { |
196 | struct tegra_ahci_priv *tegra = hpriv->plat_data; |
197 | struct sata_pad_calibration calib; |
198 | int ret; |
199 | u32 val; |
200 | |
201 | /* Pad calibration */ |
202 | ret = tegra_fuse_readl(FUSE_SATA_CALIB, value: &val); |
203 | if (ret) |
204 | return ret; |
205 | |
206 | calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; |
207 | |
208 | writel(BIT(0), addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); |
209 | |
210 | val = readl(addr: tegra->sata_regs + |
211 | SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1); |
212 | val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK; |
213 | val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK; |
214 | val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; |
215 | val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; |
216 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + |
217 | T_SATA0_CHX_PHY_CTRL1_GEN1); |
218 | |
219 | val = readl(addr: tegra->sata_regs + |
220 | SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2); |
221 | val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK; |
222 | val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK; |
223 | val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT; |
224 | val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT; |
225 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + |
226 | T_SATA0_CHX_PHY_CTRL1_GEN2); |
227 | |
228 | writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ, |
229 | addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11); |
230 | writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1, |
231 | addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2); |
232 | |
233 | writel(val: 0, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX); |
234 | |
235 | return 0; |
236 | } |
237 | |
238 | static int tegra_ahci_power_on(struct ahci_host_priv *hpriv) |
239 | { |
240 | struct tegra_ahci_priv *tegra = hpriv->plat_data; |
241 | int ret; |
242 | |
243 | ret = regulator_bulk_enable(num_consumers: tegra->soc->num_supplies, |
244 | consumers: tegra->supplies); |
245 | if (ret) |
246 | return ret; |
247 | |
248 | if (!tegra->pdev->dev.pm_domain) { |
249 | ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA, |
250 | clk: tegra->sata_clk, |
251 | rst: tegra->sata_rst); |
252 | if (ret) |
253 | goto disable_regulators; |
254 | } |
255 | |
256 | reset_control_assert(rstc: tegra->sata_oob_rst); |
257 | reset_control_assert(rstc: tegra->sata_cold_rst); |
258 | |
259 | ret = ahci_platform_enable_resources(hpriv); |
260 | if (ret) |
261 | goto disable_power; |
262 | |
263 | reset_control_deassert(rstc: tegra->sata_cold_rst); |
264 | reset_control_deassert(rstc: tegra->sata_oob_rst); |
265 | |
266 | return 0; |
267 | |
268 | disable_power: |
269 | clk_disable_unprepare(clk: tegra->sata_clk); |
270 | |
271 | if (!tegra->pdev->dev.pm_domain) |
272 | tegra_powergate_power_off(TEGRA_POWERGATE_SATA); |
273 | |
274 | disable_regulators: |
275 | regulator_bulk_disable(num_consumers: tegra->soc->num_supplies, consumers: tegra->supplies); |
276 | |
277 | return ret; |
278 | } |
279 | |
280 | static void tegra_ahci_power_off(struct ahci_host_priv *hpriv) |
281 | { |
282 | struct tegra_ahci_priv *tegra = hpriv->plat_data; |
283 | |
284 | ahci_platform_disable_resources(hpriv); |
285 | |
286 | reset_control_assert(rstc: tegra->sata_rst); |
287 | reset_control_assert(rstc: tegra->sata_oob_rst); |
288 | reset_control_assert(rstc: tegra->sata_cold_rst); |
289 | |
290 | clk_disable_unprepare(clk: tegra->sata_clk); |
291 | if (!tegra->pdev->dev.pm_domain) |
292 | tegra_powergate_power_off(TEGRA_POWERGATE_SATA); |
293 | |
294 | regulator_bulk_disable(num_consumers: tegra->soc->num_supplies, consumers: tegra->supplies); |
295 | } |
296 | |
297 | static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) |
298 | { |
299 | struct tegra_ahci_priv *tegra = hpriv->plat_data; |
300 | int ret; |
301 | u32 val; |
302 | |
303 | ret = tegra_ahci_power_on(hpriv); |
304 | if (ret) { |
305 | dev_err(&tegra->pdev->dev, |
306 | "failed to power on AHCI controller: %d\n" , ret); |
307 | return ret; |
308 | } |
309 | |
310 | /* |
311 | * Program the following SATA IPFS registers to allow SW accesses to |
312 | * SATA's MMIO register range. |
313 | */ |
314 | val = readl(addr: tegra->sata_regs + SATA_FPCI_BAR5); |
315 | val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE); |
316 | val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE; |
317 | writel(val, addr: tegra->sata_regs + SATA_FPCI_BAR5); |
318 | |
319 | /* Program the following SATA IPFS register to enable the SATA */ |
320 | val = readl(addr: tegra->sata_regs + SATA_CONFIGURATION_0); |
321 | val |= SATA_CONFIGURATION_0_EN_FPCI; |
322 | writel(val, addr: tegra->sata_regs + SATA_CONFIGURATION_0); |
323 | |
324 | /* Electrical settings for better link stability */ |
325 | val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1; |
326 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0); |
327 | val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2; |
328 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0); |
329 | val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1; |
330 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0); |
331 | val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2; |
332 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0); |
333 | |
334 | /* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */ |
335 | |
336 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0); |
337 | val |= T_SATA_CFG_PHY_0_MASK_SQUELCH; |
338 | val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD; |
339 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0); |
340 | |
341 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); |
342 | val &= ~(tegra->soc->regs->nvoob_comma_cnt_mask | |
343 | T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK | |
344 | T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK); |
345 | val |= (tegra->soc->regs->nvoob_comma_cnt_val | |
346 | T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH | |
347 | T_SATA0_NVOOB_SQUELCH_FILTER_MODE); |
348 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); |
349 | |
350 | /* |
351 | * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns |
352 | */ |
353 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2); |
354 | val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK; |
355 | val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW; |
356 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2); |
357 | |
358 | if (tegra->soc->ops && tegra->soc->ops->init) |
359 | tegra->soc->ops->init(hpriv); |
360 | |
361 | /* |
362 | * Program the following SATA configuration registers to |
363 | * initialize SATA |
364 | */ |
365 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); |
366 | val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE | |
367 | T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR); |
368 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1); |
369 | val = T_SATA0_CFG_9_BASE_ADDRESS; |
370 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9); |
371 | |
372 | /* Program Class Code and Programming interface for SATA */ |
373 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); |
374 | val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN; |
375 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); |
376 | |
377 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); |
378 | val &= |
379 | ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK | |
380 | T_SATA0_BKDOOR_CC_PROG_IF_MASK); |
381 | val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF; |
382 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC); |
383 | |
384 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); |
385 | val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN; |
386 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA); |
387 | |
388 | /* Enabling LPM capabilities through Backdoor Programming */ |
389 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR); |
390 | val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP | |
391 | T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP | |
392 | T_SATA0_AHCI_HBA_CAP_BKDR_SALP | |
393 | T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM); |
394 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR); |
395 | |
396 | /* SATA Second Level Clock Gating configuration |
397 | * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane |
398 | * IDDQ Signals |
399 | */ |
400 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35); |
401 | val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK; |
402 | val |= T_SATA0_CFG_35_IDP_INDEX; |
403 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35); |
404 | |
405 | val = T_SATA0_AHCI_IDP1_DATA; |
406 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1); |
407 | |
408 | val = readl(addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1); |
409 | val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN | |
410 | T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN); |
411 | writel(val, addr: tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1); |
412 | |
413 | /* Enabling IPFS Clock Gating */ |
414 | val = readl(addr: tegra->sata_regs + SATA_CONFIGURATION_0); |
415 | val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE; |
416 | writel(val, addr: tegra->sata_regs + SATA_CONFIGURATION_0); |
417 | |
418 | tegra_ahci_handle_quirks(hpriv); |
419 | |
420 | /* Unmask SATA interrupts */ |
421 | |
422 | val = readl(addr: tegra->sata_regs + SATA_INTR_MASK); |
423 | val |= SATA_INTR_MASK_IP_INT_MASK; |
424 | writel(val, addr: tegra->sata_regs + SATA_INTR_MASK); |
425 | |
426 | return 0; |
427 | } |
428 | |
429 | static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv) |
430 | { |
431 | tegra_ahci_power_off(hpriv); |
432 | } |
433 | |
434 | static void tegra_ahci_host_stop(struct ata_host *host) |
435 | { |
436 | struct ahci_host_priv *hpriv = host->private_data; |
437 | |
438 | tegra_ahci_controller_deinit(hpriv); |
439 | } |
440 | |
441 | static struct ata_port_operations ahci_tegra_port_ops = { |
442 | .inherits = &ahci_ops, |
443 | .host_stop = tegra_ahci_host_stop, |
444 | }; |
445 | |
446 | static const struct ata_port_info ahci_tegra_port_info = { |
447 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, |
448 | .pio_mask = ATA_PIO4, |
449 | .udma_mask = ATA_UDMA6, |
450 | .port_ops = &ahci_tegra_port_ops, |
451 | }; |
452 | |
453 | static const char *const tegra124_supply_names[] = { |
454 | "avdd" , "hvdd" , "vddio" , "target-5v" , "target-12v" |
455 | }; |
456 | |
457 | static const struct tegra_ahci_ops tegra124_ahci_ops = { |
458 | .init = tegra124_ahci_init, |
459 | }; |
460 | |
461 | static const struct tegra_ahci_regs tegra124_ahci_regs = { |
462 | .nvoob_comma_cnt_mask = GENMASK(30, 28), |
463 | .nvoob_comma_cnt_val = (7 << 28), |
464 | }; |
465 | |
466 | static const struct tegra_ahci_soc tegra124_ahci_soc = { |
467 | .supply_names = tegra124_supply_names, |
468 | .num_supplies = ARRAY_SIZE(tegra124_supply_names), |
469 | .supports_devslp = false, |
470 | .has_sata_oob_rst = true, |
471 | .ops = &tegra124_ahci_ops, |
472 | .regs = &tegra124_ahci_regs, |
473 | }; |
474 | |
475 | static const struct tegra_ahci_soc tegra210_ahci_soc = { |
476 | .supports_devslp = false, |
477 | .has_sata_oob_rst = true, |
478 | .regs = &tegra124_ahci_regs, |
479 | }; |
480 | |
481 | static const struct tegra_ahci_regs tegra186_ahci_regs = { |
482 | .nvoob_comma_cnt_mask = GENMASK(23, 16), |
483 | .nvoob_comma_cnt_val = (7 << 16), |
484 | }; |
485 | |
486 | static const struct tegra_ahci_soc tegra186_ahci_soc = { |
487 | .supports_devslp = false, |
488 | .has_sata_oob_rst = false, |
489 | .regs = &tegra186_ahci_regs, |
490 | }; |
491 | |
492 | static const struct of_device_id tegra_ahci_of_match[] = { |
493 | { |
494 | .compatible = "nvidia,tegra124-ahci" , |
495 | .data = &tegra124_ahci_soc |
496 | }, |
497 | { |
498 | .compatible = "nvidia,tegra210-ahci" , |
499 | .data = &tegra210_ahci_soc |
500 | }, |
501 | { |
502 | .compatible = "nvidia,tegra186-ahci" , |
503 | .data = &tegra186_ahci_soc |
504 | }, |
505 | {} |
506 | }; |
507 | MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); |
508 | |
509 | static const struct scsi_host_template ahci_platform_sht = { |
510 | AHCI_SHT(DRV_NAME), |
511 | }; |
512 | |
513 | static int tegra_ahci_probe(struct platform_device *pdev) |
514 | { |
515 | struct ahci_host_priv *hpriv; |
516 | struct tegra_ahci_priv *tegra; |
517 | struct resource *res; |
518 | int ret; |
519 | |
520 | hpriv = ahci_platform_get_resources(pdev, flags: 0); |
521 | if (IS_ERR(ptr: hpriv)) |
522 | return PTR_ERR(ptr: hpriv); |
523 | |
524 | tegra = devm_kzalloc(dev: &pdev->dev, size: sizeof(*tegra), GFP_KERNEL); |
525 | if (!tegra) |
526 | return -ENOMEM; |
527 | |
528 | hpriv->plat_data = tegra; |
529 | |
530 | tegra->pdev = pdev; |
531 | tegra->soc = of_device_get_match_data(dev: &pdev->dev); |
532 | |
533 | tegra->sata_regs = devm_platform_ioremap_resource(pdev, index: 1); |
534 | if (IS_ERR(ptr: tegra->sata_regs)) |
535 | return PTR_ERR(ptr: tegra->sata_regs); |
536 | |
537 | /* |
538 | * AUX registers is optional. |
539 | */ |
540 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); |
541 | if (res) { |
542 | tegra->sata_aux_regs = devm_ioremap_resource(dev: &pdev->dev, res); |
543 | if (IS_ERR(ptr: tegra->sata_aux_regs)) |
544 | return PTR_ERR(ptr: tegra->sata_aux_regs); |
545 | } |
546 | |
547 | tegra->sata_rst = devm_reset_control_get(dev: &pdev->dev, id: "sata" ); |
548 | if (IS_ERR(ptr: tegra->sata_rst)) { |
549 | dev_err(&pdev->dev, "Failed to get sata reset\n" ); |
550 | return PTR_ERR(ptr: tegra->sata_rst); |
551 | } |
552 | |
553 | if (tegra->soc->has_sata_oob_rst) { |
554 | tegra->sata_oob_rst = devm_reset_control_get(dev: &pdev->dev, |
555 | id: "sata-oob" ); |
556 | if (IS_ERR(ptr: tegra->sata_oob_rst)) { |
557 | dev_err(&pdev->dev, "Failed to get sata-oob reset\n" ); |
558 | return PTR_ERR(ptr: tegra->sata_oob_rst); |
559 | } |
560 | } |
561 | |
562 | tegra->sata_cold_rst = devm_reset_control_get(dev: &pdev->dev, id: "sata-cold" ); |
563 | if (IS_ERR(ptr: tegra->sata_cold_rst)) { |
564 | dev_err(&pdev->dev, "Failed to get sata-cold reset\n" ); |
565 | return PTR_ERR(ptr: tegra->sata_cold_rst); |
566 | } |
567 | |
568 | tegra->sata_clk = devm_clk_get(dev: &pdev->dev, id: "sata" ); |
569 | if (IS_ERR(ptr: tegra->sata_clk)) { |
570 | dev_err(&pdev->dev, "Failed to get sata clock\n" ); |
571 | return PTR_ERR(ptr: tegra->sata_clk); |
572 | } |
573 | |
574 | tegra->supplies = devm_kcalloc(dev: &pdev->dev, |
575 | n: tegra->soc->num_supplies, |
576 | size: sizeof(*tegra->supplies), GFP_KERNEL); |
577 | if (!tegra->supplies) |
578 | return -ENOMEM; |
579 | |
580 | regulator_bulk_set_supply_names(consumers: tegra->supplies, |
581 | supply_names: tegra->soc->supply_names, |
582 | num_supplies: tegra->soc->num_supplies); |
583 | |
584 | ret = devm_regulator_bulk_get(dev: &pdev->dev, |
585 | num_consumers: tegra->soc->num_supplies, |
586 | consumers: tegra->supplies); |
587 | if (ret) { |
588 | dev_err(&pdev->dev, "Failed to get regulators\n" ); |
589 | return ret; |
590 | } |
591 | |
592 | ret = tegra_ahci_controller_init(hpriv); |
593 | if (ret) |
594 | return ret; |
595 | |
596 | ret = ahci_platform_init_host(pdev, hpriv, pi_template: &ahci_tegra_port_info, |
597 | sht: &ahci_platform_sht); |
598 | if (ret) |
599 | goto deinit_controller; |
600 | |
601 | return 0; |
602 | |
603 | deinit_controller: |
604 | tegra_ahci_controller_deinit(hpriv); |
605 | |
606 | return ret; |
607 | }; |
608 | |
609 | static struct platform_driver tegra_ahci_driver = { |
610 | .probe = tegra_ahci_probe, |
611 | .remove_new = ata_platform_remove_one, |
612 | .driver = { |
613 | .name = DRV_NAME, |
614 | .of_match_table = tegra_ahci_of_match, |
615 | }, |
616 | /* LP0 suspend support not implemented */ |
617 | }; |
618 | module_platform_driver(tegra_ahci_driver); |
619 | |
620 | MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>" ); |
621 | MODULE_DESCRIPTION("Tegra AHCI SATA driver" ); |
622 | MODULE_LICENSE("GPL v2" ); |
623 | |