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