ahci_brcm.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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 const struct ata_port_info ahci_brcm_port_info = {
  87. .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
  88. .link_flags = ATA_LFLAG_NO_DB_DELAY,
  89. .pio_mask = ATA_PIO4,
  90. .udma_mask = ATA_UDMA6,
  91. .port_ops = &ahci_platform_ops,
  92. };
  93. static 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. static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
  109. {
  110. /* See brcm_sata_readreg() comments */
  111. if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
  112. __raw_writel(val, addr);
  113. else
  114. writel_relaxed(val, addr);
  115. }
  116. static void brcm_sata_alpm_init(struct ahci_host_priv *hpriv)
  117. {
  118. struct brcm_ahci_priv *priv = hpriv->plat_data;
  119. u32 port_ctrl, host_caps;
  120. int i;
  121. /* Enable support for ALPM */
  122. host_caps = readl(hpriv->mmio + HOST_CAP);
  123. if (!(host_caps & HOST_CAP_ALPM))
  124. hpriv->flags |= AHCI_HFLAG_YES_ALPM;
  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. u32 data;
  224. /* Configure endianness */
  225. data = brcm_sata_readreg(ctrl);
  226. data &= ~BUS_CTRL_ENDIAN_CONF_MASK;
  227. if (priv->version == BRCM_SATA_NSP)
  228. data |= BUS_CTRL_ENDIAN_NSP_CONF;
  229. else
  230. data |= BUS_CTRL_ENDIAN_CONF;
  231. brcm_sata_writereg(data, ctrl);
  232. }
  233. #ifdef CONFIG_PM_SLEEP
  234. static int brcm_ahci_suspend(struct device *dev)
  235. {
  236. struct ata_host *host = dev_get_drvdata(dev);
  237. struct ahci_host_priv *hpriv = host->private_data;
  238. struct brcm_ahci_priv *priv = hpriv->plat_data;
  239. int ret;
  240. ret = ahci_platform_suspend(dev);
  241. brcm_sata_phys_disable(priv);
  242. return ret;
  243. }
  244. static int brcm_ahci_resume(struct device *dev)
  245. {
  246. struct ata_host *host = dev_get_drvdata(dev);
  247. struct ahci_host_priv *hpriv = host->private_data;
  248. struct brcm_ahci_priv *priv = hpriv->plat_data;
  249. brcm_sata_init(priv);
  250. brcm_sata_phys_enable(priv);
  251. brcm_sata_alpm_init(hpriv);
  252. return ahci_platform_resume(dev);
  253. }
  254. #endif
  255. static struct scsi_host_template ahci_platform_sht = {
  256. AHCI_SHT(DRV_NAME),
  257. };
  258. static const struct of_device_id ahci_of_match[] = {
  259. {.compatible = "brcm,bcm7425-ahci", .data = (void *)BRCM_SATA_BCM7425},
  260. {.compatible = "brcm,bcm7445-ahci", .data = (void *)BRCM_SATA_BCM7445},
  261. {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP},
  262. {},
  263. };
  264. MODULE_DEVICE_TABLE(of, ahci_of_match);
  265. static int brcm_ahci_probe(struct platform_device *pdev)
  266. {
  267. const struct of_device_id *of_id;
  268. struct device *dev = &pdev->dev;
  269. struct brcm_ahci_priv *priv;
  270. struct ahci_host_priv *hpriv;
  271. struct resource *res;
  272. int ret;
  273. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  274. if (!priv)
  275. return -ENOMEM;
  276. of_id = of_match_node(ahci_of_match, pdev->dev.of_node);
  277. if (!of_id)
  278. return -ENODEV;
  279. priv->version = (enum brcm_ahci_version)of_id->data;
  280. priv->dev = dev;
  281. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "top-ctrl");
  282. priv->top_ctrl = devm_ioremap_resource(dev, res);
  283. if (IS_ERR(priv->top_ctrl))
  284. return PTR_ERR(priv->top_ctrl);
  285. if ((priv->version == BRCM_SATA_BCM7425) ||
  286. (priv->version == BRCM_SATA_NSP)) {
  287. priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ;
  288. priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE;
  289. }
  290. brcm_sata_init(priv);
  291. priv->port_mask = brcm_ahci_get_portmask(pdev, priv);
  292. if (!priv->port_mask)
  293. return -ENODEV;
  294. brcm_sata_phys_enable(priv);
  295. hpriv = ahci_platform_get_resources(pdev);
  296. if (IS_ERR(hpriv))
  297. return PTR_ERR(hpriv);
  298. hpriv->plat_data = priv;
  299. hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP;
  300. brcm_sata_alpm_init(hpriv);
  301. ret = ahci_platform_enable_resources(hpriv);
  302. if (ret)
  303. return ret;
  304. if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ)
  305. hpriv->flags |= AHCI_HFLAG_NO_NCQ;
  306. hpriv->flags |= AHCI_HFLAG_NO_WRITE_TO_RO;
  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");