diff --git a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c index 8df0eb2b532a89..6078d6e2ace019 100644 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c @@ -679,6 +679,9 @@ struct bcm2835_codec_ctx { enum v4l2_xfer_func xfer_func; enum v4l2_quantization quant; + int hflip; + int vflip; + /* Source and destination queue data */ struct bcm2835_codec_q_data q_data[2]; s32 bitrate; @@ -926,13 +929,15 @@ static void ip_buffer_cb(struct vchiq_mmal_instance *instance, v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: no error. Return buffer %p\n", __func__, &buf->m2m.vb.vb2_buf); - vb2_buffer_done(&buf->m2m.vb.vb2_buf, VB2_BUF_STATE_DONE); + vb2_buffer_done(&buf->m2m.vb.vb2_buf, + port->enabled ? VB2_BUF_STATE_DONE : + VB2_BUF_STATE_QUEUED); ctx->num_ip_buffers++; v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d input buffers\n", __func__, ctx->num_ip_buffers); - if (!port->enabled) + if (!port->enabled && atomic_read(&port->buffers_with_vpu)) complete(&ctx->frame_cmplt); } @@ -1005,6 +1010,7 @@ static void handle_fmt_changed(struct bcm2835_codec_ctx *ctx, (struct mmal_msg_event_format_changed *)mmal_buf->buffer; struct mmal_parameter_video_interlace_type interlace; int interlace_size = sizeof(interlace); + struct vb2_queue *vq; int ret; v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed: buff size min %u, rec %u, buff num min %u, rec %u\n", @@ -1074,6 +1080,10 @@ static void handle_fmt_changed(struct bcm2835_codec_ctx *ctx, q_data->field = V4L2_FIELD_NONE; } + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (vq->streaming) + vq->last_buffer_dequeued = true; + queue_res_chg_event(ctx); } @@ -1128,7 +1138,8 @@ static void op_buffer_cb(struct vchiq_mmal_instance *instance, __func__, mmal_buf->mmal_flags); if (!(mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS)) { vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_QUEUED); - if (!port->enabled) + if (!port->enabled && + atomic_read(&port->buffers_with_vpu)) complete(&ctx->frame_cmplt); return; } @@ -1171,7 +1182,7 @@ static void op_buffer_cb(struct vchiq_mmal_instance *instance, v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d output buffers\n", __func__, ctx->num_op_buffers); - if (!port->enabled) + if (!port->enabled && atomic_read(&port->buffers_with_vpu)) complete(&ctx->frame_cmplt); } @@ -1244,35 +1255,47 @@ static void device_run(void *priv) v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: off we go\n", __func__); - src_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->out_q_ctx); - if (src_buf) { - m2m = container_of(src_buf, struct v4l2_m2m_buffer, vb); - src_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); - vb2_to_mmal_buffer(src_m2m_buf, src_buf); - - ret = vchiq_mmal_submit_buffer(dev->instance, - &ctx->component->input[0], - &src_m2m_buf->mmal); - v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted ip buffer len %lu, pts %llu, flags %04x\n", - __func__, src_m2m_buf->mmal.length, - src_m2m_buf->mmal.pts, src_m2m_buf->mmal.mmal_flags); - if (ret) - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting ip buffer\n", - __func__); + if (ctx->fh.m2m_ctx->out_q_ctx.q.streaming) { + src_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->out_q_ctx); + if (src_buf) { + m2m = container_of(src_buf, struct v4l2_m2m_buffer, vb); + src_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, + m2m); + vb2_to_mmal_buffer(src_m2m_buf, src_buf); + + ret = vchiq_mmal_submit_buffer(dev->instance, + &ctx->component->input[0], + &src_m2m_buf->mmal); + v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, + "%s: Submitted ip buffer len %lu, pts %llu, flags %04x\n", + __func__, src_m2m_buf->mmal.length, + src_m2m_buf->mmal.pts, + src_m2m_buf->mmal.mmal_flags); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, + "%s: Failed submitting ip buffer\n", + __func__); + } } - dst_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->cap_q_ctx); - if (dst_buf) { - m2m = container_of(dst_buf, struct v4l2_m2m_buffer, vb); - dst_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); - vb2_to_mmal_buffer(dst_m2m_buf, dst_buf); + if (ctx->fh.m2m_ctx->cap_q_ctx.q.streaming) { + dst_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->cap_q_ctx); + if (dst_buf) { + m2m = container_of(dst_buf, struct v4l2_m2m_buffer, vb); + dst_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, + m2m); + vb2_to_mmal_buffer(dst_m2m_buf, dst_buf); - ret = vchiq_mmal_submit_buffer(dev->instance, - &ctx->component->output[0], - &dst_m2m_buf->mmal); - if (ret) - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting op buffer\n", - __func__); + v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, + "%s: Submitted op buffer\n", __func__); + ret = vchiq_mmal_submit_buffer(dev->instance, + &ctx->component->output[0], + &dst_m2m_buf->mmal); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, + "%s: Failed submitting op buffer\n", + __func__); + } } v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted src %p, dst %p\n", @@ -1498,6 +1521,7 @@ static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, struct vb2_queue *vq; struct vchiq_mmal_port *port; bool update_capture_port = false; + bool reenable_port = false; int ret; v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Setting format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", @@ -1575,6 +1599,34 @@ static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, if (!port) return 0; + if (port->enabled) { + unsigned int num_buffers; + + /* + * This should only ever happen with DECODE and the MMAL output + * port that has been enabled for resolution changed events. + * In this case no buffers have been allocated or sent to the + * component, so warn on that. + */ + WARN_ON(ctx->dev->role != DECODE || + f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || + atomic_read(&port->buffers_with_vpu)); + + /* + * Disable will reread the port format, so retain buffer count. + */ + num_buffers = port->current_buffer.num; + + ret = vchiq_mmal_port_disable(ctx->dev->instance, port); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Error disabling port update buffer count, ret %d\n", + __func__, ret); + + port->current_buffer.num = num_buffers; + + reenable_port = true; + } + setup_mmal_port_format(ctx, q_data, port); ret = vchiq_mmal_port_set_format(ctx->dev->instance, port); if (ret) { @@ -1589,6 +1641,14 @@ static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, port->minimum_buffer.size); } + if (reenable_port) { + ret = vchiq_mmal_port_enable(ctx->dev->instance, + port, + op_buffer_cb); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", + __func__, ret); + } v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Set format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", f->type, q_data->crop_width, q_data->height, q_data->fmt->fourcc, q_data->sizeimage); @@ -2145,6 +2205,34 @@ static int bcm2835_codec_s_ctrl(struct v4l2_ctrl *ctrl) sizeof(mmal_bool)); break; } + case V4L2_CID_HFLIP: + case V4L2_CID_VFLIP: { + u32 u32_value; + + if (ctrl->id == V4L2_CID_HFLIP) + ctx->hflip = ctrl->val; + else + ctx->vflip = ctrl->val; + + if (!ctx->component) + break; + + if (ctx->hflip && ctx->vflip) + u32_value = MMAL_PARAM_MIRROR_BOTH; + else if (ctx->hflip) + u32_value = MMAL_PARAM_MIRROR_HORIZONTAL; + else if (ctx->vflip) + u32_value = MMAL_PARAM_MIRROR_VERTICAL; + else + u32_value = MMAL_PARAM_MIRROR_NONE; + + ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, + &ctx->component->input[0], + MMAL_PARAMETER_MIRROR, + &u32_value, + sizeof(u32_value)); + break; + } default: v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); @@ -2380,33 +2468,6 @@ static const struct v4l2_ioctl_ops bcm2835_codec_ioctl_ops = { .vidioc_enum_framesizes = vidioc_enum_framesizes, }; -static int bcm2835_codec_set_ctrls(struct bcm2835_codec_ctx *ctx) -{ - /* - * Query the control handler for the value of the various controls and - * set them. - */ - const u32 control_ids[] = { - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, - V4L2_CID_MPEG_VIDEO_HEADER_MODE, - V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, - V4L2_CID_MPEG_VIDEO_H264_LEVEL, - V4L2_CID_MPEG_VIDEO_H264_PROFILE, - }; - int i; - - for (i = 0; i < ARRAY_SIZE(control_ids); i++) { - struct v4l2_ctrl *ctrl; - - ctrl = v4l2_ctrl_find(&ctx->hdl, control_ids[i]); - if (ctrl) - bcm2835_codec_s_ctrl(ctrl); - } - - return 0; -} - static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) { struct bcm2835_codec_dev *dev = ctx->dev; @@ -2439,6 +2500,16 @@ static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) MMAL_PARAMETER_VIDEO_VALIDATE_TIMESTAMPS, &enable, sizeof(enable)); + /* + * Enable firmware option to stop on colourspace and pixel + * aspect ratio changed + */ + enable = 1; + vchiq_mmal_port_parameter_set(dev->instance, + &ctx->component->control, + MMAL_PARAMETER_VIDEO_STOP_ON_PAR_COLOUR_CHANGE, + &enable, + sizeof(enable)); } else if (dev->role == DEINTERLACE) { /* Select the default deinterlace algorithm. */ int half_framerate = 0; @@ -2467,9 +2538,11 @@ static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC], &ctx->component->input[0]); + ctx->component->input[0].cb_ctx = ctx; setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_DST], &ctx->component->output[0]); + ctx->component->output[0].cb_ctx = ctx; ret = vchiq_mmal_port_set_format(dev->instance, &ctx->component->input[0]); @@ -2498,9 +2571,6 @@ static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) ctx->q_data[V4L2_M2M_SRC].sizeimage, ctx->component->output[0].minimum_buffer.size); - /* Now we have a component we can set all the ctrls */ - bcm2835_codec_set_ctrls(ctx); - /* Enable SPS Timing header so framerate information is encoded * in the H264 header. */ @@ -2529,6 +2599,10 @@ static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) ctx->q_data[V4L2_M2M_DST].sizeimage, ctx->component->output[0].minimum_buffer.size); } + + /* Now we have a component we can set all the ctrls */ + ret = v4l2_ctrl_handler_setup(&ctx->hdl); + v4l2_dbg(2, debug, &dev->v4l2_dev, "%s: component created as %s\n", __func__, components[dev->role]); @@ -2724,6 +2798,23 @@ static void bcm2835_codec_buffer_cleanup(struct vb2_buffer *vb) bcm2835_codec_mmal_buf_cleanup(&buf->mmal); } +static void bcm2835_codec_flush_buffers(struct bcm2835_codec_ctx *ctx, + struct vchiq_mmal_port *port) +{ + int ret; + + if (atomic_read(&port->buffers_with_vpu)) { + v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", + __func__, atomic_read(&port->buffers_with_vpu)); + ret = wait_for_completion_timeout(&ctx->frame_cmplt, + COMPLETE_TIMEOUT); + if (ret <= 0) { + v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", + __func__, + atomic_read(&port->buffers_with_vpu)); + } + } +} static int bcm2835_codec_start_streaming(struct vb2_queue *q, unsigned int count) { @@ -2731,7 +2822,7 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, struct bcm2835_codec_dev *dev = ctx->dev; struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); struct vchiq_mmal_port *port = get_port_data(ctx, q->type); - int ret; + int ret = 0; v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n", __func__, q->type, count); @@ -2746,6 +2837,34 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, ctx->component_enabled = true; } + if (port->enabled) { + unsigned int num_buffers; + + init_completion(&ctx->frame_cmplt); + + /* + * This should only ever happen with DECODE and the MMAL output + * port that has been enabled for resolution changed events. + * In this case no buffers have been allocated or sent to the + * component, so warn on that. + */ + WARN_ON(ctx->dev->role != DECODE); + WARN_ON(q->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + WARN_ON(atomic_read(&port->buffers_with_vpu)); + + /* + * Disable will reread the port format, so retain buffer count. + */ + num_buffers = port->current_buffer.num; + + ret = vchiq_mmal_port_disable(dev->instance, port); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Error disabling port update buffer count, ret %d\n", + __func__, ret); + bcm2835_codec_flush_buffers(ctx, port); + port->current_buffer.num = num_buffers; + } + if (count < port->minimum_buffer.num) count = port->minimum_buffer.num; @@ -2760,6 +2879,22 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, __func__, ret); } + if (dev->role == DECODE && + q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && + !ctx->component->output[0].enabled) { + /* + * Decode needs to enable the MMAL output/V4L2 CAPTURE + * port at this point too so that we have everything + * set up for dynamic resolution changes. + */ + ret = vchiq_mmal_port_enable(dev->instance, + &ctx->component->output[0], + op_buffer_cb); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", + __func__, ret); + } + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* * Create the EOS buffer. @@ -2771,7 +2906,6 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, &q_data->eos_buffer.mmal); q_data->eos_buffer_in_use = false; - port->cb_ctx = ctx; ret = vchiq_mmal_port_enable(dev->instance, port, ip_buffer_cb); @@ -2779,14 +2913,17 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n", __func__, ret); } else { - port->cb_ctx = ctx; - ret = vchiq_mmal_port_enable(dev->instance, - port, - op_buffer_cb); - if (ret) - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", - __func__, ret); + if (!port->enabled) { + ret = vchiq_mmal_port_enable(dev->instance, + port, + op_buffer_cb); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", + __func__, ret); + } } + v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Done, ret %d\n", + __func__, ret); return ret; } @@ -2825,17 +2962,21 @@ static void bcm2835_codec_stop_streaming(struct vb2_queue *q) __func__, V4L2_TYPE_IS_OUTPUT(q->type) ? "i/p" : "o/p", ret); - while (atomic_read(&port->buffers_with_vpu)) { - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", - __func__, atomic_read(&port->buffers_with_vpu)); - ret = wait_for_completion_timeout(&ctx->frame_cmplt, - COMPLETE_TIMEOUT); - if (ret <= 0) { - v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", - __func__, - atomic_read(&port->buffers_with_vpu)); - break; - } + bcm2835_codec_flush_buffers(ctx, port); + + if (dev->role == DECODE && + q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && + ctx->component->input[0].enabled) { + /* + * For decode we need to keep the MMAL output port enabled for + * resolution changed events whenever the input is enabled. + */ + ret = vchiq_mmal_port_enable(dev->instance, + &ctx->component->output[0], + op_buffer_cb); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", + __func__, ret); } /* If both ports disabled, then disable the component */ @@ -2963,7 +3104,9 @@ static int bcm2835_codec_open(struct file *file) file->private_data = &ctx->fh; ctx->dev = dev; hdl = &ctx->hdl; - if (dev->role == ENCODE) { + switch (dev->role) { + case ENCODE: + { /* Encode controls */ v4l2_ctrl_handler_init(hdl, 9); @@ -3022,7 +3165,10 @@ static int bcm2835_codec_open(struct file *file) } ctx->fh.ctrl_handler = hdl; v4l2_ctrl_handler_setup(hdl); - } else if (dev->role == DECODE) { + } + break; + case DECODE: + { v4l2_ctrl_handler_init(hdl, 1); v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, @@ -3035,6 +3181,31 @@ static int bcm2835_codec_open(struct file *file) ctx->fh.ctrl_handler = hdl; v4l2_ctrl_handler_setup(hdl); } + break; + case ISP: + { + v4l2_ctrl_handler_init(hdl, 2); + + v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_HFLIP, + 1, 0, 1, 0); + v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, + V4L2_CID_VFLIP, + 1, 0, 1, 0); + if (hdl->error) { + rc = hdl->error; + goto free_ctrl_handler; + } + ctx->fh.ctrl_handler = hdl; + v4l2_ctrl_handler_setup(hdl); + } + break; + case DEINTERLACE: + { + v4l2_ctrl_handler_init(hdl, 0); + } + break; + } ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h index 622508dc6e2758..21087496a48175 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h @@ -682,6 +682,9 @@ enum mmal_parameter_video_type { /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T */ MMAL_PARAMETER_VIDEO_VALIDATE_TIMESTAMPS, + + /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ + MMAL_PARAMETER_VIDEO_STOP_ON_PAR_COLOUR_CHANGE, }; /** Valid mirror modes */ diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 014fbace54cdbf..a6cdc7dc9c300e 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -15,16 +15,15 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include +#include #include #include -#include -#include -#include -#include #include -#include +#include +#include #include "mmal-common.h" #include "mmal-parameters.h" @@ -32,6 +31,17 @@ #include "mmal-msg.h" #include "vc-sm-cma/vc_sm_knl.h" + +#define pr_dbg_lvl(__level, __debug, __fmt, __arg...) \ + do { \ + if (__debug >= (__level)) \ + printk(KERN_DEBUG __fmt, ##__arg); \ + } while (0) + +static unsigned int debug; +module_param(debug, uint, 0644); +MODULE_PARM_DESC(debug, "activates debug info (0-3)"); + /* * maximum number of components supported. * This matches the maximum permitted by default on the VPU @@ -382,7 +392,8 @@ buffer_from_host(struct vchiq_mmal_instance *instance, if (!port->enabled) return -EINVAL; - pr_debug("instance:%u buffer:%p\n", instance->service_handle, buf); + pr_dbg_lvl(3, debug, "instance:%u buffer:%p\n", + instance->service_handle, buf); /* get context */ if (!buf->msg_context) { @@ -550,11 +561,11 @@ static void event_to_host_cb(struct vchiq_mmal_instance *instance, msg_context->u.bulk.pts = MMAL_TIME_UNKNOWN; msg_context->u.bulk.cmd = msg->u.event_to_host.cmd; - pr_debug("event component:%u port type:%d num:%d cmd:0x%x length:%d\n", - msg->u.event_to_host.client_component, - msg->u.event_to_host.port_type, - msg->u.event_to_host.port_num, - msg->u.event_to_host.cmd, msg->u.event_to_host.length); + pr_dbg_lvl(3, debug, "event component:%u port type:%d num:%d cmd:0x%x length:%d\n", + msg->u.event_to_host.client_component, + msg->u.event_to_host.port_type, + msg->u.event_to_host.port_num, + msg->u.event_to_host.cmd, msg->u.event_to_host.length); } schedule_work(&msg_context->u.bulk.work); @@ -567,8 +578,8 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, struct mmal_msg_context *msg_context; u32 handle; - pr_debug("%s: instance:%p msg:%p msg_len:%d\n", - __func__, instance, msg, msg_len); + pr_dbg_lvl(3, debug, "%s: instance:%p msg:%p msg_len:%d\n", + __func__, instance, msg, msg_len); if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { handle = msg->u.buffer_from_host.drvbuf.client_context; @@ -838,42 +849,43 @@ static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance, static void dump_port_info(struct vchiq_mmal_port *port) { - pr_debug("port handle:0x%x enabled:%d\n", port->handle, port->enabled); + pr_dbg_lvl(3, debug, "port handle:0x%x enabled:%d\n", port->handle, + port->enabled); - pr_debug("buffer minimum num:%d size:%d align:%d\n", - port->minimum_buffer.num, - port->minimum_buffer.size, port->minimum_buffer.alignment); + pr_dbg_lvl(3, debug, "buffer minimum num:%d size:%d align:%d\n", + port->minimum_buffer.num, + port->minimum_buffer.size, port->minimum_buffer.alignment); - pr_debug("buffer recommended num:%d size:%d align:%d\n", - port->recommended_buffer.num, - port->recommended_buffer.size, - port->recommended_buffer.alignment); + pr_dbg_lvl(3, debug, "buffer recommended num:%d size:%d align:%d\n", + port->recommended_buffer.num, + port->recommended_buffer.size, + port->recommended_buffer.alignment); - pr_debug("buffer current values num:%d size:%d align:%d\n", - port->current_buffer.num, - port->current_buffer.size, port->current_buffer.alignment); + pr_dbg_lvl(3, debug, "buffer current values num:%d size:%d align:%d\n", + port->current_buffer.num, + port->current_buffer.size, port->current_buffer.alignment); - pr_debug("elementary stream: type:%d encoding:0x%x variant:0x%x\n", - port->format.type, - port->format.encoding, port->format.encoding_variant); + pr_dbg_lvl(3, debug, "elementary stream: type:%d encoding:0x%x variant:0x%x\n", + port->format.type, + port->format.encoding, port->format.encoding_variant); - pr_debug(" bitrate:%d flags:0x%x\n", - port->format.bitrate, port->format.flags); + pr_dbg_lvl(3, debug, " bitrate:%d flags:0x%x\n", + port->format.bitrate, port->format.flags); if (port->format.type == MMAL_ES_TYPE_VIDEO) { - pr_debug - ("es video format: width:%d height:%d colourspace:0x%x\n", - port->es.video.width, port->es.video.height, - port->es.video.color_space); - - pr_debug(" : crop xywh %d,%d,%d,%d\n", - port->es.video.crop.x, - port->es.video.crop.y, - port->es.video.crop.width, port->es.video.crop.height); - pr_debug(" : framerate %d/%d aspect %d/%d\n", - port->es.video.frame_rate.num, - port->es.video.frame_rate.den, - port->es.video.par.num, port->es.video.par.den); + pr_dbg_lvl(3, debug, + "es video format: width:%d height:%d colourspace:0x%x\n", + port->es.video.width, port->es.video.height, + port->es.video.color_space); + + pr_dbg_lvl(3, debug, " : crop xywh %d,%d,%d,%d\n", + port->es.video.crop.x, + port->es.video.crop.y, + port->es.video.crop.width, port->es.video.crop.height); + pr_dbg_lvl(3, debug, " : framerate %d/%d aspect %d/%d\n", + port->es.video.frame_rate.num, + port->es.video.frame_rate.den, + port->es.video.par.num, port->es.video.par.den); } } @@ -904,7 +916,7 @@ static int port_info_set(struct vchiq_mmal_instance *instance, struct mmal_msg *rmsg; struct vchiq_header *rmsg_handle; - pr_debug("setting port info port %p\n", port); + pr_dbg_lvl(1, debug, "setting port info port %p\n", port); if (!port) return -1; dump_port_info(port); @@ -947,8 +959,8 @@ static int port_info_set(struct vchiq_mmal_instance *instance, /* return operation status */ ret = -rmsg->u.port_info_get_reply.status; - pr_debug("%s:result:%d component:0x%x port:%d\n", __func__, ret, - port->component->handle, port->handle); + pr_dbg_lvl(1, debug, "%s:result:%d component:0x%x port:%d\n", __func__, + ret, port->component->handle, port->handle); release_msg: vchiq_release_message(instance->service_handle, rmsg_handle); @@ -1038,13 +1050,13 @@ static int port_info_get(struct vchiq_mmal_instance *instance, rmsg->u.port_info_get_reply.extradata, port->format.extradata_size); - pr_debug("received port info\n"); + pr_dbg_lvl(1, debug, "received port info\n"); dump_port_info(port); release_msg: - pr_debug("%s:result:%d component:0x%x port:%d\n", - __func__, ret, port->component->handle, port->handle); + pr_dbg_lvl(1, debug, "%s:result:%d component:0x%x port:%d\n", + __func__, ret, port->component->handle, port->handle); vchiq_release_message(instance->service_handle, rmsg_handle); @@ -1089,9 +1101,9 @@ static int create_component(struct vchiq_mmal_instance *instance, component->outputs = rmsg->u.component_create_reply.output_num; component->clocks = rmsg->u.component_create_reply.clock_num; - pr_debug("Component handle:0x%x in:%d out:%d clock:%d\n", - component->handle, - component->inputs, component->outputs, component->clocks); + pr_dbg_lvl(2, debug, "Component handle:0x%x in:%d out:%d clock:%d\n", + component->handle, + component->inputs, component->outputs, component->clocks); release_msg: vchiq_release_message(instance->service_handle, rmsg_handle); @@ -1260,10 +1272,9 @@ static int port_action_port(struct vchiq_mmal_instance *instance, ret = -rmsg->u.port_action_reply.status; - pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)\n", - __func__, - ret, port->component->handle, port->handle, - port_action_type_names[action_type], action_type); + pr_dbg_lvl(2, debug, "%s:result:%d component:0x%x port:%d action:%s(%d)\n", + __func__, ret, port->component->handle, port->handle, + port_action_type_names[action_type], action_type); release_msg: vchiq_release_message(instance->service_handle, rmsg_handle); @@ -1307,11 +1318,11 @@ static int port_action_handle(struct vchiq_mmal_instance *instance, ret = -rmsg->u.port_action_reply.status; - pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n", - __func__, - ret, port->component->handle, port->handle, - port_action_type_names[action_type], - action_type, connect_component_handle, connect_port_handle); + pr_dbg_lvl(2, debug, + "%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n", + __func__, ret, port->component->handle, port->handle, + port_action_type_names[action_type], + action_type, connect_component_handle, connect_port_handle); release_msg: vchiq_release_message(instance->service_handle, rmsg_handle); @@ -1350,9 +1361,9 @@ static int port_parameter_set(struct vchiq_mmal_instance *instance, ret = -rmsg->u.port_parameter_set_reply.status; - pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", - __func__, - ret, port->component->handle, port->handle, parameter_id); + pr_dbg_lvl(1, debug, "%s:result:%d component:0x%x port:%d parameter:%d\n", + __func__, ret, port->component->handle, port->handle, + parameter_id); release_msg: vchiq_release_message(instance->service_handle, rmsg_handle); @@ -1410,8 +1421,9 @@ static int port_parameter_get(struct vchiq_mmal_instance *instance, /* Always report the size of the returned parameter to the caller */ *value_size = rmsg->u.port_parameter_get_reply.size; - pr_debug("%s:result:%d component:0x%x port:%d parameter:%d\n", __func__, - ret, port->component->handle, port->handle, parameter_id); + pr_dbg_lvl(1, debug, "%s:result:%d component:0x%x port:%d parameter:%d\n", + __func__, ret, port->component->handle, port->handle, + parameter_id); release_msg: vchiq_release_message(instance->service_handle, rmsg_handle); @@ -1488,6 +1500,8 @@ static int port_enable(struct vchiq_mmal_instance *instance, port->enabled = 1; + atomic_set(&port->buffers_with_vpu, 0); + if (port->buffer_cb) { /* send buffer headers to videocore */ hdr_count = 1; @@ -1668,7 +1682,7 @@ int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, if (!dst) { /* do not make new connection */ ret = 0; - pr_debug("not making new connection\n"); + pr_dbg_lvl(3, debug, "not making new connection\n"); goto release_unlock; } @@ -1686,14 +1700,14 @@ int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, /* set new format */ ret = port_info_set(instance, dst); if (ret) { - pr_debug("setting port info failed\n"); + pr_dbg_lvl(1, debug, "setting port info failed\n"); goto release_unlock; } /* read what has actually been set */ ret = port_info_get(instance, dst); if (ret) { - pr_debug("read back port info failed\n"); + pr_dbg_lvl(1, debug, "read back port info failed\n"); goto release_unlock; } @@ -1702,9 +1716,9 @@ int vchiq_mmal_port_connect_tunnel(struct vchiq_mmal_instance *instance, MMAL_MSG_PORT_ACTION_TYPE_CONNECT, dst->component->handle, dst->handle); if (ret < 0) { - pr_debug("connecting port %d:%d to %d:%d failed\n", - src->component->handle, src->handle, - dst->component->handle, dst->handle); + pr_dbg_lvl(2, debug, "connecting port %d:%d to %d:%d failed\n", + src->component->handle, src->handle, + dst->component->handle, dst->handle); goto release_unlock; } src->connected = dst; @@ -1729,7 +1743,8 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, * videobuf2 won't let us have the dmabuf there. */ if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) { - pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf); + pr_dbg_lvl(2, debug, "%s: import dmabuf %p\n", + __func__, buffer->dma_buf); ret = vc_sm_cma_import_dmabuf(buffer->dma_buf, &buffer->vcsm_handle); if (ret) { @@ -1745,8 +1760,8 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, vc_sm_cma_free(buffer->vcsm_handle); return ret; } - pr_debug("%s: import dmabuf %p - got vc handle %08X\n", - __func__, buffer->dma_buf, buffer->vc_handle); + pr_dbg_lvl(2, debug, "%s: import dmabuf %p - got vc handle %08X\n", + __func__, buffer->dma_buf, buffer->vc_handle); } ret = buffer_from_host(instance, port, buffer); @@ -1785,8 +1800,8 @@ int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf) if (buf->vcsm_handle) { int ret; - pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__, - buf->vcsm_handle); + pr_dbg_lvl(2, debug, "%s: vc_sm_cma_free on handle %p\n", __func__, + buf->vcsm_handle); ret = vc_sm_cma_free(buf->vcsm_handle); if (ret) pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);