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