Commit 28bcf1fd authored by Oded Gabbay's avatar Oded Gabbay

habanalabs: enable F/W events after init done

Only after the initialization of the device is done, the driver is
ready to receive events from the F/W. The driver can't handle events
before that because of races so it will ignore events. In case of
a fatal event, the driver won't know about it and the device will be
operational although it shouldn't be.

Same logic should be applied after hard-reset.
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent b520ca5d
...@@ -1159,12 +1159,20 @@ int hl_device_reset(struct hl_device *hdev, bool hard_reset, ...@@ -1159,12 +1159,20 @@ int hl_device_reset(struct hl_device *hdev, bool hard_reset,
atomic_set(&hdev->in_reset, 0); atomic_set(&hdev->in_reset, 0);
hdev->needs_reset = false; hdev->needs_reset = false;
if (hard_reset) dev_notice(hdev->dev, "Successfully finished resetting the device\n");
if (hard_reset) {
hdev->hard_reset_cnt++; hdev->hard_reset_cnt++;
else
hdev->soft_reset_cnt++;
dev_warn(hdev->dev, "Successfully finished resetting the device\n"); /* After reset is done, we are ready to receive events from
* the F/W. We can't do it before because we will ignore events
* and if those events are fatal, we won't know about it and
* the device will be operational although it shouldn't be
*/
hdev->asic_funcs->enable_events_from_fw(hdev);
} else {
hdev->soft_reset_cnt++;
}
return 0; return 0;
...@@ -1415,6 +1423,13 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass) ...@@ -1415,6 +1423,13 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass)
hdev->init_done = true; hdev->init_done = true;
/* After initialization is done, we are ready to receive events from
* the F/W. We can't do it before because we will ignore events and if
* those events are fatal, we won't know about it and the device will
* be operational although it shouldn't be
*/
hdev->asic_funcs->enable_events_from_fw(hdev);
return 0; return 0;
release_ctx: release_ctx:
......
...@@ -860,12 +860,16 @@ enum div_select_defs { ...@@ -860,12 +860,16 @@ enum div_select_defs {
* and place them in the relevant cs jobs * and place them in the relevant cs jobs
* @collective_wait_create_jobs: allocate collective wait cs jobs * @collective_wait_create_jobs: allocate collective wait cs jobs
* @scramble_addr: Routine to scramble the address prior of mapping it * @scramble_addr: Routine to scramble the address prior of mapping it
* in the MMU. * in the MMU.
* @descramble_addr: Routine to de-scramble the address prior of * @descramble_addr: Routine to de-scramble the address prior of
* showing it to users. * showing it to users.
* @ack_protection_bits_errors: ack and dump all security violations * @ack_protection_bits_errors: ack and dump all security violations
* @get_hw_block_id: retrieve a HW block id to be used by the user to mmap it. * @get_hw_block_id: retrieve a HW block id to be used by the user to mmap it.
* @hw_block_mmap: mmap a HW block with a given id. * @hw_block_mmap: mmap a HW block with a given id.
* @enable_events_from_fw: send interrupt to firmware to notify them the
* driver is ready to receive asynchronous events. This
* function should be called during the first init and
* after every hard-reset of the device
*/ */
struct hl_asic_funcs { struct hl_asic_funcs {
int (*early_init)(struct hl_device *hdev); int (*early_init)(struct hl_device *hdev);
...@@ -982,6 +986,7 @@ struct hl_asic_funcs { ...@@ -982,6 +986,7 @@ struct hl_asic_funcs {
u32 *block_id); u32 *block_id);
int (*hw_block_mmap)(struct hl_device *hdev, struct vm_area_struct *vma, int (*hw_block_mmap)(struct hl_device *hdev, struct vm_area_struct *vma,
u32 block_id, u32 block_size); u32 block_id, u32 block_size);
void (*enable_events_from_fw)(struct hl_device *hdev);
}; };
......
...@@ -1383,8 +1383,6 @@ static int gaudi_late_init(struct hl_device *hdev) ...@@ -1383,8 +1383,6 @@ static int gaudi_late_init(struct hl_device *hdev)
return rc; return rc;
} }
WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_INTS_REGISTER);
rc = gaudi_fetch_psoc_frequency(hdev); rc = gaudi_fetch_psoc_frequency(hdev);
if (rc) { if (rc) {
dev_err(hdev->dev, "Failed to fetch psoc frequency\n"); dev_err(hdev->dev, "Failed to fetch psoc frequency\n");
...@@ -8500,6 +8498,11 @@ static int gaudi_block_mmap(struct hl_device *hdev, ...@@ -8500,6 +8498,11 @@ static int gaudi_block_mmap(struct hl_device *hdev,
return -EPERM; return -EPERM;
} }
static void gaudi_enable_events_from_fw(struct hl_device *hdev)
{
WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_INTS_REGISTER);
}
static const struct hl_asic_funcs gaudi_funcs = { static const struct hl_asic_funcs gaudi_funcs = {
.early_init = gaudi_early_init, .early_init = gaudi_early_init,
.early_fini = gaudi_early_fini, .early_fini = gaudi_early_fini,
...@@ -8581,7 +8584,8 @@ static const struct hl_asic_funcs gaudi_funcs = { ...@@ -8581,7 +8584,8 @@ static const struct hl_asic_funcs gaudi_funcs = {
.descramble_addr = hl_mmu_descramble_addr, .descramble_addr = hl_mmu_descramble_addr,
.ack_protection_bits_errors = gaudi_ack_protection_bits_errors, .ack_protection_bits_errors = gaudi_ack_protection_bits_errors,
.get_hw_block_id = gaudi_get_hw_block_id, .get_hw_block_id = gaudi_get_hw_block_id,
.hw_block_mmap = gaudi_block_mmap .hw_block_mmap = gaudi_block_mmap,
.enable_events_from_fw = gaudi_enable_events_from_fw
}; };
/** /**
......
...@@ -798,9 +798,6 @@ int goya_late_init(struct hl_device *hdev) ...@@ -798,9 +798,6 @@ int goya_late_init(struct hl_device *hdev)
return rc; return rc;
} }
WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
GOYA_ASYNC_EVENT_ID_INTS_REGISTER);
return 0; return 0;
} }
...@@ -5400,6 +5397,12 @@ static int goya_block_mmap(struct hl_device *hdev, struct vm_area_struct *vma, ...@@ -5400,6 +5397,12 @@ static int goya_block_mmap(struct hl_device *hdev, struct vm_area_struct *vma,
return -EPERM; return -EPERM;
} }
static void goya_enable_events_from_fw(struct hl_device *hdev)
{
WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR,
GOYA_ASYNC_EVENT_ID_INTS_REGISTER);
}
static const struct hl_asic_funcs goya_funcs = { static const struct hl_asic_funcs goya_funcs = {
.early_init = goya_early_init, .early_init = goya_early_init,
.early_fini = goya_early_fini, .early_fini = goya_early_fini,
...@@ -5481,7 +5484,8 @@ static const struct hl_asic_funcs goya_funcs = { ...@@ -5481,7 +5484,8 @@ static const struct hl_asic_funcs goya_funcs = {
.descramble_addr = hl_mmu_descramble_addr, .descramble_addr = hl_mmu_descramble_addr,
.ack_protection_bits_errors = goya_ack_protection_bits_errors, .ack_protection_bits_errors = goya_ack_protection_bits_errors,
.get_hw_block_id = goya_get_hw_block_id, .get_hw_block_id = goya_get_hw_block_id,
.hw_block_mmap = goya_block_mmap .hw_block_mmap = goya_block_mmap,
.enable_events_from_fw = goya_enable_events_from_fw
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment