ahci_brcm.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  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 OVERRIDE_HWINIT BIT(16)
  39. #define SATA_TOP_CTRL_TP_CTRL 0x8
  40. #define SATA_TOP_CTRL_PHY_CTRL 0xc
  41. #define SATA_TOP_CTRL_PHY_CTRL_1 0x0
  42. #define SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE BIT(14)
  43. #define SATA_TOP_CTRL_PHY_CTRL_2 0x4
  44. #define SATA_TOP_CTRL_2_SW_RST_MDIOREG BIT(0)
  45. #define SATA_TOP_CTRL_2_SW_RST_OOB BIT(1)
  46. #define SATA_TOP_CTRL_2_SW_RST_RX BIT(2)
  47. #define SATA_TOP_CTRL_2_SW_RST_TX BIT(3)
  48. #define SATA_TOP_CTRL_2_PHY_GLOBAL_RESET BIT(14)
  49. #define SATA_TOP_CTRL_PHY_OFFS 0x8
  50. #define SATA_TOP_MAX_PHYS 2
  51. #define SATA_FIRST_PORT_CTRL 0x700
  52. #define SATA_NEXT_PORT_CTRL_OFFSET 0x80
  53. #define SATA_PORT_PCTRL6(reg_base) (reg_base + 0x18)
  54. /* On big-endian MIPS, buses are reversed to big endian, so switch them back */
  55. #if defined(CONFIG_MIPS) && defined(__BIG_ENDIAN)
  56. #define DATA_ENDIAN 2 /* AHCI->DDR inbound accesses */
  57. #define MMIO_ENDIAN 2 /* CPU->AHCI outbound accesses */
  58. #else
  59. #define DATA_ENDIAN 0
  60. #define MMIO_ENDIAN 0
  61. #endif
  62. #define BUS_CTRL_ENDIAN_CONF \
  63. ((DATA_ENDIAN << DMADATA_ENDIAN_SHIFT) | \
  64. (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \
  65. (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT))
  66. enum brcm_ahci_version {
  67. BRCM_SATA_BCM7425 = 1,
  68. BRCM_SATA_BCM7445,
  69. BRCM_SATA_NSP,
  70. };
  71. enum brcm_ahci_quirks {
  72. BRCM_AHCI_QUIRK_NO_NCQ = BIT(0),
  73. BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1),
  74. };
  75. struct brcm_ahci_priv {
  76. struct device *dev;
  77. void __iomem *top_ctrl;
  78. u32 port_mask;
  79. u32 quirks;
  80. enum brcm_ahci_version version;
  81. };
  82. static const struct ata_port_info ahci_brcm_port_info = {
  83. .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
  84. .link_flags = ATA_LFLAG_NO_DB_DELAY,
  85. .pio_mask = ATA_PIO4,
  86. .udma_mask = ATA_UDMA6,
  87. .port_ops = &ahci_platform_ops,
  88. };
  89. static inline u32 brcm_sata_readreg(void __iomem *addr)
  90. {
  91. /*
  92. * MIPS endianness is configured by boot strap, which also reverses all
  93. * bus endianness (i.e., big-endian CPU + big endian bus ==> native
  94. * endian I/O).
  95. *
  96. * Other architectures (e.g., ARM) either do not support big endian, or
  97. * else leave I/O in little endian mode.
  98. */
  99. if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
  100. return __raw_readl(addr);
  101. else
  102. return readl_relaxed(addr);
  103. }
  104. static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
  105. {
  106. /* See brcm_sata_readreg() comments */
  107. if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
  108. __raw_writel(val, addr);
  109. else
  110. writel_relaxed(val, addr);
  111. }
  112. static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv)
  113. {
  114. struct brcm_ahci_priv *priv = hpriv->plat_data;
  115. u32 bus_ctrl, port_ctrl, host_caps;
  116. int i;
  117. /* Enable support for ALPM */
  118. bus_ctrl = brcm_sata_readreg(priv->top_ctrl +
  119. SATA_TOP_CTRL_BUS_CTRL);
  120. brcm_sata_writereg(bus_ctrl | OVERRIDE_HWINIT,
  121. priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL);
  122. host_caps = readl(hpriv->mmio + HOST_CAP);
  123. writel(host_caps | HOST_CAP_ALPM, hpriv->mmio);
  124. brcm_sata_writereg(bus_ctrl, priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL);
  125. /*
  126. * Adjust timeout to allow PLL sufficient time to lock while waking
  127. * up from slumber mode.
  128. */
  129. for (i = 0, port_ctrl = SATA_FIRST_PORT_CTRL;
  130. i < SATA_TOP_MAX_PHYS;
  131. i++, port_ctrl += SATA_NEXT_PORT_CTRL_OFFSET) {
  132. if (priv->port_mask & BIT(i))
  133. writel(0xff1003fc,
  134. hpriv->mmio + SATA_PORT_PCTRL6(port_ctrl));
  135. }
  136. }
  137. static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port)
  138. {
  139. void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
  140. (port * SATA_TOP_CTRL_PHY_OFFS);
  141. void __iomem *p;
  142. u32 reg;
  143. if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
  144. return;
  145. /* clear PHY_DEFAULT_POWER_STATE */
  146. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
  147. reg = brcm_sata_readreg(p);
  148. reg &= ~SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
  149. brcm_sata_writereg(reg, p);
  150. /* reset the PHY digital logic */
  151. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
  152. reg = brcm_sata_readreg(p);
  153. reg &= ~(SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
  154. SATA_TOP_CTRL_2_SW_RST_RX);
  155. reg |= SATA_TOP_CTRL_2_SW_RST_TX;
  156. brcm_sata_writereg(reg, p);
  157. reg = brcm_sata_readreg(p);
  158. reg |= SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
  159. brcm_sata_writereg(reg, p);
  160. reg = brcm_sata_readreg(p);
  161. reg &= ~SATA_TOP_CTRL_2_PHY_GLOBAL_RESET;
  162. brcm_sata_writereg(reg, p);
  163. (void)brcm_sata_readreg(p);
  164. }
  165. static void brcm_sata_phy_disable(struct brcm_ahci_priv *priv, int port)
  166. {
  167. void __iomem *phyctrl = priv->top_ctrl + SATA_TOP_CTRL_PHY_CTRL +
  168. (port * SATA_TOP_CTRL_PHY_OFFS);
  169. void __iomem *p;
  170. u32 reg;
  171. if (priv->quirks & BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE)
  172. return;
  173. /* power-off the PHY digital logic */
  174. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_2;
  175. reg = brcm_sata_readreg(p);
  176. reg |= (SATA_TOP_CTRL_2_SW_RST_MDIOREG | SATA_TOP_CTRL_2_SW_RST_OOB |
  177. SATA_TOP_CTRL_2_SW_RST_RX | SATA_TOP_CTRL_2_SW_RST_TX |
  178. SATA_TOP_CTRL_2_PHY_GLOBAL_RESET);
  179. brcm_sata_writereg(reg, p);
  180. /* set PHY_DEFAULT_POWER_STATE */
  181. p = phyctrl + SATA_TOP_CTRL_PHY_CTRL_1;
  182. reg = brcm_sata_readreg(p);
  183. reg |= SATA_TOP_CTRL_1_PHY_DEFAULT_POWER_STATE;
  184. brcm_sata_writereg(reg, p);
  185. }
  186. static void brcm_sata_phys_enable(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_enable(priv, i);
  192. }
  193. static void brcm_sata_phys_disable(struct brcm_ahci_priv *priv)
  194. {
  195. int i;
  196. for (i = 0; i < SATA_TOP_MAX_PHYS; i++)
  197. if (priv->port_mask & BIT(i))
  198. brcm_sata_phy_disable(priv, i);
  199. }
  200. static u32 brcm_ahci_get_portmask(struct platform_device *pdev,
  201. struct brcm_ahci_priv *priv)
  202. {
  203. void __iomem *ahci;
  204. struct resource *res;
  205. u32 impl;
  206. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci");
  207. ahci = devm_ioremap_resource(&pdev->dev, res);
  208. if (IS_ERR(ahci))
  209. return 0;
  210. impl = readl(ahci + HOST_PORTS_IMPL);
  211. if (fls(impl) > SATA_TOP_MAX_PHYS)
  212. dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n",
  213. impl);
  214. else if (!impl)
  215. dev_info(priv->dev, "no ports found\n");
  216. devm_iounmap(&pdev->dev, ahci);
  217. devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
  218. return impl;
  219. }
  220. static void brcm_sata_init(struct brcm_ahci_priv *priv)
  221. {
  222. void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL;
  223. /* Configure endianness */
  224. if (priv->version == BRCM_SATA_NSP) {
  225. u32 data = brcm_sata_readreg(ctrl);
  226. data &= ~((0x03 << DMADATA_ENDIAN_SHIFT) |
  227. (0x03 << DMADESC_ENDIAN_SHIFT));
  228. data |= (0x02 << DMADATA_ENDIAN_SHIFT) |
  229. (0x02 << DMADESC_ENDIAN_SHIFT);
  230. brcm_sata_writereg(data, ctrl);
  231. } else
  232. brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, ctrl);
  233. }
  234. #ifdef CONFIG_PM_SLEEP
  235. static int brcm_ahci_suspend(struct device *dev)
  236. {
  237. struct ata_host *host = dev_get_drvdata(dev);
  238. struct ahci_host_priv *hpriv = host->private_data;
  239. struct brcm_ahci_priv *priv = hpriv->plat_data;
  240. int ret;
  241. ret = ahci_platform_suspend(dev);
  242. brcm_sata_phys_disable(priv);
  243. return ret;
  244. }
  245. static int brcm_ahci_resume(struct device *dev)
  246. {
  247. struct ata_host *host = dev_get_drvdata(dev);
  248. struct ahci_host_priv *hpriv = host->private_data;
  249. struct brcm_ahci_priv *priv = hpriv->plat_data;
  250. brcm_sata_init(priv);
  251. brcm_sata_phys_enable(priv);
  252. brcm_sata_alpm_init(hpriv);
  253. return ahci_platform_resume(dev);
  254. }
  255. #endif
  256. static struct scsi_host_template ahci_platform_sht = {
  257. AHCI_SHT(DRV_NAME),
  258. };
  259. static const struct of_device_id ahci_of_match[] = {
  260. {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
  261. {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
  262. {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
  263. {},
  264. };
  265. MODULE_DEVICE_TABLE(of, ahci_of_match);
  266. static int brcm_ahci_probe(struct platform_device *pdev)
  267. {
  268. const struct of_device_id *of_id;
  269. struct device *dev = &pdev->dev;
  270. struct brcm_ahci_priv *priv;
  271. struct ahci_host_priv *hpriv;
  272. struct resource *res;
  273. int ret;
  274. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  275. if (!priv)
  276. return -ENOMEM;
  277. of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
  278. if (!of_id)
  279. return -ENODEV;
  280. priv->version = (enum brcm_ahci_version)of_id->data;
  281. priv->dev = dev;
  282. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
  283. priv->top_ctrl = devm_ioremap_resource(dev, res);
  284. if (IS_ERR(priv->top_ctrl))
  285. return PTR_ERR(priv->top_ctrl);
  286. if ((priv->version == BRCM_SATA_BCM7425) ||
  287. (priv->version == BRCM_SATA_NSP)) {
  288. priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ;
  289. priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
  290. }
  291. brcm_sata_init(priv);
  292. priv->port_mask = brcm_ahci_get_portmask(pdev, priv);
  293. if (!priv->port_mask)
  294. return -ENODEV;
  295. brcm_sata_phys_enable(priv);
  296. hpriv = ahci_platform_get_resources(pdev);
  297. if (IS_ERR(hpriv))
  298. return PTR_ERR(hpriv);
  299. hpriv->plat_data = priv;
  300. hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP;
  301. brcm_sata_alpm_init(hpriv);
  302. ret = ahci_platform_enable_resources(hpriv);
  303. if (ret)
  304. return ret;
  305. if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ)
  306. hpriv->flags |= AHCI_HFLAG_NO_NCQ;
  307. ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info,
  308. &ahci_platform_sht);
  309. if (ret)
  310. return ret;
  311. dev_info(dev, "Broadcom AHCI SATA3 registered\n");
  312. return 0;
  313. }
  314. static int brcm_ahci_remove(struct platform_device *pdev)
  315. {
  316. struct ata_host *host = dev_get_drvdata(&pdev->dev);
  317. struct ahci_host_priv *hpriv = host->private_data;
  318. struct brcm_ahci_priv *priv = hpriv->plat_data;
  319. int ret;
  320. ret = ata_platform_remove_one(pdev);
  321. if (ret)
  322. return ret;
  323. brcm_sata_phys_disable(priv);
  324. return 0;
  325. }
  326. static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
  327. static struct platform_driver brcm_ahci_driver = {
  328. .probe = brcm_ahci_probe,
  329. .remove = brcm_ahci_remove,
  330. .driver = {
  331. .name = DRV_NAME,
  332. .of_match_table = ahci_of_match,
  333. .pm = &ahci_brcm_pm_ops,
  334. },
  335. };
  336. module_platform_driver(brcm_ahci_driver);
  337. MODULE_DESCRIPTION("Broadcom SATA3 AHCI Controller Driver");
  338. MODULE_AUTHOR("Brian Norris");
  339. MODULE_LICENSE("GPL");
  340. MODULE_ALIAS("platform:sata-brcmstb");