dmc_common.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Mem setup common file for different types of DDR present on Exynos boards.
  3. *
  4. * Copyright (C) 2012 Samsung Electronics
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <asm/arch/spl.h>
  10. #include "clock_init.h"
  11. #include "common_setup.h"
  12. #include "exynos5_setup.h"
  13. #define ZQ_INIT_TIMEOUT 10000
  14. int dmc_config_zq(struct mem_timings *mem, uint32_t *phy0_con16,
  15. uint32_t *phy1_con16, uint32_t *phy0_con17,
  16. uint32_t *phy1_con17)
  17. {
  18. unsigned long val = 0;
  19. int i;
  20. /*
  21. * ZQ Calibration:
  22. * Select Driver Strength,
  23. * long calibration for manual calibration
  24. */
  25. val = PHY_CON16_RESET_VAL;
  26. val |= mem->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT;
  27. val |= mem->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT;
  28. val |= ZQ_CLK_DIV_EN;
  29. writel(val, phy0_con16);
  30. writel(val, phy1_con16);
  31. /* Disable termination */
  32. if (mem->zq_mode_noterm)
  33. val |= PHY_CON16_ZQ_MODE_NOTERM_MASK;
  34. writel(val, phy0_con16);
  35. writel(val, phy1_con16);
  36. /* ZQ_MANUAL_START: Enable */
  37. val |= ZQ_MANUAL_STR;
  38. writel(val, phy0_con16);
  39. writel(val, phy1_con16);
  40. /* ZQ_MANUAL_START: Disable */
  41. val &= ~ZQ_MANUAL_STR;
  42. /*
  43. * Since we are manaully calibrating the ZQ values,
  44. * we are looping for the ZQ_init to complete.
  45. */
  46. i = ZQ_INIT_TIMEOUT;
  47. while ((readl(phy0_con17) & ZQ_DONE) != ZQ_DONE && i > 0) {
  48. sdelay(100);
  49. i--;
  50. }
  51. if (!i)
  52. return -1;
  53. writel(val, phy0_con16);
  54. i = ZQ_INIT_TIMEOUT;
  55. while ((readl(phy1_con17) & ZQ_DONE) != ZQ_DONE && i > 0) {
  56. sdelay(100);
  57. i--;
  58. }
  59. if (!i)
  60. return -1;
  61. writel(val, phy1_con16);
  62. return 0;
  63. }
  64. void update_reset_dll(uint32_t *phycontrol0, enum ddr_mode mode)
  65. {
  66. unsigned long val;
  67. if (mode == DDR_MODE_DDR3) {
  68. val = MEM_TERM_EN | PHY_TERM_EN | DMC_CTRL_SHGATE;
  69. writel(val, phycontrol0);
  70. }
  71. /* Update DLL Information: Force DLL Resyncronization */
  72. val = readl(phycontrol0);
  73. val |= FP_RSYNC;
  74. writel(val, phycontrol0);
  75. /* Reset Force DLL Resyncronization */
  76. val = readl(phycontrol0);
  77. val &= ~FP_RSYNC;
  78. writel(val, phycontrol0);
  79. }
  80. void dmc_config_mrs(struct mem_timings *mem, uint32_t *directcmd)
  81. {
  82. int channel, chip;
  83. for (channel = 0; channel < mem->dmc_channels; channel++) {
  84. unsigned long mask;
  85. mask = channel << DIRECT_CMD_CHANNEL_SHIFT;
  86. for (chip = 0; chip < mem->chips_to_configure; chip++) {
  87. int i;
  88. mask |= chip << DIRECT_CMD_CHIP_SHIFT;
  89. /* Sending NOP command */
  90. writel(DIRECT_CMD_NOP | mask, directcmd);
  91. /*
  92. * TODO(alim.akhtar@samsung.com): Do we need these
  93. * delays? This one and the next were not there for
  94. * DDR3.
  95. */
  96. sdelay(0x10000);
  97. /* Sending EMRS/MRS commands */
  98. for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) {
  99. writel(mem->direct_cmd_msr[i] | mask,
  100. directcmd);
  101. sdelay(0x10000);
  102. }
  103. if (mem->send_zq_init) {
  104. /* Sending ZQINIT command */
  105. writel(DIRECT_CMD_ZQINIT | mask,
  106. directcmd);
  107. sdelay(10000);
  108. }
  109. }
  110. }
  111. }
  112. void dmc_config_prech(struct mem_timings *mem, uint32_t *directcmd)
  113. {
  114. int channel, chip;
  115. for (channel = 0; channel < mem->dmc_channels; channel++) {
  116. unsigned long mask;
  117. mask = channel << DIRECT_CMD_CHANNEL_SHIFT;
  118. for (chip = 0; chip < mem->chips_per_channel; chip++) {
  119. mask |= chip << DIRECT_CMD_CHIP_SHIFT;
  120. /* PALL (all banks precharge) CMD */
  121. writel(DIRECT_CMD_PALL | mask, directcmd);
  122. sdelay(0x10000);
  123. }
  124. }
  125. }
  126. void mem_ctrl_init(int reset)
  127. {
  128. struct spl_machine_param *param = spl_get_machine_params();
  129. struct mem_timings *mem;
  130. int ret;
  131. mem = clock_get_mem_timings();
  132. /* If there are any other memory variant, add their init call below */
  133. if (param->mem_type == DDR_MODE_DDR3) {
  134. ret = ddr3_mem_ctrl_init(mem, reset);
  135. if (ret) {
  136. /* will hang if failed to init memory control */
  137. while (1)
  138. ;
  139. }
  140. } else {
  141. /* will hang if unknow memory type */
  142. while (1)
  143. ;
  144. }
  145. }