Merge branch 'nvme-5.2-rc2' of git://git.infradead.org/nvme into for-linus
[linux-2.6-microblaze.git] / drivers / ata / ahci_qoriq.c
1 /*
2  * Freescale QorIQ AHCI SATA platform driver
3  *
4  * Copyright 2015 Freescale, Inc.
5  *   Tang Yuantian <Yuantian.Tang@freescale.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/pm.h>
16 #include <linux/ahci_platform.h>
17 #include <linux/device.h>
18 #include <linux/of_address.h>
19 #include <linux/of.h>
20 #include <linux/of_device.h>
21 #include <linux/platform_device.h>
22 #include <linux/libata.h>
23 #include "ahci.h"
24
25 #define DRV_NAME "ahci-qoriq"
26
27 /* port register definition */
28 #define PORT_PHY1       0xA8
29 #define PORT_PHY2       0xAC
30 #define PORT_PHY3       0xB0
31 #define PORT_PHY4       0xB4
32 #define PORT_PHY5       0xB8
33 #define PORT_AXICC      0xBC
34 #define PORT_TRANS      0xC8
35
36 /* port register default value */
37 #define AHCI_PORT_PHY_1_CFG     0xa003fffe
38 #define AHCI_PORT_PHY2_CFG      0x28184d1f
39 #define AHCI_PORT_PHY3_CFG      0x0e081509
40 #define AHCI_PORT_TRANS_CFG     0x08000029
41 #define AHCI_PORT_AXICC_CFG     0x3fffffff
42
43 /* for ls1021a */
44 #define LS1021A_PORT_PHY2       0x28183414
45 #define LS1021A_PORT_PHY3       0x0e080e06
46 #define LS1021A_PORT_PHY4       0x064a080b
47 #define LS1021A_PORT_PHY5       0x2aa86470
48 #define LS1021A_AXICC_ADDR      0xC0
49
50 #define SATA_ECC_DISABLE        0x00020000
51 #define ECC_DIS_ARMV8_CH2       0x80000000
52 #define ECC_DIS_LS1088A         0x40000000
53
54 enum ahci_qoriq_type {
55         AHCI_LS1021A,
56         AHCI_LS1028A,
57         AHCI_LS1043A,
58         AHCI_LS2080A,
59         AHCI_LS1046A,
60         AHCI_LS1088A,
61         AHCI_LS2088A,
62         AHCI_LX2160A,
63 };
64
65 struct ahci_qoriq_priv {
66         struct ccsr_ahci *reg_base;
67         enum ahci_qoriq_type type;
68         void __iomem *ecc_addr;
69         bool is_dmacoherent;
70 };
71
72 static bool ecc_initialized;
73
74 static const struct of_device_id ahci_qoriq_of_match[] = {
75         { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
76         { .compatible = "fsl,ls1028a-ahci", .data = (void *)AHCI_LS1028A},
77         { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
78         { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
79         { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
80         { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
81         { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
82         { .compatible = "fsl,lx2160a-ahci", .data = (void *)AHCI_LX2160A},
83         {},
84 };
85 MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
86
87 static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class,
88                           unsigned long deadline)
89 {
90         const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
91         void __iomem *port_mmio = ahci_port_base(link->ap);
92         u32 px_cmd, px_is, px_val;
93         struct ata_port *ap = link->ap;
94         struct ahci_port_priv *pp = ap->private_data;
95         struct ahci_host_priv *hpriv = ap->host->private_data;
96         struct ahci_qoriq_priv *qoriq_priv = hpriv->plat_data;
97         u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
98         struct ata_taskfile tf;
99         bool online;
100         int rc;
101         bool ls1021a_workaround = (qoriq_priv->type == AHCI_LS1021A);
102
103         DPRINTK("ENTER\n");
104
105         hpriv->stop_engine(ap);
106
107         /*
108          * There is a errata on ls1021a Rev1.0 and Rev2.0 which is:
109          * A-009042: The device detection initialization sequence
110          * mistakenly resets some registers.
111          *
112          * Workaround for this is:
113          * The software should read and store PxCMD and PxIS values
114          * before issuing the device detection initialization sequence.
115          * After the sequence is complete, software should restore the
116          * PxCMD and PxIS with the stored values.
117          */
118         if (ls1021a_workaround) {
119                 px_cmd = readl(port_mmio + PORT_CMD);
120                 px_is = readl(port_mmio + PORT_IRQ_STAT);
121         }
122
123         /* clear D2H reception area to properly wait for D2H FIS */
124         ata_tf_init(link->device, &tf);
125         tf.command = ATA_BUSY;
126         ata_tf_to_fis(&tf, 0, 0, d2h_fis);
127
128         rc = sata_link_hardreset(link, timing, deadline, &online,
129                                  ahci_check_ready);
130
131         /* restore the PxCMD and PxIS on ls1021 */
132         if (ls1021a_workaround) {
133                 px_val = readl(port_mmio + PORT_CMD);
134                 if (px_val != px_cmd)
135                         writel(px_cmd, port_mmio + PORT_CMD);
136
137                 px_val = readl(port_mmio + PORT_IRQ_STAT);
138                 if (px_val != px_is)
139                         writel(px_is, port_mmio + PORT_IRQ_STAT);
140         }
141
142         hpriv->start_engine(ap);
143
144         if (online)
145                 *class = ahci_dev_classify(ap);
146
147         DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
148         return rc;
149 }
150
151 static struct ata_port_operations ahci_qoriq_ops = {
152         .inherits       = &ahci_ops,
153         .hardreset      = ahci_qoriq_hardreset,
154 };
155
156 static const struct ata_port_info ahci_qoriq_port_info = {
157         .flags          = AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
158         .pio_mask       = ATA_PIO4,
159         .udma_mask      = ATA_UDMA6,
160         .port_ops       = &ahci_qoriq_ops,
161 };
162
163 static struct scsi_host_template ahci_qoriq_sht = {
164         AHCI_SHT(DRV_NAME),
165 };
166
167 static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
168 {
169         struct ahci_qoriq_priv *qpriv = hpriv->plat_data;
170         void __iomem *reg_base = hpriv->mmio;
171
172         switch (qpriv->type) {
173         case AHCI_LS1021A:
174                 if (!(qpriv->ecc_addr || ecc_initialized))
175                         return -EINVAL;
176                 else if (qpriv->ecc_addr && !ecc_initialized)
177                         writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
178                 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
179                 writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
180                 writel(LS1021A_PORT_PHY3, reg_base + PORT_PHY3);
181                 writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
182                 writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
183                 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
184                 if (qpriv->is_dmacoherent)
185                         writel(AHCI_PORT_AXICC_CFG,
186                                         reg_base + LS1021A_AXICC_ADDR);
187                 break;
188
189         case AHCI_LS1043A:
190                 if (!(qpriv->ecc_addr || ecc_initialized))
191                         return -EINVAL;
192                 else if (qpriv->ecc_addr && !ecc_initialized)
193                         writel(readl(qpriv->ecc_addr) |
194                                ECC_DIS_ARMV8_CH2,
195                                qpriv->ecc_addr);
196                 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
197                 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
198                 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
199                 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
200                 if (qpriv->is_dmacoherent)
201                         writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
202                 break;
203
204         case AHCI_LS2080A:
205                 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
206                 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
207                 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
208                 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
209                 if (qpriv->is_dmacoherent)
210                         writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
211                 break;
212
213         case AHCI_LS1046A:
214                 if (!(qpriv->ecc_addr || ecc_initialized))
215                         return -EINVAL;
216                 else if (qpriv->ecc_addr && !ecc_initialized)
217                         writel(readl(qpriv->ecc_addr) |
218                                ECC_DIS_ARMV8_CH2,
219                                qpriv->ecc_addr);
220                 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
221                 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
222                 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
223                 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
224                 if (qpriv->is_dmacoherent)
225                         writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
226                 break;
227
228         case AHCI_LS1028A:
229         case AHCI_LS1088A:
230         case AHCI_LX2160A:
231                 if (!(qpriv->ecc_addr || ecc_initialized))
232                         return -EINVAL;
233                 else if (qpriv->ecc_addr && !ecc_initialized)
234                         writel(readl(qpriv->ecc_addr) |
235                                ECC_DIS_LS1088A,
236                                qpriv->ecc_addr);
237                 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
238                 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
239                 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
240                 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
241                 if (qpriv->is_dmacoherent)
242                         writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
243                 break;
244
245         case AHCI_LS2088A:
246                 writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
247                 writel(AHCI_PORT_PHY2_CFG, reg_base + PORT_PHY2);
248                 writel(AHCI_PORT_PHY3_CFG, reg_base + PORT_PHY3);
249                 writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
250                 if (qpriv->is_dmacoherent)
251                         writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
252                 break;
253         }
254
255         ecc_initialized = true;
256         return 0;
257 }
258
259 static int ahci_qoriq_probe(struct platform_device *pdev)
260 {
261         struct device_node *np = pdev->dev.of_node;
262         struct device *dev = &pdev->dev;
263         struct ahci_host_priv *hpriv;
264         struct ahci_qoriq_priv *qoriq_priv;
265         const struct of_device_id *of_id;
266         struct resource *res;
267         int rc;
268
269         hpriv = ahci_platform_get_resources(pdev, 0);
270         if (IS_ERR(hpriv))
271                 return PTR_ERR(hpriv);
272
273         of_id = of_match_node(ahci_qoriq_of_match, np);
274         if (!of_id)
275                 return -ENODEV;
276
277         qoriq_priv = devm_kzalloc(dev, sizeof(*qoriq_priv), GFP_KERNEL);
278         if (!qoriq_priv)
279                 return -ENOMEM;
280
281         qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
282
283         if (unlikely(!ecc_initialized)) {
284                 res = platform_get_resource_byname(pdev,
285                                                    IORESOURCE_MEM,
286                                                    "sata-ecc");
287                 if (res) {
288                         qoriq_priv->ecc_addr =
289                                 devm_ioremap_resource(dev, res);
290                         if (IS_ERR(qoriq_priv->ecc_addr))
291                                 return PTR_ERR(qoriq_priv->ecc_addr);
292                 }
293         }
294
295         qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
296
297         rc = ahci_platform_enable_resources(hpriv);
298         if (rc)
299                 return rc;
300
301         hpriv->plat_data = qoriq_priv;
302         rc = ahci_qoriq_phy_init(hpriv);
303         if (rc)
304                 goto disable_resources;
305
306         rc = ahci_platform_init_host(pdev, hpriv, &ahci_qoriq_port_info,
307                                      &ahci_qoriq_sht);
308         if (rc)
309                 goto disable_resources;
310
311         return 0;
312
313 disable_resources:
314         ahci_platform_disable_resources(hpriv);
315
316         return rc;
317 }
318
319 #ifdef CONFIG_PM_SLEEP
320 static int ahci_qoriq_resume(struct device *dev)
321 {
322         struct ata_host *host = dev_get_drvdata(dev);
323         struct ahci_host_priv *hpriv = host->private_data;
324         int rc;
325
326         rc = ahci_platform_enable_resources(hpriv);
327         if (rc)
328                 return rc;
329
330         rc = ahci_qoriq_phy_init(hpriv);
331         if (rc)
332                 goto disable_resources;
333
334         rc = ahci_platform_resume_host(dev);
335         if (rc)
336                 goto disable_resources;
337
338         /* We resumed so update PM runtime state */
339         pm_runtime_disable(dev);
340         pm_runtime_set_active(dev);
341         pm_runtime_enable(dev);
342
343         return 0;
344
345 disable_resources:
346         ahci_platform_disable_resources(hpriv);
347
348         return rc;
349 }
350 #endif
351
352 static SIMPLE_DEV_PM_OPS(ahci_qoriq_pm_ops, ahci_platform_suspend,
353                          ahci_qoriq_resume);
354
355 static struct platform_driver ahci_qoriq_driver = {
356         .probe = ahci_qoriq_probe,
357         .remove = ata_platform_remove_one,
358         .driver = {
359                 .name = DRV_NAME,
360                 .of_match_table = ahci_qoriq_of_match,
361                 .pm = &ahci_qoriq_pm_ops,
362         },
363 };
364 module_platform_driver(ahci_qoriq_driver);
365
366 MODULE_DESCRIPTION("Freescale QorIQ AHCI SATA platform driver");
367 MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
368 MODULE_LICENSE("GPL");