0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/ahci_platform.h>
0009 #include <linux/compiler.h>
0010 #include <linux/device.h>
0011 #include <linux/init.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/kernel.h>
0015 #include <linux/libata.h>
0016 #include <linux/module.h>
0017 #include <linux/of.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/reset.h>
0020 #include <linux/string.h>
0021
0022 #include "ahci.h"
0023
0024 #define DRV_NAME "brcm-ahci"
0025
0026 #define SATA_TOP_CTRL_VERSION 0x0
0027 #define SATA_TOP_CTRL_BUS_CTRL 0x4
0028 #define MMIO_ENDIAN_SHIFT 0
0029 #define DMADESC_ENDIAN_SHIFT 2
0030 #define DMADATA_ENDIAN_SHIFT 4
0031 #define PIODATA_ENDIAN_SHIFT 6
0032 #define ENDIAN_SWAP_NONE 0
0033 #define ENDIAN_SWAP_FULL 2
0034 #define SATA_TOP_CTRL_TP_CTRL 0x8
0035 #define SATA_TOP_CTRL_PHY_CTRL 0xc
0036 #define SATA_TOP_CTRL_PHY_CTRL_1 0x0
0037 #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14)
0038 #define SATA_TOP_CTRL_PHY_CTRL_2 0x4
0039 #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0)
0040 #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1)
0041 #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2)
0042 #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3)
0043 #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14)
0044 #define SATA_TOP_CTRL_PHY_OFFS 0x8
0045 #define SATA_TOP_MAX_PHYS 2
0046
0047 #define SATA_FIRST_PORT_CTRL 0x700
0048 #define SATA_NEXT_PORT_CTRL_OFFSET 0x80
0049 #define SATA_PORT_PCTRL6(reg_base) (reg_base + 0x18)
0050
0051
0052 #if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN)
0053 #define DATA_ENDIAN 2
0054 #define MMIO_ENDIAN 2
0055 #else
0056 #define DATA_ENDIAN 0
0057 #define MMIO_ENDIAN 0
0058 #endif
0059
0060 #define BUS_CTRL_ENDIAN_CONF \
0061 ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \
0062 (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \
0063 (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
0064
0065 #define BUS_CTRL_ENDIAN_NSP_CONF \
0066 (0x02 << DMADATA_ENDIAN_SHIFT | 0x02 << DMADESC_ENDIAN_SHIFT)
0067
0068 #define BUS_CTRL_ENDIAN_CONF_MASK \
0069 (0x3 << MMIO_ENDIAN_SHIFT | 0x3 << DMADESC_ENDIAN_SHIFT | \
0070 0x3 << DMADATA_ENDIAN_SHIFT | 0x3 << PIODATA_ENDIAN_SHIFT)
0071
0072 enum brcm_ahci_version {
0073 BRCM_SATA_BCM7425 = 1,
0074 BRCM_SATA_BCM7445,
0075 BRCM_SATA_NSP,
0076 BRCM_SATA_BCM7216,
0077 };
0078
0079 enum brcm_ahci_quirks {
0080 BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0),
0081 };
0082
0083 struct brcm_ahci_priv {
0084 struct device *dev;
0085 void __iomem *top_ctrl;
0086 u32 port_mask;
0087 u32 quirks;
0088 enum brcm_ahci_version version;
0089 struct reset_control *rcdev_rescal;
0090 struct reset_control *rcdev_ahci;
0091 };
0092
0093 static inline u32 brcm_sata_readreg(void __iomem *addr)
0094 {
0095
0096
0097
0098
0099
0100
0101
0102
0103 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
0104 return __raw_readl(addr);
0105 else
0106 return readl_relaxed(addr);
0107 }
0108
0109 static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
0110 {
0111
0112 if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
0113 __raw_writel(val, addr);
0114 else
0115 writel_relaxed(val, addr);
0116 }
0117
0118 static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv)
0119 {
0120 struct brcm_ahci_priv *priv = hpriv->plat_data;
0121 u32 port_ctrl, host_caps;
0122 int i;
0123
0124
0125 host_caps = readl(hpriv->mmio + HOST_CAP);
0126 if (!(host_caps & HOST_CAP_ALPM))
0127 hpriv->flags |= AHCI_HFLAG_YES_ALPM;
0128
0129
0130
0131
0132
0133 for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL;
0134 i < SATA_TOP_MAX_PHYS;
0135 i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) {
0136 if (priv->port_mask & BIT(i))
0137 writel(0xff1003fc,
0138 hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl));
0139 }
0140 }
0141
0142 static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port)
0143 {
0144 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
0145 (port * SATA_TOP_CTRL_PHY_OFFS);
0146 void __iomem *p;
0147 u32 reg;
0148
0149 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
0150 return;
0151
0152
0153 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
0154 reg = brcm_sata_readreg(p);
0155 reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
0156 brcm_sata_writereg(reg, p);
0157
0158
0159 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
0160 reg = brcm_sata_readreg(p);
0161 reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
0162 SATA_TOP_CTRL_2_SW_RST_RX);
0163 reg |= SATA_TOP_CTRL_2_SW_RST_TX;
0164 brcm_sata_writereg(reg, p);
0165 reg = brcm_sata_readreg(p);
0166 reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
0167 brcm_sata_writereg(reg, p);
0168 reg = brcm_sata_readreg(p);
0169 reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
0170 brcm_sata_writereg(reg, p);
0171 (void)brcm_sata_readreg(p);
0172 }
0173
0174 static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port)
0175 {
0176 void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
0177 (port * SATA_TOP_CTRL_PHY_OFFS);
0178 void __iomem *p;
0179 u32 reg;
0180
0181 if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
0182 return;
0183
0184
0185 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
0186 reg = brcm_sata_readreg(p);
0187 reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
0188 SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX |
0189 SATA_TOP_CTRL_2_PHY_GLOBAL_RESET);
0190 brcm_sata_writereg(reg, p);
0191
0192
0193 p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
0194 reg = brcm_sata_readreg(p);
0195 reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
0196 brcm_sata_writereg(reg, p);
0197 }
0198
0199 static void brcm_sata_phys_enable(struct brcm_ahci_priv *priv)
0200 {
0201 int i;
0202
0203 for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
0204 if (priv->port_mask & BIT(i))
0205 brcm_sata_phy_enable(priv, i);
0206 }
0207
0208 static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv)
0209 {
0210 int i;
0211
0212 for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
0213 if (priv->port_mask & BIT(i))
0214 brcm_sata_phy_disable(priv, i);
0215 }
0216
0217 static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv,
0218 struct brcm_ahci_priv *priv)
0219 {
0220 u32 impl;
0221
0222 impl = readl(hpriv->mmio + HOST_PORTS_IMPL);
0223
0224 if (fls(impl) > SATA_TOP_MAX_PHYS)
0225 dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n",
0226 impl);
0227 else if (!impl)
0228 dev_info(priv->dev, "no ports found\n");
0229
0230 return impl;
0231 }
0232
0233 static void brcm_sata_init(struct brcm_ahci_priv *priv)
0234 {
0235 void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
0236 u32 data;
0237
0238
0239 data = brcm_sata_readreg(ctrl);
0240 data &= ~BUS_CTRL_ENDIAN_CONF_MASK;
0241 if (priv->version == BRCM_SATA_NSP)
0242 data |= BUS_CTRL_ENDIAN_NSP_CONF;
0243 else
0244 data |= BUS_CTRL_ENDIAN_CONF;
0245 brcm_sata_writereg(data, ctrl);
0246 }
0247
0248 static unsigned int brcm_ahci_read_id(struct ata_device *dev,
0249 struct ata_taskfile *tf, __le16 *id)
0250 {
0251 struct ata_port *ap = dev->link->ap;
0252 struct ata_host *host = ap->host;
0253 struct ahci_host_priv *hpriv = host->private_data;
0254 struct brcm_ahci_priv *priv = hpriv->plat_data;
0255 void __iomem *mmio = hpriv->mmio;
0256 unsigned int err_mask;
0257 unsigned long flags;
0258 int i, rc;
0259 u32 ctl;
0260
0261
0262
0263
0264 err_mask = ata_do_dev_read_id(dev, tf, id);
0265 if (likely(!err_mask))
0266 return err_mask;
0267
0268
0269 spin_lock_irqsave(&host->lock, flags);
0270 ctl = readl(mmio + HOST_CTL);
0271 ctl &= ~HOST_IRQ_EN;
0272 writel(ctl, mmio + HOST_CTL);
0273 readl(mmio + HOST_CTL);
0274 spin_unlock_irqrestore(&host->lock, flags);
0275
0276
0277 brcm_sata_phy_disable(priv, ap->port_no);
0278
0279
0280 ahci_platform_disable_clks(hpriv);
0281 msleep(10);
0282
0283 ahci_platform_enable_clks(hpriv);
0284 msleep(10);
0285
0286
0287 brcm_sata_phy_enable(priv, ap->port_no);
0288
0289
0290 for (i = 0; i < hpriv->nports; i++) {
0291 rc = phy_init(hpriv->phys[i]);
0292 if (rc)
0293 goto disable_phys;
0294
0295 rc = phy_calibrate(hpriv->phys[i]);
0296 if (rc) {
0297 phy_exit(hpriv->phys[i]);
0298 goto disable_phys;
0299 }
0300 }
0301
0302
0303 spin_lock_irqsave(&host->lock, flags);
0304 ctl = readl(mmio + HOST_CTL);
0305 ctl |= HOST_IRQ_EN;
0306 writel(ctl, mmio + HOST_CTL);
0307 readl(mmio + HOST_CTL);
0308 spin_unlock_irqrestore(&host->lock, flags);
0309
0310 return ata_do_dev_read_id(dev, tf, id);
0311
0312 disable_phys:
0313 while (--i >= 0) {
0314 phy_power_off(hpriv->phys[i]);
0315 phy_exit(hpriv->phys[i]);
0316 }
0317
0318 return AC_ERR_OTHER;
0319 }
0320
0321 static void brcm_ahci_host_stop(struct ata_host *host)
0322 {
0323 struct ahci_host_priv *hpriv = host->private_data;
0324
0325 ahci_platform_disable_resources(hpriv);
0326 }
0327
0328 static struct ata_port_operations ahci_brcm_platform_ops = {
0329 .inherits = &ahci_ops,
0330 .host_stop = brcm_ahci_host_stop,
0331 .read_id = brcm_ahci_read_id,
0332 };
0333
0334 static const struct ata_port_info ahci_brcm_port_info = {
0335 .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
0336 .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY,
0337 .pio_mask = ATA_PIO4,
0338 .udma_mask = ATA_UDMA6,
0339 .port_ops = &ahci_brcm_platform_ops,
0340 };
0341
0342 static int brcm_ahci_suspend(struct device *dev)
0343 {
0344 struct ata_host *host = dev_get_drvdata(dev);
0345 struct ahci_host_priv *hpriv = host->private_data;
0346 struct brcm_ahci_priv *priv = hpriv->plat_data;
0347 int ret;
0348
0349 brcm_sata_phys_disable(priv);
0350
0351 if (IS_ENABLED(CONFIG_PM_SLEEP))
0352 ret = ahci_platform_suspend(dev);
0353 else
0354 ret = 0;
0355
0356 reset_control_assert(priv->rcdev_ahci);
0357 reset_control_rearm(priv->rcdev_rescal);
0358
0359 return ret;
0360 }
0361
0362 static int __maybe_unused brcm_ahci_resume(struct device *dev)
0363 {
0364 struct ata_host *host = dev_get_drvdata(dev);
0365 struct ahci_host_priv *hpriv = host->private_data;
0366 struct brcm_ahci_priv *priv = hpriv->plat_data;
0367 int ret = 0;
0368
0369 ret = reset_control_deassert(priv->rcdev_ahci);
0370 if (ret)
0371 return ret;
0372 ret = reset_control_reset(priv->rcdev_rescal);
0373 if (ret)
0374 return ret;
0375
0376
0377 ret = ahci_platform_enable_clks(hpriv);
0378 if (ret)
0379 return ret;
0380
0381 ret = ahci_platform_enable_regulators(hpriv);
0382 if (ret)
0383 goto out_disable_clks;
0384
0385 brcm_sata_init(priv);
0386 brcm_sata_phys_enable(priv);
0387 brcm_sata_alpm_init(hpriv);
0388
0389
0390
0391
0392
0393
0394
0395 ret = ahci_platform_enable_phys(hpriv);
0396 if (ret)
0397 goto out_disable_phys;
0398
0399 ret = ahci_platform_resume_host(dev);
0400 if (ret)
0401 goto out_disable_platform_phys;
0402
0403
0404 pm_runtime_disable(dev);
0405 pm_runtime_set_active(dev);
0406 pm_runtime_enable(dev);
0407
0408 return 0;
0409
0410 out_disable_platform_phys:
0411 ahci_platform_disable_phys(hpriv);
0412 out_disable_phys:
0413 brcm_sata_phys_disable(priv);
0414 ahci_platform_disable_regulators(hpriv);
0415 out_disable_clks:
0416 ahci_platform_disable_clks(hpriv);
0417 return ret;
0418 }
0419
0420 static struct scsi_host_template ahci_platform_sht = {
0421 AHCI_SHT(DRV_NAME),
0422 };
0423
0424 static const struct of_device_id ahci_of_match[] = {
0425 {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
0426 {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
0427 {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445},
0428 {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
0429 {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216},
0430 { }
0431 };
0432 MODULE_DEVICE_TABLE(of, ahci_of_match);
0433
0434 static int brcm_ahci_probe(struct platform_device *pdev)
0435 {
0436 const struct of_device_id *of_id;
0437 struct device *dev = &pdev->dev;
0438 struct brcm_ahci_priv *priv;
0439 struct ahci_host_priv *hpriv;
0440 struct resource *res;
0441 int ret;
0442
0443 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0444 if (!priv)
0445 return -ENOMEM;
0446
0447 of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
0448 if (!of_id)
0449 return -ENODEV;
0450
0451 priv->version = (enum brcm_ahci_version)of_id->data;
0452 priv->dev = dev;
0453
0454 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
0455 priv->top_ctrl = devm_ioremap_resource(dev, res);
0456 if (IS_ERR(priv->top_ctrl))
0457 return PTR_ERR(priv->top_ctrl);
0458
0459 if (priv->version == BRCM_SATA_BCM7216) {
0460 priv->rcdev_rescal = devm_reset_control_get_optional_shared(
0461 &pdev->dev, "rescal");
0462 if (IS_ERR(priv->rcdev_rescal))
0463 return PTR_ERR(priv->rcdev_rescal);
0464 }
0465 priv->rcdev_ahci = devm_reset_control_get_optional(&pdev->dev, "ahci");
0466 if (IS_ERR(priv->rcdev_ahci))
0467 return PTR_ERR(priv->rcdev_ahci);
0468
0469 hpriv = ahci_platform_get_resources(pdev, 0);
0470 if (IS_ERR(hpriv))
0471 return PTR_ERR(hpriv);
0472
0473 hpriv->plat_data = priv;
0474 hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO;
0475
0476 switch (priv->version) {
0477 case BRCM_SATA_BCM7425:
0478 hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE;
0479 fallthrough;
0480 case BRCM_SATA_NSP:
0481 hpriv->flags |= AHCI_HFLAG_NO_NCQ;
0482 priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
0483 break;
0484 default:
0485 break;
0486 }
0487
0488 ret = reset_control_reset(priv->rcdev_rescal);
0489 if (ret)
0490 return ret;
0491 ret = reset_control_deassert(priv->rcdev_ahci);
0492 if (ret)
0493 return ret;
0494
0495 ret = ahci_platform_enable_clks(hpriv);
0496 if (ret)
0497 goto out_reset;
0498
0499 ret = ahci_platform_enable_regulators(hpriv);
0500 if (ret)
0501 goto out_disable_clks;
0502
0503
0504
0505
0506 brcm_sata_init(priv);
0507
0508
0509 priv->port_mask = brcm_ahci_get_portmask(hpriv, priv);
0510 if (!priv->port_mask) {
0511 ret = -ENODEV;
0512 goto out_disable_regulators;
0513 }
0514
0515
0516 brcm_sata_phys_enable(priv);
0517
0518 brcm_sata_alpm_init(hpriv);
0519
0520 ret = ahci_platform_enable_phys(hpriv);
0521 if (ret)
0522 goto out_disable_phys;
0523
0524 ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info,
0525 &ahci_platform_sht);
0526 if (ret)
0527 goto out_disable_platform_phys;
0528
0529 dev_info(dev, "Broadcom AHCI SATA3 registered\n");
0530
0531 return 0;
0532
0533 out_disable_platform_phys:
0534 ahci_platform_disable_phys(hpriv);
0535 out_disable_phys:
0536 brcm_sata_phys_disable(priv);
0537 out_disable_regulators:
0538 ahci_platform_disable_regulators(hpriv);
0539 out_disable_clks:
0540 ahci_platform_disable_clks(hpriv);
0541 out_reset:
0542 reset_control_assert(priv->rcdev_ahci);
0543 reset_control_rearm(priv->rcdev_rescal);
0544 return ret;
0545 }
0546
0547 static int brcm_ahci_remove(struct platform_device *pdev)
0548 {
0549 struct ata_host *host = dev_get_drvdata(&pdev->dev);
0550 struct ahci_host_priv *hpriv = host->private_data;
0551 struct brcm_ahci_priv *priv = hpriv->plat_data;
0552
0553 brcm_sata_phys_disable(priv);
0554
0555 return ata_platform_remove_one(pdev);
0556 }
0557
0558 static void brcm_ahci_shutdown(struct platform_device *pdev)
0559 {
0560 int ret;
0561
0562
0563
0564
0565
0566
0567 ret = brcm_ahci_suspend(&pdev->dev);
0568 if (ret)
0569 dev_err(&pdev->dev, "failed to shutdown\n");
0570 }
0571
0572 static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
0573
0574 static struct platform_driver brcm_ahci_driver = {
0575 .probe = brcm_ahci_probe,
0576 .remove = brcm_ahci_remove,
0577 .shutdown = brcm_ahci_shutdown,
0578 .driver = {
0579 .name = DRV_NAME,
0580 .of_match_table = ahci_of_match,
0581 .pm = &ahci_brcm_pm_ops,
0582 },
0583 };
0584 module_platform_driver(brcm_ahci_driver);
0585
0586 MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver");
0587 MODULE_AUTHOR("Brian Norris");
0588 MODULE_LICENSE("GPL");
0589 MODULE_ALIAS("platform:sata-brcmstb");