diff options
author | Ohad Sharabi <osharabi@habana.ai> | 2021-03-25 11:06:26 +0300 |
---|---|---|
committer | Oded Gabbay <ogabbay@kernel.org> | 2021-06-18 15:23:38 +0300 |
commit | 6e16ab6c326cd149c086ccbab6da9ccff1a528ff (patch) | |
tree | bc4868b321f42e96d6dbca3668232b89f0068343 /drivers/misc | |
parent | 3b39840083ef809e71206e9717d5bd502317e696 (diff) | |
download | linux-6e16ab6c326cd149c086ccbab6da9ccff1a528ff.tar.xz |
habanalabs: prepare preboot stage to dynamic f/w load
Start the skeleton for the dynamic F/W load by marking current preboot
code path as legacy.
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')
-rw-r--r-- | drivers/misc/habanalabs/common/firmware_if.c | 78 | ||||
-rw-r--r-- | drivers/misc/habanalabs/common/habanalabs.h | 8 |
2 files changed, 71 insertions, 15 deletions
diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index 0713b2c12d54..a45aea4730cf 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -809,21 +809,15 @@ static void detect_cpu_boot_status(struct hl_device *hdev, u32 status) } } -int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, - u32 cpu_security_boot_status_reg, u32 boot_err0_reg, - u32 timeout) +static int hl_fw_read_preboot_caps(struct hl_device *hdev, + u32 cpu_boot_status_reg, + u32 cpu_boot_caps_reg, + u32 boot_err0_reg, u32 timeout) { struct asic_fixed_properties *prop = &hdev->asic_prop; - u32 status, security_status; + u32 status; int rc; - /* 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 - */ - if (!(hdev->fw_components & FW_TYPE_PREBOOT_CPU) || hdev->pldm) - return 0; - /* Need to check two possible scenarios: * * CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT - for newer firmwares where @@ -846,7 +840,7 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, timeout); if (rc) { - dev_err(hdev->dev, "Failed to read preboot version\n"); + dev_err(hdev->dev, "CPU boot ready status timeout\n"); detect_cpu_boot_status(hdev, status); /* If we read all FF, then something is totally wrong, no point @@ -854,15 +848,39 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, */ if (status != -1) fw_read_errors(hdev, boot_err0_reg, - cpu_security_boot_status_reg); + cpu_boot_status_reg); return -EIO; } + prop->fw_preboot_caps_map = RREG32(cpu_boot_caps_reg); + + /* + * For now- force dynamic_fw_load to false as LKD does not yet + * implements all necessary parts of it. + * TODO: once dynamic load is ready set to: + * prop->dynamic_fw_load = !!(prop->fw_preboot_caps_map & + * CPU_BOOT_DEV_STS0_FW_LD_COM_EN) + */ + prop->dynamic_fw_load = 0; + + dev_dbg(hdev->dev, "Attempting %s FW load\n", + prop->dynamic_fw_load ? "dynamic" : "legacy"); + 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) +{ + struct asic_fixed_properties *prop = &hdev->asic_prop; + u32 security_status; + int rc; + rc = hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_PREBOOT); if (rc) return rc; - security_status = RREG32(cpu_security_boot_status_reg); + security_status = prop->fw_preboot_caps_map; /* We read security status multiple times during boot: * 1. preboot - a. Check whether the security status bits are valid @@ -904,6 +922,38 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, return 0; } +int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, + u32 cpu_boot_caps_reg, u32 boot_err0_reg, + u32 timeout) +{ + int rc; + + /* 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 + */ + if (!(hdev->fw_components & FW_TYPE_PREBOOT_CPU) || hdev->pldm) + return 0; + + /* + * In order to determine boot method (static VS dymanic) we need to + * read the boot caps register + */ + rc = hl_fw_read_preboot_caps(hdev, cpu_boot_status_reg, + cpu_boot_caps_reg, boot_err0_reg, + timeout); + if (rc) + return rc; + + if (!hdev->asic_prop.dynamic_fw_load) + return hl_fw_read_preboot_status_legacy(hdev, cpu_boot_status_reg, + cpu_boot_caps_reg, boot_err0_reg, + timeout); + + dev_err(hdev->dev, "Dynamic FW load is not supported\n"); + return -EINVAL; +} + int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, u32 msg_to_cpu_reg, u32 cpu_msg_status_reg, u32 cpu_security_boot_status_reg, u32 boot_err0_reg, diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 6579f8767abd..72726de6575c 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -420,6 +420,9 @@ struct hl_mmu_properties { * @cb_pool_cb_size: size of each CB in the CB pool. * @max_pending_cs: maximum of concurrent pending command submissions * @max_queues: maximum amount of queues in the system + * @fw_preboot_caps_map: bitmap representation of preboot cpu capabilities + * reported by FW, bit description can be found in + * CPU_BOOT_DEV_STS* * @fw_boot_cpu_security_map: bitmap representation of boot cpu security status * reported by FW, bit description can be found in * CPU_BOOT_DEV_STS* @@ -446,6 +449,7 @@ struct hl_mmu_properties { * @hard_reset_done_by_fw: true if firmware is handling hard reset flow * @num_functional_hbms: number of functional HBMs in each DCORE. * @iatu_done_by_fw: true if iATU configuration is being done by FW. + * @dynamic_fw_load: is dynamic FW load is supported. */ struct asic_fixed_properties { struct hw_queue_properties *hw_queues_props; @@ -491,6 +495,7 @@ struct asic_fixed_properties { u32 cb_pool_cb_size; u32 max_pending_cs; u32 max_queues; + u32 fw_preboot_caps_map; u32 fw_boot_cpu_security_map; u32 fw_app_security_map; u16 collective_first_sob; @@ -510,6 +515,7 @@ struct asic_fixed_properties { u8 hard_reset_done_by_fw; u8 num_functional_hbms; u8 iatu_done_by_fw; + u8 dynamic_fw_load; }; /** @@ -2404,7 +2410,7 @@ int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, u32 cpu_security_boot_status_reg, u32 boot_err0_reg, bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout); int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, - u32 cpu_security_boot_status_reg, u32 boot_err0_reg, + u32 cpu_boot_caps_reg, u32 boot_err0_reg, u32 timeout); int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3], |