Commit d1ddd905 authored by Ofir Bitton's avatar Ofir Bitton Committed by Oded Gabbay
Browse files

habanalabs: move HW dirty check to a proper location



Driver must verify if HW is dirty before trying to fetch preboot
information. Hence, we move this validation to a prior stage of
the boot sequence.

Signed-off-by: default avatarOfir Bitton <obitton@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent 28e052c9
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
@@ -1278,13 +1278,6 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass)

	hl_debugfs_add_device(hdev);

	if (hdev->asic_funcs->get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) {
		dev_info(hdev->dev,
			"H/W state is dirty, must reset before initializing\n");
		hdev->asic_funcs->halt_engines(hdev, true);
		hdev->asic_funcs->hw_fini(hdev, true);
	}

	/*
	 * From this point, in case of an error, add char devices and create
	 * sysfs nodes as part of the error flow, to allow debugging.
+2 −4
Original line number Diff line number Diff line
@@ -917,7 +917,6 @@ struct hl_asic_funcs {
				size_t max_size);
	int (*send_cpu_message)(struct hl_device *hdev, u32 *msg,
				u16 len, u32 timeout, long *result);
	enum hl_device_hw_state (*get_hw_state)(struct hl_device *hdev);
	int (*pci_bars_map)(struct hl_device *hdev);
	int (*init_iatu)(struct hl_device *hdev);
	u32 (*rreg)(struct hl_device *hdev, u32 reg);
@@ -1901,6 +1900,7 @@ struct hl_device {
	u8				hard_reset_on_fw_events;
	u8				bmc_enable;
	u8				rl_enable;
	u8				reset_on_preboot_fail;
};


@@ -2148,9 +2148,7 @@ int hl_pci_set_inbound_region(struct hl_device *hdev, u8 region,
		struct hl_inbound_pci_region *pci_region);
int hl_pci_set_outbound_region(struct hl_device *hdev,
		struct hl_outbound_pci_region *pci_region);
int hl_pci_init(struct hl_device *hdev, u32 cpu_boot_status_reg,
		u32 cpu_security_boot_status_reg, u32 boot_err0_reg,
		u32 preboot_ver_timeout);
int hl_pci_init(struct hl_device *hdev);
void hl_pci_fini(struct hl_device *hdev);

long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr);
+6 −6
Original line number Diff line number Diff line
@@ -234,20 +234,20 @@ int hl_device_open_ctrl(struct inode *inode, struct file *filp)

static void set_driver_behavior_per_device(struct hl_device *hdev)
{
	hdev->mmu_enable = 1;
	hdev->cpu_enable = 1;
	hdev->fw_loading = 1;
	hdev->fw_loading = FW_TYPE_ALL_TYPES;
	hdev->cpu_queues_enable = 1;
	hdev->heartbeat = 1;
	hdev->mmu_enable = 1;
	hdev->clock_gating_mask = ULONG_MAX;

	hdev->reset_pcilink = 0;
	hdev->axi_drain = 0;
	hdev->sram_scrambler_enable = 1;
	hdev->dram_scrambler_enable = 1;
	hdev->bmc_enable = 1;
	hdev->hard_reset_on_fw_events = 1;
	hdev->fw_loading = FW_TYPE_ALL_TYPES;
	hdev->reset_on_preboot_fail = 1;

	hdev->reset_pcilink = 0;
	hdev->axi_drain = 0;
}

/*
+1 −22
Original line number Diff line number Diff line
@@ -338,20 +338,12 @@ static int hl_pci_set_dma_mask(struct hl_device *hdev)
/**
 * hl_pci_init() - PCI initialization code.
 * @hdev: Pointer to hl_device structure.
 * @cpu_boot_status_reg: status register of the device's CPU
 * @cpu_security_boot_status_reg: status register of device's CPU security
 *                                configuration
 * @boot_err0_reg: boot error register of the device's CPU
 * @preboot_ver_timeout: how much to wait before bailing out on reading
 *                       the preboot version
 *
 * Set DMA masks, initialize the PCI controller and map the PCI BARs.
 *
 * Return: 0 on success, non-zero for failure.
 */
int hl_pci_init(struct hl_device *hdev, u32 cpu_boot_status_reg,
		u32 cpu_security_boot_status_reg, u32 boot_err0_reg,
		u32 preboot_ver_timeout)
int hl_pci_init(struct hl_device *hdev)
{
	struct pci_dev *pdev = hdev->pdev;
	int rc;
@@ -383,19 +375,6 @@ int hl_pci_init(struct hl_device *hdev, u32 cpu_boot_status_reg,
	if (rc)
		goto unmap_pci_bars;

	/* Before continuing in the initialization, we need to read the preboot
	 * version to determine whether we run with a security-enabled firmware
	 * The check will be done in each ASIC's specific code
	 */
	rc = hl_fw_read_preboot_status(hdev, cpu_boot_status_reg,
			cpu_security_boot_status_reg, boot_err0_reg,
			preboot_ver_timeout);
	if (rc) {
		dev_err(hdev->dev, "Failed to read preboot version\n");
		hdev->asic_funcs->hw_fini(hdev, true);
		goto unmap_pci_bars;
	}

	return 0;

unmap_pci_bars:
+26 −9
Original line number Diff line number Diff line
@@ -604,6 +604,11 @@ static int gaudi_init_iatu(struct hl_device *hdev)
	return rc;
}

static enum hl_device_hw_state gaudi_get_hw_state(struct hl_device *hdev)
{
	return RREG32(mmHW_STATE);
}

static int gaudi_early_init(struct hl_device *hdev)
{
	struct asic_fixed_properties *prop = &hdev->asic_prop;
@@ -641,14 +646,32 @@ static int gaudi_early_init(struct hl_device *hdev)

	prop->dram_pci_bar_size = pci_resource_len(pdev, HBM_BAR_ID);

	rc = hl_pci_init(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS,
			mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0,
			GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC);
	rc = hl_pci_init(hdev);
	if (rc)
		goto free_queue_props;

	if (gaudi_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) {
		dev_info(hdev->dev,
			"H/W state is dirty, must reset before initializing\n");
		hdev->asic_funcs->hw_fini(hdev, true);
	}

	/* Before continuing in the initialization, we need to read the preboot
	 * version to determine whether we run with a security-enabled firmware
	 */
	rc = hl_fw_read_preboot_status(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS,
			mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0,
			GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC);
	if (rc) {
		if (hdev->reset_on_preboot_fail)
			hdev->asic_funcs->hw_fini(hdev, true);
		goto pci_fini;
	}

	return 0;

pci_fini:
	hl_pci_fini(hdev);
free_queue_props:
	kfree(hdev->asic_prop.hw_queues_props);
	return rc;
@@ -7691,11 +7714,6 @@ static int gaudi_run_tpc_kernel(struct hl_device *hdev, u64 tpc_kernel,
	return 0;
}

static enum hl_device_hw_state gaudi_get_hw_state(struct hl_device *hdev)
{
	return RREG32(mmHW_STATE);
}

static int gaudi_internal_cb_pool_init(struct hl_device *hdev,
		struct hl_ctx *ctx)
{
@@ -8252,7 +8270,6 @@ static const struct hl_asic_funcs gaudi_funcs = {
	.get_pci_id = gaudi_get_pci_id,
	.get_eeprom_data = gaudi_get_eeprom_data,
	.send_cpu_message = gaudi_send_cpu_message,
	.get_hw_state = gaudi_get_hw_state,
	.pci_bars_map = gaudi_pci_bars_map,
	.init_iatu = gaudi_init_iatu,
	.rreg = hl_rreg,
Loading