scg.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <div64.h>
  7. #include <asm/io.h>
  8. #include <errno.h>
  9. #include <asm/arch/imx-regs.h>
  10. #include <asm/arch/pcc.h>
  11. #include <asm/arch/sys_proto.h>
  12. scg_p scg1_regs = (scg_p)SCG1_RBASE;
  13. static u32 scg_src_get_rate(enum scg_clk clksrc)
  14. {
  15. u32 reg;
  16. switch (clksrc) {
  17. case SCG_SOSC_CLK:
  18. reg = readl(&scg1_regs->sosccsr);
  19. if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
  20. return 0;
  21. return 24000000;
  22. case SCG_FIRC_CLK:
  23. reg = readl(&scg1_regs->firccsr);
  24. if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
  25. return 0;
  26. return 48000000;
  27. case SCG_SIRC_CLK:
  28. reg = readl(&scg1_regs->sirccsr);
  29. if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
  30. return 0;
  31. return 16000000;
  32. case SCG_ROSC_CLK:
  33. reg = readl(&scg1_regs->rtccsr);
  34. if (!(reg & SCG_ROSC_CSR_ROSCVLD_MASK))
  35. return 0;
  36. return 32768;
  37. default:
  38. break;
  39. }
  40. return 0;
  41. }
  42. static u32 scg_sircdiv_get_rate(enum scg_clk clk)
  43. {
  44. u32 reg, val, rate;
  45. u32 shift, mask;
  46. switch (clk) {
  47. case SCG_SIRC_DIV1_CLK:
  48. mask = SCG_SIRCDIV_DIV1_MASK;
  49. shift = SCG_SIRCDIV_DIV1_SHIFT;
  50. break;
  51. case SCG_SIRC_DIV2_CLK:
  52. mask = SCG_SIRCDIV_DIV2_MASK;
  53. shift = SCG_SIRCDIV_DIV2_SHIFT;
  54. break;
  55. case SCG_SIRC_DIV3_CLK:
  56. mask = SCG_SIRCDIV_DIV3_MASK;
  57. shift = SCG_SIRCDIV_DIV3_SHIFT;
  58. break;
  59. default:
  60. return 0;
  61. }
  62. reg = readl(&scg1_regs->sirccsr);
  63. if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
  64. return 0;
  65. reg = readl(&scg1_regs->sircdiv);
  66. val = (reg & mask) >> shift;
  67. if (!val) /*clock disabled*/
  68. return 0;
  69. rate = scg_src_get_rate(SCG_SIRC_CLK);
  70. rate = rate / (1 << (val - 1));
  71. return rate;
  72. }
  73. static u32 scg_fircdiv_get_rate(enum scg_clk clk)
  74. {
  75. u32 reg, val, rate;
  76. u32 shift, mask;
  77. switch (clk) {
  78. case SCG_FIRC_DIV1_CLK:
  79. mask = SCG_FIRCDIV_DIV1_MASK;
  80. shift = SCG_FIRCDIV_DIV1_SHIFT;
  81. break;
  82. case SCG_FIRC_DIV2_CLK:
  83. mask = SCG_FIRCDIV_DIV2_MASK;
  84. shift = SCG_FIRCDIV_DIV2_SHIFT;
  85. break;
  86. case SCG_FIRC_DIV3_CLK:
  87. mask = SCG_FIRCDIV_DIV3_MASK;
  88. shift = SCG_FIRCDIV_DIV3_SHIFT;
  89. break;
  90. default:
  91. return 0;
  92. }
  93. reg = readl(&scg1_regs->firccsr);
  94. if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
  95. return 0;
  96. reg = readl(&scg1_regs->fircdiv);
  97. val = (reg & mask) >> shift;
  98. if (!val) /*clock disabled*/
  99. return 0;
  100. rate = scg_src_get_rate(SCG_FIRC_CLK);
  101. rate = rate / (1 << (val - 1));
  102. return rate;
  103. }
  104. static u32 scg_soscdiv_get_rate(enum scg_clk clk)
  105. {
  106. u32 reg, val, rate;
  107. u32 shift, mask;
  108. switch (clk) {
  109. case SCG_SOSC_DIV1_CLK:
  110. mask = SCG_SOSCDIV_DIV1_MASK;
  111. shift = SCG_SOSCDIV_DIV1_SHIFT;
  112. break;
  113. case SCG_SOSC_DIV2_CLK:
  114. mask = SCG_SOSCDIV_DIV2_MASK;
  115. shift = SCG_SOSCDIV_DIV2_SHIFT;
  116. break;
  117. case SCG_SOSC_DIV3_CLK:
  118. mask = SCG_SOSCDIV_DIV3_MASK;
  119. shift = SCG_SOSCDIV_DIV3_SHIFT;
  120. break;
  121. default:
  122. return 0;
  123. }
  124. reg = readl(&scg1_regs->sosccsr);
  125. if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
  126. return 0;
  127. reg = readl(&scg1_regs->soscdiv);
  128. val = (reg & mask) >> shift;
  129. if (!val) /*clock disabled*/
  130. return 0;
  131. rate = scg_src_get_rate(SCG_SOSC_CLK);
  132. rate = rate / (1 << (val - 1));
  133. return rate;
  134. }
  135. static u32 scg_apll_pfd_get_rate(enum scg_clk clk)
  136. {
  137. u32 reg, val, rate;
  138. u32 shift, mask, gate, valid;
  139. switch (clk) {
  140. case SCG_APLL_PFD0_CLK:
  141. gate = SCG_PLL_PFD0_GATE_MASK;
  142. valid = SCG_PLL_PFD0_VALID_MASK;
  143. mask = SCG_PLL_PFD0_FRAC_MASK;
  144. shift = SCG_PLL_PFD0_FRAC_SHIFT;
  145. break;
  146. case SCG_APLL_PFD1_CLK:
  147. gate = SCG_PLL_PFD1_GATE_MASK;
  148. valid = SCG_PLL_PFD1_VALID_MASK;
  149. mask = SCG_PLL_PFD1_FRAC_MASK;
  150. shift = SCG_PLL_PFD1_FRAC_SHIFT;
  151. break;
  152. case SCG_APLL_PFD2_CLK:
  153. gate = SCG_PLL_PFD2_GATE_MASK;
  154. valid = SCG_PLL_PFD2_VALID_MASK;
  155. mask = SCG_PLL_PFD2_FRAC_MASK;
  156. shift = SCG_PLL_PFD2_FRAC_SHIFT;
  157. break;
  158. case SCG_APLL_PFD3_CLK:
  159. gate = SCG_PLL_PFD3_GATE_MASK;
  160. valid = SCG_PLL_PFD3_VALID_MASK;
  161. mask = SCG_PLL_PFD3_FRAC_MASK;
  162. shift = SCG_PLL_PFD3_FRAC_SHIFT;
  163. break;
  164. default:
  165. return 0;
  166. }
  167. reg = readl(&scg1_regs->apllpfd);
  168. if (reg & gate || !(reg & valid))
  169. return 0;
  170. clk_debug("scg_apll_pfd_get_rate reg 0x%x\n", reg);
  171. val = (reg & mask) >> shift;
  172. rate = decode_pll(PLL_A7_APLL);
  173. rate = rate / val * 18;
  174. clk_debug("scg_apll_pfd_get_rate rate %u\n", rate);
  175. return rate;
  176. }
  177. static u32 scg_spll_pfd_get_rate(enum scg_clk clk)
  178. {
  179. u32 reg, val, rate;
  180. u32 shift, mask, gate, valid;
  181. switch (clk) {
  182. case SCG_SPLL_PFD0_CLK:
  183. gate = SCG_PLL_PFD0_GATE_MASK;
  184. valid = SCG_PLL_PFD0_VALID_MASK;
  185. mask = SCG_PLL_PFD0_FRAC_MASK;
  186. shift = SCG_PLL_PFD0_FRAC_SHIFT;
  187. break;
  188. case SCG_SPLL_PFD1_CLK:
  189. gate = SCG_PLL_PFD1_GATE_MASK;
  190. valid = SCG_PLL_PFD1_VALID_MASK;
  191. mask = SCG_PLL_PFD1_FRAC_MASK;
  192. shift = SCG_PLL_PFD1_FRAC_SHIFT;
  193. break;
  194. case SCG_SPLL_PFD2_CLK:
  195. gate = SCG_PLL_PFD2_GATE_MASK;
  196. valid = SCG_PLL_PFD2_VALID_MASK;
  197. mask = SCG_PLL_PFD2_FRAC_MASK;
  198. shift = SCG_PLL_PFD2_FRAC_SHIFT;
  199. break;
  200. case SCG_SPLL_PFD3_CLK:
  201. gate = SCG_PLL_PFD3_GATE_MASK;
  202. valid = SCG_PLL_PFD3_VALID_MASK;
  203. mask = SCG_PLL_PFD3_FRAC_MASK;
  204. shift = SCG_PLL_PFD3_FRAC_SHIFT;
  205. break;
  206. default:
  207. return 0;
  208. }
  209. reg = readl(&scg1_regs->spllpfd);
  210. if (reg & gate || !(reg & valid))
  211. return 0;
  212. clk_debug("scg_spll_pfd_get_rate reg 0x%x\n", reg);
  213. val = (reg & mask) >> shift;
  214. rate = decode_pll(PLL_A7_SPLL);
  215. rate = rate / val * 18;
  216. clk_debug("scg_spll_pfd_get_rate rate %u\n", rate);
  217. return rate;
  218. }
  219. static u32 scg_apll_get_rate(void)
  220. {
  221. u32 reg, val, rate;
  222. reg = readl(&scg1_regs->apllcfg);
  223. val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
  224. if (!val) {
  225. /* APLL clock after two dividers */
  226. rate = decode_pll(PLL_A7_APLL);
  227. val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
  228. SCG_PLL_CFG_POSTDIV1_SHIFT;
  229. rate = rate / (val + 1);
  230. val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
  231. SCG_PLL_CFG_POSTDIV2_SHIFT;
  232. rate = rate / (val + 1);
  233. } else {
  234. /* APLL PFD clock */
  235. val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
  236. SCG_PLL_CFG_PFDSEL_SHIFT;
  237. rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val);
  238. }
  239. return rate;
  240. }
  241. static u32 scg_spll_get_rate(void)
  242. {
  243. u32 reg, val, rate;
  244. reg = readl(&scg1_regs->spllcfg);
  245. val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
  246. clk_debug("scg_spll_get_rate reg 0x%x\n", reg);
  247. if (!val) {
  248. /* APLL clock after two dividers */
  249. rate = decode_pll(PLL_A7_SPLL);
  250. val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
  251. SCG_PLL_CFG_POSTDIV1_SHIFT;
  252. rate = rate / (val + 1);
  253. val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
  254. SCG_PLL_CFG_POSTDIV2_SHIFT;
  255. rate = rate / (val + 1);
  256. clk_debug("scg_spll_get_rate SPLL %u\n", rate);
  257. } else {
  258. /* APLL PFD clock */
  259. val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
  260. SCG_PLL_CFG_PFDSEL_SHIFT;
  261. rate = scg_spll_pfd_get_rate(SCG_SPLL_PFD0_CLK + val);
  262. clk_debug("scg_spll_get_rate PFD %u\n", rate);
  263. }
  264. return rate;
  265. }
  266. static u32 scg_ddr_get_rate(void)
  267. {
  268. u32 reg, val, rate, div;
  269. reg = readl(&scg1_regs->ddrccr);
  270. val = (reg & SCG_DDRCCR_DDRCS_MASK) >> SCG_DDRCCR_DDRCS_SHIFT;
  271. div = (reg & SCG_DDRCCR_DDRDIV_MASK) >> SCG_DDRCCR_DDRDIV_SHIFT;
  272. if (!div)
  273. return 0;
  274. if (!val) {
  275. reg = readl(&scg1_regs->apllcfg);
  276. val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
  277. SCG_PLL_CFG_PFDSEL_SHIFT;
  278. rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val);
  279. } else {
  280. rate = decode_pll(PLL_USB);
  281. }
  282. rate = rate / (1 << (div - 1));
  283. return rate;
  284. }
  285. static u32 scg_nic_get_rate(enum scg_clk clk)
  286. {
  287. u32 reg, val, rate;
  288. u32 shift, mask;
  289. reg = readl(&scg1_regs->niccsr);
  290. val = (reg & SCG_NICCSR_NICCS_MASK) >> SCG_NICCSR_NICCS_SHIFT;
  291. clk_debug("scg_nic_get_rate niccsr 0x%x\n", reg);
  292. if (!val)
  293. rate = scg_src_get_rate(SCG_FIRC_CLK);
  294. else
  295. rate = scg_ddr_get_rate();
  296. clk_debug("scg_nic_get_rate parent rate %u\n", rate);
  297. val = (reg & SCG_NICCSR_NIC0DIV_MASK) >> SCG_NICCSR_NIC0DIV_SHIFT;
  298. rate = rate / (val + 1);
  299. clk_debug("scg_nic_get_rate NIC0 rate %u\n", rate);
  300. switch (clk) {
  301. case SCG_NIC0_CLK:
  302. return rate;
  303. case SCG_GPU_CLK:
  304. mask = SCG_NICCSR_GPUDIV_MASK;
  305. shift = SCG_NICCSR_GPUDIV_SHIFT;
  306. break;
  307. case SCG_NIC1_EXT_CLK:
  308. case SCG_NIC1_BUS_CLK:
  309. case SCG_NIC1_CLK:
  310. mask = SCG_NICCSR_NIC1DIV_MASK;
  311. shift = SCG_NICCSR_NIC1DIV_SHIFT;
  312. break;
  313. default:
  314. return 0;
  315. }
  316. val = (reg & mask) >> shift;
  317. rate = rate / (val + 1);
  318. clk_debug("scg_nic_get_rate NIC1 rate %u\n", rate);
  319. switch (clk) {
  320. case SCG_GPU_CLK:
  321. case SCG_NIC1_CLK:
  322. return rate;
  323. case SCG_NIC1_EXT_CLK:
  324. mask = SCG_NICCSR_NIC1EXTDIV_MASK;
  325. shift = SCG_NICCSR_NIC1EXTDIV_SHIFT;
  326. break;
  327. case SCG_NIC1_BUS_CLK:
  328. mask = SCG_NICCSR_NIC1BUSDIV_MASK;
  329. shift = SCG_NICCSR_NIC1BUSDIV_SHIFT;
  330. break;
  331. default:
  332. return 0;
  333. }
  334. val = (reg & mask) >> shift;
  335. rate = rate / (val + 1);
  336. clk_debug("scg_nic_get_rate NIC1 bus rate %u\n", rate);
  337. return rate;
  338. }
  339. static enum scg_clk scg_scs_array[4] = {
  340. SCG_SOSC_CLK, SCG_SIRC_CLK, SCG_FIRC_CLK, SCG_ROSC_CLK,
  341. };
  342. static u32 scg_sys_get_rate(enum scg_clk clk)
  343. {
  344. u32 reg, val, rate;
  345. if (clk != SCG_CORE_CLK && clk != SCG_BUS_CLK)
  346. return 0;
  347. reg = readl(&scg1_regs->csr);
  348. val = (reg & SCG_CCR_SCS_MASK) >> SCG_CCR_SCS_SHIFT;
  349. clk_debug("scg_sys_get_rate reg 0x%x\n", reg);
  350. switch (val) {
  351. case SCG_SCS_SYS_OSC:
  352. case SCG_SCS_SLOW_IRC:
  353. case SCG_SCS_FAST_IRC:
  354. case SCG_SCS_RTC_OSC:
  355. rate = scg_src_get_rate(scg_scs_array[val]);
  356. break;
  357. case 5:
  358. rate = scg_apll_get_rate();
  359. break;
  360. case 6:
  361. rate = scg_spll_get_rate();
  362. break;
  363. default:
  364. return 0;
  365. }
  366. clk_debug("scg_sys_get_rate parent rate %u\n", rate);
  367. val = (reg & SCG_CCR_DIVCORE_MASK) >> SCG_CCR_DIVCORE_SHIFT;
  368. rate = rate / (val + 1);
  369. if (clk == SCG_BUS_CLK) {
  370. val = (reg & SCG_CCR_DIVBUS_MASK) >> SCG_CCR_DIVBUS_SHIFT;
  371. rate = rate / (val + 1);
  372. }
  373. return rate;
  374. }
  375. u32 decode_pll(enum pll_clocks pll)
  376. {
  377. u32 reg, pre_div, infreq, mult;
  378. u32 num, denom;
  379. /*
  380. * Alought there are four choices for the bypass src,
  381. * we choose OSC_24M which is the default set in ROM.
  382. */
  383. switch (pll) {
  384. case PLL_A7_SPLL:
  385. reg = readl(&scg1_regs->spllcsr);
  386. if (!(reg & SCG_SPLL_CSR_SPLLVLD_MASK))
  387. return 0;
  388. reg = readl(&scg1_regs->spllcfg);
  389. pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
  390. SCG_PLL_CFG_PREDIV_SHIFT;
  391. pre_div += 1;
  392. mult = (reg & SCG1_SPLL_CFG_MULT_MASK) >>
  393. SCG_PLL_CFG_MULT_SHIFT;
  394. infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
  395. SCG_PLL_CFG_CLKSRC_SHIFT;
  396. if (!infreq)
  397. infreq = scg_src_get_rate(SCG_SOSC_CLK);
  398. else
  399. infreq = scg_src_get_rate(SCG_FIRC_CLK);
  400. num = readl(&scg1_regs->spllnum);
  401. denom = readl(&scg1_regs->splldenom);
  402. infreq = infreq / pre_div;
  403. return infreq * mult + infreq * num / denom;
  404. case PLL_A7_APLL:
  405. reg = readl(&scg1_regs->apllcsr);
  406. if (!(reg & SCG_APLL_CSR_APLLVLD_MASK))
  407. return 0;
  408. reg = readl(&scg1_regs->apllcfg);
  409. pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
  410. SCG_PLL_CFG_PREDIV_SHIFT;
  411. pre_div += 1;
  412. mult = (reg & SCG_APLL_CFG_MULT_MASK) >>
  413. SCG_PLL_CFG_MULT_SHIFT;
  414. infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
  415. SCG_PLL_CFG_CLKSRC_SHIFT;
  416. if (!infreq)
  417. infreq = scg_src_get_rate(SCG_SOSC_CLK);
  418. else
  419. infreq = scg_src_get_rate(SCG_FIRC_CLK);
  420. num = readl(&scg1_regs->apllnum);
  421. denom = readl(&scg1_regs->aplldenom);
  422. infreq = infreq / pre_div;
  423. return infreq * mult + infreq * num / denom;
  424. case PLL_USB:
  425. reg = readl(&scg1_regs->upllcsr);
  426. if (!(reg & SCG_UPLL_CSR_UPLLVLD_MASK))
  427. return 0;
  428. return 480000000u;
  429. case PLL_MIPI:
  430. return 480000000u;
  431. default:
  432. printf("Unsupported pll clocks %d\n", pll);
  433. break;
  434. }
  435. return 0;
  436. }
  437. u32 scg_clk_get_rate(enum scg_clk clk)
  438. {
  439. switch (clk) {
  440. case SCG_SIRC_DIV1_CLK:
  441. case SCG_SIRC_DIV2_CLK:
  442. case SCG_SIRC_DIV3_CLK:
  443. return scg_sircdiv_get_rate(clk);
  444. case SCG_FIRC_DIV1_CLK:
  445. case SCG_FIRC_DIV2_CLK:
  446. case SCG_FIRC_DIV3_CLK:
  447. return scg_fircdiv_get_rate(clk);
  448. case SCG_SOSC_DIV1_CLK:
  449. case SCG_SOSC_DIV2_CLK:
  450. case SCG_SOSC_DIV3_CLK:
  451. return scg_soscdiv_get_rate(clk);
  452. case SCG_CORE_CLK:
  453. case SCG_BUS_CLK:
  454. return scg_sys_get_rate(clk);
  455. case SCG_SPLL_PFD0_CLK:
  456. case SCG_SPLL_PFD1_CLK:
  457. case SCG_SPLL_PFD2_CLK:
  458. case SCG_SPLL_PFD3_CLK:
  459. return scg_spll_pfd_get_rate(clk);
  460. case SCG_APLL_PFD0_CLK:
  461. case SCG_APLL_PFD1_CLK:
  462. case SCG_APLL_PFD2_CLK:
  463. case SCG_APLL_PFD3_CLK:
  464. return scg_apll_pfd_get_rate(clk);
  465. case SCG_DDR_CLK:
  466. return scg_ddr_get_rate();
  467. case SCG_NIC0_CLK:
  468. case SCG_GPU_CLK:
  469. case SCG_NIC1_CLK:
  470. case SCG_NIC1_BUS_CLK:
  471. case SCG_NIC1_EXT_CLK:
  472. return scg_nic_get_rate(clk);
  473. case USB_PLL_OUT:
  474. return decode_pll(PLL_USB);
  475. case MIPI_PLL_OUT:
  476. return decode_pll(PLL_MIPI);
  477. case SCG_SOSC_CLK:
  478. case SCG_FIRC_CLK:
  479. case SCG_SIRC_CLK:
  480. case SCG_ROSC_CLK:
  481. return scg_src_get_rate(clk);
  482. default:
  483. return 0;
  484. }
  485. }
  486. int scg_enable_pll_pfd(enum scg_clk clk, u32 frac)
  487. {
  488. u32 reg;
  489. u32 shift, mask, gate, valid;
  490. u32 addr;
  491. if (frac < 12 || frac > 35)
  492. return -EINVAL;
  493. switch (clk) {
  494. case SCG_SPLL_PFD0_CLK:
  495. case SCG_APLL_PFD0_CLK:
  496. gate = SCG_PLL_PFD0_GATE_MASK;
  497. valid = SCG_PLL_PFD0_VALID_MASK;
  498. mask = SCG_PLL_PFD0_FRAC_MASK;
  499. shift = SCG_PLL_PFD0_FRAC_SHIFT;
  500. if (clk == SCG_SPLL_PFD0_CLK)
  501. addr = (u32)(&scg1_regs->spllpfd);
  502. else
  503. addr = (u32)(&scg1_regs->apllpfd);
  504. break;
  505. case SCG_SPLL_PFD1_CLK:
  506. case SCG_APLL_PFD1_CLK:
  507. gate = SCG_PLL_PFD1_GATE_MASK;
  508. valid = SCG_PLL_PFD1_VALID_MASK;
  509. mask = SCG_PLL_PFD1_FRAC_MASK;
  510. shift = SCG_PLL_PFD1_FRAC_SHIFT;
  511. if (clk == SCG_SPLL_PFD1_CLK)
  512. addr = (u32)(&scg1_regs->spllpfd);
  513. else
  514. addr = (u32)(&scg1_regs->apllpfd);
  515. break;
  516. case SCG_SPLL_PFD2_CLK:
  517. case SCG_APLL_PFD2_CLK:
  518. gate = SCG_PLL_PFD2_GATE_MASK;
  519. valid = SCG_PLL_PFD2_VALID_MASK;
  520. mask = SCG_PLL_PFD2_FRAC_MASK;
  521. shift = SCG_PLL_PFD2_FRAC_SHIFT;
  522. if (clk == SCG_SPLL_PFD2_CLK)
  523. addr = (u32)(&scg1_regs->spllpfd);
  524. else
  525. addr = (u32)(&scg1_regs->apllpfd);
  526. break;
  527. case SCG_SPLL_PFD3_CLK:
  528. case SCG_APLL_PFD3_CLK:
  529. gate = SCG_PLL_PFD3_GATE_MASK;
  530. valid = SCG_PLL_PFD3_VALID_MASK;
  531. mask = SCG_PLL_PFD3_FRAC_MASK;
  532. shift = SCG_PLL_PFD3_FRAC_SHIFT;
  533. if (clk == SCG_SPLL_PFD3_CLK)
  534. addr = (u32)(&scg1_regs->spllpfd);
  535. else
  536. addr = (u32)(&scg1_regs->apllpfd);
  537. break;
  538. default:
  539. return -EINVAL;
  540. }
  541. /* Gate the PFD */
  542. reg = readl(addr);
  543. reg |= gate;
  544. writel(reg, addr);
  545. /* Write Frac divider */
  546. reg &= ~mask;
  547. reg |= (frac << shift) & mask;
  548. writel(reg, addr);
  549. /*
  550. * Un-gate the PFD
  551. * (Need un-gate before checking valid, not align with RM)
  552. */
  553. reg &= ~gate;
  554. writel(reg, addr);
  555. /* Wait for PFD clock being valid */
  556. do {
  557. reg = readl(addr);
  558. } while (!(reg & valid));
  559. return 0;
  560. }
  561. #define SIM_MISC_CTRL0_USB_PLL_EN_MASK (0x1 << 2)
  562. int scg_enable_usb_pll(bool usb_control)
  563. {
  564. u32 sosc_rate;
  565. s32 timeout = 1000000;
  566. u32 reg;
  567. struct usbphy_regs *usbphy =
  568. (struct usbphy_regs *)USBPHY_RBASE;
  569. sosc_rate = scg_src_get_rate(SCG_SOSC_CLK);
  570. if (!sosc_rate)
  571. return -EPERM;
  572. reg = readl(SIM0_RBASE + 0x3C);
  573. if (usb_control)
  574. reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK;
  575. else
  576. reg |= SIM_MISC_CTRL0_USB_PLL_EN_MASK;
  577. writel(reg, SIM0_RBASE + 0x3C);
  578. if (!(readl(&usbphy->usb1_pll_480_ctrl) & PLL_USB_LOCK_MASK)) {
  579. writel(0x1c00000, &usbphy->usb1_pll_480_ctrl_clr);
  580. switch (sosc_rate) {
  581. case 24000000:
  582. writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
  583. break;
  584. case 30000000:
  585. writel(0x800000, &usbphy->usb1_pll_480_ctrl_set);
  586. break;
  587. case 19200000:
  588. writel(0x1400000, &usbphy->usb1_pll_480_ctrl_set);
  589. break;
  590. default:
  591. writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
  592. break;
  593. }
  594. /* Enable the regulator first */
  595. writel(PLL_USB_REG_ENABLE_MASK,
  596. &usbphy->usb1_pll_480_ctrl_set);
  597. /* Wait at least 15us */
  598. udelay(15);
  599. /* Enable the power */
  600. writel(PLL_USB_PWR_MASK, &usbphy->usb1_pll_480_ctrl_set);
  601. /* Wait lock */
  602. while (timeout--) {
  603. if (readl(&usbphy->usb1_pll_480_ctrl) &
  604. PLL_USB_LOCK_MASK)
  605. break;
  606. }
  607. if (timeout <= 0) {
  608. /* If timeout, we power down the pll */
  609. writel(PLL_USB_PWR_MASK,
  610. &usbphy->usb1_pll_480_ctrl_clr);
  611. return -ETIME;
  612. }
  613. }
  614. /* Clear the bypass */
  615. writel(PLL_USB_BYPASS_MASK, &usbphy->usb1_pll_480_ctrl_clr);
  616. /* Enable the PLL clock out to USB */
  617. writel((PLL_USB_EN_USB_CLKS_MASK | PLL_USB_ENABLE_MASK),
  618. &usbphy->usb1_pll_480_ctrl_set);
  619. if (!usb_control) {
  620. while (timeout--) {
  621. if (readl(&scg1_regs->upllcsr) &
  622. SCG_UPLL_CSR_UPLLVLD_MASK)
  623. break;
  624. }
  625. if (timeout <= 0) {
  626. reg = readl(SIM0_RBASE + 0x3C);
  627. reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK;
  628. writel(reg, SIM0_RBASE + 0x3C);
  629. return -ETIME;
  630. }
  631. }
  632. return 0;
  633. }
  634. /* A7 domain system clock source is SPLL */
  635. #define SCG1_RCCR_SCS_NUM ((SCG_SCS_SYS_PLL) << SCG_CCR_SCS_SHIFT)
  636. /* A7 Core clck = SPLL PFD0 / 1 = 500MHz / 1 = 500MHz */
  637. #define SCG1_RCCR_DIVCORE_NUM ((0x0) << SCG_CCR_DIVCORE_SHIFT)
  638. #define SCG1_RCCR_CFG_MASK (SCG_CCR_SCS_MASK | SCG_CCR_DIVBUS_MASK)
  639. /* A7 Plat clck = A7 Core Clock / 2 = 250MHz / 1 = 250MHz */
  640. #define SCG1_RCCR_DIVBUS_NUM ((0x1) << SCG_CCR_DIVBUS_SHIFT)
  641. #define SCG1_RCCR_CFG_NUM (SCG1_RCCR_SCS_NUM | SCG1_RCCR_DIVBUS_NUM)
  642. void scg_a7_rccr_init(void)
  643. {
  644. u32 rccr_reg_val = 0;
  645. rccr_reg_val = readl(&scg1_regs->rccr);
  646. rccr_reg_val &= (~SCG1_RCCR_CFG_MASK);
  647. rccr_reg_val |= (SCG1_RCCR_CFG_NUM);
  648. writel(rccr_reg_val, &scg1_regs->rccr);
  649. }
  650. /* POSTDIV2 = 1 */
  651. #define SCG1_SPLL_CFG_POSTDIV2_NUM ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT)
  652. /* POSTDIV1 = 1 */
  653. #define SCG1_SPLL_CFG_POSTDIV1_NUM ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT)
  654. /* MULT = 22 */
  655. #define SCG1_SPLL_CFG_MULT_NUM ((22) << SCG_PLL_CFG_MULT_SHIFT)
  656. /* PFD0 output clock selected */
  657. #define SCG1_SPLL_CFG_PFDSEL_NUM ((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
  658. /* PREDIV = 1 */
  659. #define SCG1_SPLL_CFG_PREDIV_NUM ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT)
  660. /* SPLL output clocks (including PFD outputs) selected */
  661. #define SCG1_SPLL_CFG_BYPASS_NUM ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT)
  662. /* SPLL PFD output clock selected */
  663. #define SCG1_SPLL_CFG_PLLSEL_NUM ((0x1) << SCG_PLL_CFG_PLLSEL_SHIFT)
  664. /* Clock source is System OSC */
  665. #define SCG1_SPLL_CFG_CLKSRC_NUM ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT)
  666. #define SCG1_SPLL_CFG_NUM_24M_OSC (SCG1_SPLL_CFG_POSTDIV2_NUM | \
  667. SCG1_SPLL_CFG_POSTDIV1_NUM | \
  668. (22 << SCG_PLL_CFG_MULT_SHIFT) | \
  669. SCG1_SPLL_CFG_PFDSEL_NUM | \
  670. SCG1_SPLL_CFG_PREDIV_NUM | \
  671. SCG1_SPLL_CFG_BYPASS_NUM | \
  672. SCG1_SPLL_CFG_PLLSEL_NUM | \
  673. SCG1_SPLL_CFG_CLKSRC_NUM)
  674. /*413Mhz = A7 SPLL(528MHz) * 18/23 */
  675. #define SCG1_SPLL_PFD0_FRAC_NUM ((23) << SCG_PLL_PFD0_FRAC_SHIFT)
  676. void scg_a7_spll_init(void)
  677. {
  678. u32 val = 0;
  679. /* Disable A7 System PLL */
  680. val = readl(&scg1_regs->spllcsr);
  681. val &= ~SCG_SPLL_CSR_SPLLEN_MASK;
  682. writel(val, &scg1_regs->spllcsr);
  683. /*
  684. * Per block guide,
  685. * "When changing PFD values, it is recommneded PFDx clock
  686. * gets gated first by writing a value of 1 to PFDx_CLKGATE register,
  687. * then program the new PFD value, then poll the PFDx_VALID
  688. * flag to set before writing a value of 0 to PFDx_CLKGATE
  689. * to ungate the PFDx clock and allow PFDx clock to run"
  690. */
  691. /* Gate off A7 SPLL PFD0 ~ PDF4 */
  692. val = readl(&scg1_regs->spllpfd);
  693. val |= (SCG_PLL_PFD3_GATE_MASK |
  694. SCG_PLL_PFD2_GATE_MASK |
  695. SCG_PLL_PFD1_GATE_MASK |
  696. SCG_PLL_PFD0_GATE_MASK);
  697. writel(val, &scg1_regs->spllpfd);
  698. /* ================ A7 SPLL Configuration Start ============== */
  699. /* Configure A7 System PLL */
  700. writel(SCG1_SPLL_CFG_NUM_24M_OSC, &scg1_regs->spllcfg);
  701. /* Enable A7 System PLL */
  702. val = readl(&scg1_regs->spllcsr);
  703. val |= SCG_SPLL_CSR_SPLLEN_MASK;
  704. writel(val, &scg1_regs->spllcsr);
  705. /* Wait for A7 SPLL clock ready */
  706. while (!(readl(&scg1_regs->spllcsr) & SCG_SPLL_CSR_SPLLVLD_MASK))
  707. ;
  708. /* Configure A7 SPLL PFD0 */
  709. val = readl(&scg1_regs->spllpfd);
  710. val &= ~SCG_PLL_PFD0_FRAC_MASK;
  711. val |= SCG1_SPLL_PFD0_FRAC_NUM;
  712. writel(val, &scg1_regs->spllpfd);
  713. /* Un-gate A7 SPLL PFD0 */
  714. val = readl(&scg1_regs->spllpfd);
  715. val &= ~SCG_PLL_PFD0_GATE_MASK;
  716. writel(val, &scg1_regs->spllpfd);
  717. /* Wait for A7 SPLL PFD0 clock being valid */
  718. while (!(readl(&scg1_regs->spllpfd) & SCG_PLL_PFD0_VALID_MASK))
  719. ;
  720. /* ================ A7 SPLL Configuration End ============== */
  721. }
  722. /* DDR clock source is APLL PFD0 (396MHz) */
  723. #define SCG1_DDRCCR_DDRCS_NUM ((0x0) << SCG_DDRCCR_DDRCS_SHIFT)
  724. /* DDR clock = APLL PFD0 / 1 = 396MHz / 1 = 396MHz */
  725. #define SCG1_DDRCCR_DDRDIV_NUM ((0x1) << SCG_DDRCCR_DDRDIV_SHIFT)
  726. /* DDR clock = APLL PFD0 / 2 = 396MHz / 2 = 198MHz */
  727. #define SCG1_DDRCCR_DDRDIV_LF_NUM ((0x2) << SCG_DDRCCR_DDRDIV_SHIFT)
  728. #define SCG1_DDRCCR_CFG_NUM (SCG1_DDRCCR_DDRCS_NUM | \
  729. SCG1_DDRCCR_DDRDIV_NUM)
  730. #define SCG1_DDRCCR_CFG_LF_NUM (SCG1_DDRCCR_DDRCS_NUM | \
  731. SCG1_DDRCCR_DDRDIV_LF_NUM)
  732. void scg_a7_ddrclk_init(void)
  733. {
  734. writel(SCG1_DDRCCR_CFG_NUM, &scg1_regs->ddrccr);
  735. }
  736. /* SCG1(A7) APLLCFG configurations */
  737. /* divide by 1 <<28 */
  738. #define SCG1_APLL_CFG_POSTDIV2_NUM ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT)
  739. /* divide by 1 <<24 */
  740. #define SCG1_APLL_CFG_POSTDIV1_NUM ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT)
  741. /* MULT is 22 <<16 */
  742. #define SCG1_APLL_CFG_MULT_NUM ((22) << SCG_PLL_CFG_MULT_SHIFT)
  743. /* PFD0 output clock selected <<14 */
  744. #define SCG1_APLL_CFG_PFDSEL_NUM ((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
  745. /* PREDIV = 1 <<8 */
  746. #define SCG1_APLL_CFG_PREDIV_NUM ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT)
  747. /* APLL output clocks (including PFD outputs) selected <<2 */
  748. #define SCG1_APLL_CFG_BYPASS_NUM ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT)
  749. /* APLL PFD output clock selected <<1 */
  750. #define SCG1_APLL_CFG_PLLSEL_NUM ((0x0) << SCG_PLL_CFG_PLLSEL_SHIFT)
  751. /* Clock source is System OSC <<0 */
  752. #define SCG1_APLL_CFG_CLKSRC_NUM ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT)
  753. /*
  754. * A7 APLL = 24MHz / 1 * 22 / 1 / 1 = 528MHz,
  755. * system PLL is sourced from APLL,
  756. * APLL clock source is system OSC (24MHz)
  757. */
  758. #define SCG1_APLL_CFG_NUM_24M_OSC (SCG1_APLL_CFG_POSTDIV2_NUM | \
  759. SCG1_APLL_CFG_POSTDIV1_NUM | \
  760. (22 << SCG_PLL_CFG_MULT_SHIFT) | \
  761. SCG1_APLL_CFG_PFDSEL_NUM | \
  762. SCG1_APLL_CFG_PREDIV_NUM | \
  763. SCG1_APLL_CFG_BYPASS_NUM | \
  764. SCG1_APLL_CFG_PLLSEL_NUM | \
  765. SCG1_APLL_CFG_CLKSRC_NUM)
  766. /* PFD0 Freq = A7 APLL(528MHz) * 18 / 27 = 352MHz */
  767. #define SCG1_APLL_PFD0_FRAC_NUM (27)
  768. void scg_a7_apll_init(void)
  769. {
  770. u32 val = 0;
  771. /* Disable A7 Auxiliary PLL */
  772. val = readl(&scg1_regs->apllcsr);
  773. val &= ~SCG_APLL_CSR_APLLEN_MASK;
  774. writel(val, &scg1_regs->apllcsr);
  775. /* Gate off A7 APLL PFD0 ~ PDF4 */
  776. val = readl(&scg1_regs->apllpfd);
  777. val |= 0x80808080;
  778. writel(val, &scg1_regs->apllpfd);
  779. /* ================ A7 APLL Configuration Start ============== */
  780. /* Configure A7 Auxiliary PLL */
  781. writel(SCG1_APLL_CFG_NUM_24M_OSC, &scg1_regs->apllcfg);
  782. /* Enable A7 Auxiliary PLL */
  783. val = readl(&scg1_regs->apllcsr);
  784. val |= SCG_APLL_CSR_APLLEN_MASK;
  785. writel(val, &scg1_regs->apllcsr);
  786. /* Wait for A7 APLL clock ready */
  787. while (!(readl(&scg1_regs->apllcsr) & SCG_APLL_CSR_APLLVLD_MASK))
  788. ;
  789. /* Configure A7 APLL PFD0 */
  790. val = readl(&scg1_regs->apllpfd);
  791. val &= ~SCG_PLL_PFD0_FRAC_MASK;
  792. val |= SCG1_APLL_PFD0_FRAC_NUM;
  793. writel(val, &scg1_regs->apllpfd);
  794. /* Un-gate A7 APLL PFD0 */
  795. val = readl(&scg1_regs->apllpfd);
  796. val &= ~SCG_PLL_PFD0_GATE_MASK;
  797. writel(val, &scg1_regs->apllpfd);
  798. /* Wait for A7 APLL PFD0 clock being valid */
  799. while (!(readl(&scg1_regs->apllpfd) & SCG_PLL_PFD0_VALID_MASK))
  800. ;
  801. }
  802. /* SCG1(A7) FIRC DIV configurations */
  803. /* Disable FIRC DIV3 */
  804. #define SCG1_FIRCDIV_DIV3_NUM ((0x0) << SCG_FIRCDIV_DIV3_SHIFT)
  805. /* FIRC DIV2 = 48MHz / 1 = 48MHz */
  806. #define SCG1_FIRCDIV_DIV2_NUM ((0x1) << SCG_FIRCDIV_DIV2_SHIFT)
  807. /* Disable FIRC DIV1 */
  808. #define SCG1_FIRCDIV_DIV1_NUM ((0x0) << SCG_FIRCDIV_DIV1_SHIFT)
  809. void scg_a7_firc_init(void)
  810. {
  811. /* Wait for FIRC clock ready */
  812. while (!(readl(&scg1_regs->firccsr) & SCG_FIRC_CSR_FIRCVLD_MASK))
  813. ;
  814. /* Configure A7 FIRC DIV1 ~ DIV3 */
  815. writel((SCG1_FIRCDIV_DIV3_NUM |
  816. SCG1_FIRCDIV_DIV2_NUM |
  817. SCG1_FIRCDIV_DIV1_NUM), &scg1_regs->fircdiv);
  818. }
  819. /* SCG1(A7) NICCCR configurations */
  820. /* NIC clock source is DDR clock (396/198MHz) */
  821. #define SCG1_NICCCR_NICCS_NUM ((0x1) << SCG_NICCCR_NICCS_SHIFT)
  822. /* NIC0 clock = DDR Clock / 2 = 396MHz / 2 = 198MHz */
  823. #define SCG1_NICCCR_NIC0_DIV_NUM ((0x1) << SCG_NICCCR_NIC0_DIV_SHIFT)
  824. /* NIC0 clock = DDR Clock / 1 = 198MHz / 1 = 198MHz */
  825. #define SCG1_NICCCR_NIC0_DIV_LF_NUM ((0x0) << SCG_NICCCR_NIC0_DIV_SHIFT)
  826. /* NIC1 clock = NIC0 Clock / 1 = 198MHz / 2 = 198MHz */
  827. #define SCG1_NICCCR_NIC1_DIV_NUM ((0x0) << SCG_NICCCR_NIC1_DIV_SHIFT)
  828. /* NIC1 bus clock = NIC1 Clock / 3 = 198MHz / 3 = 66MHz */
  829. #define SCG1_NICCCR_NIC1_DIVBUS_NUM ((0x2) << SCG_NICCCR_NIC1_DIVBUS_SHIFT)
  830. #define SCG1_NICCCR_CFG_NUM (SCG1_NICCCR_NICCS_NUM | \
  831. SCG1_NICCCR_NIC0_DIV_NUM | \
  832. SCG1_NICCCR_NIC1_DIV_NUM | \
  833. SCG1_NICCCR_NIC1_DIVBUS_NUM)
  834. void scg_a7_nicclk_init(void)
  835. {
  836. writel(SCG1_NICCCR_CFG_NUM, &scg1_regs->nicccr);
  837. }
  838. /* SCG1(A7) FIRC DIV configurations */
  839. /* Enable FIRC DIV3 */
  840. #define SCG1_SOSCDIV_DIV3_NUM ((0x1) << SCG_SOSCDIV_DIV3_SHIFT)
  841. /* FIRC DIV2 = 48MHz / 1 = 48MHz */
  842. #define SCG1_SOSCDIV_DIV2_NUM ((0x1) << SCG_SOSCDIV_DIV2_SHIFT)
  843. /* Enable FIRC DIV1 */
  844. #define SCG1_SOSCDIV_DIV1_NUM ((0x1) << SCG_SOSCDIV_DIV1_SHIFT)
  845. void scg_a7_soscdiv_init(void)
  846. {
  847. /* Wait for FIRC clock ready */
  848. while (!(readl(&scg1_regs->sosccsr) & SCG_SOSC_CSR_SOSCVLD_MASK))
  849. ;
  850. /* Configure A7 FIRC DIV1 ~ DIV3 */
  851. writel((SCG1_SOSCDIV_DIV3_NUM | SCG1_SOSCDIV_DIV2_NUM |
  852. SCG1_SOSCDIV_DIV1_NUM), &scg1_regs->soscdiv);
  853. }
  854. void scg_a7_sys_clk_sel(enum scg_sys_src clk)
  855. {
  856. u32 rccr_reg_val = 0;
  857. clk_debug("%s: system clock selected as %s\n", "[SCG]",
  858. clk == SCG_SCS_SYS_OSC ? "SYS_OSC" :
  859. clk == SCG_SCS_SLOW_IRC ? "SLOW_IRC" :
  860. clk == SCG_SCS_FAST_IRC ? "FAST_IRC" :
  861. clk == SCG_SCS_RTC_OSC ? "RTC_OSC" :
  862. clk == SCG_SCS_AUX_PLL ? "AUX_PLL" :
  863. clk == SCG_SCS_SYS_PLL ? "SYS_PLL" :
  864. clk == SCG_SCS_USBPHY_PLL ? "USBPHY_PLL" :
  865. "Invalid source"
  866. );
  867. rccr_reg_val = readl(&scg1_regs->rccr);
  868. rccr_reg_val &= ~SCG_CCR_SCS_MASK;
  869. rccr_reg_val |= (clk << SCG_CCR_SCS_SHIFT);
  870. writel(rccr_reg_val, &scg1_regs->rccr);
  871. }
  872. void scg_a7_info(void)
  873. {
  874. debug("SCG Version: 0x%x\n", readl(&scg1_regs->verid));
  875. debug("SCG Parameter: 0x%x\n", readl(&scg1_regs->param));
  876. debug("SCG RCCR Value: 0x%x\n", readl(&scg1_regs->rccr));
  877. debug("SCG Clock Status: 0x%x\n", readl(&scg1_regs->csr));
  878. }