disp: msm: sde: add support for hw fence error handling

Register callback function to hw fence driver and implement the
callback funtion.

As part of fence error handling, address out of ordering of HW
fences, SW override for release fence signal and handle BW voting
in both cmd and video mode.

Change-Id: I22902762b4cc09a5f5a20cf0dd01fc336a0f0cb4
Signed-off-by: GG Hou <quic_renjhou@quicinc.com>
This commit is contained in:
GG Hou
2023-03-22 11:26:41 +08:00
committed by Gerrit - the friendly Code Review server
parent 97b1afdda8
commit 725c7a0f3d
10 changed files with 236 additions and 3 deletions

View File

@@ -12,6 +12,7 @@
#include "msm_drv.h"
#include "sde_kms.h"
#include "sde_fence.h"
#include "sde_encoder.h"
#define TIMELINE_VAL_LENGTH 128
#define SPEC_FENCE_FLAG_FENCE_ARRAY 0x10
@@ -102,12 +103,39 @@ struct sde_hw_fence_data hw_fence_data_dpu_client[SDE_HW_FENCE_CLIENT_MAX] = {
0, 8, 25, 0, 0}
};
int sde_hw_fence_init(struct sde_hw_ctl *hw_ctl, bool use_dpu_ipcc, struct msm_mmu *mmu)
void msm_hw_fence_error_cb(u32 handle, int error, void *cb_data)
{
struct msm_hw_fence_cb_data *msm_hw_fence_cb_data;
struct sde_hw_fence_error_cb_data *sde_hw_fence_error_data;
SDE_EVT32(handle, error, SDE_EVTLOG_FUNC_ENTRY);
msm_hw_fence_cb_data = (struct msm_hw_fence_cb_data *)cb_data;
if (!msm_hw_fence_cb_data) {
SDE_ERROR("msm hw fence cb data is NULL.\n");
SDE_EVT32(SDE_EVTLOG_FUNC_CASE1, SDE_EVTLOG_ERROR);
return;
}
sde_hw_fence_error_data = (struct sde_hw_fence_error_cb_data *)(msm_hw_fence_cb_data->data);
if (!sde_hw_fence_error_data) {
SDE_ERROR("sde hw fence cb data is NULL.\n");
SDE_EVT32(SDE_EVTLOG_FUNC_CASE2, SDE_EVTLOG_ERROR);
return;
}
sde_encoder_handle_hw_fence_error(sde_hw_fence_error_data->ctl_idx,
sde_hw_fence_error_data->sde_kms, handle, error);
}
int sde_hw_fence_init(struct sde_hw_ctl *hw_ctl, struct sde_kms *sde_kms, bool use_dpu_ipcc,
struct msm_mmu *mmu)
{
struct msm_hw_fence_hfi_queue_header *hfi_queue_header_va, *hfi_queue_header_pa;
struct msm_hw_fence_hfi_queue_table_header *hfi_table_header;
struct sde_hw_fence_data *sde_hw_fence_data;
struct sde_hw_fence_data *hwfence_data;
struct sde_hw_fence_error_cb_data *sde_hw_fence_error_cb_data;
phys_addr_t queue_pa;
void *queue_va;
u32 qhdr0_offset, ctl_hfi_iova;
@@ -149,6 +177,17 @@ int sde_hw_fence_init(struct sde_hw_ctl *hw_ctl, bool use_dpu_ipcc, struct msm_m
return -EINVAL;
}
sde_hw_fence_error_cb_data = &(hwfence_data->sde_hw_fence_error_cb_data);
sde_hw_fence_error_cb_data->ctl_idx = hw_ctl->idx;
sde_hw_fence_error_cb_data->sde_kms = sde_kms;
ret = msm_hw_fence_register_error_cb(hwfence_data->hw_fence_handle,
msm_hw_fence_error_cb, (void *)sde_hw_fence_error_cb_data);
if (ret) {
SDE_EVT32(hw_ctl->idx, SDE_EVTLOG_ERROR);
SDE_DEBUG("hw fence cb register failed. ret = %d\n", ret);
}
/* one-to-one memory map of ctl-path client queues */
ctl_hfi_iova = HW_FENCE_HFI_MMAP_DPU_BA +
PAGE_ALIGN(hwfence_data->mem_descriptor.size * ctl_id);