Merge "msm: vidc: Add support to prefetch & drain memory"

This commit is contained in:
qctecmdr 2020-03-13 02:50:01 -07:00 • committed by Gerrit - the friendly Code Review server
commit 1af989dbb8
10 changed files with 227 additions and 1 deletions

View file

@ -9,7 +9,6 @@
#include "msm_vidc_debug.h"
#include "msm_vidc_resources.h"
static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align,
dma_addr_t *iova, unsigned long *buffer_size,
unsigned long flags, enum hal_buffer buffer_type,
@ -599,3 +598,73 @@ struct context_bank_info *msm_smem_get_context_bank(u32 session_type,
return match;
}
int msm_smem_memory_prefetch(struct msm_vidc_inst *inst)
{
int i, rc = 0;
struct memory_regions *vidc_regions = NULL;
struct ion_prefetch_region ion_region[MEMORY_REGIONS_MAX];
if (!inst) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
vidc_regions = &inst->regions;
if (vidc_regions->num_regions > MEMORY_REGIONS_MAX) {
s_vpr_e(inst->sid, "%s: invalid num_regions %d, max %d\n",
__func__, vidc_regions->num_regions,
MEMORY_REGIONS_MAX);
return -EINVAL;
}
memset(ion_region, 0, sizeof(ion_region));
for (i = 0; i < vidc_regions->num_regions; i++) {
ion_region[i].size = vidc_regions->region[i].size;
ion_region[i].vmid = vidc_regions->region[i].vmid;
}
rc = msm_ion_heap_prefetch(ION_SECURE_HEAP_ID, ion_region,
vidc_regions->num_regions);
if (rc)
s_vpr_e(inst->sid, "%s: prefetch failed, ret: %d\n",
__func__, rc);
else
s_vpr_l(inst->sid, "%s: prefetch succeeded\n", __func__);
return rc;
}
int msm_smem_memory_drain(struct msm_vidc_inst *inst)
{
int i, rc = 0;
struct memory_regions *vidc_regions = NULL;
struct ion_prefetch_region ion_region[MEMORY_REGIONS_MAX];
if (!inst) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
vidc_regions = &inst->regions;
if (vidc_regions->num_regions > MEMORY_REGIONS_MAX) {
s_vpr_e(inst->sid, "%s: invalid num_regions %d, max %d\n",
__func__, vidc_regions->num_regions,
MEMORY_REGIONS_MAX);
return -EINVAL;
}
memset(ion_region, 0, sizeof(ion_region));
for (i = 0; i < vidc_regions->num_regions; i++) {
ion_region[i].size = vidc_regions->region[i].size;
ion_region[i].vmid = vidc_regions->region[i].vmid;
}
rc = msm_ion_heap_drain(ION_SECURE_HEAP_ID, ion_region,
vidc_regions->num_regions);
if (rc)
s_vpr_e(inst->sid, "%s: drain failed, ret: %d\n", __func__, rc);
else
s_vpr_l(inst->sid, "%s: drain succeeded\n", __func__);
return rc;
}

View file

@ -883,6 +883,7 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
__func__);
return -ENOTSUPP;
}
msm_comm_memory_prefetch(inst);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
if (ctrl->val == EXTRADATA_NONE)

View file

@ -1415,6 +1415,8 @@ static const struct v4l2_ctrl_ops msm_vidc_ctrl_ops = {
static struct msm_vidc_inst_smem_ops msm_vidc_smem_ops = {
.smem_map_dma_buf = msm_smem_map_dma_buf,
.smem_unmap_dma_buf = msm_smem_unmap_dma_buf,
.smem_prefetch = msm_smem_memory_prefetch,
.smem_drain = msm_smem_memory_drain,
};
void *msm_vidc_open(int core_id, int session_type)
@ -1756,6 +1758,7 @@ int msm_vidc_close(void *instance)
}
msm_comm_session_clean(inst);
msm_comm_memory_drain(inst);
kref_put(&inst->kref, close_helper);
return 0;

View file

@ -13,6 +13,7 @@
#define HAL_BUFFER_MAX 0xe
#define CVP_FRAME_RATE_MAX (60)
#define MEMORY_REGIONS_MAX 30
enum smem_type {
SMEM_DMA = 1,
@ -75,6 +76,19 @@ enum smem_cache_ops {
SMEM_CACHE_CLEAN_INVALIDATE,
};
struct memory_regions {
u32 num_regions;
struct {
u64 size;
u32 vmid;
} region[MEMORY_REGIONS_MAX];
};
enum memory_ops {
MEMORY_PREFETCH = 1,
MEMORY_DRAIN,
};
enum core_id {
MSM_VIDC_CORE_VENUS = 0,
MSM_VIDC_CORE_Q6,

View file

@ -7351,3 +7351,94 @@ int msm_comm_fetch_framerate(struct msm_vidc_inst *inst,
}
return rc;
}
static int msm_comm_memory_regions_prepare(struct msm_vidc_inst *inst)
{
u32 i = 0;
struct msm_vidc_platform_resources *res;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
res = &inst->core->resources;
inst->regions.num_regions = res->prefetch_non_pix_buf_count +
res->prefetch_pix_buf_count;
if (inst->regions.num_regions > MEMORY_REGIONS_MAX) {
s_vpr_e(inst->sid, "%s: invalid num_regions: %d, max: %d\n",
__func__, inst->regions.num_regions,
MEMORY_REGIONS_MAX);
return -EINVAL;
}
s_vpr_h(inst->sid,
"%s: preparing %d nonpixel memory regions of %ld bytes each and %d pixel memory regions of %ld bytes each\n",
__func__, res->prefetch_non_pix_buf_count,
res->prefetch_non_pix_buf_size, res->prefetch_pix_buf_count,
res->prefetch_pix_buf_size);
for (i = 0; i < res->prefetch_non_pix_buf_count; i++) {
inst->regions.region[i].size = res->prefetch_non_pix_buf_size;
inst->regions.region[i].vmid = ION_FLAG_CP_NON_PIXEL;
}
for (i = res->prefetch_non_pix_buf_count;
i < inst->regions.num_regions; i++) {
inst->regions.region[i].size = res->prefetch_pix_buf_size;
inst->regions.region[i].vmid = ION_FLAG_CP_PIXEL;
}
return 0;
}
int msm_comm_memory_prefetch(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst || !inst->smem_ops) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
if (inst->memory_ops & MEMORY_PREFETCH) {
s_vpr_h(inst->sid, "%s: prefetch done already\n", __func__);
return 0;
}
rc = msm_comm_memory_regions_prepare(inst);
if (rc)
return rc;
if (inst->regions.num_regions == 0)
return 0;
rc = inst->smem_ops->smem_prefetch(inst);
if (rc)
return rc;
inst->memory_ops |= MEMORY_PREFETCH;
return rc;
}
int msm_comm_memory_drain(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst || !inst->smem_ops) {
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
if (!(inst->memory_ops & MEMORY_PREFETCH))
return 0;
rc = inst->smem_ops->smem_drain(inst);
if (rc)
return rc;
inst->memory_ops &= ~MEMORY_PREFETCH;
return rc;
}

