Skip to content

drivers: media: bcm2835_isp: Cache LS table dmabuf #6429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 46 additions & 31 deletions drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ struct bcm2835_isp_dev {
/* Image pipeline controls. */
int r_gain;
int b_gain;
struct dma_buf *last_ls_dmabuf;
struct mmal_parameter_lens_shading_v2 ls;
};

struct bcm2835_isp_buffer {
Expand Down Expand Up @@ -657,18 +659,18 @@ static void bcm2835_isp_node_stop_streaming(struct vb2_queue *q)
atomic_dec(&dev->num_streaming);
/* If all ports disabled, then disable the component */
if (atomic_read(&dev->num_streaming) == 0) {
struct bcm2835_isp_lens_shading ls;
/*
* The ISP component on the firmware has a reference to the
* dmabuf handle for the lens shading table. Pass a null handle
* to remove that reference now.
*/
memset(&ls, 0, sizeof(ls));
memset(&dev->ls, 0, sizeof(dev->ls));
/* Must set a valid grid size for the FW */
ls.grid_cell_size = 16;
dev->ls.grid_cell_size = 16;
set_isp_param(&dev->node[0],
MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
&ls, sizeof(ls));
&dev->ls, sizeof(dev->ls));
dev->last_ls_dmabuf = NULL;

ret = vchiq_mmal_component_disable(dev->mmal_instance,
dev->component);
Expand Down Expand Up @@ -719,6 +721,36 @@ static inline unsigned int get_sizeimage(int bpl, int width, int height,
return (bpl * height * fmt->size_multiplier_x2) >> 1;
}

static int map_ls_table(struct bcm2835_isp_dev *dev, struct dma_buf *dmabuf,
const struct bcm2835_isp_lens_shading *v4l2_ls)
{
void *vcsm_handle;
int ret;

if (IS_ERR_OR_NULL(dmabuf))
return -EINVAL;

/*
* struct bcm2835_isp_lens_shading and struct
* mmal_parameter_lens_shading_v2 match so that we can do a
* simple memcpy here.
* Only the dmabuf to the actual table needs any manipulation.
*/
memcpy(&dev->ls, v4l2_ls, sizeof(dev->ls));
ret = vc_sm_cma_import_dmabuf(dmabuf, &vcsm_handle);
if (ret) {
dma_buf_put(dmabuf);
return ret;
}

dev->ls.mem_handle_table = vc_sm_cma_int_handle(vcsm_handle);
dev->last_ls_dmabuf = dmabuf;

vc_sm_cma_free(vcsm_handle);

return 0;
}

static int bcm2835_isp_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct bcm2835_isp_dev *dev =
Expand Down Expand Up @@ -754,44 +786,27 @@ static int bcm2835_isp_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_USER_BCM2835_ISP_LENS_SHADING:
{
struct bcm2835_isp_lens_shading *v4l2_ls;
struct mmal_parameter_lens_shading_v2 ls;
struct dma_buf *dmabuf;
void *vcsm_handle;

v4l2_ls = (struct bcm2835_isp_lens_shading *)ctrl->p_new.p_u8;
/*
* struct bcm2835_isp_lens_shading and struct
* mmal_parameter_lens_shading_v2 match so that we can do a
* simple memcpy here.
* Only the dmabuf to the actual table needs any manipulation.
*/
memcpy(&ls, v4l2_ls, sizeof(ls));
struct dma_buf *dmabuf = dma_buf_get(v4l2_ls->dmabuf);

dmabuf = dma_buf_get(v4l2_ls->dmabuf);
if (IS_ERR_OR_NULL(dmabuf))
return -EINVAL;

ret = vc_sm_cma_import_dmabuf(dmabuf, &vcsm_handle);
if (ret) {
dma_buf_put(dmabuf);
return -EINVAL;
}
if (dmabuf != dev->last_ls_dmabuf)
ret = map_ls_table(dev, dmabuf, v4l2_ls);

ls.mem_handle_table = vc_sm_cma_int_handle(vcsm_handle);
if (ls.mem_handle_table)
/* The VPU will take a reference on the vcsm handle,
if (!ret && dev->ls.mem_handle_table)
/*
* The VPU will take a reference on the vcsm handle,
* which in turn will retain a reference on the dmabuf.
* This code can therefore safely release all
* references to the buffer.
*/
ret = set_isp_param(node,
MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
&ls,
sizeof(ls));
ret =
set_isp_param(node,
MMAL_PARAMETER_LENS_SHADING_OVERRIDE,
&dev->ls, sizeof(dev->ls));
else
ret = -EINVAL;

vc_sm_cma_free(vcsm_handle);
dma_buf_put(dmabuf);
break;
}
Expand Down