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