ddr3_init.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. /*
  2. * Copyright (C) Marvell International Ltd. and its affiliates
  3. *
  4. * SPDX-License-Identifier: GPL-2.0
  5. */
  6. #include <common.h>
  7. #include <i2c.h>
  8. #include <spl.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/cpu.h>
  11. #include <asm/arch/soc.h>
  12. #include "ddr3_init.h"
  13. #if defined(MV88F78X60)
  14. #include "ddr3_axp_vars.h"
  15. #elif defined(MV88F67XX)
  16. #include "ddr3_a370_vars.h"
  17. #elif defined(MV88F672X)
  18. #include "ddr3_a375_vars.h"
  19. #endif
  20. #ifdef STATIC_TRAINING
  21. static void ddr3_static_training_init(void);
  22. #endif
  23. #ifdef DUNIT_STATIC
  24. static void ddr3_static_mc_init(void);
  25. #endif
  26. #if defined(DUNIT_STATIC) || defined(STATIC_TRAINING)
  27. MV_DRAM_MODES *ddr3_get_static_ddr_mode(void);
  28. #endif
  29. #if defined(MV88F672X)
  30. void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps);
  31. #endif
  32. u32 mv_board_id_get(void);
  33. extern void ddr3_set_sw_wl_rl_debug(u32);
  34. extern void ddr3_set_pbs(u32);
  35. extern void ddr3_set_log_level(u32 val);
  36. static u32 log_level = DDR3_LOG_LEVEL;
  37. static u32 ddr3_init_main(void);
  38. /*
  39. * Name: ddr3_set_log_level
  40. * Desc: This routine initialize the log_level acording to nLogLevel
  41. * which getting from user
  42. * Args: nLogLevel
  43. * Notes:
  44. * Returns: None.
  45. */
  46. void ddr3_set_log_level(u32 val)
  47. {
  48. log_level = val;
  49. }
  50. /*
  51. * Name: ddr3_get_log_level
  52. * Desc: This routine returns the log level
  53. * Args: none
  54. * Notes:
  55. * Returns: log level.
  56. */
  57. u32 ddr3_get_log_level(void)
  58. {
  59. return log_level;
  60. }
  61. static void debug_print_reg(u32 reg)
  62. {
  63. printf("0x%08x = 0x%08x\n", reg, reg_read(reg));
  64. }
  65. static void print_dunit_setup(void)
  66. {
  67. puts("\n########### LOG LEVEL 1 (D-UNIT SETUP)###########\n");
  68. #ifdef DUNIT_STATIC
  69. puts("\nStatic D-UNIT Setup:\n");
  70. #endif
  71. #ifdef DUNIT_SPD
  72. puts("\nDynamic(using SPD) D-UNIT Setup:\n");
  73. #endif
  74. debug_print_reg(REG_SDRAM_CONFIG_ADDR);
  75. debug_print_reg(REG_DUNIT_CTRL_LOW_ADDR);
  76. debug_print_reg(REG_SDRAM_TIMING_LOW_ADDR);
  77. debug_print_reg(REG_SDRAM_TIMING_HIGH_ADDR);
  78. debug_print_reg(REG_SDRAM_ADDRESS_CTRL_ADDR);
  79. debug_print_reg(REG_SDRAM_OPEN_PAGES_ADDR);
  80. debug_print_reg(REG_SDRAM_OPERATION_ADDR);
  81. debug_print_reg(REG_SDRAM_MODE_ADDR);
  82. debug_print_reg(REG_SDRAM_EXT_MODE_ADDR);
  83. debug_print_reg(REG_DDR_CONT_HIGH_ADDR);
  84. debug_print_reg(REG_ODT_TIME_LOW_ADDR);
  85. debug_print_reg(REG_SDRAM_ERROR_ADDR);
  86. debug_print_reg(REG_SDRAM_AUTO_PWR_SAVE_ADDR);
  87. debug_print_reg(REG_OUDDR3_TIMING_ADDR);
  88. debug_print_reg(REG_ODT_TIME_HIGH_ADDR);
  89. debug_print_reg(REG_SDRAM_ODT_CTRL_LOW_ADDR);
  90. debug_print_reg(REG_SDRAM_ODT_CTRL_HIGH_ADDR);
  91. debug_print_reg(REG_DUNIT_ODT_CTRL_ADDR);
  92. #ifndef MV88F67XX
  93. debug_print_reg(REG_DRAM_FIFO_CTRL_ADDR);
  94. debug_print_reg(REG_DRAM_AXI_CTRL_ADDR);
  95. debug_print_reg(REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR);
  96. debug_print_reg(REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR);
  97. debug_print_reg(REG_DRAM_VER_CAL_MACHINE_CTRL_ADDR);
  98. debug_print_reg(REG_DRAM_MAIN_PADS_CAL_ADDR);
  99. debug_print_reg(REG_DRAM_HOR_CAL_MACHINE_CTRL_ADDR);
  100. debug_print_reg(REG_CS_SIZE_SCRATCH_ADDR);
  101. debug_print_reg(REG_DYNAMIC_POWER_SAVE_ADDR);
  102. debug_print_reg(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
  103. debug_print_reg(REG_READ_DATA_READY_DELAYS_ADDR);
  104. debug_print_reg(REG_DDR3_MR0_ADDR);
  105. debug_print_reg(REG_DDR3_MR1_ADDR);
  106. debug_print_reg(REG_DDR3_MR2_ADDR);
  107. debug_print_reg(REG_DDR3_MR3_ADDR);
  108. debug_print_reg(REG_DDR3_RANK_CTRL_ADDR);
  109. debug_print_reg(REG_DRAM_PHY_CONFIG_ADDR);
  110. debug_print_reg(REG_STATIC_DRAM_DLB_CONTROL);
  111. debug_print_reg(DLB_BUS_OPTIMIZATION_WEIGHTS_REG);
  112. debug_print_reg(DLB_AGING_REGISTER);
  113. debug_print_reg(DLB_EVICTION_CONTROL_REG);
  114. debug_print_reg(DLB_EVICTION_TIMERS_REGISTER_REG);
  115. #if defined(MV88F672X)
  116. debug_print_reg(REG_FASTPATH_WIN_CTRL_ADDR(0));
  117. debug_print_reg(REG_FASTPATH_WIN_BASE_ADDR(0));
  118. debug_print_reg(REG_FASTPATH_WIN_CTRL_ADDR(1));
  119. debug_print_reg(REG_FASTPATH_WIN_BASE_ADDR(1));
  120. #else
  121. debug_print_reg(REG_FASTPATH_WIN_0_CTRL_ADDR);
  122. #endif
  123. debug_print_reg(REG_CDI_CONFIG_ADDR);
  124. #endif
  125. }
  126. #if !defined(STATIC_TRAINING)
  127. static void ddr3_restore_and_set_final_windows(u32 *win_backup)
  128. {
  129. u32 ui, reg, cs;
  130. u32 win_ctrl_reg, num_of_win_regs;
  131. u32 cs_ena = ddr3_get_cs_ena_from_reg();
  132. #if defined(MV88F672X)
  133. if (DDR3_FAST_PATH_EN == 0)
  134. return;
  135. #endif
  136. #if defined(MV88F672X)
  137. win_ctrl_reg = REG_XBAR_WIN_16_CTRL_ADDR;
  138. num_of_win_regs = 8;
  139. #else
  140. win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
  141. num_of_win_regs = 16;
  142. #endif
  143. /* Return XBAR windows 4-7 or 16-19 init configuration */
  144. for (ui = 0; ui < num_of_win_regs; ui++)
  145. reg_write((win_ctrl_reg + 0x4 * ui), win_backup[ui]);
  146. DEBUG_INIT_FULL_S("DDR3 Training Sequence - Switching XBAR Window to FastPath Window\n");
  147. #if defined(MV88F672X)
  148. /* Set L2 filtering to 1G */
  149. reg_write(0x8c04, 0x40000000);
  150. /* Open fast path windows */
  151. for (cs = 0; cs < MAX_CS; cs++) {
  152. if (cs_ena & (1 << cs)) {
  153. /* set fast path window control for the cs */
  154. reg = 0x1FFFFFE1;
  155. reg |= (cs << 2);
  156. reg |= (SDRAM_CS_SIZE & 0xFFFF0000);
  157. /* Open fast path Window */
  158. reg_write(REG_FASTPATH_WIN_CTRL_ADDR(cs), reg);
  159. /* set fast path window base address for the cs */
  160. reg = (((SDRAM_CS_SIZE + 1) * cs) & 0xFFFF0000);
  161. /* Set base address */
  162. reg_write(REG_FASTPATH_WIN_BASE_ADDR(cs), reg);
  163. }
  164. }
  165. #else
  166. reg = 0x1FFFFFE1;
  167. for (cs = 0; cs < MAX_CS; cs++) {
  168. if (cs_ena & (1 << cs)) {
  169. reg |= (cs << 2);
  170. break;
  171. }
  172. }
  173. /* Open fast path Window to - 0.5G */
  174. reg_write(REG_FASTPATH_WIN_0_CTRL_ADDR, reg);
  175. #endif
  176. }
  177. static void ddr3_save_and_set_training_windows(u32 *win_backup)
  178. {
  179. u32 cs_ena = ddr3_get_cs_ena_from_reg();
  180. u32 reg, tmp_count, cs, ui;
  181. u32 win_ctrl_reg, win_base_reg, win_remap_reg;
  182. u32 num_of_win_regs, win_jump_index;
  183. #if defined(MV88F672X)
  184. /* Disable L2 filtering */
  185. reg_write(0x8c04, 0);
  186. win_ctrl_reg = REG_XBAR_WIN_16_CTRL_ADDR;
  187. win_base_reg = REG_XBAR_WIN_16_BASE_ADDR;
  188. win_remap_reg = REG_XBAR_WIN_16_REMAP_ADDR;
  189. win_jump_index = 0x8;
  190. num_of_win_regs = 8;
  191. #else
  192. win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
  193. win_base_reg = REG_XBAR_WIN_4_BASE_ADDR;
  194. win_remap_reg = REG_XBAR_WIN_4_REMAP_ADDR;
  195. win_jump_index = 0x10;
  196. num_of_win_regs = 16;
  197. #endif
  198. /* Close XBAR Window 19 - Not needed */
  199. /* {0x000200e8} - Open Mbus Window - 2G */
  200. reg_write(REG_XBAR_WIN_19_CTRL_ADDR, 0);
  201. /* Save XBAR Windows 4-19 init configurations */
  202. for (ui = 0; ui < num_of_win_regs; ui++)
  203. win_backup[ui] = reg_read(win_ctrl_reg + 0x4 * ui);
  204. /* Open XBAR Windows 4-7 or 16-19 for other CS */
  205. reg = 0;
  206. tmp_count = 0;
  207. for (cs = 0; cs < MAX_CS; cs++) {
  208. if (cs_ena & (1 << cs)) {
  209. switch (cs) {
  210. case 0:
  211. reg = 0x0E00;
  212. break;
  213. case 1:
  214. reg = 0x0D00;
  215. break;
  216. case 2:
  217. reg = 0x0B00;
  218. break;
  219. case 3:
  220. reg = 0x0700;
  221. break;
  222. }
  223. reg |= (1 << 0);
  224. reg |= (SDRAM_CS_SIZE & 0xFFFF0000);
  225. reg_write(win_ctrl_reg + win_jump_index * tmp_count,
  226. reg);
  227. reg = ((SDRAM_CS_SIZE + 1) * (tmp_count)) & 0xFFFF0000;
  228. reg_write(win_base_reg + win_jump_index * tmp_count,
  229. reg);
  230. if (win_remap_reg <= REG_XBAR_WIN_7_REMAP_ADDR) {
  231. reg_write(win_remap_reg +
  232. win_jump_index * tmp_count, 0);
  233. }
  234. tmp_count++;
  235. }
  236. }
  237. }
  238. #endif /* !defined(STATIC_TRAINING) */
  239. /*
  240. * Name: ddr3_init - Main DDR3 Init function
  241. * Desc: This routine initialize the DDR3 MC and runs HW training.
  242. * Args: None.
  243. * Notes:
  244. * Returns: None.
  245. */
  246. int ddr3_init(void)
  247. {
  248. unsigned int status;
  249. ddr3_set_pbs(DDR3_PBS);
  250. ddr3_set_sw_wl_rl_debug(DDR3_RUN_SW_WHEN_HW_FAIL);
  251. status = ddr3_init_main();
  252. if (status == MV_DDR3_TRAINING_ERR_BAD_SAR)
  253. DEBUG_INIT_S("DDR3 Training Error: Bad sample at reset");
  254. if (status == MV_DDR3_TRAINING_ERR_BAD_DIMM_SETUP)
  255. DEBUG_INIT_S("DDR3 Training Error: Bad DIMM setup");
  256. if (status == MV_DDR3_TRAINING_ERR_MAX_CS_LIMIT)
  257. DEBUG_INIT_S("DDR3 Training Error: Max CS limit");
  258. if (status == MV_DDR3_TRAINING_ERR_MAX_ENA_CS_LIMIT)
  259. DEBUG_INIT_S("DDR3 Training Error: Max enable CS limit");
  260. if (status == MV_DDR3_TRAINING_ERR_BAD_R_DIMM_SETUP)
  261. DEBUG_INIT_S("DDR3 Training Error: Bad R-DIMM setup");
  262. if (status == MV_DDR3_TRAINING_ERR_TWSI_FAIL)
  263. DEBUG_INIT_S("DDR3 Training Error: TWSI failure");
  264. if (status == MV_DDR3_TRAINING_ERR_DIMM_TYPE_NO_MATCH)
  265. DEBUG_INIT_S("DDR3 Training Error: DIMM type no match");
  266. if (status == MV_DDR3_TRAINING_ERR_TWSI_BAD_TYPE)
  267. DEBUG_INIT_S("DDR3 Training Error: TWSI bad type");
  268. if (status == MV_DDR3_TRAINING_ERR_BUS_WIDTH_NOT_MATCH)
  269. DEBUG_INIT_S("DDR3 Training Error: bus width no match");
  270. if (status > MV_DDR3_TRAINING_ERR_HW_FAIL_BASE)
  271. DEBUG_INIT_C("DDR3 Training Error: HW Failure 0x", status, 8);
  272. return status;
  273. }
  274. static void print_ddr_target_freq(u32 cpu_freq, u32 fab_opt)
  275. {
  276. puts("\nDDR3 Training Sequence - Run DDR3 at ");
  277. switch (cpu_freq) {
  278. #if defined(MV88F672X)
  279. case 21:
  280. puts("533 Mhz\n");
  281. break;
  282. #else
  283. case 1:
  284. puts("533 Mhz\n");
  285. break;
  286. case 2:
  287. if (fab_opt == 5)
  288. puts("600 Mhz\n");
  289. if (fab_opt == 9)
  290. puts("400 Mhz\n");
  291. break;
  292. case 3:
  293. puts("667 Mhz\n");
  294. break;
  295. case 4:
  296. if (fab_opt == 5)
  297. puts("750 Mhz\n");
  298. if (fab_opt == 9)
  299. puts("500 Mhz\n");
  300. break;
  301. case 0xa:
  302. puts("400 Mhz\n");
  303. break;
  304. case 0xb:
  305. if (fab_opt == 5)
  306. puts("800 Mhz\n");
  307. if (fab_opt == 9)
  308. puts("553 Mhz\n");
  309. if (fab_opt == 0xA)
  310. puts("640 Mhz\n");
  311. break;
  312. #endif
  313. default:
  314. puts("NOT DEFINED FREQ\n");
  315. }
  316. }
  317. static u32 ddr3_init_main(void)
  318. {
  319. u32 target_freq;
  320. u32 reg = 0;
  321. u32 cpu_freq, fab_opt, hclk_time_ps, soc_num;
  322. __maybe_unused u32 ecc = DRAM_ECC;
  323. __maybe_unused int dqs_clk_aligned = 0;
  324. __maybe_unused u32 scrub_offs, scrub_size;
  325. __maybe_unused u32 ddr_width = BUS_WIDTH;
  326. __maybe_unused int status;
  327. __maybe_unused u32 win_backup[16];
  328. /* SoC/Board special Initializtions */
  329. fab_opt = ddr3_get_fab_opt();
  330. #ifdef CONFIG_SPD_EEPROM
  331. i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
  332. #endif
  333. ddr3_print_version();
  334. DEBUG_INIT_S("4\n");
  335. /* Lib version 5.5.4 */
  336. fab_opt = ddr3_get_fab_opt();
  337. /* Switching CPU to MRVL ID */
  338. soc_num = (reg_read(REG_SAMPLE_RESET_HIGH_ADDR) & SAR1_CPU_CORE_MASK) >>
  339. SAR1_CPU_CORE_OFFSET;
  340. switch (soc_num) {
  341. case 0x3:
  342. reg_bit_set(CPU_CONFIGURATION_REG(3), CPU_MRVL_ID_OFFSET);
  343. reg_bit_set(CPU_CONFIGURATION_REG(2), CPU_MRVL_ID_OFFSET);
  344. case 0x1:
  345. reg_bit_set(CPU_CONFIGURATION_REG(1), CPU_MRVL_ID_OFFSET);
  346. case 0x0:
  347. reg_bit_set(CPU_CONFIGURATION_REG(0), CPU_MRVL_ID_OFFSET);
  348. default:
  349. break;
  350. }
  351. /* Power down deskew PLL */
  352. #if !defined(MV88F672X)
  353. /* 0x18780 [25] */
  354. reg = (reg_read(REG_DDRPHY_APLL_CTRL_ADDR) & ~(1 << 25));
  355. reg_write(REG_DDRPHY_APLL_CTRL_ADDR, reg);
  356. #endif
  357. /*
  358. * Stage 0 - Set board configuration
  359. */
  360. cpu_freq = ddr3_get_cpu_freq();
  361. if (fab_opt > FAB_OPT)
  362. fab_opt = FAB_OPT - 1;
  363. if (ddr3_get_log_level() > 0)
  364. print_ddr_target_freq(cpu_freq, fab_opt);
  365. #if defined(MV88F672X)
  366. get_target_freq(cpu_freq, &target_freq, &hclk_time_ps);
  367. #else
  368. target_freq = cpu_ddr_ratios[fab_opt][cpu_freq];
  369. hclk_time_ps = cpu_fab_clk_to_hclk[fab_opt][cpu_freq];
  370. #endif
  371. if ((target_freq == 0) || (hclk_time_ps == 0)) {
  372. DEBUG_INIT_S("DDR3 Training Sequence - FAILED - Wrong Sample at Reset Configurations\n");
  373. if (target_freq == 0) {
  374. DEBUG_INIT_C("target_freq", target_freq, 2);
  375. DEBUG_INIT_C("fab_opt", fab_opt, 2);
  376. DEBUG_INIT_C("cpu_freq", cpu_freq, 2);
  377. } else if (hclk_time_ps == 0) {
  378. DEBUG_INIT_C("hclk_time_ps", hclk_time_ps, 2);
  379. DEBUG_INIT_C("fab_opt", fab_opt, 2);
  380. DEBUG_INIT_C("cpu_freq", cpu_freq, 2);
  381. }
  382. return MV_DDR3_TRAINING_ERR_BAD_SAR;
  383. }
  384. #if defined(ECC_SUPPORT)
  385. scrub_offs = U_BOOT_START_ADDR;
  386. scrub_size = U_BOOT_SCRUB_SIZE;
  387. #else
  388. scrub_offs = 0;
  389. scrub_size = 0;
  390. #endif
  391. #if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT)
  392. ecc = DRAM_ECC;
  393. #endif
  394. #if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT)
  395. ecc = 0;
  396. if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_ECC))
  397. ecc = 1;
  398. #endif
  399. #ifdef DQS_CLK_ALIGNED
  400. dqs_clk_aligned = 1;
  401. #endif
  402. /* Check if DRAM is already initialized */
  403. if (reg_read(REG_BOOTROM_ROUTINE_ADDR) &
  404. (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) {
  405. DEBUG_INIT_S("DDR3 Training Sequence - 2nd boot - Skip\n");
  406. return MV_OK;
  407. }
  408. /*
  409. * Stage 1 - Dunit Setup
  410. */
  411. #ifdef DUNIT_STATIC
  412. /*
  413. * For Static D-Unit Setup use must set the correct static values
  414. * at the ddr3_*soc*_vars.h file
  415. */
  416. DEBUG_INIT_FULL_S("DDR3 Training Sequence - Static MC Init\n");
  417. ddr3_static_mc_init();
  418. #ifdef ECC_SUPPORT
  419. ecc = DRAM_ECC;
  420. if (ecc) {
  421. reg = reg_read(REG_SDRAM_CONFIG_ADDR);
  422. reg |= (1 << REG_SDRAM_CONFIG_ECC_OFFS);
  423. reg_write(REG_SDRAM_CONFIG_ADDR, reg);
  424. }
  425. #endif
  426. #endif
  427. #if defined(MV88F78X60) || defined(MV88F672X)
  428. #if defined(AUTO_DETECTION_SUPPORT)
  429. /*
  430. * Configurations for both static and dynamic MC setups
  431. *
  432. * Dynamically Set 32Bit and ECC for AXP (Relevant only for
  433. * Marvell DB boards)
  434. */
  435. if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_BUS_WIDTH)) {
  436. ddr_width = 32;
  437. DEBUG_INIT_S("DDR3 Training Sequence - DRAM bus width 32Bit\n");
  438. }
  439. #endif
  440. #if defined(MV88F672X)
  441. reg = reg_read(REG_SDRAM_CONFIG_ADDR);
  442. if ((reg >> 15) & 1)
  443. ddr_width = 32;
  444. else
  445. ddr_width = 16;
  446. #endif
  447. #endif
  448. #ifdef DUNIT_SPD
  449. status = ddr3_dunit_setup(ecc, hclk_time_ps, &ddr_width);
  450. if (MV_OK != status) {
  451. DEBUG_INIT_S("DDR3 Training Sequence - FAILED (ddr3 Dunit Setup)\n");
  452. return status;
  453. }
  454. #endif
  455. /* Fix read ready phases for all SOC in reg 0x15C8 */
  456. reg = reg_read(REG_TRAINING_DEBUG_3_ADDR);
  457. reg &= ~(REG_TRAINING_DEBUG_3_MASK);
  458. reg |= 0x4; /* Phase 0 */
  459. reg &= ~(REG_TRAINING_DEBUG_3_MASK << REG_TRAINING_DEBUG_3_OFFS);
  460. reg |= (0x4 << (1 * REG_TRAINING_DEBUG_3_OFFS)); /* Phase 1 */
  461. reg &= ~(REG_TRAINING_DEBUG_3_MASK << (3 * REG_TRAINING_DEBUG_3_OFFS));
  462. reg |= (0x6 << (3 * REG_TRAINING_DEBUG_3_OFFS)); /* Phase 3 */
  463. reg &= ~(REG_TRAINING_DEBUG_3_MASK << (4 * REG_TRAINING_DEBUG_3_OFFS));
  464. reg |= (0x6 << (4 * REG_TRAINING_DEBUG_3_OFFS));
  465. reg &= ~(REG_TRAINING_DEBUG_3_MASK << (5 * REG_TRAINING_DEBUG_3_OFFS));
  466. reg |= (0x6 << (5 * REG_TRAINING_DEBUG_3_OFFS));
  467. reg_write(REG_TRAINING_DEBUG_3_ADDR, reg);
  468. #if defined(MV88F672X)
  469. /*
  470. * AxiBrespMode[8] = Compliant,
  471. * AxiAddrDecodeCntrl[11] = Internal,
  472. * AxiDataBusWidth[0] = 128bit
  473. */
  474. /* 0x14A8 - AXI Control Register */
  475. reg_write(REG_DRAM_AXI_CTRL_ADDR, 0);
  476. #else
  477. /* 0x14A8 - AXI Control Register */
  478. reg_write(REG_DRAM_AXI_CTRL_ADDR, 0x00000100);
  479. reg_write(REG_CDI_CONFIG_ADDR, 0x00000006);
  480. if ((ddr_width == 64) && (reg_read(REG_DDR_IO_ADDR) &
  481. (1 << REG_DDR_IO_CLK_RATIO_OFFS))) {
  482. /* 0x14A8 - AXI Control Register */
  483. reg_write(REG_DRAM_AXI_CTRL_ADDR, 0x00000101);
  484. reg_write(REG_CDI_CONFIG_ADDR, 0x00000007);
  485. }
  486. #endif
  487. #if !defined(MV88F67XX)
  488. /*
  489. * ARMADA-370 activate DLB later at the u-boot,
  490. * Armada38x - No DLB activation at this time
  491. */
  492. reg_write(DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0x18C01E);
  493. #if defined(MV88F78X60)
  494. /* WA according to eratta GL-8672902*/
  495. if (mv_ctrl_rev_get() == MV_78XX0_B0_REV)
  496. reg_write(DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0xc19e);
  497. #endif
  498. reg_write(DLB_AGING_REGISTER, 0x0f7f007f);
  499. reg_write(DLB_EVICTION_CONTROL_REG, 0x0);
  500. reg_write(DLB_EVICTION_TIMERS_REGISTER_REG, 0x00FF3C1F);
  501. reg_write(MBUS_UNITS_PRIORITY_CONTROL_REG, 0x55555555);
  502. reg_write(FABRIC_UNITS_PRIORITY_CONTROL_REG, 0xAA);
  503. reg_write(MBUS_UNITS_PREFETCH_CONTROL_REG, 0xffff);
  504. reg_write(FABRIC_UNITS_PREFETCH_CONTROL_REG, 0xf0f);
  505. #if defined(MV88F78X60)
  506. /* WA according to eratta GL-8672902 */
  507. if (mv_ctrl_rev_get() == MV_78XX0_B0_REV) {
  508. reg = reg_read(REG_STATIC_DRAM_DLB_CONTROL);
  509. reg |= DLB_ENABLE;
  510. reg_write(REG_STATIC_DRAM_DLB_CONTROL, reg);
  511. }
  512. #endif /* end defined(MV88F78X60) */
  513. #endif /* end !defined(MV88F67XX) */
  514. if (ddr3_get_log_level() >= MV_LOG_LEVEL_1)
  515. print_dunit_setup();
  516. /*
  517. * Stage 2 - Training Values Setup
  518. */
  519. #ifdef STATIC_TRAINING
  520. /*
  521. * DRAM Init - After all the D-unit values are set, its time to init
  522. * the D-unit
  523. */
  524. /* Wait for '0' */
  525. reg_write(REG_SDRAM_INIT_CTRL_ADDR, 0x1);
  526. do {
  527. reg = (reg_read(REG_SDRAM_INIT_CTRL_ADDR)) &
  528. (1 << REG_SDRAM_INIT_CTRL_OFFS);
  529. } while (reg);
  530. /* ddr3 init using static parameters - HW training is disabled */
  531. DEBUG_INIT_FULL_S("DDR3 Training Sequence - Static Training Parameters\n");
  532. ddr3_static_training_init();
  533. #if defined(MV88F78X60)
  534. /*
  535. * If ECC is enabled, need to scrub the U-Boot area memory region -
  536. * Run training function with Xor bypass just to scrub the memory
  537. */
  538. status = ddr3_hw_training(target_freq, ddr_width,
  539. 1, scrub_offs, scrub_size,
  540. dqs_clk_aligned, DDR3_TRAINING_DEBUG,
  541. REG_DIMM_SKIP_WL);
  542. if (MV_OK != status) {
  543. DEBUG_INIT_FULL_S("DDR3 Training Sequence - FAILED\n");
  544. return status;
  545. }
  546. #endif
  547. #else
  548. /* Set X-BAR windows for the training sequence */
  549. ddr3_save_and_set_training_windows(win_backup);
  550. /* Run DDR3 Training Sequence */
  551. /* DRAM Init */
  552. reg_write(REG_SDRAM_INIT_CTRL_ADDR, 0x1);
  553. do {
  554. reg = (reg_read(REG_SDRAM_INIT_CTRL_ADDR)) &
  555. (1 << REG_SDRAM_INIT_CTRL_OFFS);
  556. } while (reg); /* Wait for '0' */
  557. /* ddr3 init using DDR3 HW training procedure */
  558. DEBUG_INIT_FULL_S("DDR3 Training Sequence - HW Training Procedure\n");
  559. status = ddr3_hw_training(target_freq, ddr_width,
  560. 0, scrub_offs, scrub_size,
  561. dqs_clk_aligned, DDR3_TRAINING_DEBUG,
  562. REG_DIMM_SKIP_WL);
  563. if (MV_OK != status) {
  564. DEBUG_INIT_FULL_S("DDR3 Training Sequence - FAILED\n");
  565. return status;
  566. }
  567. #endif
  568. /*
  569. * Stage 3 - Finish
  570. */
  571. #if defined(MV88F78X60) || defined(MV88F672X)
  572. /* Disable ECC Ignore bit */
  573. reg = reg_read(REG_SDRAM_CONFIG_ADDR) &
  574. ~(1 << REG_SDRAM_CONFIG_IERR_OFFS);
  575. reg_write(REG_SDRAM_CONFIG_ADDR, reg);
  576. #endif
  577. #if !defined(STATIC_TRAINING)
  578. /* Restore and set windows */
  579. ddr3_restore_and_set_final_windows(win_backup);
  580. #endif
  581. /* Update DRAM init indication in bootROM register */
  582. reg = reg_read(REG_BOOTROM_ROUTINE_ADDR);
  583. reg_write(REG_BOOTROM_ROUTINE_ADDR,
  584. reg | (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS));
  585. #if !defined(MV88F67XX)
  586. #if defined(MV88F78X60)
  587. if (mv_ctrl_rev_get() == MV_78XX0_B0_REV) {
  588. reg = reg_read(REG_SDRAM_CONFIG_ADDR);
  589. if (ecc == 0)
  590. reg_write(REG_SDRAM_CONFIG_ADDR, reg | (1 << 19));
  591. }
  592. #endif /* end defined(MV88F78X60) */
  593. reg_write(DLB_EVICTION_CONTROL_REG, 0x9);
  594. reg = reg_read(REG_STATIC_DRAM_DLB_CONTROL);
  595. reg |= (DLB_ENABLE | DLB_WRITE_COALESING | DLB_AXI_PREFETCH_EN |
  596. DLB_MBUS_PREFETCH_EN | PREFETCH_NLNSZTR);
  597. reg_write(REG_STATIC_DRAM_DLB_CONTROL, reg);
  598. #endif /* end !defined(MV88F67XX) */
  599. #ifdef STATIC_TRAINING
  600. DEBUG_INIT_S("DDR3 Training Sequence - Ended Successfully (S)\n");
  601. #else
  602. DEBUG_INIT_S("DDR3 Training Sequence - Ended Successfully\n");
  603. #endif
  604. return MV_OK;
  605. }
  606. /*
  607. * Name: ddr3_get_cpu_freq
  608. * Desc: read S@R and return CPU frequency
  609. * Args:
  610. * Notes:
  611. * Returns: required value
  612. */
  613. u32 ddr3_get_cpu_freq(void)
  614. {
  615. u32 reg, cpu_freq;
  616. #if defined(MV88F672X)
  617. /* Read sample at reset setting */
  618. reg = reg_read(REG_SAMPLE_RESET_HIGH_ADDR); /* 0xE8200 */
  619. cpu_freq = (reg & REG_SAMPLE_RESET_CPU_FREQ_MASK) >>
  620. REG_SAMPLE_RESET_CPU_FREQ_OFFS;
  621. #else
  622. /* Read sample at reset setting */
  623. reg = reg_read(REG_SAMPLE_RESET_LOW_ADDR); /* 0x18230 [23:21] */
  624. #if defined(MV88F78X60)
  625. cpu_freq = (reg & REG_SAMPLE_RESET_CPU_FREQ_MASK) >>
  626. REG_SAMPLE_RESET_CPU_FREQ_OFFS;
  627. reg = reg_read(REG_SAMPLE_RESET_HIGH_ADDR); /* 0x18234 [20] */
  628. cpu_freq |= (((reg >> REG_SAMPLE_RESET_HIGH_CPU_FREQ_OFFS) & 0x1) << 3);
  629. #elif defined(MV88F67XX)
  630. cpu_freq = (reg & REG_SAMPLE_RESET_CPU_FREQ_MASK) >>
  631. REG_SAMPLE_RESET_CPU_FREQ_OFFS;
  632. #endif
  633. #endif
  634. return cpu_freq;
  635. }
  636. /*
  637. * Name: ddr3_get_fab_opt
  638. * Desc: read S@R and return CPU frequency
  639. * Args:
  640. * Notes:
  641. * Returns: required value
  642. */
  643. u32 ddr3_get_fab_opt(void)
  644. {
  645. __maybe_unused u32 reg, fab_opt;
  646. #if defined(MV88F672X)
  647. return 0; /* No fabric */
  648. #else
  649. /* Read sample at reset setting */
  650. reg = reg_read(REG_SAMPLE_RESET_LOW_ADDR);
  651. fab_opt = (reg & REG_SAMPLE_RESET_FAB_MASK) >>
  652. REG_SAMPLE_RESET_FAB_OFFS;
  653. #if defined(MV88F78X60)
  654. reg = reg_read(REG_SAMPLE_RESET_HIGH_ADDR);
  655. fab_opt |= (((reg >> 19) & 0x1) << 4);
  656. #endif
  657. return fab_opt;
  658. #endif
  659. }
  660. /*
  661. * Name: ddr3_get_vco_freq
  662. * Desc: read S@R and return VCO frequency
  663. * Args:
  664. * Notes:
  665. * Returns: required value
  666. */
  667. u32 ddr3_get_vco_freq(void)
  668. {
  669. u32 fab, cpu_freq, ui_vco_freq;
  670. fab = ddr3_get_fab_opt();
  671. cpu_freq = ddr3_get_cpu_freq();
  672. if (fab == 2 || fab == 3 || fab == 7 || fab == 8 || fab == 10 ||
  673. fab == 15 || fab == 17 || fab == 20)
  674. ui_vco_freq = cpu_freq + CLK_CPU;
  675. else
  676. ui_vco_freq = cpu_freq;
  677. return ui_vco_freq;
  678. }
  679. #ifdef STATIC_TRAINING
  680. /*
  681. * Name: ddr3_static_training_init - Init DDR3 Training with
  682. * static parameters
  683. * Desc: Use this routine to init the controller without the HW training
  684. * procedure
  685. * User must provide compatible header file with registers data.
  686. * Args: None.
  687. * Notes:
  688. * Returns: None.
  689. */
  690. void ddr3_static_training_init(void)
  691. {
  692. MV_DRAM_MODES *ddr_mode;
  693. u32 reg;
  694. int j;
  695. ddr_mode = ddr3_get_static_ddr_mode();
  696. j = 0;
  697. while (ddr_mode->vals[j].reg_addr != 0) {
  698. udelay(10); /* haim want to delay each write */
  699. reg_write(ddr_mode->vals[j].reg_addr,
  700. ddr_mode->vals[j].reg_value);
  701. if (ddr_mode->vals[j].reg_addr ==
  702. REG_PHY_REGISTRY_FILE_ACCESS_ADDR)
  703. do {
  704. reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) &
  705. REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE;
  706. } while (reg);
  707. j++;
  708. }
  709. }
  710. #endif
  711. /*
  712. * Name: ddr3_get_static_mc_value - Init Memory controller with static
  713. * parameters
  714. * Desc: Use this routine to init the controller without the HW training
  715. * procedure
  716. * User must provide compatible header file with registers data.
  717. * Args: None.
  718. * Notes:
  719. * Returns: None.
  720. */
  721. u32 ddr3_get_static_mc_value(u32 reg_addr, u32 offset1, u32 mask1, u32 offset2,
  722. u32 mask2)
  723. {
  724. u32 reg, tmp;
  725. reg = reg_read(reg_addr);
  726. tmp = (reg >> offset1) & mask1;
  727. if (mask2)
  728. tmp |= (reg >> offset2) & mask2;
  729. return tmp;
  730. }
  731. /*
  732. * Name: ddr3_get_static_ddr_mode - Init Memory controller with static
  733. * parameters
  734. * Desc: Use this routine to init the controller without the HW training
  735. * procedure
  736. * User must provide compatible header file with registers data.
  737. * Args: None.
  738. * Notes:
  739. * Returns: None.
  740. */
  741. __weak MV_DRAM_MODES *ddr3_get_static_ddr_mode(void)
  742. {
  743. u32 chip_board_rev, i;
  744. u32 size;
  745. /* Do not modify this code. relevant only for marvell Boards */
  746. #if defined(DB_78X60_PCAC)
  747. chip_board_rev = Z1_PCAC;
  748. #elif defined(DB_78X60_AMC)
  749. chip_board_rev = A0_AMC;
  750. #elif defined(DB_88F6710_PCAC)
  751. chip_board_rev = A0_PCAC;
  752. #elif defined(RD_88F6710)
  753. chip_board_rev = A0_RD;
  754. #elif defined(MV88F672X)
  755. chip_board_rev = mv_board_id_get();
  756. #else
  757. chip_board_rev = A0;
  758. #endif
  759. size = sizeof(ddr_modes) / sizeof(MV_DRAM_MODES);
  760. for (i = 0; i < size; i++) {
  761. if ((ddr3_get_cpu_freq() == ddr_modes[i].cpu_freq) &&
  762. (ddr3_get_fab_opt() == ddr_modes[i].fab_freq) &&
  763. (chip_board_rev == ddr_modes[i].chip_board_rev))
  764. return &ddr_modes[i];
  765. }
  766. return &ddr_modes[0];
  767. }
  768. #ifdef DUNIT_STATIC
  769. /*
  770. * Name: ddr3_static_mc_init - Init Memory controller with static parameters
  771. * Desc: Use this routine to init the controller without the HW training
  772. * procedure
  773. * User must provide compatible header file with registers data.
  774. * Args: None.
  775. * Notes:
  776. * Returns: None.
  777. */
  778. void ddr3_static_mc_init(void)
  779. {
  780. MV_DRAM_MODES *ddr_mode;
  781. u32 reg;
  782. int j;
  783. ddr_mode = ddr3_get_static_ddr_mode();
  784. j = 0;
  785. while (ddr_mode->regs[j].reg_addr != 0) {
  786. reg_write(ddr_mode->regs[j].reg_addr,
  787. ddr_mode->regs[j].reg_value);
  788. if (ddr_mode->regs[j].reg_addr ==
  789. REG_PHY_REGISTRY_FILE_ACCESS_ADDR)
  790. do {
  791. reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) &
  792. REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE;
  793. } while (reg);
  794. j++;
  795. }
  796. }
  797. #endif
  798. /*
  799. * Name: ddr3_check_config - Check user configurations: ECC/MultiCS
  800. * Desc:
  801. * Args: twsi Address
  802. * Notes: Only Available for ArmadaXP/Armada 370 DB boards
  803. * Returns: None.
  804. */
  805. int ddr3_check_config(u32 twsi_addr, MV_CONFIG_TYPE config_type)
  806. {
  807. #ifdef AUTO_DETECTION_SUPPORT
  808. u8 data = 0;
  809. int ret;
  810. int offset;
  811. if ((config_type == CONFIG_ECC) || (config_type == CONFIG_BUS_WIDTH))
  812. offset = 1;
  813. else
  814. offset = 0;
  815. ret = i2c_read(twsi_addr, offset, 1, (u8 *)&data, 1);
  816. if (!ret) {
  817. switch (config_type) {
  818. case CONFIG_ECC:
  819. if (data & 0x2)
  820. return 1;
  821. break;
  822. case CONFIG_BUS_WIDTH:
  823. if (data & 0x1)
  824. return 1;
  825. break;
  826. #ifdef DB_88F6710
  827. case CONFIG_MULTI_CS:
  828. if (CFG_MULTI_CS_MODE(data))
  829. return 1;
  830. break;
  831. #else
  832. case CONFIG_MULTI_CS:
  833. break;
  834. #endif
  835. }
  836. }
  837. #endif
  838. return 0;
  839. }
  840. #if defined(DB_88F78X60_REV2)
  841. /*
  842. * Name: ddr3_get_eprom_fabric - Get Fabric configuration from EPROM
  843. * Desc:
  844. * Args: twsi Address
  845. * Notes: Only Available for ArmadaXP DB Rev2 boards
  846. * Returns: None.
  847. */
  848. u8 ddr3_get_eprom_fabric(void)
  849. {
  850. #ifdef AUTO_DETECTION_SUPPORT
  851. u8 data = 0;
  852. int ret;
  853. ret = i2c_read(NEW_FABRIC_TWSI_ADDR, 1, 1, (u8 *)&data, 1);
  854. if (!ret)
  855. return data & 0x1F;
  856. #endif
  857. return 0;
  858. }
  859. #endif
  860. /*
  861. * Name: ddr3_cl_to_valid_cl - this return register matching CL value
  862. * Desc:
  863. * Args: clValue - the value
  864. * Notes:
  865. * Returns: required CL value
  866. */
  867. u32 ddr3_cl_to_valid_cl(u32 cl)
  868. {
  869. switch (cl) {
  870. case 5:
  871. return 2;
  872. break;
  873. case 6:
  874. return 4;
  875. break;
  876. case 7:
  877. return 6;
  878. break;
  879. case 8:
  880. return 8;
  881. break;
  882. case 9:
  883. return 10;
  884. break;
  885. case 10:
  886. return 12;
  887. break;
  888. case 11:
  889. return 14;
  890. break;
  891. case 12:
  892. return 1;
  893. break;
  894. case 13:
  895. return 3;
  896. break;
  897. case 14:
  898. return 5;
  899. break;
  900. default:
  901. return 2;
  902. }
  903. }
  904. /*
  905. * Name: ddr3_cl_to_valid_cl - this return register matching CL value
  906. * Desc:
  907. * Args: clValue - the value
  908. * Notes:
  909. * Returns: required CL value
  910. */
  911. u32 ddr3_valid_cl_to_cl(u32 ui_valid_cl)
  912. {
  913. switch (ui_valid_cl) {
  914. case 1:
  915. return 12;
  916. break;
  917. case 2:
  918. return 5;
  919. break;
  920. case 3:
  921. return 13;
  922. break;
  923. case 4:
  924. return 6;
  925. break;
  926. case 5:
  927. return 14;
  928. break;
  929. case 6:
  930. return 7;
  931. break;
  932. case 8:
  933. return 8;
  934. break;
  935. case 10:
  936. return 9;
  937. break;
  938. case 12:
  939. return 10;
  940. break;
  941. case 14:
  942. return 11;
  943. break;
  944. default:
  945. return 0;
  946. }
  947. }
  948. /*
  949. * Name: ddr3_get_cs_num_from_reg
  950. * Desc:
  951. * Args:
  952. * Notes:
  953. * Returns:
  954. */
  955. u32 ddr3_get_cs_num_from_reg(void)
  956. {
  957. u32 cs_ena = ddr3_get_cs_ena_from_reg();
  958. u32 cs_count = 0;
  959. u32 cs;
  960. for (cs = 0; cs < MAX_CS; cs++) {
  961. if (cs_ena & (1 << cs))
  962. cs_count++;
  963. }
  964. return cs_count;
  965. }
  966. /*
  967. * Name: ddr3_get_cs_ena_from_reg
  968. * Desc:
  969. * Args:
  970. * Notes:
  971. * Returns:
  972. */
  973. u32 ddr3_get_cs_ena_from_reg(void)
  974. {
  975. return reg_read(REG_DDR3_RANK_CTRL_ADDR) &
  976. REG_DDR3_RANK_CTRL_CS_ENA_MASK;
  977. }
  978. /*
  979. * mv_ctrl_rev_get - Get Marvell controller device revision number
  980. *
  981. * DESCRIPTION:
  982. * This function returns 8bit describing the device revision as defined
  983. * in PCI Express Class Code and Revision ID Register.
  984. *
  985. * INPUT:
  986. * None.
  987. *
  988. * OUTPUT:
  989. * None.
  990. *
  991. * RETURN:
  992. * 8bit desscribing Marvell controller revision number
  993. *
  994. */
  995. #if !defined(MV88F672X)
  996. u8 mv_ctrl_rev_get(void)
  997. {
  998. u8 rev_num;
  999. #if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  1000. /* Check pex power state */
  1001. u32 pex_power;
  1002. pex_power = mv_ctrl_pwr_clck_get(PEX_UNIT_ID, 0);
  1003. if (pex_power == 0)
  1004. mv_ctrl_pwr_clck_set(PEX_UNIT_ID, 0, 1);
  1005. #endif
  1006. rev_num = (u8)reg_read(PEX_CFG_DIRECT_ACCESS(0,
  1007. PCI_CLASS_CODE_AND_REVISION_ID));
  1008. #if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  1009. /* Return to power off state */
  1010. if (pex_power == 0)
  1011. mv_ctrl_pwr_clck_set(PEX_UNIT_ID, 0, 0);
  1012. #endif
  1013. return (rev_num & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
  1014. }
  1015. #endif
  1016. #if defined(MV88F672X)
  1017. void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps)
  1018. {
  1019. u32 tmp, hclk;
  1020. switch (freq_mode) {
  1021. case CPU_333MHz_DDR_167MHz_L2_167MHz:
  1022. hclk = 84;
  1023. tmp = DDR_100;
  1024. break;
  1025. case CPU_266MHz_DDR_266MHz_L2_133MHz:
  1026. case CPU_333MHz_DDR_222MHz_L2_167MHz:
  1027. case CPU_400MHz_DDR_200MHz_L2_200MHz:
  1028. case CPU_400MHz_DDR_267MHz_L2_200MHz:
  1029. case CPU_533MHz_DDR_267MHz_L2_267MHz:
  1030. case CPU_500MHz_DDR_250MHz_L2_250MHz:
  1031. case CPU_600MHz_DDR_300MHz_L2_300MHz:
  1032. case CPU_800MHz_DDR_267MHz_L2_400MHz:
  1033. case CPU_900MHz_DDR_300MHz_L2_450MHz:
  1034. tmp = DDR_300;
  1035. hclk = 150;
  1036. break;
  1037. case CPU_333MHz_DDR_333MHz_L2_167MHz:
  1038. case CPU_500MHz_DDR_334MHz_L2_250MHz:
  1039. case CPU_666MHz_DDR_333MHz_L2_333MHz:
  1040. tmp = DDR_333;
  1041. hclk = 165;
  1042. break;
  1043. case CPU_533MHz_DDR_356MHz_L2_267MHz:
  1044. tmp = DDR_360;
  1045. hclk = 180;
  1046. break;
  1047. case CPU_400MHz_DDR_400MHz_L2_200MHz:
  1048. case CPU_600MHz_DDR_400MHz_L2_300MHz:
  1049. case CPU_800MHz_DDR_400MHz_L2_400MHz:
  1050. case CPU_400MHz_DDR_400MHz_L2_400MHz:
  1051. tmp = DDR_400;
  1052. hclk = 200;
  1053. break;
  1054. case CPU_666MHz_DDR_444MHz_L2_333MHz:
  1055. case CPU_900MHz_DDR_450MHz_L2_450MHz:
  1056. tmp = DDR_444;
  1057. hclk = 222;
  1058. break;
  1059. case CPU_500MHz_DDR_500MHz_L2_250MHz:
  1060. case CPU_1000MHz_DDR_500MHz_L2_500MHz:
  1061. case CPU_1000MHz_DDR_500MHz_L2_333MHz:
  1062. tmp = DDR_500;
  1063. hclk = 250;
  1064. break;
  1065. case CPU_533MHz_DDR_533MHz_L2_267MHz:
  1066. case CPU_800MHz_DDR_534MHz_L2_400MHz:
  1067. case CPU_1100MHz_DDR_550MHz_L2_550MHz:
  1068. tmp = DDR_533;
  1069. hclk = 267;
  1070. break;
  1071. case CPU_600MHz_DDR_600MHz_L2_300MHz:
  1072. case CPU_900MHz_DDR_600MHz_L2_450MHz:
  1073. case CPU_1200MHz_DDR_600MHz_L2_600MHz:
  1074. tmp = DDR_600;
  1075. hclk = 300;
  1076. break;
  1077. case CPU_666MHz_DDR_666MHz_L2_333MHz:
  1078. case CPU_1000MHz_DDR_667MHz_L2_500MHz:
  1079. tmp = DDR_666;
  1080. hclk = 333;
  1081. break;
  1082. default:
  1083. *ddr_freq = 0;
  1084. *hclk_ps = 0;
  1085. break;
  1086. }
  1087. *ddr_freq = tmp; /* DDR freq define */
  1088. *hclk_ps = 1000000 / hclk; /* values are 1/HCLK in ps */
  1089. return;
  1090. }
  1091. #endif