1 /* 2 * Broadcom SATA3 AHCI Controller Driver 3 * 4 * Copyright © 2009-2015 Broadcom Corporation 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/ahci_platform.h> 18 #include <linux/compiler.h> 19 #include <linux/device.h> 20 #include <linux/init.h> 21 #include <linux/interrupt.h> 22 #include <linux/io.h> 23 #include <linux/kernel.h> 24 #include <linux/libata.h> 25 #include <linux/module.h> 26 #include <linux/of.h> 27 #include <linux/platform_device.h> 28 #include <linux/reset.h> 29 #include <linux/string.h> 30 31 #include "ahci.h" 32 33 #define DRV_NAME "brcm-ahci" 34 35 #define SATA_TOP_CTRL_VERSION 0x0 36 #define SATA_TOP_CTRL_BUS_CTRL 0x4 37 #define MMIO_ENDIAN_SHIFT 0 /* CPU->AHCI */ 38 #define DMADESC_ENDIAN_SHIFT 2 /* AHCI->DDR */ 39 #define DMADATA_ENDIAN_SHIFT 4 /* AHCI->DDR */ 40 #define PIODATA_ENDIAN_SHIFT 6 41 #define ENDIAN_SWAP_NONE 0 42 #define ENDIAN_SWAP_FULL 2 43 #define SATA_TOP_CTRL_TP_CTRL 0x8 44 #define SATA_TOP_CTRL_PHY_CTRL 0xc 45 #define SATA_TOP_CTRL_PHY_CTRL_1 0x0 46 #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14) 47 #define SATA_TOP_CTRL_PHY_CTRL_2 0x4 48 #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0) 49 #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1) 50 #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2) 51 #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3) 52 #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14) 53 #define SATA_TOP_CTRL_PHY_OFFS 0x8 54 #define SATA_TOP_MAX_PHYS 2 55 56 #define SATA_FIRST_PORT_CTRL 0x700 57 #define SATA_NEXT_PORT_CTRL_OFFSET 0x80 58 #define SATA_PORT_PCTRL6(reg_base) (reg_base + 0x18) 59 60 /* On big-endian MIPS, buses are reversed to big endian, so switch them back */ 61 #if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN) 62 #define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */ 63 #define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */ 64 #else 65 #define DATA_ENDIAN 0 66 #define MMIO_ENDIAN 0 67 #endif 68 69 #define BUS_CTRL_ENDIAN_CONF \ 70 ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \ 71 (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \ 72 (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT)) 73 74 #define BUS_CTRL_ENDIAN_NSP_CONF \ 75 (0x02 << DMADATA_ENDIAN_SHIFT | 0x02 << DMADESC_ENDIAN_SHIFT) 76 77 #define BUS_CTRL_ENDIAN_CONF_MASK \ 78 (0x3 << MMIO_ENDIAN_SHIFT | 0x3 << DMADESC_ENDIAN_SHIFT | \ 79 0x3 << DMADATA_ENDIAN_SHIFT | 0x3 << PIODATA_ENDIAN_SHIFT) 80 81 enum brcm_ahci_version { 82 BRCM_SATA_BCM7425 = 1, 83 BRCM_SATA_BCM7445, 84 BRCM_SATA_NSP, 85 }; 86 87 enum brcm_ahci_quirks { 88 BRCM_AHCI_QUIRK_NO_NCQ = BIT(0), 89 BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1), 90 }; 91 92 struct brcm_ahci_priv { 93 struct device *dev; 94 void __iomem *top_ctrl; 95 u32 port_mask; 96 u32 quirks; 97 enum brcm_ahci_version version; 98 struct reset_control *rcdev; 99 }; 100 101 static inline u32 brcm_sata_readreg(void __iomem *addr) 102 { 103 /* 104 * MIPS endianness is configured by boot strap, which also reverses all 105 * bus endianness (i.e., big-endian CPU + big endian bus ==> native 106 * endian I/O). 107 * 108 * Other architectures (e.g., ARM) either do not support big endian, or 109 * else leave I/O in little endian mode. 110 */ 111 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) 112 return __raw_readl(addr); 113 else 114 return readl_relaxed(addr); 115 } 116 117 static inline void brcm_sata_writereg(u32 val, void __iomem *addr) 118 { 119 /* See brcm_sata_readreg() comments */ 120 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) 121 __raw_writel(val, addr); 122 else 123 writel_relaxed(val, addr); 124 } 125 126 static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv) 127 { 128 struct brcm_ahci_priv *priv = hpriv->plat_data; 129 u32 port_ctrl, host_caps; 130 int i; 131 132 /* Enable support for ALPM */ 133 host_caps = readl(hpriv->mmio + HOST_CAP); 134 if (!(host_caps & HOST_CAP_ALPM)) 135 hpriv->flags |= AHCI_HFLAG_YES_ALPM; 136 137 /* 138 * Adjust timeout to allow PLL sufficient time to lock while waking 139 * up from slumber mode. 140 */ 141 for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL; 142 i < SATA_TOP_MAX_PHYS; 143 i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) { 144 if (priv->port_mask & BIT(i)) 145 writel(0xff1003fc, 146 hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl)); 147 } 148 } 149 150 static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port) 151 { 152 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + 153 (port * SATA_TOP_CTRL_PHY_OFFS); 154 void __iomem *p; 155 u32 reg; 156 157 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) 158 return; 159 160 /* clear PHY_DEFAULT_POWER_STATE */ 161 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; 162 reg = brcm_sata_readreg(p); 163 reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; 164 brcm_sata_writereg(reg, p); 165 166 /* reset the PHY digital logic */ 167 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; 168 reg = brcm_sata_readreg(p); 169 reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | 170 SATA_TOP_CTRL_2_SW_RST_RX); 171 reg |= SATA_TOP_CTRL_2_SW_RST_TX; 172 brcm_sata_writereg(reg, p); 173 reg = brcm_sata_readreg(p); 174 reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; 175 brcm_sata_writereg(reg, p); 176 reg = brcm_sata_readreg(p); 177 reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; 178 brcm_sata_writereg(reg, p); 179 (void)brcm_sata_readreg(p); 180 } 181 182 static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port) 183 { 184 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + 185 (port * SATA_TOP_CTRL_PHY_OFFS); 186 void __iomem *p; 187 u32 reg; 188 189 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) 190 return; 191 192 /* power-off the PHY digital logic */ 193 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; 194 reg = brcm_sata_readreg(p); 195 reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | 196 SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX | 197 SATA_TOP_CTRL_2_PHY_GLOBAL_RESET); 198 brcm_sata_writereg(reg, p); 199 200 /* set PHY_DEFAULT_POWER_STATE */ 201 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; 202 reg = brcm_sata_readreg(p); 203 reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; 204 brcm_sata_writereg(reg, p); 205 } 206 207 static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv) 208 { 209 int i; 210 211 for (i = 0; i < SATA_TOP_MAX_PHYS; i++) 212 if (priv->port_mask & BIT(i)) 213 brcm_sata_phy_enable(priv, i); 214 } 215 216 static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv) 217 { 218 int i; 219 220 for (i = 0; i < SATA_TOP_MAX_PHYS; i++) 221 if (priv->port_mask & BIT(i)) 222 brcm_sata_phy_disable(priv, i); 223 } 224 225 static u32 brcm_ahci_get_portmask(struct platform_device *pdev, 226 struct brcm_ahci_priv *priv) 227 { 228 void __iomem *ahci; 229 struct resource *res; 230 u32 impl; 231 232 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci"); 233 ahci = devm_ioremap_resource(&pdev->dev, res); 234 if (IS_ERR(ahci)) 235 return 0; 236 237 impl = readl(ahci + HOST_PORTS_IMPL); 238 239 if (fls(impl) > SATA_TOP_MAX_PHYS) 240 dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", 241 impl); 242 else if (!impl) 243 dev_info(priv->dev, "no ports found\n"); 244 245 devm_iounmap(&pdev->dev, ahci); 246 devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); 247 248 return impl; 249 } 250 251 static void brcm_sata_init(struct brcm_ahci_priv *priv) 252 { 253 void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL; 254 u32 data; 255 256 /* Configure endianness */ 257 data = brcm_sata_readreg(ctrl); 258 data &= ~BUS_CTRL_ENDIAN_CONF_MASK; 259 if (priv->version == BRCM_SATA_NSP) 260 data |= BUS_CTRL_ENDIAN_NSP_CONF; 261 else 262 data |= BUS_CTRL_ENDIAN_CONF; 263 brcm_sata_writereg(data, ctrl); 264 } 265 266 static unsigned int brcm_ahci_read_id(struct ata_device *dev, 267 struct ata_taskfile *tf, u16 *id) 268 { 269 struct ata_port *ap = dev->link->ap; 270 struct ata_host *host = ap->host; 271 struct ahci_host_priv *hpriv = host->private_data; 272 struct brcm_ahci_priv *priv = hpriv->plat_data; 273 void __iomem *mmio = hpriv->mmio; 274 unsigned int err_mask; 275 unsigned long flags; 276 int i, rc; 277 u32 ctl; 278 279 /* Try to read the device ID and, if this fails, proceed with the 280 * recovery sequence below 281 */ 282 err_mask = ata_do_dev_read_id(dev, tf, id); 283 if (likely(!err_mask)) 284 return err_mask; 285 286 /* Disable host interrupts */ 287 spin_lock_irqsave(&host->lock, flags); 288 ctl = readl(mmio + HOST_CTL); 289 ctl &= ~HOST_IRQ_EN; 290 writel(ctl, mmio + HOST_CTL); 291 readl(mmio + HOST_CTL); /* flush */ 292 spin_unlock_irqrestore(&host->lock, flags); 293 294 /* Perform the SATA PHY reset sequence */ 295 brcm_sata_phy_disable(priv, ap->port_no); 296 297 /* Bring the PHY back on */ 298 brcm_sata_phy_enable(priv, ap->port_no); 299 300 /* Re-initialize and calibrate the PHY */ 301 for (i = 0; i < hpriv->nports; i++) { 302 rc = phy_init(hpriv->phys[i]); 303 if (rc) 304 goto disable_phys; 305 306 rc = phy_calibrate(hpriv->phys[i]); 307 if (rc) { 308 phy_exit(hpriv->phys[i]); 309 goto disable_phys; 310 } 311 } 312 313 /* Re-enable host interrupts */ 314 spin_lock_irqsave(&host->lock, flags); 315 ctl = readl(mmio + HOST_CTL); 316 ctl |= HOST_IRQ_EN; 317 writel(ctl, mmio + HOST_CTL); 318 readl(mmio + HOST_CTL); /* flush */ 319 spin_unlock_irqrestore(&host->lock, flags); 320 321 return ata_do_dev_read_id(dev, tf, id); 322 323 disable_phys: 324 while (--i >= 0) { 325 phy_power_off(hpriv->phys[i]); 326 phy_exit(hpriv->phys[i]); 327 } 328 329 return AC_ERR_OTHER; 330 } 331 332 static void brcm_ahci_host_stop(struct ata_host *host) 333 { 334 struct ahci_host_priv *hpriv = host->private_data; 335 336 ahci_platform_disable_resources(hpriv); 337 } 338 339 static struct ata_port_operations ahci_brcm_platform_ops = { 340 .inherits = &ahci_ops, 341 .host_stop = brcm_ahci_host_stop, 342 .read_id = brcm_ahci_read_id, 343 }; 344 345 static const struct ata_port_info ahci_brcm_port_info = { 346 .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, 347 .link_flags = ATA_LFLAG_NO_DB_DELAY, 348 .pio_mask = ATA_PIO4, 349 .udma_mask = ATA_UDMA6, 350 .port_ops = &ahci_brcm_platform_ops, 351 }; 352 353 #ifdef CONFIG_PM_SLEEP 354 static int brcm_ahci_suspend(struct device *dev) 355 { 356 struct ata_host *host = dev_get_drvdata(dev); 357 struct ahci_host_priv *hpriv = host->private_data; 358 struct brcm_ahci_priv *priv = hpriv->plat_data; 359 int ret; 360 361 ret = ahci_platform_suspend(dev); 362 brcm_sata_phys_disable(priv); 363 return ret; 364 } 365 366 static int brcm_ahci_resume(struct device *dev) 367 { 368 struct ata_host *host = dev_get_drvdata(dev); 369 struct ahci_host_priv *hpriv = host->private_data; 370 struct brcm_ahci_priv *priv = hpriv->plat_data; 371 372 brcm_sata_init(priv); 373 brcm_sata_phys_enable(priv); 374 brcm_sata_alpm_init(hpriv); 375 return ahci_platform_resume(dev); 376 } 377 #endif 378 379 static struct scsi_host_template ahci_platform_sht = { 380 AHCI_SHT(DRV_NAME), 381 }; 382 383 static const struct of_device_id ahci_of_match[] = { 384 {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425}, 385 {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445}, 386 {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445}, 387 {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP}, 388 {}, 389 }; 390 MODULE_DEVICE_TABLE(of, ahci_of_match); 391 392 static int brcm_ahci_probe(struct platform_device *pdev) 393 { 394 const struct of_device_id *of_id; 395 struct device *dev = &pdev->dev; 396 struct brcm_ahci_priv *priv; 397 struct ahci_host_priv *hpriv; 398 struct resource *res; 399 int ret; 400 401 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 402 if (!priv) 403 return -ENOMEM; 404 405 of_id = of_match_node(ahci_of_match, pdev->dev.of_node); 406 if (!of_id) 407 return -ENODEV; 408 409 priv->version = (enum brcm_ahci_version)of_id->data; 410 priv->dev = dev; 411 412 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl"); 413 priv->top_ctrl = devm_ioremap_resource(dev, res); 414 if (IS_ERR(priv->top_ctrl)) 415 return PTR_ERR(priv->top_ctrl); 416 417 /* Reset is optional depending on platform */ 418 priv->rcdev = devm_reset_control_get(&pdev->dev, "ahci"); 419 if (!IS_ERR_OR_NULL(priv->rcdev)) 420 reset_control_deassert(priv->rcdev); 421 422 if ((priv->version == BRCM_SATA_BCM7425) || 423 (priv->version == BRCM_SATA_NSP)) { 424 priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ; 425 priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; 426 } 427 428 brcm_sata_init(priv); 429 430 priv->port_mask = brcm_ahci_get_portmask(pdev, priv); 431 if (!priv->port_mask) 432 return -ENODEV; 433 434 brcm_sata_phys_enable(priv); 435 436 hpriv = ahci_platform_get_resources(pdev, 0); 437 if (IS_ERR(hpriv)) 438 return PTR_ERR(hpriv); 439 hpriv->plat_data = priv; 440 hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP; 441 442 brcm_sata_alpm_init(hpriv); 443 444 ret = ahci_platform_enable_resources(hpriv); 445 if (ret) 446 return ret; 447 448 if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ) 449 hpriv->flags |= AHCI_HFLAG_NO_NCQ; 450 hpriv->flags |= AHCI_HFLAG_NO_WRITE_TO_RO; 451 452 ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, 453 &ahci_platform_sht); 454 if (ret) 455 return ret; 456 457 dev_info(dev, "Broadcom AHCI SATA3 registered\n"); 458 459 return 0; 460 } 461 462 static int brcm_ahci_remove(struct platform_device *pdev) 463 { 464 struct ata_host *host = dev_get_drvdata(&pdev->dev); 465 struct ahci_host_priv *hpriv = host->private_data; 466 struct brcm_ahci_priv *priv = hpriv->plat_data; 467 int ret; 468 469 ret = ata_platform_remove_one(pdev); 470 if (ret) 471 return ret; 472 473 brcm_sata_phys_disable(priv); 474 475 return 0; 476 } 477 478 static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); 479 480 static struct platform_driver brcm_ahci_driver = { 481 .probe = brcm_ahci_probe, 482 .remove = brcm_ahci_remove, 483 .driver = { 484 .name = DRV_NAME, 485 .of_match_table = ahci_of_match, 486 .pm = &ahci_brcm_pm_ops, 487 }, 488 }; 489 module_platform_driver(brcm_ahci_driver); 490 491 MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver"); 492 MODULE_AUTHOR("Brian Norris"); 493 MODULE_LICENSE("GPL"); 494 MODULE_ALIAS("platform:sata-brcmstb"); 495