| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| |
| #include <console/console.h> |
| #include <inttypes.h> |
| #include <baseboard/variants.h> |
| #include <ec/google/chromeec/ec.h> |
| |
| /* Global definitions for FW_CONFIG values */ |
| enum { |
| /* Daughterboard index for attributes. */ |
| FW_CONFIG_MASK_DB_INDEX = 0xf, |
| FW_CONFIG_DB_INDEX_SHIFT = 0, |
| /* Mainboard USB index for attributes. */ |
| FW_CONFIG_MASK_MB_USB_INDEX = 0xf, |
| FW_CONFIG_MB_USB_INDEX_SHIFT = 4, |
| /* Lid accelerometer properties. */ |
| FW_CONFIG_MASK_LID_ACCEL = 0x7, |
| FW_CONFIG_LID_ACCEL_SHIFT = 8, |
| /* Base gyro sensor properties. */ |
| FW_CONFIG_MASK_BASE_GYRO = 0x7, |
| FW_CONFIG_BASE_GYRO_SHIFT = 11, |
| /* Keyboard backlight presence */ |
| FW_CONFIG_MASK_KEYB_BL = 0x1, |
| FW_CONFIG_KEYB_BL_SHIFT = 14, |
| /* Tablet mode supported through lid angle */ |
| FW_CONFIG_MASK_LID_ANGLE_TABLET_MODE = 0x1, |
| FW_CONFIG_LID_ANGLE_TABLET_MODE_SHIFT = 15, |
| /* Stylus presence */ |
| FW_CONFIG_MASK_STYLUS = 0x1, |
| FW_CONFIG_STYLUS_SHIFT = 16, |
| /* Fingerprint sensor presence */ |
| FW_CONFIG_MASK_FP = 0x1, |
| FW_CONFIG_SHIFT_FP = 17, |
| /* NVME presence */ |
| FW_CONFIG_MASK_NVME = 0x1, |
| FW_CONFIG_SHIFT_NVME = 18, |
| /* EMMC presence */ |
| FW_CONFIG_MASK_EMMC = 0x1, |
| FW_CONFIG_SHIFT_EMMC = 19, |
| /* SD controller type */ |
| FW_CONFIG_MASK_SD_CTRLR = 0x7, |
| FW_CONFIG_SHIFT_SD_CTRLR = 20, |
| /* SPI speed value */ |
| FW_CONFIG_MASK_SPI_SPEED = 0xf, |
| FW_CONFIG_SHIFT_SPI_SPEED = 23, |
| /* Fan information */ |
| FW_CONFIG_MASK_FAN = 0x3, |
| FW_CONFIG_SHIFT_FAN = 27, |
| }; |
| |
| int variant_fw_config_valid(void) |
| { |
| static uint32_t board_version; |
| const uint32_t bv_valid = CONFIG_VARIANT_BOARD_VER_FW_CONFIG_VALID; |
| |
| if (!CONFIG(VARIANT_HAS_FW_CONFIG)) |
| return 0; |
| |
| /* Fast path for non-zero board version. */ |
| if (board_version >= bv_valid) |
| return 1; |
| |
| if (google_chromeec_cbi_get_board_version(&board_version)) { |
| printk(BIOS_ERR, "Unable to obtain board version for FW_CONFIG\n"); |
| return 0; |
| } |
| |
| if (board_version >= bv_valid) |
| return 1; |
| |
| return 0; |
| } |
| |
| static int get_fw_config(uint32_t *val) |
| { |
| static uint32_t known_value; |
| |
| if (!variant_fw_config_valid()) |
| return -1; |
| |
| if (known_value) { |
| *val = known_value; |
| return 0; |
| } |
| |
| if (google_chromeec_cbi_get_fw_config(&known_value)) { |
| printk(BIOS_ERR, "FW_CONFIG not set in CBI\n"); |
| return -1; |
| } |
| |
| *val = known_value; |
| |
| return 0; |
| } |
| |
| static unsigned int extract_field(uint32_t mask, int shift) |
| { |
| uint32_t fw_config; |
| |
| /* On errors nothing is assumed to be set. */ |
| if (get_fw_config(&fw_config)) |
| return 0; |
| |
| return (fw_config >> shift) & mask; |
| } |
| |
| int variant_has_emmc(void) |
| { |
| return !!extract_field(FW_CONFIG_MASK_EMMC, FW_CONFIG_SHIFT_EMMC); |
| } |
| |
| int variant_has_nvme(void) |
| { |
| return !!extract_field(FW_CONFIG_MASK_NVME, FW_CONFIG_SHIFT_NVME); |
| } |