dmc_common.c 3.7 KB

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