ahci_brcm.c (15644B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Broadcom SATA3 AHCI Controller Driver 4 * 5 * Copyright © 2009-2015 Broadcom Corporation 6 */ 7 8#include <linux/ahci_platform.h> 9#include <linux/compiler.h> 10#include <linux/device.h> 11#include <linux/init.h> 12#include <linux/interrupt.h> 13#include <linux/io.h> 14#include <linux/kernel.h> 15#include <linux/libata.h> 16#include <linux/module.h> 17#include <linux/of.h> 18#include <linux/platform_device.h> 19#include <linux/reset.h> 20#include <linux/string.h> 21 22#include "ahci.h" 23 24#define DRV_NAME "brcm-ahci" 25 26#define SATA_TOP_CTRL_VERSION 0x0 27#define SATA_TOP_CTRL_BUS_CTRL 0x4 28 #define MMIO_ENDIAN_SHIFT 0 /* CPU->AHCI */ 29 #define DMADESC_ENDIAN_SHIFT 2 /* AHCI->DDR */ 30 #define DMADATA_ENDIAN_SHIFT 4 /* AHCI->DDR */ 31 #define PIODATA_ENDIAN_SHIFT 6 32 #define ENDIAN_SWAP_NONE 0 33 #define ENDIAN_SWAP_FULL 2 34#define SATA_TOP_CTRL_TP_CTRL 0x8 35#define SATA_TOP_CTRL_PHY_CTRL 0xc 36 #define SATA_TOP_CTRL_PHY_CTRL_1 0x0 37 #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14) 38 #define SATA_TOP_CTRL_PHY_CTRL_2 0x4 39 #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0) 40 #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1) 41 #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2) 42 #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3) 43 #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14) 44 #define SATA_TOP_CTRL_PHY_OFFS 0x8 45 #define SATA_TOP_MAX_PHYS 2 46 47#define SATA_FIRST_PORT_CTRL 0x700 48#define SATA_NEXT_PORT_CTRL_OFFSET 0x80 49#define SATA_PORT_PCTRL6(reg_base) (reg_base + 0x18) 50 51/* On big-endian MIPS, buses are reversed to big endian, so switch them back */ 52#if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN) 53#define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */ 54#define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */ 55#else 56#define DATA_ENDIAN 0 57#define MMIO_ENDIAN 0 58#endif 59 60#define BUS_CTRL_ENDIAN_CONF \ 61 ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \ 62 (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \ 63 (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT)) 64 65#define BUS_CTRL_ENDIAN_NSP_CONF \ 66 (0x02 << DMADATA_ENDIAN_SHIFT | 0x02 << DMADESC_ENDIAN_SHIFT) 67 68#define BUS_CTRL_ENDIAN_CONF_MASK \ 69 (0x3 << MMIO_ENDIAN_SHIFT | 0x3 << DMADESC_ENDIAN_SHIFT | \ 70 0x3 << DMADATA_ENDIAN_SHIFT | 0x3 << PIODATA_ENDIAN_SHIFT) 71 72enum brcm_ahci_version { 73 BRCM_SATA_BCM7425 = 1, 74 BRCM_SATA_BCM7445, 75 BRCM_SATA_NSP, 76 BRCM_SATA_BCM7216, 77}; 78 79enum brcm_ahci_quirks { 80 BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0), 81}; 82 83struct brcm_ahci_priv { 84 struct device *dev; 85 void __iomem *top_ctrl; 86 u32 port_mask; 87 u32 quirks; 88 enum brcm_ahci_version version; 89 struct reset_control *rcdev_rescal; 90 struct reset_control *rcdev_ahci; 91}; 92 93static inline u32 brcm_sata_readreg(void __iomem *addr) 94{ 95 /* 96 * MIPS endianness is configured by boot strap, which also reverses all 97 * bus endianness (i.e., big-endian CPU + big endian bus ==> native 98 * endian I/O). 99 * 100 * Other architectures (e.g., ARM) either do not support big endian, or 101 * else leave I/O in little endian mode. 102 */ 103 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) 104 return __raw_readl(addr); 105 else 106 return readl_relaxed(addr); 107} 108 109static inline void brcm_sata_writereg(u32 val, void __iomem *addr) 110{ 111 /* See brcm_sata_readreg() comments */ 112 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) 113 __raw_writel(val, addr); 114 else 115 writel_relaxed(val, addr); 116} 117 118static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv) 119{ 120 struct brcm_ahci_priv *priv = hpriv->plat_data; 121 u32 port_ctrl, host_caps; 122 int i; 123 124 /* Enable support for ALPM */ 125 host_caps = readl(hpriv->mmio + HOST_CAP); 126 if (!(host_caps & HOST_CAP_ALPM)) 127 hpriv->flags |= AHCI_HFLAG_YES_ALPM; 128 129 /* 130 * Adjust timeout to allow PLL sufficient time to lock while waking 131 * up from slumber mode. 132 */ 133 for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL; 134 i < SATA_TOP_MAX_PHYS; 135 i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) { 136 if (priv->port_mask & BIT(i)) 137 writel(0xff1003fc, 138 hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl)); 139 } 140} 141 142static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port) 143{ 144 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + 145 (port * SATA_TOP_CTRL_PHY_OFFS); 146 void __iomem *p; 147 u32 reg; 148 149 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) 150 return; 151 152 /* clear PHY_DEFAULT_POWER_STATE */ 153 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; 154 reg = brcm_sata_readreg(p); 155 reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; 156 brcm_sata_writereg(reg, p); 157 158 /* reset the PHY digital logic */ 159 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; 160 reg = brcm_sata_readreg(p); 161 reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | 162 SATA_TOP_CTRL_2_SW_RST_RX); 163 reg |= SATA_TOP_CTRL_2_SW_RST_TX; 164 brcm_sata_writereg(reg, p); 165 reg = brcm_sata_readreg(p); 166 reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; 167 brcm_sata_writereg(reg, p); 168 reg = brcm_sata_readreg(p); 169 reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET; 170 brcm_sata_writereg(reg, p); 171 (void)brcm_sata_readreg(p); 172} 173 174static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port) 175{ 176 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL + 177 (port * SATA_TOP_CTRL_PHY_OFFS); 178 void __iomem *p; 179 u32 reg; 180 181 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE) 182 return; 183 184 /* power-off the PHY digital logic */ 185 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2; 186 reg = brcm_sata_readreg(p); 187 reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB | 188 SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX | 189 SATA_TOP_CTRL_2_PHY_GLOBAL_RESET); 190 brcm_sata_writereg(reg, p); 191 192 /* set PHY_DEFAULT_POWER_STATE */ 193 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1; 194 reg = brcm_sata_readreg(p); 195 reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE; 196 brcm_sata_writereg(reg, p); 197} 198 199static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv) 200{ 201 int i; 202 203 for (i = 0; i < SATA_TOP_MAX_PHYS; i++) 204 if (priv->port_mask & BIT(i)) 205 brcm_sata_phy_enable(priv, i); 206} 207 208static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv) 209{ 210 int i; 211 212 for (i = 0; i < SATA_TOP_MAX_PHYS; i++) 213 if (priv->port_mask & BIT(i)) 214 brcm_sata_phy_disable(priv, i); 215} 216 217static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv, 218 struct brcm_ahci_priv *priv) 219{ 220 u32 impl; 221 222 impl = readl(hpriv->mmio + HOST_PORTS_IMPL); 223 224 if (fls(impl) > SATA_TOP_MAX_PHYS) 225 dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", 226 impl); 227 else if (!impl) 228 dev_info(priv->dev, "no ports found\n"); 229 230 return impl; 231} 232 233static void brcm_sata_init(struct brcm_ahci_priv *priv) 234{ 235 void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL; 236 u32 data; 237 238 /* Configure endianness */ 239 data = brcm_sata_readreg(ctrl); 240 data &= ~BUS_CTRL_ENDIAN_CONF_MASK; 241 if (priv->version == BRCM_SATA_NSP) 242 data |= BUS_CTRL_ENDIAN_NSP_CONF; 243 else 244 data |= BUS_CTRL_ENDIAN_CONF; 245 brcm_sata_writereg(data, ctrl); 246} 247 248static unsigned int brcm_ahci_read_id(struct ata_device *dev, 249 struct ata_taskfile *tf, __le16 *id) 250{ 251 struct ata_port *ap = dev->link->ap; 252 struct ata_host *host = ap->host; 253 struct ahci_host_priv *hpriv = host->private_data; 254 struct brcm_ahci_priv *priv = hpriv->plat_data; 255 void __iomem *mmio = hpriv->mmio; 256 unsigned int err_mask; 257 unsigned long flags; 258 int i, rc; 259 u32 ctl; 260 261 /* Try to read the device ID and, if this fails, proceed with the 262 * recovery sequence below 263 */ 264 err_mask = ata_do_dev_read_id(dev, tf, id); 265 if (likely(!err_mask)) 266 return err_mask; 267 268 /* Disable host interrupts */ 269 spin_lock_irqsave(&host->lock, flags); 270 ctl = readl(mmio + HOST_CTL); 271 ctl &= ~HOST_IRQ_EN; 272 writel(ctl, mmio + HOST_CTL); 273 readl(mmio + HOST_CTL); /* flush */ 274 spin_unlock_irqrestore(&host->lock, flags); 275 276 /* Perform the SATA PHY reset sequence */ 277 brcm_sata_phy_disable(priv, ap->port_no); 278 279 /* Reset the SATA clock */ 280 ahci_platform_disable_clks(hpriv); 281 msleep(10); 282 283 ahci_platform_enable_clks(hpriv); 284 msleep(10); 285 286 /* Bring the PHY back on */ 287 brcm_sata_phy_enable(priv, ap->port_no); 288 289 /* Re-initialize and calibrate the PHY */ 290 for (i = 0; i < hpriv->nports; i++) { 291 rc = phy_init(hpriv->phys[i]); 292 if (rc) 293 goto disable_phys; 294 295 rc = phy_calibrate(hpriv->phys[i]); 296 if (rc) { 297 phy_exit(hpriv->phys[i]); 298 goto disable_phys; 299 } 300 } 301 302 /* Re-enable host interrupts */ 303 spin_lock_irqsave(&host->lock, flags); 304 ctl = readl(mmio + HOST_CTL); 305 ctl |= HOST_IRQ_EN; 306 writel(ctl, mmio + HOST_CTL); 307 readl(mmio + HOST_CTL); /* flush */ 308 spin_unlock_irqrestore(&host->lock, flags); 309 310 return ata_do_dev_read_id(dev, tf, id); 311 312disable_phys: 313 while (--i >= 0) { 314 phy_power_off(hpriv->phys[i]); 315 phy_exit(hpriv->phys[i]); 316 } 317 318 return AC_ERR_OTHER; 319} 320 321static void brcm_ahci_host_stop(struct ata_host *host) 322{ 323 struct ahci_host_priv *hpriv = host->private_data; 324 325 ahci_platform_disable_resources(hpriv); 326} 327 328static struct ata_port_operations ahci_brcm_platform_ops = { 329 .inherits = &ahci_ops, 330 .host_stop = brcm_ahci_host_stop, 331 .read_id = brcm_ahci_read_id, 332}; 333 334static const struct ata_port_info ahci_brcm_port_info = { 335 .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, 336 .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY, 337 .pio_mask = ATA_PIO4, 338 .udma_mask = ATA_UDMA6, 339 .port_ops = &ahci_brcm_platform_ops, 340}; 341 342static int brcm_ahci_suspend(struct device *dev) 343{ 344 struct ata_host *host = dev_get_drvdata(dev); 345 struct ahci_host_priv *hpriv = host->private_data; 346 struct brcm_ahci_priv *priv = hpriv->plat_data; 347 int ret; 348 349 brcm_sata_phys_disable(priv); 350 351 if (IS_ENABLED(CONFIG_PM_SLEEP)) 352 ret = ahci_platform_suspend(dev); 353 else 354 ret = 0; 355 356 reset_control_assert(priv->rcdev_ahci); 357 reset_control_rearm(priv->rcdev_rescal); 358 359 return ret; 360} 361 362static int __maybe_unused brcm_ahci_resume(struct device *dev) 363{ 364 struct ata_host *host = dev_get_drvdata(dev); 365 struct ahci_host_priv *hpriv = host->private_data; 366 struct brcm_ahci_priv *priv = hpriv->plat_data; 367 int ret = 0; 368 369 ret = reset_control_deassert(priv->rcdev_ahci); 370 if (ret) 371 return ret; 372 ret = reset_control_reset(priv->rcdev_rescal); 373 if (ret) 374 return ret; 375 376 /* Make sure clocks are turned on before re-configuration */ 377 ret = ahci_platform_enable_clks(hpriv); 378 if (ret) 379 return ret; 380 381 ret = ahci_platform_enable_regulators(hpriv); 382 if (ret) 383 goto out_disable_clks; 384 385 brcm_sata_init(priv); 386 brcm_sata_phys_enable(priv); 387 brcm_sata_alpm_init(hpriv); 388 389 /* Since we had to enable clocks earlier on, we cannot use 390 * ahci_platform_resume() as-is since a second call to 391 * ahci_platform_enable_resources() would bump up the resources 392 * (regulators, clocks, PHYs) count artificially so we copy the part 393 * after ahci_platform_enable_resources(). 394 */ 395 ret = ahci_platform_enable_phys(hpriv); 396 if (ret) 397 goto out_disable_phys; 398 399 ret = ahci_platform_resume_host(dev); 400 if (ret) 401 goto out_disable_platform_phys; 402 403 /* We resumed so update PM runtime state */ 404 pm_runtime_disable(dev); 405 pm_runtime_set_active(dev); 406 pm_runtime_enable(dev); 407 408 return 0; 409 410out_disable_platform_phys: 411 ahci_platform_disable_phys(hpriv); 412out_disable_phys: 413 brcm_sata_phys_disable(priv); 414 ahci_platform_disable_regulators(hpriv); 415out_disable_clks: 416 ahci_platform_disable_clks(hpriv); 417 return ret; 418} 419 420static struct scsi_host_template ahci_platform_sht = { 421 AHCI_SHT(DRV_NAME), 422}; 423 424static const struct of_device_id ahci_of_match[] = { 425 {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425}, 426 {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445}, 427 {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445}, 428 {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP}, 429 {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216}, 430 { /* sentinel */ } 431}; 432MODULE_DEVICE_TABLE(of, ahci_of_match); 433 434static int brcm_ahci_probe(struct platform_device *pdev) 435{ 436 const struct of_device_id *of_id; 437 struct device *dev = &pdev->dev; 438 struct brcm_ahci_priv *priv; 439 struct ahci_host_priv *hpriv; 440 struct resource *res; 441 int ret; 442 443 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 444 if (!priv) 445 return -ENOMEM; 446 447 of_id = of_match_node(ahci_of_match, pdev->dev.of_node); 448 if (!of_id) 449 return -ENODEV; 450 451 priv->version = (enum brcm_ahci_version)of_id->data; 452 priv->dev = dev; 453 454 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl"); 455 priv->top_ctrl = devm_ioremap_resource(dev, res); 456 if (IS_ERR(priv->top_ctrl)) 457 return PTR_ERR(priv->top_ctrl); 458 459 if (priv->version == BRCM_SATA_BCM7216) { 460 priv->rcdev_rescal = devm_reset_control_get_optional_shared( 461 &pdev->dev, "rescal"); 462 if (IS_ERR(priv->rcdev_rescal)) 463 return PTR_ERR(priv->rcdev_rescal); 464 } 465 priv->rcdev_ahci = devm_reset_control_get_optional(&pdev->dev, "ahci"); 466 if (IS_ERR(priv->rcdev_ahci)) 467 return PTR_ERR(priv->rcdev_ahci); 468 469 hpriv = ahci_platform_get_resources(pdev, 0); 470 if (IS_ERR(hpriv)) 471 return PTR_ERR(hpriv); 472 473 hpriv->plat_data = priv; 474 hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO; 475 476 switch (priv->version) { 477 case BRCM_SATA_BCM7425: 478 hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE; 479 fallthrough; 480 case BRCM_SATA_NSP: 481 hpriv->flags |= AHCI_HFLAG_NO_NCQ; 482 priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; 483 break; 484 default: 485 break; 486 } 487 488 ret = reset_control_reset(priv->rcdev_rescal); 489 if (ret) 490 return ret; 491 ret = reset_control_deassert(priv->rcdev_ahci); 492 if (ret) 493 return ret; 494 495 ret = ahci_platform_enable_clks(hpriv); 496 if (ret) 497 goto out_reset; 498 499 ret = ahci_platform_enable_regulators(hpriv); 500 if (ret) 501 goto out_disable_clks; 502 503 /* Must be first so as to configure endianness including that 504 * of the standard AHCI register space. 505 */ 506 brcm_sata_init(priv); 507 508 /* Initializes priv->port_mask which is used below */ 509 priv->port_mask = brcm_ahci_get_portmask(hpriv, priv); 510 if (!priv->port_mask) { 511 ret = -ENODEV; 512 goto out_disable_regulators; 513 } 514 515 /* Must be done before ahci_platform_enable_phys() */ 516 brcm_sata_phys_enable(priv); 517 518 brcm_sata_alpm_init(hpriv); 519 520 ret = ahci_platform_enable_phys(hpriv); 521 if (ret) 522 goto out_disable_phys; 523 524 ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, 525 &ahci_platform_sht); 526 if (ret) 527 goto out_disable_platform_phys; 528 529 dev_info(dev, "Broadcom AHCI SATA3 registered\n"); 530 531 return 0; 532 533out_disable_platform_phys: 534 ahci_platform_disable_phys(hpriv); 535out_disable_phys: 536 brcm_sata_phys_disable(priv); 537out_disable_regulators: 538 ahci_platform_disable_regulators(hpriv); 539out_disable_clks: 540 ahci_platform_disable_clks(hpriv); 541out_reset: 542 reset_control_assert(priv->rcdev_ahci); 543 reset_control_rearm(priv->rcdev_rescal); 544 return ret; 545} 546 547static int brcm_ahci_remove(struct platform_device *pdev) 548{ 549 struct ata_host *host = dev_get_drvdata(&pdev->dev); 550 struct ahci_host_priv *hpriv = host->private_data; 551 struct brcm_ahci_priv *priv = hpriv->plat_data; 552 553 brcm_sata_phys_disable(priv); 554 555 return ata_platform_remove_one(pdev); 556} 557 558static void brcm_ahci_shutdown(struct platform_device *pdev) 559{ 560 int ret; 561 562 /* All resources releasing happens via devres, but our device, unlike a 563 * proper remove is not disappearing, therefore using 564 * brcm_ahci_suspend() here which does explicit power management is 565 * appropriate. 566 */ 567 ret = brcm_ahci_suspend(&pdev->dev); 568 if (ret) 569 dev_err(&pdev->dev, "failed to shutdown\n"); 570} 571 572static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); 573 574static struct platform_driver brcm_ahci_driver = { 575 .probe = brcm_ahci_probe, 576 .remove = brcm_ahci_remove, 577 .shutdown = brcm_ahci_shutdown, 578 .driver = { 579 .name = DRV_NAME, 580 .of_match_table = ahci_of_match, 581 .pm = &ahci_brcm_pm_ops, 582 }, 583}; 584module_platform_driver(brcm_ahci_driver); 585 586MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver"); 587MODULE_AUTHOR("Brian Norris"); 588MODULE_LICENSE("GPL"); 589MODULE_ALIAS("platform:sata-brcmstb");