habanalabs: use common fw_version read
authorOhad Sharabi <osharabi@habana.ai>
Sun, 11 Apr 2021 12:26:28 +0000 (15:26 +0300)
committerOded Gabbay <ogabbay@kernel.org>
Fri, 18 Jun 2021 12:23:38 +0000 (15:23 +0300)
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>
drivers/misc/habanalabs/common/firmware_if.c
drivers/misc/habanalabs/common/habanalabs.h
drivers/misc/habanalabs/gaudi/gaudi.c
drivers/misc/habanalabs/goya/goya.c

index e0b0b98..d62ec5b 100644 (file)
@@ -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;
index 108ed2d..a4308d4 100644 (file)
@@ -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);
index 05a74f8..1286687 100644 (file)
@@ -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,
index 678fbbc..dd55fec 100644 (file)
@@ -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,