Commit 50f036df authored by Ohad Sharabi's avatar Ohad Sharabi Committed by Oded Gabbay
Browse files

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: default avatarOhad Sharabi <osharabi@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent 08c03a19
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -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;
+15 −7
Original line number Diff line number Diff line
@@ -178,11 +178,11 @@ enum hl_pci_match_mode {

/**
 * enum hl_fw_component - F/W components to read version through registers.
 * @FW_COMP_UBOOT: u-boot.
 * @FW_COMP_BOOT_FIT: boot fit.
 * @FW_COMP_PREBOOT: preboot.
 */
enum hl_fw_component {
	FW_COMP_UBOOT,
	FW_COMP_BOOT_FIT,
	FW_COMP_PREBOOT
};

@@ -820,24 +820,36 @@ enum div_select_defs {

/**
 * struct fw_load_mgr - manager FW loading process
 * @kmd_msg_to_cpu_reg: register address for KMD->CPU messages
 * @preboot_version_max_off: max offset to preboot version
 * @boot_fit_version_max_off: max offset to boot fit version
 * @kmd_msg_to_cpu_reg: register address for KDM->CPU messages
 * @cpu_cmd_status_to_host_reg: register address for CPU command status response
 * @cpu_boot_status_reg: boot status register
 * @cpu_boot_dev_status_reg: boot device status register
 * @boot_err0_reg: boot error register
 * @preboot_version_offset_reg: SRAM offset to preboot version register
 * @boot_fit_version_offset_reg: SRAM offset to boot fit version register
 * @sram_offset_mask: mask for getting offset into the SRAM
 * @cpu_timeout: CPU response timeout in usec
 * @boot_fit_timeout: Boot fit load timeout in usec
 * @skip_bmc: should BMC be skipped
 * @sram_bar_id: SRAM bar ID
 */
struct fw_load_mgr {
	u64 preboot_version_max_off;
	u64 boot_fit_version_max_off;
	u32 kmd_msg_to_cpu_reg;
	u32 cpu_cmd_status_to_host_reg;
	u32 cpu_boot_status_reg;
	u32 cpu_boot_dev_status_reg;
	u32 boot_err0_reg;
	u32 preboot_version_offset_reg;
	u32 boot_fit_version_offset_reg;
	u32 sram_offset_mask;
	u32 cpu_timeout;
	u32 boot_fit_timeout;
	u8 skip_bmc;
	u8 sram_bar_id;
};

/**
@@ -929,8 +941,6 @@ struct fw_load_mgr {
 * @ctx_fini: context dependent cleanup.
 * @get_clk_rate: Retrieve the ASIC current and maximum clock rate in MHz
 * @get_queue_id_for_cq: Get the H/W queue id related to the given CQ index.
 * @read_device_fw_version: read the device's firmware versions that are
 *                          contained in registers
 * @load_firmware_to_device: load the firmware to the device's memory
 * @load_boot_fit_to_device: load boot fit to device's memory
 * @get_signal_cb_size: Get signal CB size.
@@ -1059,8 +1069,6 @@ struct hl_asic_funcs {
	void (*ctx_fini)(struct hl_ctx *ctx);
	int (*get_clk_rate)(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk);
	u32 (*get_queue_id_for_cq)(struct hl_device *hdev, u32 cq_idx);
	int (*read_device_fw_version)(struct hl_device *hdev,
					enum hl_fw_component fwc);
	int (*load_firmware_to_device)(struct hl_device *hdev);
	int (*load_boot_fit_to_device)(struct hl_device *hdev);
	u32 (*get_signal_cb_size)(struct hl_device *hdev);
+6 −39
Original line number Diff line number Diff line
@@ -3691,56 +3691,24 @@ static int gaudi_load_boot_fit_to_device(struct hl_device *hdev)
	return hl_fw_load_fw_to_device(hdev, GAUDI_BOOT_FIT_FILE, dst, 0, 0);
}

static int gaudi_read_device_fw_version(struct hl_device *hdev,
					enum hl_fw_component fwc)
{
	const char *name;
	u32 ver_off;
	char *dest;

	switch (fwc) {
	case FW_COMP_UBOOT:
		ver_off = RREG32(mmUBOOT_VER_OFFSET);
		dest = hdev->asic_prop.uboot_ver;
		name = "U-Boot";
		break;
	case FW_COMP_PREBOOT:
		ver_off = RREG32(mmPREBOOT_VER_OFFSET);
		dest = hdev->asic_prop.preboot_ver;
		name = "Preboot";
		break;
	default:
		dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc);
		return -EIO;
	}

	ver_off &= ~((u32)SRAM_BASE_ADDR);

	if (ver_off < SRAM_SIZE - VERSION_MAX_LEN) {
		memcpy_fromio(dest, hdev->pcie_bar[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);
		strcpy(dest, "unavailable");
		return -EIO;
	}

	return 0;
}

static void gaudi_init_firmware_loader(struct hl_device *hdev)
{
	struct fw_load_mgr *fw_loader = &hdev->fw_loader;

	fw_loader->preboot_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
	fw_loader->boot_fit_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
	fw_loader->kmd_msg_to_cpu_reg = mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU;
	fw_loader->cpu_cmd_status_to_host_reg = mmCPU_CMD_STATUS_TO_HOST;
	fw_loader->preboot_version_offset_reg = mmPREBOOT_VER_OFFSET;
	fw_loader->boot_fit_version_offset_reg = mmUBOOT_VER_OFFSET;
	fw_loader->sram_offset_mask = ~((u32)SRAM_BASE_ADDR);
	fw_loader->cpu_timeout = GAUDI_CPU_TIMEOUT_USEC;
	fw_loader->boot_fit_timeout = GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC;
	fw_loader->skip_bmc = !hdev->bmc_enable;
	fw_loader->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
	fw_loader->cpu_boot_dev_status_reg = mmCPU_BOOT_DEV_STS0;
	fw_loader->boot_err0_reg = mmCPU_BOOT_ERR0;
	fw_loader->sram_bar_id = SRAM_BAR_ID;
}

static int gaudi_init_cpu(struct hl_device *hdev)
@@ -8801,7 +8769,6 @@ static const struct hl_asic_funcs gaudi_funcs = {
	.ctx_fini = gaudi_ctx_fini,
	.get_clk_rate = gaudi_get_clk_rate,
	.get_queue_id_for_cq = gaudi_get_queue_id_for_cq,
	.read_device_fw_version = gaudi_read_device_fw_version,
	.load_firmware_to_device = gaudi_load_firmware_to_device,
	.load_boot_fit_to_device = gaudi_load_boot_fit_to_device,
	.get_signal_cb_size = gaudi_get_signal_cb_size,
+6 −44
Original line number Diff line number Diff line
@@ -2402,61 +2402,24 @@ static int goya_load_boot_fit_to_device(struct hl_device *hdev)
	return hl_fw_load_fw_to_device(hdev, GOYA_BOOT_FIT_FILE, dst, 0, 0);
}

/*
 * FW component passes an offset from SRAM_BASE_ADDR in SCRATCHPAD_xx.
 * The version string should be located by that offset.
 */
static int goya_read_device_fw_version(struct hl_device *hdev,
					enum hl_fw_component fwc)
{
	const char *name;
	u32 ver_off;
	char *dest;

	switch (fwc) {
	case FW_COMP_UBOOT:
		ver_off = RREG32(mmUBOOT_VER_OFFSET);
		dest = hdev->asic_prop.uboot_ver;
		name = "U-Boot";
		break;
	case FW_COMP_PREBOOT:
		ver_off = RREG32(mmPREBOOT_VER_OFFSET);
		dest = hdev->asic_prop.preboot_ver;
		name = "Preboot";
		break;
	default:
		dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc);
		return -EIO;
	}

	ver_off &= ~((u32)SRAM_BASE_ADDR);

	if (ver_off < SRAM_SIZE - VERSION_MAX_LEN) {
		memcpy_fromio(dest, hdev->pcie_bar[SRAM_CFG_BAR_ID] + ver_off,
							VERSION_MAX_LEN);
	} else {
		dev_err(hdev->dev, "%s version offset (0x%x) is above SRAM\n",
								name, ver_off);
		strcpy(dest, "unavailable");

		return -EIO;
	}

	return 0;
}

static void goya_init_firmware_loader(struct hl_device *hdev)
{
	struct fw_load_mgr *fw_loader = &hdev->fw_loader;

	fw_loader->preboot_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
	fw_loader->boot_fit_version_max_off = SRAM_SIZE - VERSION_MAX_LEN;
	fw_loader->kmd_msg_to_cpu_reg = mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU;
	fw_loader->cpu_cmd_status_to_host_reg = mmCPU_CMD_STATUS_TO_HOST;
	fw_loader->preboot_version_offset_reg = mmPREBOOT_VER_OFFSET;
	fw_loader->boot_fit_version_offset_reg = mmUBOOT_VER_OFFSET;
	fw_loader->sram_offset_mask = ~((u32)SRAM_BASE_ADDR);
	fw_loader->cpu_timeout = GOYA_CPU_TIMEOUT_USEC;
	fw_loader->boot_fit_timeout = GOYA_BOOT_FIT_REQ_TIMEOUT_USEC;
	fw_loader->skip_bmc = false;
	fw_loader->cpu_boot_status_reg = mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS;
	fw_loader->cpu_boot_dev_status_reg = mmCPU_BOOT_DEV_STS0;
	fw_loader->boot_err0_reg = mmCPU_BOOT_ERR0;
	fw_loader->sram_bar_id = SRAM_CFG_BAR_ID;
}

static int goya_init_cpu(struct hl_device *hdev)
@@ -5533,7 +5496,6 @@ static const struct hl_asic_funcs goya_funcs = {
	.ctx_fini = goya_ctx_fini,
	.get_clk_rate = goya_get_clk_rate,
	.get_queue_id_for_cq = goya_get_queue_id_for_cq,
	.read_device_fw_version = goya_read_device_fw_version,
	.load_firmware_to_device = goya_load_firmware_to_device,
	.load_boot_fit_to_device = goya_load_boot_fit_to_device,
	.get_signal_cb_size = goya_get_signal_cb_size,