Blame view

drivers/ata/ahci_tegra.c 17.7 KB
9c92ab619   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
ccfde5081   Mikko Perttunen   ata: Add support ...
2
3
4
5
6
7
8
  /*
   * drivers/ata/ahci_tegra.c
   *
   * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
   *
   * Author:
   *	Mikko Perttunen <mperttunen@nvidia.com>
ccfde5081   Mikko Perttunen   ata: Add support ...
9
10
11
   */
  
  #include <linux/ahci_platform.h>
ccfde5081   Mikko Perttunen   ata: Add support ...
12
13
14
15
16
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/of_device.h>
  #include <linux/platform_device.h>
ccfde5081   Mikko Perttunen   ata: Add support ...
17
  #include <linux/regulator/consumer.h>
e327f1154   Mikko Perttunen   ata: ahci_tegra: ...
18
19
20
  #include <linux/reset.h>
  
  #include <soc/tegra/fuse.h>
0e5740770   Mikko Perttunen   ata: ahci_tegra: ...
21
  #include <soc/tegra/pmc.h>
e327f1154   Mikko Perttunen   ata: ahci_tegra: ...
22

ccfde5081   Mikko Perttunen   ata: Add support ...
23
  #include "ahci.h"
018d5ef20   Akinobu Mita   ata: ahci_platfor...
24
  #define DRV_NAME "tegra-ahci"
ccfde5081   Mikko Perttunen   ata: Add support ...
25
  #define SATA_CONFIGURATION_0				0x180
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
26
27
  #define SATA_CONFIGURATION_0_EN_FPCI			BIT(0)
  #define SATA_CONFIGURATION_0_CLK_OVERRIDE			BIT(31)
ccfde5081   Mikko Perttunen   ata: Add support ...
28
29
30
31
32
33
34
35
36
37
  
  #define SCFG_OFFSET					0x1000
  
  #define T_SATA0_CFG_1					0x04
  #define T_SATA0_CFG_1_IO_SPACE				BIT(0)
  #define T_SATA0_CFG_1_MEMORY_SPACE			BIT(1)
  #define T_SATA0_CFG_1_BUS_MASTER			BIT(2)
  #define T_SATA0_CFG_1_SERR				BIT(8)
  
  #define T_SATA0_CFG_9					0x24
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
38
  #define T_SATA0_CFG_9_BASE_ADDRESS			0x40020000
ccfde5081   Mikko Perttunen   ata: Add support ...
39
40
  
  #define SATA_FPCI_BAR5					0x94
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
41
42
43
  #define SATA_FPCI_BAR5_START_MASK			(0xfffffff << 4)
  #define SATA_FPCI_BAR5_START				(0x0040020 << 4)
  #define SATA_FPCI_BAR5_ACCESS_TYPE			(0x1)
ccfde5081   Mikko Perttunen   ata: Add support ...
44
45
46
  
  #define SATA_INTR_MASK					0x188
  #define SATA_INTR_MASK_IP_INT_MASK			BIT(16)
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  #define T_SATA0_CFG_35					0x94
  #define T_SATA0_CFG_35_IDP_INDEX_MASK			(0x7ff << 2)
  #define T_SATA0_CFG_35_IDP_INDEX			(0x2a << 2)
  
  #define T_SATA0_AHCI_IDP1				0x98
  #define T_SATA0_AHCI_IDP1_DATA				(0x400040)
  
  #define T_SATA0_CFG_PHY_1				0x12c
  #define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN			BIT(23)
  #define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
  
  #define T_SATA0_NVOOB                                   0x114
  #define T_SATA0_NVOOB_COMMA_CNT_MASK                    (0xff << 16)
  #define T_SATA0_NVOOB_COMMA_CNT                         (0x07 << 16)
  #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK          (0x3 << 24)
  #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 24)
  #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK        (0x3 << 26)
  #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH             (0x3 << 26)
  
  #define T_SATA_CFG_PHY_0                                0x120
  #define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD     BIT(11)
  #define T_SATA_CFG_PHY_0_MASK_SQUELCH                   BIT(24)
  
  #define T_SATA0_CFG2NVOOB_2				0x134
  #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK	(0x1ff << 18)
  #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW	(0xc << 18)
