ddr.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2010 Extreme Engineering Solutions, Inc.
  4. * Copyright 2007-2008 Freescale Semiconductor, Inc.
  5. */
  6. #include <common.h>
  7. #include <i2c.h>
  8. #include <fsl_ddr_sdram.h>
  9. #include <fsl_ddr_dimm_params.h>
  10. void get_spd(ddr3_spd_eeprom_t *spd, u8 i2c_address)
  11. {
  12. i2c_read(i2c_address, SPD_EEPROM_OFFSET, 2, (uchar *)spd,
  13. sizeof(ddr3_spd_eeprom_t));
  14. }
  15. /*
  16. * There are traditionally three board-specific SDRAM timing parameters
  17. * which must be calculated based on the particular PCB artwork. These are:
  18. * 1.) CPO (Read Capture Delay)
  19. * - TIMING_CFG_2 register
  20. * Source: Calculation based on board trace lengths and
  21. * chip-specific internal delays.
  22. * 2.) CLK_ADJUST (Clock and Addr/Cmd alignment control)
  23. * - DDR_SDRAM_CLK_CNTL register
  24. * Source: Signal Integrity Simulations
  25. * 3.) 2T Timing on Addr/Ctl
  26. * - TIMING_CFG_2 register
  27. * Source: Signal Integrity Simulations
  28. * Usually only needed with heavy load/very high speed (>DDR2-800)
  29. *
  30. * ====== XPedite550x DDR3-800 read delay calculations ======
  31. *
  32. * The P2020 processor provides an autoleveling option. Setting CPO to
  33. * 0x1f enables this auto configuration.
  34. */
  35. typedef struct {
  36. unsigned short datarate_mhz_low;
  37. unsigned short datarate_mhz_high;
  38. unsigned char clk_adjust;
  39. unsigned char cpo;
  40. } board_specific_parameters_t;
  41. const board_specific_parameters_t board_specific_parameters[][20] = {
  42. {
  43. /* Controller 0 */
  44. {
  45. /* DDR3-600/667 */
  46. .datarate_mhz_low = 500,
  47. .datarate_mhz_high = 750,
  48. .clk_adjust = 5,
  49. .cpo = 31,
  50. },
  51. {
  52. /* DDR3-800 */
  53. .datarate_mhz_low = 750,
  54. .datarate_mhz_high = 850,
  55. .clk_adjust = 5,
  56. .cpo = 31,
  57. },
  58. },
  59. };
  60. void fsl_ddr_board_options(memctl_options_t *popts,
  61. dimm_params_t *pdimm,
  62. unsigned int ctrl_num)
  63. {
  64. const board_specific_parameters_t *pbsp =
  65. &(board_specific_parameters[ctrl_num][0]);
  66. u32 num_params = sizeof(board_specific_parameters[ctrl_num]) /
  67. sizeof(board_specific_parameters[0][0]);
  68. u32 i;
  69. ulong ddr_freq;
  70. /*
  71. * Set odt_rd_cfg and odt_wr_cfg. If the there is only one dimm in
  72. * that controller, set odt_wr_cfg to 4 for CS0, and 0 to CS1. If
  73. * there are two dimms in the controller, set odt_rd_cfg to 3 and
  74. * odt_wr_cfg to 3 for the even CS, 0 for the odd CS.
  75. */
  76. for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
  77. if (i&1) { /* odd CS */
  78. popts->cs_local_opts[i].odt_rd_cfg = 0;
  79. popts->cs_local_opts[i].odt_wr_cfg = 0;
  80. } else { /* even CS */
  81. if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) {
  82. popts->cs_local_opts[i].odt_rd_cfg = 0;
  83. popts->cs_local_opts[i].odt_wr_cfg = 4;
  84. } else if (CONFIG_DIMM_SLOTS_PER_CTLR == 2) {
  85. popts->cs_local_opts[i].odt_rd_cfg = 3;
  86. popts->cs_local_opts[i].odt_wr_cfg = 3;
  87. }
  88. }
  89. }
  90. /*
  91. * Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
  92. * freqency and n_banks specified in board_specific_parameters table.
  93. */
  94. ddr_freq = get_ddr_freq(0) / 1000000;
  95. for (i = 0; i < num_params; i++) {
  96. if (ddr_freq >= pbsp->datarate_mhz_low &&
  97. ddr_freq <= pbsp->datarate_mhz_high) {
  98. popts->clk_adjust = pbsp->clk_adjust;
  99. popts->cpo_override = pbsp->cpo;
  100. popts->twot_en = 0;
  101. break;
  102. }
  103. pbsp++;
  104. }
  105. if (i == num_params) {
  106. printf("Warning: board specific timing not found "
  107. "for data rate %lu MT/s!\n", ddr_freq);
  108. }
  109. /*
  110. * Factors to consider for half-strength driver enable:
  111. * - number of DIMMs installed
  112. */
  113. popts->half_strength_driver_enable = 0;
  114. /*
  115. * Enable on-die termination.
  116. * From the Micron Technical Node TN-41-04, RTT_Nom should typically
  117. * be 30 to 40 ohms, while RTT_WR should be 120 ohms. Setting RTT_WR
  118. * is handled in the Freescale DDR3 driver. Set RTT_Nom here.
  119. */
  120. popts->rtt_override = 1;
  121. popts->rtt_override_value = 3;
  122. }