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
15enum 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
27u32 g_dev_id = -1;
28
29u32 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
42u32 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
58u32 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 */
77enum 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 */
137u32 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	default:
149		return MV_6820_INDEX;
150	}
151}
152
153u32 sys_env_unit_max_num_get(enum unit_id unit)
154{
155	u32 dev_id_index;
156
157	if (unit >= MAX_UNITS_ID) {
158		printf("%s: Error: Wrong unit type (%u)\n", __func__, unit);
159		return 0;
160	}
161
162	dev_id_index = sys_env_id_index_get(sys_env_model_get());
163	return sys_env_soc_unit_nums[unit][dev_id_index];
164}
165
166/*
167 * sys_env_model_get
168 * DESCRIPTION:	Returns 16bit describing the device model (ID) as defined
169 *		in Vendor ID configuration register
170 */
171u16 sys_env_model_get(void)
172{
173	u32 default_ctrl_id, ctrl_id = reg_read(DEV_ID_REG);
174	ctrl_id = (ctrl_id & (DEV_ID_REG_DEVICE_ID_MASK)) >>
175		DEV_ID_REG_DEVICE_ID_OFFS;
176
177	switch (ctrl_id) {
178	case MV_6820_DEV_ID:
179	case MV_6810_DEV_ID:
180	case MV_6811_DEV_ID:
181	case MV_6828_DEV_ID:
182		return ctrl_id;
183	default:
184		/* Device ID Default for A38x: 6820 */
185		default_ctrl_id =  MV_6820_DEV_ID;
186		printf("%s: Error retrieving device ID (%x), using default ID = %x\n",
187		       __func__, ctrl_id, default_ctrl_id);
188		return default_ctrl_id;
189	}
190}
191
192/*
193 * sys_env_device_id_get
194 * DESCRIPTION:	Returns enum (0..7) index of the device model (ID)
195 */
196u32 sys_env_device_id_get(void)
197{
198	char *device_id_str[4] = {
199		"6810", "6820", "6811", "6828",
200	};
201
202	if (g_dev_id != -1)
203		return g_dev_id;
204
205	g_dev_id = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
206	g_dev_id = g_dev_id >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
207	printf("Detected Device ID %s\n", g_dev_id < 4 ? device_id_str[g_dev_id] : "NONE");
208
209	return g_dev_id;
210}
211
212/*
213 * sys_env_device_rev_get - Get Marvell controller device revision number
214 *
215 * DESCRIPTION:
216 *       This function returns 8bit describing the device revision as defined
217 *       Revision ID Register.
218 *
219 * INPUT:
220 *       None.
221 *
222 * OUTPUT:
223 *       None.
224 *
225 * RETURN:
226 *       8bit desscribing Marvell controller revision number
227 */
228u8 sys_env_device_rev_get(void)
229{
230	u32 value;
231
232	value = reg_read(DEV_VERSION_ID_REG);
233	return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS;
234}
235
236void mv_rtc_config(void)
237{
238	u32 i, val;
239
240	/* Activate pipe0 for read/write transaction, and set XBAR client number #1 */
241	val = 0x1 << DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS |
242	      0x1 << DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS;
243	writel(val, MVEBU_DFX_BASE);
244
245	/* Set new RTC value for all memory wrappers */
246	for (i = 0; i < RTC_MEMORY_WRAPPER_COUNT; i++)
247		reg_write(RTC_MEMORY_WRAPPER_REG(i), RTC_MEMORY_WRAPPER_CTRL_VAL);
248}
249
250void mv_avs_init(void)
251{
252	u32 sar_freq;
253
254	reg_write(AVS_DEBUG_CNTR_REG, AVS_DEBUG_CNTR_DEFAULT_VALUE);
255	reg_write(AVS_DEBUG_CNTR_REG, AVS_DEBUG_CNTR_DEFAULT_VALUE);
256
257	sar_freq = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
258	sar_freq = sar_freq >> SAR_FREQ_OFFSET & SAR_FREQ_MASK;
259
260	/* Set AVS value only for core frequency of 1600MHz or less.
261	 * For higher frequency leave the default value.
262	 */
263	if (sar_freq <= 0xd) {
264		u32 avs_reg_data = reg_read(AVS_ENABLED_CONTROL);
265
266		avs_reg_data &= ~(AVS_LOW_VDD_LIMIT_MASK
267				| AVS_HIGH_VDD_LIMIT_MASK);
268		avs_reg_data |= AVS_LOW_VDD_SLOW_VAL | AVS_HIGH_VDD_SLOW_VAL;
269		reg_write(AVS_ENABLED_CONTROL, avs_reg_data);
270	}
271}
272