ccfde5081   Mikko Perttunen   ata: Add support ...
73
  #define T_SATA0_AHCI_HBA_CAP_BKDR			0x300
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
74
75
76
77
78
  #define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP	BIT(13)
  #define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP	BIT(14)
  #define T_SATA0_AHCI_HBA_CAP_BKDR_SALP			BIT(26)
  #define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM		BIT(17)
  #define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ			BIT(30)
ccfde5081   Mikko Perttunen   ata: Add support ...
79
80
  
  #define T_SATA0_BKDOOR_CC				0x4a4
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
81
82
83
84
  #define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK		(0xffff << 16)
  #define T_SATA0_BKDOOR_CC_CLASS_CODE			(0x0106 << 16)
  #define T_SATA0_BKDOOR_CC_PROG_IF_MASK			(0xff << 8)
  #define T_SATA0_BKDOOR_CC_PROG_IF			(0x01 << 8)
ccfde5081   Mikko Perttunen   ata: Add support ...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  
  #define T_SATA0_CFG_SATA				0x54c
  #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN		BIT(12)
  
  #define T_SATA0_CFG_MISC				0x550
  
  #define T_SATA0_INDEX					0x680
  
  #define T_SATA0_CHX_PHY_CTRL1_GEN1			0x690
  #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK		0xff
  #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT		0
  #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK		(0xff << 8)
  #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT	8
  
  #define T_SATA0_CHX_PHY_CTRL1_GEN2			0x694
  #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK		0xff
  #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT		0
  #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK		(0xff << 12)
  #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT	12
  
  #define T_SATA0_CHX_PHY_CTRL2				0x69c
  #define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1		0x23
  
  #define T_SATA0_CHX_PHY_CTRL11				0x6d0
  #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ		(0x2800 << 16)
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  #define T_SATA0_CHX_PHY_CTRL17_0			0x6e8
  #define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1	0x55010000
  #define T_SATA0_CHX_PHY_CTRL18_0			0x6ec
  #define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2	0x55010000
  #define T_SATA0_CHX_PHY_CTRL20_0			0x6f4
  #define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1	0x1
  #define T_SATA0_CHX_PHY_CTRL21_0			0x6f8
  #define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2	0x1
  
  /* AUX Registers */
  #define SATA_AUX_MISC_CNTL_1_0				0x8
  #define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE		BIT(17)
  #define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT		BIT(13)
  #define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT		BIT(15)
  
  #define SATA_AUX_RX_STAT_INT_0				0xc
  #define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP		BIT(7)
  
  #define SATA_AUX_SPARE_CFG0_0				0x18
  #define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID	BIT(14)
ccfde5081   Mikko Perttunen   ata: Add support ...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  #define FUSE_SATA_CALIB					0x124
  #define FUSE_SATA_CALIB_MASK				0x3
  
  struct sata_pad_calibration {
  	u8 gen1_tx_amp;
  	u8 gen1_tx_peak;
  	u8 gen2_tx_amp;
  	u8 gen2_tx_peak;
  };
  
  static const struct sata_pad_calibration tegra124_pad_calibration[] = {
  	{0x18, 0x04, 0x18, 0x0a},
  	{0x0e, 0x04, 0x14, 0x0a},
  	{0x0e, 0x07, 0x1a, 0x0e},
  	{0x14, 0x0e, 0x1a, 0x0e},
  };
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
146
147
148
149
150
  struct tegra_ahci_ops {
  	int (*init)(struct ahci_host_priv *hpriv);
  };
  
  struct tegra_ahci_soc {
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
151
152
  	const char *const		*supply_names;
  	u32				num_supplies;
502717ccf   Preetham Ramchandra   ata: ahci_tegra: ...
153
  	bool				supports_devslp;
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
154
155
  	const struct tegra_ahci_ops	*ops;
  };
