atmel-ebi.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  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 %s",
  137. np->full_name);
  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 %s",
  227. np->full_name);
  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 %s\n",
  265. np->full_name);
  266. return -EINVAL;
  267. }
  268. if (!test_and_set_bit(cs, &cslines))
  269. numcs++;
  270. }
  271. if (!numcs) {
  272. dev_err(dev, "invalid reg property in %s\n", np->full_name);
  273. return -EINVAL;
  274. }
  275. ebid = devm_kzalloc(ebi->dev,
  276. sizeof(*ebid) + (numcs * sizeof(*ebid->configs)),
  277. GFP_KERNEL);
  278. if (!ebid)
  279. return -ENOMEM;
  280. ebid->ebi = ebi;
  281. ebid->numcs = numcs;
  282. ret = caps->xlate_config(ebid, np, &conf);
  283. if (ret < 0)
  284. return ret;
  285. else if (ret)
  286. apply = true;
  287. i = 0;
  288. for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) {
  289. ebid->configs[i].cs = cs;
  290. if (apply) {
  291. conf.cs = cs;
  292. caps->apply_config(ebid, &conf);
  293. }
  294. caps->get_config(ebid, &ebid->configs[i]);
  295. /*
  296. * Attach the EBI device to the generic SMC logic if at least
  297. * one "atmel,smc-" property is present.
  298. */
  299. if (ebi->caps->ebi_csa_offs && apply)
  300. regmap_update_bits(ebi->matrix,
  301. ebi->caps->ebi_csa_offs,
  302. BIT(cs), 0);
  303. i++;
  304. }
  305. list_add_tail(&ebid->node, &ebi->devs);
  306. return 0;
  307. }
  308. static const struct atmel_ebi_caps at91sam9260_ebi_caps = {
  309. .available_cs = 0xff,
  310. .ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA,
  311. .get_config = at91sam9_ebi_get_config,
  312. .xlate_config = atmel_ebi_xslate_smc_config,
  313. .apply_config = at91sam9_ebi_apply_config,
  314. };
  315. static const struct atmel_ebi_caps at91sam9261_ebi_caps = {
  316. .available_cs = 0xff,
  317. .ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA,
  318. .get_config = at91sam9_ebi_get_config,
  319. .xlate_config = atmel_ebi_xslate_smc_config,
  320. .apply_config = at91sam9_ebi_apply_config,
  321. };
  322. static const struct atmel_ebi_caps at91sam9263_ebi0_caps = {
  323. .available_cs = 0x3f,
  324. .ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA,
  325. .get_config = at91sam9_ebi_get_config,
  326. .xlate_config = atmel_ebi_xslate_smc_config,
  327. .apply_config = at91sam9_ebi_apply_config,
  328. };
  329. static const struct atmel_ebi_caps at91sam9263_ebi1_caps = {
  330. .available_cs = 0x7,
  331. .ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA,
  332. .get_config = at91sam9_ebi_get_config,
  333. .xlate_config = atmel_ebi_xslate_smc_config,
  334. .apply_config = at91sam9_ebi_apply_config,
  335. };
  336. static const struct atmel_ebi_caps at91sam9rl_ebi_caps = {
  337. .available_cs = 0x3f,
  338. .ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA,
  339. .get_config = at91sam9_ebi_get_config,
  340. .xlate_config = atmel_ebi_xslate_smc_config,
  341. .apply_config = at91sam9_ebi_apply_config,
  342. };
  343. static const struct atmel_ebi_caps at91sam9g45_ebi_caps = {
  344. .available_cs = 0x3f,
  345. .ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA,
  346. .get_config = at91sam9_ebi_get_config,
  347. .xlate_config = atmel_ebi_xslate_smc_config,
  348. .apply_config = at91sam9_ebi_apply_config,
  349. };
  350. static const struct atmel_ebi_caps at91sam9x5_ebi_caps = {
  351. .available_cs = 0x3f,
  352. .ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA,
  353. .get_config = at91sam9_ebi_get_config,
  354. .xlate_config = atmel_ebi_xslate_smc_config,
  355. .apply_config = at91sam9_ebi_apply_config,
  356. };
  357. static const struct atmel_ebi_caps sama5d3_ebi_caps = {
  358. .available_cs = 0xf,
  359. .get_config = sama5_ebi_get_config,
  360. .xlate_config = atmel_ebi_xslate_smc_config,
  361. .apply_config = sama5_ebi_apply_config,
  362. };
  363. static const struct of_device_id atmel_ebi_id_table[] = {
  364. {
  365. .compatible = "atmel,at91sam9260-ebi",
  366. .data = &at91sam9260_ebi_caps,
  367. },
  368. {
  369. .compatible = "atmel,at91sam9261-ebi",
  370. .data = &at91sam9261_ebi_caps,
  371. },
  372. {
  373. .compatible = "atmel,at91sam9263-ebi0",
  374. .data = &at91sam9263_ebi0_caps,
  375. },
  376. {
  377. .compatible = "atmel,at91sam9263-ebi1",
  378. .data = &at91sam9263_ebi1_caps,
  379. },
  380. {
  381. .compatible = "atmel,at91sam9rl-ebi",
  382. .data = &at91sam9rl_ebi_caps,
  383. },
  384. {
  385. .compatible = "atmel,at91sam9g45-ebi",
  386. .data = &at91sam9g45_ebi_caps,
  387. },
  388. {
  389. .compatible = "atmel,at91sam9x5-ebi",
  390. .data = &at91sam9x5_ebi_caps,
  391. },
  392. {
  393. .compatible = "atmel,sama5d3-ebi",
  394. .data = &sama5d3_ebi_caps,
  395. },
  396. { /* sentinel */ }
  397. };
  398. static int atmel_ebi_dev_disable(struct atmel_ebi *ebi, struct device_node *np)
  399. {
  400. struct device *dev = ebi->dev;
  401. struct property *newprop;
  402. newprop = devm_kzalloc(dev, sizeof(*newprop), GFP_KERNEL);
  403. if (!newprop)
  404. return -ENOMEM;
  405. newprop->name = devm_kstrdup(dev, "status", GFP_KERNEL);
  406. if (!newprop->name)
  407. return -ENOMEM;
  408. newprop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
  409. if (!newprop->value)
  410. return -ENOMEM;
  411. newprop->length = sizeof("disabled");
  412. return of_update_property(np, newprop);
  413. }
  414. static int atmel_ebi_probe(struct platform_device *pdev)
  415. {
  416. struct device *dev = &pdev->dev;
  417. struct device_node *child, *np = dev->of_node, *smc_np;
  418. const struct of_device_id *match;
  419. struct atmel_ebi *ebi;
  420. int ret, reg_cells;
  421. struct clk *clk;
  422. u32 val;
  423. match = of_match_device(atmel_ebi_id_table, dev);
  424. if (!match || !match->data)
  425. return -EINVAL;
  426. ebi = devm_kzalloc(dev, sizeof(*ebi), GFP_KERNEL);
  427. if (!ebi)
  428. return -ENOMEM;
  429. platform_set_drvdata(pdev, ebi);
  430. INIT_LIST_HEAD(&ebi->devs);
  431. ebi->caps = match->data;
  432. ebi->dev = dev;
  433. clk = devm_clk_get(dev, NULL);
  434. if (IS_ERR(clk))
  435. return PTR_ERR(clk);
  436. ebi->clk = clk;
  437. smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0);
  438. ebi->smc.regmap = syscon_node_to_regmap(smc_np);
  439. if (IS_ERR(ebi->smc.regmap))
  440. return PTR_ERR(ebi->smc.regmap);
  441. ebi->smc.clk = of_clk_get(smc_np, 0);
  442. if (IS_ERR(ebi->smc.clk)) {
  443. if (PTR_ERR(ebi->smc.clk) != -ENOENT)
  444. return PTR_ERR(ebi->smc.clk);
  445. ebi->smc.clk = NULL;
  446. }
  447. ret = clk_prepare_enable(ebi->smc.clk);
  448. if (ret)
  449. return ret;
  450. /*
  451. * The sama5d3 does not provide an EBICSA register and thus does need
  452. * to access the matrix registers.
  453. */
  454. if (ebi->caps->ebi_csa_offs) {
  455. ebi->matrix =
  456. syscon_regmap_lookup_by_phandle(np, "atmel,matrix");
  457. if (IS_ERR(ebi->matrix))
  458. return PTR_ERR(ebi->matrix);
  459. }
  460. ret = of_property_read_u32(np, "#address-cells", &val);
  461. if (ret) {
  462. dev_err(dev, "missing #address-cells property\n");
  463. return ret;
  464. }
  465. reg_cells = val;
  466. ret = of_property_read_u32(np, "#size-cells", &val);
  467. if (ret) {
  468. dev_err(dev, "missing #address-cells property\n");
  469. return ret;
  470. }
  471. reg_cells += val;
  472. for_each_available_child_of_node(np, child) {
  473. if (!of_find_property(child, "reg", NULL))
  474. continue;
  475. ret = atmel_ebi_dev_setup(ebi, child, reg_cells);
  476. if (ret) {
  477. dev_err(dev, "failed to configure EBI bus for %s, disabling the device",
  478. child->full_name);
  479. ret = atmel_ebi_dev_disable(ebi, child);
  480. if (ret)
  481. return ret;
  482. }
  483. }
  484. return of_platform_populate(np, NULL, NULL, dev);
  485. }
  486. static int atmel_ebi_resume(struct device *dev)
  487. {
  488. struct atmel_ebi *ebi = dev_get_drvdata(dev);
  489. struct atmel_ebi_dev *ebid;
  490. list_for_each_entry(ebid, &ebi->devs, node) {
  491. int i;
  492. for (i = 0; i < ebid->numcs; i++)
  493. ebid->ebi->caps->apply_config(ebid, &ebid->configs[i]);
  494. }
  495. return 0;
  496. }
  497. static SIMPLE_DEV_PM_OPS(atmel_ebi_pm_ops, NULL, atmel_ebi_resume);
  498. static struct platform_driver atmel_ebi_driver = {
  499. .driver = {
  500. .name = "atmel-ebi",
  501. .of_match_table = atmel_ebi_id_table,
  502. .pm = &atmel_ebi_pm_ops,
  503. },
  504. };
  505. builtin_platform_driver_probe(atmel_ebi_driver, atmel_ebi_probe);