clk_rk3399.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * (C) Copyright 2015 Google, Inc
  4. * (C) 2017 Theobroma Systems Design und Consulting GmbH
  5. */
  6. #include <common.h>
  7. #include <clk-uclass.h>
  8. #include <dm.h>
  9. #include <dt-structs.h>
  10. #include <errno.h>
  11. #include <log.h>
  12. #include <malloc.h>
  13. #include <mapmem.h>
  14. #include <syscon.h>
  15. #include <bitfield.h>
  16. #include <asm/io.h>
  17. #include <asm/arch-rockchip/clock.h>
  18. #include <asm/arch-rockchip/cru.h>
  19. #include <asm/arch-rockchip/hardware.h>
  20. #include <dm/lists.h>
  21. #include <dt-bindings/clock/rk3399-cru.h>
  22. #include <linux/bitops.h>
  23. #include <linux/delay.h>
  24. DECLARE_GLOBAL_DATA_PTR;
  25. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  26. struct rk3399_clk_plat {
  27. struct dtd_rockchip_rk3399_cru dtd;
  28. };
  29. struct rk3399_pmuclk_plat {
  30. struct dtd_rockchip_rk3399_pmucru dtd;
  31. };
  32. #endif
  33. struct pll_div {
  34. u32 refdiv;
  35. u32 fbdiv;
  36. u32 postdiv1;
  37. u32 postdiv2;
  38. u32 frac;
  39. };
  40. #define RATE_TO_DIV(input_rate, output_rate) \
  41. ((input_rate) / (output_rate) - 1)
  42. #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
  43. #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
  44. .refdiv = _refdiv,\
  45. .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
  46. .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
  47. static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
  48. static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2);
  49. #if !defined(CONFIG_SPL_BUILD)
  50. static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
  51. #endif
  52. static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600 * MHz, 3, 1, 1);
  53. static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600 * MHz, 1, 2, 1);
  54. static const struct pll_div *apll_l_cfgs[] = {
  55. [APLL_L_1600_MHZ] = &apll_l_1600_cfg,
  56. [APLL_L_600_MHZ] = &apll_l_600_cfg,
  57. };
  58. static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600 * MHz, 1, 2, 1);
  59. static const struct pll_div *apll_b_cfgs[] = {
  60. [APLL_B_600_MHZ] = &apll_b_600_cfg,
  61. };
  62. enum {
  63. /* PLL_CON0 */
  64. PLL_FBDIV_MASK = 0xfff,
  65. PLL_FBDIV_SHIFT = 0,
  66. /* PLL_CON1 */
  67. PLL_POSTDIV2_SHIFT = 12,
  68. PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT,
  69. PLL_POSTDIV1_SHIFT = 8,
  70. PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT,
  71. PLL_REFDIV_MASK = 0x3f,
  72. PLL_REFDIV_SHIFT = 0,
  73. /* PLL_CON2 */
  74. PLL_LOCK_STATUS_SHIFT = 31,
  75. PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT,
  76. PLL_FRACDIV_MASK = 0xffffff,
  77. PLL_FRACDIV_SHIFT = 0,
  78. /* PLL_CON3 */
  79. PLL_MODE_SHIFT = 8,
  80. PLL_MODE_MASK = 3 << PLL_MODE_SHIFT,
  81. PLL_MODE_SLOW = 0,
  82. PLL_MODE_NORM,
  83. PLL_MODE_DEEP,
  84. PLL_DSMPD_SHIFT = 3,
  85. PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT,
  86. PLL_INTEGER_MODE = 1,
  87. /* PMUCRU_CLKSEL_CON0 */
  88. PMU_PCLK_DIV_CON_MASK = 0x1f,
  89. PMU_PCLK_DIV_CON_SHIFT = 0,
  90. /* PMUCRU_CLKSEL_CON1 */
  91. SPI3_PLL_SEL_SHIFT = 7,
  92. SPI3_PLL_SEL_MASK = 1 << SPI3_PLL_SEL_SHIFT,
  93. SPI3_PLL_SEL_24M = 0,
  94. SPI3_PLL_SEL_PPLL = 1,
  95. SPI3_DIV_CON_SHIFT = 0x0,
  96. SPI3_DIV_CON_MASK = 0x7f,
  97. /* PMUCRU_CLKSEL_CON2 */
  98. I2C_DIV_CON_MASK = 0x7f,
  99. CLK_I2C8_DIV_CON_SHIFT = 8,
  100. CLK_I2C0_DIV_CON_SHIFT = 0,
  101. /* PMUCRU_CLKSEL_CON3 */
  102. CLK_I2C4_DIV_CON_SHIFT = 0,
  103. /* CLKSEL_CON0 */
  104. ACLKM_CORE_L_DIV_CON_SHIFT = 8,
  105. ACLKM_CORE_L_DIV_CON_MASK = 0x1f << ACLKM_CORE_L_DIV_CON_SHIFT,
  106. CLK_CORE_L_PLL_SEL_SHIFT = 6,
  107. CLK_CORE_L_PLL_SEL_MASK = 3 << CLK_CORE_L_PLL_SEL_SHIFT,
  108. CLK_CORE_L_PLL_SEL_ALPLL = 0x0,
  109. CLK_CORE_L_PLL_SEL_ABPLL = 0x1,
  110. CLK_CORE_L_PLL_SEL_DPLL = 0x10,
  111. CLK_CORE_L_PLL_SEL_GPLL = 0x11,
  112. CLK_CORE_L_DIV_MASK = 0x1f,
  113. CLK_CORE_L_DIV_SHIFT = 0,
  114. /* CLKSEL_CON1 */
  115. PCLK_DBG_L_DIV_SHIFT = 0x8,
  116. PCLK_DBG_L_DIV_MASK = 0x1f << PCLK_DBG_L_DIV_SHIFT,
  117. ATCLK_CORE_L_DIV_SHIFT = 0,
  118. ATCLK_CORE_L_DIV_MASK = 0x1f << ATCLK_CORE_L_DIV_SHIFT,
  119. /* CLKSEL_CON2 */
  120. ACLKM_CORE_B_DIV_CON_SHIFT = 8,
  121. ACLKM_CORE_B_DIV_CON_MASK = 0x1f << ACLKM_CORE_B_DIV_CON_SHIFT,
  122. CLK_CORE_B_PLL_SEL_SHIFT = 6,
  123. CLK_CORE_B_PLL_SEL_MASK = 3 << CLK_CORE_B_PLL_SEL_SHIFT,
  124. CLK_CORE_B_PLL_SEL_ALPLL = 0x0,
  125. CLK_CORE_B_PLL_SEL_ABPLL = 0x1,
  126. CLK_CORE_B_PLL_SEL_DPLL = 0x10,
  127. CLK_CORE_B_PLL_SEL_GPLL = 0x11,
  128. CLK_CORE_B_DIV_MASK = 0x1f,
  129. CLK_CORE_B_DIV_SHIFT = 0,
  130. /* CLKSEL_CON3 */
  131. PCLK_DBG_B_DIV_SHIFT = 0x8,
  132. PCLK_DBG_B_DIV_MASK = 0x1f << PCLK_DBG_B_DIV_SHIFT,
  133. ATCLK_CORE_B_DIV_SHIFT = 0,
  134. ATCLK_CORE_B_DIV_MASK = 0x1f << ATCLK_CORE_B_DIV_SHIFT,
  135. /* CLKSEL_CON14 */
  136. PCLK_PERIHP_DIV_CON_SHIFT = 12,
  137. PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
  138. HCLK_PERIHP_DIV_CON_SHIFT = 8,
  139. HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT,
  140. ACLK_PERIHP_PLL_SEL_SHIFT = 7,
  141. ACLK_PERIHP_PLL_SEL_MASK = 1 << ACLK_PERIHP_PLL_SEL_SHIFT,
  142. ACLK_PERIHP_PLL_SEL_CPLL = 0,
  143. ACLK_PERIHP_PLL_SEL_GPLL = 1,
  144. ACLK_PERIHP_DIV_CON_SHIFT = 0,
  145. ACLK_PERIHP_DIV_CON_MASK = 0x1f,
  146. /* CLKSEL_CON21 */
  147. ACLK_EMMC_PLL_SEL_SHIFT = 7,
  148. ACLK_EMMC_PLL_SEL_MASK = 0x1 << ACLK_EMMC_PLL_SEL_SHIFT,
  149. ACLK_EMMC_PLL_SEL_GPLL = 0x1,
  150. ACLK_EMMC_DIV_CON_SHIFT = 0,
  151. ACLK_EMMC_DIV_CON_MASK = 0x1f,
  152. /* CLKSEL_CON22 */
  153. CLK_EMMC_PLL_SHIFT = 8,
  154. CLK_EMMC_PLL_MASK = 0x7 << CLK_EMMC_PLL_SHIFT,
  155. CLK_EMMC_PLL_SEL_GPLL = 0x1,
  156. CLK_EMMC_PLL_SEL_24M = 0x5,
  157. CLK_EMMC_DIV_CON_SHIFT = 0,
  158. CLK_EMMC_DIV_CON_MASK = 0x7f << CLK_EMMC_DIV_CON_SHIFT,
  159. /* CLKSEL_CON23 */
  160. PCLK_PERILP0_DIV_CON_SHIFT = 12,
  161. PCLK_PERILP0_DIV_CON_MASK = 0x7 << PCLK_PERILP0_DIV_CON_SHIFT,
  162. HCLK_PERILP0_DIV_CON_SHIFT = 8,
  163. HCLK_PERILP0_DIV_CON_MASK = 3 << HCLK_PERILP0_DIV_CON_SHIFT,
  164. ACLK_PERILP0_PLL_SEL_SHIFT = 7,
  165. ACLK_PERILP0_PLL_SEL_MASK = 1 << ACLK_PERILP0_PLL_SEL_SHIFT,
  166. ACLK_PERILP0_PLL_SEL_CPLL = 0,
  167. ACLK_PERILP0_PLL_SEL_GPLL = 1,
  168. ACLK_PERILP0_DIV_CON_SHIFT = 0,
  169. ACLK_PERILP0_DIV_CON_MASK = 0x1f,
  170. /* CLKSEL_CON25 */
  171. PCLK_PERILP1_DIV_CON_SHIFT = 8,
  172. PCLK_PERILP1_DIV_CON_MASK = 0x7 << PCLK_PERILP1_DIV_CON_SHIFT,
  173. HCLK_PERILP1_PLL_SEL_SHIFT = 7,
  174. HCLK_PERILP1_PLL_SEL_MASK = 1 << HCLK_PERILP1_PLL_SEL_SHIFT,
  175. HCLK_PERILP1_PLL_SEL_CPLL = 0,
  176. HCLK_PERILP1_PLL_SEL_GPLL = 1,
  177. HCLK_PERILP1_DIV_CON_SHIFT = 0,
  178. HCLK_PERILP1_DIV_CON_MASK = 0x1f,
  179. /* CLKSEL_CON26 */
  180. CLK_SARADC_DIV_CON_SHIFT = 8,
  181. CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
  182. CLK_SARADC_DIV_CON_WIDTH = 8,
  183. /* CLKSEL_CON27 */
  184. CLK_TSADC_SEL_X24M = 0x0,
  185. CLK_TSADC_SEL_SHIFT = 15,
  186. CLK_TSADC_SEL_MASK = 1 << CLK_TSADC_SEL_SHIFT,
  187. CLK_TSADC_DIV_CON_SHIFT = 0,
  188. CLK_TSADC_DIV_CON_MASK = 0x3ff,
  189. /* CLKSEL_CON47 & CLKSEL_CON48 */
  190. ACLK_VOP_PLL_SEL_SHIFT = 6,
  191. ACLK_VOP_PLL_SEL_MASK = 0x3 << ACLK_VOP_PLL_SEL_SHIFT,
  192. ACLK_VOP_PLL_SEL_CPLL = 0x1,
  193. ACLK_VOP_DIV_CON_SHIFT = 0,
  194. ACLK_VOP_DIV_CON_MASK = 0x1f << ACLK_VOP_DIV_CON_SHIFT,
  195. /* CLKSEL_CON49 & CLKSEL_CON50 */
  196. DCLK_VOP_DCLK_SEL_SHIFT = 11,
  197. DCLK_VOP_DCLK_SEL_MASK = 1 << DCLK_VOP_DCLK_SEL_SHIFT,
  198. DCLK_VOP_DCLK_SEL_DIVOUT = 0,
  199. DCLK_VOP_PLL_SEL_SHIFT = 8,
  200. DCLK_VOP_PLL_SEL_MASK = 3 << DCLK_VOP_PLL_SEL_SHIFT,
  201. DCLK_VOP_PLL_SEL_VPLL = 0,
  202. DCLK_VOP_DIV_CON_MASK = 0xff,
  203. DCLK_VOP_DIV_CON_SHIFT = 0,
  204. /* CLKSEL_CON57 */
  205. PCLK_ALIVE_DIV_CON_SHIFT = 0,
  206. PCLK_ALIVE_DIV_CON_MASK = 0x1f << PCLK_ALIVE_DIV_CON_SHIFT,
  207. /* CLKSEL_CON58 */
  208. CLK_SPI_PLL_SEL_WIDTH = 1,
  209. CLK_SPI_PLL_SEL_MASK = ((1 < CLK_SPI_PLL_SEL_WIDTH) - 1),
  210. CLK_SPI_PLL_SEL_CPLL = 0,
  211. CLK_SPI_PLL_SEL_GPLL = 1,
  212. CLK_SPI_PLL_DIV_CON_WIDTH = 7,
  213. CLK_SPI_PLL_DIV_CON_MASK = ((1 << CLK_SPI_PLL_DIV_CON_WIDTH) - 1),
  214. CLK_SPI5_PLL_DIV_CON_SHIFT = 8,
  215. CLK_SPI5_PLL_SEL_SHIFT = 15,
  216. /* CLKSEL_CON59 */
  217. CLK_SPI1_PLL_SEL_SHIFT = 15,
  218. CLK_SPI1_PLL_DIV_CON_SHIFT = 8,
  219. CLK_SPI0_PLL_SEL_SHIFT = 7,
  220. CLK_SPI0_PLL_DIV_CON_SHIFT = 0,
  221. /* CLKSEL_CON60 */
  222. CLK_SPI4_PLL_SEL_SHIFT = 15,
  223. CLK_SPI4_PLL_DIV_CON_SHIFT = 8,
  224. CLK_SPI2_PLL_SEL_SHIFT = 7,
  225. CLK_SPI2_PLL_DIV_CON_SHIFT = 0,
  226. /* CLKSEL_CON61 */
  227. CLK_I2C_PLL_SEL_MASK = 1,
  228. CLK_I2C_PLL_SEL_CPLL = 0,
  229. CLK_I2C_PLL_SEL_GPLL = 1,
  230. CLK_I2C5_PLL_SEL_SHIFT = 15,
  231. CLK_I2C5_DIV_CON_SHIFT = 8,
  232. CLK_I2C1_PLL_SEL_SHIFT = 7,
  233. CLK_I2C1_DIV_CON_SHIFT = 0,
  234. /* CLKSEL_CON62 */
  235. CLK_I2C6_PLL_SEL_SHIFT = 15,
  236. CLK_I2C6_DIV_CON_SHIFT = 8,
  237. CLK_I2C2_PLL_SEL_SHIFT = 7,
  238. CLK_I2C2_DIV_CON_SHIFT = 0,
  239. /* CLKSEL_CON63 */
  240. CLK_I2C7_PLL_SEL_SHIFT = 15,
  241. CLK_I2C7_DIV_CON_SHIFT = 8,
  242. CLK_I2C3_PLL_SEL_SHIFT = 7,
  243. CLK_I2C3_DIV_CON_SHIFT = 0,
  244. /* CRU_SOFTRST_CON4 */
  245. RESETN_DDR0_REQ_SHIFT = 8,
  246. RESETN_DDR0_REQ_MASK = 1 << RESETN_DDR0_REQ_SHIFT,
  247. RESETN_DDRPHY0_REQ_SHIFT = 9,
  248. RESETN_DDRPHY0_REQ_MASK = 1 << RESETN_DDRPHY0_REQ_SHIFT,
  249. RESETN_DDR1_REQ_SHIFT = 12,
  250. RESETN_DDR1_REQ_MASK = 1 << RESETN_DDR1_REQ_SHIFT,
  251. RESETN_DDRPHY1_REQ_SHIFT = 13,
  252. RESETN_DDRPHY1_REQ_MASK = 1 << RESETN_DDRPHY1_REQ_SHIFT,
  253. };
  254. #define VCO_MAX_KHZ (3200 * (MHz / KHz))
  255. #define VCO_MIN_KHZ (800 * (MHz / KHz))
  256. #define OUTPUT_MAX_KHZ (3200 * (MHz / KHz))
  257. #define OUTPUT_MIN_KHZ (16 * (MHz / KHz))
  258. /*
  259. * the div restructions of pll in integer mode, these are defined in
  260. * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0
  261. */
  262. #define PLL_DIV_MIN 16
  263. #define PLL_DIV_MAX 3200
  264. /*
  265. * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
  266. * Formulas also embedded within the Fractional PLL Verilog model:
  267. * If DSMPD = 1 (DSM is disabled, "integer mode")
  268. * FOUTVCO = FREF / REFDIV * FBDIV
  269. * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
  270. * Where:
  271. * FOUTVCO = Fractional PLL non-divided output frequency
  272. * FOUTPOSTDIV = Fractional PLL divided output frequency
  273. * (output of second post divider)
  274. * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
  275. * REFDIV = Fractional PLL input reference clock divider
  276. * FBDIV = Integer value programmed into feedback divide
  277. *
  278. */
  279. static void rkclk_set_pll(u32 *pll_con, const struct pll_div *div)
  280. {
  281. /* All 8 PLLs have same VCO and output frequency range restrictions. */
  282. u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv;
  283. u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2;
  284. debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, "
  285. "postdiv2=%d, vco=%u khz, output=%u khz\n",
  286. pll_con, div->fbdiv, div->refdiv, div->postdiv1,
  287. div->postdiv2, vco_khz, output_khz);
  288. assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ &&
  289. output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ &&
  290. div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX);
  291. /*
  292. * When power on or changing PLL setting,
  293. * we must force PLL into slow mode to ensure output stable clock.
  294. */
  295. rk_clrsetreg(&pll_con[3], PLL_MODE_MASK,
  296. PLL_MODE_SLOW << PLL_MODE_SHIFT);
  297. /* use integer mode */
  298. rk_clrsetreg(&pll_con[3], PLL_DSMPD_MASK,
  299. PLL_INTEGER_MODE << PLL_DSMPD_SHIFT);
  300. rk_clrsetreg(&pll_con[0], PLL_FBDIV_MASK,
  301. div->fbdiv << PLL_FBDIV_SHIFT);
  302. rk_clrsetreg(&pll_con[1],
  303. PLL_POSTDIV2_MASK | PLL_POSTDIV1_MASK |
  304. PLL_REFDIV_MASK | PLL_REFDIV_SHIFT,
  305. (div->postdiv2 << PLL_POSTDIV2_SHIFT) |
  306. (div->postdiv1 << PLL_POSTDIV1_SHIFT) |
  307. (div->refdiv << PLL_REFDIV_SHIFT));
  308. /* waiting for pll lock */
  309. while (!(readl(&pll_con[2]) & (1 << PLL_LOCK_STATUS_SHIFT)))
  310. udelay(1);
  311. /* pll enter normal mode */
  312. rk_clrsetreg(&pll_con[3], PLL_MODE_MASK,
  313. PLL_MODE_NORM << PLL_MODE_SHIFT);
  314. }
  315. static int pll_para_config(u32 freq_hz, struct pll_div *div)
  316. {
  317. u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
  318. u32 postdiv1, postdiv2 = 1;
  319. u32 fref_khz;
  320. u32 diff_khz, best_diff_khz;
  321. const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
  322. const u32 max_postdiv1 = 7, max_postdiv2 = 7;
  323. u32 vco_khz;
  324. u32 freq_khz = freq_hz / KHz;
  325. if (!freq_hz) {
  326. printf("%s: the frequency can't be 0 Hz\n", __func__);
  327. return -1;
  328. }
  329. postdiv1 = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz);
  330. if (postdiv1 > max_postdiv1) {
  331. postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
  332. postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
  333. }
  334. vco_khz = freq_khz * postdiv1 * postdiv2;
  335. if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ ||
  336. postdiv2 > max_postdiv2) {
  337. printf("%s: Cannot find out a supported VCO"
  338. " for Frequency (%uHz).\n", __func__, freq_hz);
  339. return -1;
  340. }
  341. div->postdiv1 = postdiv1;
  342. div->postdiv2 = postdiv2;
  343. best_diff_khz = vco_khz;
  344. for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
  345. fref_khz = ref_khz / refdiv;
  346. fbdiv = vco_khz / fref_khz;
  347. if (fbdiv >= max_fbdiv || fbdiv <= min_fbdiv)
  348. continue;
  349. diff_khz = vco_khz - fbdiv * fref_khz;
  350. if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
  351. fbdiv++;
  352. diff_khz = fref_khz - diff_khz;
  353. }
  354. if (diff_khz >= best_diff_khz)
  355. continue;
  356. best_diff_khz = diff_khz;
  357. div->refdiv = refdiv;
  358. div->fbdiv = fbdiv;
  359. }
  360. if (best_diff_khz > 4 * (MHz / KHz)) {
  361. printf("%s: Failed to match output frequency %u, "
  362. "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz,
  363. best_diff_khz * KHz);
  364. return -1;
  365. }
  366. return 0;
  367. }
  368. void rk3399_configure_cpu_l(struct rockchip_cru *cru,
  369. enum apll_l_frequencies apll_l_freq)
  370. {
  371. u32 aclkm_div;
  372. u32 pclk_dbg_div;
  373. u32 atclk_div;
  374. /* Setup cluster L */
  375. rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]);
  376. aclkm_div = LPLL_HZ / ACLKM_CORE_L_HZ - 1;
  377. assert((aclkm_div + 1) * ACLKM_CORE_L_HZ == LPLL_HZ &&
  378. aclkm_div < 0x1f);
  379. pclk_dbg_div = LPLL_HZ / PCLK_DBG_L_HZ - 1;
  380. assert((pclk_dbg_div + 1) * PCLK_DBG_L_HZ == LPLL_HZ &&
  381. pclk_dbg_div < 0x1f);
  382. atclk_div = LPLL_HZ / ATCLK_CORE_L_HZ - 1;
  383. assert((atclk_div + 1) * ATCLK_CORE_L_HZ == LPLL_HZ &&
  384. atclk_div < 0x1f);
  385. rk_clrsetreg(&cru->clksel_con[0],
  386. ACLKM_CORE_L_DIV_CON_MASK | CLK_CORE_L_PLL_SEL_MASK |
  387. CLK_CORE_L_DIV_MASK,
  388. aclkm_div << ACLKM_CORE_L_DIV_CON_SHIFT |
  389. CLK_CORE_L_PLL_SEL_ALPLL << CLK_CORE_L_PLL_SEL_SHIFT |
  390. 0 << CLK_CORE_L_DIV_SHIFT);
  391. rk_clrsetreg(&cru->clksel_con[1],
  392. PCLK_DBG_L_DIV_MASK | ATCLK_CORE_L_DIV_MASK,
  393. pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT |
  394. atclk_div << ATCLK_CORE_L_DIV_SHIFT);
  395. }
  396. void rk3399_configure_cpu_b(struct rockchip_cru *cru,
  397. enum apll_b_frequencies apll_b_freq)
  398. {
  399. u32 aclkm_div;
  400. u32 pclk_dbg_div;
  401. u32 atclk_div;
  402. /* Setup cluster B */
  403. rkclk_set_pll(&cru->apll_b_con[0], apll_b_cfgs[apll_b_freq]);
  404. aclkm_div = BPLL_HZ / ACLKM_CORE_B_HZ - 1;
  405. assert((aclkm_div + 1) * ACLKM_CORE_B_HZ == BPLL_HZ &&
  406. aclkm_div < 0x1f);
  407. pclk_dbg_div = BPLL_HZ / PCLK_DBG_B_HZ - 1;
  408. assert((pclk_dbg_div + 1) * PCLK_DBG_B_HZ == BPLL_HZ &&
  409. pclk_dbg_div < 0x1f);
  410. atclk_div = BPLL_HZ / ATCLK_CORE_B_HZ - 1;
  411. assert((atclk_div + 1) * ATCLK_CORE_B_HZ == BPLL_HZ &&
  412. atclk_div < 0x1f);
  413. rk_clrsetreg(&cru->clksel_con[2],
  414. ACLKM_CORE_B_DIV_CON_MASK | CLK_CORE_B_PLL_SEL_MASK |
  415. CLK_CORE_B_DIV_MASK,
  416. aclkm_div << ACLKM_CORE_B_DIV_CON_SHIFT |
  417. CLK_CORE_B_PLL_SEL_ABPLL << CLK_CORE_B_PLL_SEL_SHIFT |
  418. 0 << CLK_CORE_B_DIV_SHIFT);
  419. rk_clrsetreg(&cru->clksel_con[3],
  420. PCLK_DBG_B_DIV_MASK | ATCLK_CORE_B_DIV_MASK,
  421. pclk_dbg_div << PCLK_DBG_B_DIV_SHIFT |
  422. atclk_div << ATCLK_CORE_B_DIV_SHIFT);
  423. }
  424. #define I2C_CLK_REG_MASK(bus) \
  425. (I2C_DIV_CON_MASK << CLK_I2C ##bus## _DIV_CON_SHIFT | \
  426. CLK_I2C_PLL_SEL_MASK << CLK_I2C ##bus## _PLL_SEL_SHIFT)
  427. #define I2C_CLK_REG_VALUE(bus, clk_div) \
  428. ((clk_div - 1) << CLK_I2C ##bus## _DIV_CON_SHIFT | \
  429. CLK_I2C_PLL_SEL_GPLL << CLK_I2C ##bus## _PLL_SEL_SHIFT)
  430. #define I2C_CLK_DIV_VALUE(con, bus) \
  431. ((con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & I2C_DIV_CON_MASK)
  432. #define I2C_PMUCLK_REG_MASK(bus) \
  433. (I2C_DIV_CON_MASK << CLK_I2C ##bus## _DIV_CON_SHIFT)
  434. #define I2C_PMUCLK_REG_VALUE(bus, clk_div) \
  435. ((clk_div - 1) << CLK_I2C ##bus## _DIV_CON_SHIFT)
  436. static ulong rk3399_i2c_get_clk(struct rockchip_cru *cru, ulong clk_id)
  437. {
  438. u32 div, con;
  439. switch (clk_id) {
  440. case SCLK_I2C1:
  441. con = readl(&cru->clksel_con[61]);
  442. div = I2C_CLK_DIV_VALUE(con, 1);
  443. break;
  444. case SCLK_I2C2:
  445. con = readl(&cru->clksel_con[62]);
  446. div = I2C_CLK_DIV_VALUE(con, 2);
  447. break;
  448. case SCLK_I2C3:
  449. con = readl(&cru->clksel_con[63]);
  450. div = I2C_CLK_DIV_VALUE(con, 3);
  451. break;
  452. case SCLK_I2C5:
  453. con = readl(&cru->clksel_con[61]);
  454. div = I2C_CLK_DIV_VALUE(con, 5);
  455. break;
  456. case SCLK_I2C6:
  457. con = readl(&cru->clksel_con[62]);
  458. div = I2C_CLK_DIV_VALUE(con, 6);
  459. break;
  460. case SCLK_I2C7:
  461. con = readl(&cru->clksel_con[63]);
  462. div = I2C_CLK_DIV_VALUE(con, 7);
  463. break;
  464. default:
  465. printf("do not support this i2c bus\n");
  466. return -EINVAL;
  467. }
  468. return DIV_TO_RATE(GPLL_HZ, div);
  469. }
  470. static ulong rk3399_i2c_set_clk(struct rockchip_cru *cru, ulong clk_id, uint hz)
  471. {
  472. int src_clk_div;
  473. /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
  474. src_clk_div = GPLL_HZ / hz;
  475. assert(src_clk_div - 1 < 127);
  476. switch (clk_id) {
  477. case SCLK_I2C1:
  478. rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(1),
  479. I2C_CLK_REG_VALUE(1, src_clk_div));
  480. break;
  481. case SCLK_I2C2:
  482. rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(2),
  483. I2C_CLK_REG_VALUE(2, src_clk_div));
  484. break;
  485. case SCLK_I2C3:
  486. rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(3),
  487. I2C_CLK_REG_VALUE(3, src_clk_div));
  488. break;
  489. case SCLK_I2C5:
  490. rk_clrsetreg(&cru->clksel_con[61], I2C_CLK_REG_MASK(5),
  491. I2C_CLK_REG_VALUE(5, src_clk_div));
  492. break;
  493. case SCLK_I2C6:
  494. rk_clrsetreg(&cru->clksel_con[62], I2C_CLK_REG_MASK(6),
  495. I2C_CLK_REG_VALUE(6, src_clk_div));
  496. break;
  497. case SCLK_I2C7:
  498. rk_clrsetreg(&cru->clksel_con[63], I2C_CLK_REG_MASK(7),
  499. I2C_CLK_REG_VALUE(7, src_clk_div));
  500. break;
  501. default:
  502. printf("do not support this i2c bus\n");
  503. return -EINVAL;
  504. }
  505. return rk3399_i2c_get_clk(cru, clk_id);
  506. }
  507. /*
  508. * RK3399 SPI clocks have a common divider-width (7 bits) and a single bit
  509. * to select either CPLL or GPLL as the clock-parent. The location within
  510. * the enclosing CLKSEL_CON (i.e. div_shift and sel_shift) are variable.
  511. */
  512. struct spi_clkreg {
  513. u8 reg; /* CLKSEL_CON[reg] register in CRU */
  514. u8 div_shift;
  515. u8 sel_shift;
  516. };
  517. /*
  518. * The entries are numbered relative to their offset from SCLK_SPI0.
  519. *
  520. * Note that SCLK_SPI3 (which is configured via PMUCRU and requires different
  521. * logic is not supported).
  522. */
  523. static const struct spi_clkreg spi_clkregs[] = {
  524. [0] = { .reg = 59,
  525. .div_shift = CLK_SPI0_PLL_DIV_CON_SHIFT,
  526. .sel_shift = CLK_SPI0_PLL_SEL_SHIFT, },
  527. [1] = { .reg = 59,
  528. .div_shift = CLK_SPI1_PLL_DIV_CON_SHIFT,
  529. .sel_shift = CLK_SPI1_PLL_SEL_SHIFT, },
  530. [2] = { .reg = 60,
  531. .div_shift = CLK_SPI2_PLL_DIV_CON_SHIFT,
  532. .sel_shift = CLK_SPI2_PLL_SEL_SHIFT, },
  533. [3] = { .reg = 60,
  534. .div_shift = CLK_SPI4_PLL_DIV_CON_SHIFT,
  535. .sel_shift = CLK_SPI4_PLL_SEL_SHIFT, },
  536. [4] = { .reg = 58,
  537. .div_shift = CLK_SPI5_PLL_DIV_CON_SHIFT,
  538. .sel_shift = CLK_SPI5_PLL_SEL_SHIFT, },
  539. };
  540. static ulong rk3399_spi_get_clk(struct rockchip_cru *cru, ulong clk_id)
  541. {
  542. const struct spi_clkreg *spiclk = NULL;
  543. u32 div, val;
  544. switch (clk_id) {
  545. case SCLK_SPI0 ... SCLK_SPI5:
  546. spiclk = &spi_clkregs[clk_id - SCLK_SPI0];
  547. break;
  548. default:
  549. pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
  550. return -EINVAL;
  551. }
  552. val = readl(&cru->clksel_con[spiclk->reg]);
  553. div = bitfield_extract(val, spiclk->div_shift,
  554. CLK_SPI_PLL_DIV_CON_WIDTH);
  555. return DIV_TO_RATE(GPLL_HZ, div);
  556. }
  557. static ulong rk3399_spi_set_clk(struct rockchip_cru *cru, ulong clk_id, uint hz)
  558. {
  559. const struct spi_clkreg *spiclk = NULL;
  560. int src_clk_div;
  561. src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
  562. assert(src_clk_div < 128);
  563. switch (clk_id) {
  564. case SCLK_SPI1 ... SCLK_SPI5:
  565. spiclk = &spi_clkregs[clk_id - SCLK_SPI0];
  566. break;
  567. default:
  568. pr_err("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
  569. return -EINVAL;
  570. }
  571. rk_clrsetreg(&cru->clksel_con[spiclk->reg],
  572. ((CLK_SPI_PLL_DIV_CON_MASK << spiclk->div_shift) |
  573. (CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift)),
  574. ((src_clk_div << spiclk->div_shift) |
  575. (CLK_SPI_PLL_SEL_GPLL << spiclk->sel_shift)));
  576. return rk3399_spi_get_clk(cru, clk_id);
  577. }
  578. static ulong rk3399_vop_set_clk(struct rockchip_cru *cru, ulong clk_id, u32 hz)
  579. {
  580. struct pll_div vpll_config = {0};
  581. int aclk_vop = 198 * MHz;
  582. void *aclkreg_addr, *dclkreg_addr;
  583. u32 div;
  584. switch (clk_id) {
  585. case DCLK_VOP0:
  586. aclkreg_addr = &cru->clksel_con[47];
  587. dclkreg_addr = &cru->clksel_con[49];
  588. break;
  589. case DCLK_VOP1:
  590. aclkreg_addr = &cru->clksel_con[48];
  591. dclkreg_addr = &cru->clksel_con[50];
  592. break;
  593. default:
  594. return -EINVAL;
  595. }
  596. /* vop aclk source clk: cpll */
  597. div = CPLL_HZ / aclk_vop;
  598. assert(div - 1 < 32);
  599. rk_clrsetreg(aclkreg_addr,
  600. ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK,
  601. ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT |
  602. (div - 1) << ACLK_VOP_DIV_CON_SHIFT);
  603. /* vop dclk source from vpll, and equals to vpll(means div == 1) */
  604. if (pll_para_config(hz, &vpll_config))
  605. return -1;
  606. rkclk_set_pll(&cru->vpll_con[0], &vpll_config);
  607. rk_clrsetreg(dclkreg_addr,
  608. DCLK_VOP_DCLK_SEL_MASK | DCLK_VOP_PLL_SEL_MASK |
  609. DCLK_VOP_DIV_CON_MASK,
  610. DCLK_VOP_DCLK_SEL_DIVOUT << DCLK_VOP_DCLK_SEL_SHIFT |
  611. DCLK_VOP_PLL_SEL_VPLL << DCLK_VOP_PLL_SEL_SHIFT |
  612. (1 - 1) << DCLK_VOP_DIV_CON_SHIFT);
  613. return hz;
  614. }
  615. static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id)
  616. {
  617. u32 div, con;
  618. switch (clk_id) {
  619. case HCLK_SDMMC:
  620. case SCLK_SDMMC:
  621. con = readl(&cru->clksel_con[16]);
  622. /* dwmmc controller have internal div 2 */
  623. div = 2;
  624. break;
  625. case SCLK_EMMC:
  626. con = readl(&cru->clksel_con[22]);
  627. div = 1;
  628. break;
  629. default:
  630. return -EINVAL;
  631. }
  632. div *= (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
  633. if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
  634. == CLK_EMMC_PLL_SEL_24M)
  635. return DIV_TO_RATE(OSC_HZ, div);
  636. else
  637. return DIV_TO_RATE(GPLL_HZ, div);
  638. }
  639. static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru,
  640. ulong clk_id, ulong set_rate)
  641. {
  642. int src_clk_div;
  643. int aclk_emmc = 198 * MHz;
  644. switch (clk_id) {
  645. case HCLK_SDMMC:
  646. case SCLK_SDMMC:
  647. /* Select clk_sdmmc source from GPLL by default */
  648. /* mmc clock defaulg div 2 internal, provide double in cru */
  649. src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
  650. if (src_clk_div > 128) {
  651. /* use 24MHz source for 400KHz clock */
  652. src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
  653. assert(src_clk_div - 1 < 128);
  654. rk_clrsetreg(&cru->clksel_con[16],
  655. CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
  656. CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
  657. (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
  658. } else {
  659. rk_clrsetreg(&cru->clksel_con[16],
  660. CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
  661. CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
  662. (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
  663. }
  664. break;
  665. case SCLK_EMMC:
  666. /* Select aclk_emmc source from GPLL */
  667. src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc);
  668. assert(src_clk_div - 1 < 32);
  669. rk_clrsetreg(&cru->clksel_con[21],
  670. ACLK_EMMC_PLL_SEL_MASK | ACLK_EMMC_DIV_CON_MASK,
  671. ACLK_EMMC_PLL_SEL_GPLL << ACLK_EMMC_PLL_SEL_SHIFT |
  672. (src_clk_div - 1) << ACLK_EMMC_DIV_CON_SHIFT);
  673. /* Select clk_emmc source from GPLL too */
  674. src_clk_div = DIV_ROUND_UP(GPLL_HZ, set_rate);
  675. assert(src_clk_div - 1 < 128);
  676. rk_clrsetreg(&cru->clksel_con[22],
  677. CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
  678. CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
  679. (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
  680. break;
  681. default:
  682. return -EINVAL;
  683. }
  684. return rk3399_mmc_get_clk(cru, clk_id);
  685. }
  686. static ulong rk3399_gmac_set_clk(struct rockchip_cru *cru, ulong rate)
  687. {
  688. ulong ret;
  689. /*
  690. * The RGMII CLK can be derived either from an external "clkin"
  691. * or can be generated from internally by a divider from SCLK_MAC.
  692. */
  693. if (readl(&cru->clksel_con[19]) & BIT(4)) {
  694. /* An external clock will always generate the right rate... */
  695. ret = rate;
  696. } else {
  697. /*
  698. * No platform uses an internal clock to date.
  699. * Implement this once it becomes necessary and print an error
  700. * if someone tries to use it (while it remains unimplemented).
  701. */
  702. pr_err("%s: internal clock is UNIMPLEMENTED\n", __func__);
  703. ret = 0;
  704. }
  705. return ret;
  706. }
  707. #define PMUSGRF_DDR_RGN_CON16 0xff330040
  708. static ulong rk3399_ddr_set_clk(struct rockchip_cru *cru,
  709. ulong set_rate)
  710. {
  711. struct pll_div dpll_cfg;
  712. /* IC ECO bug, need to set this register */
  713. writel(0xc000c000, PMUSGRF_DDR_RGN_CON16);
  714. /* clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
  715. switch (set_rate) {
  716. case 50 * MHz:
  717. dpll_cfg = (struct pll_div)
  718. {.refdiv = 1, .fbdiv = 12, .postdiv1 = 3, .postdiv2 = 2};
  719. break;
  720. case 200 * MHz:
  721. dpll_cfg = (struct pll_div)
  722. {.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
  723. break;
  724. case 300 * MHz:
  725. dpll_cfg = (struct pll_div)
  726. {.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
  727. break;
  728. case 400 * MHz:
  729. dpll_cfg = (struct pll_div)
  730. {.refdiv = 1, .fbdiv = 50, .postdiv1 = 3, .postdiv2 = 1};
  731. break;
  732. case 666 * MHz:
  733. dpll_cfg = (struct pll_div)
  734. {.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
  735. break;
  736. case 800 * MHz:
  737. dpll_cfg = (struct pll_div)
  738. {.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
  739. break;
  740. case 933 * MHz:
  741. dpll_cfg = (struct pll_div)
  742. {.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
  743. break;
  744. default:
  745. pr_err("Unsupported SDRAM frequency!,%ld\n", set_rate);
  746. }
  747. rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
  748. return set_rate;
  749. }
  750. static ulong rk3399_alive_get_clk(struct rockchip_cru *cru)
  751. {
  752. u32 div, val;
  753. val = readl(&cru->clksel_con[57]);
  754. div = (val & PCLK_ALIVE_DIV_CON_MASK) >>
  755. PCLK_ALIVE_DIV_CON_SHIFT;
  756. return DIV_TO_RATE(GPLL_HZ, div);
  757. }
  758. static ulong rk3399_saradc_get_clk(struct rockchip_cru *cru)
  759. {
  760. u32 div, val;
  761. val = readl(&cru->clksel_con[26]);
  762. div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
  763. CLK_SARADC_DIV_CON_WIDTH);
  764. return DIV_TO_RATE(OSC_HZ, div);
  765. }
  766. static ulong rk3399_saradc_set_clk(struct rockchip_cru *cru, uint hz)
  767. {
  768. int src_clk_div;
  769. src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
  770. assert(src_clk_div < 128);
  771. rk_clrsetreg(&cru->clksel_con[26],
  772. CLK_SARADC_DIV_CON_MASK,
  773. src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
  774. return rk3399_saradc_get_clk(cru);
  775. }
  776. static ulong rk3399_clk_get_rate(struct clk *clk)
  777. {
  778. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  779. ulong rate = 0;
  780. switch (clk->id) {
  781. case 0 ... 63:
  782. return 0;
  783. case HCLK_SDMMC:
  784. case SCLK_SDMMC:
  785. case SCLK_EMMC:
  786. rate = rk3399_mmc_get_clk(priv->cru, clk->id);
  787. break;
  788. case SCLK_I2C1:
  789. case SCLK_I2C2:
  790. case SCLK_I2C3:
  791. case SCLK_I2C5:
  792. case SCLK_I2C6:
  793. case SCLK_I2C7:
  794. rate = rk3399_i2c_get_clk(priv->cru, clk->id);
  795. break;
  796. case SCLK_SPI0...SCLK_SPI5:
  797. rate = rk3399_spi_get_clk(priv->cru, clk->id);
  798. break;
  799. case SCLK_UART0:
  800. case SCLK_UART1:
  801. case SCLK_UART2:
  802. case SCLK_UART3:
  803. return 24000000;
  804. case PCLK_HDMI_CTRL:
  805. break;
  806. case DCLK_VOP0:
  807. case DCLK_VOP1:
  808. break;
  809. case PCLK_EFUSE1024NS:
  810. break;
  811. case SCLK_SARADC:
  812. rate = rk3399_saradc_get_clk(priv->cru);
  813. break;
  814. case ACLK_VIO:
  815. case ACLK_HDCP:
  816. case ACLK_GIC_PRE:
  817. case PCLK_DDR:
  818. break;
  819. case PCLK_ALIVE:
  820. case PCLK_WDT:
  821. rate = rk3399_alive_get_clk(priv->cru);
  822. break;
  823. default:
  824. log_debug("Unknown clock %lu\n", clk->id);
  825. return -ENOENT;
  826. }
  827. return rate;
  828. }
  829. static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
  830. {
  831. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  832. ulong ret = 0;
  833. switch (clk->id) {
  834. case 0 ... 63:
  835. return 0;
  836. case ACLK_PERIHP:
  837. case HCLK_PERIHP:
  838. case PCLK_PERIHP:
  839. return 0;
  840. case ACLK_PERILP0:
  841. case HCLK_PERILP0:
  842. case PCLK_PERILP0:
  843. return 0;
  844. case ACLK_CCI:
  845. return 0;
  846. case HCLK_PERILP1:
  847. case PCLK_PERILP1:
  848. return 0;
  849. case HCLK_SDMMC:
  850. case SCLK_SDMMC:
  851. case SCLK_EMMC:
  852. ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate);
  853. break;
  854. case SCLK_MAC:
  855. ret = rk3399_gmac_set_clk(priv->cru, rate);
  856. break;
  857. case SCLK_I2C1:
  858. case SCLK_I2C2:
  859. case SCLK_I2C3:
  860. case SCLK_I2C5:
  861. case SCLK_I2C6:
  862. case SCLK_I2C7:
  863. ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate);
  864. break;
  865. case SCLK_SPI0...SCLK_SPI5:
  866. ret = rk3399_spi_set_clk(priv->cru, clk->id, rate);
  867. break;
  868. case PCLK_HDMI_CTRL:
  869. case PCLK_VIO_GRF:
  870. /* the PCLK gates for video are enabled by default */
  871. break;
  872. case DCLK_VOP0:
  873. case DCLK_VOP1:
  874. ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
  875. break;
  876. case ACLK_VOP1:
  877. case HCLK_VOP1:
  878. case HCLK_SD:
  879. case SCLK_UPHY0_TCPDCORE:
  880. case SCLK_UPHY1_TCPDCORE:
  881. /**
  882. * assigned-clocks handling won't require for vopl, so
  883. * return 0 to satisfy clk_set_defaults during device probe.
  884. */
  885. return 0;
  886. case SCLK_DDRCLK:
  887. ret = rk3399_ddr_set_clk(priv->cru, rate);
  888. break;
  889. case PCLK_EFUSE1024NS:
  890. break;
  891. case SCLK_SARADC:
  892. ret = rk3399_saradc_set_clk(priv->cru, rate);
  893. break;
  894. case ACLK_VIO:
  895. case ACLK_HDCP:
  896. case ACLK_GIC_PRE:
  897. case PCLK_DDR:
  898. return 0;
  899. default:
  900. log_debug("Unknown clock %lu\n", clk->id);
  901. return -ENOENT;
  902. }
  903. return ret;
  904. }
  905. static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk,
  906. struct clk *parent)
  907. {
  908. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  909. const char *clock_output_name;
  910. int ret;
  911. /*
  912. * If the requested parent is in the same clock-controller and
  913. * the id is SCLK_MAC ("clk_gmac"), switch to the internal clock.
  914. */
  915. if (parent->dev == clk->dev && parent->id == SCLK_MAC) {
  916. debug("%s: switching RGMII to SCLK_MAC\n", __func__);
  917. rk_clrreg(&priv->cru->clksel_con[19], BIT(4));
  918. return 0;
  919. }
  920. /*
  921. * Otherwise, we need to check the clock-output-names of the
  922. * requested parent to see if the requested id is "clkin_gmac".
  923. */
  924. ret = dev_read_string_index(parent->dev, "clock-output-names",
  925. parent->id, &clock_output_name);
  926. if (ret < 0)
  927. return -ENODATA;
  928. /* If this is "clkin_gmac", switch to the external clock input */
  929. if (!strcmp(clock_output_name, "clkin_gmac")) {
  930. debug("%s: switching RGMII to CLKIN\n", __func__);
  931. rk_setreg(&priv->cru->clksel_con[19], BIT(4));
  932. return 0;
  933. }
  934. return -EINVAL;
  935. }
  936. static int __maybe_unused rk3399_clk_set_parent(struct clk *clk,
  937. struct clk *parent)
  938. {
  939. switch (clk->id) {
  940. case SCLK_RMII_SRC:
  941. return rk3399_gmac_set_parent(clk, parent);
  942. }
  943. debug("%s: unsupported clk %ld\n", __func__, clk->id);
  944. return -ENOENT;
  945. }
  946. static int rk3399_clk_enable(struct clk *clk)
  947. {
  948. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  949. switch (clk->id) {
  950. case SCLK_MAC:
  951. rk_clrreg(&priv->cru->clkgate_con[5], BIT(5));
  952. break;
  953. case SCLK_MAC_RX:
  954. rk_clrreg(&priv->cru->clkgate_con[5], BIT(8));
  955. break;
  956. case SCLK_MAC_TX:
  957. rk_clrreg(&priv->cru->clkgate_con[5], BIT(9));
  958. break;
  959. case SCLK_MACREF:
  960. rk_clrreg(&priv->cru->clkgate_con[5], BIT(7));
  961. break;
  962. case SCLK_MACREF_OUT:
  963. rk_clrreg(&priv->cru->clkgate_con[5], BIT(6));
  964. break;
  965. case SCLK_USB2PHY0_REF:
  966. rk_clrreg(&priv->cru->clkgate_con[6], BIT(5));
  967. break;
  968. case SCLK_USB2PHY1_REF:
  969. rk_clrreg(&priv->cru->clkgate_con[6], BIT(6));
  970. break;
  971. case ACLK_GMAC:
  972. rk_clrreg(&priv->cru->clkgate_con[32], BIT(0));
  973. break;
  974. case PCLK_GMAC:
  975. rk_clrreg(&priv->cru->clkgate_con[32], BIT(2));
  976. break;
  977. case SCLK_USB3OTG0_REF:
  978. rk_clrreg(&priv->cru->clkgate_con[12], BIT(1));
  979. break;
  980. case SCLK_USB3OTG1_REF:
  981. rk_clrreg(&priv->cru->clkgate_con[12], BIT(2));
  982. break;
  983. case SCLK_USB3OTG0_SUSPEND:
  984. rk_clrreg(&priv->cru->clkgate_con[12], BIT(3));
  985. break;
  986. case SCLK_USB3OTG1_SUSPEND:
  987. rk_clrreg(&priv->cru->clkgate_con[12], BIT(4));
  988. break;
  989. case ACLK_USB3OTG0:
  990. rk_clrreg(&priv->cru->clkgate_con[30], BIT(1));
  991. break;
  992. case ACLK_USB3OTG1:
  993. rk_clrreg(&priv->cru->clkgate_con[30], BIT(2));
  994. break;
  995. case ACLK_USB3_RKSOC_AXI_PERF:
  996. rk_clrreg(&priv->cru->clkgate_con[30], BIT(3));
  997. break;
  998. case ACLK_USB3:
  999. rk_clrreg(&priv->cru->clkgate_con[12], BIT(0));
  1000. break;
  1001. case ACLK_USB3_GRF:
  1002. rk_clrreg(&priv->cru->clkgate_con[30], BIT(4));
  1003. break;
  1004. case HCLK_HOST0:
  1005. rk_clrreg(&priv->cru->clksel_con[20], BIT(5));
  1006. break;
  1007. case HCLK_HOST0_ARB:
  1008. rk_clrreg(&priv->cru->clksel_con[20], BIT(6));
  1009. break;
  1010. case HCLK_HOST1:
  1011. rk_clrreg(&priv->cru->clksel_con[20], BIT(7));
  1012. break;
  1013. case HCLK_HOST1_ARB:
  1014. rk_clrreg(&priv->cru->clksel_con[20], BIT(8));
  1015. break;
  1016. case SCLK_UPHY0_TCPDPHY_REF:
  1017. rk_clrreg(&priv->cru->clkgate_con[13], BIT(4));
  1018. break;
  1019. case SCLK_UPHY0_TCPDCORE:
  1020. rk_clrreg(&priv->cru->clkgate_con[13], BIT(5));
  1021. break;
  1022. case SCLK_UPHY1_TCPDPHY_REF:
  1023. rk_clrreg(&priv->cru->clkgate_con[13], BIT(6));
  1024. break;
  1025. case SCLK_UPHY1_TCPDCORE:
  1026. rk_clrreg(&priv->cru->clkgate_con[13], BIT(7));
  1027. break;
  1028. case SCLK_PCIEPHY_REF:
  1029. rk_clrreg(&priv->cru->clksel_con[18], BIT(10));
  1030. break;
  1031. default:
  1032. debug("%s: unsupported clk %ld\n", __func__, clk->id);
  1033. return -ENOENT;
  1034. }
  1035. return 0;
  1036. }
  1037. static int rk3399_clk_disable(struct clk *clk)
  1038. {
  1039. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  1040. switch (clk->id) {
  1041. case SCLK_MAC:
  1042. rk_setreg(&priv->cru->clkgate_con[5], BIT(5));
  1043. break;
  1044. case SCLK_MAC_RX:
  1045. rk_setreg(&priv->cru->clkgate_con[5], BIT(8));
  1046. break;
  1047. case SCLK_MAC_TX:
  1048. rk_setreg(&priv->cru->clkgate_con[5], BIT(9));
  1049. break;
  1050. case SCLK_MACREF:
  1051. rk_setreg(&priv->cru->clkgate_con[5], BIT(7));
  1052. break;
  1053. case SCLK_MACREF_OUT:
  1054. rk_setreg(&priv->cru->clkgate_con[5], BIT(6));
  1055. break;
  1056. case SCLK_USB2PHY0_REF:
  1057. rk_setreg(&priv->cru->clkgate_con[6], BIT(5));
  1058. break;
  1059. case SCLK_USB2PHY1_REF:
  1060. rk_setreg(&priv->cru->clkgate_con[6], BIT(6));
  1061. break;
  1062. case ACLK_GMAC:
  1063. rk_setreg(&priv->cru->clkgate_con[32], BIT(0));
  1064. break;
  1065. case PCLK_GMAC:
  1066. rk_setreg(&priv->cru->clkgate_con[32], BIT(2));
  1067. break;
  1068. case SCLK_USB3OTG0_REF:
  1069. rk_setreg(&priv->cru->clkgate_con[12], BIT(1));
  1070. break;
  1071. case SCLK_USB3OTG1_REF:
  1072. rk_setreg(&priv->cru->clkgate_con[12], BIT(2));
  1073. break;
  1074. case SCLK_USB3OTG0_SUSPEND:
  1075. rk_setreg(&priv->cru->clkgate_con[12], BIT(3));
  1076. break;
  1077. case SCLK_USB3OTG1_SUSPEND:
  1078. rk_setreg(&priv->cru->clkgate_con[12], BIT(4));
  1079. break;
  1080. case ACLK_USB3OTG0:
  1081. rk_setreg(&priv->cru->clkgate_con[30], BIT(1));
  1082. break;
  1083. case ACLK_USB3OTG1:
  1084. rk_setreg(&priv->cru->clkgate_con[30], BIT(2));
  1085. break;
  1086. case ACLK_USB3_RKSOC_AXI_PERF:
  1087. rk_setreg(&priv->cru->clkgate_con[30], BIT(3));
  1088. break;
  1089. case ACLK_USB3:
  1090. rk_setreg(&priv->cru->clkgate_con[12], BIT(0));
  1091. break;
  1092. case ACLK_USB3_GRF:
  1093. rk_setreg(&priv->cru->clkgate_con[30], BIT(4));
  1094. break;
  1095. case HCLK_HOST0:
  1096. rk_setreg(&priv->cru->clksel_con[20], BIT(5));
  1097. break;
  1098. case HCLK_HOST0_ARB:
  1099. rk_setreg(&priv->cru->clksel_con[20], BIT(6));
  1100. break;
  1101. case HCLK_HOST1:
  1102. rk_setreg(&priv->cru->clksel_con[20], BIT(7));
  1103. break;
  1104. case HCLK_HOST1_ARB:
  1105. rk_setreg(&priv->cru->clksel_con[20], BIT(8));
  1106. break;
  1107. case SCLK_UPHY0_TCPDPHY_REF:
  1108. rk_setreg(&priv->cru->clkgate_con[13], BIT(4));
  1109. break;
  1110. case SCLK_UPHY0_TCPDCORE:
  1111. rk_setreg(&priv->cru->clkgate_con[13], BIT(5));
  1112. break;
  1113. case SCLK_UPHY1_TCPDPHY_REF:
  1114. rk_setreg(&priv->cru->clkgate_con[13], BIT(6));
  1115. break;
  1116. case SCLK_UPHY1_TCPDCORE:
  1117. rk_setreg(&priv->cru->clkgate_con[13], BIT(7));
  1118. break;
  1119. case SCLK_PCIEPHY_REF:
  1120. rk_clrreg(&priv->cru->clksel_con[18], BIT(10));
  1121. break;
  1122. default:
  1123. debug("%s: unsupported clk %ld\n", __func__, clk->id);
  1124. return -ENOENT;
  1125. }
  1126. return 0;
  1127. }
  1128. static struct clk_ops rk3399_clk_ops = {
  1129. .get_rate = rk3399_clk_get_rate,
  1130. .set_rate = rk3399_clk_set_rate,
  1131. #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
  1132. .set_parent = rk3399_clk_set_parent,
  1133. #endif
  1134. .enable = rk3399_clk_enable,
  1135. .disable = rk3399_clk_disable,
  1136. };
  1137. static void rkclk_init(struct rockchip_cru *cru)
  1138. {
  1139. u32 aclk_div;
  1140. u32 hclk_div;
  1141. u32 pclk_div;
  1142. rk3399_configure_cpu_l(cru, APLL_L_600_MHZ);
  1143. rk3399_configure_cpu_b(cru, APLL_B_600_MHZ);
  1144. /*
  1145. * some cru registers changed by bootrom, we'd better reset them to
  1146. * reset/default values described in TRM to avoid confusion in kernel.
  1147. * Please consider these three lines as a fix of bootrom bug.
  1148. */
  1149. rk_clrsetreg(&cru->clksel_con[12], 0xffff, 0x4101);
  1150. rk_clrsetreg(&cru->clksel_con[19], 0xffff, 0x033f);
  1151. rk_clrsetreg(&cru->clksel_con[56], 0x0003, 0x0003);
  1152. /* configure gpll cpll */
  1153. rkclk_set_pll(&cru->gpll_con[0], &gpll_init_cfg);
  1154. rkclk_set_pll(&cru->cpll_con[0], &cpll_init_cfg);
  1155. /* configure perihp aclk, hclk, pclk */
  1156. aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1;
  1157. assert((aclk_div + 1) * PERIHP_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
  1158. hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1;
  1159. assert((hclk_div + 1) * PERIHP_HCLK_HZ ==
  1160. PERIHP_ACLK_HZ && (hclk_div < 0x4));
  1161. pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1;
  1162. assert((pclk_div + 1) * PERIHP_PCLK_HZ ==
  1163. PERIHP_ACLK_HZ && (pclk_div < 0x7));
  1164. rk_clrsetreg(&cru->clksel_con[14],
  1165. PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK |
  1166. ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK,
  1167. pclk_div << PCLK_PERIHP_DIV_CON_SHIFT |
  1168. hclk_div << HCLK_PERIHP_DIV_CON_SHIFT |
  1169. ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT |
  1170. aclk_div << ACLK_PERIHP_DIV_CON_SHIFT);
  1171. /* configure perilp0 aclk, hclk, pclk */
  1172. aclk_div = GPLL_HZ / PERILP0_ACLK_HZ - 1;
  1173. assert((aclk_div + 1) * PERILP0_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
  1174. hclk_div = PERILP0_ACLK_HZ / PERILP0_HCLK_HZ - 1;
  1175. assert((hclk_div + 1) * PERILP0_HCLK_HZ ==
  1176. PERILP0_ACLK_HZ && (hclk_div < 0x4));
  1177. pclk_div = PERILP0_ACLK_HZ / PERILP0_PCLK_HZ - 1;
  1178. assert((pclk_div + 1) * PERILP0_PCLK_HZ ==
  1179. PERILP0_ACLK_HZ && (pclk_div < 0x7));
  1180. rk_clrsetreg(&cru->clksel_con[23],
  1181. PCLK_PERILP0_DIV_CON_MASK | HCLK_PERILP0_DIV_CON_MASK |
  1182. ACLK_PERILP0_PLL_SEL_MASK | ACLK_PERILP0_DIV_CON_MASK,
  1183. pclk_div << PCLK_PERILP0_DIV_CON_SHIFT |
  1184. hclk_div << HCLK_PERILP0_DIV_CON_SHIFT |
  1185. ACLK_PERILP0_PLL_SEL_GPLL << ACLK_PERILP0_PLL_SEL_SHIFT |
  1186. aclk_div << ACLK_PERILP0_DIV_CON_SHIFT);
  1187. /* perilp1 hclk select gpll as source */
  1188. hclk_div = GPLL_HZ / PERILP1_HCLK_HZ - 1;
  1189. assert((hclk_div + 1) * PERILP1_HCLK_HZ ==
  1190. GPLL_HZ && (hclk_div < 0x1f));
  1191. pclk_div = PERILP1_HCLK_HZ / PERILP1_HCLK_HZ - 1;
  1192. assert((pclk_div + 1) * PERILP1_HCLK_HZ ==
  1193. PERILP1_HCLK_HZ && (hclk_div < 0x7));
  1194. rk_clrsetreg(&cru->clksel_con[25],
  1195. PCLK_PERILP1_DIV_CON_MASK | HCLK_PERILP1_DIV_CON_MASK |
  1196. HCLK_PERILP1_PLL_SEL_MASK,
  1197. pclk_div << PCLK_PERILP1_DIV_CON_SHIFT |
  1198. hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
  1199. HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
  1200. }
  1201. static int rk3399_clk_probe(struct udevice *dev)
  1202. {
  1203. struct rk3399_clk_priv *priv = dev_get_priv(dev);
  1204. bool init_clocks = false;
  1205. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1206. struct rk3399_clk_plat *plat = dev_get_platdata(dev);
  1207. priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
  1208. #endif
  1209. #if defined(CONFIG_SPL_BUILD)
  1210. init_clocks = true;
  1211. #elif CONFIG_IS_ENABLED(HANDOFF)
  1212. if (!(gd->flags & GD_FLG_RELOC)) {
  1213. if (!(gd->spl_handoff))
  1214. init_clocks = true;
  1215. }
  1216. #endif
  1217. if (init_clocks)
  1218. rkclk_init(priv->cru);
  1219. return 0;
  1220. }
  1221. static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
  1222. {
  1223. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  1224. struct rk3399_clk_priv *priv = dev_get_priv(dev);
  1225. priv->cru = dev_read_addr_ptr(dev);
  1226. #endif
  1227. return 0;
  1228. }
  1229. static int rk3399_clk_bind(struct udevice *dev)
  1230. {
  1231. int ret;
  1232. struct udevice *sys_child;
  1233. struct sysreset_reg *priv;
  1234. /* The reset driver does not have a device node, so bind it here */
  1235. ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
  1236. &sys_child);
  1237. if (ret) {
  1238. debug("Warning: No sysreset driver: ret=%d\n", ret);
  1239. } else {
  1240. priv = malloc(sizeof(struct sysreset_reg));
  1241. priv->glb_srst_fst_value = offsetof(struct rockchip_cru,
  1242. glb_srst_fst_value);
  1243. priv->glb_srst_snd_value = offsetof(struct rockchip_cru,
  1244. glb_srst_snd_value);
  1245. sys_child->priv = priv;
  1246. }
  1247. #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
  1248. ret = offsetof(struct rockchip_cru, softrst_con[0]);
  1249. ret = rockchip_reset_bind(dev, ret, 21);
  1250. if (ret)
  1251. debug("Warning: software reset driver bind faile\n");
  1252. #endif
  1253. return 0;
  1254. }
  1255. static const struct udevice_id rk3399_clk_ids[] = {
  1256. { .compatible = "rockchip,rk3399-cru" },
  1257. { }
  1258. };
  1259. U_BOOT_DRIVER(clk_rk3399) = {
  1260. .name = "rockchip_rk3399_cru",
  1261. .id = UCLASS_CLK,
  1262. .of_match = rk3399_clk_ids,
  1263. .priv_auto = sizeof(struct rk3399_clk_priv),
  1264. .ofdata_to_platdata = rk3399_clk_ofdata_to_platdata,
  1265. .ops = &rk3399_clk_ops,
  1266. .bind = rk3399_clk_bind,
  1267. .probe = rk3399_clk_probe,
  1268. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1269. .plat_auto = sizeof(struct rk3399_clk_plat),
  1270. #endif
  1271. };
  1272. static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id)
  1273. {
  1274. u32 div, con;
  1275. switch (clk_id) {
  1276. case SCLK_I2C0_PMU:
  1277. con = readl(&pmucru->pmucru_clksel[2]);
  1278. div = I2C_CLK_DIV_VALUE(con, 0);
  1279. break;
  1280. case SCLK_I2C4_PMU:
  1281. con = readl(&pmucru->pmucru_clksel[3]);
  1282. div = I2C_CLK_DIV_VALUE(con, 4);
  1283. break;
  1284. case SCLK_I2C8_PMU:
  1285. con = readl(&pmucru->pmucru_clksel[2]);
  1286. div = I2C_CLK_DIV_VALUE(con, 8);
  1287. break;
  1288. default:
  1289. printf("do not support this i2c bus\n");
  1290. return -EINVAL;
  1291. }
  1292. return DIV_TO_RATE(PPLL_HZ, div);
  1293. }
  1294. static ulong rk3399_i2c_set_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id,
  1295. uint hz)
  1296. {
  1297. int src_clk_div;
  1298. src_clk_div = PPLL_HZ / hz;
  1299. assert(src_clk_div - 1 < 127);
  1300. switch (clk_id) {
  1301. case SCLK_I2C0_PMU:
  1302. rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(0),
  1303. I2C_PMUCLK_REG_VALUE(0, src_clk_div));
  1304. break;
  1305. case SCLK_I2C4_PMU:
  1306. rk_clrsetreg(&pmucru->pmucru_clksel[3], I2C_PMUCLK_REG_MASK(4),
  1307. I2C_PMUCLK_REG_VALUE(4, src_clk_div));
  1308. break;
  1309. case SCLK_I2C8_PMU:
  1310. rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(8),
  1311. I2C_PMUCLK_REG_VALUE(8, src_clk_div));
  1312. break;
  1313. default:
  1314. printf("do not support this i2c bus\n");
  1315. return -EINVAL;
  1316. }
  1317. return DIV_TO_RATE(PPLL_HZ, src_clk_div);
  1318. }
  1319. static ulong rk3399_pwm_get_clk(struct rk3399_pmucru *pmucru)
  1320. {
  1321. u32 div, con;
  1322. /* PWM closk rate is same as pclk_pmu */
  1323. con = readl(&pmucru->pmucru_clksel[0]);
  1324. div = con & PMU_PCLK_DIV_CON_MASK;
  1325. return DIV_TO_RATE(PPLL_HZ, div);
  1326. }
  1327. static ulong rk3399_pmuclk_get_rate(struct clk *clk)
  1328. {
  1329. struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev);
  1330. ulong rate = 0;
  1331. switch (clk->id) {
  1332. case PLL_PPLL:
  1333. return PPLL_HZ;
  1334. case PCLK_RKPWM_PMU:
  1335. case PCLK_WDT_M0_PMU:
  1336. rate = rk3399_pwm_get_clk(priv->pmucru);
  1337. break;
  1338. case SCLK_I2C0_PMU:
  1339. case SCLK_I2C4_PMU:
  1340. case SCLK_I2C8_PMU:
  1341. rate = rk3399_i2c_get_pmuclk(priv->pmucru, clk->id);
  1342. break;
  1343. default:
  1344. return -ENOENT;
  1345. }
  1346. return rate;
  1347. }
  1348. static ulong rk3399_pmuclk_set_rate(struct clk *clk, ulong rate)
  1349. {
  1350. struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev);
  1351. ulong ret = 0;
  1352. switch (clk->id) {
  1353. case PLL_PPLL:
  1354. /*
  1355. * This has already been set up and we don't want/need
  1356. * to change it here. Accept the request though, as the
  1357. * device-tree has this in an 'assigned-clocks' list.
  1358. */
  1359. return PPLL_HZ;
  1360. case SCLK_I2C0_PMU:
  1361. case SCLK_I2C4_PMU:
  1362. case SCLK_I2C8_PMU:
  1363. ret = rk3399_i2c_set_pmuclk(priv->pmucru, clk->id, rate);
  1364. break;
  1365. default:
  1366. return -ENOENT;
  1367. }
  1368. return ret;
  1369. }
  1370. static struct clk_ops rk3399_pmuclk_ops = {
  1371. .get_rate = rk3399_pmuclk_get_rate,
  1372. .set_rate = rk3399_pmuclk_set_rate,
  1373. };
  1374. #ifndef CONFIG_SPL_BUILD
  1375. static void pmuclk_init(struct rk3399_pmucru *pmucru)
  1376. {
  1377. u32 pclk_div;
  1378. /* configure pmu pll(ppll) */
  1379. rkclk_set_pll(&pmucru->ppll_con[0], &ppll_init_cfg);
  1380. /* configure pmu pclk */
  1381. pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
  1382. rk_clrsetreg(&pmucru->pmucru_clksel[0],
  1383. PMU_PCLK_DIV_CON_MASK,
  1384. pclk_div << PMU_PCLK_DIV_CON_SHIFT);
  1385. }
  1386. #endif
  1387. static int rk3399_pmuclk_probe(struct udevice *dev)
  1388. {
  1389. #if CONFIG_IS_ENABLED(OF_PLATDATA) || !defined(CONFIG_SPL_BUILD)
  1390. struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
  1391. #endif
  1392. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1393. struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev);
  1394. priv->pmucru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
  1395. #endif
  1396. #ifndef CONFIG_SPL_BUILD
  1397. pmuclk_init(priv->pmucru);
  1398. #endif
  1399. return 0;
  1400. }
  1401. static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
  1402. {
  1403. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  1404. struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
  1405. priv->pmucru = dev_read_addr_ptr(dev);
  1406. #endif
  1407. return 0;
  1408. }
  1409. static int rk3399_pmuclk_bind(struct udevice *dev)
  1410. {
  1411. #if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
  1412. int ret;
  1413. ret = offsetof(struct rk3399_pmucru, pmucru_softrst_con[0]);
  1414. ret = rockchip_reset_bind(dev, ret, 2);
  1415. if (ret)
  1416. debug("Warning: software reset driver bind faile\n");
  1417. #endif
  1418. return 0;
  1419. }
  1420. static const struct udevice_id rk3399_pmuclk_ids[] = {
  1421. { .compatible = "rockchip,rk3399-pmucru" },
  1422. { }
  1423. };
  1424. U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
  1425. .name = "rockchip_rk3399_pmucru",
  1426. .id = UCLASS_CLK,
  1427. .of_match = rk3399_pmuclk_ids,
  1428. .priv_auto = sizeof(struct rk3399_pmuclk_priv),
  1429. .ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata,
  1430. .ops = &rk3399_pmuclk_ops,
  1431. .probe = rk3399_pmuclk_probe,
  1432. .bind = rk3399_pmuclk_bind,
  1433. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1434. .plat_auto = sizeof(struct rk3399_pmuclk_plat),
  1435. #endif
  1436. };