1 /*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8 #include <arch_helpers.h>
9 #include <common/debug.h>
10 #include <drivers/mentor/mi2cv.h>
11 #include <lib/mmio.h>
12
13 #include <mv_ddr_if.h>
14 #include <mvebu_def.h>
15 #include <plat_marvell.h>
16
17 #define MVEBU_CP_MPP_CTRL37_OFFS 20
18 #define MVEBU_CP_MPP_CTRL38_OFFS 24
19 #define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2
20 #define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2
21
22 #define MVEBU_MPP_CTRL_MASK 0xf
23
24 /*
25 * This struct provides the DRAM training code with
26 * the appropriate board DRAM configuration
27 */
28 struct mv_ddr_iface dram_iface_ap0 = {
29 .ap_base = MVEBU_REGS_BASE_AP(0),
30 .state = MV_DDR_IFACE_NRDY,
31 .validation = MV_DDR_MEMORY_CHECK,
32 .sscg = SSCG_EN,
33 .id = 0,
34 .iface_base_addr = 0,
35 .tm = {
36 DEBUG_LEVEL_ERROR,
37 0x1, /* active interfaces */
38 /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
39 { { { {0x1, 0x0, 0, 0},
40 {0x1, 0x0, 0, 0},
41 {0x1, 0x0, 0, 0},
42 {0x1, 0x0, 0, 0},
43 {0x1, 0x0, 0, 0},
44 {0x1, 0x0, 0, 0},
45 {0x1, 0x0, 0, 0},
46 {0x1, 0x0, 0, 0},
47 {0x1, 0x0, 0, 0} },
48 SPEED_BIN_DDR_2400T, /* speed_bin */
49 MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
50 MV_DDR_DIE_CAP_8GBIT, /* die capacity */
51 MV_DDR_FREQ_SAR, /* frequency */
52 0, 0, /* cas_l, cas_wl */
53 MV_DDR_TEMP_LOW} }, /* temperature */
54 #if DDR32
55 MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
56 #else
57 MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
58 #endif
59 MV_DDR_CFG_SPD, /* ddr configuration data src */
60 NOT_COMBINED, /* ddr twin-die combined*/
61 { {0} }, /* raw spd data */
62 {0}, /* timing parameters */
63 { /* electrical configuration */
64 { /* memory electrical configuration */
65 MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
66 { /* rtt_park 1cs */
67 MV_DDR_RTT_NOM_PARK_RZQ_DIV4,
68 /* rtt_park 2cs */
69 MV_DDR_RTT_NOM_PARK_RZQ_DIV1
70 },
71 { /* rtt_wr 1cs */
72 MV_DDR_RTT_WR_DYN_ODT_OFF,
73 /* rtt_wr 2cs */
74 MV_DDR_RTT_WR_RZQ_DIV2
75 },
76 MV_DDR_DIC_RZQ_DIV7 /* dic */
77 },
78 { /* phy electrical configuration */
79 MV_DDR_OHM_30, /* data_drv_p */
80 MV_DDR_OHM_30, /* data_drv_n */
81 MV_DDR_OHM_30, /* ctrl_drv_p */
82 MV_DDR_OHM_30, /* ctrl_drv_n */
83 {
84 MV_DDR_OHM_60, /* odt_p 1cs */
85 MV_DDR_OHM_120 /* odt_p 2cs */
86 },
87 {
88 MV_DDR_OHM_60, /* odt_n 1cs */
89 MV_DDR_OHM_120 /* odt_n 2cs */
90 },
91 },
92 { /* mac electrical configuration */
93 MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
94 MV_DDR_ODT_CFG_ALWAYS_ON,/* odtcfg_write */
95 MV_DDR_ODT_CFG_NORMAL /* odtcfg_read */
96 },
97 },
98 },
99 };
100
101 /* Pointer to the first DRAM interface in the system */
102 struct mv_ddr_iface *ptr_iface = &dram_iface_ap0;
103
mv_ddr_iface_get(void)104 struct mv_ddr_iface *mv_ddr_iface_get(void)
105 {
106 /* Return current ddr interface */
107 return ptr_iface;
108 }
109
mv_ddr_topology_map_get(void)110 struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
111 {
112 /* Return the board topology as defined in the board code */
113 return &ptr_iface->tm;
114 }
115
mpp_config(void)116 static void mpp_config(void)
117 {
118 uintptr_t reg;
119 uint32_t val;
120
121 reg = MVEBU_CP_MPP_REGS(0, 4);
122 /* configure CP0 MPP 37 and 38 to i2c */
123 val = mmio_read_32(reg);
124 val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
125 (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
126 val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA <<
127 MVEBU_CP_MPP_CTRL37_OFFS) |
128 (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA <<
129 MVEBU_CP_MPP_CTRL38_OFFS);
130 mmio_write_32(reg, val);
131 }
132
133 /*
134 * This function may modify the default DRAM parameters
135 * based on information received from SPD or bootloader
136 * configuration located on non volatile storage
137 */
plat_marvell_dram_update_topology(void)138 void plat_marvell_dram_update_topology(void)
139 {
140 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
141
142 INFO("Gathering DRAM information\n");
143
144 if (tm->cfg_src == MV_DDR_CFG_SPD) {
145 /* configure MPPs to enable i2c */
146 mpp_config();
147
148 /* initialize i2c */
149 i2c_init((void *)MVEBU_CP0_I2C_BASE);
150
151 /* select SPD memory page 0 to access DRAM configuration */
152 i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 0);
153
154 /* read data from spd */
155 i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
156 sizeof(tm->spd_data.all_bytes));
157 }
158 }
159