ccfde5081   Mikko Perttunen   ata: Add support ...
156
157
158
  struct tegra_ahci_priv {
  	struct platform_device	   *pdev;
  	void __iomem		   *sata_regs;
502717ccf   Preetham Ramchandra   ata: ahci_tegra: ...
159
  	void __iomem		   *sata_aux_regs;
ccfde5081   Mikko Perttunen   ata: Add support ...
160
161
162
163
164
  	struct reset_control	   *sata_rst;
  	struct reset_control	   *sata_oob_rst;
  	struct reset_control	   *sata_cold_rst;
  	/* Needs special handling, cannot use ahci_platform */
  	struct clk		   *sata_clk;
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
165
  	struct regulator_bulk_data *supplies;
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
166
  	const struct tegra_ahci_soc *soc;
ccfde5081   Mikko Perttunen   ata: Add support ...
167
  };
502717ccf   Preetham Ramchandra   ata: ahci_tegra: ...
168
169
170
171
172
173
174
175
176
177
178
  static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv)
  {
  	struct tegra_ahci_priv *tegra = hpriv->plat_data;
  	u32 val;
  
  	if (tegra->sata_aux_regs && !tegra->soc->supports_devslp) {
  		val = readl(tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
  		val &= ~SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT;
  		writel(val, tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
  	}
  }
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
  {
  	struct tegra_ahci_priv *tegra = hpriv->plat_data;
  	struct sata_pad_calibration calib;
  	int ret;
  	u32 val;
  
  	/* Pad calibration */
  	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
  	if (ret)
  		return ret;
  
  	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
  
  	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
  
  	val = readl(tegra->sata_regs +
  		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
  	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
  	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
  	val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
  	val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
  	writel(val, tegra->sata_regs + SCFG_OFFSET +
  	       T_SATA0_CHX_PHY_CTRL1_GEN1);
  
  	val = readl(tegra->sata_regs +
  		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
  	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
  	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
  	val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
  	val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
  	writel(val, tegra->sata_regs + SCFG_OFFSET +
  	       T_SATA0_CHX_PHY_CTRL1_GEN2);
  
  	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
  	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
  	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
  	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
  
  	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
  
  	return 0;
  }
ccfde5081   Mikko Perttunen   ata: Add support ...
222
223
224
225
  static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
  {
  	struct tegra_ahci_priv *tegra = hpriv->plat_data;
  	int ret;
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
226
  	ret = regulator_bulk_enable(tegra->soc->num_supplies,
ccfde5081   Mikko Perttunen   ata: Add support ...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  				    tegra->supplies);
  	if (ret)
  		return ret;
  
  	ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
  						tegra->sata_clk,
  						tegra->sata_rst);
  	if (ret)
  		goto disable_regulators;
  
  	reset_control_assert(tegra->sata_oob_rst);
  	reset_control_assert(tegra->sata_cold_rst);
  
  	ret = ahci_platform_enable_resources(hpriv);
  	if (ret)
  		goto disable_power;
  
  	reset_control_deassert(tegra->sata_cold_rst);
  	reset_control_deassert(tegra->sata_oob_rst);
  
  	return 0;
  
  disable_power:
  	clk_disable_unprepare(tegra->sata_clk);
  
  	tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
  
  disable_regulators:
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
255
  	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
ccfde5081   Mikko Perttunen   ata: Add support ...
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  
  	return ret;
  }
  
  static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
  {
  	struct tegra_ahci_priv *tegra = hpriv->plat_data;
  
  	ahci_platform_disable_resources(hpriv);
  
  	reset_control_assert(tegra->sata_rst);
  	reset_control_assert(tegra->sata_oob_rst);
  	reset_control_assert(tegra->sata_cold_rst);
  
  	clk_disable_unprepare(tegra->sata_clk);
  	tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
272
  	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
ccfde5081   Mikko Perttunen   ata: Add support ...
273
274
275
276
277
278
  }
  
  static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
  {
  	struct tegra_ahci_priv *tegra = hpriv->plat_data;
  	int ret;
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
279
  	u32 val;
ccfde5081   Mikko Perttunen   ata: Add support ...
280
281
282
283
284
285
286
287
  
  	ret = tegra_ahci_power_on(hpriv);
  	if (ret) {
  		dev_err(&tegra->pdev->dev,
  			"failed to power on AHCI controller: %d
  ", ret);
  		return ret;
  	}
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
288
289
290
291
292
293
294
295
296
297
  	/*
  	 * Program the following SATA IPFS registers to allow SW accesses to
  	 * SATA's MMIO register range.
  	 */
  	val = readl(tegra->sata_regs + SATA_FPCI_BAR5);
  	val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE);
  	val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE;
  	writel(val, tegra->sata_regs + SATA_FPCI_BAR5);
  
  	/* Program the following SATA IPFS register to enable the SATA */
ccfde5081   Mikko Perttunen   ata: Add support ...
298
  	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
299
  	val |= SATA_CONFIGURATION_0_EN_FPCI;
ccfde5081   Mikko Perttunen   ata: Add support ...
300
  	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  	/* Electrical settings for better link stability */
  	val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0);
  	val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0);
  	val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0);
  	val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0);
  
  	/* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */
  
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
  	val |= T_SATA_CFG_PHY_0_MASK_SQUELCH;
  	val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
  
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
  	val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK |
  		 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
  		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
  	val |= (T_SATA0_NVOOB_COMMA_CNT |
  		T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
  		T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
  
  	/*
  	 * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns
  	 */
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
  	val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
  	val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
  
  	if (tegra->soc->ops && tegra->soc->ops->init)
  		tegra->soc->ops->init(hpriv);
  
  	/*
  	 * Program the following SATA configuration registers to
  	 * initialize SATA
  	 */
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
  	val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
  		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR);
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
  	val = T_SATA0_CFG_9_BASE_ADDRESS;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
