dmc_init_exynos4.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Memory setup for board based on EXYNOS4210
  3. *
  4. * Copyright (C) 2013 Samsung Electronics
  5. * Rajeshwari Shinde <rajeshwari.s@samsung.com>
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. */
  25. #include <config.h>
  26. #include <asm/arch/dmc.h>
  27. #include "common_setup.h"
  28. #include "exynos4_setup.h"
  29. struct mem_timings mem = {
  30. .direct_cmd_msr = {
  31. DIRECT_CMD1, DIRECT_CMD2, DIRECT_CMD3, DIRECT_CMD4
  32. },
  33. .timingref = TIMINGREF_VAL,
  34. .timingrow = TIMINGROW_VAL,
  35. .timingdata = TIMINGDATA_VAL,
  36. .timingpower = TIMINGPOWER_VAL,
  37. .zqcontrol = ZQ_CONTROL_VAL,
  38. .control0 = CONTROL0_VAL,
  39. .control1 = CONTROL1_VAL,
  40. .control2 = CONTROL2_VAL,
  41. .concontrol = CONCONTROL_VAL,
  42. .prechconfig = PRECHCONFIG,
  43. .memcontrol = MEMCONTROL_VAL,
  44. .memconfig0 = MEMCONFIG0_VAL,
  45. .memconfig1 = MEMCONFIG1_VAL,
  46. .dll_resync = FORCE_DLL_RESYNC,
  47. .dll_on = DLL_CONTROL_ON,
  48. };
  49. static void phy_control_reset(int ctrl_no, struct exynos4_dmc *dmc)
  50. {
  51. if (ctrl_no) {
  52. writel((mem.control1 | (1 << mem.dll_resync)),
  53. &dmc->phycontrol1);
  54. writel((mem.control1 | (0 << mem.dll_resync)),
  55. &dmc->phycontrol1);
  56. } else {
  57. writel((mem.control0 | (0 << mem.dll_on)),
  58. &dmc->phycontrol0);
  59. writel((mem.control0 | (1 << mem.dll_on)),
  60. &dmc->phycontrol0);
  61. }
  62. }
  63. static void dmc_config_mrs(struct exynos4_dmc *dmc, int chip)
  64. {
  65. int i;
  66. unsigned long mask = 0;
  67. if (chip)
  68. mask = DIRECT_CMD_CHIP1_SHIFT;
  69. for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) {
  70. writel(mem.direct_cmd_msr[i] | mask,
  71. &dmc->directcmd);
  72. }
  73. }
  74. static void dmc_init(struct exynos4_dmc *dmc)
  75. {
  76. /*
  77. * DLL Parameter Setting:
  78. * Termination: Enable R/W
  79. * Phase Delay for DQS Cleaning: 180' Shift
  80. */
  81. writel(mem.control1, &dmc->phycontrol1);
  82. /*
  83. * ZQ Calibration
  84. * Termination: Disable
  85. * Auto Calibration Start: Enable
  86. */
  87. writel(mem.zqcontrol, &dmc->phyzqcontrol);
  88. sdelay(0x100000);
  89. /*
  90. * Update DLL Information:
  91. * Force DLL Resyncronization
  92. */
  93. phy_control_reset(1, dmc);
  94. phy_control_reset(0, dmc);
  95. /* Set DLL Parameters */
  96. writel(mem.control1, &dmc->phycontrol1);
  97. /* DLL Start */
  98. writel((mem.control0 | CTRL_START | CTRL_DLL_ON), &dmc->phycontrol0);
  99. writel(mem.control2, &dmc->phycontrol2);
  100. /* Set Clock Ratio of Bus clock to Memory Clock */
  101. writel(mem.concontrol, &dmc->concontrol);
  102. /*
  103. * Memor Burst length: 8
  104. * Number of chips: 2
  105. * Memory Bus width: 32 bit
  106. * Memory Type: DDR3
  107. * Additional Latancy for PLL: 1 Cycle
  108. */
  109. writel(mem.memcontrol, &dmc->memcontrol);
  110. writel(mem.memconfig0, &dmc->memconfig0);
  111. writel(mem.memconfig1, &dmc->memconfig1);
  112. /* Config Precharge Policy */
  113. writel(mem.prechconfig, &dmc->prechconfig);
  114. /*
  115. * TimingAref, TimingRow, TimingData, TimingPower Setting:
  116. * Values as per Memory AC Parameters
  117. */
  118. writel(mem.timingref, &dmc->timingref);
  119. writel(mem.timingrow, &dmc->timingrow);
  120. writel(mem.timingdata, &dmc->timingdata);
  121. writel(mem.timingpower, &dmc->timingpower);
  122. /* Chip0: NOP Command: Assert and Hold CKE to high level */
  123. writel(DIRECT_CMD_NOP, &dmc->directcmd);
  124. sdelay(0x100000);
  125. /* Chip0: EMRS2, EMRS3, EMRS, MRS Commands Using Direct Command */
  126. dmc_config_mrs(dmc, 0);
  127. sdelay(0x100000);
  128. /* Chip0: ZQINIT */
  129. writel(DIRECT_CMD_ZQ, &dmc->directcmd);
  130. sdelay(0x100000);
  131. writel((DIRECT_CMD_NOP | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd);
  132. sdelay(0x100000);
  133. /* Chip1: EMRS2, EMRS3, EMRS, MRS Commands Using Direct Command */
  134. dmc_config_mrs(dmc, 1);
  135. sdelay(0x100000);
  136. /* Chip1: ZQINIT */
  137. writel((DIRECT_CMD_ZQ | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd);
  138. sdelay(0x100000);
  139. phy_control_reset(1, dmc);
  140. sdelay(0x100000);
  141. /* turn on DREX0, DREX1 */
  142. writel((mem.concontrol | AREF_EN), &dmc->concontrol);
  143. }
  144. void mem_ctrl_init(int reset)
  145. {
  146. struct exynos4_dmc *dmc;
  147. /*
  148. * Async bridge configuration at CPU_core:
  149. * 1: half_sync
  150. * 0: full_sync
  151. */
  152. writel(1, ASYNC_CONFIG);
  153. #ifdef CONFIG_ORIGEN
  154. /* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */
  155. writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE +
  156. APB_SFR_INTERLEAVE_CONF_OFFSET);
  157. /* Update MIU Configuration */
  158. writel(APB_SFR_ARBRITATION_CONF_VAL, EXYNOS4_MIU_BASE +
  159. APB_SFR_ARBRITATION_CONF_OFFSET);
  160. #else
  161. writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE +
  162. APB_SFR_INTERLEAVE_CONF_OFFSET);
  163. writel(INTERLEAVE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE +
  164. ABP_SFR_INTERLEAVE_ADDRMAP_START_OFFSET);
  165. writel(INTERLEAVE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE +
  166. ABP_SFR_INTERLEAVE_ADDRMAP_END_OFFSET);
  167. writel(INTERLEAVE_ADDR_MAP_EN, EXYNOS4_MIU_BASE +
  168. ABP_SFR_SLV_ADDRMAP_CONF_OFFSET);
  169. #ifdef CONFIG_MIU_LINEAR
  170. writel(SLAVE0_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE +
  171. ABP_SFR_SLV0_SINGLE_ADDRMAP_START_OFFSET);
  172. writel(SLAVE0_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE +
  173. ABP_SFR_SLV0_SINGLE_ADDRMAP_END_OFFSET);
  174. writel(SLAVE1_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE +
  175. ABP_SFR_SLV1_SINGLE_ADDRMAP_START_OFFSET);
  176. writel(SLAVE1_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE +
  177. ABP_SFR_SLV1_SINGLE_ADDRMAP_END_OFFSET);
  178. writel(APB_SFR_SLV_ADDR_MAP_CONF_VAL, EXYNOS4_MIU_BASE +
  179. ABP_SFR_SLV_ADDRMAP_CONF_OFFSET);
  180. #endif
  181. #endif
  182. /* DREX0 */
  183. dmc = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl();
  184. dmc_init(dmc);
  185. dmc = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl()
  186. + DMC_OFFSET);
  187. dmc_init(dmc);
  188. }