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