ccfde5081   Mikko Perttunen   ata: Add support ...
348

56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
349
  	/* Program Class Code and Programming interface for SATA */
ccfde5081   Mikko Perttunen   ata: Add support ...
350
351
352
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
  	val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
353
354
355
356
357
358
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
  	val &=
  	    ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK |
  	      T_SATA0_BKDOOR_CC_PROG_IF_MASK);
  	val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
ccfde5081   Mikko Perttunen   ata: Add support ...
359
360
361
362
  
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
  	val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
  	/* Enabling LPM capabilities through Backdoor Programming */
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
  	val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP |
  		T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP |
  		T_SATA0_AHCI_HBA_CAP_BKDR_SALP |
  		T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM);
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
  
  	/* SATA Second Level Clock Gating configuration
  	 * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane
  	 * IDDQ Signals
  	 */
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
  	val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK;
  	val |= T_SATA0_CFG_35_IDP_INDEX;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
  
  	val = T_SATA0_AHCI_IDP1_DATA;
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1);
  
  	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
  	val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN |
  		T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN);
  	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
  
  	/* Enabling IPFS Clock Gating */
  	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
  	val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE;
  	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
ccfde5081   Mikko Perttunen   ata: Add support ...
392

502717ccf   Preetham Ramchandra   ata: ahci_tegra: ...
393
  	tegra_ahci_handle_quirks(hpriv);
