ddrphy_utils.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2018 NXP
  4. */
  5. #include <common.h>
  6. #include <errno.h>
  7. #include <asm/io.h>
  8. #include <asm/arch/ddr.h>
  9. #include <asm/arch/clock.h>
  10. #include <asm/arch/ddr.h>
  11. #include <asm/arch/lpddr4_define.h>
  12. static inline void poll_pmu_message_ready(void)
  13. {
  14. unsigned int reg;
  15. do {
  16. reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
  17. } while (reg & 0x1);
  18. }
  19. static inline void ack_pmu_message_receive(void)
  20. {
  21. unsigned int reg;
  22. reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x0);
  23. do {
  24. reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
  25. } while (!(reg & 0x1));
  26. reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x1);
  27. }
  28. static inline unsigned int get_mail(void)
  29. {
  30. unsigned int reg;
  31. poll_pmu_message_ready();
  32. reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
  33. ack_pmu_message_receive();
  34. return reg;
  35. }
  36. static inline unsigned int get_stream_message(void)
  37. {
  38. unsigned int reg, reg2;
  39. poll_pmu_message_ready();
  40. reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
  41. reg2 = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0034);
  42. reg2 = (reg2 << 16) | reg;
  43. ack_pmu_message_receive();
  44. return reg2;
  45. }
  46. static inline void decode_major_message(unsigned int mail)
  47. {
  48. debug("[PMU Major message = 0x%08x]\n", mail);
  49. }
  50. static inline void decode_streaming_message(void)
  51. {
  52. unsigned int string_index, arg __maybe_unused;
  53. int i = 0;
  54. string_index = get_stream_message();
  55. debug("PMU String index = 0x%08x\n", string_index);
  56. while (i < (string_index & 0xffff)) {
  57. arg = get_stream_message();
  58. debug("arg[%d] = 0x%08x\n", i, arg);
  59. i++;
  60. }
  61. debug("\n");
  62. }
  63. void wait_ddrphy_training_complete(void)
  64. {
  65. unsigned int mail;
  66. while (1) {
  67. mail = get_mail();
  68. decode_major_message(mail);
  69. if (mail == 0x08) {
  70. decode_streaming_message();
  71. } else if (mail == 0x07) {
  72. debug("Training PASS\n");
  73. break;
  74. } else if (mail == 0xff) {
  75. printf("Training FAILED\n");
  76. break;
  77. }
  78. }
  79. }
  80. void ddrphy_init_set_dfi_clk(unsigned int drate)
  81. {
  82. switch (drate) {
  83. case 3200:
  84. dram_pll_init(MHZ(800));
  85. dram_disable_bypass();
  86. break;
  87. case 3000:
  88. dram_pll_init(MHZ(750));
  89. dram_disable_bypass();
  90. break;
  91. case 2400:
  92. dram_pll_init(MHZ(600));
  93. dram_disable_bypass();
  94. break;
  95. case 1600:
  96. dram_pll_init(MHZ(400));
  97. dram_disable_bypass();
  98. break;
  99. case 667:
  100. dram_pll_init(MHZ(167));
  101. dram_disable_bypass();
  102. break;
  103. case 400:
  104. dram_enable_bypass(MHZ(400));
  105. break;
  106. case 100:
  107. dram_enable_bypass(MHZ(100));
  108. break;
  109. default:
  110. return;
  111. }
  112. }
  113. void ddrphy_init_read_msg_block(enum fw_type type)
  114. {
  115. }
  116. void lpddr4_mr_write(unsigned int mr_rank, unsigned int mr_addr,
  117. unsigned int mr_data)
  118. {
  119. unsigned int tmp;
  120. /*
  121. * 1. Poll MRSTAT.mr_wr_busy until it is 0.
  122. * This checks that there is no outstanding MR transaction.
  123. * No writes should be performed to MRCTRL0 and MRCTRL1 if
  124. * MRSTAT.mr_wr_busy = 1.
  125. */
  126. do {
  127. tmp = reg32_read(DDRC_MRSTAT(0));
  128. } while (tmp & 0x1);
  129. /*
  130. * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank and
  131. * (for MRWs) MRCTRL1.mr_data to define the MR transaction.
  132. */
  133. reg32_write(DDRC_MRCTRL0(0), (mr_rank << 4));
  134. reg32_write(DDRC_MRCTRL1(0), (mr_addr << 8) | mr_data);
  135. reg32setbit(DDRC_MRCTRL0(0), 31);
  136. }
  137. unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr)
  138. {
  139. unsigned int tmp;
  140. reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x1);
  141. do {
  142. tmp = reg32_read(DDRC_MRSTAT(0));
  143. } while (tmp & 0x1);
  144. reg32_write(DDRC_MRCTRL0(0), (mr_rank << 4) | 0x1);
  145. reg32_write(DDRC_MRCTRL1(0), (mr_addr << 8));
  146. reg32setbit(DDRC_MRCTRL0(0), 31);
  147. do {
  148. tmp = reg32_read(DRC_PERF_MON_MRR0_DAT(0));
  149. } while ((tmp & 0x8) == 0);
  150. tmp = reg32_read(DRC_PERF_MON_MRR1_DAT(0));
  151. tmp = tmp & 0xff;
  152. reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x4);
  153. return tmp;
  154. }