dram_port.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (C) 2018 Marvell International Ltd.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. * https://spdx.org/licenses
  6. */
  7. #include <arch_helpers.h>
  8. #include <common/debug.h>
  9. #include <drivers/mentor/mi2cv.h>
  10. #include <lib/mmio.h>
  11. #include <mv_ddr_if.h>
  12. #include <mvebu_def.h>
  13. #include <plat_marvell.h>
  14. #define MVEBU_CP_MPP_CTRL37_OFFS 20
  15. #define MVEBU_CP_MPP_CTRL38_OFFS 24
  16. #define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2
  17. #define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2
  18. #define MVEBU_MPP_CTRL_MASK 0xf
  19. /*
  20. * This struct provides the DRAM training code with
  21. * the appropriate board DRAM configuration
  22. */
  23. static struct mv_ddr_topology_map board_topology_map = {
  24. /* Board with 1CS 8Gb x4 devices of Micron 2400T */
  25. DEBUG_LEVEL_ERROR,
  26. 0x1, /* active interfaces */
  27. /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
  28. { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */
  29. {0x1, 0x0, 0, 0},
  30. {0x1, 0x0, 0, 0},
  31. {0x1, 0x0, 0, 0},
  32. {0x1, 0x0, 0, 0},
  33. {0x1, 0x0, 0, 0},
  34. {0x1, 0x0, 0, 0},
  35. {0x1, 0x0, 0, 0},
  36. {0x1, 0x0, 0, 0} },
  37. /* TODO: double check if the speed bin is 2400T */
  38. SPEED_BIN_DDR_2400T, /* speed_bin */
  39. MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
  40. MV_DDR_DIE_CAP_8GBIT, /* die capacity */
  41. MV_DDR_FREQ_SAR, /* frequency */
  42. 0, 0, /* cas_l, cas_wl */
  43. MV_DDR_TEMP_LOW} }, /* temperature */
  44. MV_DDR_64BIT_BUS_MASK, /* subphys mask */
  45. MV_DDR_CFG_SPD, /* ddr configuration data source */
  46. NOT_COMBINED, /* ddr twin-die combined*/
  47. { {0} }, /* raw spd data */
  48. {0}, /* timing parameters */
  49. { /* electrical configuration */
  50. { /* memory electrical configuration */
  51. MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
  52. {
  53. MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
  54. MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
  55. },
  56. {
  57. MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
  58. MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
  59. },
  60. MV_DDR_DIC_RZQ_DIV7 /* dic */
  61. },
  62. { /* phy electrical configuration */
  63. MV_DDR_OHM_30, /* data_drv_p */
  64. MV_DDR_OHM_30, /* data_drv_n */
  65. MV_DDR_OHM_30, /* ctrl_drv_p */
  66. MV_DDR_OHM_30, /* ctrl_drv_n */
  67. {
  68. MV_DDR_OHM_60, /* odt_p 1cs */
  69. MV_DDR_OHM_120 /* odt_p 2cs */
  70. },
  71. {
  72. MV_DDR_OHM_60, /* odt_n 1cs */
  73. MV_DDR_OHM_120 /* odt_n 2cs */
  74. },
  75. },
  76. { /* mac electrical configuration */
  77. MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
  78. MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
  79. MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
  80. },
  81. }
  82. };
  83. struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
  84. {
  85. /* Return the board topology as defined in the board code */
  86. return &board_topology_map;
  87. }
  88. static void mpp_config(void)
  89. {
  90. uint32_t val;
  91. uintptr_t reg = MVEBU_CP_MPP_REGS(0, 4);
  92. /* configure CP0 MPP 37 and 38 to i2c */
  93. val = mmio_read_32(reg);
  94. val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
  95. (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
  96. val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << MVEBU_CP_MPP_CTRL37_OFFS) |
  97. (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << MVEBU_CP_MPP_CTRL38_OFFS);
  98. mmio_write_32(reg, val);
  99. }
  100. /*
  101. * This function may modify the default DRAM parameters
  102. * based on information received from SPD or bootloader
  103. * configuration located on non volatile storage
  104. */
  105. void plat_marvell_dram_update_topology(void)
  106. {
  107. struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
  108. INFO("Gathering DRAM information\n");
  109. if (tm->cfg_src == MV_DDR_CFG_SPD) {
  110. /* configure MPPs to enable i2c */
  111. mpp_config();
  112. /* initialize the i2c */
  113. i2c_init((void *)MVEBU_CP0_I2C_BASE);
  114. /* select SPD memory page 0 to access DRAM configuration */
  115. i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 0);
  116. /* read data from spd */
  117. i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
  118. sizeof(tm->spd_data.all_bytes));
  119. }
  120. }