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