compat.c 22 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Compatible code for non CCF AT91 platforms.
  4. *
  5. * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
  6. *
  7. * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
  8. */
  9. #include <common.h>
  10. #include <clk-uclass.h>
  11. #include <dm.h>
  12. #include <asm/global_data.h>
  13. #include <dm/device_compat.h>
  14. #include <dm/lists.h>
  15. #include <dm/util.h>
  16. #include <mach/at91_pmc.h>
  17. #include <mach/at91_sfr.h>
  18. #include <regmap.h>
  19. #include <syscon.h>
  20. #include "pmc.h"
  21. DECLARE_GLOBAL_DATA_PTR;
  22. struct pmc_plat {
  23. struct at91_pmc *reg_base;
  24. struct regmap *regmap_sfr;
  25. };
  26. static const struct udevice_id at91_pmc_match[] = {
  27. { .compatible = "atmel,at91rm9200-pmc" },
  28. { .compatible = "atmel,at91sam9260-pmc" },
  29. { .compatible = "atmel,at91sam9g45-pmc" },
  30. { .compatible = "atmel,at91sam9n12-pmc" },
  31. { .compatible = "atmel,at91sam9x5-pmc" },
  32. { .compatible = "atmel,sama5d3-pmc" },
  33. { .compatible = "atmel,sama5d2-pmc" },
  34. {}
  35. };
  36. U_BOOT_DRIVER(at91_pmc) = {
  37. .name = "at91-pmc",
  38. .id = UCLASS_SIMPLE_BUS,
  39. .of_match = at91_pmc_match,
  40. };
  41. static int at91_pmc_core_probe(struct udevice *dev)
  42. {
  43. struct pmc_plat *plat = dev_get_plat(dev);
  44. dev = dev_get_parent(dev);
  45. plat->reg_base = dev_read_addr_ptr(dev);
  46. return 0;
  47. }
  48. /**
  49. * at91_clk_sub_device_bind() - for the at91 clock driver
  50. * Recursively bind its children as clk devices.
  51. *
  52. * @return: 0 on success, or negative error code on failure
  53. */
  54. int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
  55. {
  56. const void *fdt = gd->fdt_blob;
  57. int offset = dev_of_offset(dev);
  58. bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
  59. const char *name;
  60. int ret;
  61. for (offset = fdt_first_subnode(fdt, offset);
  62. offset > 0;
  63. offset = fdt_next_subnode(fdt, offset)) {
  64. if (pre_reloc_only &&
  65. !ofnode_pre_reloc(offset_to_ofnode(offset)))
  66. continue;
  67. /*
  68. * If this node has "compatible" property, this is not
  69. * a clock sub-node, but a normal device. skip.
  70. */
  71. fdt_get_property(fdt, offset, "compatible", &ret);
  72. if (ret >= 0)
  73. continue;
  74. if (ret != -FDT_ERR_NOTFOUND)
  75. return ret;
  76. name = fdt_get_name(fdt, offset, NULL);
  77. if (!name)
  78. return -EINVAL;
  79. ret = device_bind_driver_to_node(dev, drv_name, name,
  80. offset_to_ofnode(offset), NULL);
  81. if (ret)
  82. return ret;
  83. }
  84. return 0;
  85. }
  86. int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
  87. {
  88. int periph;
  89. if (args->args_count) {
  90. debug("Invalid args_count: %d\n", args->args_count);
  91. return -EINVAL;
  92. }
  93. periph = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(clk->dev), "reg",
  94. -1);
  95. if (periph < 0)
  96. return -EINVAL;
  97. clk->id = periph;
  98. return 0;
  99. }
  100. int at91_clk_probe(struct udevice *dev)
  101. {
  102. struct udevice *dev_periph_container, *dev_pmc;
  103. struct pmc_plat *plat = dev_get_plat(dev);
  104. dev_periph_container = dev_get_parent(dev);
  105. dev_pmc = dev_get_parent(dev_periph_container);
  106. plat->reg_base = dev_read_addr_ptr(dev_pmc);
  107. return 0;
  108. }
  109. /* SCKC specific code. */
  110. static const struct udevice_id at91_sckc_match[] = {
  111. { .compatible = "atmel,at91sam9x5-sckc" },
  112. {}
  113. };
  114. U_BOOT_DRIVER(at91_sckc) = {
  115. .name = "at91-sckc",
  116. .id = UCLASS_SIMPLE_BUS,
  117. .of_match = at91_sckc_match,
  118. };
  119. /* Slow clock specific code. */
  120. static int at91_slow_clk_enable(struct clk *clk)
  121. {
  122. return 0;
  123. }
  124. static ulong at91_slow_clk_get_rate(struct clk *clk)
  125. {
  126. return CONFIG_SYS_AT91_SLOW_CLOCK;
  127. }
  128. static struct clk_ops at91_slow_clk_ops = {
  129. .enable = at91_slow_clk_enable,
  130. .get_rate = at91_slow_clk_get_rate,
  131. };
  132. static const struct udevice_id at91_slow_clk_match[] = {
  133. { .compatible = "atmel,at91sam9x5-clk-slow" },
  134. {}
  135. };
  136. U_BOOT_DRIVER(at91_slow_clk) = {
  137. .name = "at91-slow-clk",
  138. .id = UCLASS_CLK,
  139. .of_match = at91_slow_clk_match,
  140. .ops = &at91_slow_clk_ops,
  141. };
  142. /* Master clock specific code. */
  143. static ulong at91_master_clk_get_rate(struct clk *clk)
  144. {
  145. return gd->arch.mck_rate_hz;
  146. }
  147. static struct clk_ops at91_master_clk_ops = {
  148. .get_rate = at91_master_clk_get_rate,
  149. };
  150. static const struct udevice_id at91_master_clk_match[] = {
  151. { .compatible = "atmel,at91rm9200-clk-master" },
  152. { .compatible = "atmel,at91sam9x5-clk-master" },
  153. {}
  154. };
  155. U_BOOT_DRIVER(at91_master_clk) = {
  156. .name = "at91-master-clk",
  157. .id = UCLASS_CLK,
  158. .of_match = at91_master_clk_match,
  159. .ops = &at91_master_clk_ops,
  160. };
  161. /* Main osc clock specific code. */
  162. static int main_osc_clk_enable(struct clk *clk)
  163. {
  164. struct pmc_plat *plat = dev_get_plat(clk->dev);
  165. struct at91_pmc *pmc = plat->reg_base;
  166. if (readl(&pmc->sr) & AT91_PMC_MOSCSELS)
  167. return 0;
  168. return -EINVAL;
  169. }
  170. static ulong main_osc_clk_get_rate(struct clk *clk)
  171. {
  172. return gd->arch.main_clk_rate_hz;
  173. }
  174. static struct clk_ops main_osc_clk_ops = {
  175. .enable = main_osc_clk_enable,
  176. .get_rate = main_osc_clk_get_rate,
  177. };
  178. static int main_osc_clk_probe(struct udevice *dev)
  179. {
  180. return at91_pmc_core_probe(dev);
  181. }
  182. static const struct udevice_id main_osc_clk_match[] = {
  183. { .compatible = "atmel,at91sam9x5-clk-main" },
  184. {}
  185. };
  186. U_BOOT_DRIVER(at91sam9x5_main_osc_clk) = {
  187. .name = "at91sam9x5-main-osc-clk",
  188. .id = UCLASS_CLK,
  189. .of_match = main_osc_clk_match,
  190. .probe = main_osc_clk_probe,
  191. .plat_auto = sizeof(struct pmc_plat),
  192. .ops = &main_osc_clk_ops,
  193. };
  194. /* PLLA clock specific code. */
  195. static int plla_clk_enable(struct clk *clk)
  196. {
  197. struct pmc_plat *plat = dev_get_plat(clk->dev);
  198. struct at91_pmc *pmc = plat->reg_base;
  199. if (readl(&pmc->sr) & AT91_PMC_LOCKA)
  200. return 0;
  201. return -EINVAL;
  202. }
  203. static ulong plla_clk_get_rate(struct clk *clk)
  204. {
  205. return gd->arch.plla_rate_hz;
  206. }
  207. static struct clk_ops plla_clk_ops = {
  208. .enable = plla_clk_enable,
  209. .get_rate = plla_clk_get_rate,
  210. };
  211. static int plla_clk_probe(struct udevice *dev)
  212. {
  213. return at91_pmc_core_probe(dev);
  214. }
  215. static const struct udevice_id plla_clk_match[] = {
  216. { .compatible = "atmel,sama5d3-clk-pll" },
  217. {}
  218. };
  219. U_BOOT_DRIVER(at91_plla_clk) = {
  220. .name = "at91-plla-clk",
  221. .id = UCLASS_CLK,
  222. .of_match = plla_clk_match,
  223. .probe = plla_clk_probe,
  224. .plat_auto = sizeof(struct pmc_plat),
  225. .ops = &plla_clk_ops,
  226. };
  227. /* PLLA DIV clock specific code. */
  228. static int at91_plladiv_clk_enable(struct clk *clk)
  229. {
  230. return 0;
  231. }
  232. static ulong at91_plladiv_clk_get_rate(struct clk *clk)
  233. {
  234. struct pmc_plat *plat = dev_get_plat(clk->dev);
  235. struct at91_pmc *pmc = plat->reg_base;
  236. struct clk source;
  237. ulong clk_rate;
  238. int ret;
  239. ret = clk_get_by_index(clk->dev, 0, &source);
  240. if (ret)
  241. return -EINVAL;
  242. clk_rate = clk_get_rate(&source);
  243. if (readl(&pmc->mckr) & AT91_PMC_MCKR_PLLADIV_2)
  244. clk_rate /= 2;
  245. return clk_rate;
  246. }
  247. static ulong at91_plladiv_clk_set_rate(struct clk *clk, ulong rate)
  248. {
  249. struct pmc_plat *plat = dev_get_plat(clk->dev);
  250. struct at91_pmc *pmc = plat->reg_base;
  251. struct clk source;
  252. ulong parent_rate;
  253. int ret;
  254. ret = clk_get_by_index(clk->dev, 0, &source);
  255. if (ret)
  256. return -EINVAL;
  257. parent_rate = clk_get_rate(&source);
  258. if ((parent_rate != rate) && ((parent_rate) / 2 != rate))
  259. return -EINVAL;
  260. if (parent_rate != rate) {
  261. writel((readl(&pmc->mckr) | AT91_PMC_MCKR_PLLADIV_2),
  262. &pmc->mckr);
  263. }
  264. return 0;
  265. }
  266. static struct clk_ops at91_plladiv_clk_ops = {
  267. .enable = at91_plladiv_clk_enable,
  268. .get_rate = at91_plladiv_clk_get_rate,
  269. .set_rate = at91_plladiv_clk_set_rate,
  270. };
  271. static int at91_plladiv_clk_probe(struct udevice *dev)
  272. {
  273. return at91_pmc_core_probe(dev);
  274. }
  275. static const struct udevice_id at91_plladiv_clk_match[] = {
  276. { .compatible = "atmel,at91sam9x5-clk-plldiv" },
  277. {}
  278. };
  279. U_BOOT_DRIVER(at91_plladiv_clk) = {
  280. .name = "at91-plladiv-clk",
  281. .id = UCLASS_CLK,
  282. .of_match = at91_plladiv_clk_match,
  283. .probe = at91_plladiv_clk_probe,
  284. .plat_auto = sizeof(struct pmc_plat),
  285. .ops = &at91_plladiv_clk_ops,
  286. };
  287. /* System clock specific code. */
  288. #define SYSTEM_MAX_ID 31
  289. /**
  290. * at91_system_clk_bind() - for the system clock driver
  291. * Recursively bind its children as clk devices.
  292. *
  293. * @return: 0 on success, or negative error code on failure
  294. */
  295. static int at91_system_clk_bind(struct udevice *dev)
  296. {
  297. return at91_clk_sub_device_bind(dev, "system-clk");
  298. }
  299. static const struct udevice_id at91_system_clk_match[] = {
  300. { .compatible = "atmel,at91rm9200-clk-system" },
  301. {}
  302. };
  303. U_BOOT_DRIVER(at91_system_clk) = {
  304. .name = "at91-system-clk",
  305. .id = UCLASS_MISC,
  306. .of_match = at91_system_clk_match,
  307. .bind = at91_system_clk_bind,
  308. };
  309. static inline int is_pck(int id)
  310. {
  311. return (id >= 8) && (id <= 15);
  312. }
  313. static ulong system_clk_get_rate(struct clk *clk)
  314. {
  315. struct clk clk_dev;
  316. int ret;
  317. ret = clk_get_by_index(clk->dev, 0, &clk_dev);
  318. if (ret)
  319. return -EINVAL;
  320. return clk_get_rate(&clk_dev);
  321. }
  322. static ulong system_clk_set_rate(struct clk *clk, ulong rate)
  323. {
  324. struct clk clk_dev;
  325. int ret;
  326. ret = clk_get_by_index(clk->dev, 0, &clk_dev);
  327. if (ret)
  328. return -EINVAL;
  329. return clk_set_rate(&clk_dev, rate);
  330. }
  331. static int system_clk_enable(struct clk *clk)
  332. {
  333. struct pmc_plat *plat = dev_get_plat(clk->dev);
  334. struct at91_pmc *pmc = plat->reg_base;
  335. u32 mask;
  336. if (clk->id > SYSTEM_MAX_ID)
  337. return -EINVAL;
  338. mask = BIT(clk->id);
  339. writel(mask, &pmc->scer);
  340. /**
  341. * For the programmable clocks the Ready status in the PMC
  342. * status register should be checked after enabling.
  343. * For other clocks this is unnecessary.
  344. */
  345. if (!is_pck(clk->id))
  346. return 0;
  347. while (!(readl(&pmc->sr) & mask))
  348. ;
  349. return 0;
  350. }
  351. static struct clk_ops system_clk_ops = {
  352. .of_xlate = at91_clk_of_xlate,
  353. .get_rate = system_clk_get_rate,
  354. .set_rate = system_clk_set_rate,
  355. .enable = system_clk_enable,
  356. };
  357. U_BOOT_DRIVER(system_clk) = {
  358. .name = "system-clk",
  359. .id = UCLASS_CLK,
  360. .probe = at91_clk_probe,
  361. .plat_auto = sizeof(struct pmc_plat),
  362. .ops = &system_clk_ops,
  363. };
  364. /* Peripheral clock specific code. */
  365. #define PERIPHERAL_ID_MIN 2
  366. #define PERIPHERAL_ID_MAX 31
  367. #define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
  368. enum periph_clk_type {
  369. CLK_PERIPH_AT91RM9200 = 0,
  370. CLK_PERIPH_AT91SAM9X5,
  371. };
  372. /**
  373. * sam9x5_periph_clk_bind() - for the periph clock driver
  374. * Recursively bind its children as clk devices.
  375. *
  376. * @return: 0 on success, or negative error code on failure
  377. */
  378. static int sam9x5_periph_clk_bind(struct udevice *dev)
  379. {
  380. return at91_clk_sub_device_bind(dev, "periph-clk");
  381. }
  382. static const struct udevice_id sam9x5_periph_clk_match[] = {
  383. {
  384. .compatible = "atmel,at91rm9200-clk-peripheral",
  385. .data = CLK_PERIPH_AT91RM9200,
  386. },
  387. {
  388. .compatible = "atmel,at91sam9x5-clk-peripheral",
  389. .data = CLK_PERIPH_AT91SAM9X5,
  390. },
  391. {}
  392. };
  393. U_BOOT_DRIVER(sam9x5_periph_clk) = {
  394. .name = "sam9x5-periph-clk",
  395. .id = UCLASS_MISC,
  396. .of_match = sam9x5_periph_clk_match,
  397. .bind = sam9x5_periph_clk_bind,
  398. };
  399. static int periph_clk_enable(struct clk *clk)
  400. {
  401. struct pmc_plat *plat = dev_get_plat(clk->dev);
  402. struct at91_pmc *pmc = plat->reg_base;
  403. enum periph_clk_type clk_type;
  404. void *addr;
  405. if (clk->id < PERIPHERAL_ID_MIN)
  406. return -1;
  407. clk_type = dev_get_driver_data(dev_get_parent(clk->dev));
  408. if (clk_type == CLK_PERIPH_AT91RM9200) {
  409. addr = &pmc->pcer;
  410. if (clk->id > PERIPHERAL_ID_MAX)
  411. addr = &pmc->pcer1;
  412. setbits_le32(addr, PERIPHERAL_MASK(clk->id));
  413. } else {
  414. writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
  415. setbits_le32(&pmc->pcr,
  416. AT91_PMC_PCR_CMD_WRITE | AT91_PMC_PCR_EN);
  417. }
  418. return 0;
  419. }
  420. static ulong periph_get_rate(struct clk *clk)
  421. {
  422. struct udevice *dev;
  423. struct clk clk_dev;
  424. ulong clk_rate;
  425. int ret;
  426. dev = dev_get_parent(clk->dev);
  427. ret = clk_get_by_index(dev, 0, &clk_dev);
  428. if (ret)
  429. return ret;
  430. clk_rate = clk_get_rate(&clk_dev);
  431. clk_free(&clk_dev);
  432. return clk_rate;
  433. }
  434. static struct clk_ops periph_clk_ops = {
  435. .of_xlate = at91_clk_of_xlate,
  436. .enable = periph_clk_enable,
  437. .get_rate = periph_get_rate,
  438. };
  439. U_BOOT_DRIVER(clk_periph) = {
  440. .name = "periph-clk",
  441. .id = UCLASS_CLK,
  442. .plat_auto = sizeof(struct pmc_plat),
  443. .probe = at91_clk_probe,
  444. .ops = &periph_clk_ops,
  445. };
  446. /* UTMI clock specific code. */
  447. #ifdef CONFIG_AT91_UTMI
  448. /*
  449. * The purpose of this clock is to generate a 480 MHz signal. A different
  450. * rate can't be configured.
  451. */
  452. #define UTMI_RATE 480000000
  453. static int utmi_clk_enable(struct clk *clk)
  454. {
  455. struct pmc_plat *plat = dev_get_plat(clk->dev);
  456. struct at91_pmc *pmc = plat->reg_base;
  457. struct clk clk_dev;
  458. ulong clk_rate;
  459. u32 utmi_ref_clk_freq;
  460. u32 tmp;
  461. int err;
  462. int timeout = 2000000;
  463. if (readl(&pmc->sr) & AT91_PMC_LOCKU)
  464. return 0;
  465. /*
  466. * If mainck rate is different from 12 MHz, we have to configure the
  467. * FREQ field of the SFR_UTMICKTRIM register to generate properly
  468. * the utmi clock.
  469. */
  470. err = clk_get_by_index(clk->dev, 0, &clk_dev);
  471. if (err)
  472. return -EINVAL;
  473. clk_rate = clk_get_rate(&clk_dev);
  474. switch (clk_rate) {
  475. case 12000000:
  476. utmi_ref_clk_freq = 0;
  477. break;
  478. case 16000000:
  479. utmi_ref_clk_freq = 1;
  480. break;
  481. case 24000000:
  482. utmi_ref_clk_freq = 2;
  483. break;
  484. /*
  485. * Not supported on SAMA5D2 but it's not an issue since MAINCK
  486. * maximum value is 24 MHz.
  487. */
  488. case 48000000:
  489. utmi_ref_clk_freq = 3;
  490. break;
  491. default:
  492. printf("UTMICK: unsupported mainck rate\n");
  493. return -EINVAL;
  494. }
  495. if (plat->regmap_sfr) {
  496. err = regmap_read(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, &tmp);
  497. if (err)
  498. return -EINVAL;
  499. tmp &= ~AT91_UTMICKTRIM_FREQ;
  500. tmp |= utmi_ref_clk_freq;
  501. err = regmap_write(plat->regmap_sfr, AT91_SFR_UTMICKTRIM, tmp);
  502. if (err)
  503. return -EINVAL;
  504. } else if (utmi_ref_clk_freq) {
  505. printf("UTMICK: sfr node required\n");
  506. return -EINVAL;
  507. }
  508. tmp = readl(&pmc->uckr);
  509. tmp |= AT91_PMC_UPLLEN |
  510. AT91_PMC_UPLLCOUNT |
  511. AT91_PMC_BIASEN;
  512. writel(tmp, &pmc->uckr);
  513. while ((--timeout) && !(readl(&pmc->sr) & AT91_PMC_LOCKU))
  514. ;
  515. if (!timeout) {
  516. printf("UTMICK: timeout waiting for UPLL lock\n");
  517. return -ETIMEDOUT;
  518. }
  519. return 0;
  520. }
  521. static ulong utmi_clk_get_rate(struct clk *clk)
  522. {
  523. /* UTMI clk rate is fixed. */
  524. return UTMI_RATE;
  525. }
  526. static struct clk_ops utmi_clk_ops = {
  527. .enable = utmi_clk_enable,
  528. .get_rate = utmi_clk_get_rate,
  529. };
  530. static int utmi_clk_of_to_plat(struct udevice *dev)
  531. {
  532. struct pmc_plat *plat = dev_get_plat(dev);
  533. struct udevice *syscon;
  534. uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
  535. "regmap-sfr", &syscon);
  536. if (syscon)
  537. plat->regmap_sfr = syscon_get_regmap(syscon);
  538. return 0;
  539. }
  540. static int utmi_clk_probe(struct udevice *dev)
  541. {
  542. return at91_pmc_core_probe(dev);
  543. }
  544. static const struct udevice_id utmi_clk_match[] = {
  545. { .compatible = "atmel,at91sam9x5-clk-utmi" },
  546. {}
  547. };
  548. U_BOOT_DRIVER(at91sam9x5_utmi_clk) = {
  549. .name = "at91sam9x5-utmi-clk",
  550. .id = UCLASS_CLK,
  551. .of_match = utmi_clk_match,
  552. .probe = utmi_clk_probe,
  553. .of_to_plat = utmi_clk_of_to_plat,
  554. .plat_auto = sizeof(struct pmc_plat),
  555. .ops = &utmi_clk_ops,
  556. };
  557. #endif /* CONFIG_AT91_UTMI */
  558. /* H32MX clock specific code. */
  559. #ifdef CONFIG_AT91_H32MX
  560. #define H32MX_MAX_FREQ 90000000
  561. static ulong sama5d4_h32mx_clk_get_rate(struct clk *clk)
  562. {
  563. struct pmc_plat *plat = dev_get_plat(clk->dev);
  564. struct at91_pmc *pmc = plat->reg_base;
  565. ulong rate = gd->arch.mck_rate_hz;
  566. if (readl(&pmc->mckr) & AT91_PMC_MCKR_H32MXDIV)
  567. rate /= 2;
  568. if (rate > H32MX_MAX_FREQ)
  569. dev_dbg(clk->dev, "H32MX clock is too fast\n");
  570. return rate;
  571. }
  572. static struct clk_ops sama5d4_h32mx_clk_ops = {
  573. .get_rate = sama5d4_h32mx_clk_get_rate,
  574. };
  575. static int sama5d4_h32mx_clk_probe(struct udevice *dev)
  576. {
  577. return at91_pmc_core_probe(dev);
  578. }
  579. static const struct udevice_id sama5d4_h32mx_clk_match[] = {
  580. { .compatible = "atmel,sama5d4-clk-h32mx" },
  581. {}
  582. };
  583. U_BOOT_DRIVER(sama5d4_h32mx_clk) = {
  584. .name = "sama5d4-h32mx-clk",
  585. .id = UCLASS_CLK,
  586. .of_match = sama5d4_h32mx_clk_match,
  587. .probe = sama5d4_h32mx_clk_probe,
  588. .plat_auto = sizeof(struct pmc_plat),
  589. .ops = &sama5d4_h32mx_clk_ops,
  590. };
  591. #endif /* CONFIG_AT91_H32MX */
  592. /* Generic clock specific code. */
  593. #ifdef CONFIG_AT91_GENERIC_CLK
  594. #define GENERATED_SOURCE_MAX 6
  595. #define GENERATED_MAX_DIV 255
  596. /**
  597. * generated_clk_bind() - for the generated clock driver
  598. * Recursively bind its children as clk devices.
  599. *
  600. * @return: 0 on success, or negative error code on failure
  601. */
  602. static int generated_clk_bind(struct udevice *dev)
  603. {
  604. return at91_clk_sub_device_bind(dev, "generic-clk");
  605. }
  606. static const struct udevice_id generated_clk_match[] = {
  607. { .compatible = "atmel,sama5d2-clk-generated" },
  608. {}
  609. };
  610. U_BOOT_DRIVER(generated_clk) = {
  611. .name = "generated-clk",
  612. .id = UCLASS_MISC,
  613. .of_match = generated_clk_match,
  614. .bind = generated_clk_bind,
  615. };
  616. struct generic_clk_priv {
  617. u32 num_parents;
  618. };
  619. static ulong generic_clk_get_rate(struct clk *clk)
  620. {
  621. struct pmc_plat *plat = dev_get_plat(clk->dev);
  622. struct at91_pmc *pmc = plat->reg_base;
  623. struct clk parent;
  624. ulong clk_rate;
  625. u32 tmp, gckdiv;
  626. u8 clock_source, parent_index;
  627. int ret;
  628. writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
  629. tmp = readl(&pmc->pcr);
  630. clock_source = (tmp >> AT91_PMC_PCR_GCKCSS_OFFSET) &
  631. AT91_PMC_PCR_GCKCSS_MASK;
  632. gckdiv = (tmp >> AT91_PMC_PCR_GCKDIV_OFFSET) & AT91_PMC_PCR_GCKDIV_MASK;
  633. parent_index = clock_source - 1;
  634. ret = clk_get_by_index(dev_get_parent(clk->dev), parent_index, &parent);
  635. if (ret)
  636. return 0;
  637. clk_rate = clk_get_rate(&parent) / (gckdiv + 1);
  638. clk_free(&parent);
  639. return clk_rate;
  640. }
  641. static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
  642. {
  643. struct pmc_plat *plat = dev_get_plat(clk->dev);
  644. struct at91_pmc *pmc = plat->reg_base;
  645. struct generic_clk_priv *priv = dev_get_priv(clk->dev);
  646. struct clk parent, best_parent;
  647. ulong tmp_rate, best_rate = rate, parent_rate;
  648. int tmp_diff, best_diff = -1;
  649. u32 div, best_div = 0;
  650. u8 best_parent_index, best_clock_source = 0;
  651. u8 i;
  652. u32 tmp;
  653. int ret;
  654. for (i = 0; i < priv->num_parents; i++) {
  655. ret = clk_get_by_index(dev_get_parent(clk->dev), i, &parent);
  656. if (ret)
  657. return ret;
  658. parent_rate = clk_get_rate(&parent);
  659. if (IS_ERR_VALUE(parent_rate))
  660. return parent_rate;
  661. for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
  662. tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
  663. tmp_diff = abs(rate - tmp_rate);
  664. if (best_diff < 0 || best_diff > tmp_diff) {
  665. best_rate = tmp_rate;
  666. best_diff = tmp_diff;
  667. best_div = div - 1;
  668. best_parent = parent;
  669. best_parent_index = i;
  670. best_clock_source = best_parent_index + 1;
  671. }
  672. if (!best_diff || tmp_rate < rate)
  673. break;
  674. }
  675. if (!best_diff)
  676. break;
  677. }
  678. debug("GCK: best parent: %s, best_rate = %ld, best_div = %d\n",
  679. best_parent.dev->name, best_rate, best_div);
  680. ret = clk_enable(&best_parent);
  681. if (ret)
  682. return ret;
  683. writel(clk->id & AT91_PMC_PCR_PID_MASK, &pmc->pcr);
  684. tmp = readl(&pmc->pcr);
  685. tmp &= ~(AT91_PMC_PCR_GCKDIV | AT91_PMC_PCR_GCKCSS);
  686. tmp |= AT91_PMC_PCR_GCKCSS_(best_clock_source) |
  687. AT91_PMC_PCR_CMD_WRITE |
  688. AT91_PMC_PCR_GCKDIV_(best_div) |
  689. AT91_PMC_PCR_GCKEN;
  690. writel(tmp, &pmc->pcr);
  691. while (!(readl(&pmc->sr) & AT91_PMC_GCKRDY))
  692. ;
  693. return 0;
  694. }
  695. static struct clk_ops generic_clk_ops = {
  696. .of_xlate = at91_clk_of_xlate,
  697. .get_rate = generic_clk_get_rate,
  698. .set_rate = generic_clk_set_rate,
  699. };
  700. static int generic_clk_of_to_plat(struct udevice *dev)
  701. {
  702. struct generic_clk_priv *priv = dev_get_priv(dev);
  703. u32 cells[GENERATED_SOURCE_MAX];
  704. u32 num_parents;
  705. num_parents = fdtdec_get_int_array_count(gd->fdt_blob,
  706. dev_of_offset(dev_get_parent(dev)), "clocks", cells,
  707. GENERATED_SOURCE_MAX);
  708. if (!num_parents)
  709. return -1;
  710. priv->num_parents = num_parents;
  711. return 0;
  712. }
  713. U_BOOT_DRIVER(generic_clk) = {
  714. .name = "generic-clk",
  715. .id = UCLASS_CLK,
  716. .probe = at91_clk_probe,
  717. .of_to_plat = generic_clk_of_to_plat,
  718. .priv_auto = sizeof(struct generic_clk_priv),
  719. .plat_auto = sizeof(struct pmc_plat),
  720. .ops = &generic_clk_ops,
  721. };
  722. #endif /* CONFIG_AT91_GENERIC_CLK */
  723. /* USB clock specific code. */
  724. #ifdef CONFIG_AT91_USB_CLK
  725. #define AT91_USB_CLK_SOURCE_MAX 2
  726. #define AT91_USB_CLK_MAX_DIV 15
  727. struct at91_usb_clk_priv {
  728. u32 num_clksource;
  729. };
  730. static ulong at91_usb_clk_get_rate(struct clk *clk)
  731. {
  732. struct pmc_plat *plat = dev_get_plat(clk->dev);
  733. struct at91_pmc *pmc = plat->reg_base;
  734. struct clk source;
  735. u32 tmp, usbdiv;
  736. u8 source_index;
  737. int ret;
  738. tmp = readl(&pmc->pcr);
  739. source_index = (tmp >> AT91_PMC_USB_USBS_OFFSET) &
  740. AT91_PMC_USB_USBS_MASK;
  741. usbdiv = (tmp >> AT91_PMC_USB_DIV_OFFSET) & AT91_PMC_USB_DIV_MASK;
  742. ret = clk_get_by_index(clk->dev, source_index, &source);
  743. if (ret)
  744. return 0;
  745. return clk_get_rate(&source) / (usbdiv + 1);
  746. }
  747. static ulong at91_usb_clk_set_rate(struct clk *clk, ulong rate)
  748. {
  749. struct pmc_plat *plat = dev_get_plat(clk->dev);
  750. struct at91_pmc *pmc = plat->reg_base;
  751. struct at91_usb_clk_priv *priv = dev_get_priv(clk->dev);
  752. struct clk source, best_source;
  753. ulong tmp_rate, best_rate = rate, source_rate;
  754. int tmp_diff, best_diff = -1;
  755. u32 div, best_div = 0;
  756. u8 best_source_index = 0;
  757. u8 i;
  758. u32 tmp;
  759. int ret;
  760. for (i = 0; i < priv->num_clksource; i++) {
  761. ret = clk_get_by_index(clk->dev, i, &source);
  762. if (ret)
  763. return ret;
  764. source_rate = clk_get_rate(&source);
  765. if (IS_ERR_VALUE(source_rate))
  766. return source_rate;
  767. for (div = 1; div < AT91_USB_CLK_MAX_DIV + 2; div++) {
  768. tmp_rate = DIV_ROUND_CLOSEST(source_rate, div);
  769. tmp_diff = abs(rate - tmp_rate);
  770. if (best_diff < 0 || best_diff > tmp_diff) {
  771. best_rate = tmp_rate;
  772. best_diff = tmp_diff;
  773. best_div = div - 1;
  774. best_source = source;
  775. best_source_index = i;
  776. }
  777. if (!best_diff || tmp_rate < rate)
  778. break;
  779. }
  780. if (!best_diff)
  781. break;
  782. }
  783. debug("AT91 USB: best sourc: %s, best_rate = %ld, best_div = %d\n",
  784. best_source.dev->name, best_rate, best_div);
  785. ret = clk_enable(&best_source);
  786. if (ret)
  787. return ret;
  788. tmp = AT91_PMC_USB_USBS_(best_source_index) |
  789. AT91_PMC_USB_DIV_(best_div);
  790. writel(tmp, &pmc->usb);
  791. return 0;
  792. }
  793. static struct clk_ops at91_usb_clk_ops = {
  794. .get_rate = at91_usb_clk_get_rate,
  795. .set_rate = at91_usb_clk_set_rate,
  796. };
  797. static int at91_usb_clk_of_to_plat(struct udevice *dev)
  798. {
  799. struct at91_usb_clk_priv *priv = dev_get_priv(dev);
  800. u32 cells[AT91_USB_CLK_SOURCE_MAX];
  801. u32 num_clksource;
  802. num_clksource = fdtdec_get_int_array_count(gd->fdt_blob,
  803. dev_of_offset(dev),
  804. "clocks", cells,
  805. AT91_USB_CLK_SOURCE_MAX);
  806. if (!num_clksource)
  807. return -1;
  808. priv->num_clksource = num_clksource;
  809. return 0;
  810. }
  811. static int at91_usb_clk_probe(struct udevice *dev)
  812. {
  813. return at91_pmc_core_probe(dev);
  814. }
  815. static const struct udevice_id at91_usb_clk_match[] = {
  816. { .compatible = "atmel,at91sam9x5-clk-usb" },
  817. {}
  818. };
  819. U_BOOT_DRIVER(at91_usb_clk) = {
  820. .name = "at91-usb-clk",
  821. .id = UCLASS_CLK,
  822. .of_match = at91_usb_clk_match,
  823. .probe = at91_usb_clk_probe,
  824. .of_to_plat = at91_usb_clk_of_to_plat,
  825. .priv_auto = sizeof(struct at91_usb_clk_priv),
  826. .plat_auto = sizeof(struct pmc_plat),
  827. .ops = &at91_usb_clk_ops,
  828. };
  829. #endif /* CONFIG_AT91_USB_CLK */