ahci_brcm.c 13 KB

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