sama7g5.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * SAMA7G5 PMC clock support.
  4. *
  5. * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
  6. *
  7. * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
  8. *
  9. * Based on drivers/clk/at91/sama7g5.c from Linux.
  10. */
  11. #include <common.h>
  12. #include <clk-uclass.h>
  13. #include <dm.h>
  14. #include <dt-bindings/clk/at91.h>
  15. #include <linux/clk-provider.h>
  16. #include "pmc.h"
  17. /**
  18. * Clock identifiers to be used in conjunction with macros like
  19. * AT91_TO_CLK_ID()
  20. *
  21. * @ID_MD_SLCK: TD slow clock identifier
  22. * @ID_TD_SLCK: MD slow clock identifier
  23. * @ID_MAIN_XTAL: Main Xtal clock identifier
  24. * @ID_MAIN_RC: Main RC clock identifier
  25. * @ID_MAIN_RC_OSC: Main RC Oscillator clock identifier
  26. * @ID_MAIN_OSC: Main Oscillator clock identifier
  27. * @ID_MAINCK: MAINCK clock identifier
  28. * @ID_PLL_CPU_FRAC: CPU PLL fractional clock identifier
  29. * @ID_PLL_CPU_DIV: CPU PLL divider clock identifier
  30. * @ID_PLL_SYS_FRAC: SYS PLL fractional clock identifier
  31. * @ID_PLL_SYS_DIV: SYS PLL divider clock identifier
  32. * @ID_PLL_DDR_FRAC: DDR PLL fractional clock identifier
  33. * @ID_PLL_DDR_DIV: DDR PLL divider clock identifier
  34. * @ID_PLL_IMG_FRAC: IMC PLL fractional clock identifier
  35. * @ID_PLL_IMG_DIV: IMG PLL divider clock identifier
  36. * @ID_PLL_BAUD_FRAC: Baud PLL fractional clock identifier
  37. * @ID_PLL_BAUD_DIV: Baud PLL divider clock identifier
  38. * @ID_PLL_AUDIO_FRAC: Audio PLL fractional clock identifier
  39. * @ID_PLL_AUDIO_DIVPMC: Audio PLL PMC divider clock identifier
  40. * @ID_PLL_AUDIO_DIVIO: Audio PLL IO divider clock identifier
  41. * @ID_PLL_ETH_FRAC: Ethernet PLL fractional clock identifier
  42. * @ID_PLL_ETH_DIV: Ethernet PLL divider clock identifier
  43. * @ID_MCK0: MCK0 clock identifier
  44. * @ID_MCK1: MCK1 clock identifier
  45. * @ID_MCK2: MCK2 clock identifier
  46. * @ID_MCK3: MCK3 clock identifier
  47. * @ID_MCK4: MCK4 clock identifier
  48. * @ID_UTMI: UTMI clock identifier
  49. * @ID_PROG0: Programmable 0 clock identifier
  50. * @ID_PROG1: Programmable 1 clock identifier
  51. * @ID_PROG2: Programmable 2 clock identifier
  52. * @ID_PROG3: Programmable 3 clock identifier
  53. * @ID_PROG4: Programmable 4 clock identifier
  54. * @ID_PROG5: Programmable 5 clock identifier
  55. * @ID_PROG6: Programmable 6 clock identifier
  56. * @ID_PROG7: Programmable 7 clock identifier
  57. * @ID_PCK0: System clock 0 clock identifier
  58. * @ID_PCK1: System clock 1 clock identifier
  59. * @ID_PCK2: System clock 2 clock identifier
  60. * @ID_PCK3: System clock 3 clock identifier
  61. * @ID_PCK4: System clock 4 clock identifier
  62. * @ID_PCK5: System clock 5 clock identifier
  63. * @ID_PCK6: System clock 6 clock identifier
  64. * @ID_PCK7: System clock 7 clock identifier
  65. */
  66. enum pmc_clk_ids {
  67. ID_MD_SLCK = 0,
  68. ID_TD_SLCK = 1,
  69. ID_MAIN_XTAL = 2,
  70. ID_MAIN_RC = 3,
  71. ID_MAIN_RC_OSC = 4,
  72. ID_MAIN_OSC = 5,
  73. ID_MAINCK = 6,
  74. ID_PLL_CPU_FRAC = 7,
  75. ID_PLL_CPU_DIV = 8,
  76. ID_PLL_SYS_FRAC = 9,
  77. ID_PLL_SYS_DIV = 10,
  78. ID_PLL_DDR_FRAC = 11,
  79. ID_PLL_DDR_DIV = 12,
  80. ID_PLL_IMG_FRAC = 13,
  81. ID_PLL_IMG_DIV = 14,
  82. ID_PLL_BAUD_FRAC = 15,
  83. ID_PLL_BAUD_DIV = 16,
  84. ID_PLL_AUDIO_FRAC = 17,
  85. ID_PLL_AUDIO_DIVPMC = 18,
  86. ID_PLL_AUDIO_DIVIO = 19,
  87. ID_PLL_ETH_FRAC = 20,
  88. ID_PLL_ETH_DIV = 21,
  89. ID_MCK0 = 22,
  90. ID_MCK1 = 23,
  91. ID_MCK2 = 24,
  92. ID_MCK3 = 25,
  93. ID_MCK4 = 26,
  94. ID_UTMI = 27,
  95. ID_PROG0 = 28,
  96. ID_PROG1 = 29,
  97. ID_PROG2 = 30,
  98. ID_PROG3 = 31,
  99. ID_PROG4 = 32,
  100. ID_PROG5 = 33,
  101. ID_PROG6 = 34,
  102. ID_PROG7 = 35,
  103. ID_PCK0 = 36,
  104. ID_PCK1 = 37,
  105. ID_PCK2 = 38,
  106. ID_PCK3 = 39,
  107. ID_PCK4 = 40,
  108. ID_PCK5 = 41,
  109. ID_PCK6 = 42,
  110. ID_PCK7 = 43,
  111. ID_MAX,
  112. };
  113. /**
  114. * PLL type identifiers
  115. * @PLL_TYPE_FRAC: fractional PLL identifier
  116. * @PLL_TYPE_DIV: divider PLL identifier
  117. */
  118. enum pll_type {
  119. PLL_TYPE_FRAC,
  120. PLL_TYPE_DIV,
  121. };
  122. /* Clock names used as parents for multiple clocks. */
  123. static const char *clk_names[] = {
  124. [ID_MAIN_RC_OSC] = "main_rc_osc",
  125. [ID_MAIN_OSC] = "main_osc",
  126. [ID_MAINCK] = "mainck",
  127. [ID_PLL_CPU_DIV] = "cpupll_divpmcck",
  128. [ID_PLL_SYS_DIV] = "syspll_divpmcck",
  129. [ID_PLL_DDR_DIV] = "ddrpll_divpmcck",
  130. [ID_PLL_IMG_DIV] = "imgpll_divpmcck",
  131. [ID_PLL_BAUD_DIV] = "baudpll_divpmcck",
  132. [ID_PLL_AUDIO_DIVPMC] = "audiopll_divpmcck",
  133. [ID_PLL_AUDIO_DIVIO] = "audiopll_diviock",
  134. [ID_PLL_ETH_DIV] = "ethpll_divpmcck",
  135. [ID_MCK0] = "mck0",
  136. };
  137. /* Fractional PLL output range. */
  138. static const struct clk_range pll_outputs[] = {
  139. { .min = 2343750, .max = 1200000000 },
  140. };
  141. /* PLL characteristics. */
  142. static const struct clk_pll_characteristics pll_characteristics = {
  143. .input = { .min = 12000000, .max = 50000000 },
  144. .num_output = ARRAY_SIZE(pll_outputs),
  145. .output = pll_outputs,
  146. };
  147. /* Layout for fractional PLLs. */
  148. static const struct clk_pll_layout pll_layout_frac = {
  149. .mul_mask = GENMASK(31, 24),
  150. .frac_mask = GENMASK(21, 0),
  151. .mul_shift = 24,
  152. .frac_shift = 0,
  153. };
  154. /* Layout for DIVPMC dividers. */
  155. static const struct clk_pll_layout pll_layout_divpmc = {
  156. .div_mask = GENMASK(7, 0),
  157. .endiv_mask = BIT(29),
  158. .div_shift = 0,
  159. .endiv_shift = 29,
  160. };
  161. /* Layout for DIVIO dividers. */
  162. static const struct clk_pll_layout pll_layout_divio = {
  163. .div_mask = GENMASK(19, 12),
  164. .endiv_mask = BIT(30),
  165. .div_shift = 12,
  166. .endiv_shift = 30,
  167. };
  168. /* MCK0 characteristics. */
  169. static const struct clk_master_characteristics mck0_characteristics = {
  170. .output = { .min = 140000000, .max = 200000000 },
  171. .divisors = { 1, 2, 4, 3 },
  172. .have_div3_pres = 1,
  173. };
  174. /* MCK0 layout. */
  175. static const struct clk_master_layout mck0_layout = {
  176. .mask = 0x373,
  177. .pres_shift = 4,
  178. .offset = 0x28,
  179. };
  180. /* Programmable clock layout. */
  181. static const struct clk_programmable_layout programmable_layout = {
  182. .pres_mask = 0xff,
  183. .pres_shift = 8,
  184. .css_mask = 0x1f,
  185. .have_slck_mck = 0,
  186. .is_pres_direct = 1,
  187. };
  188. /* Peripheral clock layout. */
  189. static const struct clk_pcr_layout sama7g5_pcr_layout = {
  190. .offset = 0x88,
  191. .cmd = BIT(31),
  192. .gckcss_mask = GENMASK(12, 8),
  193. .pid_mask = GENMASK(6, 0),
  194. .div_mask = GENMASK(15, 14),
  195. };
  196. /**
  197. * PLL clocks description
  198. * @n: clock name
  199. * @p: clock parent
  200. * @l: clock layout
  201. * @t: clock type
  202. * @c: true if clock is critical and cannot be disabled
  203. * @id: clock id corresponding to PLL driver
  204. * @cid: clock id corresponding to clock subsystem
  205. */
  206. static const struct {
  207. const char *n;
  208. const char *p;
  209. const struct clk_pll_layout *l;
  210. u8 t;
  211. u8 c;
  212. u8 id;
  213. u8 cid;
  214. } sama7g5_plls[] = {
  215. {
  216. .n = "cpupll_fracck",
  217. .p = "mainck",
  218. .l = &pll_layout_frac,
  219. .t = PLL_TYPE_FRAC,
  220. .c = 1,
  221. .id = 0,
  222. .cid = ID_PLL_CPU_FRAC,
  223. },
  224. {
  225. .n = "cpupll_divpmcck",
  226. .p = "cpupll_fracck",
  227. .l = &pll_layout_divpmc,
  228. .t = PLL_TYPE_DIV,
  229. .c = 1,
  230. .id = 0,
  231. .cid = ID_PLL_CPU_DIV,
  232. },
  233. {
  234. .n = "syspll_fracck",
  235. .p = "mainck",
  236. .l = &pll_layout_frac,
  237. .t = PLL_TYPE_FRAC,
  238. .c = 1,
  239. .id = 1,
  240. .cid = ID_PLL_SYS_FRAC,
  241. },
  242. {
  243. .n = "syspll_divpmcck",
  244. .p = "syspll_fracck",
  245. .l = &pll_layout_divpmc,
  246. .t = PLL_TYPE_DIV,
  247. .c = 1,
  248. .id = 1,
  249. .cid = ID_PLL_SYS_DIV,
  250. },
  251. {
  252. .n = "ddrpll_fracck",
  253. .p = "mainck",
  254. .l = &pll_layout_frac,
  255. .t = PLL_TYPE_FRAC,
  256. .c = 1,
  257. .id = 2,
  258. .cid = ID_PLL_DDR_FRAC,
  259. },
  260. {
  261. .n = "ddrpll_divpmcck",
  262. .p = "ddrpll_fracck",
  263. .l = &pll_layout_divpmc,
  264. .t = PLL_TYPE_DIV,
  265. .c = 1,
  266. .id = 2,
  267. .cid = ID_PLL_DDR_DIV,
  268. },
  269. {
  270. .n = "imgpll_fracck",
  271. .p = "mainck",
  272. .l = &pll_layout_frac,
  273. .t = PLL_TYPE_FRAC,
  274. .id = 3,
  275. .cid = ID_PLL_IMG_FRAC,
  276. },
  277. {
  278. .n = "imgpll_divpmcck",
  279. .p = "imgpll_fracck",
  280. .l = &pll_layout_divpmc,
  281. .t = PLL_TYPE_DIV,
  282. .id = 3,
  283. .cid = ID_PLL_IMG_DIV
  284. },
  285. {
  286. .n = "baudpll_fracck",
  287. .p = "mainck",
  288. .l = &pll_layout_frac,
  289. .t = PLL_TYPE_FRAC,
  290. .id = 4,
  291. .cid = ID_PLL_BAUD_FRAC,
  292. },
  293. {
  294. .n = "baudpll_divpmcck",
  295. .p = "baudpll_fracck",
  296. .l = &pll_layout_divpmc,
  297. .t = PLL_TYPE_DIV,
  298. .id = 4,
  299. .cid = ID_PLL_BAUD_DIV,
  300. },
  301. {
  302. .n = "audiopll_fracck",
  303. .p = "main_osc",
  304. .l = &pll_layout_frac,
  305. .t = PLL_TYPE_FRAC,
  306. .id = 5,
  307. .cid = ID_PLL_AUDIO_FRAC,
  308. },
  309. {
  310. .n = "audiopll_divpmcck",
  311. .p = "audiopll_fracck",
  312. .l = &pll_layout_divpmc,
  313. .t = PLL_TYPE_DIV,
  314. .id = 5,
  315. .cid = ID_PLL_AUDIO_DIVPMC,
  316. },
  317. {
  318. .n = "audiopll_diviock",
  319. .p = "audiopll_fracck",
  320. .l = &pll_layout_divio,
  321. .t = PLL_TYPE_DIV,
  322. .id = 5,
  323. .cid = ID_PLL_AUDIO_DIVIO,
  324. },
  325. {
  326. .n = "ethpll_fracck",
  327. .p = "main_osc",
  328. .l = &pll_layout_frac,
  329. .t = PLL_TYPE_FRAC,
  330. .id = 6,
  331. .cid = ID_PLL_ETH_FRAC,
  332. },
  333. {
  334. .n = "ethpll_divpmcck",
  335. .p = "ethpll_fracck",
  336. .l = &pll_layout_divpmc,
  337. .t = PLL_TYPE_DIV,
  338. .id = 6,
  339. .cid = ID_PLL_ETH_DIV,
  340. },
  341. };
  342. /**
  343. * Master clock (MCK[1..4]) description
  344. * @n: clock name
  345. * @ep: extra parents names array
  346. * @ep_chg_chg_id: index in parents array that specifies the changeable
  347. * parent
  348. * @ep_count: extra parents count
  349. * @ep_mux_table: mux table for extra parents
  350. * @ep_clk_mux_table: mux table to deal with subsystem clock ids
  351. * @id: clock id corresponding to MCK driver
  352. * @cid: clock id corresponding to clock subsystem
  353. * @c: true if clock is critical and cannot be disabled
  354. */
  355. static const struct {
  356. const char *n;
  357. const char *ep[4];
  358. u8 ep_count;
  359. u8 ep_mux_table[4];
  360. u8 ep_clk_mux_table[4];
  361. u8 id;
  362. u8 cid;
  363. u8 c;
  364. } sama7g5_mckx[] = {
  365. {
  366. .n = "mck1",
  367. .id = 1,
  368. .cid = ID_MCK1,
  369. .ep = { "syspll_divpmcck", },
  370. .ep_mux_table = { 5, },
  371. .ep_clk_mux_table = { ID_PLL_SYS_DIV, },
  372. .ep_count = 1,
  373. .c = 1,
  374. },
  375. {
  376. .n = "mck2",
  377. .id = 2,
  378. .cid = ID_MCK2,
  379. .ep = { "ddrpll_divpmcck", },
  380. .ep_mux_table = { 6, },
  381. .ep_clk_mux_table = { ID_PLL_DDR_DIV, },
  382. .ep_count = 1,
  383. .c = 1,
  384. },
  385. {
  386. .n = "mck3",
  387. .id = 3,
  388. .cid = ID_MCK3,
  389. .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", },
  390. .ep_mux_table = { 5, 6, 7, },
  391. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, },
  392. .ep_count = 3,
  393. },
  394. {
  395. .n = "mck4",
  396. .id = 4,
  397. .cid = ID_MCK4,
  398. .ep = { "syspll_divpmcck", },
  399. .ep_mux_table = { 5, },
  400. .ep_clk_mux_table = { ID_PLL_SYS_DIV, },
  401. .ep_count = 1,
  402. .c = 1,
  403. },
  404. };
  405. /**
  406. * Programmable clock description
  407. * @n: clock name
  408. * @cid: clock id corresponding to clock subsystem
  409. */
  410. static const struct {
  411. const char *n;
  412. u8 cid;
  413. } sama7g5_prog[] = {
  414. { .n = "prog0", .cid = ID_PROG0, },
  415. { .n = "prog1", .cid = ID_PROG1, },
  416. { .n = "prog2", .cid = ID_PROG2, },
  417. { .n = "prog3", .cid = ID_PROG3, },
  418. { .n = "prog4", .cid = ID_PROG4, },
  419. { .n = "prog5", .cid = ID_PROG5, },
  420. { .n = "prog6", .cid = ID_PROG6, },
  421. { .n = "prog7", .cid = ID_PROG7, },
  422. };
  423. /* Mux table for programmable clocks. */
  424. static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, };
  425. /**
  426. * System clock description
  427. * @n: clock name
  428. * @p: parent clock name
  429. * @id: clock id corresponding to system clock driver
  430. * @cid: clock id corresponding to clock subsystem
  431. */
  432. static const struct {
  433. const char *n;
  434. const char *p;
  435. u8 id;
  436. u8 cid;
  437. } sama7g5_systemck[] = {
  438. { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, },
  439. { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, },
  440. { .n = "pck2", .p = "prog2", .id = 10, .cid = ID_PCK2, },
  441. { .n = "pck3", .p = "prog3", .id = 11, .cid = ID_PCK3, },
  442. { .n = "pck4", .p = "prog4", .id = 12, .cid = ID_PCK4, },
  443. { .n = "pck5", .p = "prog5", .id = 13, .cid = ID_PCK5, },
  444. { .n = "pck6", .p = "prog6", .id = 14, .cid = ID_PCK6, },
  445. { .n = "pck7", .p = "prog7", .id = 15, .cid = ID_PCK7, },
  446. };
  447. /**
  448. * Peripheral clock description
  449. * @n: clock name
  450. * @p: clock parent name
  451. * @r: clock range values
  452. * @id: clock id
  453. */
  454. static const struct {
  455. const char *n;
  456. const char *p;
  457. struct clk_range r;
  458. u8 id;
  459. } sama7g5_periphck[] = {
  460. { .n = "pioA_clk", .p = "mck0", .id = 11, },
  461. { .n = "sfr_clk", .p = "mck1", .id = 19, },
  462. { .n = "hsmc_clk", .p = "mck1", .id = 21, },
  463. { .n = "xdmac0_clk", .p = "mck1", .id = 22, },
  464. { .n = "xdmac1_clk", .p = "mck1", .id = 23, },
  465. { .n = "xdmac2_clk", .p = "mck1", .id = 24, },
  466. { .n = "acc_clk", .p = "mck1", .id = 25, },
  467. { .n = "aes_clk", .p = "mck1", .id = 27, },
  468. { .n = "tzaesbasc_clk", .p = "mck1", .id = 28, },
  469. { .n = "asrc_clk", .p = "mck1", .id = 30, .r = { .max = 200000000, }, },
  470. { .n = "cpkcc_clk", .p = "mck0", .id = 32, },
  471. { .n = "csi_clk", .p = "mck3", .id = 33, .r = { .max = 266000000, }, },
  472. { .n = "csi2dc_clk", .p = "mck3", .id = 34, .r = { .max = 266000000, }, },
  473. { .n = "eic_clk", .p = "mck1", .id = 37, },
  474. { .n = "flex0_clk", .p = "mck1", .id = 38, },
  475. { .n = "flex1_clk", .p = "mck1", .id = 39, },
  476. { .n = "flex2_clk", .p = "mck1", .id = 40, },
  477. { .n = "flex3_clk", .p = "mck1", .id = 41, },
  478. { .n = "flex4_clk", .p = "mck1", .id = 42, },
  479. { .n = "flex5_clk", .p = "mck1", .id = 43, },
  480. { .n = "flex6_clk", .p = "mck1", .id = 44, },
  481. { .n = "flex7_clk", .p = "mck1", .id = 45, },
  482. { .n = "flex8_clk", .p = "mck1", .id = 46, },
  483. { .n = "flex9_clk", .p = "mck1", .id = 47, },
  484. { .n = "flex10_clk", .p = "mck1", .id = 48, },
  485. { .n = "flex11_clk", .p = "mck1", .id = 49, },
  486. { .n = "gmac0_clk", .p = "mck1", .id = 51, },
  487. { .n = "gmac1_clk", .p = "mck1", .id = 52, },
  488. { .n = "gmac0_tsu_clk", .p = "mck1", .id = 53, },
  489. { .n = "gmac1_tsu_clk", .p = "mck1", .id = 54, },
  490. { .n = "icm_clk", .p = "mck1", .id = 55, },
  491. { .n = "isc_clk", .p = "mck3", .id = 56, .r = { .max = 266000000, }, },
  492. { .n = "i2smcc0_clk", .p = "mck1", .id = 57, .r = { .max = 200000000, }, },
  493. { .n = "i2smcc1_clk", .p = "mck1", .id = 58, .r = { .max = 200000000, }, },
  494. { .n = "matrix_clk", .p = "mck1", .id = 60, },
  495. { .n = "mcan0_clk", .p = "mck1", .id = 61, .r = { .max = 200000000, }, },
  496. { .n = "mcan1_clk", .p = "mck1", .id = 62, .r = { .max = 200000000, }, },
  497. { .n = "mcan2_clk", .p = "mck1", .id = 63, .r = { .max = 200000000, }, },
  498. { .n = "mcan3_clk", .p = "mck1", .id = 64, .r = { .max = 200000000, }, },
  499. { .n = "mcan4_clk", .p = "mck1", .id = 65, .r = { .max = 200000000, }, },
  500. { .n = "mcan5_clk", .p = "mck1", .id = 66, .r = { .max = 200000000, }, },
  501. { .n = "pdmc0_clk", .p = "mck1", .id = 68, .r = { .max = 200000000, }, },
  502. { .n = "pdmc1_clk", .p = "mck1", .id = 69, .r = { .max = 200000000, }, },
  503. { .n = "pit64b0_clk", .p = "mck1", .id = 70, },
  504. { .n = "pit64b1_clk", .p = "mck1", .id = 71, },
  505. { .n = "pit64b2_clk", .p = "mck1", .id = 72, },
  506. { .n = "pit64b3_clk", .p = "mck1", .id = 73, },
  507. { .n = "pit64b4_clk", .p = "mck1", .id = 74, },
  508. { .n = "pit64b5_clk", .p = "mck1", .id = 75, },
  509. { .n = "pwm_clk", .p = "mck1", .id = 77, },
  510. { .n = "qspi0_clk", .p = "mck1", .id = 78, },
  511. { .n = "qspi1_clk", .p = "mck1", .id = 79, },
  512. { .n = "sdmmc0_clk", .p = "mck1", .id = 80, },
  513. { .n = "sdmmc1_clk", .p = "mck1", .id = 81, },
  514. { .n = "sdmmc2_clk", .p = "mck1", .id = 82, },
  515. { .n = "sha_clk", .p = "mck1", .id = 83, },
  516. { .n = "spdifrx_clk", .p = "mck1", .id = 84, .r = { .max = 200000000, }, },
  517. { .n = "spdiftx_clk", .p = "mck1", .id = 85, .r = { .max = 200000000, }, },
  518. { .n = "ssc0_clk", .p = "mck1", .id = 86, .r = { .max = 200000000, }, },
  519. { .n = "ssc1_clk", .p = "mck1", .id = 87, .r = { .max = 200000000, }, },
  520. { .n = "tcb0_ch0_clk", .p = "mck1", .id = 88, .r = { .max = 200000000, }, },
  521. { .n = "tcb0_ch1_clk", .p = "mck1", .id = 89, .r = { .max = 200000000, }, },
  522. { .n = "tcb0_ch2_clk", .p = "mck1", .id = 90, .r = { .max = 200000000, }, },
  523. { .n = "tcb1_ch0_clk", .p = "mck1", .id = 91, .r = { .max = 200000000, }, },
  524. { .n = "tcb1_ch1_clk", .p = "mck1", .id = 92, .r = { .max = 200000000, }, },
  525. { .n = "tcb1_ch2_clk", .p = "mck1", .id = 93, .r = { .max = 200000000, }, },
  526. { .n = "tcpca_clk", .p = "mck1", .id = 94, },
  527. { .n = "tcpcb_clk", .p = "mck1", .id = 95, },
  528. { .n = "tdes_clk", .p = "mck1", .id = 96, },
  529. { .n = "trng_clk", .p = "mck1", .id = 97, },
  530. { .n = "udphsa_clk", .p = "mck1", .id = 104, },
  531. { .n = "udphsb_clk", .p = "mck1", .id = 105, },
  532. { .n = "uhphs_clk", .p = "mck1", .id = 106, },
  533. };
  534. /**
  535. * Generic clock description
  536. * @n: clock name
  537. * @ep: extra parents names
  538. * @ep_mux_table: extra parents mux table
  539. * @ep_clk_mux_table: extra parents clock mux table (for CCF)
  540. * @r: clock output range
  541. * @ep_count: extra parents count
  542. * @id: clock id
  543. */
  544. static const struct {
  545. const char *n;
  546. const char *ep[8];
  547. const char ep_mux_table[8];
  548. const char ep_clk_mux_table[8];
  549. struct clk_range r;
  550. u8 ep_count;
  551. u8 id;
  552. } sama7g5_gck[] = {
  553. {
  554. .n = "adc_gclk",
  555. .id = 26,
  556. .r = { .max = 100000000, },
  557. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "audiopll_divpmcck", },
  558. .ep_mux_table = { 5, 7, 9, },
  559. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  560. ID_PLL_AUDIO_DIVPMC, },
  561. .ep_count = 3,
  562. },
  563. {
  564. .n = "asrc_gclk",
  565. .id = 30,
  566. .r = { .max = 200000000 },
  567. .ep = { "audiopll_divpmcck", },
  568. .ep_mux_table = { 9, },
  569. .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, },
  570. .ep_count = 1,
  571. },
  572. {
  573. .n = "csi_gclk",
  574. .id = 33,
  575. .r = { .max = 27000000 },
  576. .ep = { "ddrpll_divpmcck", "imgpll_divpmcck", },
  577. .ep_clk_mux_table = { ID_PLL_DDR_DIV, ID_PLL_IMG_DIV, },
  578. .ep_mux_table = { 6, 7, },
  579. .ep_count = 2,
  580. },
  581. {
  582. .n = "flex0_gclk",
  583. .id = 38,
  584. .r = { .max = 200000000 },
  585. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  586. .ep_mux_table = { 5, 8, },
  587. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  588. .ep_count = 2,
  589. },
  590. {
  591. .n = "flex1_gclk",
  592. .id = 39,
  593. .r = { .max = 200000000 },
  594. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  595. .ep_mux_table = { 5, 8, },
  596. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  597. .ep_count = 2,
  598. },
  599. {
  600. .n = "flex2_gclk",
  601. .id = 40,
  602. .r = { .max = 200000000 },
  603. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  604. .ep_mux_table = { 5, 8, },
  605. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  606. .ep_count = 2,
  607. },
  608. {
  609. .n = "flex3_gclk",
  610. .id = 41,
  611. .r = { .max = 200000000 },
  612. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  613. .ep_mux_table = { 5, 8, },
  614. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  615. .ep_count = 2,
  616. },
  617. {
  618. .n = "flex4_gclk",
  619. .id = 42,
  620. .r = { .max = 200000000 },
  621. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  622. .ep_mux_table = { 5, 8, },
  623. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  624. .ep_count = 2,
  625. },
  626. {
  627. .n = "flex5_gclk",
  628. .id = 43,
  629. .r = { .max = 200000000 },
  630. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  631. .ep_mux_table = { 5, 8, },
  632. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  633. .ep_count = 2,
  634. },
  635. {
  636. .n = "flex6_gclk",
  637. .id = 44,
  638. .r = { .max = 200000000 },
  639. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  640. .ep_mux_table = { 5, 8, },
  641. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  642. .ep_count = 2,
  643. },
  644. {
  645. .n = "flex7_gclk",
  646. .id = 45,
  647. .r = { .max = 200000000 },
  648. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  649. .ep_mux_table = { 5, 8, },
  650. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  651. .ep_count = 2,
  652. },
  653. {
  654. .n = "flex8_gclk",
  655. .id = 46,
  656. .r = { .max = 200000000 },
  657. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  658. .ep_mux_table = { 5, 8, },
  659. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  660. .ep_count = 2,
  661. },
  662. {
  663. .n = "flex9_gclk",
  664. .id = 47,
  665. .r = { .max = 200000000 },
  666. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  667. .ep_mux_table = { 5, 8, },
  668. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  669. .ep_count = 2,
  670. },
  671. {
  672. .n = "flex10_gclk",
  673. .id = 48,
  674. .r = { .max = 200000000 },
  675. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  676. .ep_mux_table = { 5, 8, },
  677. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  678. .ep_count = 2,
  679. },
  680. {
  681. .n = "flex11_gclk",
  682. .id = 49,
  683. .r = { .max = 200000000 },
  684. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  685. .ep_mux_table = { 5, 8, },
  686. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  687. .ep_count = 2,
  688. },
  689. {
  690. .n = "gmac0_gclk",
  691. .id = 51,
  692. .r = { .max = 125000000 },
  693. .ep = { "ethpll_divpmcck", },
  694. .ep_clk_mux_table = { ID_PLL_ETH_DIV, },
  695. .ep_mux_table = { 10, },
  696. .ep_count = 1,
  697. },
  698. {
  699. .n = "gmac1_gclk",
  700. .id = 52,
  701. .r = { .max = 50000000 },
  702. .ep = { "ethpll_divpmcck", },
  703. .ep_mux_table = { 10, },
  704. .ep_clk_mux_table = { ID_PLL_ETH_DIV, },
  705. .ep_count = 1,
  706. },
  707. {
  708. .n = "gmac0_tsu_gclk",
  709. .id = 53,
  710. .r = { .max = 300000000 },
  711. .ep = { "audiopll_divpmcck", "ethpll_divpmcck", },
  712. .ep_mux_table = { 9, 10, },
  713. .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, },
  714. .ep_count = 2,
  715. },
  716. {
  717. .n = "gmac1_tsu_gclk",
  718. .id = 54,
  719. .r = { .max = 300000000 },
  720. .ep = { "audiopll_divpmcck", "ethpll_divpmcck", },
  721. .ep_mux_table = { 9, 10, },
  722. .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_ETH_DIV, },
  723. .ep_count = 2,
  724. },
  725. {
  726. .n = "i2smcc0_gclk",
  727. .id = 57,
  728. .r = { .max = 100000000 },
  729. .ep = { "syspll_divpmcck", "audiopll_divpmcck", },
  730. .ep_mux_table = { 5, 9, },
  731. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
  732. .ep_count = 2,
  733. },
  734. {
  735. .n = "i2smcc1_gclk",
  736. .id = 58,
  737. .r = { .max = 100000000 },
  738. .ep = { "syspll_divpmcck", "audiopll_divpmcck", },
  739. .ep_mux_table = { 5, 9, },
  740. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
  741. .ep_count = 2,
  742. },
  743. {
  744. .n = "mcan0_gclk",
  745. .id = 61,
  746. .r = { .max = 200000000 },
  747. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  748. .ep_mux_table = { 5, 8, },
  749. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  750. .ep_count = 2,
  751. },
  752. {
  753. .n = "mcan1_gclk",
  754. .id = 62,
  755. .r = { .max = 200000000 },
  756. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  757. .ep_mux_table = { 5, 8, },
  758. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  759. .ep_count = 2,
  760. },
  761. {
  762. .n = "mcan2_gclk",
  763. .id = 63,
  764. .r = { .max = 200000000 },
  765. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  766. .ep_mux_table = { 5, 8, },
  767. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  768. .ep_count = 2,
  769. },
  770. {
  771. .n = "mcan3_gclk",
  772. .id = 64,
  773. .r = { .max = 200000000 },
  774. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  775. .ep_mux_table = { 5, 8, },
  776. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  777. .ep_count = 2,
  778. },
  779. {
  780. .n = "mcan4_gclk",
  781. .id = 65,
  782. .r = { .max = 200000000 },
  783. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  784. .ep_mux_table = { 5, 8, },
  785. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  786. .ep_count = 2,
  787. },
  788. {
  789. .n = "mcan5_gclk",
  790. .id = 66,
  791. .r = { .max = 200000000 },
  792. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  793. .ep_mux_table = { 5, 8, },
  794. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  795. .ep_count = 2,
  796. },
  797. {
  798. .n = "pdmc0_gclk",
  799. .id = 68,
  800. .r = { .max = 50000000 },
  801. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  802. .ep_mux_table = { 5, 8, },
  803. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  804. .ep_count = 2,
  805. },
  806. {
  807. .n = "pdmc1_gclk",
  808. .id = 69,
  809. .r = { .max = 50000000, },
  810. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  811. .ep_mux_table = { 5, 8, },
  812. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  813. .ep_count = 2,
  814. },
  815. {
  816. .n = "pit64b0_gclk",
  817. .id = 70,
  818. .r = { .max = 200000000 },
  819. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  820. "audiopll_divpmcck", "ethpll_divpmcck", },
  821. .ep_mux_table = { 5, 7, 8, 9, 10, },
  822. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  823. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  824. ID_PLL_ETH_DIV, },
  825. .ep_count = 5,
  826. },
  827. {
  828. .n = "pit64b1_gclk",
  829. .id = 71,
  830. .r = { .max = 200000000 },
  831. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  832. "audiopll_divpmcck", "ethpll_divpmcck", },
  833. .ep_mux_table = { 5, 7, 8, 9, 10, },
  834. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  835. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  836. ID_PLL_ETH_DIV, },
  837. .ep_count = 5,
  838. },
  839. {
  840. .n = "pit64b2_gclk",
  841. .id = 72,
  842. .r = { .max = 200000000 },
  843. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  844. "audiopll_divpmcck", "ethpll_divpmcck", },
  845. .ep_mux_table = { 5, 7, 8, 9, 10, },
  846. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  847. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  848. ID_PLL_ETH_DIV, },
  849. .ep_count = 5,
  850. },
  851. {
  852. .n = "pit64b3_gclk",
  853. .id = 73,
  854. .r = { .max = 200000000 },
  855. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  856. "audiopll_divpmcck", "ethpll_divpmcck", },
  857. .ep_mux_table = { 5, 7, 8, 9, 10, },
  858. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  859. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  860. ID_PLL_ETH_DIV, },
  861. .ep_count = 5,
  862. },
  863. {
  864. .n = "pit64b4_gclk",
  865. .id = 74,
  866. .r = { .max = 200000000 },
  867. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  868. "audiopll_divpmcck", "ethpll_divpmcck", },
  869. .ep_mux_table = { 5, 7, 8, 9, 10, },
  870. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  871. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  872. ID_PLL_ETH_DIV, },
  873. .ep_count = 5,
  874. },
  875. {
  876. .n = "pit64b5_gclk",
  877. .id = 75,
  878. .r = { .max = 200000000 },
  879. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  880. "audiopll_divpmcck", "ethpll_divpmcck", },
  881. .ep_mux_table = { 5, 7, 8, 9, 10, },
  882. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  883. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  884. ID_PLL_ETH_DIV, },
  885. .ep_count = 5,
  886. },
  887. {
  888. .n = "qspi0_gclk",
  889. .id = 78,
  890. .r = { .max = 200000000 },
  891. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  892. .ep_mux_table = { 5, 8, },
  893. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  894. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  895. ID_PLL_ETH_DIV, },
  896. .ep_count = 2,
  897. },
  898. {
  899. .n = "qspi1_gclk",
  900. .id = 79,
  901. .r = { .max = 200000000 },
  902. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  903. .ep_mux_table = { 5, 8, },
  904. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  905. .ep_count = 2,
  906. },
  907. {
  908. .n = "sdmmc0_gclk",
  909. .id = 80,
  910. .r = { .max = 208000000 },
  911. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  912. .ep_mux_table = { 5, 8, },
  913. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  914. .ep_count = 2,
  915. },
  916. {
  917. .n = "sdmmc1_gclk",
  918. .id = 81,
  919. .r = { .max = 208000000 },
  920. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  921. .ep_mux_table = { 5, 8, },
  922. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  923. .ep_count = 2,
  924. },
  925. {
  926. .n = "sdmmc2_gclk",
  927. .id = 82,
  928. .r = { .max = 208000000 },
  929. .ep = { "syspll_divpmcck", "baudpll_divpmcck", },
  930. .ep_mux_table = { 5, 8, },
  931. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_BAUD_DIV, },
  932. .ep_count = 2,
  933. },
  934. {
  935. .n = "spdifrx_gclk",
  936. .id = 84,
  937. .r = { .max = 150000000 },
  938. .ep = { "syspll_divpmcck", "audiopll_divpmcck", },
  939. .ep_mux_table = { 5, 9, },
  940. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
  941. .ep_count = 2,
  942. },
  943. {
  944. .n = "spdiftx_gclk",
  945. .id = 85,
  946. .r = { .max = 25000000 },
  947. .ep = { "syspll_divpmcck", "audiopll_divpmcck", },
  948. .ep_mux_table = { 5, 9, },
  949. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_AUDIO_DIVPMC, },
  950. .ep_count = 2,
  951. },
  952. {
  953. .n = "tcb0_ch0_gclk",
  954. .id = 88,
  955. .r = { .max = 200000000 },
  956. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  957. "audiopll_divpmcck", "ethpll_divpmcck", },
  958. .ep_mux_table = { 5, 7, 8, 9, 10, },
  959. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  960. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  961. ID_PLL_ETH_DIV, },
  962. .ep_count = 5,
  963. },
  964. {
  965. .n = "tcb1_ch0_gclk",
  966. .id = 91,
  967. .r = { .max = 200000000 },
  968. .ep = { "syspll_divpmcck", "imgpll_divpmcck", "baudpll_divpmcck",
  969. "audiopll_divpmcck", "ethpll_divpmcck", },
  970. .ep_mux_table = { 5, 7, 8, 9, 10, },
  971. .ep_clk_mux_table = { ID_PLL_SYS_DIV, ID_PLL_IMG_DIV,
  972. ID_PLL_BAUD_DIV, ID_PLL_AUDIO_DIVPMC,
  973. ID_PLL_ETH_DIV, },
  974. .ep_count = 5,
  975. },
  976. };
  977. /**
  978. * Clock setup description
  979. * @cid: clock id corresponding to clock subsystem
  980. * @pid: parent clock id corresponding to clock subsystem
  981. * @rate: clock rate
  982. * @prate: parent rate
  983. */
  984. static const struct pmc_clk_setup {
  985. unsigned int cid;
  986. unsigned int pid;
  987. unsigned long rate;
  988. unsigned long prate;
  989. } sama7g5_clk_setup[] = {
  990. {
  991. .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_FRAC),
  992. .rate = 625000000,
  993. },
  994. {
  995. .cid = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV),
  996. .rate = 625000000,
  997. },
  998. };
  999. #define SAMA7G5_MAX_MUX_ALLOCS (64)
  1000. #define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label) \
  1001. do { \
  1002. int _i; \
  1003. if ((_index) >= SAMA7G5_MAX_MUX_ALLOCS) { \
  1004. debug("%s(): AT91: MUX: insufficient space\n", \
  1005. __func__); \
  1006. goto _label; \
  1007. } \
  1008. (_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL); \
  1009. if (!(_dst)) \
  1010. goto _label; \
  1011. (_allocs)[(_index)++] = (_dst); \
  1012. for (_i = 0; _i < (_num); _i++) \
  1013. (_dst)[_i] = (_src)[_i]; \
  1014. } while (0)
  1015. static int sama7g5_clk_probe(struct udevice *dev)
  1016. {
  1017. void __iomem *base = (void *)devfdt_get_addr(dev);
  1018. unsigned int *clkmuxallocs[SAMA7G5_MAX_MUX_ALLOCS];
  1019. unsigned int *muxallocs[SAMA7G5_MAX_MUX_ALLOCS];
  1020. const char *p[10];
  1021. unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
  1022. struct clk clk, *c, *parent;
  1023. bool main_osc_bypass;
  1024. int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
  1025. if (IS_ERR(base))
  1026. return PTR_ERR(base);
  1027. memset(muxallocs, 0, ARRAY_SIZE(muxallocs));
  1028. memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs));
  1029. ret = clk_get_by_index(dev, 0, &clk);
  1030. if (ret)
  1031. return ret;
  1032. ret = clk_get_by_id(clk.id, &c);
  1033. if (ret)
  1034. return ret;
  1035. clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c),
  1036. strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL);
  1037. if (!clk_names[ID_TD_SLCK])
  1038. return -ENOMEM;
  1039. ret = clk_get_by_index(dev, 1, &clk);
  1040. if (ret)
  1041. return ret;
  1042. ret = clk_get_by_id(clk.id, &c);
  1043. if (ret)
  1044. return ret;
  1045. clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c),
  1046. strlen(clk_hw_get_name(c)) + 1, GFP_KERNEL);
  1047. if (!clk_names[ID_MD_SLCK])
  1048. return -ENOMEM;
  1049. ret = clk_get_by_index(dev, 2, &clk);
  1050. if (ret)
  1051. return ret;
  1052. clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk),
  1053. strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL);
  1054. if (!clk_names[ID_MAIN_XTAL])
  1055. return -ENOMEM;
  1056. ret = clk_get_by_index(dev, 3, &clk);
  1057. if (ret)
  1058. goto fail;
  1059. clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk),
  1060. strlen(clk_hw_get_name(&clk)) + 1, GFP_KERNEL);
  1061. if (ret)
  1062. goto fail;
  1063. main_osc_bypass = dev_read_bool(dev, "atmel,main-osc-bypass");
  1064. /* Register main rc oscillator. */
  1065. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC),
  1066. at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
  1067. clk_names[ID_MAIN_RC]));
  1068. /* Register main oscillator. */
  1069. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC),
  1070. at91_clk_main_osc(base, clk_names[ID_MAIN_OSC],
  1071. clk_names[ID_MAIN_XTAL], main_osc_bypass));
  1072. /* Register mainck. */
  1073. p[0] = clk_names[ID_MAIN_RC_OSC];
  1074. p[1] = clk_names[ID_MAIN_OSC];
  1075. cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC);
  1076. cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC);
  1077. prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
  1078. fail);
  1079. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK),
  1080. at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p,
  1081. 2, tmpclkmux, PMC_TYPE_CORE));
  1082. /* Register PLL fracs clocks. */
  1083. for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) {
  1084. if (sama7g5_plls[i].t != PLL_TYPE_FRAC)
  1085. continue;
  1086. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid),
  1087. sam9x60_clk_register_frac_pll(base, sama7g5_plls[i].n,
  1088. sama7g5_plls[i].p, sama7g5_plls[i].id,
  1089. &pll_characteristics, sama7g5_plls[i].l,
  1090. sama7g5_plls[i].c));
  1091. }
  1092. /* Register PLL div clocks. */
  1093. for (i = 0; i < ARRAY_SIZE(sama7g5_plls); i++) {
  1094. if (sama7g5_plls[i].t != PLL_TYPE_DIV)
  1095. continue;
  1096. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_plls[i].cid),
  1097. sam9x60_clk_register_div_pll(base, sama7g5_plls[i].n,
  1098. sama7g5_plls[i].p, sama7g5_plls[i].id,
  1099. &pll_characteristics, sama7g5_plls[i].l,
  1100. sama7g5_plls[i].c));
  1101. }
  1102. /* Register MCK0 clock. */
  1103. p[0] = clk_names[ID_MD_SLCK];
  1104. p[1] = clk_names[ID_MAINCK];
  1105. p[2] = clk_names[ID_PLL_CPU_DIV];
  1106. p[3] = clk_names[ID_PLL_SYS_DIV];
  1107. cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
  1108. cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
  1109. cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_CPU_DIV);
  1110. cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV);
  1111. prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
  1112. fail);
  1113. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0),
  1114. at91_clk_register_master(base, clk_names[ID_MCK0], p,
  1115. 4, &mck0_layout, &mck0_characteristics, tmpclkmux));
  1116. /* Register MCK1-4 clocks. */
  1117. p[0] = clk_names[ID_MD_SLCK];
  1118. p[1] = clk_names[ID_TD_SLCK];
  1119. p[2] = clk_names[ID_MAINCK];
  1120. p[3] = clk_names[ID_MCK0];
  1121. m[0] = 0;
  1122. m[1] = 1;
  1123. m[2] = 2;
  1124. m[3] = 3;
  1125. cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
  1126. cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
  1127. cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
  1128. cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0);
  1129. for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) {
  1130. for (j = 0; j < sama7g5_mckx[i].ep_count; j++) {
  1131. p[4 + j] = sama7g5_mckx[i].ep[j];
  1132. m[4 + j] = sama7g5_mckx[i].ep_mux_table[j];
  1133. cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
  1134. sama7g5_mckx[i].ep_clk_mux_table[j]);
  1135. }
  1136. prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
  1137. 4 + sama7g5_mckx[i].ep_count, fail);
  1138. prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
  1139. 4 + sama7g5_mckx[i].ep_count, fail);
  1140. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_mckx[i].cid),
  1141. at91_clk_sama7g5_register_master(base,
  1142. sama7g5_mckx[i].n, p, 4 + sama7g5_mckx[i].ep_count,
  1143. tmpmux, tmpclkmux, sama7g5_mckx[i].c,
  1144. sama7g5_mckx[i].id));
  1145. }
  1146. /* Register UTMI clock. */
  1147. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_UTMI),
  1148. at91_clk_sama7g5_register_utmi(base, "utmick",
  1149. clk_names[ID_MAIN_XTAL]));
  1150. /* Register programmable clocks. */
  1151. p[0] = clk_names[ID_MD_SLCK];
  1152. p[1] = clk_names[ID_TD_SLCK];
  1153. p[2] = clk_names[ID_MAINCK];
  1154. p[3] = clk_names[ID_MCK0];
  1155. p[4] = clk_names[ID_PLL_SYS_DIV];
  1156. p[5] = clk_names[ID_PLL_DDR_DIV];
  1157. p[6] = clk_names[ID_PLL_IMG_DIV];
  1158. p[7] = clk_names[ID_PLL_BAUD_DIV];
  1159. p[8] = clk_names[ID_PLL_AUDIO_DIVPMC];
  1160. p[9] = clk_names[ID_PLL_ETH_DIV];
  1161. cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
  1162. cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
  1163. cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
  1164. cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0);
  1165. cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_SYS_DIV);
  1166. cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_DDR_DIV);
  1167. cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_IMG_DIV);
  1168. cm[7] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_BAUD_DIV);
  1169. cm[8] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_AUDIO_DIVPMC);
  1170. cm[9] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_ETH_DIV);
  1171. for (i = 0; i < ARRAY_SIZE(sama7g5_prog); i++) {
  1172. prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
  1173. 10, fail);
  1174. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sama7g5_prog[i].cid),
  1175. at91_clk_register_programmable(base, sama7g5_prog[i].n,
  1176. p, 10, i, &programmable_layout, tmpclkmux,
  1177. sama7g5_prog_mux_table));
  1178. }
  1179. /* System clocks. */
  1180. for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
  1181. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sama7g5_systemck[i].cid),
  1182. at91_clk_register_system(base, sama7g5_systemck[i].n,
  1183. sama7g5_systemck[i].p, sama7g5_systemck[i].id));
  1184. }
  1185. /* Peripheral clocks. */
  1186. for (i = 0; i < ARRAY_SIZE(sama7g5_periphck); i++) {
  1187. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL,
  1188. sama7g5_periphck[i].id),
  1189. at91_clk_register_sam9x5_peripheral(base,
  1190. &sama7g5_pcr_layout, sama7g5_periphck[i].n,
  1191. sama7g5_periphck[i].p, sama7g5_periphck[i].id,
  1192. &sama7g5_periphck[i].r));
  1193. }
  1194. /* Generic clocks. */
  1195. p[0] = clk_names[ID_MD_SLCK];
  1196. p[1] = clk_names[ID_TD_SLCK];
  1197. p[2] = clk_names[ID_MAINCK];
  1198. p[3] = clk_names[ID_MCK0];
  1199. m[0] = 0;
  1200. m[1] = 1;
  1201. m[2] = 2;
  1202. m[3] = 3;
  1203. cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
  1204. cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
  1205. cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
  1206. cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK0);
  1207. for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) {
  1208. for (j = 0; j < sama7g5_gck[i].ep_count; j++) {
  1209. p[4 + j] = sama7g5_gck[i].ep[j];
  1210. m[4 + j] = sama7g5_gck[i].ep_mux_table[j];
  1211. cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
  1212. sama7g5_gck[i].ep_clk_mux_table[j]);
  1213. }
  1214. prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
  1215. 4 + sama7g5_gck[i].ep_count, fail);
  1216. prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
  1217. 4 + sama7g5_gck[i].ep_count, fail);
  1218. clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sama7g5_gck[i].id),
  1219. at91_clk_register_generic(base, &sama7g5_pcr_layout,
  1220. sama7g5_gck[i].n, p, tmpclkmux, tmpmux,
  1221. 4 + sama7g5_gck[i].ep_count, sama7g5_gck[i].id,
  1222. &sama7g5_gck[i].r));
  1223. }
  1224. /* Setup clocks. */
  1225. for (i = 0; i < ARRAY_SIZE(sama7g5_clk_setup); i++) {
  1226. ret = clk_get_by_id(sama7g5_clk_setup[i].cid, &c);
  1227. if (ret)
  1228. goto fail;
  1229. if (sama7g5_clk_setup[i].pid) {
  1230. ret = clk_get_by_id(sama7g5_clk_setup[i].pid, &parent);
  1231. if (ret)
  1232. goto fail;
  1233. ret = clk_set_parent(c, parent);
  1234. if (ret)
  1235. goto fail;
  1236. if (sama7g5_clk_setup[i].prate) {
  1237. ret = clk_set_rate(parent,
  1238. sama7g5_clk_setup[i].prate);
  1239. if (ret < 0)
  1240. goto fail;
  1241. }
  1242. }
  1243. if (sama7g5_clk_setup[i].rate) {
  1244. ret = clk_set_rate(c, sama7g5_clk_setup[i].rate);
  1245. if (ret < 0)
  1246. goto fail;
  1247. }
  1248. }
  1249. return 0;
  1250. fail:
  1251. for (i = 0; i < ARRAY_SIZE(muxallocs); i++)
  1252. kfree(muxallocs[i]);
  1253. for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++)
  1254. kfree(clkmuxallocs[i]);
  1255. return -ENOMEM;
  1256. }
  1257. static const struct udevice_id sama7g5_clk_ids[] = {
  1258. { .compatible = "microchip,sama7g5-pmc" },
  1259. { /* Sentinel. */ },
  1260. };
  1261. U_BOOT_DRIVER(at91_sama7g5_pmc) = {
  1262. .name = "at91-sama7g5-pmc",
  1263. .id = UCLASS_CLK,
  1264. .of_match = sama7g5_clk_ids,
  1265. .ops = &at91_clk_ops,
  1266. .probe = sama7g5_clk_probe,
  1267. .flags = DM_FLAG_PRE_RELOC,
  1268. };