View file

@ -339,4 +339,6 @@ void msm_comm_release_timestamps(struct msm_vidc_inst *inst);
u32 msm_comm_get_max_framerate(struct msm_vidc_inst *inst);
u32 msm_comm_calc_framerate(struct msm_vidc_inst *inst, u64 timestamp_us,
u64 prev_ts);
int msm_comm_memory_prefetch(struct msm_vidc_inst *inst);
int msm_comm_memory_drain(struct msm_vidc_inst *inst);
#endif

View file

@ -485,6 +485,8 @@ struct msm_vidc_inst_smem_ops {
struct msm_smem *smem);
int (*smem_unmap_dma_buf)(struct msm_vidc_inst *inst,
struct msm_smem *smem);
int (*smem_prefetch)(struct msm_vidc_inst *inst);
int (*smem_drain)(struct msm_vidc_inst *inst);
};
struct msm_vidc_inst {
@ -552,6 +554,8 @@ struct msm_vidc_inst {
struct batch_mode batch;
struct delayed_work batch_work;
struct msm_vidc_inst_smem_ops *smem_ops;
enum memory_ops memory_ops;
struct memory_regions regions;
int (*buffer_size_calculators)(struct msm_vidc_inst *inst);
bool all_intra;
bool is_perf_eligible_session;
@ -612,6 +616,8 @@ void msm_smem_put_dma_buf(void *dma_buf, u32 sid);
int msm_smem_cache_operations(struct dma_buf *dbuf,
enum smem_cache_ops cache_op, unsigned long offset,
unsigned long size, u32 sid);
int msm_smem_memory_prefetch(struct msm_vidc_inst *inst);
int msm_smem_memory_drain(struct msm_vidc_inst *inst);
void msm_vidc_fw_unload_handler(struct work_struct *work);
void msm_vidc_ssr_handler(struct work_struct *work);
/*

View file

@ -431,6 +431,33 @@ static struct msm_vidc_common_data lahaina_common_data[] = {
.key = "qcom,avsync-window-size",
.value = 40,
},
{
.key = "qcom,prefetch_non_pix_buf_count",
.value = 1,
},
{
.key = "qcom,prefetch_non_pix_buf_size",
/*
* Internal buffer size is calculated for secure decode session
* of resolution 4k (4096x2160)
* Internal buf size = calculate_scratch_size() +
* calculate_scratch1_size() + calculate_persist1_size()
* Take maximum between VP9 10bit, HEVC 10bit, AVC, MPEG2 secure
* decoder sessions
*/
.value = 209715200,
},
{
.key = "qcom,prefetch_pix_buf_count",
.value = 18,
},
{
.key = "qcom,prefetch_pix_buf_size",
/*
* Calculated by VENUS_BUFFER_SIZE for 4096x2160 UBWC
*/
.value = 13434880,
},
};
static struct msm_vidc_common_data bengal_common_data_v0[] = {

View file

@ -775,6 +775,15 @@ int read_platform_resources_from_drv_data(
res->max_secure_inst_count = find_key_value(platform_data,
"qcom,max-secure-instances");
res->prefetch_pix_buf_count = find_key_value(platform_data,
"qcom,prefetch_pix_buf_count");
res->prefetch_pix_buf_size = find_key_value(platform_data,
"qcom,prefetch_pix_buf_size");
res->prefetch_non_pix_buf_count = find_key_value(platform_data,
"qcom,prefetch_non_pix_buf_count");
res->prefetch_non_pix_buf_size = find_key_value(platform_data,
"qcom,prefetch_non_pix_buf_size");
res->slave_side_cp = find_key_value(platform_data,
"qcom,slave-side-cp");
res->thermal_mitigable = find_key_value(platform_data,

View file

@ -168,6 +168,10 @@ struct msm_vidc_platform_resources {
uint32_t pm_qos_latency_us;
uint32_t max_inst_count;
uint32_t max_secure_inst_count;
uint32_t prefetch_pix_buf_count;
uint32_t prefetch_pix_buf_size;
uint32_t prefetch_non_pix_buf_count;
uint32_t prefetch_non_pix_buf_size;
int msm_vidc_hw_rsp_timeout;
int msm_vidc_firmware_unload_delay;
uint32_t msm_vidc_pwr_collapse_delay;