clk_rk3399.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440
  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 <mapmem.h>
  12. #include <syscon.h>
  13. #include <bitfield.h>
  14. #include <asm/io.h>
  15. #include <asm/arch-rockchip/clock.h>
  16. #include <asm/arch-rockchip/cru_rk3399.h>
  17. #include <asm/arch-rockchip/hardware.h>
  18. #include <dm/lists.h>
  19. #include <dt-bindings/clock/rk3399-cru.h>
  20. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  21. struct rk3399_clk_plat {
  22. struct dtd_rockchip_rk3399_cru dtd;
  23. };
  24. struct rk3399_pmuclk_plat {
  25. struct dtd_rockchip_rk3399_pmucru dtd;
  26. };
  27. #endif
  28. struct pll_div {
  29. u32 refdiv;
  30. u32 fbdiv;
  31. u32 postdiv1;
  32. u32 postdiv2;
  33. u32 frac;
  34. };
  35. #define RATE_TO_DIV(input_rate, output_rate) \
  36. ((input_rate) / (output_rate) - 1);
  37. #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
  38. #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
  39. .refdiv = _refdiv,\
  40. .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
  41. .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
  42. #if defined(CONFIG_SPL_BUILD)
  43. static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
  44. static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2);
  45. #else
  46. static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
  47. #endif
  48. static const struct pll_div apll_l_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1);
  49. static const struct pll_div apll_l_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
  50. static const struct pll_div *apll_l_cfgs[] = {
  51. [APLL_L_1600_MHZ] = &apll_l_1600_cfg,
  52. [APLL_L_600_MHZ] = &apll_l_600_cfg,
  53. };
  54. static const struct pll_div apll_b_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
  55. static const struct pll_div *apll_b_cfgs[] = {
  56. [APLL_B_600_MHZ] = &apll_b_600_cfg,
  57. };
  58. enum {
  59. /* PLL_CON0 */
  60. PLL_FBDIV_MASK = 0xfff,
  61. PLL_FBDIV_SHIFT = 0,
  62. /* PLL_CON1 */
  63. PLL_POSTDIV2_SHIFT = 12,
  64. PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT,
  65. PLL_POSTDIV1_SHIFT = 8,
  66. PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT,
  67. PLL_REFDIV_MASK = 0x3f,
  68. PLL_REFDIV_SHIFT = 0,
  69. /* PLL_CON2 */
  70. PLL_LOCK_STATUS_SHIFT = 31,
  71. PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT,
  72. PLL_FRACDIV_MASK = 0xffffff,
  73. PLL_FRACDIV_SHIFT = 0,
  74. /* PLL_CON3 */
  75. PLL_MODE_SHIFT = 8,
  76. PLL_MODE_MASK = 3 << PLL_MODE_SHIFT,
  77. PLL_MODE_SLOW = 0,
  78. PLL_MODE_NORM,
  79. PLL_MODE_DEEP,
  80. PLL_DSMPD_SHIFT = 3,
  81. PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT,
  82. PLL_INTEGER_MODE = 1,
  83. /* PMUCRU_CLKSEL_CON0 */
  84. PMU_PCLK_DIV_CON_MASK = 0x1f,
  85. PMU_PCLK_DIV_CON_SHIFT = 0,
  86. /* PMUCRU_CLKSEL_CON1 */
  87. SPI3_PLL_SEL_SHIFT = 7,
  88. SPI3_PLL_SEL_MASK = 1 << SPI3_PLL_SEL_SHIFT,
  89. SPI3_PLL_SEL_24M = 0,
  90. SPI3_PLL_SEL_PPLL = 1,
  91. SPI3_DIV_CON_SHIFT = 0x0,
  92. SPI3_DIV_CON_MASK = 0x7f,
  93. /* PMUCRU_CLKSEL_CON2 */
  94. I2C_DIV_CON_MASK = 0x7f,
  95. CLK_I2C8_DIV_CON_SHIFT = 8,
  96. CLK_I2C0_DIV_CON_SHIFT = 0,
  97. /* PMUCRU_CLKSEL_CON3 */
  98. CLK_I2C4_DIV_CON_SHIFT = 0,
  99. /* CLKSEL_CON0 */
  100. ACLKM_CORE_L_DIV_CON_SHIFT = 8,
  101. ACLKM_CORE_L_DIV_CON_MASK = 0x1f << ACLKM_CORE_L_DIV_CON_SHIFT,
  102. CLK_CORE_L_PLL_SEL_SHIFT = 6,
  103. CLK_CORE_L_PLL_SEL_MASK = 3 << CLK_CORE_L_PLL_SEL_SHIFT,
  104. CLK_CORE_L_PLL_SEL_ALPLL = 0x0,
  105. CLK_CORE_L_PLL_SEL_ABPLL = 0x1,
  106. CLK_CORE_L_PLL_SEL_DPLL = 0x10,
  107. CLK_CORE_L_PLL_SEL_GPLL = 0x11,
  108. CLK_CORE_L_DIV_MASK = 0x1f,
  109. CLK_CORE_L_DIV_SHIFT = 0,
  110. /* CLKSEL_CON1 */
  111. PCLK_DBG_L_DIV_SHIFT = 0x8,
  112. PCLK_DBG_L_DIV_MASK = 0x1f << PCLK_DBG_L_DIV_SHIFT,
  113. ATCLK_CORE_L_DIV_SHIFT = 0,
  114. ATCLK_CORE_L_DIV_MASK = 0x1f << ATCLK_CORE_L_DIV_SHIFT,
  115. /* CLKSEL_CON2 */
  116. ACLKM_CORE_B_DIV_CON_SHIFT = 8,
  117. ACLKM_CORE_B_DIV_CON_MASK = 0x1f << ACLKM_CORE_B_DIV_CON_SHIFT,
  118. CLK_CORE_B_PLL_SEL_SHIFT = 6,
  119. CLK_CORE_B_PLL_SEL_MASK = 3 << CLK_CORE_B_PLL_SEL_SHIFT,
  120. CLK_CORE_B_PLL_SEL_ALPLL = 0x0,
  121. CLK_CORE_B_PLL_SEL_ABPLL = 0x1,
  122. CLK_CORE_B_PLL_SEL_DPLL = 0x10,
  123. CLK_CORE_B_PLL_SEL_GPLL = 0x11,
  124. CLK_CORE_B_DIV_MASK = 0x1f,
  125. CLK_CORE_B_DIV_SHIFT = 0,
  126. /* CLKSEL_CON3 */
  127. PCLK_DBG_B_DIV_SHIFT = 0x8,
  128. PCLK_DBG_B_DIV_MASK = 0x1f << PCLK_DBG_B_DIV_SHIFT,
  129. ATCLK_CORE_B_DIV_SHIFT = 0,
  130. ATCLK_CORE_B_DIV_MASK = 0x1f << ATCLK_CORE_B_DIV_SHIFT,
  131. /* CLKSEL_CON14 */
  132. PCLK_PERIHP_DIV_CON_SHIFT = 12,
  133. PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
  134. HCLK_PERIHP_DIV_CON_SHIFT = 8,
  135. HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT,
  136. ACLK_PERIHP_PLL_SEL_SHIFT = 7,
  137. ACLK_PERIHP_PLL_SEL_MASK = 1 << ACLK_PERIHP_PLL_SEL_SHIFT,
  138. ACLK_PERIHP_PLL_SEL_CPLL = 0,
  139. ACLK_PERIHP_PLL_SEL_GPLL = 1,
  140. ACLK_PERIHP_DIV_CON_SHIFT = 0,
  141. ACLK_PERIHP_DIV_CON_MASK = 0x1f,
  142. /* CLKSEL_CON21 */
  143. ACLK_EMMC_PLL_SEL_SHIFT = 7,
  144. ACLK_EMMC_PLL_SEL_MASK = 0x1 << ACLK_EMMC_PLL_SEL_SHIFT,
  145. ACLK_EMMC_PLL_SEL_GPLL = 0x1,
  146. ACLK_EMMC_DIV_CON_SHIFT = 0,
  147. ACLK_EMMC_DIV_CON_MASK = 0x1f,
  148. /* CLKSEL_CON22 */
  149. CLK_EMMC_PLL_SHIFT = 8,
  150. CLK_EMMC_PLL_MASK = 0x7 << CLK_EMMC_PLL_SHIFT,
  151. CLK_EMMC_PLL_SEL_GPLL = 0x1,
  152. CLK_EMMC_PLL_SEL_24M = 0x5,
  153. CLK_EMMC_DIV_CON_SHIFT = 0,
  154. CLK_EMMC_DIV_CON_MASK = 0x7f << CLK_EMMC_DIV_CON_SHIFT,
  155. /* CLKSEL_CON23 */
  156. PCLK_PERILP0_DIV_CON_SHIFT = 12,
  157. PCLK_PERILP0_DIV_CON_MASK = 0x7 << PCLK_PERILP0_DIV_CON_SHIFT,
  158. HCLK_PERILP0_DIV_CON_SHIFT = 8,
  159. HCLK_PERILP0_DIV_CON_MASK = 3 << HCLK_PERILP0_DIV_CON_SHIFT,
  160. ACLK_PERILP0_PLL_SEL_SHIFT = 7,
  161. ACLK_PERILP0_PLL_SEL_MASK = 1 << ACLK_PERILP0_PLL_SEL_SHIFT,
  162. ACLK_PERILP0_PLL_SEL_CPLL = 0,
  163. ACLK_PERILP0_PLL_SEL_GPLL = 1,
  164. ACLK_PERILP0_DIV_CON_SHIFT = 0,
  165. ACLK_PERILP0_DIV_CON_MASK = 0x1f,
  166. /* CLKSEL_CON25 */
  167. PCLK_PERILP1_DIV_CON_SHIFT = 8,
  168. PCLK_PERILP1_DIV_CON_MASK = 0x7 << PCLK_PERILP1_DIV_CON_SHIFT,
  169. HCLK_PERILP1_PLL_SEL_SHIFT = 7,
  170. HCLK_PERILP1_PLL_SEL_MASK = 1 << HCLK_PERILP1_PLL_SEL_SHIFT,
  171. HCLK_PERILP1_PLL_SEL_CPLL = 0,
  172. HCLK_PERILP1_PLL_SEL_GPLL = 1,
  173. HCLK_PERILP1_DIV_CON_SHIFT = 0,
  174. HCLK_PERILP1_DIV_CON_MASK = 0x1f,
  175. /* CLKSEL_CON26 */
  176. CLK_SARADC_DIV_CON_SHIFT = 8,
  177. CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
  178. CLK_SARADC_DIV_CON_WIDTH = 8,
  179. /* CLKSEL_CON27 */
  180. CLK_TSADC_SEL_X24M = 0x0,
  181. CLK_TSADC_SEL_SHIFT = 15,
  182. CLK_TSADC_SEL_MASK = 1 << CLK_TSADC_SEL_SHIFT,
  183. CLK_TSADC_DIV_CON_SHIFT = 0,
  184. CLK_TSADC_DIV_CON_MASK = 0x3ff,
  185. /* CLKSEL_CON47 & CLKSEL_CON48 */
  186. ACLK_VOP_PLL_SEL_SHIFT = 6,
  187. ACLK_VOP_PLL_SEL_MASK = 0x3 << ACLK_VOP_PLL_SEL_SHIFT,
  188. ACLK_VOP_PLL_SEL_CPLL = 0x1,
  189. ACLK_VOP_DIV_CON_SHIFT = 0,
  190. ACLK_VOP_DIV_CON_MASK = 0x1f << ACLK_VOP_DIV_CON_SHIFT,
  191. /* CLKSEL_CON49 & CLKSEL_CON50 */
  192. DCLK_VOP_DCLK_SEL_SHIFT = 11,
  193. DCLK_VOP_DCLK_SEL_MASK = 1 << DCLK_VOP_DCLK_SEL_SHIFT,
  194. DCLK_VOP_DCLK_SEL_DIVOUT = 0,
  195. DCLK_VOP_PLL_SEL_SHIFT = 8,
  196. DCLK_VOP_PLL_SEL_MASK = 3 << DCLK_VOP_PLL_SEL_SHIFT,
  197. DCLK_VOP_PLL_SEL_VPLL = 0,
  198. DCLK_VOP_DIV_CON_MASK = 0xff,
  199. DCLK_VOP_DIV_CON_SHIFT = 0,
  200. /* CLKSEL_CON58 */
  201. CLK_SPI_PLL_SEL_WIDTH = 1,
  202. CLK_SPI_PLL_SEL_MASK = ((1 < CLK_SPI_PLL_SEL_WIDTH) - 1),
  203. CLK_SPI_PLL_SEL_CPLL = 0,
  204. CLK_SPI_PLL_SEL_GPLL = 1,
  205. CLK_SPI_PLL_DIV_CON_WIDTH = 7,
  206. CLK_SPI_PLL_DIV_CON_MASK = ((1 << CLK_SPI_PLL_DIV_CON_WIDTH) - 1),
  207. CLK_SPI5_PLL_DIV_CON_SHIFT = 8,
  208. CLK_SPI5_PLL_SEL_SHIFT = 15,
  209. /* CLKSEL_CON59 */
  210. CLK_SPI1_PLL_SEL_SHIFT = 15,
  211. CLK_SPI1_PLL_DIV_CON_SHIFT = 8,
  212. CLK_SPI0_PLL_SEL_SHIFT = 7,
  213. CLK_SPI0_PLL_DIV_CON_SHIFT = 0,
  214. /* CLKSEL_CON60 */
  215. CLK_SPI4_PLL_SEL_SHIFT = 15,
  216. CLK_SPI4_PLL_DIV_CON_SHIFT = 8,
  217. CLK_SPI2_PLL_SEL_SHIFT = 7,
  218. CLK_SPI2_PLL_DIV_CON_SHIFT = 0,
  219. /* CLKSEL_CON61 */
  220. CLK_I2C_PLL_SEL_MASK = 1,
  221. CLK_I2C_PLL_SEL_CPLL = 0,
  222. CLK_I2C_PLL_SEL_GPLL = 1,
  223. CLK_I2C5_PLL_SEL_SHIFT = 15,
  224. CLK_I2C5_DIV_CON_SHIFT = 8,
  225. CLK_I2C1_PLL_SEL_SHIFT = 7,
  226. CLK_I2C1_DIV_CON_SHIFT = 0,
  227. /* CLKSEL_CON62 */
  228. CLK_I2C6_PLL_SEL_SHIFT = 15,
  229. CLK_I2C6_DIV_CON_SHIFT = 8,
  230. CLK_I2C2_PLL_SEL_SHIFT = 7,
  231. CLK_I2C2_DIV_CON_SHIFT = 0,
  232. /* CLKSEL_CON63 */
  233. CLK_I2C7_PLL_SEL_SHIFT = 15,
  234. CLK_I2C7_DIV_CON_SHIFT = 8,
  235. CLK_I2C3_PLL_SEL_SHIFT = 7,
  236. CLK_I2C3_DIV_CON_SHIFT = 0,
  237. /* CRU_SOFTRST_CON4 */
  238. RESETN_DDR0_REQ_SHIFT = 8,
  239. RESETN_DDR0_REQ_MASK = 1 << RESETN_DDR0_REQ_SHIFT,
  240. RESETN_DDRPHY0_REQ_SHIFT = 9,
  241. RESETN_DDRPHY0_REQ_MASK = 1 << RESETN_DDRPHY0_REQ_SHIFT,
  242. RESETN_DDR1_REQ_SHIFT = 12,
  243. RESETN_DDR1_REQ_MASK = 1 << RESETN_DDR1_REQ_SHIFT,
  244. RESETN_DDRPHY1_REQ_SHIFT = 13,
  245. RESETN_DDRPHY1_REQ_MASK = 1 << RESETN_DDRPHY1_REQ_SHIFT,
  246. };
  247. #define VCO_MAX_KHZ (3200 * (MHz / KHz))
  248. #define VCO_MIN_KHZ (800 * (MHz / KHz))
  249. #define OUTPUT_MAX_KHZ (3200 * (MHz / KHz))
  250. #define OUTPUT_MIN_KHZ (16 * (MHz / KHz))
  251. /*
  252. * the div restructions of pll in integer mode, these are defined in
  253. * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0
  254. */
  255. #define PLL_DIV_MIN 16
  256. #define PLL_DIV_MAX 3200
  257. /*
  258. * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
  259. * Formulas also embedded within the Fractional PLL Verilog model:
  260. * If DSMPD = 1 (DSM is disabled, "integer mode")
  261. * FOUTVCO = FREF / REFDIV * FBDIV
  262. * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
  263. * Where:
  264. * FOUTVCO = Fractional PLL non-divided output frequency
  265. * FOUTPOSTDIV = Fractional PLL divided output frequency
  266. * (output of second post divider)
  267. * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
  268. * REFDIV = Fractional PLL input reference clock divider
  269. * FBDIV = Integer value programmed into feedback divide
  270. *
  271. */
  272. static void rkclk_set_pll(u32 *pll_con, const struct pll_div *div)
  273. {
  274. /* All 8 PLLs have same VCO and output frequency range restrictions. */
  275. u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv;
  276. u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2;
  277. debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, "
  278. "postdiv2=%d, vco=%u khz, output=%u khz\n",
  279. pll_con, div->fbdiv, div->refdiv, div->postdiv1,
  280. div->postdiv2, vco_khz, output_khz);
  281. assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ &&
  282. output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ &&
  283. div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX);
  284. /*
  285. * When power on or changing PLL setting,
  286. * we must force PLL into slow mode to ensure output stable clock.
  287. */
  288. rk_clrsetreg(&pll_con[3], PLL_MODE_MASK,
  289. PLL_MODE_SLOW << PLL_MODE_SHIFT);
  290. /* use integer mode */
  291. rk_clrsetreg(&pll_con[3], PLL_DSMPD_MASK,
  292. PLL_INTEGER_MODE << PLL_DSMPD_SHIFT);
  293. rk_clrsetreg(&pll_con[0], PLL_FBDIV_MASK,
  294. div->fbdiv << PLL_FBDIV_SHIFT);
  295. rk_clrsetreg(&pll_con[1],
  296. PLL_POSTDIV2_MASK | PLL_POSTDIV1_MASK |
  297. PLL_REFDIV_MASK | PLL_REFDIV_SHIFT,
  298. (div->postdiv2 << PLL_POSTDIV2_SHIFT) |
  299. (div->postdiv1 << PLL_POSTDIV1_SHIFT) |
  300. (div->refdiv << PLL_REFDIV_SHIFT));
  301. /* waiting for pll lock */
  302. while (!(readl(&pll_con[2]) & (1 << PLL_LOCK_STATUS_SHIFT)))
  303. udelay(1);
  304. /* pll enter normal mode */
  305. rk_clrsetreg(&pll_con[3], PLL_MODE_MASK,
  306. PLL_MODE_NORM << PLL_MODE_SHIFT);
  307. }
  308. static int pll_para_config(u32 freq_hz, struct pll_div *div)
  309. {
  310. u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
  311. u32 postdiv1, postdiv2 = 1;
  312. u32 fref_khz;
  313. u32 diff_khz, best_diff_khz;
  314. const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
  315. const u32 max_postdiv1 = 7, max_postdiv2 = 7;
  316. u32 vco_khz;
  317. u32 freq_khz = freq_hz / KHz;
  318. if (!freq_hz) {
  319. printf("%s: the frequency can't be 0 Hz\n", __func__);
  320. return -1;
  321. }
  322. postdiv1 = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz);
  323. if (postdiv1 > max_postdiv1) {
  324. postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
  325. postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
  326. }
  327. vco_khz = freq_khz * postdiv1 * postdiv2;
  328. if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ ||
  329. postdiv2 > max_postdiv2) {
  330. printf("%s: Cannot find out a supported VCO"
  331. " for Frequency (%uHz).\n", __func__, freq_hz);
  332. return -1;
  333. }
  334. div->postdiv1 = postdiv1;
  335. div->postdiv2 = postdiv2;
  336. best_diff_khz = vco_khz;
  337. for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
  338. fref_khz = ref_khz / refdiv;
  339. fbdiv = vco_khz / fref_khz;
  340. if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
  341. continue;
  342. diff_khz = vco_khz - fbdiv * fref_khz;
  343. if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
  344. fbdiv++;
  345. diff_khz = fref_khz - diff_khz;
  346. }
  347. if (diff_khz >= best_diff_khz)
  348. continue;
  349. best_diff_khz = diff_khz;
  350. div->refdiv = refdiv;
  351. div->fbdiv = fbdiv;
  352. }
  353. if (best_diff_khz > 4 * (MHz/KHz)) {
  354. printf("%s: Failed to match output frequency %u, "
  355. "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz,
  356. best_diff_khz * KHz);
  357. return -1;
  358. }
  359. return 0;
  360. }
  361. void rk3399_configure_cpu_l(struct rk3399_cru *cru,
  362. enum apll_l_frequencies apll_l_freq)
  363. {
  364. u32 aclkm_div;
  365. u32 pclk_dbg_div;
  366. u32 atclk_div;
  367. /* Setup cluster L */
  368. rkclk_set_pll(&cru->apll_l_con[0], apll_l_cfgs[apll_l_freq]);
  369. aclkm_div = LPLL_HZ / ACLKM_CORE_L_HZ - 1;
  370. assert((aclkm_div + 1) * ACLKM_CORE_L_HZ == LPLL_HZ &&
  371. aclkm_div < 0x1f);
  372. pclk_dbg_div = LPLL_HZ / PCLK_DBG_L_HZ - 1;
  373. assert((pclk_dbg_div + 1) * PCLK_DBG_L_HZ == LPLL_HZ &&
  374. pclk_dbg_div < 0x1f);
  375. atclk_div = LPLL_HZ / ATCLK_CORE_L_HZ - 1;
  376. assert((atclk_div + 1) * ATCLK_CORE_L_HZ == LPLL_HZ &&
  377. atclk_div < 0x1f);
  378. rk_clrsetreg(&cru->clksel_con[0],
  379. ACLKM_CORE_L_DIV_CON_MASK | CLK_CORE_L_PLL_SEL_MASK |
  380. CLK_CORE_L_DIV_MASK,
  381. aclkm_div << ACLKM_CORE_L_DIV_CON_SHIFT |
  382. CLK_CORE_L_PLL_SEL_ALPLL << CLK_CORE_L_PLL_SEL_SHIFT |
  383. 0 << CLK_CORE_L_DIV_SHIFT);
  384. rk_clrsetreg(&cru->clksel_con[1],
  385. PCLK_DBG_L_DIV_MASK | ATCLK_CORE_L_DIV_MASK,
  386. pclk_dbg_div << PCLK_DBG_L_DIV_SHIFT |
  387. atclk_div << ATCLK_CORE_L_DIV_SHIFT);
  388. }
  389. void rk3399_configure_cpu_b(struct rk3399_cru *cru,
  390. enum apll_b_frequencies apll_b_freq)
  391. {
  392. u32 aclkm_div;
  393. u32 pclk_dbg_div;
  394. u32 atclk_div;
  395. /* Setup cluster B */
  396. rkclk_set_pll(&cru->apll_b_con[0], apll_b_cfgs[apll_b_freq]);
  397. aclkm_div = BPLL_HZ / ACLKM_CORE_B_HZ - 1;
  398. assert((aclkm_div + 1) * ACLKM_CORE_B_HZ == BPLL_HZ &&
  399. aclkm_div < 0x1f);
  400. pclk_dbg_div = BPLL_HZ / PCLK_DBG_B_HZ - 1;
  401. assert((pclk_dbg_div + 1) * PCLK_DBG_B_HZ == BPLL_HZ &&
  402. pclk_dbg_div < 0x1f);
  403. atclk_div = BPLL_HZ / ATCLK_CORE_B_HZ - 1;
  404. assert((atclk_div + 1) * ATCLK_CORE_B_HZ == BPLL_HZ &&
  405. atclk_div < 0x1f);
  406. rk_clrsetreg(&cru->clksel_con[2],
  407. ACLKM_CORE_B_DIV_CON_MASK | CLK_CORE_B_PLL_SEL_MASK |
  408. CLK_CORE_B_DIV_MASK,
  409. aclkm_div << ACLKM_CORE_B_DIV_CON_SHIFT |
  410. CLK_CORE_B_PLL_SEL_ABPLL << CLK_CORE_B_PLL_SEL_SHIFT |
  411. 0 << CLK_CORE_B_DIV_SHIFT);
  412. rk_clrsetreg(&cru->clksel_con[3],
  413. PCLK_DBG_B_DIV_MASK | ATCLK_CORE_B_DIV_MASK,
  414. pclk_dbg_div << PCLK_DBG_B_DIV_SHIFT |
  415. atclk_div << ATCLK_CORE_B_DIV_SHIFT);
  416. }
  417. #define I2C_CLK_REG_MASK(bus) \
  418. (I2C_DIV_CON_MASK << \
  419. CLK_I2C ##bus## _DIV_CON_SHIFT | \
  420. CLK_I2C_PLL_SEL_MASK << \
  421. CLK_I2C ##bus## _PLL_SEL_SHIFT)
  422. #define I2C_CLK_REG_VALUE(bus, clk_div) \
  423. ((clk_div - 1) << \
  424. CLK_I2C ##bus## _DIV_CON_SHIFT | \
  425. CLK_I2C_PLL_SEL_GPLL << \
  426. CLK_I2C ##bus## _PLL_SEL_SHIFT)
  427. #define I2C_CLK_DIV_VALUE(con, bus) \
  428. (con >> CLK_I2C ##bus## _DIV_CON_SHIFT) & \
  429. I2C_DIV_CON_MASK;
  430. #define I2C_PMUCLK_REG_MASK(bus) \
  431. (I2C_DIV_CON_MASK << \
  432. CLK_I2C ##bus## _DIV_CON_SHIFT)
  433. #define I2C_PMUCLK_REG_VALUE(bus, clk_div) \
  434. ((clk_div - 1) << \
  435. CLK_I2C ##bus## _DIV_CON_SHIFT)
  436. static ulong rk3399_i2c_get_clk(struct rk3399_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 rk3399_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. uint8_t reg; /* CLKSEL_CON[reg] register in CRU */
  514. uint8_t div_shift;
  515. uint8_t 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 rk3399_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 rk3399_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 rk3399_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 rk3399_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[21]);
  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 rk3399_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 rk3399_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 rk3399_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 200*MHz:
  717. dpll_cfg = (struct pll_div)
  718. {.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
  719. break;
  720. case 300*MHz:
  721. dpll_cfg = (struct pll_div)
  722. {.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
  723. break;
  724. case 666*MHz:
  725. dpll_cfg = (struct pll_div)
  726. {.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
  727. break;
  728. case 800*MHz:
  729. dpll_cfg = (struct pll_div)
  730. {.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
  731. break;
  732. case 933*MHz:
  733. dpll_cfg = (struct pll_div)
  734. {.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
  735. break;
  736. default:
  737. pr_err("Unsupported SDRAM frequency!,%ld\n", set_rate);
  738. }
  739. rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
  740. return set_rate;
  741. }
  742. static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru)
  743. {
  744. u32 div, val;
  745. val = readl(&cru->clksel_con[26]);
  746. div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
  747. CLK_SARADC_DIV_CON_WIDTH);
  748. return DIV_TO_RATE(OSC_HZ, div);
  749. }
  750. static ulong rk3399_saradc_set_clk(struct rk3399_cru *cru, uint hz)
  751. {
  752. int src_clk_div;
  753. src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
  754. assert(src_clk_div < 128);
  755. rk_clrsetreg(&cru->clksel_con[26],
  756. CLK_SARADC_DIV_CON_MASK,
  757. src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
  758. return rk3399_saradc_get_clk(cru);
  759. }
  760. static ulong rk3399_clk_get_rate(struct clk *clk)
  761. {
  762. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  763. ulong rate = 0;
  764. switch (clk->id) {
  765. case 0 ... 63:
  766. return 0;
  767. case HCLK_SDMMC:
  768. case SCLK_SDMMC:
  769. case SCLK_EMMC:
  770. rate = rk3399_mmc_get_clk(priv->cru, clk->id);
  771. break;
  772. case SCLK_I2C1:
  773. case SCLK_I2C2:
  774. case SCLK_I2C3:
  775. case SCLK_I2C5:
  776. case SCLK_I2C6:
  777. case SCLK_I2C7:
  778. rate = rk3399_i2c_get_clk(priv->cru, clk->id);
  779. break;
  780. case SCLK_SPI0...SCLK_SPI5:
  781. rate = rk3399_spi_get_clk(priv->cru, clk->id);
  782. break;
  783. case SCLK_UART0:
  784. case SCLK_UART2:
  785. return 24000000;
  786. break;
  787. case PCLK_HDMI_CTRL:
  788. break;
  789. case DCLK_VOP0:
  790. case DCLK_VOP1:
  791. break;
  792. case PCLK_EFUSE1024NS:
  793. break;
  794. case SCLK_SARADC:
  795. rate = rk3399_saradc_get_clk(priv->cru);
  796. break;
  797. case ACLK_VIO:
  798. case ACLK_HDCP:
  799. case ACLK_GIC_PRE:
  800. case PCLK_DDR:
  801. break;
  802. default:
  803. log_debug("Unknown clock %lu\n", clk->id);
  804. return -ENOENT;
  805. }
  806. return rate;
  807. }
  808. static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
  809. {
  810. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  811. ulong ret = 0;
  812. switch (clk->id) {
  813. case 0 ... 63:
  814. return 0;
  815. case ACLK_PERIHP:
  816. case HCLK_PERIHP:
  817. case PCLK_PERIHP:
  818. return 0;
  819. case ACLK_PERILP0:
  820. case HCLK_PERILP0:
  821. case PCLK_PERILP0:
  822. return 0;
  823. case ACLK_CCI:
  824. return 0;
  825. case HCLK_PERILP1:
  826. case PCLK_PERILP1:
  827. return 0;
  828. case HCLK_SDMMC:
  829. case SCLK_SDMMC:
  830. case SCLK_EMMC:
  831. ret = rk3399_mmc_set_clk(priv->cru, clk->id, rate);
  832. break;
  833. case SCLK_MAC:
  834. ret = rk3399_gmac_set_clk(priv->cru, rate);
  835. break;
  836. case SCLK_I2C1:
  837. case SCLK_I2C2:
  838. case SCLK_I2C3:
  839. case SCLK_I2C5:
  840. case SCLK_I2C6:
  841. case SCLK_I2C7:
  842. ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate);
  843. break;
  844. case SCLK_SPI0...SCLK_SPI5:
  845. ret = rk3399_spi_set_clk(priv->cru, clk->id, rate);
  846. break;
  847. case PCLK_HDMI_CTRL:
  848. case PCLK_VIO_GRF:
  849. /* the PCLK gates for video are enabled by default */
  850. break;
  851. case DCLK_VOP0:
  852. case DCLK_VOP1:
  853. ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
  854. break;
  855. case SCLK_DDRCLK:
  856. ret = rk3399_ddr_set_clk(priv->cru, rate);
  857. break;
  858. case PCLK_EFUSE1024NS:
  859. break;
  860. case SCLK_SARADC:
  861. ret = rk3399_saradc_set_clk(priv->cru, rate);
  862. break;
  863. case ACLK_VIO:
  864. case ACLK_HDCP:
  865. case ACLK_GIC_PRE:
  866. case PCLK_DDR:
  867. return 0;
  868. default:
  869. log_debug("Unknown clock %lu\n", clk->id);
  870. return -ENOENT;
  871. }
  872. return ret;
  873. }
  874. static int __maybe_unused rk3399_gmac_set_parent(struct clk *clk, struct clk *parent)
  875. {
  876. struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
  877. const char *clock_output_name;
  878. int ret;
  879. /*
  880. * If the requested parent is in the same clock-controller and
  881. * the id is SCLK_MAC ("clk_gmac"), switch to the internal clock.
  882. */
  883. if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC)) {
  884. debug("%s: switching RGMII to SCLK_MAC\n", __func__);
  885. rk_clrreg(&priv->cru->clksel_con[19], BIT(4));
  886. return 0;
  887. }
  888. /*
  889. * Otherwise, we need to check the clock-output-names of the
  890. * requested parent to see if the requested id is "clkin_gmac".
  891. */
  892. ret = dev_read_string_index(parent->dev, "clock-output-names",
  893. parent->id, &clock_output_name);
  894. if (ret < 0)
  895. return -ENODATA;
  896. /* If this is "clkin_gmac", switch to the external clock input */
  897. if (!strcmp(clock_output_name, "clkin_gmac")) {
  898. debug("%s: switching RGMII to CLKIN\n", __func__);
  899. rk_setreg(&priv->cru->clksel_con[19], BIT(4));
  900. return 0;
  901. }
  902. return -EINVAL;
  903. }
  904. static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, struct clk *parent)
  905. {
  906. switch (clk->id) {
  907. case SCLK_RMII_SRC:
  908. return rk3399_gmac_set_parent(clk, parent);
  909. }
  910. debug("%s: unsupported clk %ld\n", __func__, clk->id);
  911. return -ENOENT;
  912. }
  913. static int rk3399_clk_enable(struct clk *clk)
  914. {
  915. switch (clk->id) {
  916. case HCLK_HOST0:
  917. case HCLK_HOST0_ARB:
  918. case HCLK_HOST1:
  919. case HCLK_HOST1_ARB:
  920. return 0;
  921. case SCLK_MAC:
  922. case SCLK_MAC_RX:
  923. case SCLK_MAC_TX:
  924. case SCLK_MACREF:
  925. case SCLK_MACREF_OUT:
  926. case ACLK_GMAC:
  927. case PCLK_GMAC:
  928. /* Required to successfully probe the Designware GMAC driver */
  929. return 0;
  930. }
  931. debug("%s: unsupported clk %ld\n", __func__, clk->id);
  932. return -ENOENT;
  933. }
  934. static struct clk_ops rk3399_clk_ops = {
  935. .get_rate = rk3399_clk_get_rate,
  936. .set_rate = rk3399_clk_set_rate,
  937. #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
  938. .set_parent = rk3399_clk_set_parent,
  939. #endif
  940. .enable = rk3399_clk_enable,
  941. };
  942. #ifdef CONFIG_SPL_BUILD
  943. static void rkclk_init(struct rk3399_cru *cru)
  944. {
  945. u32 aclk_div;
  946. u32 hclk_div;
  947. u32 pclk_div;
  948. rk3399_configure_cpu_l(cru, APLL_L_600_MHZ);
  949. rk3399_configure_cpu_b(cru, APLL_B_600_MHZ);
  950. /*
  951. * some cru registers changed by bootrom, we'd better reset them to
  952. * reset/default values described in TRM to avoid confusion in kernel.
  953. * Please consider these three lines as a fix of bootrom bug.
  954. */
  955. rk_clrsetreg(&cru->clksel_con[12], 0xffff, 0x4101);
  956. rk_clrsetreg(&cru->clksel_con[19], 0xffff, 0x033f);
  957. rk_clrsetreg(&cru->clksel_con[56], 0x0003, 0x0003);
  958. /* configure gpll cpll */
  959. rkclk_set_pll(&cru->gpll_con[0], &gpll_init_cfg);
  960. rkclk_set_pll(&cru->cpll_con[0], &cpll_init_cfg);
  961. /* configure perihp aclk, hclk, pclk */
  962. aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1;
  963. assert((aclk_div + 1) * PERIHP_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
  964. hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1;
  965. assert((hclk_div + 1) * PERIHP_HCLK_HZ ==
  966. PERIHP_ACLK_HZ && (hclk_div < 0x4));
  967. pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1;
  968. assert((pclk_div + 1) * PERIHP_PCLK_HZ ==
  969. PERIHP_ACLK_HZ && (pclk_div < 0x7));
  970. rk_clrsetreg(&cru->clksel_con[14],
  971. PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK |
  972. ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK,
  973. pclk_div << PCLK_PERIHP_DIV_CON_SHIFT |
  974. hclk_div << HCLK_PERIHP_DIV_CON_SHIFT |
  975. ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT |
  976. aclk_div << ACLK_PERIHP_DIV_CON_SHIFT);
  977. /* configure perilp0 aclk, hclk, pclk */
  978. aclk_div = GPLL_HZ / PERILP0_ACLK_HZ - 1;
  979. assert((aclk_div + 1) * PERILP0_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
  980. hclk_div = PERILP0_ACLK_HZ / PERILP0_HCLK_HZ - 1;
  981. assert((hclk_div + 1) * PERILP0_HCLK_HZ ==
  982. PERILP0_ACLK_HZ && (hclk_div < 0x4));
  983. pclk_div = PERILP0_ACLK_HZ / PERILP0_PCLK_HZ - 1;
  984. assert((pclk_div + 1) * PERILP0_PCLK_HZ ==
  985. PERILP0_ACLK_HZ && (pclk_div < 0x7));
  986. rk_clrsetreg(&cru->clksel_con[23],
  987. PCLK_PERILP0_DIV_CON_MASK | HCLK_PERILP0_DIV_CON_MASK |
  988. ACLK_PERILP0_PLL_SEL_MASK | ACLK_PERILP0_DIV_CON_MASK,
  989. pclk_div << PCLK_PERILP0_DIV_CON_SHIFT |
  990. hclk_div << HCLK_PERILP0_DIV_CON_SHIFT |
  991. ACLK_PERILP0_PLL_SEL_GPLL << ACLK_PERILP0_PLL_SEL_SHIFT |
  992. aclk_div << ACLK_PERILP0_DIV_CON_SHIFT);
  993. /* perilp1 hclk select gpll as source */
  994. hclk_div = GPLL_HZ / PERILP1_HCLK_HZ - 1;
  995. assert((hclk_div + 1) * PERILP1_HCLK_HZ ==
  996. GPLL_HZ && (hclk_div < 0x1f));
  997. pclk_div = PERILP1_HCLK_HZ / PERILP1_HCLK_HZ - 1;
  998. assert((pclk_div + 1) * PERILP1_HCLK_HZ ==
  999. PERILP1_HCLK_HZ && (hclk_div < 0x7));
  1000. rk_clrsetreg(&cru->clksel_con[25],
  1001. PCLK_PERILP1_DIV_CON_MASK | HCLK_PERILP1_DIV_CON_MASK |
  1002. HCLK_PERILP1_PLL_SEL_MASK,
  1003. pclk_div << PCLK_PERILP1_DIV_CON_SHIFT |
  1004. hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
  1005. HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
  1006. }
  1007. #endif
  1008. static int rk3399_clk_probe(struct udevice *dev)
  1009. {
  1010. #ifdef CONFIG_SPL_BUILD
  1011. struct rk3399_clk_priv *priv = dev_get_priv(dev);
  1012. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1013. struct rk3399_clk_plat *plat = dev_get_platdata(dev);
  1014. priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
  1015. #endif
  1016. rkclk_init(priv->cru);
  1017. #endif
  1018. return 0;
  1019. }
  1020. static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
  1021. {
  1022. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  1023. struct rk3399_clk_priv *priv = dev_get_priv(dev);
  1024. priv->cru = dev_read_addr_ptr(dev);
  1025. #endif
  1026. return 0;
  1027. }
  1028. static int rk3399_clk_bind(struct udevice *dev)
  1029. {
  1030. int ret;
  1031. struct udevice *sys_child;
  1032. struct sysreset_reg *priv;
  1033. /* The reset driver does not have a device node, so bind it here */
  1034. ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
  1035. &sys_child);
  1036. if (ret) {
  1037. debug("Warning: No sysreset driver: ret=%d\n", ret);
  1038. } else {
  1039. priv = malloc(sizeof(struct sysreset_reg));
  1040. priv->glb_srst_fst_value = offsetof(struct rk3399_cru,
  1041. glb_srst_fst_value);
  1042. priv->glb_srst_snd_value = offsetof(struct rk3399_cru,
  1043. glb_srst_snd_value);
  1044. sys_child->priv = priv;
  1045. }
  1046. #if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
  1047. ret = offsetof(struct rk3399_cru, softrst_con[0]);
  1048. ret = rockchip_reset_bind(dev, ret, 21);
  1049. if (ret)
  1050. debug("Warning: software reset driver bind faile\n");
  1051. #endif
  1052. return 0;
  1053. }
  1054. static const struct udevice_id rk3399_clk_ids[] = {
  1055. { .compatible = "rockchip,rk3399-cru" },
  1056. { }
  1057. };
  1058. U_BOOT_DRIVER(clk_rk3399) = {
  1059. .name = "rockchip_rk3399_cru",
  1060. .id = UCLASS_CLK,
  1061. .of_match = rk3399_clk_ids,
  1062. .priv_auto_alloc_size = sizeof(struct rk3399_clk_priv),
  1063. .ofdata_to_platdata = rk3399_clk_ofdata_to_platdata,
  1064. .ops = &rk3399_clk_ops,
  1065. .bind = rk3399_clk_bind,
  1066. .probe = rk3399_clk_probe,
  1067. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1068. .platdata_auto_alloc_size = sizeof(struct rk3399_clk_plat),
  1069. #endif
  1070. };
  1071. static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id)
  1072. {
  1073. u32 div, con;
  1074. switch (clk_id) {
  1075. case SCLK_I2C0_PMU:
  1076. con = readl(&pmucru->pmucru_clksel[2]);
  1077. div = I2C_CLK_DIV_VALUE(con, 0);
  1078. break;
  1079. case SCLK_I2C4_PMU:
  1080. con = readl(&pmucru->pmucru_clksel[3]);
  1081. div = I2C_CLK_DIV_VALUE(con, 4);
  1082. break;
  1083. case SCLK_I2C8_PMU:
  1084. con = readl(&pmucru->pmucru_clksel[2]);
  1085. div = I2C_CLK_DIV_VALUE(con, 8);
  1086. break;
  1087. default:
  1088. printf("do not support this i2c bus\n");
  1089. return -EINVAL;
  1090. }
  1091. return DIV_TO_RATE(PPLL_HZ, div);
  1092. }
  1093. static ulong rk3399_i2c_set_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id,
  1094. uint hz)
  1095. {
  1096. int src_clk_div;
  1097. src_clk_div = PPLL_HZ / hz;
  1098. assert(src_clk_div - 1 < 127);
  1099. switch (clk_id) {
  1100. case SCLK_I2C0_PMU:
  1101. rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(0),
  1102. I2C_PMUCLK_REG_VALUE(0, src_clk_div));
  1103. break;
  1104. case SCLK_I2C4_PMU:
  1105. rk_clrsetreg(&pmucru->pmucru_clksel[3], I2C_PMUCLK_REG_MASK(4),
  1106. I2C_PMUCLK_REG_VALUE(4, src_clk_div));
  1107. break;
  1108. case SCLK_I2C8_PMU:
  1109. rk_clrsetreg(&pmucru->pmucru_clksel[2], I2C_PMUCLK_REG_MASK(8),
  1110. I2C_PMUCLK_REG_VALUE(8, src_clk_div));
  1111. break;
  1112. default:
  1113. printf("do not support this i2c bus\n");
  1114. return -EINVAL;
  1115. }
  1116. return DIV_TO_RATE(PPLL_HZ, src_clk_div);
  1117. }
  1118. static ulong rk3399_pwm_get_clk(struct rk3399_pmucru *pmucru)
  1119. {
  1120. u32 div, con;
  1121. /* PWM closk rate is same as pclk_pmu */
  1122. con = readl(&pmucru->pmucru_clksel[0]);
  1123. div = con & PMU_PCLK_DIV_CON_MASK;
  1124. return DIV_TO_RATE(PPLL_HZ, div);
  1125. }
  1126. static ulong rk3399_pmuclk_get_rate(struct clk *clk)
  1127. {
  1128. struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev);
  1129. ulong rate = 0;
  1130. switch (clk->id) {
  1131. case PLL_PPLL:
  1132. return PPLL_HZ;
  1133. case PCLK_RKPWM_PMU:
  1134. rate = rk3399_pwm_get_clk(priv->pmucru);
  1135. break;
  1136. case SCLK_I2C0_PMU:
  1137. case SCLK_I2C4_PMU:
  1138. case SCLK_I2C8_PMU:
  1139. rate = rk3399_i2c_get_pmuclk(priv->pmucru, clk->id);
  1140. break;
  1141. default:
  1142. return -ENOENT;
  1143. }
  1144. return rate;
  1145. }
  1146. static ulong rk3399_pmuclk_set_rate(struct clk *clk, ulong rate)
  1147. {
  1148. struct rk3399_pmuclk_priv *priv = dev_get_priv(clk->dev);
  1149. ulong ret = 0;
  1150. switch (clk->id) {
  1151. case PLL_PPLL:
  1152. /*
  1153. * This has already been set up and we don't want/need
  1154. * to change it here. Accept the request though, as the
  1155. * device-tree has this in an 'assigned-clocks' list.
  1156. */
  1157. return PPLL_HZ;
  1158. case SCLK_I2C0_PMU:
  1159. case SCLK_I2C4_PMU:
  1160. case SCLK_I2C8_PMU:
  1161. ret = rk3399_i2c_set_pmuclk(priv->pmucru, clk->id, rate);
  1162. break;
  1163. default:
  1164. return -ENOENT;
  1165. }
  1166. return ret;
  1167. }
  1168. static struct clk_ops rk3399_pmuclk_ops = {
  1169. .get_rate = rk3399_pmuclk_get_rate,
  1170. .set_rate = rk3399_pmuclk_set_rate,
  1171. };
  1172. #ifndef CONFIG_SPL_BUILD
  1173. static void pmuclk_init(struct rk3399_pmucru *pmucru)
  1174. {
  1175. u32 pclk_div;
  1176. /* configure pmu pll(ppll) */
  1177. rkclk_set_pll(&pmucru->ppll_con[0], &ppll_init_cfg);
  1178. /* configure pmu pclk */
  1179. pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
  1180. rk_clrsetreg(&pmucru->pmucru_clksel[0],
  1181. PMU_PCLK_DIV_CON_MASK,
  1182. pclk_div << PMU_PCLK_DIV_CON_SHIFT);
  1183. }
  1184. #endif
  1185. static int rk3399_pmuclk_probe(struct udevice *dev)
  1186. {
  1187. #if CONFIG_IS_ENABLED(OF_PLATDATA) || !defined(CONFIG_SPL_BUILD)
  1188. struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
  1189. #endif
  1190. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1191. struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev);
  1192. priv->pmucru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
  1193. #endif
  1194. #ifndef CONFIG_SPL_BUILD
  1195. pmuclk_init(priv->pmucru);
  1196. #endif
  1197. return 0;
  1198. }
  1199. static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
  1200. {
  1201. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  1202. struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
  1203. priv->pmucru = dev_read_addr_ptr(dev);
  1204. #endif
  1205. return 0;
  1206. }
  1207. static int rk3399_pmuclk_bind(struct udevice *dev)
  1208. {
  1209. #if CONFIG_IS_ENABLED(CONFIG_RESET_ROCKCHIP)
  1210. int ret;
  1211. ret = offsetof(struct rk3399_pmucru, pmucru_softrst_con[0]);
  1212. ret = rockchip_reset_bind(dev, ret, 2);
  1213. if (ret)
  1214. debug("Warning: software reset driver bind faile\n");
  1215. #endif
  1216. return 0;
  1217. }
  1218. static const struct udevice_id rk3399_pmuclk_ids[] = {
  1219. { .compatible = "rockchip,rk3399-pmucru" },
  1220. { }
  1221. };
  1222. U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
  1223. .name = "rockchip_rk3399_pmucru",
  1224. .id = UCLASS_CLK,
  1225. .of_match = rk3399_pmuclk_ids,
  1226. .priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv),
  1227. .ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata,
  1228. .ops = &rk3399_pmuclk_ops,
  1229. .probe = rk3399_pmuclk_probe,
  1230. .bind = rk3399_pmuclk_bind,
  1231. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  1232. .platdata_auto_alloc_size = sizeof(struct rk3399_pmuclk_plat),
  1233. #endif
  1234. };