phy-brcm-sata.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*
  2. * Broadcom SATA3 AHCI Controller PHY Driver
  3. *
  4. * Copyright (C) 2016 Broadcom
  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/delay.h>
  17. #include <linux/device.h>
  18. #include <linux/init.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/io.h>
  21. #include <linux/kernel.h>
  22. #include <linux/module.h>
  23. #include <linux/of.h>
  24. #include <linux/phy/phy.h>
  25. #include <linux/platform_device.h>
  26. #define SATA_PCB_BANK_OFFSET 0x23c
  27. #define SATA_PCB_REG_OFFSET(ofs) ((ofs) * 4)
  28. #define MAX_PORTS 2
  29. /* Register offset between PHYs in PCB space */
  30. #define SATA_PCB_REG_28NM_SPACE_SIZE 0x1000
  31. /* The older SATA PHY registers duplicated per port registers within the map,
  32. * rather than having a separate map per port.
  33. */
  34. #define SATA_PCB_REG_40NM_SPACE_SIZE 0x10
  35. /* Register offset between PHYs in PHY control space */
  36. #define SATA_PHY_CTRL_REG_28NM_SPACE_SIZE 0x8
  37. enum brcm_sata_phy_version {
  38. BRCM_SATA_PHY_STB_28NM,
  39. BRCM_SATA_PHY_STB_40NM,
  40. BRCM_SATA_PHY_IPROC_NS2,
  41. BRCM_SATA_PHY_IPROC_NSP,
  42. };
  43. struct brcm_sata_port {
  44. int portnum;
  45. struct phy *phy;
  46. struct brcm_sata_phy *phy_priv;
  47. bool ssc_en;
  48. };
  49. struct brcm_sata_phy {
  50. struct device *dev;
  51. void __iomem *phy_base;
  52. void __iomem *ctrl_base;
  53. enum brcm_sata_phy_version version;
  54. struct brcm_sata_port phys[MAX_PORTS];
  55. };
  56. enum sata_phy_regs {
  57. BLOCK0_REG_BANK = 0x000,
  58. BLOCK0_XGXSSTATUS = 0x81,
  59. BLOCK0_XGXSSTATUS_PLL_LOCK = BIT(12),
  60. BLOCK0_SPARE = 0x8d,
  61. BLOCK0_SPARE_OOB_CLK_SEL_MASK = 0x3,
  62. BLOCK0_SPARE_OOB_CLK_SEL_REFBY2 = 0x1,
  63. PLL_REG_BANK_0 = 0x050,
  64. PLL_REG_BANK_0_PLLCONTROL_0 = 0x81,
  65. PLLCONTROL_0_FREQ_DET_RESTART = BIT(13),
  66. PLLCONTROL_0_FREQ_MONITOR = BIT(12),
  67. PLLCONTROL_0_SEQ_START = BIT(15),
  68. PLL_CAP_CONTROL = 0x85,
  69. PLL_ACTRL2 = 0x8b,
  70. PLL_ACTRL2_SELDIV_MASK = 0x1f,
  71. PLL_ACTRL2_SELDIV_SHIFT = 9,
  72. PLL1_REG_BANK = 0x060,
  73. PLL1_ACTRL2 = 0x82,
  74. PLL1_ACTRL3 = 0x83,
  75. PLL1_ACTRL4 = 0x84,
  76. OOB_REG_BANK = 0x150,
  77. OOB1_REG_BANK = 0x160,
  78. OOB_CTRL1 = 0x80,
  79. OOB_CTRL1_BURST_MAX_MASK = 0xf,
  80. OOB_CTRL1_BURST_MAX_SHIFT = 12,
  81. OOB_CTRL1_BURST_MIN_MASK = 0xf,
  82. OOB_CTRL1_BURST_MIN_SHIFT = 8,
  83. OOB_CTRL1_WAKE_IDLE_MAX_MASK = 0xf,
  84. OOB_CTRL1_WAKE_IDLE_MAX_SHIFT = 4,
  85. OOB_CTRL1_WAKE_IDLE_MIN_MASK = 0xf,
  86. OOB_CTRL1_WAKE_IDLE_MIN_SHIFT = 0,
  87. OOB_CTRL2 = 0x81,
  88. OOB_CTRL2_SEL_ENA_SHIFT = 15,
  89. OOB_CTRL2_SEL_ENA_RC_SHIFT = 14,
  90. OOB_CTRL2_RESET_IDLE_MAX_MASK = 0x3f,
  91. OOB_CTRL2_RESET_IDLE_MAX_SHIFT = 8,
  92. OOB_CTRL2_BURST_CNT_MASK = 0x3,
  93. OOB_CTRL2_BURST_CNT_SHIFT = 6,
  94. OOB_CTRL2_RESET_IDLE_MIN_MASK = 0x3f,
  95. OOB_CTRL2_RESET_IDLE_MIN_SHIFT = 0,
  96. TXPMD_REG_BANK = 0x1a0,
  97. TXPMD_CONTROL1 = 0x81,
  98. TXPMD_CONTROL1_TX_SSC_EN_FRC = BIT(0),
  99. TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL = BIT(1),
  100. TXPMD_TX_FREQ_CTRL_CONTROL1 = 0x82,
  101. TXPMD_TX_FREQ_CTRL_CONTROL2 = 0x83,
  102. TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK = 0x3ff,
  103. TXPMD_TX_FREQ_CTRL_CONTROL3 = 0x84,
  104. TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK = 0x3ff,
  105. };
  106. enum sata_phy_ctrl_regs {
  107. PHY_CTRL_1 = 0x0,
  108. PHY_CTRL_1_RESET = BIT(0),
  109. };
  110. static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port)
  111. {
  112. struct brcm_sata_phy *priv = port->phy_priv;
  113. u32 size = 0;
  114. switch (priv->version) {
  115. case BRCM_SATA_PHY_STB_28NM:
  116. case BRCM_SATA_PHY_IPROC_NS2:
  117. size = SATA_PCB_REG_28NM_SPACE_SIZE;
  118. break;
  119. case BRCM_SATA_PHY_STB_40NM:
  120. size = SATA_PCB_REG_40NM_SPACE_SIZE;
  121. break;
  122. default:
  123. dev_err(priv->dev, "invalid phy version\n");
  124. break;
  125. };
  126. return priv->phy_base + (port->portnum * size);
  127. }
  128. static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port)
  129. {
  130. struct brcm_sata_phy *priv = port->phy_priv;
  131. u32 size = 0;
  132. switch (priv->version) {
  133. case BRCM_SATA_PHY_IPROC_NS2:
  134. size = SATA_PHY_CTRL_REG_28NM_SPACE_SIZE;
  135. break;
  136. default:
  137. dev_err(priv->dev, "invalid phy version\n");
  138. break;
  139. };
  140. return priv->ctrl_base + (port->portnum * size);
  141. }
  142. static void brcm_sata_phy_wr(void __iomem *pcb_base, u32 bank,
  143. u32 ofs, u32 msk, u32 value)
  144. {
  145. u32 tmp;
  146. writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
  147. tmp = readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
  148. tmp = (tmp & msk) | value;
  149. writel(tmp, pcb_base + SATA_PCB_REG_OFFSET(ofs));
  150. }
  151. static u32 brcm_sata_phy_rd(void __iomem *pcb_base, u32 bank, u32 ofs)
  152. {
  153. writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
  154. return readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
  155. }
  156. /* These defaults were characterized by H/W group */
  157. #define STB_FMIN_VAL_DEFAULT 0x3df
  158. #define STB_FMAX_VAL_DEFAULT 0x3df
  159. #define STB_FMAX_VAL_SSC 0x83
  160. static int brcm_stb_sata_init(struct brcm_sata_port *port)
  161. {
  162. void __iomem *base = brcm_sata_pcb_base(port);
  163. struct brcm_sata_phy *priv = port->phy_priv;
  164. u32 tmp;
  165. /* override the TX spread spectrum setting */
  166. tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC;
  167. brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp);
  168. /* set fixed min freq */
  169. brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2,
  170. ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK,
  171. STB_FMIN_VAL_DEFAULT);
  172. /* set fixed max freq depending on SSC config */
  173. if (port->ssc_en) {
  174. dev_info(priv->dev, "enabling SSC on port%d\n", port->portnum);
  175. tmp = STB_FMAX_VAL_SSC;
  176. } else {
  177. tmp = STB_FMAX_VAL_DEFAULT;
  178. }
  179. brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3,
  180. ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp);
  181. return 0;
  182. }
  183. /* NS2 SATA PLL1 defaults were characterized by H/W group */
  184. #define NS2_PLL1_ACTRL2_MAGIC 0x1df8
  185. #define NS2_PLL1_ACTRL3_MAGIC 0x2b00
  186. #define NS2_PLL1_ACTRL4_MAGIC 0x8824
  187. static int brcm_ns2_sata_init(struct brcm_sata_port *port)
  188. {
  189. int try;
  190. unsigned int val;
  191. void __iomem *base = brcm_sata_pcb_base(port);
  192. void __iomem *ctrl_base = brcm_sata_ctrl_base(port);
  193. struct device *dev = port->phy_priv->dev;
  194. /* Configure OOB control */
  195. val = 0x0;
  196. val |= (0xc << OOB_CTRL1_BURST_MAX_SHIFT);
  197. val |= (0x4 << OOB_CTRL1_BURST_MIN_SHIFT);
  198. val |= (0x9 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
  199. val |= (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
  200. brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
  201. val = 0x0;
  202. val |= (0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
  203. val |= (0x2 << OOB_CTRL2_BURST_CNT_SHIFT);
  204. val |= (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
  205. brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
  206. /* Configure PHY PLL register bank 1 */
  207. val = NS2_PLL1_ACTRL2_MAGIC;
  208. brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
  209. val = NS2_PLL1_ACTRL3_MAGIC;
  210. brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
  211. val = NS2_PLL1_ACTRL4_MAGIC;
  212. brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
  213. /* Configure PHY BLOCK0 register bank */
  214. /* Set oob_clk_sel to refclk/2 */
  215. brcm_sata_phy_wr(base, BLOCK0_REG_BANK, BLOCK0_SPARE,
  216. ~BLOCK0_SPARE_OOB_CLK_SEL_MASK,
  217. BLOCK0_SPARE_OOB_CLK_SEL_REFBY2);
  218. /* Strobe PHY reset using PHY control register */
  219. writel(PHY_CTRL_1_RESET, ctrl_base + PHY_CTRL_1);
  220. mdelay(1);
  221. writel(0x0, ctrl_base + PHY_CTRL_1);
  222. mdelay(1);
  223. /* Wait for PHY PLL lock by polling pll_lock bit */
  224. try = 50;
  225. while (try) {
  226. val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
  227. BLOCK0_XGXSSTATUS);
  228. if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
  229. break;
  230. msleep(20);
  231. try--;
  232. }
  233. if (!try) {
  234. /* PLL did not lock; give up */
  235. dev_err(dev, "port%d PLL did not lock\n", port->portnum);
  236. return -ETIMEDOUT;
  237. }
  238. dev_dbg(dev, "port%d initialized\n", port->portnum);
  239. return 0;
  240. }
  241. static int brcm_nsp_sata_init(struct brcm_sata_port *port)
  242. {
  243. struct brcm_sata_phy *priv = port->phy_priv;
  244. struct device *dev = port->phy_priv->dev;
  245. void __iomem *base = priv->phy_base;
  246. unsigned int oob_bank;
  247. unsigned int val, try;
  248. /* Configure OOB control */
  249. if (port->portnum == 0)
  250. oob_bank = OOB_REG_BANK;
  251. else if (port->portnum == 1)
  252. oob_bank = OOB1_REG_BANK;
  253. else
  254. return -EINVAL;
  255. val = 0x0;
  256. val |= (0x0f << OOB_CTRL1_BURST_MAX_SHIFT);
  257. val |= (0x06 << OOB_CTRL1_BURST_MIN_SHIFT);
  258. val |= (0x0f << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
  259. val |= (0x06 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
  260. brcm_sata_phy_wr(base, oob_bank, OOB_CTRL1, 0x0, val);
  261. val = 0x0;
  262. val |= (0x2e << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
  263. val |= (0x02 << OOB_CTRL2_BURST_CNT_SHIFT);
  264. val |= (0x16 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
  265. brcm_sata_phy_wr(base, oob_bank, OOB_CTRL2, 0x0, val);
  266. brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL2,
  267. ~(PLL_ACTRL2_SELDIV_MASK << PLL_ACTRL2_SELDIV_SHIFT),
  268. 0x0c << PLL_ACTRL2_SELDIV_SHIFT);
  269. brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CONTROL,
  270. 0xff0, 0x4f0);
  271. val = PLLCONTROL_0_FREQ_DET_RESTART | PLLCONTROL_0_FREQ_MONITOR;
  272. brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
  273. ~val, val);
  274. val = PLLCONTROL_0_SEQ_START;
  275. brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
  276. ~val, 0);
  277. mdelay(10);
  278. brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0,
  279. ~val, val);
  280. /* Wait for pll_seq_done bit */
  281. try = 50;
  282. while (try--) {
  283. val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
  284. BLOCK0_XGXSSTATUS);
  285. if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
  286. break;
  287. msleep(20);
  288. }
  289. if (!try) {
  290. /* PLL did not lock; give up */
  291. dev_err(dev, "port%d PLL did not lock\n", port->portnum);
  292. return -ETIMEDOUT;
  293. }
  294. dev_dbg(dev, "port%d initialized\n", port->portnum);
  295. return 0;
  296. }
  297. static int brcm_sata_phy_init(struct phy *phy)
  298. {
  299. int rc;
  300. struct brcm_sata_port *port = phy_get_drvdata(phy);
  301. switch (port->phy_priv->version) {
  302. case BRCM_SATA_PHY_STB_28NM:
  303. case BRCM_SATA_PHY_STB_40NM:
  304. rc = brcm_stb_sata_init(port);
  305. break;
  306. case BRCM_SATA_PHY_IPROC_NS2:
  307. rc = brcm_ns2_sata_init(port);
  308. break;
  309. case BRCM_SATA_PHY_IPROC_NSP:
  310. rc = brcm_nsp_sata_init(port);
  311. break;
  312. default:
  313. rc = -ENODEV;
  314. };
  315. return rc;
  316. }
  317. static const struct phy_ops phy_ops = {
  318. .init = brcm_sata_phy_init,
  319. .owner = THIS_MODULE,
  320. };
  321. static const struct of_device_id brcm_sata_phy_of_match[] = {
  322. { .compatible = "brcm,bcm7445-sata-phy",
  323. .data = (void *)BRCM_SATA_PHY_STB_28NM },
  324. { .compatible = "brcm,bcm7425-sata-phy",
  325. .data = (void *)BRCM_SATA_PHY_STB_40NM },
  326. { .compatible = "brcm,iproc-ns2-sata-phy",
  327. .data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
  328. { .compatible = "brcm,iproc-nsp-sata-phy",
  329. .data = (void *)BRCM_SATA_PHY_IPROC_NSP },
  330. {},
  331. };
  332. MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
  333. static int brcm_sata_phy_probe(struct platform_device *pdev)
  334. {
  335. struct device *dev = &pdev->dev;
  336. struct device_node *dn = dev->of_node, *child;
  337. const struct of_device_id *of_id;
  338. struct brcm_sata_phy *priv;
  339. struct resource *res;
  340. struct phy_provider *provider;
  341. int ret, count = 0;
  342. if (of_get_child_count(dn) == 0)
  343. return -ENODEV;
  344. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  345. if (!priv)
  346. return -ENOMEM;
  347. dev_set_drvdata(dev, priv);
  348. priv->dev = dev;
  349. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
  350. priv->phy_base = devm_ioremap_resource(dev, res);
  351. if (IS_ERR(priv->phy_base))
  352. return PTR_ERR(priv->phy_base);
  353. of_id = of_match_node(brcm_sata_phy_of_match, dn);
  354. if (of_id)
  355. priv->version = (enum brcm_sata_phy_version)of_id->data;
  356. else
  357. priv->version = BRCM_SATA_PHY_STB_28NM;
  358. if (priv->version == BRCM_SATA_PHY_IPROC_NS2) {
  359. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  360. "phy-ctrl");
  361. priv->ctrl_base = devm_ioremap_resource(dev, res);
  362. if (IS_ERR(priv->ctrl_base))
  363. return PTR_ERR(priv->ctrl_base);
  364. }
  365. for_each_available_child_of_node(dn, child) {
  366. unsigned int id;
  367. struct brcm_sata_port *port;
  368. if (of_property_read_u32(child, "reg", &id)) {
  369. dev_err(dev, "missing reg property in node %s\n",
  370. child->name);
  371. ret = -EINVAL;
  372. goto put_child;
  373. }
  374. if (id >= MAX_PORTS) {
  375. dev_err(dev, "invalid reg: %u\n", id);
  376. ret = -EINVAL;
  377. goto put_child;
  378. }
  379. if (priv->phys[id].phy) {
  380. dev_err(dev, "already registered port %u\n", id);
  381. ret = -EINVAL;
  382. goto put_child;
  383. }
  384. port = &priv->phys[id];
  385. port->portnum = id;
  386. port->phy_priv = priv;
  387. port->phy = devm_phy_create(dev, child, &phy_ops);
  388. port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
  389. if (IS_ERR(port->phy)) {
  390. dev_err(dev, "failed to create PHY\n");
  391. ret = PTR_ERR(port->phy);
  392. goto put_child;
  393. }
  394. phy_set_drvdata(port->phy, port);
  395. count++;
  396. }
  397. provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
  398. if (IS_ERR(provider)) {
  399. dev_err(dev, "could not register PHY provider\n");
  400. return PTR_ERR(provider);
  401. }
  402. dev_info(dev, "registered %d port(s)\n", count);
  403. return 0;
  404. put_child:
  405. of_node_put(child);
  406. return ret;
  407. }
  408. static struct platform_driver brcm_sata_phy_driver = {
  409. .probe = brcm_sata_phy_probe,
  410. .driver = {
  411. .of_match_table = brcm_sata_phy_of_match,
  412. .name = "brcm-sata-phy",
  413. }
  414. };
  415. module_platform_driver(brcm_sata_phy_driver);
  416. MODULE_DESCRIPTION("Broadcom SATA PHY driver");
  417. MODULE_LICENSE("GPL");
  418. MODULE_AUTHOR("Marc Carino");
  419. MODULE_AUTHOR("Brian Norris");
  420. MODULE_ALIAS("platform:phy-brcm-sata");