Commit 6e16ab6c authored by Ohad Sharabi's avatar Ohad Sharabi Committed by Oded Gabbay

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: default avatarOhad Sharabi <osharabi@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent 3b398400
...@@ -809,21 +809,15 @@ static void detect_cpu_boot_status(struct hl_device *hdev, u32 status) ...@@ -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, static int hl_fw_read_preboot_caps(struct hl_device *hdev,
u32 cpu_security_boot_status_reg, u32 boot_err0_reg, u32 cpu_boot_status_reg,
u32 timeout) u32 cpu_boot_caps_reg,
u32 boot_err0_reg, u32 timeout)
{ {
struct asic_fixed_properties *prop = &hdev->asic_prop; struct asic_fixed_properties *prop = &hdev->asic_prop;
u32 status, security_status; u32 status;
int rc; 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: /* Need to check two possible scenarios:
* *
* CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT - for newer firmwares where * 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, ...@@ -846,7 +840,7 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
timeout); timeout);
if (rc) { 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); detect_cpu_boot_status(hdev, status);
/* If we read all FF, then something is totally wrong, no point /* 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, ...@@ -854,15 +848,39 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
*/ */
if (status != -1) if (status != -1)
fw_read_errors(hdev, boot_err0_reg, fw_read_errors(hdev, boot_err0_reg,
cpu_security_boot_status_reg); cpu_boot_status_reg);
return -EIO; 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); rc = hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_PREBOOT);
if (rc) if (rc)
return 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: /* We read security status multiple times during boot:
* 1. preboot - a. Check whether the security status bits are valid * 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, ...@@ -904,6 +922,38 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
return 0; 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, 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 msg_to_cpu_reg, u32 cpu_msg_status_reg,
u32 cpu_security_boot_status_reg, u32 boot_err0_reg, u32 cpu_security_boot_status_reg, u32 boot_err0_reg,
......
...@@ -420,6 +420,9 @@ struct hl_mmu_properties { ...@@ -420,6 +420,9 @@ struct hl_mmu_properties {
* @cb_pool_cb_size: size of each CB in the CB pool. * @cb_pool_cb_size: size of each CB in the CB pool.
* @max_pending_cs: maximum of concurrent pending command submissions * @max_pending_cs: maximum of concurrent pending command submissions
* @max_queues: maximum amount of queues in the system * @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 * @fw_boot_cpu_security_map: bitmap representation of boot cpu security status
* reported by FW, bit description can be found in * reported by FW, bit description can be found in
* CPU_BOOT_DEV_STS* * CPU_BOOT_DEV_STS*
...@@ -446,6 +449,7 @@ struct hl_mmu_properties { ...@@ -446,6 +449,7 @@ struct hl_mmu_properties {
* @hard_reset_done_by_fw: true if firmware is handling hard reset flow * @hard_reset_done_by_fw: true if firmware is handling hard reset flow
* @num_functional_hbms: number of functional HBMs in each DCORE. * @num_functional_hbms: number of functional HBMs in each DCORE.
* @iatu_done_by_fw: true if iATU configuration is being done by FW. * @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 asic_fixed_properties {
struct hw_queue_properties *hw_queues_props; struct hw_queue_properties *hw_queues_props;
...@@ -491,6 +495,7 @@ struct asic_fixed_properties { ...@@ -491,6 +495,7 @@ struct asic_fixed_properties {
u32 cb_pool_cb_size; u32 cb_pool_cb_size;
u32 max_pending_cs; u32 max_pending_cs;
u32 max_queues; u32 max_queues;
u32 fw_preboot_caps_map;
u32 fw_boot_cpu_security_map; u32 fw_boot_cpu_security_map;
u32 fw_app_security_map; u32 fw_app_security_map;
u16 collective_first_sob; u16 collective_first_sob;
...@@ -510,6 +515,7 @@ struct asic_fixed_properties { ...@@ -510,6 +515,7 @@ struct asic_fixed_properties {
u8 hard_reset_done_by_fw; u8 hard_reset_done_by_fw;
u8 num_functional_hbms; u8 num_functional_hbms;
u8 iatu_done_by_fw; 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, ...@@ -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, u32 cpu_security_boot_status_reg, u32 boot_err0_reg,
bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout); 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, 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); u32 timeout);
int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3], int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment