diff options
author | Ohad Sharabi <osharabi@habana.ai> | 2021-04-11 15:26:28 +0300 |
---|---|---|
committer | Oded Gabbay <ogabbay@kernel.org> | 2021-06-18 15:23:38 +0300 |
commit | 50f036df476c6e58f597f684345141e406b12099 (patch) | |
tree | 5971b19e17f68e14028721c9d0c4ba94e9a2daf9 /drivers/misc/habanalabs/common/firmware_if.c | |
parent | 08c03a19662fd628e8866d89769d594c1d8c8093 (diff) | |
download | lwn-50f036df476c6e58f597f684345141e406b12099.tar.gz lwn-50f036df476c6e58f597f684345141e406b12099.zip |
habanalabs: use common fw_version read
Instead of using multiple ASIC specific copies of functions to read the
FW version use single common one that gets ASIC specific arguments.
Signed-off-by: Ohad Sharabi <osharabi@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Diffstat (limited to 'drivers/misc/habanalabs/common/firmware_if.c')
-rw-r--r-- | drivers/misc/habanalabs/common/firmware_if.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index e0b0b98b7879..d62ec5bbdb41 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -891,6 +891,49 @@ static int hl_fw_read_preboot_caps(struct hl_device *hdev, return 0; } +static int hl_read_device_fw_version(struct hl_device *hdev, + enum hl_fw_component fwc) +{ + struct fw_load_mgr *fw_loader = &hdev->fw_loader; + const char *name; + u32 ver_off, limit; + char *dest; + + switch (fwc) { + case FW_COMP_BOOT_FIT: + ver_off = RREG32(fw_loader->boot_fit_version_offset_reg); + dest = hdev->asic_prop.uboot_ver; + name = "Boot-fit"; + limit = fw_loader->boot_fit_version_max_off; + break; + case FW_COMP_PREBOOT: + ver_off = RREG32( + fw_loader->preboot_version_offset_reg); + dest = hdev->asic_prop.preboot_ver; + name = "Preboot"; + limit = fw_loader->preboot_version_max_off; + break; + default: + dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc); + return -EIO; + } + + ver_off &= fw_loader->sram_offset_mask; + + if (ver_off < limit) { + memcpy_fromio(dest, + hdev->pcie_bar[fw_loader->sram_bar_id] + ver_off, + VERSION_MAX_LEN); + } else { + dev_err(hdev->dev, "%s version offset (0x%x) is above SRAM\n", + name, ver_off); + strscpy(dest, "unavailable", VERSION_MAX_LEN); + return -EIO; + } + + return 0; +} + static int hl_fw_read_preboot_status_legacy(struct hl_device *hdev, u32 cpu_boot_status_reg, u32 cpu_security_boot_status_reg, u32 boot_err0_reg, u32 timeout) @@ -899,7 +942,7 @@ static int hl_fw_read_preboot_status_legacy(struct hl_device *hdev, u32 security_status; int rc; - rc = hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_PREBOOT); + rc = hl_read_device_fw_version(hdev, FW_COMP_PREBOOT); if (rc) return rc; @@ -951,6 +994,8 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, { int rc; + hdev->asic_funcs->init_firmware_loader(hdev); + /* pldm was added for cases in which we use preboot on pldm and want * to load boot fit, but we can't wait for preboot because it runs * very slowly @@ -989,7 +1034,6 @@ int hl_fw_init_cpu(struct hl_device *hdev) return 0; /* init loader parameters */ - hdev->asic_funcs->init_firmware_loader(hdev); fw_loader = &hdev->fw_loader; cpu_security_boot_status_reg = fw_loader->cpu_boot_status_reg; cpu_msg_status_reg = fw_loader->cpu_cmd_status_to_host_reg; @@ -1057,7 +1101,7 @@ int hl_fw_init_cpu(struct hl_device *hdev) dev_dbg(hdev->dev, "uboot status = %d\n", status); /* Read U-Boot version now in case we will later fail */ - hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_UBOOT); + hl_read_device_fw_version(hdev, FW_COMP_BOOT_FIT); /* Clear reset status since we need to read it again from boot CPU */ prop->hard_reset_done_by_fw = false; |