mvebu-devbus.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * Marvell EBU SoC Device Bus Controller
  3. * (memory controller for NOR/NAND/SRAM/FPGA devices)
  4. *
  5. * Copyright (C) 2013-2014 Marvell
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation version 2 of the License.
  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. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. #include <linux/kernel.h>
  21. #include <linux/module.h>
  22. #include <linux/slab.h>
  23. #include <linux/err.h>
  24. #include <linux/io.h>
  25. #include <linux/clk.h>
  26. #include <linux/mbus.h>
  27. #include <linux/of_platform.h>
  28. #include <linux/of_address.h>
  29. #include <linux/platform_device.h>
  30. /* Register definitions */
  31. #define ARMADA_DEV_WIDTH_SHIFT 30
  32. #define ARMADA_BADR_SKEW_SHIFT 28
  33. #define ARMADA_RD_HOLD_SHIFT 23
  34. #define ARMADA_ACC_NEXT_SHIFT 17
  35. #define ARMADA_RD_SETUP_SHIFT 12
  36. #define ARMADA_ACC_FIRST_SHIFT 6
  37. #define ARMADA_SYNC_ENABLE_SHIFT 24
  38. #define ARMADA_WR_HIGH_SHIFT 16
  39. #define ARMADA_WR_LOW_SHIFT 8
  40. #define ARMADA_READ_PARAM_OFFSET 0x0
  41. #define ARMADA_WRITE_PARAM_OFFSET 0x4
  42. #define ORION_RESERVED (0x2 << 30)
  43. #define ORION_BADR_SKEW_SHIFT 28
  44. #define ORION_WR_HIGH_EXT_BIT BIT(27)
  45. #define ORION_WR_HIGH_EXT_MASK 0x8
  46. #define ORION_WR_LOW_EXT_BIT BIT(26)
  47. #define ORION_WR_LOW_EXT_MASK 0x8
  48. #define ORION_ALE_WR_EXT_BIT BIT(25)
  49. #define ORION_ALE_WR_EXT_MASK 0x8
  50. #define ORION_ACC_NEXT_EXT_BIT BIT(24)
  51. #define ORION_ACC_NEXT_EXT_MASK 0x10
  52. #define ORION_ACC_FIRST_EXT_BIT BIT(23)
  53. #define ORION_ACC_FIRST_EXT_MASK 0x10
  54. #define ORION_TURN_OFF_EXT_BIT BIT(22)
  55. #define ORION_TURN_OFF_EXT_MASK 0x8
  56. #define ORION_DEV_WIDTH_SHIFT 20
  57. #define ORION_WR_HIGH_SHIFT 17
  58. #define ORION_WR_HIGH_MASK 0x7
  59. #define ORION_WR_LOW_SHIFT 14
  60. #define ORION_WR_LOW_MASK 0x7
  61. #define ORION_ALE_WR_SHIFT 11
  62. #define ORION_ALE_WR_MASK 0x7
  63. #define ORION_ACC_NEXT_SHIFT 7
  64. #define ORION_ACC_NEXT_MASK 0xF
  65. #define ORION_ACC_FIRST_SHIFT 3
  66. #define ORION_ACC_FIRST_MASK 0xF
  67. #define ORION_TURN_OFF_SHIFT 0
  68. #define ORION_TURN_OFF_MASK 0x7
  69. struct devbus_read_params {
  70. u32 bus_width;
  71. u32 badr_skew;
  72. u32 turn_off;
  73. u32 acc_first;
  74. u32 acc_next;
  75. u32 rd_setup;
  76. u32 rd_hold;
  77. };
  78. struct devbus_write_params {
  79. u32 sync_enable;
  80. u32 wr_high;
  81. u32 wr_low;
  82. u32 ale_wr;
  83. };
  84. struct devbus {
  85. struct device *dev;
  86. void __iomem *base;
  87. unsigned long tick_ps;
  88. };
  89. static int get_timing_param_ps(struct devbus *devbus,
  90. struct device_node *node,
  91. const char *name,
  92. u32 *ticks)
  93. {
  94. u32 time_ps;
  95. int err;
  96. err = of_property_read_u32(node, name, &time_ps);
  97. if (err < 0) {
  98. dev_err(devbus->dev, "%s has no '%s' property\n",
  99. name, node->full_name);
  100. return err;
  101. }
  102. *ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps;
  103. dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n",
  104. name, time_ps, *ticks);
  105. return 0;
  106. }
  107. static int devbus_get_timing_params(struct devbus *devbus,
  108. struct device_node *node,
  109. struct devbus_read_params *r,
  110. struct devbus_write_params *w)
  111. {
  112. int err;
  113. err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width);
  114. if (err < 0) {
  115. dev_err(devbus->dev,
  116. "%s has no 'devbus,bus-width' property\n",
  117. node->full_name);
  118. return err;
  119. }
  120. /*
  121. * The bus width is encoded into the register as 0 for 8 bits,
  122. * and 1 for 16 bits, so we do the necessary conversion here.
  123. */
  124. if (r->bus_width == 8)
  125. r->bus_width = 0;
  126. else if (r->bus_width == 16)
  127. r->bus_width = 1;
  128. else {
  129. dev_err(devbus->dev, "invalid bus width %d\n", r->bus_width);
  130. return -EINVAL;
  131. }
  132. err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps",
  133. &r->badr_skew);
  134. if (err < 0)
  135. return err;
  136. err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps",
  137. &r->turn_off);
  138. if (err < 0)
  139. return err;
  140. err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps",
  141. &r->acc_first);
  142. if (err < 0)
  143. return err;
  144. err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps",
  145. &r->acc_next);
  146. if (err < 0)
  147. return err;
  148. if (of_device_is_compatible(devbus->dev->of_node, "marvell,mvebu-devbus")) {
  149. err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps",
  150. &r->rd_setup);
  151. if (err < 0)
  152. return err;
  153. err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps",
  154. &r->rd_hold);
  155. if (err < 0)
  156. return err;
  157. err = of_property_read_u32(node, "devbus,sync-enable",
  158. &w->sync_enable);
  159. if (err < 0) {
  160. dev_err(devbus->dev,
  161. "%s has no 'devbus,sync-enable' property\n",
  162. node->full_name);
  163. return err;
  164. }
  165. }
  166. err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps",
  167. &w->ale_wr);
  168. if (err < 0)
  169. return err;
  170. err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps",
  171. &w->wr_low);
  172. if (err < 0)
  173. return err;
  174. err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps",
  175. &w->wr_high);
  176. if (err < 0)
  177. return err;
  178. return 0;
  179. }
  180. static void devbus_orion_set_timing_params(struct devbus *devbus,
  181. struct device_node *node,
  182. struct devbus_read_params *r,
  183. struct devbus_write_params *w)
  184. {
  185. u32 value;
  186. /*
  187. * The hardware designers found it would be a good idea to
  188. * split most of the values in the register into two fields:
  189. * one containing all the low-order bits, and another one
  190. * containing just the high-order bit. For all of those
  191. * fields, we have to split the value into these two parts.
  192. */
  193. value = (r->turn_off & ORION_TURN_OFF_MASK) << ORION_TURN_OFF_SHIFT |
  194. (r->acc_first & ORION_ACC_FIRST_MASK) << ORION_ACC_FIRST_SHIFT |
  195. (r->acc_next & ORION_ACC_NEXT_MASK) << ORION_ACC_NEXT_SHIFT |
  196. (w->ale_wr & ORION_ALE_WR_MASK) << ORION_ALE_WR_SHIFT |
  197. (w->wr_low & ORION_WR_LOW_MASK) << ORION_WR_LOW_SHIFT |
  198. (w->wr_high & ORION_WR_HIGH_MASK) << ORION_WR_HIGH_SHIFT |
  199. r->bus_width << ORION_DEV_WIDTH_SHIFT |
  200. ((r->turn_off & ORION_TURN_OFF_EXT_MASK) ? ORION_TURN_OFF_EXT_BIT : 0) |
  201. ((r->acc_first & ORION_ACC_FIRST_EXT_MASK) ? ORION_ACC_FIRST_EXT_BIT : 0) |
  202. ((r->acc_next & ORION_ACC_NEXT_EXT_MASK) ? ORION_ACC_NEXT_EXT_BIT : 0) |
  203. ((w->ale_wr & ORION_ALE_WR_EXT_MASK) ? ORION_ALE_WR_EXT_BIT : 0) |
  204. ((w->wr_low & ORION_WR_LOW_EXT_MASK) ? ORION_WR_LOW_EXT_BIT : 0) |
  205. ((w->wr_high & ORION_WR_HIGH_EXT_MASK) ? ORION_WR_HIGH_EXT_BIT : 0) |
  206. (r->badr_skew << ORION_BADR_SKEW_SHIFT) |
  207. ORION_RESERVED;
  208. writel(value, devbus->base);
  209. }
  210. static void devbus_armada_set_timing_params(struct devbus *devbus,
  211. struct device_node *node,
  212. struct devbus_read_params *r,
  213. struct devbus_write_params *w)
  214. {
  215. u32 value;
  216. /* Set read timings */
  217. value = r->bus_width << ARMADA_DEV_WIDTH_SHIFT |
  218. r->badr_skew << ARMADA_BADR_SKEW_SHIFT |
  219. r->rd_hold << ARMADA_RD_HOLD_SHIFT |
  220. r->acc_next << ARMADA_ACC_NEXT_SHIFT |
  221. r->rd_setup << ARMADA_RD_SETUP_SHIFT |
  222. r->acc_first << ARMADA_ACC_FIRST_SHIFT |
  223. r->turn_off;
  224. dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n",
  225. devbus->base + ARMADA_READ_PARAM_OFFSET,
  226. value);
  227. writel(value, devbus->base + ARMADA_READ_PARAM_OFFSET);
  228. /* Set write timings */
  229. value = w->sync_enable << ARMADA_SYNC_ENABLE_SHIFT |
  230. w->wr_low << ARMADA_WR_LOW_SHIFT |
  231. w->wr_high << ARMADA_WR_HIGH_SHIFT |
  232. w->ale_wr;
  233. dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n",
  234. devbus->base + ARMADA_WRITE_PARAM_OFFSET,
  235. value);
  236. writel(value, devbus->base + ARMADA_WRITE_PARAM_OFFSET);
  237. }
  238. static int mvebu_devbus_probe(struct platform_device *pdev)
  239. {
  240. struct device *dev = &pdev->dev;
  241. struct device_node *node = pdev->dev.of_node;
  242. struct devbus_read_params r;
  243. struct devbus_write_params w;
  244. struct devbus *devbus;
  245. struct resource *res;
  246. struct clk *clk;
  247. unsigned long rate;
  248. int err;
  249. devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL);
  250. if (!devbus)
  251. return -ENOMEM;
  252. devbus->dev = dev;
  253. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  254. devbus->base = devm_ioremap_resource(&pdev->dev, res);
  255. if (IS_ERR(devbus->base))
  256. return PTR_ERR(devbus->base);
  257. clk = devm_clk_get(&pdev->dev, NULL);
  258. if (IS_ERR(clk))
  259. return PTR_ERR(clk);
  260. clk_prepare_enable(clk);
  261. /*
  262. * Obtain clock period in picoseconds,
  263. * we need this in order to convert timing
  264. * parameters from cycles to picoseconds.
  265. */
  266. rate = clk_get_rate(clk) / 1000;
  267. devbus->tick_ps = 1000000000 / rate;
  268. dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n",
  269. devbus->tick_ps);
  270. if (!of_property_read_bool(node, "devbus,keep-config")) {
  271. /* Read the Device Tree node */
  272. err = devbus_get_timing_params(devbus, node, &r, &w);
  273. if (err < 0)
  274. return err;
  275. /* Set the new timing parameters */
  276. if (of_device_is_compatible(node, "marvell,orion-devbus"))
  277. devbus_orion_set_timing_params(devbus, node, &r, &w);
  278. else
  279. devbus_armada_set_timing_params(devbus, node, &r, &w);
  280. }
  281. /*
  282. * We need to create a child device explicitly from here to
  283. * guarantee that the child will be probed after the timing
  284. * parameters for the bus are written.
  285. */
  286. err = of_platform_populate(node, NULL, NULL, dev);
  287. if (err < 0)
  288. return err;
  289. return 0;
  290. }
  291. static const struct of_device_id mvebu_devbus_of_match[] = {
  292. { .compatible = "marvell,mvebu-devbus" },
  293. { .compatible = "marvell,orion-devbus" },
  294. {},
  295. };
  296. MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match);
  297. static struct platform_driver mvebu_devbus_driver = {
  298. .probe = mvebu_devbus_probe,
  299. .driver = {
  300. .name = "mvebu-devbus",
  301. .of_match_table = mvebu_devbus_of_match,
  302. },
  303. };
  304. static int __init mvebu_devbus_init(void)
  305. {
  306. return platform_driver_register(&mvebu_devbus_driver);
  307. }
  308. module_init(mvebu_devbus_init);
  309. MODULE_LICENSE("GPL v2");
  310. MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
  311. MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller");