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 à :

révisé par
Gerrit - the friendly Code Review server

Parent
55082654a9
révision
13b4e1270c
@@ -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);
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur