scg.c 25 KB

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