clock.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. /*
  2. * (C) Copyright 2013
  3. * NVIDIA Corporation <www.nvidia.com>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. /* Tegra124 Clock control functions */
  8. #include <common.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/clock.h>
  11. #include <asm/arch/sysctr.h>
  12. #include <asm/arch/tegra.h>
  13. #include <asm/arch-tegra/clk_rst.h>
  14. #include <asm/arch-tegra/timer.h>
  15. #include <div64.h>
  16. #include <fdtdec.h>
  17. /*
  18. * Clock types that we can use as a source. The Tegra124 has muxes for the
  19. * peripheral clocks, and in most cases there are four options for the clock
  20. * source. This gives us a clock 'type' and exploits what commonality exists
  21. * in the device.
  22. *
  23. * Letters are obvious, except for T which means CLK_M, and S which means the
  24. * clock derived from 32KHz. Beware that CLK_M (also called OSC in the
  25. * datasheet) and PLL_M are different things. The former is the basic
  26. * clock supplied to the SOC from an external oscillator. The latter is the
  27. * memory clock PLL.
  28. *
  29. * See definitions in clock_id in the header file.
  30. */
  31. enum clock_type_id {
  32. CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */
  33. CLOCK_TYPE_MCPA, /* and so on */
  34. CLOCK_TYPE_MCPT,
  35. CLOCK_TYPE_PCM,
  36. CLOCK_TYPE_PCMT,
  37. CLOCK_TYPE_PDCT,
  38. CLOCK_TYPE_ACPT,
  39. CLOCK_TYPE_ASPTE,
  40. CLOCK_TYPE_PMDACD2T,
  41. CLOCK_TYPE_PCST,
  42. CLOCK_TYPE_PC2CC3M,
  43. CLOCK_TYPE_PC2CC3S_T,
  44. CLOCK_TYPE_PC2CC3M_T,
  45. CLOCK_TYPE_PC2CC3M_T16, /* PC2CC3M_T, but w/16-bit divisor (I2C) */
  46. CLOCK_TYPE_MC2CC3P_A,
  47. CLOCK_TYPE_M,
  48. CLOCK_TYPE_MCPTM2C2C3,
  49. CLOCK_TYPE_PC2CC3T_S,
  50. CLOCK_TYPE_AC2CC3P_TS2,
  51. CLOCK_TYPE_COUNT,
  52. CLOCK_TYPE_NONE = -1, /* invalid clock type */
  53. };
  54. enum {
  55. CLOCK_MAX_MUX = 8 /* number of source options for each clock */
  56. };
  57. /*
  58. * Clock source mux for each clock type. This just converts our enum into
  59. * a list of mux sources for use by the code.
  60. *
  61. * Note:
  62. * The extra column in each clock source array is used to store the mask
  63. * bits in its register for the source.
  64. */
  65. #define CLK(x) CLOCK_ID_ ## x
  66. static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = {
  67. { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC),
  68. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  69. MASK_BITS_31_30},
  70. { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO),
  71. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  72. MASK_BITS_31_30},
  73. { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
  74. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  75. MASK_BITS_31_30},
  76. { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE),
  77. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  78. MASK_BITS_31_30},
  79. { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC),
  80. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  81. MASK_BITS_31_30},
  82. { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC),
  83. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  84. MASK_BITS_31_30},
  85. { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
  86. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  87. MASK_BITS_31_30},
  88. { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC),
  89. CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE),
  90. MASK_BITS_31_29},
  91. { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO),
  92. CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE),
  93. MASK_BITS_31_29},
  94. { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC),
  95. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  96. MASK_BITS_31_28},
  97. /* Additional clock types on Tegra114+ */
  98. /* CLOCK_TYPE_PC2CC3M */
  99. { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
  100. CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE),
  101. MASK_BITS_31_29},
  102. /* CLOCK_TYPE_PC2CC3S_T */
  103. { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
  104. CLK(SFROM32KHZ), CLK(NONE), CLK(OSC), CLK(NONE),
  105. MASK_BITS_31_29},
  106. /* CLOCK_TYPE_PC2CC3M_T */
  107. { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
  108. CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE),
  109. MASK_BITS_31_29},
  110. /* CLOCK_TYPE_PC2CC3M_T, w/16-bit divisor (I2C) */
  111. { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
  112. CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE),
  113. MASK_BITS_31_29},
  114. /* CLOCK_TYPE_MC2CC3P_A */
  115. { CLK(MEMORY), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
  116. CLK(PERIPH), CLK(NONE), CLK(AUDIO), CLK(NONE),
  117. MASK_BITS_31_29},
  118. /* CLOCK_TYPE_M */
  119. { CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE),
  120. CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
  121. MASK_BITS_31_30},
  122. /* CLOCK_TYPE_MCPTM2C2C3 */
  123. { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
  124. CLK(MEMORY2), CLK(CGENERAL2), CLK(CGENERAL3), CLK(NONE),
  125. MASK_BITS_31_29},
  126. /* CLOCK_TYPE_PC2CC3T_S */
  127. { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
  128. CLK(OSC), CLK(NONE), CLK(SFROM32KHZ), CLK(NONE),
  129. MASK_BITS_31_29},
  130. /* CLOCK_TYPE_AC2CC3P_TS2 */
  131. { CLK(AUDIO), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
  132. CLK(PERIPH), CLK(NONE), CLK(OSC), CLK(SRC2),
  133. MASK_BITS_31_29},
  134. };
  135. /*
  136. * Clock type for each peripheral clock source. We put the name in each
  137. * record just so it is easy to match things up
  138. */
  139. #define TYPE(name, type) type
  140. static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
  141. /* 0x00 */
  142. TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT),
  143. TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT),
  144. TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT),
  145. TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PC2CC3M),
  146. TYPE(PERIPHC_PWM, CLOCK_TYPE_PC2CC3S_T),
  147. TYPE(PERIPHC_05h, CLOCK_TYPE_NONE),
  148. TYPE(PERIPHC_SBC2, CLOCK_TYPE_PC2CC3M_T),
  149. TYPE(PERIPHC_SBC3, CLOCK_TYPE_PC2CC3M_T),
  150. /* 0x08 */
  151. TYPE(PERIPHC_08h, CLOCK_TYPE_NONE),
  152. TYPE(PERIPHC_I2C1, CLOCK_TYPE_PC2CC3M_T16),
  153. TYPE(PERIPHC_I2C5, CLOCK_TYPE_PC2CC3M_T16),
  154. TYPE(PERIPHC_0bh, CLOCK_TYPE_NONE),
  155. TYPE(PERIPHC_0ch, CLOCK_TYPE_NONE),
  156. TYPE(PERIPHC_SBC1, CLOCK_TYPE_PC2CC3M_T),
  157. TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T),
  158. TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T),
  159. /* 0x10 */
  160. TYPE(PERIPHC_10h, CLOCK_TYPE_NONE),
  161. TYPE(PERIPHC_11h, CLOCK_TYPE_NONE),
  162. TYPE(PERIPHC_VI, CLOCK_TYPE_MC2CC3P_A),
  163. TYPE(PERIPHC_13h, CLOCK_TYPE_NONE),
  164. TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PC2CC3M_T),
  165. TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PC2CC3M_T),
  166. TYPE(PERIPHC_16h, CLOCK_TYPE_NONE),
  167. TYPE(PERIPHC_17h, CLOCK_TYPE_NONE),
  168. /* 0x18 */
  169. TYPE(PERIPHC_18h, CLOCK_TYPE_NONE),
  170. TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PC2CC3M_T),
  171. TYPE(PERIPHC_VFIR, CLOCK_TYPE_PC2CC3M_T),
  172. TYPE(PERIPHC_1Bh, CLOCK_TYPE_NONE),
  173. TYPE(PERIPHC_1Ch, CLOCK_TYPE_NONE),
  174. TYPE(PERIPHC_HSI, CLOCK_TYPE_PC2CC3M_T),
  175. TYPE(PERIPHC_UART1, CLOCK_TYPE_PC2CC3M_T),
  176. TYPE(PERIPHC_UART2, CLOCK_TYPE_PC2CC3M_T),
  177. /* 0x20 */
  178. TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MC2CC3P_A),
  179. TYPE(PERIPHC_21h, CLOCK_TYPE_NONE),
  180. TYPE(PERIPHC_22h, CLOCK_TYPE_NONE),
  181. TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T),
  182. TYPE(PERIPHC_24h, CLOCK_TYPE_NONE),
  183. TYPE(PERIPHC_25h, CLOCK_TYPE_NONE),
  184. TYPE(PERIPHC_I2C2, CLOCK_TYPE_PC2CC3M_T16),
  185. TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPTM2C2C3),
  186. /* 0x28 */
  187. TYPE(PERIPHC_UART3, CLOCK_TYPE_PC2CC3M_T),
  188. TYPE(PERIPHC_29h, CLOCK_TYPE_NONE),
  189. TYPE(PERIPHC_VI_SENSOR, CLOCK_TYPE_MC2CC3P_A),
  190. TYPE(PERIPHC_2bh, CLOCK_TYPE_NONE),
  191. TYPE(PERIPHC_2ch, CLOCK_TYPE_NONE),
  192. TYPE(PERIPHC_SBC4, CLOCK_TYPE_PC2CC3M_T),
  193. TYPE(PERIPHC_I2C3, CLOCK_TYPE_PC2CC3M_T16),
  194. TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PC2CC3M_T),
  195. /* 0x30 */
  196. TYPE(PERIPHC_UART4, CLOCK_TYPE_PC2CC3M_T),
  197. TYPE(PERIPHC_UART5, CLOCK_TYPE_PC2CC3M_T),
  198. TYPE(PERIPHC_VDE, CLOCK_TYPE_PC2CC3M_T),
  199. TYPE(PERIPHC_OWR, CLOCK_TYPE_PC2CC3M_T),
  200. TYPE(PERIPHC_NOR, CLOCK_TYPE_PC2CC3M_T),
  201. TYPE(PERIPHC_CSITE, CLOCK_TYPE_PC2CC3M_T),
  202. TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT),
  203. TYPE(PERIPHC_DTV, CLOCK_TYPE_NONE),
  204. /* 0x38 */
  205. TYPE(PERIPHC_38h, CLOCK_TYPE_NONE),
  206. TYPE(PERIPHC_39h, CLOCK_TYPE_NONE),
  207. TYPE(PERIPHC_3ah, CLOCK_TYPE_NONE),
  208. TYPE(PERIPHC_3bh, CLOCK_TYPE_NONE),
  209. TYPE(PERIPHC_MSENC, CLOCK_TYPE_MC2CC3P_A),
  210. TYPE(PERIPHC_TSEC, CLOCK_TYPE_PC2CC3M_T),
  211. TYPE(PERIPHC_3eh, CLOCK_TYPE_NONE),
  212. TYPE(PERIPHC_OSC, CLOCK_TYPE_NONE),
  213. /* 0x40 */
  214. TYPE(PERIPHC_40h, CLOCK_TYPE_NONE), /* start with 0x3b0 */
  215. TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PC2CC3M_T),
  216. TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PC2CC3T_S),
  217. TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT),
  218. TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT),
  219. TYPE(PERIPHC_I2C4, CLOCK_TYPE_PC2CC3M_T16),
  220. TYPE(PERIPHC_SBC5, CLOCK_TYPE_PC2CC3M_T),
  221. TYPE(PERIPHC_SBC6, CLOCK_TYPE_PC2CC3M_T),
  222. /* 0x48 */
  223. TYPE(PERIPHC_AUDIO, CLOCK_TYPE_AC2CC3P_TS2),
  224. TYPE(PERIPHC_49h, CLOCK_TYPE_NONE),
  225. TYPE(PERIPHC_DAM0, CLOCK_TYPE_AC2CC3P_TS2),
  226. TYPE(PERIPHC_DAM1, CLOCK_TYPE_AC2CC3P_TS2),
  227. TYPE(PERIPHC_DAM2, CLOCK_TYPE_AC2CC3P_TS2),
  228. TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PC2CC3M_T),
  229. TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PC2CC3S_T),
  230. TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE),
  231. /* 0x50 */
  232. TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE),
  233. TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE),
  234. TYPE(PERIPHC_52h, CLOCK_TYPE_NONE),
  235. TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PC2CC3S_T),
  236. TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE),
  237. TYPE(PERIPHC_55h, CLOCK_TYPE_NONE),
  238. TYPE(PERIPHC_56h, CLOCK_TYPE_NONE),
  239. TYPE(PERIPHC_57h, CLOCK_TYPE_NONE),
  240. /* 0x58 */
  241. TYPE(PERIPHC_58h, CLOCK_TYPE_NONE),
  242. TYPE(PERIPHC_59h, CLOCK_TYPE_NONE),
  243. TYPE(PERIPHC_5ah, CLOCK_TYPE_NONE),
  244. TYPE(PERIPHC_5bh, CLOCK_TYPE_NONE),
  245. TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT),
  246. TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT),
  247. TYPE(PERIPHC_HDA, CLOCK_TYPE_PC2CC3M_T),
  248. TYPE(PERIPHC_5fh, CLOCK_TYPE_NONE),
  249. /* 0x60 */
  250. TYPE(PERIPHC_XUSB_CORE_HOST, CLOCK_TYPE_NONE),
  251. TYPE(PERIPHC_XUSB_FALCON, CLOCK_TYPE_NONE),
  252. TYPE(PERIPHC_XUSB_FS, CLOCK_TYPE_NONE),
  253. TYPE(PERIPHC_XUSB_CORE_DEV, CLOCK_TYPE_NONE),
  254. TYPE(PERIPHC_XUSB_SS, CLOCK_TYPE_NONE),
  255. TYPE(PERIPHC_CILAB, CLOCK_TYPE_NONE),
  256. TYPE(PERIPHC_CILCD, CLOCK_TYPE_NONE),
  257. TYPE(PERIPHC_CILE, CLOCK_TYPE_NONE),
  258. /* 0x68 */
  259. TYPE(PERIPHC_DSIA_LP, CLOCK_TYPE_NONE),
  260. TYPE(PERIPHC_DSIB_LP, CLOCK_TYPE_NONE),
  261. TYPE(PERIPHC_ENTROPY, CLOCK_TYPE_NONE),
  262. TYPE(PERIPHC_DVFS_REF, CLOCK_TYPE_NONE),
  263. TYPE(PERIPHC_DVFS_SOC, CLOCK_TYPE_NONE),
  264. TYPE(PERIPHC_TRACECLKIN, CLOCK_TYPE_NONE),
  265. TYPE(PERIPHC_ADX0, CLOCK_TYPE_NONE),
  266. TYPE(PERIPHC_AMX0, CLOCK_TYPE_NONE),
  267. /* 0x70 */
  268. TYPE(PERIPHC_EMC_LATENCY, CLOCK_TYPE_NONE),
  269. TYPE(PERIPHC_SOC_THERM, CLOCK_TYPE_NONE),
  270. TYPE(PERIPHC_72h, CLOCK_TYPE_NONE),
  271. TYPE(PERIPHC_73h, CLOCK_TYPE_NONE),
  272. TYPE(PERIPHC_74h, CLOCK_TYPE_NONE),
  273. TYPE(PERIPHC_75h, CLOCK_TYPE_NONE),
  274. TYPE(PERIPHC_VI_SENSOR2, CLOCK_TYPE_NONE),
  275. TYPE(PERIPHC_I2C6, CLOCK_TYPE_PC2CC3M_T16),
  276. /* 0x78 */
  277. TYPE(PERIPHC_78h, CLOCK_TYPE_NONE),
  278. TYPE(PERIPHC_EMC_DLL, CLOCK_TYPE_MCPTM2C2C3),
  279. TYPE(PERIPHC_HDMI_AUDIO, CLOCK_TYPE_NONE),
  280. TYPE(PERIPHC_CLK72MHZ, CLOCK_TYPE_NONE),
  281. TYPE(PERIPHC_ADX1, CLOCK_TYPE_AC2CC3P_TS2),
  282. TYPE(PERIPHC_AMX1, CLOCK_TYPE_AC2CC3P_TS2),
  283. TYPE(PERIPHC_VIC, CLOCK_TYPE_NONE),
  284. TYPE(PERIPHC_7Fh, CLOCK_TYPE_NONE),
  285. };
  286. /*
  287. * This array translates a periph_id to a periphc_internal_id
  288. *
  289. * Not present/matched up:
  290. * uint vi_sensor; _VI_SENSOR_0, 0x1A8
  291. * SPDIF - which is both 0x08 and 0x0c
  292. *
  293. */
  294. #define NONE(name) (-1)
  295. #define OFFSET(name, value) PERIPHC_ ## name
  296. static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
  297. /* Low word: 31:0 */
  298. NONE(CPU),
  299. NONE(COP),
  300. NONE(TRIGSYS),
  301. NONE(ISPB),
  302. NONE(RESERVED4),
  303. NONE(TMR),
  304. PERIPHC_UART1,
  305. PERIPHC_UART2, /* and vfir 0x68 */
  306. /* 8 */
  307. NONE(GPIO),
  308. PERIPHC_SDMMC2,
  309. PERIPHC_SPDIF_IN,
  310. PERIPHC_I2S1,
  311. PERIPHC_I2C1,
  312. NONE(RESERVED13),
  313. PERIPHC_SDMMC1,
  314. PERIPHC_SDMMC4,
  315. /* 16 */
  316. NONE(TCW),
  317. PERIPHC_PWM,
  318. PERIPHC_I2S2,
  319. NONE(RESERVED19),
  320. PERIPHC_VI,
  321. NONE(RESERVED21),
  322. NONE(USBD),
  323. NONE(ISP),
  324. /* 24 */
  325. NONE(RESERVED24),
  326. NONE(RESERVED25),
  327. PERIPHC_DISP2,
  328. PERIPHC_DISP1,
  329. PERIPHC_HOST1X,
  330. NONE(VCP),
  331. PERIPHC_I2S0,
  332. NONE(CACHE2),
  333. /* Middle word: 63:32 */
  334. NONE(MEM),
  335. NONE(AHBDMA),
  336. NONE(APBDMA),
  337. NONE(RESERVED35),
  338. NONE(RESERVED36),
  339. NONE(STAT_MON),
  340. NONE(RESERVED38),
  341. NONE(FUSE),
  342. /* 40 */
  343. NONE(KFUSE),
  344. PERIPHC_SBC1, /* SBCx = SPIx */
  345. PERIPHC_NOR,
  346. NONE(RESERVED43),
  347. PERIPHC_SBC2,
  348. NONE(XIO),
  349. PERIPHC_SBC3,
  350. PERIPHC_I2C5,
  351. /* 48 */
  352. NONE(DSI),
  353. NONE(RESERVED49),
  354. PERIPHC_HSI,
  355. PERIPHC_HDMI,
  356. NONE(CSI),
  357. NONE(RESERVED53),
  358. PERIPHC_I2C2,
  359. PERIPHC_UART3,
  360. /* 56 */
  361. NONE(MIPI_CAL),
  362. PERIPHC_EMC,
  363. NONE(USB2),
  364. NONE(USB3),
  365. NONE(RESERVED60),
  366. PERIPHC_VDE,
  367. NONE(BSEA),
  368. NONE(BSEV),
  369. /* Upper word 95:64 */
  370. NONE(RESERVED64),
  371. PERIPHC_UART4,
  372. PERIPHC_UART5,
  373. PERIPHC_I2C3,
  374. PERIPHC_SBC4,
  375. PERIPHC_SDMMC3,
  376. NONE(PCIE),
  377. PERIPHC_OWR,
  378. /* 72 */
  379. NONE(AFI),
  380. PERIPHC_CSITE,
  381. NONE(PCIEXCLK),
  382. NONE(AVPUCQ),
  383. NONE(LA),
  384. NONE(TRACECLKIN),
  385. NONE(SOC_THERM),
  386. NONE(DTV),
  387. /* 80 */
  388. NONE(RESERVED80),
  389. PERIPHC_I2CSLOW,
  390. NONE(DSIB),
  391. PERIPHC_TSEC,
  392. NONE(RESERVED84),
  393. NONE(RESERVED85),
  394. NONE(RESERVED86),
  395. NONE(EMUCIF),
  396. /* 88 */
  397. NONE(RESERVED88),
  398. NONE(XUSB_HOST),
  399. NONE(RESERVED90),
  400. PERIPHC_MSENC,
  401. NONE(RESERVED92),
  402. NONE(RESERVED93),
  403. NONE(RESERVED94),
  404. NONE(XUSB_DEV),
  405. /* V word: 31:0 */
  406. NONE(CPUG),
  407. NONE(CPULP),
  408. NONE(V_RESERVED2),
  409. PERIPHC_MSELECT,
  410. NONE(V_RESERVED4),
  411. PERIPHC_I2S3,
  412. PERIPHC_I2S4,
  413. PERIPHC_I2C4,
  414. /* 104 */
  415. PERIPHC_SBC5,
  416. PERIPHC_SBC6,
  417. PERIPHC_AUDIO,
  418. NONE(APBIF),
  419. PERIPHC_DAM0,
  420. PERIPHC_DAM1,
  421. PERIPHC_DAM2,
  422. PERIPHC_HDA2CODEC2X,
  423. /* 112 */
  424. NONE(ATOMICS),
  425. NONE(V_RESERVED17),
  426. NONE(V_RESERVED18),
  427. NONE(V_RESERVED19),
  428. NONE(V_RESERVED20),
  429. NONE(V_RESERVED21),
  430. NONE(V_RESERVED22),
  431. PERIPHC_ACTMON,
  432. /* 120 */
  433. NONE(EXTPERIPH1),
  434. NONE(EXTPERIPH2),
  435. NONE(EXTPERIPH3),
  436. NONE(OOB),
  437. PERIPHC_SATA,
  438. PERIPHC_HDA,
  439. NONE(TZRAM),
  440. NONE(SE),
  441. /* W word: 31:0 */
  442. NONE(HDA2HDMICODEC),
  443. NONE(SATACOLD),
  444. NONE(W_RESERVED2),
  445. NONE(W_RESERVED3),
  446. NONE(W_RESERVED4),
  447. NONE(W_RESERVED5),
  448. NONE(W_RESERVED6),
  449. NONE(W_RESERVED7),
  450. /* 136 */
  451. NONE(CEC),
  452. NONE(W_RESERVED9),
  453. NONE(W_RESERVED10),
  454. NONE(W_RESERVED11),
  455. NONE(W_RESERVED12),
  456. NONE(W_RESERVED13),
  457. NONE(XUSB_PADCTL),
  458. NONE(W_RESERVED15),
  459. /* 144 */
  460. NONE(W_RESERVED16),
  461. NONE(W_RESERVED17),
  462. NONE(W_RESERVED18),
  463. NONE(W_RESERVED19),
  464. NONE(W_RESERVED20),
  465. NONE(ENTROPY),
  466. NONE(DDS),
  467. NONE(W_RESERVED23),
  468. /* 152 */
  469. NONE(DP2),
  470. NONE(AMX0),
  471. NONE(ADX0),
  472. NONE(DVFS),
  473. NONE(XUSB_SS),
  474. NONE(W_RESERVED29),
  475. NONE(W_RESERVED30),
  476. NONE(W_RESERVED31),
  477. /* X word: 31:0 */
  478. NONE(SPARE),
  479. NONE(X_RESERVED1),
  480. NONE(X_RESERVED2),
  481. NONE(X_RESERVED3),
  482. NONE(CAM_MCLK),
  483. NONE(CAM_MCLK2),
  484. PERIPHC_I2C6,
  485. NONE(X_RESERVED7),
  486. /* 168 */
  487. NONE(X_RESERVED8),
  488. NONE(X_RESERVED9),
  489. NONE(X_RESERVED10),
  490. NONE(VIM2_CLK),
  491. NONE(X_RESERVED12),
  492. NONE(X_RESERVED13),
  493. NONE(EMC_DLL),
  494. NONE(X_RESERVED15),
  495. /* 176 */
  496. NONE(HDMI_AUDIO),
  497. NONE(CLK72MHZ),
  498. NONE(VIC),
  499. NONE(X_RESERVED19),
  500. NONE(ADX1),
  501. NONE(DPAUX),
  502. NONE(SOR0),
  503. NONE(X_RESERVED23),
  504. /* 184 */
  505. NONE(GPU),
  506. NONE(AMX1),
  507. NONE(X_RESERVED26),
  508. NONE(X_RESERVED27),
  509. NONE(X_RESERVED28),
  510. NONE(X_RESERVED29),
  511. NONE(X_RESERVED30),
  512. NONE(X_RESERVED31),
  513. };
  514. /*
  515. * Get the oscillator frequency, from the corresponding hardware configuration
  516. * field. Note that Tegra30+ support 3 new higher freqs, but we map back
  517. * to the old T20 freqs. Support for the higher oscillators is TBD.
  518. */
  519. enum clock_osc_freq clock_get_osc_freq(void)
  520. {
  521. struct clk_rst_ctlr *clkrst =
  522. (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
  523. u32 reg;
  524. reg = readl(&clkrst->crc_osc_ctrl);
  525. reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
  526. if (reg & 1) /* one of the newer freqs */
  527. printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg);
  528. return reg >> 2; /* Map to most common (T20) freqs */
  529. }
  530. /* Returns a pointer to the clock source register for a peripheral */
  531. u32 *get_periph_source_reg(enum periph_id periph_id)
  532. {
  533. struct clk_rst_ctlr *clkrst =
  534. (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
  535. enum periphc_internal_id internal_id;
  536. /* Coresight is a special case */
  537. if (periph_id == PERIPH_ID_CSI)
  538. return &clkrst->crc_clk_src[PERIPH_ID_CSI+1];
  539. assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT);
  540. internal_id = periph_id_to_internal_id[periph_id];
  541. assert(internal_id != -1);
  542. if (internal_id >= PERIPHC_VW_FIRST) {
  543. internal_id -= PERIPHC_VW_FIRST;
  544. return &clkrst->crc_clk_src_vw[internal_id];
  545. } else {
  546. return &clkrst->crc_clk_src[internal_id];
  547. }
  548. }
  549. /**
  550. * Given a peripheral ID and the required source clock, this returns which
  551. * value should be programmed into the source mux for that peripheral.
  552. *
  553. * There is special code here to handle the one source type with 5 sources.
  554. *
  555. * @param periph_id peripheral to start
  556. * @param source PLL id of required parent clock
  557. * @param mux_bits Set to number of bits in mux register: 2 or 4
  558. * @param divider_bits Set to number of divider bits (8 or 16)
  559. * @return mux value (0-4, or -1 if not found)
  560. */
  561. int get_periph_clock_source(enum periph_id periph_id,
  562. enum clock_id parent, int *mux_bits, int *divider_bits)
  563. {
  564. enum clock_type_id type;
  565. enum periphc_internal_id internal_id;
  566. int mux;
  567. assert(clock_periph_id_isvalid(periph_id));
  568. internal_id = periph_id_to_internal_id[periph_id];
  569. assert(periphc_internal_id_isvalid(internal_id));
  570. type = clock_periph_type[internal_id];
  571. assert(clock_type_id_isvalid(type));
  572. *mux_bits = clock_source[type][CLOCK_MAX_MUX];
  573. if (type == CLOCK_TYPE_PC2CC3M_T16)
  574. *divider_bits = 16;
  575. else
  576. *divider_bits = 8;
  577. for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
  578. if (clock_source[type][mux] == parent)
  579. return mux;
  580. /* if we get here, either us or the caller has made a mistake */
  581. printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
  582. parent);
  583. return -1;
  584. }
  585. void clock_set_enable(enum periph_id periph_id, int enable)
  586. {
  587. struct clk_rst_ctlr *clkrst =
  588. (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
  589. u32 *clk;
  590. u32 reg;
  591. /* Enable/disable the clock to this peripheral */
  592. assert(clock_periph_id_isvalid(periph_id));
  593. if ((int)periph_id < (int)PERIPH_ID_VW_FIRST)
  594. clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
  595. else
  596. clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)];
  597. reg = readl(clk);
  598. if (enable)
  599. reg |= PERIPH_MASK(periph_id);
  600. else
  601. reg &= ~PERIPH_MASK(periph_id);
  602. writel(reg, clk);
  603. }
  604. void reset_set_enable(enum periph_id periph_id, int enable)
  605. {
  606. struct clk_rst_ctlr *clkrst =
  607. (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
  608. u32 *reset;
  609. u32 reg;
  610. /* Enable/disable reset to the peripheral */
  611. assert(clock_periph_id_isvalid(periph_id));
  612. if (periph_id < PERIPH_ID_VW_FIRST)
  613. reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
  614. else
  615. reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)];
  616. reg = readl(reset);
  617. if (enable)
  618. reg |= PERIPH_MASK(periph_id);
  619. else
  620. reg &= ~PERIPH_MASK(periph_id);
  621. writel(reg, reset);
  622. }
  623. #ifdef CONFIG_OF_CONTROL
  624. /*
  625. * Convert a device tree clock ID to our peripheral ID. They are mostly
  626. * the same but we are very cautious so we check that a valid clock ID is
  627. * provided.
  628. *
  629. * @param clk_id Clock ID according to tegra124 device tree binding
  630. * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
  631. */
  632. enum periph_id clk_id_to_periph_id(int clk_id)
  633. {
  634. if (clk_id > PERIPH_ID_COUNT)
  635. return PERIPH_ID_NONE;
  636. switch (clk_id) {
  637. case PERIPH_ID_RESERVED4:
  638. case PERIPH_ID_RESERVED25:
  639. case PERIPH_ID_RESERVED35:
  640. case PERIPH_ID_RESERVED36:
  641. case PERIPH_ID_RESERVED38:
  642. case PERIPH_ID_RESERVED43:
  643. case PERIPH_ID_RESERVED49:
  644. case PERIPH_ID_RESERVED53:
  645. case PERIPH_ID_RESERVED64:
  646. case PERIPH_ID_RESERVED84:
  647. case PERIPH_ID_RESERVED85:
  648. case PERIPH_ID_RESERVED86:
  649. case PERIPH_ID_RESERVED88:
  650. case PERIPH_ID_RESERVED90:
  651. case PERIPH_ID_RESERVED92:
  652. case PERIPH_ID_RESERVED93:
  653. case PERIPH_ID_RESERVED94:
  654. case PERIPH_ID_V_RESERVED2:
  655. case PERIPH_ID_V_RESERVED4:
  656. case PERIPH_ID_V_RESERVED17:
  657. case PERIPH_ID_V_RESERVED18:
  658. case PERIPH_ID_V_RESERVED19:
  659. case PERIPH_ID_V_RESERVED20:
  660. case PERIPH_ID_V_RESERVED21:
  661. case PERIPH_ID_V_RESERVED22:
  662. case PERIPH_ID_W_RESERVED2:
  663. case PERIPH_ID_W_RESERVED3:
  664. case PERIPH_ID_W_RESERVED4:
  665. case PERIPH_ID_W_RESERVED5:
  666. case PERIPH_ID_W_RESERVED6:
  667. case PERIPH_ID_W_RESERVED7:
  668. case PERIPH_ID_W_RESERVED9:
  669. case PERIPH_ID_W_RESERVED10:
  670. case PERIPH_ID_W_RESERVED11:
  671. case PERIPH_ID_W_RESERVED12:
  672. case PERIPH_ID_W_RESERVED13:
  673. case PERIPH_ID_W_RESERVED15:
  674. case PERIPH_ID_W_RESERVED16:
  675. case PERIPH_ID_W_RESERVED17:
  676. case PERIPH_ID_W_RESERVED18:
  677. case PERIPH_ID_W_RESERVED19:
  678. case PERIPH_ID_W_RESERVED20:
  679. case PERIPH_ID_W_RESERVED23:
  680. case PERIPH_ID_W_RESERVED29:
  681. case PERIPH_ID_W_RESERVED30:
  682. case PERIPH_ID_W_RESERVED31:
  683. return PERIPH_ID_NONE;
  684. default:
  685. return clk_id;
  686. }
  687. }
  688. #endif /* CONFIG_OF_CONTROL */
  689. void clock_early_init(void)
  690. {
  691. struct clk_rst_ctlr *clkrst =
  692. (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
  693. tegra30_set_up_pllp();
  694. /*
  695. * PLLC output frequency set to 600Mhz
  696. * PLLD output frequency set to 925Mhz
  697. */
  698. switch (clock_get_osc_freq()) {
  699. case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
  700. clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
  701. clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12);
  702. break;
  703. case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
  704. clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
  705. clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12);
  706. break;
  707. case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
  708. clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
  709. clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12);
  710. break;
  711. case CLOCK_OSC_FREQ_19_2:
  712. default:
  713. /*
  714. * These are not supported. It is too early to print a
  715. * message and the UART likely won't work anyway due to the
  716. * oscillator being wrong.
  717. */
  718. break;
  719. }
  720. /* PLLC_MISC2: Set dynramp_stepA/B. MISC2 maps to pll_out[1] */
  721. writel(0x00561600, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1]);
  722. /* PLLC_MISC: Set LOCK_ENABLE */
  723. writel(0x01000000, &clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc);
  724. udelay(2);
  725. /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1 */
  726. writel(0x40000C10, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc);
  727. udelay(2);
  728. }
  729. void arch_timer_init(void)
  730. {
  731. struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE;
  732. u32 freq, val;
  733. freq = clock_get_rate(CLOCK_ID_OSC);
  734. debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq);
  735. /* ARM CNTFRQ */
  736. asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq));
  737. /* Only Tegra114+ has the System Counter regs */
  738. debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq);
  739. writel(freq, &sysctr->cntfid0);
  740. val = readl(&sysctr->cntcr);
  741. val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG;
  742. writel(val, &sysctr->cntcr);
  743. debug("%s: TSC CNTCR = 0x%08X\n", __func__, val);
  744. }
  745. #define PLLE_SS_CNTL 0x68
  746. #define PLLE_SS_CNTL_SSCINCINTR(x) (((x) & 0x3f) << 24)
  747. #define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16)
  748. #define PLLE_SS_CNTL_SSCINVERT (1 << 15)
  749. #define PLLE_SS_CNTL_SSCCENTER (1 << 14)
  750. #define PLLE_SS_CNTL_SSCBYP (1 << 12)
  751. #define PLLE_SS_CNTL_INTERP_RESET (1 << 11)
  752. #define PLLE_SS_CNTL_BYPASS_SS (1 << 10)
  753. #define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0)
  754. #define PLLE_BASE 0x0e8
  755. #define PLLE_BASE_ENABLE (1 << 30)
  756. #define PLLE_BASE_LOCK_OVERRIDE (1 << 29)
  757. #define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24)
  758. #define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8)
  759. #define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0)
  760. #define PLLE_MISC 0x0ec
  761. #define PLLE_MISC_IDDQ_SWCTL (1 << 14)
  762. #define PLLE_MISC_IDDQ_OVERRIDE (1 << 13)
  763. #define PLLE_MISC_LOCK_ENABLE (1 << 9)
  764. #define PLLE_MISC_PTS (1 << 8)
  765. #define PLLE_MISC_VREG_BG_CTRL(x) (((x) & 0x3) << 4)
  766. #define PLLE_MISC_VREG_CTRL(x) (((x) & 0x3) << 2)
  767. #define PLLE_AUX 0x48c
  768. #define PLLE_AUX_SEQ_ENABLE (1 << 24)
  769. #define PLLE_AUX_ENABLE_SWCTL (1 << 4)
  770. int tegra_plle_enable(void)
  771. {
  772. unsigned int m = 1, n = 200, cpcon = 13;
  773. u32 value;
  774. value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
  775. value &= ~PLLE_BASE_LOCK_OVERRIDE;
  776. writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
  777. value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX);
  778. value |= PLLE_AUX_ENABLE_SWCTL;
  779. value &= ~PLLE_AUX_SEQ_ENABLE;
  780. writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX);
  781. udelay(1);
  782. value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
  783. value |= PLLE_MISC_IDDQ_SWCTL;
  784. value &= ~PLLE_MISC_IDDQ_OVERRIDE;
  785. value |= PLLE_MISC_LOCK_ENABLE;
  786. value |= PLLE_MISC_PTS;
  787. value |= PLLE_MISC_VREG_BG_CTRL(3);
  788. value |= PLLE_MISC_VREG_CTRL(2);
  789. writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC);
  790. udelay(5);
  791. value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  792. value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET |
  793. PLLE_SS_CNTL_BYPASS_SS;
  794. writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  795. value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
  796. value &= ~PLLE_BASE_PLDIV_CML(0xf);
  797. value &= ~PLLE_BASE_NDIV(0xff);
  798. value &= ~PLLE_BASE_MDIV(0xff);
  799. value |= PLLE_BASE_PLDIV_CML(cpcon);
  800. value |= PLLE_BASE_NDIV(n);
  801. value |= PLLE_BASE_MDIV(m);
  802. writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
  803. udelay(1);
  804. value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
  805. value |= PLLE_BASE_ENABLE;
  806. writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
  807. /* wait for lock */
  808. udelay(300);
  809. value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  810. value &= ~PLLE_SS_CNTL_SSCINVERT;
  811. value &= ~PLLE_SS_CNTL_SSCCENTER;
  812. value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f);
  813. value &= ~PLLE_SS_CNTL_SSCINC(0xff);
  814. value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff);
  815. value |= PLLE_SS_CNTL_SSCINCINTR(0x20);
  816. value |= PLLE_SS_CNTL_SSCINC(0x01);
  817. value |= PLLE_SS_CNTL_SSCMAX(0x25);
  818. writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  819. value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  820. value &= ~PLLE_SS_CNTL_SSCBYP;
  821. value &= ~PLLE_SS_CNTL_BYPASS_SS;
  822. writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  823. udelay(1);
  824. value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  825. value &= ~PLLE_SS_CNTL_INTERP_RESET;
  826. writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
  827. udelay(1);
  828. return 0;
  829. }