diff --git a/drivers/gpu/nvgpu/common/vbios/bios.c b/drivers/gpu/nvgpu/common/vbios/bios.c index ca4ad4257..a1fa1df05 100644 --- a/drivers/gpu/nvgpu/common/vbios/bios.c +++ b/drivers/gpu/nvgpu/common/vbios/bios.c @@ -405,6 +405,14 @@ static void nvgpu_bios_parse_memory_ptrs(struct gk20a *g, u16 offset, u8 version return; } +static void nvgpu_bios_parse_bios_board_id_ptrs(struct gk20a *g, u16 offset) +{ + struct bios_board_id board; + + nvgpu_memcpy((u8 *)&board, &g->bios->data[offset], sizeof(board)); + g->bios->vbios_board_id = board.board_id; +} + static void nvgpu_bios_parse_devinit_appinfo(struct gk20a *g, u32 dmem_offset) { struct devinit_engine_interface interface; @@ -756,6 +764,10 @@ static void nvgpu_bios_parse_bit(struct gk20a *g, u32 offset) nvgpu_bios_parse_memory_ptrs(g, token.data_ptr, token.data_version); break; + case TOKEN_ID_BIOS_BOARD_ID_PTRS: + nvgpu_bios_parse_bios_board_id_ptrs(g, + token.data_ptr); + break; default: nvgpu_log_info(g, "Token id %d not supported", token.token_id); diff --git a/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c b/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c index 93c502e83..ad6371f09 100644 --- a/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c +++ b/drivers/gpu/nvgpu/common/vbios/bios_sw_gv100.c @@ -255,21 +255,11 @@ int gv100_bios_init(struct gk20a *g) goto free_firmware; } - if (g->bios->vbios_version < g->vbios_min_version) { - nvgpu_err(g, "unsupported VBIOS version %08x", - g->bios->vbios_version); - err = -EINVAL; - goto free_firmware; - } else { - nvgpu_info(g, "VBIOS version %08x", g->bios->vbios_version); - } - - if ((g->vbios_compatible_version != 0U) && - (g->bios->vbios_version != g->vbios_compatible_version)) { - nvgpu_err(g, "VBIOS version %08x is not officially supported.", - g->bios->vbios_version); - nvgpu_err(g, "Update to VBIOS %08x, or use at your own risks.", - g->vbios_compatible_version); + if (g->bios->verify_version != NULL) { + if (g->bios->verify_version(g) < 0) { + err = -EINVAL; + goto free_firmware; + } } nvgpu_log_fn(g, "done"); @@ -384,6 +374,7 @@ void nvgpu_gv100_bios_sw_init(struct gk20a *g, struct nvgpu_bios *bios) { bios->init = gv100_bios_init; + bios->verify_version = NULL; bios->preos_wait_for_halt = gv100_bios_preos_wait_for_halt; bios->preos_reload_check = gv100_bios_preos_reload_check; bios->preos_bios = gv100_bios_preos; diff --git a/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c b/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c index 278a5e00c..042584eac 100644 --- a/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c +++ b/drivers/gpu/nvgpu/common/vbios/bios_sw_tu104.c @@ -36,6 +36,80 @@ #define NV_PGC6_AON_SECURE_SCRATCH_GROUP_05_0_GFW_BOOT_PROGRESS_COMPLETED \ 0xFFU +#define NVGPU_PG189_MIN_VBIOS 0x90041800U + +#define NVGPU_PG189_0600_VBIOS 0x90047200U +#define NVGPU_PG189_0601_VBIOS 0x90045a00U +#define NVGPU_PG189_0610_VBIOS 0U + +struct nvgpu_vbios_board { + u16 board_id; + u32 vbios_version; +}; + +#define NVGPU_PG189_NUM_VBIOS_BOARDS 4U + +static struct nvgpu_vbios_board vbios_boards[NVGPU_PG189_NUM_VBIOS_BOARDS] = { + /* SKU 600 ES/CS, SKU 606*/ + [0] = { + .board_id = 0x0068, + .vbios_version = NVGPU_PG189_0600_VBIOS, + }, + /* SKU 600 QS */ + [1] = { + .board_id = 0x0183, + .vbios_version = NVGPU_PG189_0600_VBIOS, + }, + /* SKU 601 CS */ + [2] = { + .board_id = 0x00E8, + .vbios_version = NVGPU_PG189_0601_VBIOS, + }, + /* SKU 610 */ + [3] = { + .board_id = 0x01a3, + .vbios_version = NVGPU_PG189_0610_VBIOS, + }, +}; + +static int tu104_bios_verify_version(struct gk20a *g) +{ + struct nvgpu_vbios_board *board = NULL; + u32 i; + + nvgpu_info(g, "VBIOS board id %04x", g->bios->vbios_board_id); + + nvgpu_info(g, "VBIOS version %08x:%02x\n", + g->bios->vbios_version, + g->bios->vbios_oem_version); + + if (g->bios->vbios_version < NVGPU_PG189_MIN_VBIOS) { + nvgpu_err(g, "unsupported VBIOS version %08x", + g->bios->vbios_version); + return -EINVAL; + } + + for (i = 0; i < NVGPU_PG189_NUM_VBIOS_BOARDS; i++) { + if (g->bios->vbios_board_id == vbios_boards[i].board_id) { + board = &vbios_boards[i]; + } + } + + if (board == NULL) { + nvgpu_warn(g, "unknown board id %04x", + g->bios->vbios_board_id); + return 0; + } + + if ((board->vbios_version != 0U) && + (g->bios->vbios_version < board->vbios_version)) { + nvgpu_warn(g, "VBIOS version should be at least %08x", + board->vbios_version); + } + + return 0; +} + int tu104_bios_verify_devinit(struct gk20a *g) { struct nvgpu_timeout timeout; @@ -80,6 +154,7 @@ void nvgpu_tu104_bios_sw_init(struct gk20a *g, struct nvgpu_bios *bios) { bios->init = tu104_bios_init; + bios->verify_version = tu104_bios_verify_version; bios->preos_wait_for_halt = NULL; bios->preos_reload_check = NULL; bios->preos_bios = NULL; diff --git a/drivers/gpu/nvgpu/include/nvgpu/bios.h b/drivers/gpu/nvgpu/include/nvgpu/bios.h index eb2f78bca..dc44452e4 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/bios.h +++ b/drivers/gpu/nvgpu/include/nvgpu/bios.h @@ -1239,6 +1239,7 @@ struct bios_bit { #define TOKEN_ID_CLOCK_PTRS 0x43U #define TOKEN_ID_VIRT_PTRS 0x56U #define TOKEN_ID_MEMORY_PTRS 0x4DU +#define TOKEN_ID_BIOS_BOARD_ID_PTRS 0x69U #define MEMORY_PTRS_V1 1U #define MEMORY_PTRS_V2 2U @@ -1432,6 +1433,11 @@ struct pci_ext_data_struct { u8 flags; } __packed; +struct bios_board_id { + u8 padding[11]; + u16 board_id; +} __packed; + struct nvgpu_bios_ucode { u8 *bootloader; u32 bootloader_phys_base; @@ -1448,6 +1454,7 @@ struct nvgpu_bios_ucode { struct nvgpu_bios { u32 vbios_version; u8 vbios_oem_version; + u16 vbios_board_id; u8 *data; size_t size; @@ -1476,6 +1483,7 @@ struct nvgpu_bios { u32 nvlink_config_data_offset; int (*init)(struct gk20a *g); + int (*verify_version)(struct gk20a *g); int (*preos_wait_for_halt)(struct gk20a *g); void (*preos_reload_check)(struct gk20a *g); int (*preos_bios)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 1c8ba8e18..e9e2f5a5f 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -2210,10 +2210,6 @@ struct gk20a { struct nvgpu_mem_alloc_tracker *kmallocs; #endif - /* The minimum VBIOS version supported */ - u32 vbios_min_version; - u32 vbios_compatible_version; - /* memory training sequence and mclk switch scripts */ u32 mem_config_idx; diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index fb4643a13..8cdf57e16 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -211,8 +211,6 @@ static void nvgpu_init_vbios_vars(struct gk20a *g) struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); nvgpu_set_enabled(g, NVGPU_PMU_RUN_PREOS, platform->run_preos); - g->vbios_min_version = platform->vbios_min_version; - g->vbios_compatible_version = platform->vbios_compatible_version; } static void nvgpu_init_ltc_vars(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index 68e5c0e27..21c3bc0f8 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -108,7 +108,6 @@ static struct gk20a_platform nvgpu_pci_device[] = { .unify_address_spaces = true, .honors_aperture = true, .dma_mask = DMA_BIT_MASK(40), - .vbios_min_version = 0x1, .hardcode_sw_threshold = false, .unified_memory = false, }, @@ -147,8 +146,6 @@ static struct gk20a_platform nvgpu_pci_device[] = { .unify_address_spaces = true, .honors_aperture = true, .dma_mask = DMA_BIT_MASK(40), - .vbios_min_version = 0x90041800, - .vbios_compatible_version = 0x90045A00, .hardcode_sw_threshold = false, .has_syncpoints = true, }, diff --git a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h index 5d041d0a4..6270fbc05 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h +++ b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h @@ -277,16 +277,6 @@ struct gk20a_platform { */ u64 dma_mask; - /* minimum supported VBIOS version. - * nvgpu driver is not loaded if VBIOS < min VBIOS version - */ - u32 vbios_min_version; - - /* blessed VBIOS version - * if defined, a warning is given if VBIOS differs. - */ - u32 vbios_compatible_version; - /* true if we run preos microcode on this board */ bool run_preos;