ccfde5081   Mikko Perttunen   ata: Add support ...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  
  	/* Unmask SATA interrupts */
  
  	val = readl(tegra->sata_regs + SATA_INTR_MASK);
  	val |= SATA_INTR_MASK_IP_INT_MASK;
  	writel(val, tegra->sata_regs + SATA_INTR_MASK);
  
  	return 0;
  }
  
  static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
  {
  	tegra_ahci_power_off(hpriv);
  }
  
  static void tegra_ahci_host_stop(struct ata_host *host)
  {
  	struct ahci_host_priv *hpriv = host->private_data;
  
  	tegra_ahci_controller_deinit(hpriv);
  }
  
  static struct ata_port_operations ahci_tegra_port_ops = {
  	.inherits	= &ahci_ops,
  	.host_stop	= tegra_ahci_host_stop,
  };
  
  static const struct ata_port_info ahci_tegra_port_info = {
01fbf60b0   Preetham Ramchandra   ata: ahci_tegra: ...
422
  	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
ccfde5081   Mikko Perttunen   ata: Add support ...
423
424
425
426
  	.pio_mask	= ATA_PIO4,
  	.udma_mask	= ATA_UDMA6,
  	.port_ops	= &ahci_tegra_port_ops,
  };
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
427
428
429
  static const char *const tegra124_supply_names[] = {
  	"avdd", "hvdd", "vddio", "target-5v", "target-12v"
  };
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
430
431
432
433
434
  static const struct tegra_ahci_ops tegra124_ahci_ops = {
  	.init = tegra124_ahci_init,
  };
  
  static const struct tegra_ahci_soc tegra124_ahci_soc = {
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
435
436
  	.supply_names = tegra124_supply_names,
  	.num_supplies = ARRAY_SIZE(tegra124_supply_names),
502717ccf   Preetham Ramchandra   ata: ahci_tegra: ...
437
  	.supports_devslp = false,
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
438
439
  	.ops = &tegra124_ahci_ops,
  };
294840fee   Preetham Ramchandra   ata: ahci_tegra: ...
440
441
442
  static const struct tegra_ahci_soc tegra210_ahci_soc = {
  	.supports_devslp = false,
  };
ccfde5081   Mikko Perttunen   ata: Add support ...
443
  static const struct of_device_id tegra_ahci_of_match[] = {
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
444
445
446
447
  	{
  		.compatible = "nvidia,tegra124-ahci",
  		.data = &tegra124_ahci_soc
  	},
294840fee   Preetham Ramchandra   ata: ahci_tegra: ...
448
449
450
451
  	{
  		.compatible = "nvidia,tegra210-ahci",
  		.data = &tegra210_ahci_soc
  	},
ccfde5081   Mikko Perttunen   ata: Add support ...
452
453
454
  	{}
  };
  MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
018d5ef20   Akinobu Mita   ata: ahci_platfor...
455
456
457
  static struct scsi_host_template ahci_platform_sht = {
  	AHCI_SHT(DRV_NAME),
  };
ccfde5081   Mikko Perttunen   ata: Add support ...
458
459
460
461
462
463
  static int tegra_ahci_probe(struct platform_device *pdev)
  {
  	struct ahci_host_priv *hpriv;
  	struct tegra_ahci_priv *tegra;
  	struct resource *res;
  	int ret;
16af2d658   Kunihiko Hayashi   ata: add an extra...
464
  	hpriv = ahci_platform_get_resources(pdev, 0);
ccfde5081   Mikko Perttunen   ata: Add support ...
465
466
467
468
469
470
471
472
473
474
  	if (IS_ERR(hpriv))
  		return PTR_ERR(hpriv);
  
  	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
  	if (!tegra)
  		return -ENOMEM;
  
  	hpriv->plat_data = tegra;
  
  	tegra->pdev = pdev;
56337b557   Preetham Ramchandra   ata: ahci_tegra: ...
475
  	tegra->soc = of_device_get_match_data(&pdev->dev);
ccfde5081   Mikko Perttunen   ata: Add support ...
476
477
478
479
480
  
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  	tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);
  	if (IS_ERR(tegra->sata_regs))
  		return PTR_ERR(tegra->sata_regs);
