mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 00:00:00 -04:00
msm: vidc: enhance CVP usage functionality
Amend below CVP functionalities - enable logic - start sequence - frame skip logic - downscale resolution logic - debugfs support. Change-Id: I21ad934526c338916d130aaf3401bd89b574b4c1 Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
This commit is contained in:
parent
ae78fd954b
commit
35da0d64cf
14 changed files with 331 additions and 212 deletions
|
|
@ -299,7 +299,7 @@ static int __dsp_send_hfi_queue(struct venus_hfi_device *device)
|
|||
{
|
||||
int rc;
|
||||
|
||||
if (!device->res->domain_cvp)
|
||||
if (!device->res->cvp_internal)
|
||||
return 0;
|
||||
|
||||
if (!device->dsp_iface_q_table.mem_data.dma_handle) {
|
||||
|
|
@ -333,7 +333,7 @@ static int __dsp_suspend(struct venus_hfi_device *device, bool force, u32 flags)
|
|||
int rc;
|
||||
struct hal_session *temp;
|
||||
|
||||
if (!device->res->domain_cvp)
|
||||
if (!device->res->cvp_internal)
|
||||
return 0;
|
||||
|
||||
if (!(device->dsp_flags & DSP_INIT))
|
||||
|
|
@ -374,7 +374,7 @@ static int __dsp_resume(struct venus_hfi_device *device, u32 flags)
|
|||
{
|
||||
int rc;
|
||||
|
||||
if (!device->res->domain_cvp)
|
||||
if (!device->res->cvp_internal)
|
||||
return 0;
|
||||
|
||||
if (!(device->dsp_flags & DSP_SUSPEND)) {
|
||||
|
|
@ -400,7 +400,7 @@ static int __dsp_shutdown(struct venus_hfi_device *device, u32 flags)
|
|||
{
|
||||
int rc;
|
||||
|
||||
if (!device->res->domain_cvp)
|
||||
if (!device->res->cvp_internal)
|
||||
return 0;
|
||||
|
||||
if (!(device->dsp_flags & DSP_INIT)) {
|
||||
|
|
@ -1171,7 +1171,7 @@ static inline int __boot_firmware_common(struct venus_hfi_device *device)
|
|||
u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000;
|
||||
|
||||
ctrl_init_val = BIT(0);
|
||||
if (device->res->domain_cvp)
|
||||
if (device->res->cvp_internal)
|
||||
ctrl_init_val |= BIT(1);
|
||||
|
||||
__write_register(device, CTRL_INIT, ctrl_init_val);
|
||||
|
|
@ -1688,7 +1688,7 @@ static void __interface_queues_release(struct venus_hfi_device *device)
|
|||
device->mem_addr.align_virtual_addr = NULL;
|
||||
device->mem_addr.align_device_addr = 0;
|
||||
|
||||
if (device->res->domain_cvp)
|
||||
if (device->res->cvp_internal)
|
||||
__interface_dsp_queues_release(device);
|
||||
}
|
||||
|
||||
|
|
@ -1901,7 +1901,7 @@ static int __interface_queues_init(struct venus_hfi_device *dev)
|
|||
}
|
||||
|
||||
|
||||
if (dev->res->domain_cvp) {
|
||||
if (dev->res->cvp_internal) {
|
||||
rc = __interface_dsp_queues_init(dev);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "dsp_queues_init failed\n");
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ void __setup_ucregion_memory_map_iris1(struct venus_hfi_device *device)
|
|||
__write_register(device, HFI_DSP_UC_REGION_ADDR,
|
||||
(u32)device->iface_q_table.align_device_addr);
|
||||
__write_register(device, HFI_DSP_UC_REGION_SIZE, SHARED_QSIZE);
|
||||
if (device->res->domain_cvp) {
|
||||
if (device->res->cvp_internal) {
|
||||
/* initialize DSP QTBL & UCREGION with DSP queues */
|
||||
__write_register(device, HFI_DSP_QTBL_ADDR,
|
||||
(u32)device->dsp_iface_q_table.align_device_addr);
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ int __boot_firmware_iris2(struct venus_hfi_device *device)
|
|||
u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 10000;
|
||||
|
||||
ctrl_init_val = BIT(0);
|
||||
if (device->res->domain_cvp)
|
||||
if (device->res->cvp_internal)
|
||||
ctrl_init_val |= BIT(1);
|
||||
|
||||
__write_register(device, CTRL_INIT_IRIS2, ctrl_init_val);
|
||||
|
|
|
|||
|
|
@ -171,6 +171,66 @@ error:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cvp_init_downscale_resolution(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_cvp_external *cvp;
|
||||
const u32 width_max = 1920;
|
||||
u32 width, height, ds_width, ds_height, temp;
|
||||
|
||||
if (!inst || !inst->cvp) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
cvp = inst->cvp;
|
||||
|
||||
ds_width = cvp->width;
|
||||
ds_height = cvp->height;
|
||||
|
||||
if (!cvp->downscale) {
|
||||
dprintk(VIDC_DBG, "%s: downscaling not enabled\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Step 1) make width always the larger number */
|
||||
if (cvp->height > cvp->width) {
|
||||
width = cvp->height;
|
||||
height = cvp->width;
|
||||
} else {
|
||||
width = cvp->width;
|
||||
height = cvp->height;
|
||||
}
|
||||
/*
|
||||
* Step 2) Downscale width by 4 and round
|
||||
* make sure width stays between 480 and 1920
|
||||
*/
|
||||
ds_width = (width + 2) >> 2;
|
||||
if (ds_width < 480)
|
||||
ds_width = 480;
|
||||
if (ds_width > width_max)
|
||||
ds_width = width_max;
|
||||
ds_height = (height * ds_width) / width;
|
||||
if (ds_height < 128)
|
||||
ds_height = 128;
|
||||
|
||||
/* Step 3) do not downscale if width is less than 480 */
|
||||
if (width <= 480)
|
||||
ds_width = width;
|
||||
if (ds_width == width)
|
||||
ds_height = height;
|
||||
|
||||
/* Step 4) switch width and height if already switched */
|
||||
if (height > width) {
|
||||
temp = ds_height;
|
||||
ds_height = ds_width;
|
||||
ds_width = temp;
|
||||
}
|
||||
|
||||
exit:
|
||||
cvp->ds_width = ds_width;
|
||||
cvp->ds_height = ds_height;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm_cvp_deinit_downscale_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_cvp_external *cvp;
|
||||
|
|
@ -389,15 +449,12 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
|
|||
struct cvp_kmd_arg *arg;
|
||||
struct msm_cvp_session_set_persist_buffers_packet persist2_packet;
|
||||
|
||||
if (!inst || !inst->cvp) {
|
||||
if (!inst || !inst->cvp || !inst->cvp->arg) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
|
||||
if (!arg)
|
||||
return -ENOMEM;
|
||||
|
||||
cvp = inst->cvp;
|
||||
arg = cvp->arg;
|
||||
dprintk(VIDC_DBG, "%s:\n", __func__);
|
||||
|
||||
cvp->persist2_buffer.size = HFI_DME_INTERNAL_PERSIST_2_BUFFER_SIZE;
|
||||
|
|
@ -451,35 +508,36 @@ static int msm_cvp_init_internal_buffers(struct msm_vidc_inst *inst)
|
|||
print_cvp_buffer(VIDC_DBG, "alloc: output_buffer",
|
||||
inst, &cvp->output_buffer);
|
||||
|
||||
kfree(arg);
|
||||
return rc;
|
||||
|
||||
error:
|
||||
msm_cvp_deinit_internal_buffers(inst);
|
||||
kfree(arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst,
|
||||
struct vb2_buffer *vb)
|
||||
struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_external *cvp;
|
||||
struct dma_buf *dbuf = NULL;
|
||||
char *kvaddr = NULL;
|
||||
struct vb2_buffer *vb;
|
||||
struct dma_buf *dbuf;
|
||||
char *kvaddr;
|
||||
struct msm_vidc_extradata_header *e_hdr;
|
||||
bool input_extradata, found_end;
|
||||
|
||||
if (!inst || !inst->cvp || !vb) {
|
||||
if (!inst || !inst->cvp || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
cvp = inst->cvp;
|
||||
|
||||
vb = &mbuf->vvb.vb2_buf;
|
||||
if (vb->num_planes <= 1) {
|
||||
dprintk(VIDC_ERR, "%s: extradata plane not enabled\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
cvp = inst->cvp;
|
||||
|
||||
dbuf = dma_buf_get(vb->planes[1].m.fd);
|
||||
if (!dbuf) {
|
||||
|
|
@ -539,17 +597,24 @@ static int msm_cvp_prepare_extradata(struct msm_vidc_inst *inst,
|
|||
dbuf->size);
|
||||
goto error;
|
||||
}
|
||||
/* copy payload */
|
||||
e_hdr->version = 0x00000001;
|
||||
e_hdr->port_index = 1;
|
||||
e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA;
|
||||
e_hdr->data_size = sizeof(struct msm_vidc_enc_cvp_metadata_payload);
|
||||
e_hdr->size = sizeof(struct msm_vidc_extradata_header) +
|
||||
if (cvp->metadata_available) {
|
||||
cvp->metadata_available = false;
|
||||
|
||||
/* copy payload */
|
||||
e_hdr->version = 0x00000001;
|
||||
e_hdr->port_index = 1;
|
||||
e_hdr->type = MSM_VIDC_EXTRADATA_CVP_METADATA;
|
||||
e_hdr->data_size =
|
||||
sizeof(struct msm_vidc_enc_cvp_metadata_payload);
|
||||
e_hdr->size = sizeof(struct msm_vidc_extradata_header) +
|
||||
e_hdr->data_size;
|
||||
dma_buf_begin_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL);
|
||||
memcpy(e_hdr->data, cvp->output_buffer.kvaddr,
|
||||
dma_buf_begin_cpu_access(cvp->output_buffer.dbuf,
|
||||
DMA_BIDIRECTIONAL);
|
||||
memcpy(e_hdr->data, cvp->output_buffer.kvaddr,
|
||||
sizeof(struct msm_vidc_enc_cvp_metadata_payload));
|
||||
dma_buf_end_cpu_access(cvp->output_buffer.dbuf, DMA_BIDIRECTIONAL);
|
||||
dma_buf_end_cpu_access(cvp->output_buffer.dbuf,
|
||||
DMA_BIDIRECTIONAL);
|
||||
}
|
||||
/* fill extradata none */
|
||||
e_hdr = (struct msm_vidc_extradata_header *)
|
||||
((char *)e_hdr + e_hdr->size);
|
||||
|
|
@ -607,27 +672,52 @@ static int msm_cvp_reference_management(struct msm_vidc_inst *inst)
|
|||
}
|
||||
|
||||
static int msm_cvp_frame_process(struct msm_vidc_inst *inst,
|
||||
struct vb2_buffer *vb)
|
||||
struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_external *cvp;
|
||||
struct vb2_buffer *vb;
|
||||
struct cvp_kmd_arg *arg;
|
||||
struct msm_cvp_dme_frame_packet *frame;
|
||||
const u32 fps_max = 60;
|
||||
u32 fps, skip_framecount;
|
||||
bool skipframe = false;
|
||||
|
||||
if (!inst || !inst->cvp) {
|
||||
if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
|
||||
if (!arg)
|
||||
return -ENOMEM;
|
||||
|
||||
cvp = inst->cvp;
|
||||
arg = cvp->arg;
|
||||
|
||||
vb = &mbuf->vvb.vb2_buf;
|
||||
cvp->fullres_buffer.index = vb->index;
|
||||
cvp->fullres_buffer.fd = vb->planes[0].m.fd;
|
||||
cvp->fullres_buffer.size = vb->planes[0].length;
|
||||
cvp->fullres_buffer.offset = vb->planes[0].data_offset;
|
||||
|
||||
/* frame skip logic */
|
||||
fps = max(inst->clk_data.operating_rate,
|
||||
inst->clk_data.frame_rate) >> 16;
|
||||
if (fps > fps_max) {
|
||||
/*
|
||||
* fps <= 120: 0, 2, 4, 6 .. are not skipped
|
||||
* fps <= 180: 0, 3, 6, 9 .. are not skipped
|
||||
* fps <= 240: 0, 4, 8, 12 .. are not skipped
|
||||
* fps <= 960: 0, 16, 32, 48 .. are not skipped
|
||||
*/
|
||||
fps = ALIGN(fps, fps_max);
|
||||
skip_framecount = fps / fps_max;
|
||||
skipframe = !(cvp->framecount % skip_framecount);
|
||||
}
|
||||
if (skipframe) {
|
||||
print_cvp_buffer(VIDC_DBG, "input frame skipped",
|
||||
inst, &cvp->fullres_buffer);
|
||||
cvp->framecount++;
|
||||
cvp->metadata_available = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
arg->type = CVP_KMD_SEND_CMD_PKT;
|
||||
frame = (struct msm_cvp_dme_frame_packet *)&arg->data.hfi_pkt.pkt_data;
|
||||
|
||||
|
|
@ -680,18 +770,19 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst,
|
|||
goto error;
|
||||
}
|
||||
cvp->framecount++;
|
||||
cvp->metadata_available = true;
|
||||
|
||||
error:
|
||||
kfree(arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
|
||||
int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_cvp_external *cvp;
|
||||
|
||||
if (!inst || !inst->cvp || !vb) {
|
||||
if (!inst || !inst->cvp || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -702,13 +793,13 @@ int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
|
|||
}
|
||||
cvp = inst->cvp;
|
||||
|
||||
rc = msm_cvp_frame_process(inst, vb);
|
||||
rc = msm_cvp_frame_process(inst, mbuf);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: cvp process failed\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = msm_cvp_prepare_extradata(inst, vb);
|
||||
rc = msm_cvp_prepare_extradata(inst, mbuf);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: prepare extradata failed\n", __func__);
|
||||
return rc;
|
||||
|
|
@ -760,6 +851,8 @@ static int msm_vidc_cvp_close(struct msm_vidc_inst *inst)
|
|||
"%s: cvp close failed with error %d\n", __func__, rc);
|
||||
cvp->priv = NULL;
|
||||
|
||||
kfree(cvp->arg);
|
||||
cvp->arg = NULL;
|
||||
kfree(inst->cvp);
|
||||
inst->cvp = NULL;
|
||||
|
||||
|
|
@ -792,39 +885,25 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
|
|||
struct msm_cvp_dme_basic_config_packet *dmecfg;
|
||||
u32 color_fmt;
|
||||
|
||||
if (!inst || !inst->cvp) {
|
||||
if (!inst || !inst->cvp || !inst->cvp->arg) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
|
||||
if (!arg)
|
||||
return -ENOMEM;
|
||||
|
||||
f = &inst->fmts[INPUT_PORT].v4l2_fmt;
|
||||
cvp = inst->cvp;
|
||||
|
||||
arg = cvp->arg;
|
||||
cvp->framecount = 0;
|
||||
cvp->metadata_available = false;
|
||||
f = &inst->fmts[INPUT_PORT].v4l2_fmt;
|
||||
cvp->width = f->fmt.pix_mp.width;
|
||||
cvp->height = f->fmt.pix_mp.height;
|
||||
color_fmt = msm_comm_convert_color_fmt(f->fmt.pix_mp.pixelformat);
|
||||
|
||||
/* enable downscale always */
|
||||
cvp->downscale = true;
|
||||
if (cvp->width * cvp->height < 640 * 480) {
|
||||
cvp->ds_width = cvp->width;
|
||||
cvp->ds_height = cvp->height;
|
||||
} else if (cvp->width * cvp->height < 1920 * 1080) {
|
||||
if (cvp->ds_width >= cvp->ds_height) {
|
||||
cvp->ds_width = 480;
|
||||
cvp->ds_height = 270;
|
||||
} else {
|
||||
cvp->ds_width = 270;
|
||||
cvp->ds_height = 480;
|
||||
}
|
||||
} else {
|
||||
cvp->ds_width = cvp->width / 4;
|
||||
cvp->ds_height = cvp->height / 4;
|
||||
}
|
||||
rc = msm_cvp_init_downscale_resolution(inst);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: pixelformat %#x, wxh %dx%d downscale %d ds_wxh %dx%d\n",
|
||||
__func__, f->fmt.pix_mp.pixelformat,
|
||||
|
|
@ -873,12 +952,10 @@ static int msm_vidc_cvp_init(struct msm_vidc_inst *inst)
|
|||
if (rc)
|
||||
goto error;
|
||||
|
||||
kfree(arg);
|
||||
return rc;
|
||||
|
||||
error:
|
||||
msm_vidc_cvp_deinit(inst);
|
||||
kfree(arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -892,18 +969,22 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst)
|
|||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
|
||||
if (!arg)
|
||||
return -ENOMEM;
|
||||
|
||||
inst->cvp = kzalloc(sizeof(struct msm_cvp_external), GFP_KERNEL);
|
||||
if (!inst->cvp) {
|
||||
dprintk(VIDC_ERR, "%s: failed to allocate\n", __func__);
|
||||
rc = -ENOMEM;
|
||||
goto error;
|
||||
return -ENOMEM;
|
||||
}
|
||||
cvp = inst->cvp;
|
||||
|
||||
cvp->arg = kzalloc(sizeof(struct cvp_kmd_arg), GFP_KERNEL);
|
||||
if (!cvp->arg) {
|
||||
kfree(inst->cvp);
|
||||
inst->cvp = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
arg = cvp->arg;
|
||||
|
||||
dprintk(VIDC_DBG, "%s: opening cvp\n", __func__);
|
||||
cvp->priv = msm_cvp_open(0, MSM_VIDC_CVP);
|
||||
if (!cvp->priv) {
|
||||
|
|
@ -923,14 +1004,10 @@ static int msm_vidc_cvp_open(struct msm_vidc_inst *inst)
|
|||
dprintk(VIDC_DBG, "%s: cvp session id %#x\n",
|
||||
__func__, cvp->session_id);
|
||||
|
||||
kfree(arg);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
msm_vidc_cvp_close(inst);
|
||||
kfree(inst->cvp);
|
||||
inst->cvp = NULL;
|
||||
kfree(arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,11 +50,6 @@ static inline bool is_vidc_cvp_enabled(struct msm_vidc_inst *inst)
|
|||
return !!inst->cvp;
|
||||
}
|
||||
|
||||
static inline bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct msm_cvp_buffer_type {
|
||||
u32 buffer_addr;
|
||||
u32 size;
|
||||
|
|
@ -143,6 +138,7 @@ struct msm_cvp_buf {
|
|||
|
||||
struct msm_cvp_external {
|
||||
void *priv;
|
||||
void *arg;
|
||||
u32 session_id;
|
||||
u32 width;
|
||||
u32 height;
|
||||
|
|
@ -151,6 +147,7 @@ struct msm_cvp_external {
|
|||
bool downscale;
|
||||
u32 framecount;
|
||||
u32 buffer_idx;
|
||||
bool metadata_available;
|
||||
struct msm_cvp_buf fullres_buffer;
|
||||
struct msm_cvp_buf src_buffer;
|
||||
struct msm_cvp_buf ref_buffer;
|
||||
|
|
@ -161,8 +158,7 @@ struct msm_cvp_external {
|
|||
};
|
||||
|
||||
int msm_vidc_cvp_preprocess(struct msm_vidc_inst *inst,
|
||||
struct vb2_buffer *vb);
|
||||
struct msm_vidc_buffer *mbuf);
|
||||
int msm_vidc_cvp_prepare_preprocess(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_cvp_unprepare_preprocess(struct msm_vidc_inst *inst);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* setup the cvp device */
|
||||
if (core->resources.domain_cvp) {
|
||||
if (core->resources.cvp_internal) {
|
||||
rc = msm_vidc_register_video_device(MSM_VIDC_CVP,
|
||||
nr + 2, core, dev);
|
||||
if (rc) {
|
||||
|
|
@ -583,7 +583,7 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
|
|||
err_fail_sub_device_probe:
|
||||
vidc_hfi_deinitialize(core->hfi_type, core->device);
|
||||
err_cores_exceeded:
|
||||
if (core->resources.domain_cvp) {
|
||||
if (core->resources.cvp_internal) {
|
||||
device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev,
|
||||
&dev_attr_link_name);
|
||||
video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev);
|
||||
|
|
@ -663,7 +663,7 @@ static int msm_vidc_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
vidc_hfi_deinitialize(core->hfi_type, core->device);
|
||||
if (core->resources.domain_cvp) {
|
||||
if (core->resources.cvp_internal) {
|
||||
device_remove_file(&core->vdev[MSM_VIDC_CVP].vdev.dev,
|
||||
&dev_attr_link_name);
|
||||
video_unregister_device(&core->vdev[MSM_VIDC_CVP].vdev);
|
||||
|
|
|
|||
|
|
@ -3833,7 +3833,6 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst)
|
|||
int msm_venc_set_extradata(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
struct v4l2_ctrl *cvp_ctrl;
|
||||
u32 value = 0x0;
|
||||
u32 codec;
|
||||
|
||||
|
|
@ -3872,25 +3871,13 @@ int msm_venc_set_extradata(struct msm_vidc_inst *inst)
|
|||
}
|
||||
}
|
||||
|
||||
cvp_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE);
|
||||
if (cvp_ctrl->val == V4L2_MPEG_MSM_VIDC_ENABLE) {
|
||||
if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* For now, enable CVP metadata only if client provides it.
|
||||
* Once the kernel-mode CVP metadata implementation
|
||||
* is completed, this condition should be removed.
|
||||
*/
|
||||
if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP)
|
||||
value = 0x1;
|
||||
|
||||
}
|
||||
if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP)
|
||||
value = 0x1;
|
||||
dprintk(VIDC_DBG, "%s: CVP extradata %d\n", __func__, value);
|
||||
rc = msm_comm_set_extradata(inst,
|
||||
HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, value);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: set CVP extradata failed\n", __func__);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,46 +325,6 @@ int msm_vidc_release_buffer(void *instance, int type, unsigned int index)
|
|||
}
|
||||
EXPORT_SYMBOL(msm_vidc_release_buffer);
|
||||
|
||||
static int msm_vidc_preprocess(struct msm_vidc_inst *inst,
|
||||
struct vb2_buffer *vb)
|
||||
{
|
||||
int rc = 0;
|
||||
struct buf_queue *q;
|
||||
|
||||
if (!inst || !vb) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!is_encode_session(inst) || vb->type !=
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
|
||||
return 0;
|
||||
|
||||
if (!is_vidc_cvp_enabled(inst))
|
||||
return 0;
|
||||
|
||||
q = msm_comm_get_vb2q(inst, vb->type);
|
||||
if (!q) {
|
||||
dprintk(VIDC_ERR, "%s: queue not found for type %d\n",
|
||||
__func__, vb->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!q->vb2_bufq.streaming) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: enable input port streaming before queuing input buffers\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = msm_vidc_cvp_preprocess(inst, vb);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: cvp preprocess failed\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
|
||||
{
|
||||
struct msm_vidc_inst *inst = instance;
|
||||
|
|
@ -739,6 +699,51 @@ static int msm_vidc_set_properties(struct msm_vidc_inst *inst)
|
|||
return rc;
|
||||
}
|
||||
|
||||
bool is_vidc_cvp_allowed(struct msm_vidc_inst *inst)
|
||||
{
|
||||
bool allowed = false;
|
||||
struct msm_vidc_core *core;
|
||||
struct v4l2_ctrl *cvp_disable;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
/*
|
||||
* CVP enable if
|
||||
* - platform support CVP external
|
||||
* - client did not disable CVP forcefully
|
||||
* - client may disable forcefully to save power
|
||||
* - client did not enable CVP extradata
|
||||
* - if enabled, client will give CVP extradata
|
||||
* - rate control is not one of below modes
|
||||
* - RATE_CONTROL_OFF
|
||||
* - V4L2_MPEG_VIDEO_BITRATE_MODE_CQ
|
||||
* - V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_PLUS
|
||||
*/
|
||||
cvp_disable = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VENC_CVP_DISABLE);
|
||||
|
||||
if (core->resources.cvp_external && !cvp_disable->val &&
|
||||
!(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) &&
|
||||
inst->rc_type != RATE_CONTROL_OFF &&
|
||||
inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ &&
|
||||
!inst->clk_data.is_cbr_plus) {
|
||||
dprintk(VIDC_DBG, "%s: cvp allowed\n", __func__);
|
||||
allowed = true;
|
||||
} else {
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: cvp not allowed, cvp_external %d cvp_disable %d extradata %#x rc_type %d\n",
|
||||
__func__, core->resources.cvp_external,
|
||||
cvp_disable->val, inst->prop.extradata_ctrls,
|
||||
inst->rc_type);
|
||||
allowed = false;
|
||||
}
|
||||
exit:
|
||||
return allowed;
|
||||
}
|
||||
|
||||
static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -748,6 +753,11 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!msm_vidc_cvp_usage) {
|
||||
dprintk(VIDC_DBG, "%s: cvp usage disabled\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!is_vidc_cvp_allowed(inst)) {
|
||||
dprintk(VIDC_DBG, "%s: cvp not allowed\n", __func__);
|
||||
return 0;
|
||||
|
|
@ -756,12 +766,21 @@ static int msm_vidc_prepare_preprocess(struct msm_vidc_inst *inst)
|
|||
rc = msm_vidc_cvp_prepare_preprocess(inst);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN, "%s: no cvp preprocessing\n", __func__);
|
||||
msm_vidc_cvp_unprepare_preprocess(inst);
|
||||
goto exit;
|
||||
}
|
||||
dprintk(VIDC_DBG, "%s: cvp enabled\n", __func__);
|
||||
|
||||
dprintk(VIDC_DBG, "%s: set CVP extradata\n", __func__);
|
||||
rc = msm_comm_set_extradata(inst,
|
||||
HFI_PROPERTY_PARAM_VENC_CVP_METADATA_EXTRADATA, 1);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN, "%s: set CVP extradata failed\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (rc)
|
||||
msm_vidc_cvp_unprepare_preprocess(inst);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -783,6 +802,15 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
|
|||
goto fail_start;
|
||||
}
|
||||
|
||||
if (is_encode_session(inst)) {
|
||||
rc = msm_vidc_prepare_preprocess(inst);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__);
|
||||
/* ignore error */
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
b.buffer_type = HFI_BUFFER_OUTPUT;
|
||||
if (inst->session_type == MSM_VIDC_DECODER &&
|
||||
is_secondary_output_mode(inst))
|
||||
|
|
@ -968,16 +996,6 @@ static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
|
|||
goto stream_start_failed;
|
||||
}
|
||||
|
||||
if (is_encode_session(inst) && q->type ==
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
rc = msm_vidc_prepare_preprocess(inst);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN, "%s: no preprocessing\n", __func__);
|
||||
/* ignore error */
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
rc = msm_comm_qbufs(inst);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
|
|
@ -1027,24 +1045,6 @@ stream_start_failed:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static inline int stop_streaming(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__,
|
||||
hash32_ptr(inst->session), inst);
|
||||
|
||||
rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to move inst: %pK to state %d\n",
|
||||
inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
|
||||
|
||||
msm_clock_data_reset(inst);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -1066,6 +1066,32 @@ static int msm_vidc_unprepare_preprocess(struct msm_vidc_inst *inst)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static inline int stop_streaming(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
dprintk(VIDC_DBG, "%s: %x : inst %pK\n", __func__,
|
||||
hash32_ptr(inst->session), inst);
|
||||
|
||||
rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to move inst: %pK to state %d\n",
|
||||
inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
|
||||
|
||||
if (is_encode_session(inst)) {
|
||||
rc = msm_vidc_unprepare_preprocess(inst);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: failed to unprepare preprocess\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
msm_clock_data_reset(inst);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void msm_vidc_stop_streaming(struct vb2_queue *q)
|
||||
{
|
||||
struct msm_vidc_inst *inst;
|
||||
|
|
@ -1078,16 +1104,6 @@ static void msm_vidc_stop_streaming(struct vb2_queue *q)
|
|||
|
||||
inst = q->drv_priv;
|
||||
dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
|
||||
|
||||
if (is_encode_session(inst) && q->type ==
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
rc = msm_vidc_unprepare_preprocess(inst);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: failed to unprepare preprocess\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
switch (q->type) {
|
||||
case INPUT_MPLANE:
|
||||
if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
|
||||
|
|
@ -1209,20 +1225,11 @@ static void msm_vidc_buf_queue(struct vb2_buffer *vb2)
|
|||
return;
|
||||
}
|
||||
|
||||
/* do preprocessing if any */
|
||||
rc = msm_vidc_preprocess(inst, vb2);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: preprocess failed %x\n",
|
||||
__func__, hash32_ptr(inst->session));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (inst->batch.enable)
|
||||
rc = msm_vidc_queue_buf_batch(inst, vb2);
|
||||
else
|
||||
rc = msm_vidc_queue_buf(inst, vb2);
|
||||
|
||||
exit:
|
||||
if (rc) {
|
||||
print_vb2_buffer(VIDC_ERR, "failed vb2-qbuf", inst, vb2);
|
||||
msm_comm_generate_session_error(inst);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "vidc_hfi.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_clocks.h"
|
||||
#include "msm_cvp_external.h"
|
||||
#include "msm_cvp_internal.h"
|
||||
#include "msm_vidc_buffer_calculations.h"
|
||||
|
||||
|
|
@ -4058,6 +4059,34 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int msm_comm_preprocess(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffer *mbuf)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!inst || !mbuf) {
|
||||
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* preprocessing is allowed for encoder input buffer only */
|
||||
if (!is_encode_session(inst) || mbuf->vvb.vb2_buf.type != INPUT_MPLANE)
|
||||
return 0;
|
||||
|
||||
/* preprocessing is done using CVP module only */
|
||||
if (!is_vidc_cvp_enabled(inst))
|
||||
return 0;
|
||||
|
||||
rc = msm_vidc_cvp_preprocess(inst, mbuf);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: cvp preprocess failed\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void populate_frame_data(struct vidc_frame_data *data,
|
||||
struct msm_vidc_buffer *mbuf, struct msm_vidc_inst *inst)
|
||||
{
|
||||
|
|
@ -4264,6 +4293,10 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
rc = msm_comm_preprocess(inst, mbuf);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = msm_comm_scale_clocks_and_bus(inst);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);
|
||||
|
|
@ -4280,6 +4313,7 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst)
|
|||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_buffer *mbuf;
|
||||
bool found;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
|
||||
|
|
@ -4292,24 +4326,36 @@ int msm_comm_qbufs(struct msm_vidc_inst *inst)
|
|||
return 0;
|
||||
}
|
||||
|
||||
rc = msm_comm_scale_clocks_and_bus(inst);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: scale clocks failed\n", __func__);
|
||||
|
||||
mutex_lock(&inst->registeredbufs.lock);
|
||||
list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
|
||||
/* Queue only deferred buffers */
|
||||
if (!(mbuf->flags & MSM_VIDC_FLAG_DEFERRED))
|
||||
continue;
|
||||
print_vidc_buffer(VIDC_DBG, "qbufs", inst, mbuf);
|
||||
rc = msm_comm_qbuf_to_hfi(inst, mbuf);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: Failed qbuf to hfi: %d\n",
|
||||
__func__, rc);
|
||||
do {
|
||||
mutex_lock(&inst->registeredbufs.lock);
|
||||
found = false;
|
||||
list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
|
||||
/* Queue only deferred buffers */
|
||||
if (mbuf->flags & MSM_VIDC_FLAG_DEFERRED) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->registeredbufs.lock);
|
||||
if (!found) {
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: no more deferred qbufs\n", __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->registeredbufs.lock);
|
||||
|
||||
/* do not call msm_comm_qbuf() under registerbufs lock */
|
||||
if (!kref_get_mbuf(inst, mbuf)) {
|
||||
dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
rc = msm_comm_qbuf(inst, mbuf);
|
||||
kref_put_mbuf(mbuf);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: failed qbuf\n", __func__);
|
||||
break;
|
||||
}
|
||||
} while (found);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ bool msm_vidc_fw_coverage = !true;
|
|||
bool msm_vidc_thermal_mitigation_disabled = !true;
|
||||
int msm_vidc_clock_voting = !1;
|
||||
bool msm_vidc_syscache_disable = !true;
|
||||
bool msm_vidc_cvp_usage = !true;
|
||||
|
||||
#define MAX_DBG_BUF_SIZE 4096
|
||||
|
||||
|
|
@ -188,6 +189,7 @@ struct dentry *msm_vidc_debugfs_init_drv(void)
|
|||
&msm_vidc_clock_voting) &&
|
||||
__debugfs_create(bool, "disable_video_syscache",
|
||||
&msm_vidc_syscache_disable) &&
|
||||
__debugfs_create(bool, "cvp_usage", &msm_vidc_cvp_usage) &&
|
||||
__debugfs_create(bool, "lossless_encoding",
|
||||
&msm_vidc_lossless_encode);
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ extern bool msm_vidc_thermal_mitigation_disabled;
|
|||
extern int msm_vidc_clock_voting;
|
||||
extern bool msm_vidc_syscache_disable;
|
||||
extern bool msm_vidc_lossless_encode;
|
||||
extern bool msm_vidc_cvp_usage;
|
||||
|
||||
#define dprintk(__level, __fmt, ...) \
|
||||
do { \
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ static struct msm_vidc_common_data lito_common_data_v0[] = {
|
|||
.value = 0,
|
||||
},
|
||||
{
|
||||
.key = "qcom,domain-cvp",
|
||||
.key = "qcom,cvp-internal",
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
|
|
@ -370,7 +370,7 @@ static struct msm_vidc_common_data lito_common_data_v1[] = {
|
|||
.value = 0,
|
||||
},
|
||||
{
|
||||
.key = "qcom,domain-cvp",
|
||||
.key = "qcom,cvp-internal",
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
|
|
@ -445,8 +445,8 @@ static struct msm_vidc_common_data kona_common_data[] = {
|
|||
.value = 0,
|
||||
},
|
||||
{
|
||||
.key = "qcom,domain-cvp",
|
||||
.value = 0,
|
||||
.key = "qcom,cvp-external",
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.key = "qcom,decode-batching",
|
||||
|
|
@ -587,7 +587,7 @@ static struct msm_vidc_common_data sm8150_common_data[] = {
|
|||
.value = 0,
|
||||
},
|
||||
{
|
||||
.key = "qcom,domain-cvp",
|
||||
.key = "qcom,cvp-internal",
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -806,8 +806,10 @@ int read_platform_resources_from_drv_data(
|
|||
"qcom,fw-unload-delay");
|
||||
res->msm_vidc_hw_rsp_timeout = find_key_value(platform_data,
|
||||
"qcom,hw-resp-timeout");
|
||||
res->domain_cvp = find_key_value(platform_data,
|
||||
"qcom,domain-cvp");
|
||||
res->cvp_internal = find_key_value(platform_data,
|
||||
"qcom,cvp-internal");
|
||||
res->cvp_external = find_key_value(platform_data,
|
||||
"qcom,cvp-external");
|
||||
res->non_fatal_pagefaults = find_key_value(platform_data,
|
||||
"qcom,domain-attr-non-fatal-faults");
|
||||
res->cache_pagetables = find_key_value(platform_data,
|
||||
|
|
|
|||
|
|
@ -188,7 +188,8 @@ struct msm_vidc_platform_resources {
|
|||
int msm_vidc_hw_rsp_timeout;
|
||||
int msm_vidc_firmware_unload_delay;
|
||||
uint32_t msm_vidc_pwr_collapse_delay;
|
||||
bool domain_cvp;
|
||||
bool cvp_internal;
|
||||
bool cvp_external;
|
||||
bool non_fatal_pagefaults;
|
||||
bool cache_pagetables;
|
||||
bool decode_batching;
|
||||
|
|
|
|||
Loading…
Reference in a new issue