ddr.c 3.8 KB

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