uniphier-system-bus.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
  4. */
  5. #include <linux/io.h>
  6. #include <linux/log2.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/of_address.h>
  10. #include <linux/of_platform.h>
  11. #include <linux/platform_device.h>
  12. /* System Bus Controller registers */
  13. #define UNIPHIER_SBC_BASE 0x100 /* base address of bank0 space */
  14. #define UNIPHIER_SBC_BASE_BE BIT(0) /* bank_enable */
  15. #define UNIPHIER_SBC_CTRL0 0x200 /* timing parameter 0 of bank0 */
  16. #define UNIPHIER_SBC_CTRL1 0x204 /* timing parameter 1 of bank0 */
  17. #define UNIPHIER_SBC_CTRL2 0x208 /* timing parameter 2 of bank0 */
  18. #define UNIPHIER_SBC_CTRL3 0x20c /* timing parameter 3 of bank0 */
  19. #define UNIPHIER_SBC_CTRL4 0x300 /* timing parameter 4 of bank0 */
  20. #define UNIPHIER_SBC_STRIDE 0x10 /* register stride to next bank */
  21. #define UNIPHIER_SBC_NR_BANKS 8 /* number of banks (chip select) */
  22. #define UNIPHIER_SBC_BASE_DUMMY 0xffffffff /* data to squash bank 0, 1 */
  23. struct uniphier_system_bus_bank {
  24. u32 base;
  25. u32 end;
  26. };
  27. struct uniphier_system_bus_priv {
  28. struct device *dev;
  29. void __iomem *membase;
  30. struct uniphier_system_bus_bank bank[UNIPHIER_SBC_NR_BANKS];
  31. };
  32. static int uniphier_system_bus_add_bank(struct uniphier_system_bus_priv *priv,
  33. int bank, u32 addr, u64 paddr, u32 size)
  34. {
  35. u64 end, mask;
  36. dev_dbg(priv->dev,
  37. "range found: bank = %d, addr = %08x, paddr = %08llx, size = %08x\n",
  38. bank, addr, paddr, size);
  39. if (bank >= ARRAY_SIZE(priv->bank)) {
  40. dev_err(priv->dev, "unsupported bank number %d\n", bank);
  41. return -EINVAL;
  42. }
  43. if (priv->bank[bank].base || priv->bank[bank].end) {
  44. dev_err(priv->dev,
  45. "range for bank %d has already been specified\n", bank);
  46. return -EINVAL;
  47. }
  48. if (paddr > U32_MAX) {
  49. dev_err(priv->dev, "base address %llx is too high\n", paddr);
  50. return -EINVAL;
  51. }
  52. end = paddr + size;
  53. if (addr > paddr) {
  54. dev_err(priv->dev,
  55. "base %08x cannot be mapped to %08llx of parent\n",
  56. addr, paddr);
  57. return -EINVAL;
  58. }
  59. paddr -= addr;
  60. paddr = round_down(paddr, 0x00020000);
  61. end = round_up(end, 0x00020000);
  62. if (end > U32_MAX) {
  63. dev_err(priv->dev, "end address %08llx is too high\n", end);
  64. return -EINVAL;
  65. }
  66. mask = paddr ^ (end - 1);
  67. mask = roundup_pow_of_two(mask);
  68. paddr = round_down(paddr, mask);
  69. end = round_up(end, mask);
  70. priv->bank[bank].base = paddr;
  71. priv->bank[bank].end = end;
  72. dev_dbg(priv->dev, "range added: bank = %d, addr = %08x, end = %08x\n",
  73. bank, priv->bank[bank].base, priv->bank[bank].end);
  74. return 0;
  75. }
  76. static int uniphier_system_bus_check_overlap(
  77. const struct uniphier_system_bus_priv *priv)
  78. {
  79. int i, j;
  80. for (i = 0; i < ARRAY_SIZE(priv->bank); i++) {
  81. for (j = i + 1; j < ARRAY_SIZE(priv->bank); j++) {
  82. if (priv->bank[i].end > priv->bank[j].base &&
  83. priv->bank[i].base < priv->bank[j].end) {
  84. dev_err(priv->dev,
  85. "region overlap between bank%d and bank%d\n",
  86. i, j);
  87. return -EINVAL;
  88. }
  89. }
  90. }
  91. return 0;
  92. }
  93. static void uniphier_system_bus_check_boot_swap(
  94. struct uniphier_system_bus_priv *priv)
  95. {
  96. void __iomem *base_reg = priv->membase + UNIPHIER_SBC_BASE;
  97. int is_swapped;
  98. is_swapped = !(readl(base_reg) & UNIPHIER_SBC_BASE_BE);
  99. dev_dbg(priv->dev, "Boot Swap: %s\n", is_swapped ? "on" : "off");
  100. /*
  101. * If BOOT_SWAP was asserted on power-on-reset, the CS0 and CS1 are
  102. * swapped. In this case, bank0 and bank1 should be swapped as well.
  103. */
  104. if (is_swapped)
  105. swap(priv->bank[0], priv->bank[1]);
  106. }
  107. static void uniphier_system_bus_set_reg(
  108. const struct uniphier_system_bus_priv *priv)
  109. {
  110. void __iomem *base_reg = priv->membase + UNIPHIER_SBC_BASE;
  111. u32 base, end, mask, val;
  112. int i;
  113. for (i = 0; i < ARRAY_SIZE(priv->bank); i++) {
  114. base = priv->bank[i].base;
  115. end = priv->bank[i].end;
  116. if (base == end) {
  117. /*
  118. * If SBC_BASE0 or SBC_BASE1 is set to zero, the access
  119. * to anywhere in the system bus space is routed to
  120. * bank 0 (if boot swap if off) or bank 1 (if boot swap
  121. * if on). It means that CPUs cannot get access to
  122. * bank 2 or later. In other words, bank 0/1 cannot
  123. * be disabled even if its bank_enable bits is cleared.
  124. * This seems odd, but it is how this hardware goes.
  125. * As a workaround, dummy data (0xffffffff) should be
  126. * set when the bank 0/1 is unused. As for bank 2 and
  127. * later, they can be simply disable by clearing the
  128. * bank_enable bit.
  129. */
  130. if (i < 2)
  131. val = UNIPHIER_SBC_BASE_DUMMY;
  132. else
  133. val = 0;
  134. } else {
  135. mask = base ^ (end - 1);
  136. val = base & 0xfffe0000;
  137. val |= (~mask >> 16) & 0xfffe;
  138. val |= UNIPHIER_SBC_BASE_BE;
  139. }
  140. dev_dbg(priv->dev, "SBC_BASE[%d] = 0x%08x\n", i, val);
  141. writel(val, base_reg + UNIPHIER_SBC_STRIDE * i);
  142. }
  143. }
  144. static int uniphier_system_bus_probe(struct platform_device *pdev)
  145. {
  146. struct device *dev = &pdev->dev;
  147. struct uniphier_system_bus_priv *priv;
  148. const __be32 *ranges;
  149. u32 cells, addr, size;
  150. u64 paddr;
  151. int pna, bank, rlen, rone, ret;
  152. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  153. if (!priv)
  154. return -ENOMEM;
  155. priv->membase = devm_platform_ioremap_resource(pdev, 0);
  156. if (IS_ERR(priv->membase))
  157. return PTR_ERR(priv->membase);
  158. priv->dev = dev;
  159. pna = of_n_addr_cells(dev->of_node);
  160. ret = of_property_read_u32(dev->of_node, "#address-cells", &cells);
  161. if (ret) {
  162. dev_err(dev, "failed to get #address-cells\n");
  163. return ret;
  164. }
  165. if (cells != 2) {
  166. dev_err(dev, "#address-cells must be 2\n");
  167. return -EINVAL;
  168. }
  169. ret = of_property_read_u32(dev->of_node, "#size-cells", &cells);
  170. if (ret) {
  171. dev_err(dev, "failed to get #size-cells\n");
  172. return ret;
  173. }
  174. if (cells != 1) {
  175. dev_err(dev, "#size-cells must be 1\n");
  176. return -EINVAL;
  177. }
  178. ranges = of_get_property(dev->of_node, "ranges", &rlen);
  179. if (!ranges) {
  180. dev_err(dev, "failed to get ranges property\n");
  181. return -ENOENT;
  182. }
  183. rlen /= sizeof(*ranges);
  184. rone = pna + 2;
  185. for (; rlen >= rone; rlen -= rone) {
  186. bank = be32_to_cpup(ranges++);
  187. addr = be32_to_cpup(ranges++);
  188. paddr = of_translate_address(dev->of_node, ranges);
  189. if (paddr == OF_BAD_ADDR)
  190. return -EINVAL;
  191. ranges += pna;
  192. size = be32_to_cpup(ranges++);
  193. ret = uniphier_system_bus_add_bank(priv, bank, addr,
  194. paddr, size);
  195. if (ret)
  196. return ret;
  197. }
  198. ret = uniphier_system_bus_check_overlap(priv);
  199. if (ret)
  200. return ret;
  201. uniphier_system_bus_check_boot_swap(priv);
  202. uniphier_system_bus_set_reg(priv);
  203. platform_set_drvdata(pdev, priv);
  204. /* Now, the bus is configured. Populate platform_devices below it */
  205. return of_platform_default_populate(dev->of_node, NULL, dev);
  206. }
  207. static int __maybe_unused uniphier_system_bus_resume(struct device *dev)
  208. {
  209. uniphier_system_bus_set_reg(dev_get_drvdata(dev));
  210. return 0;
  211. }
  212. static const struct dev_pm_ops uniphier_system_bus_pm_ops = {
  213. SET_SYSTEM_SLEEP_PM_OPS(NULL, uniphier_system_bus_resume)
  214. };
  215. static const struct of_device_id uniphier_system_bus_match[] = {
  216. { .compatible = "socionext,uniphier-system-bus" },
  217. { /* sentinel */ }
  218. };
  219. MODULE_DEVICE_TABLE(of, uniphier_system_bus_match);
  220. static struct platform_driver uniphier_system_bus_driver = {
  221. .probe = uniphier_system_bus_probe,
  222. .driver = {
  223. .name = "uniphier-system-bus",
  224. .of_match_table = uniphier_system_bus_match,
  225. .pm = &uniphier_system_bus_pm_ops,
  226. },
  227. };
  228. module_platform_driver(uniphier_system_bus_driver);
  229. MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
  230. MODULE_DESCRIPTION("UniPhier System Bus driver");
  231. MODULE_LICENSE("GPL");