atmel-ebi.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /*
  2. * EBI driver for Atmel chips
  3. * inspired by the fsl weim bus driver
  4. *
  5. * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
  6. *
  7. * This file is licensed under the terms of the GNU General Public
  8. * License version 2. This program is licensed "as is" without any
  9. * warranty of any kind, whether express or implied.
  10. */
  11. #include <linux/clk.h>
  12. #include <linux/io.h>
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/mfd/syscon/atmel-matrix.h>
  15. #include <linux/mfd/syscon/atmel-smc.h>
  16. #include <linux/init.h>
  17. #include <linux/of_device.h>
  18. #include <linux/regmap.h>
  19. struct atmel_ebi_dev_config {
  20. int cs;
  21. struct atmel_smc_cs_conf smcconf;
  22. };
  23. struct atmel_ebi;
  24. struct atmel_ebi_dev {
  25. struct list_head node;
  26. struct atmel_ebi *ebi;
  27. u32 mode;
  28. int numcs;
  29. struct atmel_ebi_dev_config configs[];
  30. };
  31. struct atmel_ebi_caps {
  32. unsigned int available_cs;
  33. unsigned int ebi_csa_offs;
  34. void (*get_config)(struct atmel_ebi_dev *ebid,
  35. struct atmel_ebi_dev_config *conf);
  36. int (*xlate_config)(struct atmel_ebi_dev *ebid,
  37. struct device_node *configs_np,
  38. struct atmel_ebi_dev_config *conf);
  39. void (*apply_config)(struct atmel_ebi_dev *ebid,
  40. struct atmel_ebi_dev_config *conf);
  41. };
  42. struct atmel_ebi {
  43. struct clk *clk;
  44. struct regmap *matrix;
  45. struct {
  46. struct regmap *regmap;
  47. struct clk *clk;
  48. } smc;
  49. struct device *dev;
  50. const struct atmel_ebi_caps *caps;
  51. struct list_head devs;
  52. };
  53. struct atmel_smc_timing_xlate {
  54. const char *name;
  55. int (*converter)(struct atmel_smc_cs_conf *conf,
  56. unsigned int shift, unsigned int nycles);
  57. unsigned int shift;
  58. };
  59. #define ATMEL_SMC_SETUP_XLATE(nm, pos) \
  60. { .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos}
  61. #define ATMEL_SMC_PULSE_XLATE(nm, pos) \
  62. { .name = nm, .converter = atmel_smc_cs_conf_set_pulse, .shift = pos}
  63. #define ATMEL_SMC_CYCLE_XLATE(nm, pos) \
  64. { .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos}
  65. static void at91sam9_ebi_get_config(struct atmel_ebi_dev *ebid,
  66. struct atmel_ebi_dev_config *conf)
  67. {
  68. atmel_smc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs,
  69. &conf->smcconf);
  70. }
  71. static void sama5_ebi_get_config(struct atmel_ebi_dev *ebid,
  72. struct atmel_ebi_dev_config *conf)
  73. {
  74. atmel_hsmc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs,
  75. &conf->smcconf);
  76. }
  77. static const struct atmel_smc_timing_xlate timings_xlate_table[] = {
  78. ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-rd-setup-ns",
  79. ATMEL_SMC_NCS_RD_SHIFT),
  80. ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-wr-setup-ns",
  81. ATMEL_SMC_NCS_WR_SHIFT),
  82. ATMEL_SMC_SETUP_XLATE("atmel,smc-nrd-setup-ns", ATMEL_SMC_NRD_SHIFT),
  83. ATMEL_SMC_SETUP_XLATE("atmel,smc-nwe-setup-ns", ATMEL_SMC_NWE_SHIFT),
  84. ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-rd-pulse-ns",
  85. ATMEL_SMC_NCS_RD_SHIFT),
  86. ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-wr-pulse-ns",
  87. ATMEL_SMC_NCS_WR_SHIFT),
  88. ATMEL_SMC_PULSE_XLATE("atmel,smc-nrd-pulse-ns", ATMEL_SMC_NRD_SHIFT),
  89. ATMEL_SMC_PULSE_XLATE("atmel,smc-nwe-pulse-ns", ATMEL_SMC_NWE_SHIFT),
  90. ATMEL_SMC_CYCLE_XLATE("atmel,smc-nrd-cycle-ns", ATMEL_SMC_NRD_SHIFT),
  91. ATMEL_SMC_CYCLE_XLATE("atmel,smc-nwe-cycle-ns", ATMEL_SMC_NWE_SHIFT),
  92. };
  93. static int atmel_ebi_xslate_smc_timings(struct atmel_ebi_dev *ebid,
  94. struct device_node *np,
  95. struct atmel_smc_cs_conf *smcconf)
  96. {
  97. unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
  98. unsigned int clk_period_ns = NSEC_PER_SEC / clk_rate;
  99. bool required = false;
  100. unsigned int ncycles;
  101. int ret, i;
  102. u32 val;
  103. ret = of_property_read_u32(np, "atmel,smc-tdf-ns", &val);
  104. if (!ret) {
  105. required = true;
  106. ncycles = DIV_ROUND_UP(val, clk_period_ns);
  107. if (ncycles > ATMEL_SMC_MODE_TDF_MAX ||
  108. ncycles < ATMEL_SMC_MODE_TDF_MIN) {
  109. ret = -EINVAL;
  110. goto out;
  111. }
  112. smcconf->mode |= ATMEL_SMC_MODE_TDF(ncycles);
  113. }
  114. for (i = 0; i < ARRAY_SIZE(timings_xlate_table); i++) {
  115. const struct atmel_smc_timing_xlate *xlate;
  116. xlate = &timings_xlate_table[i];
  117. ret = of_property_read_u32(np, xlate->name, &val);
  118. if (ret) {
  119. if (!required)
  120. continue;
  121. else
  122. break;
  123. }
  124. if (!required) {
  125. ret = -EINVAL;
  126. break;
  127. }
  128. ncycles = DIV_ROUND_UP(val, clk_period_ns);
  129. ret = xlate->converter(smcconf, xlate->shift, ncycles);
  130. if (ret)
  131. goto out;
  132. }
  133. out:
  134. if (ret) {
  135. dev_err(ebid->ebi->dev,
  136. "missing or invalid timings definition in %pOF",
  137. np);
  138. return ret;
  139. }
  140. return required;
  141. }
  142. static int atmel_ebi_xslate_smc_config(struct atmel_ebi_dev *ebid,
  143. struct device_node *np,
  144. struct atmel_ebi_dev_config *conf)
  145. {
  146. struct atmel_smc_cs_conf *smcconf = &conf->smcconf;
  147. bool required = false;
  148. const char *tmp_str;
  149. u32 tmp;
  150. int ret;
  151. ret = of_property_read_u32(np, "atmel,smc-bus-width", &tmp);
  152. if (!ret) {
  153. switch (tmp) {
  154. case 8:
  155. smcconf->mode |= ATMEL_SMC_MODE_DBW_8;
  156. break;
  157. case 16:
  158. smcconf->mode |= ATMEL_SMC_MODE_DBW_16;
  159. break;
  160. case 32:
  161. smcconf->mode |= ATMEL_SMC_MODE_DBW_32;
  162. break;
  163. default:
  164. return -EINVAL;
  165. }
  166. required = true;
  167. }
  168. if (of_property_read_bool(np, "atmel,smc-tdf-optimized")) {
  169. smcconf->mode |= ATMEL_SMC_MODE_TDFMODE_OPTIMIZED;
  170. required = true;
  171. }
  172. tmp_str = NULL;
  173. of_property_read_string(np, "atmel,smc-byte-access-type", &tmp_str);
  174. if (tmp_str && !strcmp(tmp_str, "write")) {
  175. smcconf->mode |= ATMEL_SMC_MODE_BAT_WRITE;
  176. required = true;
  177. }
  178. tmp_str = NULL;
  179. of_property_read_string(np, "atmel,smc-read-mode", &tmp_str);
  180. if (tmp_str && !strcmp(tmp_str, "nrd")) {
  181. smcconf->mode |= ATMEL_SMC_MODE_READMODE_NRD;
  182. required = true;
  183. }
  184. tmp_str = NULL;
  185. of_property_read_string(np, "atmel,smc-write-mode", &tmp_str);
  186. if (tmp_str && !strcmp(tmp_str, "nwe")) {
  187. smcconf->mode |= ATMEL_SMC_MODE_WRITEMODE_NWE;
  188. required = true;
  189. }
  190. tmp_str = NULL;
  191. of_property_read_string(np, "atmel,smc-exnw-mode", &tmp_str);
  192. if (tmp_str) {
  193. if (!strcmp(tmp_str, "frozen"))
  194. smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_FROZEN;
  195. else if (!strcmp(tmp_str, "ready"))
  196. smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_READY;
  197. else if (strcmp(tmp_str, "disabled"))
  198. return -EINVAL;
  199. required = true;
  200. }
  201. ret = of_property_read_u32(np, "atmel,smc-page-mode", &tmp);
  202. if (!ret) {
  203. switch (tmp) {
  204. case 4:
  205. smcconf->mode |= ATMEL_SMC_MODE_PS_4;
  206. break;
  207. case 8:
  208. smcconf->mode |= ATMEL_SMC_MODE_PS_8;
  209. break;
  210. case 16:
  211. smcconf->mode |= ATMEL_SMC_MODE_PS_16;
  212. break;
  213. case 32:
  214. smcconf->mode |= ATMEL_SMC_MODE_PS_32;
  215. break;
  216. default:
  217. return -EINVAL;
  218. }
  219. smcconf->mode |= ATMEL_SMC_MODE_PMEN;
  220. required = true;
  221. }
  222. ret = atmel_ebi_xslate_smc_timings(ebid, np, &conf->smcconf);
  223. if (ret)
  224. return -EINVAL;
  225. if ((ret > 0 && !required) || (!ret && required)) {
  226. dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %pOF",
  227. np);
  228. return -EINVAL;
  229. }
  230. return required;
  231. }
  232. static void at91sam9_ebi_apply_config(struct atmel_ebi_dev *ebid,
  233. struct atmel_ebi_dev_config *conf)
  234. {
  235. atmel_smc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs,
  236. &conf->smcconf);
  237. }
  238. static void sama5_ebi_apply_config(struct atmel_ebi_dev *ebid,
  239. struct atmel_ebi_dev_config *conf)
  240. {
  241. atmel_hsmc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs,
  242. &conf->smcconf);
  243. }
  244. static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
  245. int reg_cells)
  246. {
  247. const struct atmel_ebi_caps *caps = ebi->caps;
  248. struct atmel_ebi_dev_config conf = { };
  249. struct device *dev = ebi->dev;
  250. struct atmel_ebi_dev *ebid;
  251. unsigned long cslines = 0;
  252. int ret, numcs = 0, nentries, i;
  253. bool apply = false;
  254. u32 cs;
  255. nentries = of_property_count_elems_of_size(np, "reg",
  256. reg_cells * sizeof(u32));
  257. for (i = 0; i < nentries; i++) {
  258. ret = of_property_read_u32_index(np, "reg", i * reg_cells,
  259. &cs);
  260. if (ret)
  261. return ret;
  262. if (cs >= AT91_MATRIX_EBI_NUM_CS ||
  263. !(ebi->caps->available_cs & BIT(cs))) {
  264. dev_err(dev, "invalid reg property in %pOF\n", np);
  265. return -EINVAL;
  266. }
  267. if (!test_and_set_bit(cs, &cslines))
  268. numcs++;
  269. }
  270. if (!numcs) {
  271. dev_err(dev, "invalid reg property in %pOF\n", np);
  272. return -EINVAL;
  273. }
  274. ebid = devm_kzalloc(ebi->dev,
  275. sizeof(*ebid) + (numcs * sizeof(*ebid->configs)),
  276. GFP_KERNEL);
  277. if (!ebid)
  278. return -ENOMEM;
  279. ebid->ebi = ebi;
  280. ebid->numcs = numcs;
  281. ret = caps->xlate_config(ebid, np, &conf);
  282. if (ret < 0)
  283. return ret;
  284. else if (ret)
  285. apply = true;
  286. i = 0;
  287. for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) {
  288. ebid->configs[i].cs = cs;
  289. if (apply) {
  290. conf.cs = cs;
  291. caps->apply_config(ebid, &conf);
  292. }
  293. caps->get_config(ebid, &ebid->configs[i]);
  294. /*
  295. * Attach the EBI device to the generic SMC logic if at least
  296. * one "atmel,smc-" property is present.
  297. */
  298. if (ebi->caps->ebi_csa_offs && apply)
  299. regmap_update_bits(ebi->matrix,
  300. ebi->caps->ebi_csa_offs,
  301. BIT(cs), 0);
  302. i++;
  303. }
  304. list_add_tail(&ebid->node, &ebi->devs);
  305. return 0;
  306. }
  307. static const struct atmel_ebi_caps at91sam9260_ebi_caps = {
  308. .available_cs = 0xff,
  309. .ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA,
  310. .get_config = at91sam9_ebi_get_config,
  311. .xlate_config = atmel_ebi_xslate_smc_config,
  312. .apply_config = at91sam9_ebi_apply_config,
  313. };
  314. static const struct atmel_ebi_caps at91sam9261_ebi_caps = {
  315. .available_cs = 0xff,
  316. .ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA,
  317. .get_config = at91sam9_ebi_get_config,
  318. .xlate_config = atmel_ebi_xslate_smc_config,
  319. .apply_config = at91sam9_ebi_apply_config,
  320. };
  321. static const struct atmel_ebi_caps at91sam9263_ebi0_caps = {
  322. .available_cs = 0x3f,
  323. .ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA,
  324. .get_config = at91sam9_ebi_get_config,
  325. .xlate_config = atmel_ebi_xslate_smc_config,
  326. .apply_config = at91sam9_ebi_apply_config,
  327. };
  328. static const struct atmel_ebi_caps at91sam9263_ebi1_caps = {
  329. .available_cs = 0x7,
  330. .ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA,
  331. .get_config = at91sam9_ebi_get_config,
  332. .xlate_config = atmel_ebi_xslate_smc_config,
  333. .apply_config = at91sam9_ebi_apply_config,
  334. };
  335. static const struct atmel_ebi_caps at91sam9rl_ebi_caps = {
  336. .available_cs = 0x3f,
  337. .ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA,
  338. .get_config = at91sam9_ebi_get_config,
  339. .xlate_config = atmel_ebi_xslate_smc_config,
  340. .apply_config = at91sam9_ebi_apply_config,
  341. };
  342. static const struct atmel_ebi_caps at91sam9g45_ebi_caps = {
  343. .available_cs = 0x3f,
  344. .ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA,
  345. .get_config = at91sam9_ebi_get_config,
  346. .xlate_config = atmel_ebi_xslate_smc_config,
  347. .apply_config = at91sam9_ebi_apply_config,
  348. };
  349. static const struct atmel_ebi_caps at91sam9x5_ebi_caps = {
  350. .available_cs = 0x3f,
  351. .ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA,
  352. .get_config = at91sam9_ebi_get_config,
  353. .xlate_config = atmel_ebi_xslate_smc_config,
  354. .apply_config = at91sam9_ebi_apply_config,
  355. };
  356. static const struct atmel_ebi_caps sama5d3_ebi_caps = {
  357. .available_cs = 0xf,
  358. .get_config = sama5_ebi_get_config,
  359. .xlate_config = atmel_ebi_xslate_smc_config,
  360. .apply_config = sama5_ebi_apply_config,
  361. };
  362. static const struct of_device_id atmel_ebi_id_table[] = {
  363. {
  364. .compatible = "atmel,at91sam9260-ebi",
  365. .data = &at91sam9260_ebi_caps,
  366. },
  367. {
  368. .compatible = "atmel,at91sam9261-ebi",
  369. .data = &at91sam9261_ebi_caps,
  370. },
  371. {
  372. .compatible = "atmel,at91sam9263-ebi0",
  373. .data = &at91sam9263_ebi0_caps,
  374. },
  375. {
  376. .compatible = "atmel,at91sam9263-ebi1",
  377. .data = &at91sam9263_ebi1_caps,
  378. },
  379. {
  380. .compatible = "atmel,at91sam9rl-ebi",
  381. .data = &at91sam9rl_ebi_caps,
  382. },
  383. {
  384. .compatible = "atmel,at91sam9g45-ebi",
  385. .data = &at91sam9g45_ebi_caps,
  386. },
  387. {
  388. .compatible = "atmel,at91sam9x5-ebi",
  389. .data = &at91sam9x5_ebi_caps,
  390. },
  391. {
  392. .compatible = "atmel,sama5d3-ebi",
  393. .data = &sama5d3_ebi_caps,
  394. },
  395. { /* sentinel */ }
  396. };
  397. static int atmel_ebi_dev_disable(struct atmel_ebi *ebi, struct device_node *np)
  398. {
  399. struct device *dev = ebi->dev;
  400. struct property *newprop;
  401. newprop = devm_kzalloc(dev, sizeof(*newprop), GFP_KERNEL);
  402. if (!newprop)
  403. return -ENOMEM;
  404. newprop->name = devm_kstrdup(dev, "status", GFP_KERNEL);
  405. if (!newprop->name)
  406. return -ENOMEM;
  407. newprop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
  408. if (!newprop->value)
  409. return -ENOMEM;
  410. newprop->length = sizeof("disabled");
  411. return of_update_property(np, newprop);
  412. }
  413. static int atmel_ebi_probe(struct platform_device *pdev)
  414. {
  415. struct device *dev = &pdev->dev;
  416. struct device_node *child, *np = dev->of_node, *smc_np;
  417. const struct of_device_id *match;
  418. struct atmel_ebi *ebi;
  419. int ret, reg_cells;
  420. struct clk *clk;
  421. u32 val;
  422. match = of_match_device(atmel_ebi_id_table, dev);
  423. if (!match || !match->data)
  424. return -EINVAL;
  425. ebi = devm_kzalloc(dev, sizeof(*ebi), GFP_KERNEL);
  426. if (!ebi)
  427. return -ENOMEM;
  428. platform_set_drvdata(pdev, ebi);
  429. INIT_LIST_HEAD(&ebi->devs);
  430. ebi->caps = match->data;
  431. ebi->dev = dev;
  432. clk = devm_clk_get(dev, NULL);
  433. if (IS_ERR(clk))
  434. return PTR_ERR(clk);
  435. ebi->clk = clk;
  436. smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0);
  437. ebi->smc.regmap = syscon_node_to_regmap(smc_np);
  438. if (IS_ERR(ebi->smc.regmap))
  439. return PTR_ERR(ebi->smc.regmap);
  440. ebi->smc.clk = of_clk_get(smc_np, 0);
  441. if (IS_ERR(ebi->smc.clk)) {
  442. if (PTR_ERR(ebi->smc.clk) != -ENOENT)
  443. return PTR_ERR(ebi->smc.clk);
  444. ebi->smc.clk = NULL;
  445. }
  446. ret = clk_prepare_enable(ebi->smc.clk);
  447. if (ret)
  448. return ret;
  449. /*
  450. * The sama5d3 does not provide an EBICSA register and thus does need
  451. * to access the matrix registers.
  452. */
  453. if (ebi->caps->ebi_csa_offs) {
  454. ebi->matrix =
  455. syscon_regmap_lookup_by_phandle(np, "atmel,matrix");
  456. if (IS_ERR(ebi->matrix))
  457. return PTR_ERR(ebi->matrix);
  458. }
  459. ret = of_property_read_u32(np, "#address-cells", &val);
  460. if (ret) {
  461. dev_err(dev, "missing #address-cells property\n");
  462. return ret;
  463. }
  464. reg_cells = val;
  465. ret = of_property_read_u32(np, "#size-cells", &val);
  466. if (ret) {
  467. dev_err(dev, "missing #address-cells property\n");
  468. return ret;
  469. }
  470. reg_cells += val;
  471. for_each_available_child_of_node(np, child) {
  472. if (!of_find_property(child, "reg", NULL))
  473. continue;
  474. ret = atmel_ebi_dev_setup(ebi, child, reg_cells);
  475. if (ret) {
  476. dev_err(dev, "failed to configure EBI bus for %pOF, disabling the device",
  477. child);
  478. ret = atmel_ebi_dev_disable(ebi, child);
  479. if (ret)
  480. return ret;
  481. }
  482. }
  483. return of_platform_populate(np, NULL, NULL, dev);
  484. }
  485. static __maybe_unused int atmel_ebi_resume(struct device *dev)
  486. {
  487. struct atmel_ebi *ebi = dev_get_drvdata(dev);
  488. struct atmel_ebi_dev *ebid;
  489. list_for_each_entry(ebid, &ebi->devs, node) {
  490. int i;
  491. for (i = 0; i < ebid->numcs; i++)
  492. ebid->ebi->caps->apply_config(ebid, &ebid->configs[i]);
  493. }
  494. return 0;
  495. }
  496. static SIMPLE_DEV_PM_OPS(atmel_ebi_pm_ops, NULL, atmel_ebi_resume);
  497. static struct platform_driver atmel_ebi_driver = {
  498. .driver = {
  499. .name = "atmel-ebi",
  500. .of_match_table = atmel_ebi_id_table,
  501. .pm = &atmel_ebi_pm_ops,
  502. },
  503. };
  504. builtin_platform_driver_probe(atmel_ebi_driver, atmel_ebi_probe);