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