ddrphy-training.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (C) 2011-2014 Panasonic Corporation
  3. * Copyright (C) 2015-2016 Socionext Inc.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <linux/bitops.h>
  8. #include <linux/delay.h>
  9. #include <linux/errno.h>
  10. #include <linux/io.h>
  11. #include <linux/kernel.h>
  12. #include <linux/printk.h>
  13. #include <time.h>
  14. #include "ddrphy-init.h"
  15. #include "ddrphy-regs.h"
  16. /* for LD4, Pro4, sLD8 */
  17. #define NR_DATX8_PER_DDRPHY 2
  18. void ddrphy_prepare_training(void __iomem *phy_base, int rank)
  19. {
  20. void __iomem *dx_base = phy_base + PHY_DX_BASE;
  21. int dx;
  22. u32 tmp;
  23. for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) {
  24. tmp = readl(dx_base + PHY_DX_GCR);
  25. /* Specify the rank that should be write leveled */
  26. tmp &= ~PHY_DX_GCR_WLRKEN_MASK;
  27. tmp |= (1 << (PHY_DX_GCR_WLRKEN_SHIFT + rank)) &
  28. PHY_DX_GCR_WLRKEN_MASK;
  29. writel(tmp, dx_base + PHY_DX_GCR);
  30. dx_base += PHY_DX_STRIDE;
  31. }
  32. tmp = readl(phy_base + PHY_DTCR);
  33. /* Specify the rank used during data bit deskew and eye centering */
  34. tmp &= ~PHY_DTCR_DTRANK_MASK;
  35. tmp |= (rank << PHY_DTCR_DTRANK_SHIFT) & PHY_DTCR_DTRANK_MASK;
  36. /* Use Multi-Purpose Register for DQS gate training */
  37. tmp |= PHY_DTCR_DTMPR;
  38. /* Specify the rank enabled for data-training */
  39. tmp &= ~PHY_DTCR_RANKEN_MASK;
  40. tmp |= (1 << (PHY_DTCR_RANKEN_SHIFT + rank)) & PHY_DTCR_RANKEN_MASK;
  41. writel(tmp, phy_base + PHY_DTCR);
  42. }
  43. struct ddrphy_init_sequence {
  44. char *description;
  45. u32 init_flag;
  46. u32 done_flag;
  47. u32 err_flag;
  48. };
  49. static const struct ddrphy_init_sequence init_sequence[] = {
  50. {
  51. "DRAM Initialization",
  52. PHY_PIR_DRAMRST | PHY_PIR_DRAMINIT,
  53. PHY_PGSR0_DIDONE,
  54. PHY_PGSR0_DIERR
  55. },
  56. {
  57. "Write Leveling",
  58. PHY_PIR_WL,
  59. PHY_PGSR0_WLDONE,
  60. PHY_PGSR0_WLERR
  61. },
  62. {
  63. "Read DQS Gate Training",
  64. PHY_PIR_QSGATE,
  65. PHY_PGSR0_QSGDONE,
  66. PHY_PGSR0_QSGERR
  67. },
  68. {
  69. "Write Leveling Adjustment",
  70. PHY_PIR_WLADJ,
  71. PHY_PGSR0_WLADONE,
  72. PHY_PGSR0_WLAERR
  73. },
  74. {
  75. "Read Bit Deskew",
  76. PHY_PIR_RDDSKW,
  77. PHY_PGSR0_RDDONE,
  78. PHY_PGSR0_RDERR
  79. },
  80. {
  81. "Write Bit Deskew",
  82. PHY_PIR_WRDSKW,
  83. PHY_PGSR0_WDDONE,
  84. PHY_PGSR0_WDERR
  85. },
  86. {
  87. "Read Eye Training",
  88. PHY_PIR_RDEYE,
  89. PHY_PGSR0_REDONE,
  90. PHY_PGSR0_REERR
  91. },
  92. {
  93. "Write Eye Training",
  94. PHY_PIR_WREYE,
  95. PHY_PGSR0_WEDONE,
  96. PHY_PGSR0_WEERR
  97. }
  98. };
  99. int ddrphy_training(void __iomem *phy_base)
  100. {
  101. int i;
  102. u32 pgsr0;
  103. u32 init_flag = PHY_PIR_INIT;
  104. u32 done_flag = PHY_PGSR0_IDONE;
  105. int timeout = 50000; /* 50 msec is long enough */
  106. #ifdef DEBUG
  107. ulong start = get_timer(0);
  108. #endif
  109. for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
  110. init_flag |= init_sequence[i].init_flag;
  111. done_flag |= init_sequence[i].done_flag;
  112. }
  113. writel(init_flag, phy_base + PHY_PIR);
  114. do {
  115. if (--timeout < 0) {
  116. pr_err("timeout during DDR training\n");
  117. return -ETIMEDOUT;
  118. }
  119. udelay(1);
  120. pgsr0 = readl(phy_base + PHY_PGSR0);
  121. } while ((pgsr0 & done_flag) != done_flag);
  122. for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
  123. if (pgsr0 & init_sequence[i].err_flag) {
  124. pr_err("%s failed\n", init_sequence[i].description);
  125. return -EIO;
  126. }
  127. }
  128. #ifdef DEBUG
  129. pr_debug("DDR training: elapsed time %ld msec\n", get_timer(start));
  130. #endif
  131. return 0;
  132. }