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