502717ccf   Preetham Ramchandra   ata: ahci_tegra: ...
481
482
483
484
485
486
487
488
489
  	/*
  	 * AUX registers is optional.
  	 */
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
  	if (res) {
  		tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res);
  		if (IS_ERR(tegra->sata_aux_regs))
  			return PTR_ERR(tegra->sata_aux_regs);
  	}
ccfde5081   Mikko Perttunen   ata: Add support ...
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
  	tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
  	if (IS_ERR(tegra->sata_rst)) {
  		dev_err(&pdev->dev, "Failed to get sata reset
  ");
  		return PTR_ERR(tegra->sata_rst);
  	}
  
  	tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, "sata-oob");
  	if (IS_ERR(tegra->sata_oob_rst)) {
  		dev_err(&pdev->dev, "Failed to get sata-oob reset
  ");
  		return PTR_ERR(tegra->sata_oob_rst);
  	}
  
  	tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
  	if (IS_ERR(tegra->sata_cold_rst)) {
  		dev_err(&pdev->dev, "Failed to get sata-cold reset
  ");
  		return PTR_ERR(tegra->sata_cold_rst);
  	}
  
  	tegra->sata_clk = devm_clk_get(&pdev->dev, "sata");
  	if (IS_ERR(tegra->sata_clk)) {
  		dev_err(&pdev->dev, "Failed to get sata clock
  ");
  		return PTR_ERR(tegra->sata_clk);
  	}
43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
517
518
519
520
521
  	tegra->supplies = devm_kcalloc(&pdev->dev,
  				       tegra->soc->num_supplies,
  				       sizeof(*tegra->supplies), GFP_KERNEL);
  	if (!tegra->supplies)
  		return -ENOMEM;
e964a17d8   Bartosz Golaszewski   ahci: tegra: use ...
522
523
524
  	regulator_bulk_set_supply_names(tegra->supplies,
  					tegra->soc->supply_names,
  					tegra->soc->num_supplies);
ccfde5081   Mikko Perttunen   ata: Add support ...
525

43ee827b5   Preetham Ramchandra   ata: ahci_tegra: ...
526
527
  	ret = devm_regulator_bulk_get(&pdev->dev,
  				      tegra->soc->num_supplies,
ccfde5081   Mikko Perttunen   ata: Add support ...
528
529
530
531
532
533
534
535
536
537
  				      tegra->supplies);
  	if (ret) {
  		dev_err(&pdev->dev, "Failed to get regulators
  ");
  		return ret;
  	}
  
  	ret = tegra_ahci_controller_init(hpriv);
  	if (ret)
  		return ret;
018d5ef20   Akinobu Mita   ata: ahci_platfor...
538
539
  	ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
  				      &ahci_platform_sht);
ccfde5081   Mikko Perttunen   ata: Add support ...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
  	if (ret)
  		goto deinit_controller;
  
  	return 0;
  
  deinit_controller:
  	tegra_ahci_controller_deinit(hpriv);
  
  	return ret;
  };
  
  static struct platform_driver tegra_ahci_driver = {
  	.probe = tegra_ahci_probe,
  	.remove = ata_platform_remove_one,
  	.driver = {
018d5ef20   Akinobu Mita   ata: ahci_platfor...
555
  		.name = DRV_NAME,
ccfde5081   Mikko Perttunen   ata: Add support ...
556
557
558
559
560
561
562
  		.of_match_table = tegra_ahci_of_match,
  	},
  	/* LP0 suspend support not implemented */
  };
  module_platform_driver(tegra_ahci_driver);
  
  MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
294840fee   Preetham Ramchandra   ata: ahci_tegra: ...
563
  MODULE_DESCRIPTION("Tegra AHCI SATA driver");
ccfde5081   Mikko Perttunen   ata: Add support ...
564
  MODULE_LICENSE("GPL v2");