pcie-bcm6318.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * BCM6318 PCIe Controller Driver
  4. *
  5. * Copyright (C) 2020 Álvaro Fernández Rojas <[email protected]>
  6. * Copyright (C) 2015 Jonas Gorski <[email protected]>
  7. * Copyright (C) 2008 Maxime Bizon <[email protected]>
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/init.h>
  11. #include <linux/delay.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mm.h>
  14. #include <linux/module.h>
  15. #include <linux/of_gpio.h>
  16. #include <linux/of_irq.h>
  17. #include <linux/of_pci.h>
  18. #include <linux/of_platform.h>
  19. #include <linux/pci.h>
  20. #include <linux/reset.h>
  21. #include <linux/types.h>
  22. #include <linux/version.h>
  23. #include <linux/vmalloc.h>
  24. #include "../pci.h"
  25. #define PCIE_BUS_BRIDGE 0
  26. #define PCIE_BUS_DEVICE 1
  27. #define PCIE_SPECIFIC_REG 0x188
  28. #define SPECIFIC_ENDIAN_MODE_BAR1_SHIFT 0
  29. #define SPECIFIC_ENDIAN_MODE_BAR1_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
  30. #define SPECIFIC_ENDIAN_MODE_BAR2_SHIFT 2
  31. #define SPECIFIC_ENDIAN_MODE_BAR2_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
  32. #define SPECIFIC_ENDIAN_MODE_BAR3_SHIFT 4
  33. #define SPECIFIC_ENDIAN_MODE_BAR3_MASK (0x3 << SPECIFIC_ENDIAN_MODE_BAR1_SHIFT)
  34. #define SPECIFIC_ENDIAN_MODE_WORD_ALIGN 0
  35. #define SPECIFIC_ENDIAN_MODE_HALFWORD_ALIGN 1
  36. #define SPECIFIC_ENDIAN_MODE_BYTE_ALIGN 2
  37. #define PCIE_CONFIG2_REG 0x408
  38. #define CONFIG2_BAR1_SIZE_EN 1
  39. #define CONFIG2_BAR1_SIZE_MASK 0xf
  40. #define PCIE_IDVAL3_REG 0x43c
  41. #define IDVAL3_CLASS_CODE_MASK 0xffffff
  42. #define IDVAL3_SUBCLASS_SHIFT 8
  43. #define IDVAL3_CLASS_SHIFT 16
  44. #define PCIE_DLSTATUS_REG 0x1048
  45. #define DLSTATUS_PHYLINKUP (1 << 13)
  46. #define PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG 0x400c
  47. #define C2P_MEM_WIN_ENDIAN_MODE_MASK 0x3
  48. #define C2P_MEM_WIN_ENDIAN_NO_SWAP 0
  49. #define C2P_MEM_WIN_ENDIAN_HALF_WORD_SWAP 1
  50. #define C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP 2
  51. #define C2P_MEM_WIN_BASE_ADDR_SHIFT 20
  52. #define C2P_MEM_WIN_BASE_ADDR_MASK (0xfff << C2P_MEM_WIN_BASE_ADDR_SHIFT)
  53. #define PCIE_RC_BAR1_CONFIG_LO_REG 0x402c
  54. #define RC_BAR_CFG_LO_SIZE_256MB 0xd
  55. #define RC_BAR_CFG_LO_MATCH_ADDR_SHIFT 20
  56. #define RC_BAR_CFG_LO_MATCH_ADDR_MASK (0xfff << RC_BAR_CFG_LO_MATCH_ADDR_SHIFT)
  57. #define PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG 0x4070
  58. #define C2P_BASELIMIT_LIMIT_SHIFT 20
  59. #define C2P_BASELIMIT_LIMIT_MASK (0xfff << C2P_BASELIMIT_LIMIT_SHIFT)
  60. #define C2P_BASELIMIT_BASE_SHIFT 4
  61. #define C2P_BASELIMIT_BASE_MASK (0xfff << C2P_BASELIMIT_BASE_SHIFT)
  62. #define PCIE_UBUS_BAR1_CFG_REMAP_REG 0x4088
  63. #define BAR1_CFG_REMAP_OFFSET_SHIFT 20
  64. #define BAR1_CFG_REMAP_OFFSET_MASK (0xfff << BAR1_CFG_REMAP_OFFSET_SHIFT)
  65. #define BAR1_CFG_REMAP_ACCESS_EN 1
  66. #define PCIE_HARD_DEBUG_REG 0x4204
  67. #define HARD_DEBUG_SERDES_IDDQ (1 << 23)
  68. #define PCIE_CPU_INT1_MASK_CLEAR_REG 0x830c
  69. #define CPU_INT_PCIE_ERR_ATTN_CPU (1 << 0)
  70. #define CPU_INT_PCIE_INTA (1 << 1)
  71. #define CPU_INT_PCIE_INTB (1 << 2)
  72. #define CPU_INT_PCIE_INTC (1 << 3)
  73. #define CPU_INT_PCIE_INTD (1 << 4)
  74. #define CPU_INT_PCIE_INTR (1 << 5)
  75. #define CPU_INT_PCIE_NMI (1 << 6)
  76. #define CPU_INT_PCIE_UBUS (1 << 7)
  77. #define CPU_INT_IPI (1 << 8)
  78. #define PCIE_EXT_CFG_INDEX_REG 0x8400
  79. #define EXT_CFG_FUNC_NUM_SHIFT 12
  80. #define EXT_CFG_FUNC_NUM_MASK (0x7 << EXT_CFG_FUNC_NUM_SHIFT)
  81. #define EXT_CFG_DEV_NUM_SHIFT 15
  82. #define EXT_CFG_DEV_NUM_MASK (0xf << EXT_CFG_DEV_NUM_SHIFT)
  83. #define EXT_CFG_BUS_NUM_SHIFT 20
  84. #define EXT_CFG_BUS_NUM_MASK (0xff << EXT_CFG_BUS_NUM_SHIFT)
  85. #define PCIE_DEVICE_OFFSET 0x9000
  86. struct bcm6318_pcie {
  87. void __iomem *base;
  88. int irq;
  89. struct clk *clk;
  90. struct clk *clk25;
  91. struct clk *clk_ubus;
  92. struct reset_control *reset;
  93. struct reset_control *reset_ext;
  94. struct reset_control *reset_core;
  95. struct reset_control *reset_hard;
  96. };
  97. static struct bcm6318_pcie bcm6318_pcie;
  98. extern int bmips_pci_irq;
  99. /*
  100. * swizzle 32bits data to return only the needed part
  101. */
  102. static int postprocess_read(u32 data, int where, unsigned int size)
  103. {
  104. u32 ret = 0;
  105. switch (size) {
  106. case 1:
  107. ret = (data >> ((where & 3) << 3)) & 0xff;
  108. break;
  109. case 2:
  110. ret = (data >> ((where & 3) << 3)) & 0xffff;
  111. break;
  112. case 4:
  113. ret = data;
  114. break;
  115. }
  116. return ret;
  117. }
  118. static int preprocess_write(u32 orig_data, u32 val, int where,
  119. unsigned int size)
  120. {
  121. u32 ret = 0;
  122. switch (size) {
  123. case 1:
  124. ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
  125. (val << ((where & 3) << 3));
  126. break;
  127. case 2:
  128. ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
  129. (val << ((where & 3) << 3));
  130. break;
  131. case 4:
  132. ret = val;
  133. break;
  134. }
  135. return ret;
  136. }
  137. static int bcm6318_pcie_can_access(struct pci_bus *bus, int devfn)
  138. {
  139. struct bcm6318_pcie *priv = &bcm6318_pcie;
  140. switch (bus->number) {
  141. case PCIE_BUS_BRIDGE:
  142. return PCI_SLOT(devfn) == 0;
  143. case PCIE_BUS_DEVICE:
  144. if (PCI_SLOT(devfn) == 0)
  145. return __raw_readl(priv->base + PCIE_DLSTATUS_REG)
  146. & DLSTATUS_PHYLINKUP;
  147. fallthrough;
  148. default:
  149. return false;
  150. }
  151. }
  152. static int bcm6318_pcie_read(struct pci_bus *bus, unsigned int devfn,
  153. int where, int size, u32 *val)
  154. {
  155. struct bcm6318_pcie *priv = &bcm6318_pcie;
  156. u32 data;
  157. u32 reg = where & ~3;
  158. if (!bcm6318_pcie_can_access(bus, devfn))
  159. return PCIBIOS_DEVICE_NOT_FOUND;
  160. if (bus->number == PCIE_BUS_DEVICE)
  161. reg += PCIE_DEVICE_OFFSET;
  162. data = __raw_readl(priv->base + reg);
  163. *val = postprocess_read(data, where, size);
  164. return PCIBIOS_SUCCESSFUL;
  165. }
  166. static int bcm6318_pcie_write(struct pci_bus *bus, unsigned int devfn,
  167. int where, int size, u32 val)
  168. {
  169. struct bcm6318_pcie *priv = &bcm6318_pcie;
  170. u32 data;
  171. u32 reg = where & ~3;
  172. if (!bcm6318_pcie_can_access(bus, devfn))
  173. return PCIBIOS_DEVICE_NOT_FOUND;
  174. if (bus->number == PCIE_BUS_DEVICE)
  175. reg += PCIE_DEVICE_OFFSET;
  176. data = __raw_readl(priv->base + reg);
  177. data = preprocess_write(data, val, where, size);
  178. __raw_writel(data, priv->base + reg);
  179. return PCIBIOS_SUCCESSFUL;
  180. }
  181. static struct pci_ops bcm6318_pcie_ops = {
  182. .read = bcm6318_pcie_read,
  183. .write = bcm6318_pcie_write,
  184. };
  185. static struct resource bcm6318_pcie_io_resource;
  186. static struct resource bcm6318_pcie_mem_resource;
  187. static struct resource bcm6318_pcie_busn_resource;
  188. static struct pci_controller bcm6318_pcie_controller = {
  189. .pci_ops = &bcm6318_pcie_ops,
  190. .io_resource = &bcm6318_pcie_io_resource,
  191. .mem_resource = &bcm6318_pcie_mem_resource,
  192. };
  193. static void bcm6318_pcie_reset(struct bcm6318_pcie *priv)
  194. {
  195. u32 val;
  196. reset_control_deassert(priv->reset_hard);
  197. reset_control_assert(priv->reset);
  198. reset_control_assert(priv->reset_core);
  199. reset_control_assert(priv->reset_ext);
  200. mdelay(10);
  201. reset_control_deassert(priv->reset_ext);
  202. mdelay(10);
  203. reset_control_deassert(priv->reset);
  204. mdelay(10);
  205. val = __raw_readl(priv->base + PCIE_HARD_DEBUG_REG);
  206. val &= ~HARD_DEBUG_SERDES_IDDQ;
  207. __raw_writel(val, priv->base + PCIE_HARD_DEBUG_REG);
  208. mdelay(10);
  209. reset_control_deassert(priv->reset_core);
  210. mdelay(200);
  211. }
  212. static void bcm6318_pcie_setup(struct bcm6318_pcie *priv)
  213. {
  214. u32 val;
  215. __raw_writel(CPU_INT_PCIE_INTA | CPU_INT_PCIE_INTB |
  216. CPU_INT_PCIE_INTC | CPU_INT_PCIE_INTD,
  217. priv->base + PCIE_CPU_INT1_MASK_CLEAR_REG);
  218. val = bcm6318_pcie_mem_resource.end & C2P_BASELIMIT_LIMIT_MASK;
  219. val |= (bcm6318_pcie_mem_resource.start >> C2P_BASELIMIT_LIMIT_SHIFT)
  220. << C2P_BASELIMIT_BASE_SHIFT;
  221. __raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_BASELIMIT_REG);
  222. /* setup class code as bridge */
  223. val = __raw_readl(priv->base + PCIE_IDVAL3_REG);
  224. val &= ~IDVAL3_CLASS_CODE_MASK;
  225. val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT);
  226. __raw_writel(val, priv->base + PCIE_IDVAL3_REG);
  227. /* disable bar1 size */
  228. val = __raw_readl(priv->base + PCIE_CONFIG2_REG);
  229. val &= ~CONFIG2_BAR1_SIZE_MASK;
  230. __raw_writel(val, priv->base + PCIE_CONFIG2_REG);
  231. /* set bar0 to little endian */
  232. val = __raw_readl(priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
  233. val |= bcm6318_pcie_mem_resource.start & C2P_MEM_WIN_BASE_ADDR_MASK;
  234. val |= C2P_MEM_WIN_ENDIAN_HALF_BYTE_SWAP;
  235. __raw_writel(val, priv->base + PCIE_CPU_2_PCIE_MEM_WIN0_LO_REG);
  236. __raw_writel(SPECIFIC_ENDIAN_MODE_BYTE_ALIGN,
  237. priv->base + PCIE_SPECIFIC_REG);
  238. __raw_writel(RC_BAR_CFG_LO_SIZE_256MB,
  239. priv->base + PCIE_RC_BAR1_CONFIG_LO_REG);
  240. __raw_writel(BAR1_CFG_REMAP_ACCESS_EN,
  241. priv->base + PCIE_UBUS_BAR1_CFG_REMAP_REG);
  242. __raw_writel(PCIE_BUS_DEVICE << EXT_CFG_BUS_NUM_SHIFT,
  243. priv->base + PCIE_EXT_CFG_INDEX_REG);
  244. }
  245. static int bcm6318_pcie_probe(struct platform_device *pdev)
  246. {
  247. struct device *dev = &pdev->dev;
  248. struct device_node *np = dev->of_node;
  249. struct bcm6318_pcie *priv = &bcm6318_pcie;
  250. struct resource *res;
  251. int ret;
  252. LIST_HEAD(resources);
  253. of_pci_check_probe_only();
  254. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  255. priv->base = devm_ioremap_resource(dev, res);
  256. if (IS_ERR(priv->base))
  257. return PTR_ERR(priv->base);
  258. priv->irq = platform_get_irq(pdev, 0);
  259. if (!priv->irq)
  260. return -ENODEV;
  261. bmips_pci_irq = priv->irq;
  262. priv->reset = devm_reset_control_get(dev, "pcie");
  263. if (IS_ERR(priv->reset))
  264. return PTR_ERR(priv->reset);
  265. priv->reset_ext = devm_reset_control_get(dev, "pcie-ext");
  266. if (IS_ERR(priv->reset_ext))
  267. return PTR_ERR(priv->reset_ext);
  268. priv->reset_core = devm_reset_control_get(dev, "pcie-core");
  269. if (IS_ERR(priv->reset_core))
  270. return PTR_ERR(priv->reset_core);
  271. priv->reset_hard = devm_reset_control_get(dev, "pcie-hard");
  272. if (IS_ERR(priv->reset_hard))
  273. return PTR_ERR(priv->reset_hard);
  274. priv->clk = devm_clk_get(dev, "pcie");
  275. if (IS_ERR(priv->clk))
  276. return PTR_ERR(priv->clk);
  277. priv->clk25 = devm_clk_get(dev, "pcie25");
  278. if (IS_ERR(priv->clk25))
  279. return PTR_ERR(priv->clk25);
  280. priv->clk_ubus = devm_clk_get(dev, "pcie-ubus");
  281. if (IS_ERR(priv->clk_ubus))
  282. return PTR_ERR(priv->clk_ubus);
  283. ret = clk_prepare_enable(priv->clk);
  284. if (ret) {
  285. dev_err(dev, "could not enable clock\n");
  286. return ret;
  287. }
  288. ret = clk_prepare_enable(priv->clk25);
  289. if (ret) {
  290. dev_err(dev, "could not enable clock\n");
  291. return ret;
  292. }
  293. ret = clk_prepare_enable(priv->clk_ubus);
  294. if (ret) {
  295. dev_err(dev, "could not enable clock\n");
  296. return ret;
  297. }
  298. pci_load_of_ranges(&bcm6318_pcie_controller, np);
  299. if (!bcm6318_pcie_mem_resource.start)
  300. return -EINVAL;
  301. of_pci_parse_bus_range(np, &bcm6318_pcie_busn_resource);
  302. pci_add_resource(&resources, &bcm6318_pcie_busn_resource);
  303. bcm6318_pcie_reset(priv);
  304. bcm6318_pcie_setup(priv);
  305. register_pci_controller(&bcm6318_pcie_controller);
  306. return 0;
  307. }
  308. static const struct of_device_id bcm6318_pcie_of_match[] = {
  309. { .compatible = "brcm,bcm6318-pcie", },
  310. { /* sentinel */ }
  311. };
  312. MODULE_DEVICE_TABLE(of, bcm6318_pcie_of_match);
  313. static struct platform_driver bcm6318_pcie_driver = {
  314. .probe = bcm6318_pcie_probe,
  315. .driver = {
  316. .name = "bcm6318-pcie",
  317. .of_match_table = bcm6318_pcie_of_match,
  318. },
  319. };
  320. module_platform_driver(bcm6318_pcie_driver);
  321. MODULE_AUTHOR("Álvaro Fernández Rojas <[email protected]>");
  322. MODULE_DESCRIPTION("BCM6318 PCIe Controller Driver");
  323. MODULE_LICENSE("GPL v2");
  324. MODULE_ALIAS("platform:bcm6318-pcie");