2 * Copyright (C) Marvell International Ltd. and its affiliates
4 * SPDX-License-Identifier: GPL-2.0
11 #include <asm/arch/cpu.h>
12 #include <asm/arch/soc.h>
15 #include "sys_env_lib.h"
17 #include "../../../drivers/ddr/marvell/a38x/ddr3_a38x.h"
19 #ifdef CONFIG_ARMADA_38X
20 enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
21 /* 6820 6810 6811 6828 */
22 /* PEX_UNIT_ID */ { 4, 3, 3, 4},
23 /* ETH_GIG_UNIT_ID */ { 3, 2, 3, 3},
24 /* USB3H_UNIT_ID */ { 2, 2, 2, 2},
25 /* USB3D_UNIT_ID */ { 1, 1, 1, 1},
26 /* SATA_UNIT_ID */ { 2, 2, 2, 4},
27 /* QSGMII_UNIT_ID */ { 1, 0, 0, 1},
28 /* XAUI_UNIT_ID */ { 0, 0, 0, 0},
29 /* RXAUI_UNIT_ID */ { 0, 0, 0, 0}
31 #else /* if (CONFIG_ARMADA_39X) */
32 enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
34 /* PEX_UNIT_ID */ { 4, 4},
35 /* ETH_GIG_UNIT_ID */ { 3, 4},
36 /* USB3H_UNIT_ID */ { 1, 2},
37 /* USB3D_UNIT_ID */ { 0, 1},
38 /* SATA_UNIT_ID */ { 0, 4},
39 /* QSGMII_UNIT_ID */ { 0, 1},
40 /* XAUI_UNIT_ID */ { 1, 1},
41 /* RXAUI_UNIT_ID */ { 1, 1}
47 u32 mv_board_id_get(void)
49 #if defined(CONFIG_DB_88F6820_GP)
53 * Return 0 here for custom board as this should not be used
60 u32 mv_board_tclk_get(void)
64 value = (reg_read(DEVICE_SAMPLE_AT_RESET1_REG) >> 15) & 0x1;
76 u32 mv_board_id_index_get(u32 board_id)
79 * Marvell Boards use 0x10 as base for Board ID:
80 * mask MSB to receive index for board ID
82 return board_id & (MARVELL_BOARD_ID_MASK - 1);
86 * sys_env_suspend_wakeup_check
87 * DESCRIPTION: Reads GPIO input for suspend-wakeup indication.
90 * RETURNS: u32 indicating suspend wakeup status:
92 * 1 - supported: read magic word detect wakeup,
93 * 2 - detected wakeup from GPIO.
95 enum suspend_wakeup_status sys_env_suspend_wakeup_check(void)
97 u32 reg, board_id_index, gpio;
98 struct board_wakeup_gpio board_gpio[] = MV_BOARD_WAKEUP_GPIO_INFO;
100 board_id_index = mv_board_id_index_get(mv_board_id_get());
101 if (!(sizeof(board_gpio) / sizeof(struct board_wakeup_gpio) >
103 printf("\n_failed loading Suspend-Wakeup information (invalid board ID)\n");
104 return SUSPEND_WAKEUP_DISABLED;
108 * - Detect if Suspend-Wakeup is supported on current board
109 * - Fetch the GPIO number for wakeup status input indication
111 if (board_gpio[board_id_index].gpio_num == -1) {
112 /* Suspend to RAM is not supported */
113 return SUSPEND_WAKEUP_DISABLED;
114 } else if (board_gpio[board_id_index].gpio_num == -2) {
116 * Suspend to RAM is supported but GPIO indication is
117 * not implemented - Skip
119 return SUSPEND_WAKEUP_ENABLED;
121 gpio = board_gpio[board_id_index].gpio_num;
124 /* Initialize MPP for GPIO (set MPP = 0x0) */
125 reg = reg_read(MPP_CONTROL_REG(MPP_REG_NUM(gpio)));
126 /* reset MPP21 to 0x0, keep rest of MPP settings*/
127 reg &= ~MPP_MASK(gpio);
128 reg_write(MPP_CONTROL_REG(MPP_REG_NUM(gpio)), reg);
130 /* Initialize GPIO as input */
131 reg = reg_read(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)));
132 reg |= GPP_MASK(gpio);
133 reg_write(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)), reg);
136 * Check GPP for input status from PIC: 0 - regular init,
139 reg = reg_read(GPP_DATA_IN_REG(GPP_REG_NUM(gpio)));
141 /* if GPIO is ON: wakeup from S2RAM indication detected */
142 return (reg & GPP_MASK(gpio)) ? SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED :
143 SUSPEND_WAKEUP_DISABLED;
147 * mv_ctrl_dev_id_index_get
149 * DESCRIPTION: return SOC device index
153 * return SOC device index
155 u32 sys_env_id_index_get(u32 ctrl_model)
157 switch (ctrl_model) {
159 return MV_6820_INDEX;
161 return MV_6810_INDEX;
163 return MV_6811_INDEX;
165 return MV_6828_INDEX;
167 return MV_6920_INDEX;
169 return MV_6928_INDEX;
171 return MV_6820_INDEX;
175 u32 sys_env_unit_max_num_get(enum unit_id unit)
179 if (unit >= MAX_UNITS_ID) {
180 printf("%s: Error: Wrong unit type (%u)\n", __func__, unit);
184 dev_id_index = sys_env_id_index_get(sys_env_model_get());
185 return sys_env_soc_unit_nums[unit][dev_id_index];
190 * DESCRIPTION: Returns 16bit describing the device model (ID) as defined
191 * in Vendor ID configuration register
193 u16 sys_env_model_get(void)
195 u32 default_ctrl_id, ctrl_id = reg_read(DEV_ID_REG);
196 ctrl_id = (ctrl_id & (DEV_ID_REG_DEVICE_ID_MASK)) >>
197 DEV_ID_REG_DEVICE_ID_OFFS;
208 /* Device ID Default for A38x: 6820 , for A39x: 6920 */
209 #ifdef CONFIG_ARMADA_38X
210 default_ctrl_id = MV_6820_DEV_ID;
212 default_ctrl_id = MV_6920_DEV_ID;
214 printf("%s: Error retrieving device ID (%x), using default ID = %x\n",
215 __func__, ctrl_id, default_ctrl_id);
216 return default_ctrl_id;
221 * sys_env_device_id_get
222 * DESCRIPTION: Returns enum (0..7) index of the device model (ID)
224 u32 sys_env_device_id_get(void)
226 char *device_id_str[7] = {
227 "6810", "6820", "6811", "6828", "NONE", "6920", "6928"
233 g_dev_id = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
234 g_dev_id = g_dev_id >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
235 printf("Detected Device ID %s\n", device_id_str[g_dev_id]);
240 #ifdef MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI
242 * sys_env_get_topology_update_info
243 * DESCRIPTION: Read TWSI fields to update DDR topology structure
245 * OUTPUT: None, 0 means no topology update
247 * Bit mask of changes topology features
249 #ifdef CONFIG_ARMADA_39X
250 u32 sys_env_get_topology_update_info(
251 struct topology_update_info *tui)
253 /* Set 16/32 bit configuration*/
254 tui->update_width = 1;
255 tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
258 if (1 == sys_env_config_get(MV_CONFIG_DDR_BUSWIDTH)) {
260 tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
263 tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
267 /* Set ECC/no ECC bit configuration */
269 if (0 == sys_env_config_get(MV_CONFIG_DDR_ECC_EN)) {
271 tui->ecc = TOPOLOGY_UPDATE_ECC_OFF;
274 tui->ecc = TOPOLOGY_UPDATE_ECC_ON;
277 tui->update_ecc_pup3_mode = 1;
278 tui->ecc_pup_mode_offset = TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
282 #else /*CONFIG_ARMADA_38X*/
283 u32 sys_env_get_topology_update_info(
284 struct topology_update_info *tui)
287 u8 ecc_mode[A38X_MV_MAX_MARVELL_BOARD_ID -
288 A38X_MARVELL_BOARD_ID_BASE][5] = TOPOLOGY_UPDATE;
289 u8 board_id = mv_board_id_get();
292 board_id = mv_board_id_index_get(board_id);
293 ret = i2c_read(EEPROM_I2C_ADDR, 0, 2, &config_val, 1);
295 DEBUG_INIT_S("sys_env_get_topology_update_info: TWSI Read failed\n");
299 /* Set 16/32 bit configuration */
300 if ((0 == (config_val & DDR_SATR_CONFIG_MASK_WIDTH)) ||
301 (ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT] == 0)) {
302 /* 16bit by SatR of 32bit mode not supported for the board */
303 if ((ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT] != 0)) {
304 tui->update_width = 1;
305 tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
309 if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT] != 0)) {
310 tui->update_width = 1;
311 tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
315 /* Set ECC/no ECC bit configuration */
316 if (0 == (config_val & DDR_SATR_CONFIG_MASK_ECC)) {
319 tui->ecc = TOPOLOGY_UPDATE_ECC_OFF;
322 if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0) ||
323 (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] != 0) ||
324 (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC_PUP3] != 0)) {
326 tui->ecc = TOPOLOGY_UPDATE_ECC_ON;
330 /* Set ECC pup bit configuration */
331 if (0 == (config_val & DDR_SATR_CONFIG_MASK_ECC_PUP)) {
334 * Check if PUP3 configuration allowed, if not -
335 * force Pup4 with warning message
337 if ((ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC_PUP3] != 0)) {
338 if (tui->width == TOPOLOGY_UPDATE_WIDTH_16BIT) {
339 tui->update_ecc_pup3_mode = 1;
340 tui->ecc_pup_mode_offset =
341 TOPOLOGY_UPDATE_ECC_OFFSET_PUP3;
343 if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0)) {
344 printf("DDR Topology Update: ECC PUP3 not valid for 32bit mode, force ECC in PUP4\n");
345 tui->update_ecc_pup3_mode = 1;
346 tui->ecc_pup_mode_offset =
347 TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
351 if (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] !=
353 printf("DDR Topology Update: ECC on PUP3 not supported, force ECC on PUP4\n");
354 tui->update_ecc_pup3_mode = 1;
355 tui->ecc_pup_mode_offset =
356 TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
361 if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0) ||
362 (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] != 0)) {
363 tui->update_ecc_pup3_mode = 1;
364 tui->ecc_pup_mode_offset =
365 TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
370 * Check for forbidden ECC mode,
371 * if by default width and pup selection set 32bit ECC mode and this
372 * mode not supported for the board - config 16bit with ECC on PUP3
374 if ((tui->ecc == TOPOLOGY_UPDATE_ECC_ON) &&
375 (tui->width == TOPOLOGY_UPDATE_WIDTH_32BIT)) {
376 if (ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] == 0) {
377 printf("DDR Topology Update: 32bit mode with ECC not allowed on this board, forced 16bit with ECC on PUP3\n");
378 tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
379 tui->update_ecc_pup3_mode = 1;
380 tui->ecc_pup_mode_offset =
381 TOPOLOGY_UPDATE_ECC_OFFSET_PUP3;
387 #endif /* CONFIG_ARMADA_38X */
388 #endif /* MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI */