clock_init_exynos5.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Clock setup for SMDK5250 board based on EXYNOS5
  4. *
  5. * Copyright (C) 2012 Samsung Electronics
  6. */
  7. #include <common.h>
  8. #include <config.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/clk.h>
  11. #include <asm/arch/clock.h>
  12. #include <asm/arch/spl.h>
  13. #include <asm/arch/dwmmc.h>
  14. #include "clock_init.h"
  15. #include "common_setup.h"
  16. #include "exynos5_setup.h"
  17. #define FSYS1_MMC0_DIV_MASK 0xff0f
  18. #define FSYS1_MMC0_DIV_VAL 0x0701
  19. struct arm_clk_ratios arm_clk_ratios[] = {
  20. #ifdef CONFIG_EXYNOS5420
  21. {
  22. .arm_freq_mhz = 900,
  23. .apll_mdiv = 0x96,
  24. .apll_pdiv = 0x2,
  25. .apll_sdiv = 0x1,
  26. .arm2_ratio = 0x0,
  27. .apll_ratio = 0x3,
  28. .pclk_dbg_ratio = 0x6,
  29. .atb_ratio = 0x6,
  30. .periph_ratio = 0x7,
  31. .acp_ratio = 0x0,
  32. .cpud_ratio = 0x2,
  33. .arm_ratio = 0x0,
  34. }
  35. #else
  36. {
  37. .arm_freq_mhz = 600,
  38. .apll_mdiv = 0xc8,
  39. .apll_pdiv = 0x4,
  40. .apll_sdiv = 0x1,
  41. .arm2_ratio = 0x0,
  42. .apll_ratio = 0x1,
  43. .pclk_dbg_ratio = 0x1,
  44. .atb_ratio = 0x2,
  45. .periph_ratio = 0x7,
  46. .acp_ratio = 0x7,
  47. .cpud_ratio = 0x1,
  48. .arm_ratio = 0x0,
  49. }, {
  50. .arm_freq_mhz = 800,
  51. .apll_mdiv = 0x64,
  52. .apll_pdiv = 0x3,
  53. .apll_sdiv = 0x0,
  54. .arm2_ratio = 0x0,
  55. .apll_ratio = 0x1,
  56. .pclk_dbg_ratio = 0x1,
  57. .atb_ratio = 0x3,
  58. .periph_ratio = 0x7,
  59. .acp_ratio = 0x7,
  60. .cpud_ratio = 0x2,
  61. .arm_ratio = 0x0,
  62. }, {
  63. .arm_freq_mhz = 1000,
  64. .apll_mdiv = 0x7d,
  65. .apll_pdiv = 0x3,
  66. .apll_sdiv = 0x0,
  67. .arm2_ratio = 0x0,
  68. .apll_ratio = 0x1,
  69. .pclk_dbg_ratio = 0x1,
  70. .atb_ratio = 0x4,
  71. .periph_ratio = 0x7,
  72. .acp_ratio = 0x7,
  73. .cpud_ratio = 0x2,
  74. .arm_ratio = 0x0,
  75. }, {
  76. .arm_freq_mhz = 1200,
  77. .apll_mdiv = 0x96,
  78. .apll_pdiv = 0x3,
  79. .apll_sdiv = 0x0,
  80. .arm2_ratio = 0x0,
  81. .apll_ratio = 0x3,
  82. .pclk_dbg_ratio = 0x1,
  83. .atb_ratio = 0x5,
  84. .periph_ratio = 0x7,
  85. .acp_ratio = 0x7,
  86. .cpud_ratio = 0x3,
  87. .arm_ratio = 0x0,
  88. }, {
  89. .arm_freq_mhz = 1400,
  90. .apll_mdiv = 0xaf,
  91. .apll_pdiv = 0x3,
  92. .apll_sdiv = 0x0,
  93. .arm2_ratio = 0x0,
  94. .apll_ratio = 0x3,
  95. .pclk_dbg_ratio = 0x1,
  96. .atb_ratio = 0x6,
  97. .periph_ratio = 0x7,
  98. .acp_ratio = 0x7,
  99. .cpud_ratio = 0x3,
  100. .arm_ratio = 0x0,
  101. }, {
  102. .arm_freq_mhz = 1700,
  103. .apll_mdiv = 0x1a9,
  104. .apll_pdiv = 0x6,
  105. .apll_sdiv = 0x0,
  106. .arm2_ratio = 0x0,
  107. .apll_ratio = 0x3,
  108. .pclk_dbg_ratio = 0x1,
  109. .atb_ratio = 0x6,
  110. .periph_ratio = 0x7,
  111. .acp_ratio = 0x7,
  112. .cpud_ratio = 0x3,
  113. .arm_ratio = 0x0,
  114. }
  115. #endif
  116. };
  117. struct mem_timings mem_timings[] = {
  118. #ifdef CONFIG_EXYNOS5420
  119. {
  120. .mem_manuf = MEM_MANUF_SAMSUNG,
  121. .mem_type = DDR_MODE_DDR3,
  122. .frequency_mhz = 800,
  123. /* MPLL @800MHz*/
  124. .mpll_mdiv = 0xc8,
  125. .mpll_pdiv = 0x3,
  126. .mpll_sdiv = 0x1,
  127. /* CPLL @666MHz */
  128. .cpll_mdiv = 0xde,
  129. .cpll_pdiv = 0x4,
  130. .cpll_sdiv = 0x1,
  131. /* EPLL @600MHz */
  132. .epll_mdiv = 0x64,
  133. .epll_pdiv = 0x2,
  134. .epll_sdiv = 0x1,
  135. /* VPLL @430MHz */
  136. .vpll_mdiv = 0xd7,
  137. .vpll_pdiv = 0x3,
  138. .vpll_sdiv = 0x2,
  139. /* BPLL @800MHz */
  140. .bpll_mdiv = 0xc8,
  141. .bpll_pdiv = 0x3,
  142. .bpll_sdiv = 0x1,
  143. /* KPLL @600MHz */
  144. .kpll_mdiv = 0x190,
  145. .kpll_pdiv = 0x4,
  146. .kpll_sdiv = 0x2,
  147. /* DPLL @600MHz */
  148. .dpll_mdiv = 0x190,
  149. .dpll_pdiv = 0x4,
  150. .dpll_sdiv = 0x2,
  151. /* IPLL @370MHz */
  152. .ipll_mdiv = 0xb9,
  153. .ipll_pdiv = 0x3,
  154. .ipll_sdiv = 0x2,
  155. /* SPLL @400MHz */
  156. .spll_mdiv = 0xc8,
  157. .spll_pdiv = 0x3,
  158. .spll_sdiv = 0x2,
  159. /* RPLL @141Mhz */
  160. .rpll_mdiv = 0x5E,
  161. .rpll_pdiv = 0x2,
  162. .rpll_sdiv = 0x3,
  163. .direct_cmd_msr = {
  164. 0x00020018, 0x00030000, 0x00010046, 0x00000d70,
  165. 0x00000c70
  166. },
  167. .timing_ref = 0x000000bb,
  168. .timing_row = 0x6836650f,
  169. .timing_data = 0x3630580b,
  170. .timing_power = 0x41000a26,
  171. .phy0_dqs = 0x08080808,
  172. .phy1_dqs = 0x08080808,
  173. .phy0_dq = 0x08080808,
  174. .phy1_dq = 0x08080808,
  175. .phy0_tFS = 0x8,
  176. .phy1_tFS = 0x8,
  177. .phy0_pulld_dqs = 0xf,
  178. .phy1_pulld_dqs = 0xf,
  179. .lpddr3_ctrl_phy_reset = 0x1,
  180. .ctrl_start_point = 0x10,
  181. .ctrl_inc = 0x10,
  182. .ctrl_start = 0x1,
  183. .ctrl_dll_on = 0x1,
  184. .ctrl_ref = 0x8,
  185. .ctrl_force = 0x1a,
  186. .ctrl_rdlat = 0x0b,
  187. .ctrl_bstlen = 0x08,
  188. .fp_resync = 0x8,
  189. .iv_size = 0x7,
  190. .dfi_init_start = 1,
  191. .aref_en = 1,
  192. .rd_fetch = 0x3,
  193. .zq_mode_dds = 0x7,
  194. .zq_mode_term = 0x1,
  195. .zq_mode_noterm = 1,
  196. /*
  197. * Dynamic Clock: Always Running
  198. * Memory Burst length: 8
  199. * Number of chips: 1
  200. * Memory Bus width: 32 bit
  201. * Memory Type: DDR3
  202. * Additional Latancy for PLL: 0 Cycle
  203. */
  204. .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
  205. DMC_MEMCONTROL_DPWRDN_DISABLE |
  206. DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
  207. DMC_MEMCONTROL_TP_DISABLE |
  208. DMC_MEMCONTROL_DSREF_DISABLE |
  209. DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
  210. DMC_MEMCONTROL_MEM_TYPE_DDR3 |
  211. DMC_MEMCONTROL_MEM_WIDTH_32BIT |
  212. DMC_MEMCONTROL_NUM_CHIP_1 |
  213. DMC_MEMCONTROL_BL_8 |
  214. DMC_MEMCONTROL_PZQ_DISABLE |
  215. DMC_MEMCONTROL_MRR_BYTE_7_0,
  216. .memconfig = DMC_MEMCONFIG_CHIP_MAP_SPLIT |
  217. DMC_MEMCONFIGX_CHIP_COL_10 |
  218. DMC_MEMCONFIGX_CHIP_ROW_15 |
  219. DMC_MEMCONFIGX_CHIP_BANK_8,
  220. .prechconfig_tp_cnt = 0xff,
  221. .dpwrdn_cyc = 0xff,
  222. .dsref_cyc = 0xffff,
  223. .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
  224. DMC_CONCONTROL_TIMEOUT_LEVEL0 |
  225. DMC_CONCONTROL_RD_FETCH_DISABLE |
  226. DMC_CONCONTROL_EMPTY_DISABLE |
  227. DMC_CONCONTROL_AREF_EN_DISABLE |
  228. DMC_CONCONTROL_IO_PD_CON_DISABLE,
  229. .dmc_channels = 1,
  230. .chips_per_channel = 1,
  231. .chips_to_configure = 1,
  232. .send_zq_init = 1,
  233. .gate_leveling_enable = 1,
  234. .read_leveling_enable = 0,
  235. }
  236. #else
  237. {
  238. .mem_manuf = MEM_MANUF_ELPIDA,
  239. .mem_type = DDR_MODE_DDR3,
  240. .frequency_mhz = 800,
  241. .mpll_mdiv = 0xc8,
  242. .mpll_pdiv = 0x3,
  243. .mpll_sdiv = 0x0,
  244. .cpll_mdiv = 0xde,
  245. .cpll_pdiv = 0x4,
  246. .cpll_sdiv = 0x2,
  247. .gpll_mdiv = 0x215,
  248. .gpll_pdiv = 0xc,
  249. .gpll_sdiv = 0x1,
  250. .epll_mdiv = 0x60,
  251. .epll_pdiv = 0x3,
  252. .epll_sdiv = 0x3,
  253. .vpll_mdiv = 0x96,
  254. .vpll_pdiv = 0x3,
  255. .vpll_sdiv = 0x2,
  256. .bpll_mdiv = 0x64,
  257. .bpll_pdiv = 0x3,
  258. .bpll_sdiv = 0x0,
  259. .pclk_cdrex_ratio = 0x5,
  260. .direct_cmd_msr = {
  261. 0x00020018, 0x00030000, 0x00010042, 0x00000d70
  262. },
  263. .timing_ref = 0x000000bb,
  264. .timing_row = 0x8c36650e,
  265. .timing_data = 0x3630580b,
  266. .timing_power = 0x41000a44,
  267. .phy0_dqs = 0x08080808,
  268. .phy1_dqs = 0x08080808,
  269. .phy0_dq = 0x08080808,
  270. .phy1_dq = 0x08080808,
  271. .phy0_tFS = 0x4,
  272. .phy1_tFS = 0x4,
  273. .phy0_pulld_dqs = 0xf,
  274. .phy1_pulld_dqs = 0xf,
  275. .lpddr3_ctrl_phy_reset = 0x1,
  276. .ctrl_start_point = 0x10,
  277. .ctrl_inc = 0x10,
  278. .ctrl_start = 0x1,
  279. .ctrl_dll_on = 0x1,
  280. .ctrl_ref = 0x8,
  281. .ctrl_force = 0x1a,
  282. .ctrl_rdlat = 0x0b,
  283. .ctrl_bstlen = 0x08,
  284. .fp_resync = 0x8,
  285. .iv_size = 0x7,
  286. .dfi_init_start = 1,
  287. .aref_en = 1,
  288. .rd_fetch = 0x3,
  289. .zq_mode_dds = 0x7,
  290. .zq_mode_term = 0x1,
  291. .zq_mode_noterm = 0,
  292. /*
  293. * Dynamic Clock: Always Running
  294. * Memory Burst length: 8
  295. * Number of chips: 1
  296. * Memory Bus width: 32 bit
  297. * Memory Type: DDR3
  298. * Additional Latancy for PLL: 0 Cycle
  299. */
  300. .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
  301. DMC_MEMCONTROL_DPWRDN_DISABLE |
  302. DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
  303. DMC_MEMCONTROL_TP_DISABLE |
  304. DMC_MEMCONTROL_DSREF_ENABLE |
  305. DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
  306. DMC_MEMCONTROL_MEM_TYPE_DDR3 |
  307. DMC_MEMCONTROL_MEM_WIDTH_32BIT |
  308. DMC_MEMCONTROL_NUM_CHIP_1 |
  309. DMC_MEMCONTROL_BL_8 |
  310. DMC_MEMCONTROL_PZQ_DISABLE |
  311. DMC_MEMCONTROL_MRR_BYTE_7_0,
  312. .memconfig = DMC_MEMCONFIGX_CHIP_MAP_INTERLEAVED |
  313. DMC_MEMCONFIGX_CHIP_COL_10 |
  314. DMC_MEMCONFIGX_CHIP_ROW_15 |
  315. DMC_MEMCONFIGX_CHIP_BANK_8,
  316. .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
  317. .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
  318. .prechconfig_tp_cnt = 0xff,
  319. .dpwrdn_cyc = 0xff,
  320. .dsref_cyc = 0xffff,
  321. .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
  322. DMC_CONCONTROL_TIMEOUT_LEVEL0 |
  323. DMC_CONCONTROL_RD_FETCH_DISABLE |
  324. DMC_CONCONTROL_EMPTY_DISABLE |
  325. DMC_CONCONTROL_AREF_EN_DISABLE |
  326. DMC_CONCONTROL_IO_PD_CON_DISABLE,
  327. .dmc_channels = 2,
  328. .chips_per_channel = 2,
  329. .chips_to_configure = 1,
  330. .send_zq_init = 1,
  331. .impedance = IMP_OUTPUT_DRV_30_OHM,
  332. .gate_leveling_enable = 0,
  333. }, {
  334. .mem_manuf = MEM_MANUF_SAMSUNG,
  335. .mem_type = DDR_MODE_DDR3,
  336. .frequency_mhz = 800,
  337. .mpll_mdiv = 0xc8,
  338. .mpll_pdiv = 0x3,
  339. .mpll_sdiv = 0x0,
  340. .cpll_mdiv = 0xde,
  341. .cpll_pdiv = 0x4,
  342. .cpll_sdiv = 0x2,
  343. .gpll_mdiv = 0x215,
  344. .gpll_pdiv = 0xc,
  345. .gpll_sdiv = 0x1,
  346. .epll_mdiv = 0x60,
  347. .epll_pdiv = 0x3,
  348. .epll_sdiv = 0x3,
  349. .vpll_mdiv = 0x96,
  350. .vpll_pdiv = 0x3,
  351. .vpll_sdiv = 0x2,
  352. .bpll_mdiv = 0x64,
  353. .bpll_pdiv = 0x3,
  354. .bpll_sdiv = 0x0,
  355. .pclk_cdrex_ratio = 0x5,
  356. .direct_cmd_msr = {
  357. 0x00020018, 0x00030000, 0x00010000, 0x00000d70
  358. },
  359. .timing_ref = 0x000000bb,
  360. .timing_row = 0x8c36650e,
  361. .timing_data = 0x3630580b,
  362. .timing_power = 0x41000a44,
  363. .phy0_dqs = 0x08080808,
  364. .phy1_dqs = 0x08080808,
  365. .phy0_dq = 0x08080808,
  366. .phy1_dq = 0x08080808,
  367. .phy0_tFS = 0x8,
  368. .phy1_tFS = 0x8,
  369. .phy0_pulld_dqs = 0xf,
  370. .phy1_pulld_dqs = 0xf,
  371. .lpddr3_ctrl_phy_reset = 0x1,
  372. .ctrl_start_point = 0x10,
  373. .ctrl_inc = 0x10,
  374. .ctrl_start = 0x1,
  375. .ctrl_dll_on = 0x1,
  376. .ctrl_ref = 0x8,
  377. .ctrl_force = 0x1a,
  378. .ctrl_rdlat = 0x0b,
  379. .ctrl_bstlen = 0x08,
  380. .fp_resync = 0x8,
  381. .iv_size = 0x7,
  382. .dfi_init_start = 1,
  383. .aref_en = 1,
  384. .rd_fetch = 0x3,
  385. .zq_mode_dds = 0x5,
  386. .zq_mode_term = 0x1,
  387. .zq_mode_noterm = 1,
  388. /*
  389. * Dynamic Clock: Always Running
  390. * Memory Burst length: 8
  391. * Number of chips: 1
  392. * Memory Bus width: 32 bit
  393. * Memory Type: DDR3
  394. * Additional Latancy for PLL: 0 Cycle
  395. */
  396. .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE |
  397. DMC_MEMCONTROL_DPWRDN_DISABLE |
  398. DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE |
  399. DMC_MEMCONTROL_TP_DISABLE |
  400. DMC_MEMCONTROL_DSREF_ENABLE |
  401. DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) |
  402. DMC_MEMCONTROL_MEM_TYPE_DDR3 |
  403. DMC_MEMCONTROL_MEM_WIDTH_32BIT |
  404. DMC_MEMCONTROL_NUM_CHIP_1 |
  405. DMC_MEMCONTROL_BL_8 |
  406. DMC_MEMCONTROL_PZQ_DISABLE |
  407. DMC_MEMCONTROL_MRR_BYTE_7_0,
  408. .memconfig = DMC_MEMCONFIGX_CHIP_MAP_INTERLEAVED |
  409. DMC_MEMCONFIGX_CHIP_COL_10 |
  410. DMC_MEMCONFIGX_CHIP_ROW_15 |
  411. DMC_MEMCONFIGX_CHIP_BANK_8,
  412. .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40),
  413. .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80),
  414. .prechconfig_tp_cnt = 0xff,
  415. .dpwrdn_cyc = 0xff,
  416. .dsref_cyc = 0xffff,
  417. .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE |
  418. DMC_CONCONTROL_TIMEOUT_LEVEL0 |
  419. DMC_CONCONTROL_RD_FETCH_DISABLE |
  420. DMC_CONCONTROL_EMPTY_DISABLE |
  421. DMC_CONCONTROL_AREF_EN_DISABLE |
  422. DMC_CONCONTROL_IO_PD_CON_DISABLE,
  423. .dmc_channels = 2,
  424. .chips_per_channel = 2,
  425. .chips_to_configure = 1,
  426. .send_zq_init = 1,
  427. .impedance = IMP_OUTPUT_DRV_40_OHM,
  428. .gate_leveling_enable = 1,
  429. }
  430. #endif
  431. };
  432. /**
  433. * Get the required memory type and speed (SPL version).
  434. *
  435. * In SPL we have no device tree, so we use the machine parameters
  436. *
  437. * @param mem_type Returns memory type
  438. * @param frequency_mhz Returns memory speed in MHz
  439. * @param arm_freq Returns ARM clock speed in MHz
  440. * @param mem_manuf Return Memory Manufacturer name
  441. */
  442. static void clock_get_mem_selection(enum ddr_mode *mem_type,
  443. unsigned *frequency_mhz, unsigned *arm_freq,
  444. enum mem_manuf *mem_manuf)
  445. {
  446. struct spl_machine_param *params;
  447. params = spl_get_machine_params();
  448. *mem_type = params->mem_type;
  449. *frequency_mhz = params->frequency_mhz;
  450. *arm_freq = params->arm_freq_mhz;
  451. *mem_manuf = params->mem_manuf;
  452. }
  453. /* Get the ratios for setting ARM clock */
  454. struct arm_clk_ratios *get_arm_ratios(void)
  455. {
  456. struct arm_clk_ratios *arm_ratio;
  457. enum ddr_mode mem_type;
  458. enum mem_manuf mem_manuf;
  459. unsigned frequency_mhz, arm_freq;
  460. int i;
  461. clock_get_mem_selection(&mem_type, &frequency_mhz,
  462. &arm_freq, &mem_manuf);
  463. for (i = 0, arm_ratio = arm_clk_ratios; i < ARRAY_SIZE(arm_clk_ratios);
  464. i++, arm_ratio++) {
  465. if (arm_ratio->arm_freq_mhz == arm_freq)
  466. return arm_ratio;
  467. }
  468. /* will hang if failed to find clock ratio */
  469. while (1)
  470. ;
  471. return NULL;
  472. }
  473. struct mem_timings *clock_get_mem_timings(void)
  474. {
  475. struct mem_timings *mem;
  476. enum ddr_mode mem_type;
  477. enum mem_manuf mem_manuf;
  478. unsigned frequency_mhz, arm_freq;
  479. int i;
  480. clock_get_mem_selection(&mem_type, &frequency_mhz,
  481. &arm_freq, &mem_manuf);
  482. for (i = 0, mem = mem_timings; i < ARRAY_SIZE(mem_timings);
  483. i++, mem++) {
  484. if (mem->mem_type == mem_type &&
  485. mem->frequency_mhz == frequency_mhz &&
  486. mem->mem_manuf == mem_manuf)
  487. return mem;
  488. }
  489. /* will hang if failed to find memory timings */
  490. while (1)
  491. ;
  492. return NULL;
  493. }
  494. static void exynos5250_system_clock_init(void)
  495. {
  496. struct exynos5_clock *clk =
  497. (struct exynos5_clock *)samsung_get_base_clock();
  498. struct mem_timings *mem;
  499. struct arm_clk_ratios *arm_clk_ratio;
  500. u32 val, tmp;
  501. mem = clock_get_mem_timings();
  502. arm_clk_ratio = get_arm_ratios();
  503. clrbits_le32(&clk->src_cpu, MUX_APLL_SEL_MASK);
  504. do {
  505. val = readl(&clk->mux_stat_cpu);
  506. } while ((val | MUX_APLL_SEL_MASK) != val);
  507. clrbits_le32(&clk->src_core1, MUX_MPLL_SEL_MASK);
  508. do {
  509. val = readl(&clk->mux_stat_core1);
  510. } while ((val | MUX_MPLL_SEL_MASK) != val);
  511. clrbits_le32(&clk->src_top2, MUX_CPLL_SEL_MASK);
  512. clrbits_le32(&clk->src_top2, MUX_EPLL_SEL_MASK);
  513. clrbits_le32(&clk->src_top2, MUX_VPLL_SEL_MASK);
  514. clrbits_le32(&clk->src_top2, MUX_GPLL_SEL_MASK);
  515. tmp = MUX_CPLL_SEL_MASK | MUX_EPLL_SEL_MASK | MUX_VPLL_SEL_MASK
  516. | MUX_GPLL_SEL_MASK;
  517. do {
  518. val = readl(&clk->mux_stat_top2);
  519. } while ((val | tmp) != val);
  520. clrbits_le32(&clk->src_cdrex, MUX_BPLL_SEL_MASK);
  521. do {
  522. val = readl(&clk->mux_stat_cdrex);
  523. } while ((val | MUX_BPLL_SEL_MASK) != val);
  524. /* PLL locktime */
  525. writel(mem->apll_pdiv * PLL_LOCK_FACTOR, &clk->apll_lock);
  526. writel(mem->mpll_pdiv * PLL_LOCK_FACTOR, &clk->mpll_lock);
  527. writel(mem->bpll_pdiv * PLL_LOCK_FACTOR, &clk->bpll_lock);
  528. writel(mem->cpll_pdiv * PLL_LOCK_FACTOR, &clk->cpll_lock);
  529. writel(mem->gpll_pdiv * PLL_X_LOCK_FACTOR, &clk->gpll_lock);
  530. writel(mem->epll_pdiv * PLL_X_LOCK_FACTOR, &clk->epll_lock);
  531. writel(mem->vpll_pdiv * PLL_X_LOCK_FACTOR, &clk->vpll_lock);
  532. writel(CLK_REG_DISABLE, &clk->pll_div2_sel);
  533. writel(MUX_HPM_SEL_MASK, &clk->src_cpu);
  534. do {
  535. val = readl(&clk->mux_stat_cpu);
  536. } while ((val | HPM_SEL_SCLK_MPLL) != val);
  537. val = arm_clk_ratio->arm2_ratio << 28
  538. | arm_clk_ratio->apll_ratio << 24
  539. | arm_clk_ratio->pclk_dbg_ratio << 20
  540. | arm_clk_ratio->atb_ratio << 16
  541. | arm_clk_ratio->periph_ratio << 12
  542. | arm_clk_ratio->acp_ratio << 8
  543. | arm_clk_ratio->cpud_ratio << 4
  544. | arm_clk_ratio->arm_ratio;
  545. writel(val, &clk->div_cpu0);
  546. do {
  547. val = readl(&clk->div_stat_cpu0);
  548. } while (0 != val);
  549. writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1);
  550. do {
  551. val = readl(&clk->div_stat_cpu1);
  552. } while (0 != val);
  553. /* Set APLL */
  554. writel(APLL_CON1_VAL, &clk->apll_con1);
  555. val = set_pll(arm_clk_ratio->apll_mdiv, arm_clk_ratio->apll_pdiv,
  556. arm_clk_ratio->apll_sdiv);
  557. writel(val, &clk->apll_con0);
  558. while ((readl(&clk->apll_con0) & APLL_CON0_LOCKED) == 0)
  559. ;
  560. /* Set MPLL */
  561. writel(MPLL_CON1_VAL, &clk->mpll_con1);
  562. val = set_pll(mem->mpll_mdiv, mem->mpll_pdiv, mem->mpll_sdiv);
  563. writel(val, &clk->mpll_con0);
  564. while ((readl(&clk->mpll_con0) & MPLL_CON0_LOCKED) == 0)
  565. ;
  566. /* Set BPLL */
  567. writel(BPLL_CON1_VAL, &clk->bpll_con1);
  568. val = set_pll(mem->bpll_mdiv, mem->bpll_pdiv, mem->bpll_sdiv);
  569. writel(val, &clk->bpll_con0);
  570. while ((readl(&clk->bpll_con0) & BPLL_CON0_LOCKED) == 0)
  571. ;
  572. /* Set CPLL */
  573. writel(CPLL_CON1_VAL, &clk->cpll_con1);
  574. val = set_pll(mem->cpll_mdiv, mem->cpll_pdiv, mem->cpll_sdiv);
  575. writel(val, &clk->cpll_con0);
  576. while ((readl(&clk->cpll_con0) & CPLL_CON0_LOCKED) == 0)
  577. ;
  578. /* Set GPLL */
  579. writel(GPLL_CON1_VAL, &clk->gpll_con1);
  580. val = set_pll(mem->gpll_mdiv, mem->gpll_pdiv, mem->gpll_sdiv);
  581. writel(val, &clk->gpll_con0);
  582. while ((readl(&clk->gpll_con0) & GPLL_CON0_LOCKED) == 0)
  583. ;
  584. /* Set EPLL */
  585. writel(EPLL_CON2_VAL, &clk->epll_con2);
  586. writel(EPLL_CON1_VAL, &clk->epll_con1);
  587. val = set_pll(mem->epll_mdiv, mem->epll_pdiv, mem->epll_sdiv);
  588. writel(val, &clk->epll_con0);
  589. while ((readl(&clk->epll_con0) & EPLL_CON0_LOCKED) == 0)
  590. ;
  591. /* Set VPLL */
  592. writel(VPLL_CON2_VAL, &clk->vpll_con2);
  593. writel(VPLL_CON1_VAL, &clk->vpll_con1);
  594. val = set_pll(mem->vpll_mdiv, mem->vpll_pdiv, mem->vpll_sdiv);
  595. writel(val, &clk->vpll_con0);
  596. while ((readl(&clk->vpll_con0) & VPLL_CON0_LOCKED) == 0)
  597. ;
  598. writel(CLK_SRC_CORE0_VAL, &clk->src_core0);
  599. writel(CLK_DIV_CORE0_VAL, &clk->div_core0);
  600. while (readl(&clk->div_stat_core0) != 0)
  601. ;
  602. writel(CLK_DIV_CORE1_VAL, &clk->div_core1);
  603. while (readl(&clk->div_stat_core1) != 0)
  604. ;
  605. writel(CLK_DIV_SYSRGT_VAL, &clk->div_sysrgt);
  606. while (readl(&clk->div_stat_sysrgt) != 0)
  607. ;
  608. writel(CLK_DIV_ACP_VAL, &clk->div_acp);
  609. while (readl(&clk->div_stat_acp) != 0)
  610. ;
  611. writel(CLK_DIV_SYSLFT_VAL, &clk->div_syslft);
  612. while (readl(&clk->div_stat_syslft) != 0)
  613. ;
  614. writel(CLK_SRC_TOP0_VAL, &clk->src_top0);
  615. writel(CLK_SRC_TOP1_VAL, &clk->src_top1);
  616. writel(TOP2_VAL, &clk->src_top2);
  617. writel(CLK_SRC_TOP3_VAL, &clk->src_top3);
  618. writel(CLK_DIV_TOP0_VAL, &clk->div_top0);
  619. while (readl(&clk->div_stat_top0))
  620. ;
  621. writel(CLK_DIV_TOP1_VAL, &clk->div_top1);
  622. while (readl(&clk->div_stat_top1))
  623. ;
  624. writel(CLK_SRC_LEX_VAL, &clk->src_lex);
  625. while (1) {
  626. val = readl(&clk->mux_stat_lex);
  627. if (val == (val | 1))
  628. break;
  629. }
  630. writel(CLK_DIV_LEX_VAL, &clk->div_lex);
  631. while (readl(&clk->div_stat_lex))
  632. ;
  633. writel(CLK_DIV_R0X_VAL, &clk->div_r0x);
  634. while (readl(&clk->div_stat_r0x))
  635. ;
  636. writel(CLK_DIV_R0X_VAL, &clk->div_r0x);
  637. while (readl(&clk->div_stat_r0x))
  638. ;
  639. writel(CLK_DIV_R1X_VAL, &clk->div_r1x);
  640. while (readl(&clk->div_stat_r1x))
  641. ;
  642. writel(CLK_REG_DISABLE, &clk->src_cdrex);
  643. writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex);
  644. while (readl(&clk->div_stat_cdrex))
  645. ;
  646. val = readl(&clk->src_cpu);
  647. val |= CLK_SRC_CPU_VAL;
  648. writel(val, &clk->src_cpu);
  649. val = readl(&clk->src_top2);
  650. val |= CLK_SRC_TOP2_VAL;
  651. writel(val, &clk->src_top2);
  652. val = readl(&clk->src_core1);
  653. val |= CLK_SRC_CORE1_VAL;
  654. writel(val, &clk->src_core1);
  655. writel(CLK_SRC_FSYS0_VAL, &clk->src_fsys);
  656. writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0);
  657. while (readl(&clk->div_stat_fsys0))
  658. ;
  659. writel(CLK_REG_DISABLE, &clk->clkout_cmu_cpu);
  660. writel(CLK_REG_DISABLE, &clk->clkout_cmu_core);
  661. writel(CLK_REG_DISABLE, &clk->clkout_cmu_acp);
  662. writel(CLK_REG_DISABLE, &clk->clkout_cmu_top);
  663. writel(CLK_REG_DISABLE, &clk->clkout_cmu_lex);
  664. writel(CLK_REG_DISABLE, &clk->clkout_cmu_r0x);
  665. writel(CLK_REG_DISABLE, &clk->clkout_cmu_r1x);
  666. writel(CLK_REG_DISABLE, &clk->clkout_cmu_cdrex);
  667. writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0);
  668. writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0);
  669. writel(CLK_SRC_PERIC1_VAL, &clk->src_peric1);
  670. writel(CLK_DIV_PERIC1_VAL, &clk->div_peric1);
  671. writel(CLK_DIV_PERIC2_VAL, &clk->div_peric2);
  672. writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3);
  673. writel(SCLK_SRC_ISP_VAL, &clk->sclk_src_isp);
  674. writel(SCLK_DIV_ISP_VAL, &clk->sclk_div_isp);
  675. writel(CLK_DIV_ISP0_VAL, &clk->div_isp0);
  676. writel(CLK_DIV_ISP1_VAL, &clk->div_isp1);
  677. writel(CLK_DIV_ISP2_VAL, &clk->div_isp2);
  678. /* FIMD1 SRC CLK SELECTION */
  679. writel(CLK_SRC_DISP1_0_VAL, &clk->src_disp1_0);
  680. val = MMC2_PRE_RATIO_VAL << MMC2_PRE_RATIO_OFFSET
  681. | MMC2_RATIO_VAL << MMC2_RATIO_OFFSET
  682. | MMC3_PRE_RATIO_VAL << MMC3_PRE_RATIO_OFFSET
  683. | MMC3_RATIO_VAL << MMC3_RATIO_OFFSET;
  684. writel(val, &clk->div_fsys2);
  685. }
  686. static void exynos5420_system_clock_init(void)
  687. {
  688. struct exynos5420_clock *clk =
  689. (struct exynos5420_clock *)samsung_get_base_clock();
  690. struct mem_timings *mem;
  691. struct arm_clk_ratios *arm_clk_ratio;
  692. u32 val;
  693. mem = clock_get_mem_timings();
  694. arm_clk_ratio = get_arm_ratios();
  695. /* PLL locktime */
  696. writel(arm_clk_ratio->apll_pdiv * PLL_LOCK_FACTOR, &clk->apll_lock);
  697. writel(mem->mpll_pdiv * PLL_LOCK_FACTOR, &clk->mpll_lock);
  698. writel(mem->bpll_pdiv * PLL_LOCK_FACTOR, &clk->bpll_lock);
  699. writel(mem->cpll_pdiv * PLL_LOCK_FACTOR, &clk->cpll_lock);
  700. writel(mem->dpll_pdiv * PLL_LOCK_FACTOR, &clk->dpll_lock);
  701. writel(mem->epll_pdiv * PLL_X_LOCK_FACTOR, &clk->epll_lock);
  702. writel(mem->vpll_pdiv * PLL_LOCK_FACTOR, &clk->vpll_lock);
  703. writel(mem->ipll_pdiv * PLL_LOCK_FACTOR, &clk->ipll_lock);
  704. writel(mem->spll_pdiv * PLL_LOCK_FACTOR, &clk->spll_lock);
  705. writel(mem->kpll_pdiv * PLL_LOCK_FACTOR, &clk->kpll_lock);
  706. writel(mem->rpll_pdiv * PLL_X_LOCK_FACTOR, &clk->rpll_lock);
  707. setbits_le32(&clk->src_cpu, MUX_HPM_SEL_MASK);
  708. writel(0, &clk->src_top6);
  709. writel(0, &clk->src_cdrex);
  710. writel(SRC_KFC_HPM_SEL, &clk->src_kfc);
  711. writel(HPM_RATIO, &clk->div_cpu1);
  712. writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0);
  713. /* switch A15 clock source to OSC clock before changing APLL */
  714. clrbits_le32(&clk->src_cpu, APLL_FOUT);
  715. /* Set APLL */
  716. writel(APLL_CON1_VAL, &clk->apll_con1);
  717. val = set_pll(arm_clk_ratio->apll_mdiv,
  718. arm_clk_ratio->apll_pdiv,
  719. arm_clk_ratio->apll_sdiv);
  720. writel(val, &clk->apll_con0);
  721. while ((readl(&clk->apll_con0) & PLL_LOCKED) == 0)
  722. ;
  723. /* now it is safe to switch to APLL */
  724. setbits_le32(&clk->src_cpu, APLL_FOUT);
  725. writel(SRC_KFC_HPM_SEL, &clk->src_kfc);
  726. writel(CLK_DIV_KFC_VAL, &clk->div_kfc0);
  727. /* switch A7 clock source to OSC clock before changing KPLL */
  728. clrbits_le32(&clk->src_kfc, KPLL_FOUT);
  729. /* Set KPLL*/
  730. writel(KPLL_CON1_VAL, &clk->kpll_con1);
  731. val = set_pll(mem->kpll_mdiv, mem->kpll_pdiv, mem->kpll_sdiv);
  732. writel(val, &clk->kpll_con0);
  733. while ((readl(&clk->kpll_con0) & PLL_LOCKED) == 0)
  734. ;
  735. /* now it is safe to switch to KPLL */
  736. setbits_le32(&clk->src_kfc, KPLL_FOUT);
  737. /* Set MPLL */
  738. writel(MPLL_CON1_VAL, &clk->mpll_con1);
  739. val = set_pll(mem->mpll_mdiv, mem->mpll_pdiv, mem->mpll_sdiv);
  740. writel(val, &clk->mpll_con0);
  741. while ((readl(&clk->mpll_con0) & PLL_LOCKED) == 0)
  742. ;
  743. /* Set DPLL */
  744. writel(DPLL_CON1_VAL, &clk->dpll_con1);
  745. val = set_pll(mem->dpll_mdiv, mem->dpll_pdiv, mem->dpll_sdiv);
  746. writel(val, &clk->dpll_con0);
  747. while ((readl(&clk->dpll_con0) & PLL_LOCKED) == 0)
  748. ;
  749. /* Set EPLL */
  750. writel(EPLL_CON2_VAL, &clk->epll_con2);
  751. writel(EPLL_CON1_VAL, &clk->epll_con1);
  752. val = set_pll(mem->epll_mdiv, mem->epll_pdiv, mem->epll_sdiv);
  753. writel(val, &clk->epll_con0);
  754. while ((readl(&clk->epll_con0) & PLL_LOCKED) == 0)
  755. ;
  756. /* Set CPLL */
  757. writel(CPLL_CON1_VAL, &clk->cpll_con1);
  758. val = set_pll(mem->cpll_mdiv, mem->cpll_pdiv, mem->cpll_sdiv);
  759. writel(val, &clk->cpll_con0);
  760. while ((readl(&clk->cpll_con0) & PLL_LOCKED) == 0)
  761. ;
  762. /* Set IPLL */
  763. writel(IPLL_CON1_VAL, &clk->ipll_con1);
  764. val = set_pll(mem->ipll_mdiv, mem->ipll_pdiv, mem->ipll_sdiv);
  765. writel(val, &clk->ipll_con0);
  766. while ((readl(&clk->ipll_con0) & PLL_LOCKED) == 0)
  767. ;
  768. /* Set VPLL */
  769. writel(VPLL_CON1_VAL, &clk->vpll_con1);
  770. val = set_pll(mem->vpll_mdiv, mem->vpll_pdiv, mem->vpll_sdiv);
  771. writel(val, &clk->vpll_con0);
  772. while ((readl(&clk->vpll_con0) & PLL_LOCKED) == 0)
  773. ;
  774. /* Set BPLL */
  775. writel(BPLL_CON1_VAL, &clk->bpll_con1);
  776. val = set_pll(mem->bpll_mdiv, mem->bpll_pdiv, mem->bpll_sdiv);
  777. writel(val, &clk->bpll_con0);
  778. while ((readl(&clk->bpll_con0) & PLL_LOCKED) == 0)
  779. ;
  780. /* Set SPLL */
  781. writel(SPLL_CON1_VAL, &clk->spll_con1);
  782. val = set_pll(mem->spll_mdiv, mem->spll_pdiv, mem->spll_sdiv);
  783. writel(val, &clk->spll_con0);
  784. while ((readl(&clk->spll_con0) & PLL_LOCKED) == 0)
  785. ;
  786. /* Set RPLL */
  787. writel(RPLL_CON2_VAL, &clk->rpll_con2);
  788. writel(RPLL_CON1_VAL, &clk->rpll_con1);
  789. val = set_pll(mem->rpll_mdiv, mem->rpll_pdiv, mem->rpll_sdiv);
  790. writel(val, &clk->rpll_con0);
  791. while ((readl(&clk->rpll_con0) & PLL_LOCKED) == 0)
  792. ;
  793. writel(CLK_DIV_CDREX0_VAL, &clk->div_cdrex0);
  794. writel(CLK_DIV_CDREX1_VAL, &clk->div_cdrex1);
  795. writel(CLK_SRC_TOP0_VAL, &clk->src_top0);
  796. writel(CLK_SRC_TOP1_VAL, &clk->src_top1);
  797. writel(CLK_SRC_TOP2_VAL, &clk->src_top2);
  798. writel(CLK_SRC_TOP7_VAL, &clk->src_top7);
  799. writel(CLK_DIV_TOP0_VAL, &clk->div_top0);
  800. writel(CLK_DIV_TOP1_VAL, &clk->div_top1);
  801. writel(CLK_DIV_TOP2_VAL, &clk->div_top2);
  802. writel(0, &clk->src_top10);
  803. writel(0, &clk->src_top11);
  804. writel(0, &clk->src_top12);
  805. writel(CLK_SRC_TOP3_VAL, &clk->src_top3);
  806. writel(CLK_SRC_TOP4_VAL, &clk->src_top4);
  807. writel(CLK_SRC_TOP5_VAL, &clk->src_top5);
  808. /* DISP1 BLK CLK SELECTION */
  809. writel(CLK_SRC_DISP1_0_VAL, &clk->src_disp10);
  810. writel(CLK_DIV_DISP1_0_VAL, &clk->div_disp10);
  811. /* AUDIO BLK */
  812. writel(AUDIO0_SEL_EPLL, &clk->src_mau);
  813. writel(DIV_MAU_VAL, &clk->div_mau);
  814. /* FSYS */
  815. writel(CLK_SRC_FSYS0_VAL, &clk->src_fsys);
  816. writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0);
  817. writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1);
  818. writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2);
  819. writel(CLK_SRC_ISP_VAL, &clk->src_isp);
  820. writel(CLK_DIV_ISP0_VAL, &clk->div_isp0);
  821. writel(CLK_DIV_ISP1_VAL, &clk->div_isp1);
  822. writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0);
  823. writel(CLK_SRC_PERIC1_VAL, &clk->src_peric1);
  824. writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0);
  825. writel(CLK_DIV_PERIC1_VAL, &clk->div_peric1);
  826. writel(CLK_DIV_PERIC2_VAL, &clk->div_peric2);
  827. writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3);
  828. writel(CLK_DIV_PERIC4_VAL, &clk->div_peric4);
  829. writel(CLK_DIV_CPERI1_VAL, &clk->div_cperi1);
  830. writel(CLK_DIV2_RATIO, &clk->clkdiv2_ratio);
  831. writel(CLK_DIV4_RATIO, &clk->clkdiv4_ratio);
  832. writel(CLK_DIV_G2D, &clk->div_g2d);
  833. writel(CLK_SRC_TOP6_VAL, &clk->src_top6);
  834. writel(CLK_SRC_CDREX_VAL, &clk->src_cdrex);
  835. writel(CLK_SRC_KFC_VAL, &clk->src_kfc);
  836. }
  837. void system_clock_init(void)
  838. {
  839. if (proid_is_exynos5420() || proid_is_exynos5422())
  840. exynos5420_system_clock_init();
  841. else
  842. exynos5250_system_clock_init();
  843. }
  844. void clock_init_dp_clock(void)
  845. {
  846. struct exynos5_clock *clk =
  847. (struct exynos5_clock *)samsung_get_base_clock();
  848. /* DP clock enable */
  849. setbits_le32(&clk->gate_ip_disp1, CLK_GATE_DP1_ALLOW);
  850. /* We run DP at 267 Mhz */
  851. setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1);
  852. }
  853. /*
  854. * Set clock divisor value for booting from EMMC.
  855. * Set DWMMC channel-0 clk div to operate mmc0 device at 50MHz.
  856. */
  857. void emmc_boot_clk_div_set(void)
  858. {
  859. struct exynos5_clock *clk =
  860. (struct exynos5_clock *)samsung_get_base_clock();
  861. unsigned int div_mmc;
  862. div_mmc = readl((unsigned int) &clk->div_fsys1) & ~FSYS1_MMC0_DIV_MASK;
  863. div_mmc |= FSYS1_MMC0_DIV_VAL;
  864. writel(div_mmc, (unsigned int) &clk->div_fsys1);
  865. }