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

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
Loading
Loading
Loading
Loading
+64 −14
Original line number Diff line number Diff line
@@ -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,
+7 −1
Original line number Diff line number Diff line
@@ -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],