1edb47025SStefan Roese /*
2edb47025SStefan Roese * Copyright (C) Marvell International Ltd. and its affiliates
3edb47025SStefan Roese *
4edb47025SStefan Roese * SPDX-License-Identifier: GPL-2.0
5edb47025SStefan Roese */
6edb47025SStefan Roese
7edb47025SStefan Roese #include <common.h>
8edb47025SStefan Roese #include <spl.h>
9edb47025SStefan Roese #include <asm/io.h>
10edb47025SStefan Roese #include <asm/arch/cpu.h>
11edb47025SStefan Roese #include <asm/arch/soc.h>
12edb47025SStefan Roese
13edb47025SStefan Roese #include "seq_exec.h"
14edb47025SStefan Roese #include "sys_env_lib.h"
15edb47025SStefan Roese
16edb47025SStefan Roese #include "../../../drivers/ddr/marvell/a38x/ddr3_a38x.h"
17edb47025SStefan Roese
18edb47025SStefan Roese #ifdef CONFIG_ARMADA_38X
19edb47025SStefan Roese enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
20edb47025SStefan Roese /* 6820 6810 6811 6828 */
21edb47025SStefan Roese /* PEX_UNIT_ID */ { 4, 3, 3, 4},
22edb47025SStefan Roese /* ETH_GIG_UNIT_ID */ { 3, 2, 3, 3},
23edb47025SStefan Roese /* USB3H_UNIT_ID */ { 2, 2, 2, 2},
24edb47025SStefan Roese /* USB3D_UNIT_ID */ { 1, 1, 1, 1},
25edb47025SStefan Roese /* SATA_UNIT_ID */ { 2, 2, 2, 4},
26edb47025SStefan Roese /* QSGMII_UNIT_ID */ { 1, 0, 0, 1},
27edb47025SStefan Roese /* XAUI_UNIT_ID */ { 0, 0, 0, 0},
28edb47025SStefan Roese /* RXAUI_UNIT_ID */ { 0, 0, 0, 0}
29edb47025SStefan Roese };
30edb47025SStefan Roese #else /* if (CONFIG_ARMADA_39X) */
31edb47025SStefan Roese enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
32edb47025SStefan Roese /* 6920 6928 */
33edb47025SStefan Roese /* PEX_UNIT_ID */ { 4, 4},
34edb47025SStefan Roese /* ETH_GIG_UNIT_ID */ { 3, 4},
35edb47025SStefan Roese /* USB3H_UNIT_ID */ { 1, 2},
36edb47025SStefan Roese /* USB3D_UNIT_ID */ { 0, 1},
37edb47025SStefan Roese /* SATA_UNIT_ID */ { 0, 4},
38edb47025SStefan Roese /* QSGMII_UNIT_ID */ { 0, 1},
39edb47025SStefan Roese /* XAUI_UNIT_ID */ { 1, 1},
40edb47025SStefan Roese /* RXAUI_UNIT_ID */ { 1, 1}
41edb47025SStefan Roese };
42edb47025SStefan Roese #endif
43edb47025SStefan Roese
44edb47025SStefan Roese u32 g_dev_id = -1;
45edb47025SStefan Roese
mv_board_id_get(void)46edb47025SStefan Roese u32 mv_board_id_get(void)
47edb47025SStefan Roese {
48*53d601fdSChris Packham #if defined(CONFIG_TARGET_DB_88F6820_GP)
49edb47025SStefan Roese return DB_GP_68XX_ID;
50edb47025SStefan Roese #else
51edb47025SStefan Roese /*
52edb47025SStefan Roese * Return 0 here for custom board as this should not be used
53edb47025SStefan Roese * for custom boards.
54edb47025SStefan Roese */
55edb47025SStefan Roese return 0;
56edb47025SStefan Roese #endif
57edb47025SStefan Roese }
58edb47025SStefan Roese
mv_board_tclk_get(void)59edb47025SStefan Roese u32 mv_board_tclk_get(void)
60edb47025SStefan Roese {
61edb47025SStefan Roese u32 value;
62edb47025SStefan Roese
63edb47025SStefan Roese value = (reg_read(DEVICE_SAMPLE_AT_RESET1_REG) >> 15) & 0x1;
64edb47025SStefan Roese
65edb47025SStefan Roese switch (value) {
66edb47025SStefan Roese case (0x0):
67edb47025SStefan Roese return 250000000;
68edb47025SStefan Roese case (0x1):
69edb47025SStefan Roese return 200000000;
70edb47025SStefan Roese default:
71edb47025SStefan Roese return 0xffffffff;
72edb47025SStefan Roese }
73edb47025SStefan Roese }
74edb47025SStefan Roese
mv_board_id_index_get(u32 board_id)75edb47025SStefan Roese u32 mv_board_id_index_get(u32 board_id)
76edb47025SStefan Roese {
77edb47025SStefan Roese /*
78edb47025SStefan Roese * Marvell Boards use 0x10 as base for Board ID:
79edb47025SStefan Roese * mask MSB to receive index for board ID
80edb47025SStefan Roese */
81edb47025SStefan Roese return board_id & (MARVELL_BOARD_ID_MASK - 1);
82edb47025SStefan Roese }
83edb47025SStefan Roese
84edb47025SStefan Roese /*
85edb47025SStefan Roese * sys_env_suspend_wakeup_check
86edb47025SStefan Roese * DESCRIPTION: Reads GPIO input for suspend-wakeup indication.
87edb47025SStefan Roese * INPUT: None.
88edb47025SStefan Roese * OUTPUT:
89edb47025SStefan Roese * RETURNS: u32 indicating suspend wakeup status:
90edb47025SStefan Roese * 0 - Not supported,
91edb47025SStefan Roese * 1 - supported: read magic word detect wakeup,
92edb47025SStefan Roese * 2 - detected wakeup from GPIO.
93edb47025SStefan Roese */
sys_env_suspend_wakeup_check(void)94edb47025SStefan Roese enum suspend_wakeup_status sys_env_suspend_wakeup_check(void)
95edb47025SStefan Roese {
96edb47025SStefan Roese u32 reg, board_id_index, gpio;
97edb47025SStefan Roese struct board_wakeup_gpio board_gpio[] = MV_BOARD_WAKEUP_GPIO_INFO;
98edb47025SStefan Roese
99edb47025SStefan Roese board_id_index = mv_board_id_index_get(mv_board_id_get());
100edb47025SStefan Roese if (!(sizeof(board_gpio) / sizeof(struct board_wakeup_gpio) >
101edb47025SStefan Roese board_id_index)) {
102edb47025SStefan Roese printf("\n_failed loading Suspend-Wakeup information (invalid board ID)\n");
103edb47025SStefan Roese return SUSPEND_WAKEUP_DISABLED;
104edb47025SStefan Roese }
105edb47025SStefan Roese
106edb47025SStefan Roese /*
107edb47025SStefan Roese * - Detect if Suspend-Wakeup is supported on current board
108edb47025SStefan Roese * - Fetch the GPIO number for wakeup status input indication
109edb47025SStefan Roese */
110edb47025SStefan Roese if (board_gpio[board_id_index].gpio_num == -1) {
111edb47025SStefan Roese /* Suspend to RAM is not supported */
112edb47025SStefan Roese return SUSPEND_WAKEUP_DISABLED;
113edb47025SStefan Roese } else if (board_gpio[board_id_index].gpio_num == -2) {
114edb47025SStefan Roese /*
115edb47025SStefan Roese * Suspend to RAM is supported but GPIO indication is
116edb47025SStefan Roese * not implemented - Skip
117edb47025SStefan Roese */
118edb47025SStefan Roese return SUSPEND_WAKEUP_ENABLED;
119edb47025SStefan Roese } else {
120edb47025SStefan Roese gpio = board_gpio[board_id_index].gpio_num;
121edb47025SStefan Roese }
122edb47025SStefan Roese
123edb47025SStefan Roese /* Initialize MPP for GPIO (set MPP = 0x0) */
124edb47025SStefan Roese reg = reg_read(MPP_CONTROL_REG(MPP_REG_NUM(gpio)));
125edb47025SStefan Roese /* reset MPP21 to 0x0, keep rest of MPP settings*/
126edb47025SStefan Roese reg &= ~MPP_MASK(gpio);
127edb47025SStefan Roese reg_write(MPP_CONTROL_REG(MPP_REG_NUM(gpio)), reg);
128edb47025SStefan Roese
129edb47025SStefan Roese /* Initialize GPIO as input */
130edb47025SStefan Roese reg = reg_read(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)));
131edb47025SStefan Roese reg |= GPP_MASK(gpio);
132edb47025SStefan Roese reg_write(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)), reg);
133edb47025SStefan Roese
134edb47025SStefan Roese /*
135edb47025SStefan Roese * Check GPP for input status from PIC: 0 - regular init,
136edb47025SStefan Roese * 1 - suspend wakeup
137edb47025SStefan Roese */
138edb47025SStefan Roese reg = reg_read(GPP_DATA_IN_REG(GPP_REG_NUM(gpio)));
139edb47025SStefan Roese
140edb47025SStefan Roese /* if GPIO is ON: wakeup from S2RAM indication detected */
141edb47025SStefan Roese return (reg & GPP_MASK(gpio)) ? SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED :
142edb47025SStefan Roese SUSPEND_WAKEUP_DISABLED;
143edb47025SStefan Roese }
144edb47025SStefan Roese
145edb47025SStefan Roese /*
146edb47025SStefan Roese * mv_ctrl_dev_id_index_get
147edb47025SStefan Roese *
148edb47025SStefan Roese * DESCRIPTION: return SOC device index
149edb47025SStefan Roese * INPUT: None
150edb47025SStefan Roese * OUTPUT: None
151edb47025SStefan Roese * RETURN:
152edb47025SStefan Roese * return SOC device index
153edb47025SStefan Roese */
sys_env_id_index_get(u32 ctrl_model)154edb47025SStefan Roese u32 sys_env_id_index_get(u32 ctrl_model)
155edb47025SStefan Roese {
156edb47025SStefan Roese switch (ctrl_model) {
157edb47025SStefan Roese case MV_6820_DEV_ID:
158edb47025SStefan Roese return MV_6820_INDEX;
159edb47025SStefan Roese case MV_6810_DEV_ID:
160edb47025SStefan Roese return MV_6810_INDEX;
161edb47025SStefan Roese case MV_6811_DEV_ID:
162edb47025SStefan Roese return MV_6811_INDEX;
163edb47025SStefan Roese case MV_6828_DEV_ID:
164edb47025SStefan Roese return MV_6828_INDEX;
165edb47025SStefan Roese case MV_6920_DEV_ID:
166edb47025SStefan Roese return MV_6920_INDEX;
167edb47025SStefan Roese case MV_6928_DEV_ID:
168edb47025SStefan Roese return MV_6928_INDEX;
169edb47025SStefan Roese default:
170edb47025SStefan Roese return MV_6820_INDEX;
171edb47025SStefan Roese }
172edb47025SStefan Roese }
173edb47025SStefan Roese
sys_env_unit_max_num_get(enum unit_id unit)174edb47025SStefan Roese u32 sys_env_unit_max_num_get(enum unit_id unit)
175edb47025SStefan Roese {
176edb47025SStefan Roese u32 dev_id_index;
177edb47025SStefan Roese
178edb47025SStefan Roese if (unit >= MAX_UNITS_ID) {
179edb47025SStefan Roese printf("%s: Error: Wrong unit type (%u)\n", __func__, unit);
180edb47025SStefan Roese return 0;
181edb47025SStefan Roese }
182edb47025SStefan Roese
183edb47025SStefan Roese dev_id_index = sys_env_id_index_get(sys_env_model_get());
184edb47025SStefan Roese return sys_env_soc_unit_nums[unit][dev_id_index];
185edb47025SStefan Roese }
186edb47025SStefan Roese
187edb47025SStefan Roese /*
188edb47025SStefan Roese * sys_env_model_get
189edb47025SStefan Roese * DESCRIPTION: Returns 16bit describing the device model (ID) as defined
190edb47025SStefan Roese * in Vendor ID configuration register
191edb47025SStefan Roese */
sys_env_model_get(void)192edb47025SStefan Roese u16 sys_env_model_get(void)
193edb47025SStefan Roese {
194edb47025SStefan Roese u32 default_ctrl_id, ctrl_id = reg_read(DEV_ID_REG);
195edb47025SStefan Roese ctrl_id = (ctrl_id & (DEV_ID_REG_DEVICE_ID_MASK)) >>
196edb47025SStefan Roese DEV_ID_REG_DEVICE_ID_OFFS;
197edb47025SStefan Roese
198edb47025SStefan Roese switch (ctrl_id) {
199edb47025SStefan Roese case MV_6820_DEV_ID:
200edb47025SStefan Roese case MV_6810_DEV_ID:
201edb47025SStefan Roese case MV_6811_DEV_ID:
202edb47025SStefan Roese case MV_6828_DEV_ID:
203edb47025SStefan Roese case MV_6920_DEV_ID:
204edb47025SStefan Roese case MV_6928_DEV_ID:
205edb47025SStefan Roese return ctrl_id;
206edb47025SStefan Roese default:
207edb47025SStefan Roese /* Device ID Default for A38x: 6820 , for A39x: 6920 */
208edb47025SStefan Roese #ifdef CONFIG_ARMADA_38X
209edb47025SStefan Roese default_ctrl_id = MV_6820_DEV_ID;
210edb47025SStefan Roese #else
211edb47025SStefan Roese default_ctrl_id = MV_6920_DEV_ID;
212edb47025SStefan Roese #endif
213edb47025SStefan Roese printf("%s: Error retrieving device ID (%x), using default ID = %x\n",
214edb47025SStefan Roese __func__, ctrl_id, default_ctrl_id);
215edb47025SStefan Roese return default_ctrl_id;
216edb47025SStefan Roese }
217edb47025SStefan Roese }
218edb47025SStefan Roese
219edb47025SStefan Roese /*
220edb47025SStefan Roese * sys_env_device_id_get
221edb47025SStefan Roese * DESCRIPTION: Returns enum (0..7) index of the device model (ID)
222edb47025SStefan Roese */
sys_env_device_id_get(void)223edb47025SStefan Roese u32 sys_env_device_id_get(void)
224edb47025SStefan Roese {
225edb47025SStefan Roese char *device_id_str[7] = {
226edb47025SStefan Roese "6810", "6820", "6811", "6828", "NONE", "6920", "6928"
227edb47025SStefan Roese };
228edb47025SStefan Roese
229edb47025SStefan Roese if (g_dev_id != -1)
230edb47025SStefan Roese return g_dev_id;
231edb47025SStefan Roese
232edb47025SStefan Roese g_dev_id = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
233edb47025SStefan Roese g_dev_id = g_dev_id >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
234edb47025SStefan Roese printf("Detected Device ID %s\n", device_id_str[g_dev_id]);
235edb47025SStefan Roese
236edb47025SStefan Roese return g_dev_id;
237edb47025SStefan Roese }
238