* [PATCH] habanalabs: load CPU device boot loader from host
@ 2020-04-20 13:46 Oded Gabbay
0 siblings, 0 replies; only message in thread
From: Oded Gabbay @ 2020-04-20 13:46 UTC (permalink / raw)
To: linux-kernel; +Cc: gregkh, Ofir Bitton
From: Ofir Bitton <obitton@habana.ai>
Load CPU device boot loader during driver boot time in order to avoid flash
write for every boot loader update.
To preserve backward-compatibility, skip the device boot load if the device
doesn't request it.
Signed-off-by: Ofir Bitton <obitton@habana.ai>
Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
---
drivers/misc/habanalabs/firmware_if.c | 22 +++++-
drivers/misc/habanalabs/goya/goya.c | 83 ++++----------------
drivers/misc/habanalabs/habanalabs.h | 4 +-
drivers/misc/habanalabs/include/hl_boot_if.h | 3 +
4 files changed, 44 insertions(+), 68 deletions(-)
diff --git a/drivers/misc/habanalabs/firmware_if.c b/drivers/misc/habanalabs/firmware_if.c
index 99983822feeb..fb15a0ffb14d 100644
--- a/drivers/misc/habanalabs/firmware_if.c
+++ b/drivers/misc/habanalabs/firmware_if.c
@@ -329,7 +329,7 @@ static void fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg)
int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg,
u32 msg_to_cpu_reg, u32 boot_err0_reg, bool skip_bmc,
- u32 cpu_timeout)
+ u32 cpu_timeout, u32 boot_fit_timeout)
{
u32 status;
int rc;
@@ -337,6 +337,26 @@ int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg,
dev_info(hdev->dev, "Going to wait for device boot (up to %lds)\n",
cpu_timeout / USEC_PER_SEC);
+ /* Wait for boot FIT request */
+ rc = hl_poll_timeout(
+ hdev,
+ cpu_boot_status_reg,
+ status,
+ status == CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT,
+ 10000,
+ boot_fit_timeout);
+
+ if (rc) {
+ dev_dbg(hdev->dev,
+ "No boot fit request received, resuming boot\n");
+ } else {
+ rc = hdev->asic_funcs->load_boot_fit_to_device(hdev);
+ if (rc)
+ goto out;
+
+ WREG32(msg_to_cpu_reg, KMD_MSG_FIT_RDY);
+ }
+
/* Make sure CPU boot-loader is running */
rc = hl_poll_timeout(
hdev,
diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c
index ddc506d74988..f969fe35f9ce 100644
--- a/drivers/misc/habanalabs/goya/goya.c
+++ b/drivers/misc/habanalabs/goya/goya.c
@@ -72,7 +72,7 @@
*
*/
-#define GOYA_UBOOT_FW_FILE "habanalabs/goya/goya-u-boot.bin"
+#define GOYA_BOOT_FIT_FILE "habanalabs/goya/goya-boot-fit.itb"
#define GOYA_LINUX_FW_FILE "habanalabs/goya/goya-fit.itb"
#define GOYA_MMU_REGS_NUM 63
@@ -87,6 +87,7 @@
#define GOYA_TEST_QUEUE_WAIT_USEC 100000 /* 100ms */
#define GOYA_PLDM_MMU_TIMEOUT_USEC (MMU_CONFIG_TIMEOUT_USEC * 100)
#define GOYA_PLDM_QMAN0_TIMEOUT_USEC (HL_DEVICE_TIMEOUT_USEC * 30)
+#define GOYA_BOOT_FIT_REQ_TIMEOUT_USEC 1000000 /* 1s */
#define GOYA_QMAN0_FENCE_VAL 0xD169B243
@@ -2210,80 +2211,37 @@ static void goya_halt_engines(struct hl_device *hdev, bool hard_reset)
}
/*
- * goya_push_uboot_to_device() - Push u-boot FW code to device.
+ * goya_load_firmware_to_device() - Load LINUX FW code to device.
* @hdev: Pointer to hl_device structure.
*
- * Copy u-boot fw code from firmware file to SRAM BAR.
+ * Copy LINUX fw code from firmware file to HBM BAR.
*
* Return: 0 on success, non-zero for failure.
*/
-static int goya_push_uboot_to_device(struct hl_device *hdev)
+static int goya_load_firmware_to_device(struct hl_device *hdev)
{
void __iomem *dst;
- dst = hdev->pcie_bar[SRAM_CFG_BAR_ID] + UBOOT_FW_OFFSET;
+ dst = hdev->pcie_bar[DDR_BAR_ID] + LINUX_FW_OFFSET;
- return hl_fw_load_fw_to_device(hdev, GOYA_UBOOT_FW_FILE, dst);
+ return hl_fw_load_fw_to_device(hdev, GOYA_LINUX_FW_FILE, dst);
}
/*
- * goya_load_firmware_to_device() - Load LINUX FW code to device.
+ * goya_load_boot_fit_to_device() - Load boot fit to device.
* @hdev: Pointer to hl_device structure.
*
- * Copy LINUX fw code from firmware file to HBM BAR.
+ * Copy boot fit file to SRAM BAR.
*
* Return: 0 on success, non-zero for failure.
*/
-static int goya_load_firmware_to_device(struct hl_device *hdev)
+static int goya_load_boot_fit_to_device(struct hl_device *hdev)
{
void __iomem *dst;
- dst = hdev->pcie_bar[DDR_BAR_ID] + LINUX_FW_OFFSET;
-
- return hl_fw_load_fw_to_device(hdev, GOYA_LINUX_FW_FILE, dst);
-}
-
-static int goya_pldm_init_cpu(struct hl_device *hdev)
-{
- u32 unit_rst_val;
- int rc;
-
- /* Must initialize SRAM scrambler before pushing u-boot to SRAM */
- goya_init_golden_registers(hdev);
-
- /* Put ARM cores into reset */
- WREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL, CPU_RESET_ASSERT);
- RREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL);
+ dst = hdev->pcie_bar[SRAM_CFG_BAR_ID] + BOOT_FIT_SRAM_OFFSET;
- /* Reset the CA53 MACRO */
- unit_rst_val = RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N);
- WREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N, CA53_RESET);
- RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N);
- WREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N, unit_rst_val);
- RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N);
-
- rc = goya_push_uboot_to_device(hdev);
- if (rc)
- return rc;
-
- rc = goya_load_firmware_to_device(hdev);
- if (rc)
- return rc;
-
- WREG32(mmPSOC_GLOBAL_CONF_UBOOT_MAGIC, KMD_MSG_FIT_RDY);
- WREG32(mmPSOC_GLOBAL_CONF_WARM_REBOOT, CPU_BOOT_STATUS_NA);
-
- WREG32(mmCPU_CA53_CFG_RST_ADDR_LSB_0,
- lower_32_bits(SRAM_BASE_ADDR + UBOOT_FW_OFFSET));
- WREG32(mmCPU_CA53_CFG_RST_ADDR_MSB_0,
- upper_32_bits(SRAM_BASE_ADDR + UBOOT_FW_OFFSET));
-
- /* Release ARM core 0 from reset */
- WREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL,
- CPU_RESET_CORE0_DEASSERT);
- RREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL);
-
- return 0;
+ return hl_fw_load_fw_to_device(hdev, GOYA_BOOT_FIT_FILE, dst);
}
/*
@@ -2325,7 +2283,7 @@ static void goya_read_device_fw_version(struct hl_device *hdev,
}
}
-static int goya_init_cpu(struct hl_device *hdev, u32 cpu_timeout)
+static int goya_init_cpu(struct hl_device *hdev)
{
struct goya_device *goya = hdev->asic_specific;
int rc;
@@ -2346,22 +2304,14 @@ static int goya_init_cpu(struct hl_device *hdev, u32 cpu_timeout)
return -EIO;
}
- if (hdev->pldm) {
- rc = goya_pldm_init_cpu(hdev);
- if (rc)
- return rc;
-
- goto out;
- }
-
rc = hl_fw_init_cpu(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS,
mmPSOC_GLOBAL_CONF_UBOOT_MAGIC, mmCPU_BOOT_ERR0,
- false, cpu_timeout);
+ false, GOYA_CPU_TIMEOUT_USEC,
+ GOYA_BOOT_FIT_REQ_TIMEOUT_USEC);
if (rc)
return rc;
-out:
goya->hw_cap_initialized |= HW_CAP_CPU;
return 0;
@@ -2476,7 +2426,7 @@ static int goya_hw_init(struct hl_device *hdev)
*/
WREG32(mmHW_STATE, HL_DEVICE_HW_STATE_DIRTY);
- rc = goya_init_cpu(hdev, GOYA_CPU_TIMEOUT_USEC);
+ rc = goya_init_cpu(hdev);
if (rc) {
dev_err(hdev->dev, "failed to initialize CPU\n");
return rc;
@@ -5270,6 +5220,7 @@ static const struct hl_asic_funcs goya_funcs = {
.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,
.set_dma_mask_from_fw = goya_set_dma_mask_from_fw,
.get_device_time = goya_get_device_time
};
diff --git a/drivers/misc/habanalabs/habanalabs.h b/drivers/misc/habanalabs/habanalabs.h
index 0d3d3c59ae2b..0def1e97bc1b 100644
--- a/drivers/misc/habanalabs/habanalabs.h
+++ b/drivers/misc/habanalabs/habanalabs.h
@@ -552,6 +552,7 @@ enum hl_pll_frequency {
* @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
* @set_dma_mask_from_fw: set the DMA mask in the driver according to the
* firmware configuration
* @get_device_time: Get the device time.
@@ -646,6 +647,7 @@ struct hl_asic_funcs {
void (*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);
void (*set_dma_mask_from_fw)(struct hl_device *hdev);
u64 (*get_device_time)(struct hl_device *hdev);
};
@@ -1645,7 +1647,7 @@ int hl_fw_armcp_info_get(struct hl_device *hdev);
int hl_fw_get_eeprom_data(struct hl_device *hdev, void *data, size_t max_size);
int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg,
u32 msg_to_cpu_reg, u32 boot_err0_reg, bool skip_bmc,
- u32 cpu_timeout);
+ u32 cpu_timeout, u32 boot_fit_timeout);
int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3],
bool is_wc[3]);
diff --git a/drivers/misc/habanalabs/include/hl_boot_if.h b/drivers/misc/habanalabs/include/hl_boot_if.h
index 7106315fc92e..c22d134e73af 100644
--- a/drivers/misc/habanalabs/include/hl_boot_if.h
+++ b/drivers/misc/habanalabs/include/hl_boot_if.h
@@ -11,6 +11,8 @@
#define LKD_HARD_RESET_MAGIC 0xED7BD694
#define HL_POWER9_HOST_MAGIC 0x1DA30009
+#define BOOT_FIT_SRAM_OFFSET 0x200000
+
/*
* CPU error bits in BOOT_ERROR registers
*
@@ -77,6 +79,7 @@ enum cpu_boot_status {
CPU_BOOT_STATUS_BMC_WAITING_SKIPPED, /* deprecated - will be removed */
/* Last boot loader progress status, ready to receive commands */
CPU_BOOT_STATUS_READY_TO_BOOT = 15,
+ CPU_BOOT_STATUS_WAITING_FOR_BOOT_FIT = 16,
};
enum kmd_msg {
--
2.17.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2020-04-20 13:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-20 13:46 [PATCH] habanalabs: load CPU device boot loader from host Oded Gabbay
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.