aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2013-11-25 03:47:02 -0500
committerTejun Heo <tj@kernel.org>2013-12-03 07:40:58 -0500
commit4a23d1793f8e268e5867eec6c20abe78ec28ba5f (patch)
treea7fc04702f21c2b8fac9d3bb6480cc48a8b86ec0 /drivers/ata
parent8403e2ec8d4c759f821996d3bc43ca7c512ac9a0 (diff)
ahci: imx: Add i.MX53 support
Add minor adjustments to support i.MX53 SATA port as well as i.MX6Q one. The difference here is mostly the clock which need to be enabled and also the lack of need of programming IOMUXC registers on i.MX53. All of which is well handles in the clock enable/disable functions. Note that this patch also cleans up the names of the common functions, so they don't read imx6q_* but imx_* instead. Signed-off-by: Marek Vasut <marex@denx.de> Reviewed-by: Shawn Guo <shawn.guo@linaro.org> Cc: Richard Zhu <r65037@freescale.com> Cc: Linux-IDE <linux-ide@vger.kernel.org> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci_imx.c180
1 files changed, 122 insertions, 58 deletions
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 6214411349de..8cb89655cf06 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -34,10 +34,21 @@ enum {
34 HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ 34 HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
35}; 35};
36 36
37enum ahci_imx_type {
38 AHCI_IMX53,
39 AHCI_IMX6Q,
40};
41
37struct imx_ahci_priv { 42struct imx_ahci_priv {
38 struct platform_device *ahci_pdev; 43 struct platform_device *ahci_pdev;
44 enum ahci_imx_type type;
45
46 /* i.MX53 clock */
47 struct clk *sata_gate_clk;
48 /* Common clock */
39 struct clk *sata_ref_clk; 49 struct clk *sata_ref_clk;
40 struct clk *ahb_clk; 50 struct clk *ahb_clk;
51
41 struct regmap *gpr; 52 struct regmap *gpr;
42 bool no_device; 53 bool no_device;
43 bool first_time; 54 bool first_time;
@@ -52,29 +63,52 @@ static int imx_sata_clock_enable(struct device *dev)
52 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); 63 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
53 int ret; 64 int ret;
54 65
66 if (imxpriv->type == AHCI_IMX53) {
67 ret = clk_prepare_enable(imxpriv->sata_gate_clk);
68 if (ret < 0) {
69 dev_err(dev, "prepare-enable sata_gate clock err:%d\n",
70 ret);
71 return ret;
72 }
73 }
74
55 ret = clk_prepare_enable(imxpriv->sata_ref_clk); 75 ret = clk_prepare_enable(imxpriv->sata_ref_clk);
56 if (ret < 0) { 76 if (ret < 0) {
57 dev_err(dev, "prepare-enable sata_ref clock err:%d\n", ret); 77 dev_err(dev, "prepare-enable sata_ref clock err:%d\n",
58 return ret; 78 ret);
79 goto clk_err;
59 } 80 }
60 81
61 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 82 if (imxpriv->type == AHCI_IMX6Q) {
62 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 83 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
63 IMX6Q_GPR13_SATA_MPLL_CLK_EN); 84 IMX6Q_GPR13_SATA_MPLL_CLK_EN,
85 IMX6Q_GPR13_SATA_MPLL_CLK_EN);
86 }
64 87
65 usleep_range(1000, 2000); 88 usleep_range(1000, 2000);
66 89
67 return 0; 90 return 0;
91
92clk_err:
93 if (imxpriv->type == AHCI_IMX53)
94 clk_disable_unprepare(imxpriv->sata_gate_clk);
95 return ret;
68} 96}
69 97
70static void imx_sata_clock_disable(struct device *dev) 98static void imx_sata_clock_disable(struct device *dev)
71{ 99{
72 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); 100 struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
73 101
74 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, 102 if (imxpriv->type == AHCI_IMX6Q) {
75 IMX6Q_GPR13_SATA_MPLL_CLK_EN, 103 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
76 !IMX6Q_GPR13_SATA_MPLL_CLK_EN); 104 IMX6Q_GPR13_SATA_MPLL_CLK_EN,
105 !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
106 }
107
77 clk_disable_unprepare(imxpriv->sata_ref_clk); 108 clk_disable_unprepare(imxpriv->sata_ref_clk);
109
110 if (imxpriv->type == AHCI_IMX53)
111 clk_disable_unprepare(imxpriv->sata_gate_clk);
78} 112}
79 113
80static void ahci_imx_error_handler(struct ata_port *ap) 114static void ahci_imx_error_handler(struct ata_port *ap)
@@ -106,9 +140,25 @@ static void ahci_imx_error_handler(struct ata_port *ap)
106 imxpriv->no_device = true; 140 imxpriv->no_device = true;
107} 141}
108 142
143int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
144 unsigned long deadline)
145{
146 struct ata_port *ap = link->ap;
147 struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
148 int ret = -EIO;
149
150 if (imxpriv->type == AHCI_IMX53)
151 ret = ahci_pmp_retry_srst_ops.softreset(link, class, deadline);
152 else if (imxpriv->type == AHCI_IMX6Q)
153 ret = ahci_ops.softreset(link, class, deadline);
154
155 return ret;
156}
157
109static struct ata_port_operations ahci_imx_ops = { 158static struct ata_port_operations ahci_imx_ops = {
110 .inherits = &ahci_platform_ops, 159 .inherits = &ahci_platform_ops,
111 .error_handler = ahci_imx_error_handler, 160 .error_handler = ahci_imx_error_handler,
161 .softreset = ahci_imx_softreset,
112}; 162};
113 163
114static const struct ata_port_info ahci_imx_port_info = { 164static const struct ata_port_info ahci_imx_port_info = {
@@ -118,7 +168,7 @@ static const struct ata_port_info ahci_imx_port_info = {
118 .port_ops = &ahci_imx_ops, 168 .port_ops = &ahci_imx_ops,
119}; 169};
120 170
121static int imx6q_sata_init(struct device *dev, void __iomem *mmio) 171static int imx_sata_init(struct device *dev, void __iomem *mmio)
122{ 172{
123 int ret = 0; 173 int ret = 0;
124 unsigned int reg_val; 174 unsigned int reg_val;
@@ -152,7 +202,7 @@ static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
152 return 0; 202 return 0;
153} 203}
154 204
155static void imx6q_sata_exit(struct device *dev) 205static void imx_sata_exit(struct device *dev)
156{ 206{
157 imx_sata_clock_disable(dev); 207 imx_sata_clock_disable(dev);
158} 208}
@@ -182,16 +232,18 @@ static int imx_ahci_resume(struct device *dev)
182 return ret; 232 return ret;
183} 233}
184 234
185static struct ahci_platform_data imx6q_sata_pdata = { 235static struct ahci_platform_data imx_sata_pdata = {
186 .init = imx6q_sata_init, 236 .init = imx_sata_init,
187 .exit = imx6q_sata_exit, 237 .exit = imx_sata_exit,
188 .ata_port_info = &ahci_imx_port_info, 238 .ata_port_info = &ahci_imx_port_info,
189 .suspend = imx_ahci_suspend, 239 .suspend = imx_ahci_suspend,
190 .resume = imx_ahci_resume, 240 .resume = imx_ahci_resume,
241
191}; 242};
192 243
193static const struct of_device_id imx_ahci_of_match[] = { 244static const struct of_device_id imx_ahci_of_match[] = {
194 { .compatible = "fsl,imx6q-ahci", .data = &imx6q_sata_pdata}, 245 { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
246 { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
195 {}, 247 {},
196}; 248};
197MODULE_DEVICE_TABLE(of, imx_ahci_of_match); 249MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
@@ -201,12 +253,20 @@ static int imx_ahci_probe(struct platform_device *pdev)
201 struct device *dev = &pdev->dev; 253 struct device *dev = &pdev->dev;
202 struct resource *mem, *irq, res[2]; 254 struct resource *mem, *irq, res[2];
203 const struct of_device_id *of_id; 255 const struct of_device_id *of_id;
256 enum ahci_imx_type type;
204 const struct ahci_platform_data *pdata = NULL; 257 const struct ahci_platform_data *pdata = NULL;
205 struct imx_ahci_priv *imxpriv; 258 struct imx_ahci_priv *imxpriv;
206 struct device *ahci_dev; 259 struct device *ahci_dev;
207 struct platform_device *ahci_pdev; 260 struct platform_device *ahci_pdev;
208 int ret; 261 int ret;
209 262
263 of_id = of_match_device(imx_ahci_of_match, dev);
264 if (!of_id)
265 return -EINVAL;
266
267 type = (enum ahci_imx_type)of_id->data;
268 pdata = &imx_sata_pdata;
269
210 imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL); 270 imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
211 if (!imxpriv) { 271 if (!imxpriv) {
212 dev_err(dev, "can't alloc ahci_host_priv\n"); 272 dev_err(dev, "can't alloc ahci_host_priv\n");
@@ -222,6 +282,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
222 282
223 imxpriv->no_device = false; 283 imxpriv->no_device = false;
224 imxpriv->first_time = true; 284 imxpriv->first_time = true;
285 imxpriv->type = type;
286
225 imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); 287 imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
226 if (IS_ERR(imxpriv->ahb_clk)) { 288 if (IS_ERR(imxpriv->ahb_clk)) {
227 dev_err(dev, "can't get ahb clock.\n"); 289 dev_err(dev, "can't get ahb clock.\n");
@@ -229,6 +291,15 @@ static int imx_ahci_probe(struct platform_device *pdev)
229 goto err_out; 291 goto err_out;
230 } 292 }
231 293
294 if (type == AHCI_IMX53) {
295 imxpriv->sata_gate_clk = devm_clk_get(dev, "sata_gate");
296 if (IS_ERR(imxpriv->sata_gate_clk)) {
297 dev_err(dev, "can't get sata_gate clock.\n");
298 ret = PTR_ERR(imxpriv->sata_gate_clk);
299 goto err_out;
300 }
301 }
302
232 imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref"); 303 imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
233 if (IS_ERR(imxpriv->sata_ref_clk)) { 304 if (IS_ERR(imxpriv->sata_ref_clk)) {
234 dev_err(dev, "can't get sata_ref clock.\n"); 305 dev_err(dev, "can't get sata_ref clock.\n");
@@ -239,14 +310,6 @@ static int imx_ahci_probe(struct platform_device *pdev)
239 imxpriv->ahci_pdev = ahci_pdev; 310 imxpriv->ahci_pdev = ahci_pdev;
240 platform_set_drvdata(pdev, imxpriv); 311 platform_set_drvdata(pdev, imxpriv);
241 312
242 of_id = of_match_device(imx_ahci_of_match, dev);
243 if (of_id) {
244 pdata = of_id->data;
245 } else {
246 ret = -EINVAL;
247 goto err_out;
248 }
249
250 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 313 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
251 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 314 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
252 if (!mem || !irq) { 315 if (!mem || !irq) {
@@ -262,41 +325,42 @@ static int imx_ahci_probe(struct platform_device *pdev)
262 ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask; 325 ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
263 ahci_dev->of_node = dev->of_node; 326 ahci_dev->of_node = dev->of_node;
264 327
265 imxpriv->gpr = 328 if (type == AHCI_IMX6Q) {
266 syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); 329 imxpriv->gpr = syscon_regmap_lookup_by_compatible(
267 330 "fsl,imx6q-iomuxc-gpr");
268 if (IS_ERR(imxpriv->gpr)) { 331 if (IS_ERR(imxpriv->gpr)) {
269 dev_err(dev, "failed to find fsl,imx6q-iomux-gpr regmap\n"); 332 dev_err(dev,
270 ret = PTR_ERR(imxpriv->gpr); 333 "failed to find fsl,imx6q-iomux-gpr regmap\n");
271 goto err_out; 334 return PTR_ERR(imxpriv->gpr);
335 }
336
337 /*
338 * Set PHY Paremeters, two steps to configure the GPR13,
339 * one write for rest of parameters, mask of first write
340 * is 0x07fffffe, and the other one write for setting
341 * the mpll_clk_en happens in imx_sata_clock_enable().
342 */
343 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
344 IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
345 IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
346 IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
347 IMX6Q_GPR13_SATA_SPD_MODE_MASK |
348 IMX6Q_GPR13_SATA_MPLL_SS_EN |
349 IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
350 IMX6Q_GPR13_SATA_TX_BOOST_MASK |
351 IMX6Q_GPR13_SATA_TX_LVL_MASK |
352 IMX6Q_GPR13_SATA_MPLL_CLK_EN |
353 IMX6Q_GPR13_SATA_TX_EDGE_RATE,
354 IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB |
355 IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
356 IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
357 IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
358 IMX6Q_GPR13_SATA_MPLL_SS_EN |
359 IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
360 IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
361 IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
272 } 362 }
273 363
274 /*
275 * Set PHY Paremeters, two steps to configure the GPR13,
276 * one write for rest of parameters, mask of first write
277 * is 0x07ffffff, and the other one write for setting
278 * the mpll_clk_en happens in imx_sata_clock_enable().
279 */
280 regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
281 IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
282 IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
283 IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
284 IMX6Q_GPR13_SATA_SPD_MODE_MASK |
285 IMX6Q_GPR13_SATA_MPLL_SS_EN |
286 IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
287 IMX6Q_GPR13_SATA_TX_BOOST_MASK |
288 IMX6Q_GPR13_SATA_TX_LVL_MASK |
289 IMX6Q_GPR13_SATA_MPLL_CLK_EN |
290 IMX6Q_GPR13_SATA_TX_EDGE_RATE,
291 IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB |
292 IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
293 IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
294 IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
295 IMX6Q_GPR13_SATA_MPLL_SS_EN |
296 IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
297 IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
298 IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
299
300 ret = platform_device_add_resources(ahci_pdev, res, 2); 364 ret = platform_device_add_resources(ahci_pdev, res, 2);
301 if (ret) 365 if (ret)
302 goto err_out; 366 goto err_out;