mm-drivers: hw_fence: reset queues during client reset

This change make sure that the write_idx and read_idx
of the client hfi queues are reset during the call
to msm_hw_fence_reset_client.

Change-Id: Iaf94865ddf78ed8e19de509e3ee6176d03c5301c
Signed-off-by: Ingrid Gallardo <quic_ingridg@quicinc.com>
Cette révision appartient à :
Ingrid Gallardo
2022-11-14 11:50:04 -08:00
révisé par Gerrit - the friendly Code Review server
Parent 55082654a9
révision 13b4e1270c
3 fichiers modifiés avec 48 ajouts et 1 suppressions

Voir le fichier

@@ -473,6 +473,8 @@ int hw_fence_init_controller_signal(struct hw_fence_driver_data *drv_data,
int hw_fence_init_controller_resources(struct msm_hw_fence_client *hw_fence_client);
void hw_fence_cleanup_client(struct hw_fence_driver_data *drv_data,
struct msm_hw_fence_client *hw_fence_client);
void hw_fence_utils_reset_queues(struct hw_fence_driver_data *drv_data,
struct msm_hw_fence_client *hw_fence_client);
int hw_fence_create(struct hw_fence_driver_data *drv_data,
struct msm_hw_fence_client *hw_fence_client,
u64 context, u64 seqno, u64 *hash);

Voir le fichier

@@ -1430,6 +1430,49 @@ static void _signal_all_wait_clients(struct hw_fence_driver_data *drv_data,
}
}
void hw_fence_utils_reset_queues(struct hw_fence_driver_data *drv_data,
struct msm_hw_fence_client *hw_fence_client)
{
struct msm_hw_fence_hfi_queue_header *hfi_header;
struct msm_hw_fence_queue *queue;
u32 rd_idx, wr_idx, lock_idx;
queue = &hw_fence_client->queues[HW_FENCE_TX_QUEUE - 1];
hfi_header = queue->va_header;
/* For the client TxQ: set the read-index same as last write that was done by the client */
mb(); /* make sure data is ready before read */
wr_idx = readl_relaxed(&hfi_header->write_index);
writel_relaxed(wr_idx, &hfi_header->read_index);
wmb(); /* make sure data is updated after write the index*/
/* For the client RxQ: set the write-index same as last read done by the client */
if (hw_fence_client->update_rxq) {
lock_idx = hw_fence_client->client_id - 1;
if (lock_idx >= drv_data->client_lock_tbl_cnt) {
HWFNC_ERR("cannot reset rxq, lock for client id:%d exceed max:%d\n",
hw_fence_client->client_id, drv_data->client_lock_tbl_cnt);
return;
}
HWFNC_DBG_Q("Locking client id:%d: idx:%d\n", hw_fence_client->client_id, lock_idx);
/* lock the client rx queue to update */
GLOBAL_ATOMIC_STORE(drv_data, &drv_data->client_lock_tbl[lock_idx], 1);
queue = &hw_fence_client->queues[HW_FENCE_RX_QUEUE - 1];
hfi_header = queue->va_header;
mb(); /* make sure data is ready before read */
rd_idx = readl_relaxed(&hfi_header->read_index);
writel_relaxed(rd_idx, &hfi_header->write_index);
wmb(); /* make sure data is updated after write the index */
/* unlock */
GLOBAL_ATOMIC_STORE(drv_data, &drv_data->client_lock_tbl[lock_idx], 0);
}
}
int hw_fence_utils_cleanup_fence(struct hw_fence_driver_data *drv_data,
struct msm_hw_fence_client *hw_fence_client, struct msm_hw_fence *hw_fence, u64 hash,
u32 reset_flags)

Voir le fichier

@@ -389,11 +389,13 @@ int msm_hw_fence_reset_client(void *client_handle, u32 reset_flags)
hw_fence_client = (struct msm_hw_fence_client *)client_handle;
hw_fences_tbl = hw_fence_drv_data->hw_fences_tbl;
HWFNC_DBG_L("reset fences for client:%d\n", hw_fence_client->client_id);
HWFNC_DBG_L("reset fences and queues for client:%d\n", hw_fence_client->client_id);
for (i = 0; i < hw_fence_drv_data->hw_fences_tbl_cnt; i++)
hw_fence_utils_cleanup_fence(hw_fence_drv_data, hw_fence_client,
&hw_fences_tbl[i], i, reset_flags);
hw_fence_utils_reset_queues(hw_fence_drv_data, hw_fence_client);
return 0;
}
EXPORT_SYMBOL(msm_hw_fence_reset_client);