diff options
Diffstat (limited to 'drivers/staging/media/rkisp1')
-rw-r--r-- | drivers/staging/media/rkisp1/TODO | 1 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-capture.c | 56 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-common.h | 26 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-dev.c | 11 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-isp.c | 75 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-params.c | 2 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-regs.h | 1 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-resizer.c | 18 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/rkisp1-stats.c | 126 | ||||
-rw-r--r-- | drivers/staging/media/rkisp1/uapi/rkisp1-config.h | 4 |
10 files changed, 110 insertions, 210 deletions
diff --git a/drivers/staging/media/rkisp1/TODO b/drivers/staging/media/rkisp1/TODO index c0cbec0a164d..bdb1b8f73556 100644 --- a/drivers/staging/media/rkisp1/TODO +++ b/drivers/staging/media/rkisp1/TODO @@ -1,5 +1,4 @@ * Fix pad format size for statistics and parameters entities. -* Use threaded interrupt for rkisp1_stats_isr(), remove work queue. * Fix checkpatch errors. * Review and comment every lock * Handle quantization diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c index f69235f82c45..c05280950ea0 100644 --- a/drivers/staging/media/rkisp1/rkisp1-capture.c +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c @@ -283,10 +283,6 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = { .fourcc = V4L2_PIX_FMT_RGB565, .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565, - }, { - .fourcc = V4L2_PIX_FMT_BGR666, - .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA, - .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB666, }, }; @@ -579,12 +575,16 @@ static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap) static void rkisp1_set_next_buf(struct rkisp1_capture *cap) { - /* - * Use the dummy space allocated by dma_alloc_coherent to - * throw data if there is no available buffer. - */ - if (cap->buf.next) { - u32 *buff_addr = cap->buf.next->buff_addr; + cap->buf.curr = cap->buf.next; + cap->buf.next = NULL; + + if (!list_empty(&cap->buf.queue)) { + u32 *buff_addr; + + cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue); + list_del(&cap->buf.next->queue); + + buff_addr = cap->buf.next->buff_addr; rkisp1_write(cap->rkisp1, buff_addr[RKISP1_PLANE_Y], @@ -596,6 +596,10 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap) buff_addr[RKISP1_PLANE_CR], cap->config->mi.cr_base_ad_init); } else { + /* + * Use the dummy space allocated by dma_alloc_coherent to + * throw data if there is no available buffer. + */ rkisp1_write(cap->rkisp1, cap->buf.dummy.dma_addr, cap->config->mi.y_base_ad_init); @@ -621,10 +625,11 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap) static void rkisp1_handle_buffer(struct rkisp1_capture *cap) { struct rkisp1_isp *isp = &cap->rkisp1->isp; - struct rkisp1_buffer *curr_buf = cap->buf.curr; + struct rkisp1_buffer *curr_buf; unsigned long flags; spin_lock_irqsave(&cap->buf.lock, flags); + curr_buf = cap->buf.curr; if (curr_buf) { curr_buf->vb.sequence = atomic_read(&isp->frame_sequence); @@ -635,18 +640,8 @@ static void rkisp1_handle_buffer(struct rkisp1_capture *cap) cap->rkisp1->debug.frame_drop[cap->id]++; } - cap->buf.curr = cap->buf.next; - cap->buf.next = NULL; - - if (!list_empty(&cap->buf.queue)) { - cap->buf.next = list_first_entry(&cap->buf.queue, - struct rkisp1_buffer, - queue); - list_del(&cap->buf.next->queue); - } - spin_unlock_irqrestore(&cap->buf.lock, flags); - rkisp1_set_next_buf(cap); + spin_unlock_irqrestore(&cap->buf.lock, flags); } void rkisp1_capture_isr(struct rkisp1_device *rkisp1) @@ -747,18 +742,7 @@ static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb) ispbuf->buff_addr[RKISP1_PLANE_CB]); spin_lock_irqsave(&cap->buf.lock, flags); - - /* - * If there's no next buffer assigned, queue this buffer directly - * as the next buffer, and update the memory interface. - */ - if (cap->is_streaming && !cap->buf.next && - atomic_read(&cap->rkisp1->isp.frame_sequence) == -1) { - cap->buf.next = ispbuf; - rkisp1_set_next_buf(cap); - } else { - list_add_tail(&ispbuf->queue, &cap->buf.queue); - } + list_add_tail(&ispbuf->queue, &cap->buf.queue); spin_unlock_irqrestore(&cap->buf.lock, flags); } @@ -932,7 +916,7 @@ static void rkisp1_stream_start(struct rkisp1_capture *cap) cap->ops->config(cap); /* Setup a buffer for the next frame */ - rkisp1_handle_buffer(cap); + rkisp1_set_next_buf(cap); cap->ops->enable(cap); /* It's safe to config ACTIVE and SHADOW regs for the * first stream. While when the second is starting, do NOT @@ -947,7 +931,7 @@ static void rkisp1_stream_start(struct rkisp1_capture *cap) /* force cfg update */ rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT_SOFT_UPD, RKISP1_CIF_MI_INIT); - rkisp1_handle_buffer(cap); + rkisp1_set_next_buf(cap); } cap->is_streaming = true; } diff --git a/drivers/staging/media/rkisp1/rkisp1-common.h b/drivers/staging/media/rkisp1/rkisp1-common.h index 0c4fe503adc9..3dc51d703f73 100644 --- a/drivers/staging/media/rkisp1/rkisp1-common.h +++ b/drivers/staging/media/rkisp1/rkisp1-common.h @@ -22,6 +22,9 @@ #include "rkisp1-regs.h" #include "uapi/rkisp1-config.h" +#define RKISP1_ISP_SD_SRC BIT(0) +#define RKISP1_ISP_SD_SINK BIT(1) + #define RKISP1_ISP_MAX_WIDTH 4032 #define RKISP1_ISP_MAX_HEIGHT 3024 #define RKISP1_ISP_MIN_WIDTH 32 @@ -42,9 +45,14 @@ #define RKISP1_MAX_BUS_CLK 8 +#define RKISP1_STATS_MEAS_MASK (RKISP1_CIF_ISP_AWB_DONE | \ + RKISP1_CIF_ISP_AFM_FIN | \ + RKISP1_CIF_ISP_EXP_END | \ + RKISP1_CIF_ISP_HIST_MEASURE_RDY) enum rkisp1_rsz_pad { RKISP1_RSZ_PAD_SINK, RKISP1_RSZ_PAD_SRC, + RKISP1_RSZ_PAD_MAX }; enum rkisp1_stream_id { @@ -174,21 +182,17 @@ struct rkisp1_capture { /* * struct rkisp1_stats - ISP Statistics device * - * @irq_lock: buffer queue lock + * @lock: locks the buffer list 'stat' and 'is_streaming' * @stat: stats buffer list - * @readout_wq: workqueue for statistics information read */ struct rkisp1_stats { struct rkisp1_vdev_node vnode; struct rkisp1_device *rkisp1; - spinlock_t irq_lock; + spinlock_t lock; /* locks 'is_streaming', and 'stats' */ struct list_head stat; struct v4l2_format vdev_fmt; bool is_streaming; - - struct workqueue_struct *readout_wq; - struct mutex wq_lock; }; /* @@ -216,8 +220,8 @@ struct rkisp1_resizer { struct v4l2_subdev sd; enum rkisp1_stream_id id; struct rkisp1_device *rkisp1; - struct media_pad pads[RKISP1_ISP_PAD_MAX]; - struct v4l2_subdev_pad_config pad_cfg[RKISP1_ISP_PAD_MAX]; + struct media_pad pads[RKISP1_RSZ_PAD_MAX]; + struct v4l2_subdev_pad_config pad_cfg[RKISP1_RSZ_PAD_MAX]; const struct rkisp1_rsz_config *config; enum v4l2_pixel_encoding pixel_enc; struct mutex ops_lock; @@ -226,7 +230,9 @@ struct rkisp1_resizer { struct rkisp1_debug { struct dentry *debugfs_dir; unsigned long data_loss; - unsigned long pic_size_error; + unsigned long outform_size_error; + unsigned long img_stabilization_size_error; + unsigned long inform_size_error; unsigned long mipi_error; unsigned long stats_error; unsigned long stop_timeout[2]; @@ -250,7 +256,6 @@ struct rkisp1_device { unsigned int clk_size; struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK]; struct v4l2_device v4l2_dev; - struct v4l2_ctrl_handler ctrl_handler; struct media_device media_dev; struct v4l2_async_notifier notifier; struct rkisp1_sensor_async *active_sensor; @@ -260,7 +265,6 @@ struct rkisp1_device { struct rkisp1_stats stats; struct rkisp1_params params; struct media_pipeline pipe; - struct vb2_alloc_ctx *alloc_ctx; struct mutex stream_lock; struct rkisp1_debug debug; }; diff --git a/drivers/staging/media/rkisp1/rkisp1-dev.c b/drivers/staging/media/rkisp1/rkisp1-dev.c index 9ac38bafb839..a0eb8f08708b 100644 --- a/drivers/staging/media/rkisp1/rkisp1-dev.c +++ b/drivers/staging/media/rkisp1/rkisp1-dev.c @@ -129,7 +129,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1) ret = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode, MEDIA_PAD_FL_SOURCE); if (ret < 0) { - dev_err(sd->dev, "failed to find src pad for %s\n", + dev_err(rkisp1->dev, "failed to find src pad for %s\n", sd->name); return ret; } @@ -438,8 +438,13 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1) } debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir, &debug->data_loss); - debugfs_create_ulong("pic_size_error", 0444, debug->debugfs_dir, - &debug->pic_size_error); + debugfs_create_ulong("outform_size_err", 0444, debug->debugfs_dir, + &debug->outform_size_error); + debugfs_create_ulong("img_stabilization_size_error", 0444, + debug->debugfs_dir, + &debug->img_stabilization_size_error); + debugfs_create_ulong("inform_size_error", 0444, debug->debugfs_dir, + &debug->inform_size_error); debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir, &debug->mipi_error); debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir, diff --git a/drivers/staging/media/rkisp1/rkisp1-isp.c b/drivers/staging/media/rkisp1/rkisp1-isp.c index dc2b59a0160a..6ec1e9816e9f 100644 --- a/drivers/staging/media/rkisp1/rkisp1-isp.c +++ b/drivers/staging/media/rkisp1/rkisp1-isp.c @@ -23,10 +23,6 @@ #define RKISP1_ISP_DEV_NAME RKISP1_DRIVER_NAME "_isp" -#define RKISP1_DIR_SRC BIT(0) -#define RKISP1_DIR_SINK BIT(1) -#define RKISP1_DIR_SINK_SRC (RKISP1_DIR_SINK | RKISP1_DIR_SRC) - /* * NOTE: MIPI controller and input MUX are also configured in this file. * This is because ISP Subdev describes not only ISP submodule (input size, @@ -62,119 +58,119 @@ static const struct rkisp1_isp_mbus_info rkisp1_isp_formats[] = { { .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .pixel_enc = V4L2_PIXEL_ENC_YUV, - .direction = RKISP1_DIR_SRC, + .direction = RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10, .bayer_pat = RKISP1_RAW_RGGB, .bus_width = 10, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10, .bayer_pat = RKISP1_RAW_BGGR, .bus_width = 10, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10, .bayer_pat = RKISP1_RAW_GBRG, .bus_width = 10, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10, .bayer_pat = RKISP1_RAW_GRBG, .bus_width = 10, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12, .bayer_pat = RKISP1_RAW_RGGB, .bus_width = 12, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12, .bayer_pat = RKISP1_RAW_BGGR, .bus_width = 12, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12, .bayer_pat = RKISP1_RAW_GBRG, .bus_width = 12, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12, .bayer_pat = RKISP1_RAW_GRBG, .bus_width = 12, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8, .bayer_pat = RKISP1_RAW_RGGB, .bus_width = 8, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8, .bayer_pat = RKISP1_RAW_BGGR, .bus_width = 8, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8, .bayer_pat = RKISP1_RAW_GBRG, .bus_width = 8, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8, .bayer_pat = RKISP1_RAW_GRBG, .bus_width = 8, - .direction = RKISP1_DIR_SINK_SRC, + .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC, }, { .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b, .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_YCBYCR, .bus_width = 16, - .direction = RKISP1_DIR_SINK, + .direction = RKISP1_ISP_SD_SINK, }, { .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b, .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_YCRYCB, .bus_width = 16, - .direction = RKISP1_DIR_SINK, + .direction = RKISP1_ISP_SD_SINK, }, { .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b, .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_CBYCRY, .bus_width = 16, - .direction = RKISP1_DIR_SINK, + .direction = RKISP1_ISP_SD_SINK, }, { .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b, .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_CRYCBY, .bus_width = 16, - .direction = RKISP1_DIR_SINK, + .direction = RKISP1_ISP_SD_SINK, }, }; @@ -203,10 +199,8 @@ static struct v4l2_subdev *rkisp1_get_remote_sensor(struct v4l2_subdev *sd) local = &sd->entity.pads[RKISP1_ISP_PAD_SINK_VIDEO]; remote = media_entity_remote_pad(local); - if (!remote) { - dev_warn(sd->dev, "No link between isp and sensor\n"); + if (!remote) return NULL; - } sensor_me = remote->entity; return media_entity_to_v4l2_subdev(sensor_me); @@ -574,9 +568,9 @@ static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd, int pos = 0; if (code->pad == RKISP1_ISP_PAD_SINK_VIDEO) { - dir = RKISP1_DIR_SINK; + dir = RKISP1_ISP_SD_SINK; } else if (code->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) { - dir = RKISP1_DIR_SRC; + dir = RKISP1_ISP_SD_SRC; } else { if (code->index > 0) return -EINVAL; @@ -661,7 +655,7 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, src_fmt->code = format->code; mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code); - if (!mbus_info || !(mbus_info->direction & RKISP1_DIR_SRC)) { + if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) { src_fmt->code = RKISP1_DEF_SRC_PAD_FMT; mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code); } @@ -745,7 +739,7 @@ static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp, which); sink_fmt->code = format->code; mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); - if (!mbus_info || !(mbus_info->direction & RKISP1_DIR_SINK)) { + if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SINK)) { sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT; mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); } @@ -889,18 +883,20 @@ static const struct v4l2_subdev_pad_ops rkisp1_isp_pad_ops = { static int rkisp1_mipi_csi2_start(struct rkisp1_isp *isp, struct rkisp1_sensor_async *sensor) { + struct rkisp1_device *rkisp1 = + container_of(isp->sd.v4l2_dev, struct rkisp1_device, v4l2_dev); union phy_configure_opts opts; struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy; s64 pixel_clock; if (!sensor->pixel_rate_ctrl) { - dev_warn(sensor->sd->dev, "No pixel rate control in subdev\n"); + dev_warn(rkisp1->dev, "No pixel rate control in sensor subdev\n"); return -EPIPE; } pixel_clock = v4l2_ctrl_g_ctrl_int64(sensor->pixel_rate_ctrl); if (!pixel_clock) { - dev_err(sensor->sd->dev, "Invalid pixel rate value\n"); + dev_err(rkisp1->dev, "Invalid pixel rate value\n"); return -EINVAL; } @@ -933,8 +929,11 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable) } sensor_sd = rkisp1_get_remote_sensor(sd); - if (!sensor_sd) + if (!sensor_sd) { + dev_warn(rkisp1->dev, "No link between isp and sensor\n"); return -ENODEV; + } + rkisp1->active_sensor = container_of(sensor_sd->asd, struct rkisp1_sensor_async, asd); @@ -1021,7 +1020,7 @@ int rkisp1_isp_register(struct rkisp1_device *rkisp1, ret = v4l2_device_register_subdev(v4l2_dev, sd); if (ret) { - dev_err(sd->dev, "Failed to register isp subdev\n"); + dev_err(rkisp1->dev, "Failed to register isp subdev\n"); goto err_cleanup_media_entity; } @@ -1123,8 +1122,13 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1) if (status & RKISP1_CIF_ISP_PIC_SIZE_ERROR) { /* Clear pic_size_error */ isp_err = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ERR); + if (isp_err & RKISP1_CIF_ISP_ERR_INFORM_SIZE) + rkisp1->debug.inform_size_error++; + if (isp_err & RKISP1_CIF_ISP_ERR_IS_SIZE) + rkisp1->debug.img_stabilization_size_error++; + if (isp_err & RKISP1_CIF_ISP_ERR_OUTFORM_SIZE) + rkisp1->debug.outform_size_error++; rkisp1_write(rkisp1, isp_err, RKISP1_CIF_ISP_ERR_CLR); - rkisp1->debug.pic_size_error++; } else if (status & RKISP1_CIF_ISP_DATA_LOSS) { /* keep track of data_loss in debugfs */ rkisp1->debug.data_loss++; @@ -1135,10 +1139,7 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1) /* New frame from the sensor received */ isp_ris = rkisp1_read(rkisp1, RKISP1_CIF_ISP_RIS); - if (isp_ris & (RKISP1_CIF_ISP_AWB_DONE | - RKISP1_CIF_ISP_AFM_FIN | - RKISP1_CIF_ISP_EXP_END | - RKISP1_CIF_ISP_HIST_MEASURE_RDY)) + if (isp_ris & RKISP1_STATS_MEAS_MASK) rkisp1_stats_isr(&rkisp1->stats, isp_ris); } diff --git a/drivers/staging/media/rkisp1/rkisp1-params.c b/drivers/staging/media/rkisp1/rkisp1-params.c index 44d542caf32b..797e79de659c 100644 --- a/drivers/staging/media/rkisp1/rkisp1-params.c +++ b/drivers/staging/media/rkisp1/rkisp1-params.c @@ -1607,7 +1607,7 @@ int rkisp1_params_register(struct rkisp1_params *params, goto err_release_queue; ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); if (ret) { - dev_err(&vdev->dev, + dev_err(rkisp1->dev, "failed to register %s, ret=%d\n", vdev->name, ret); goto err_cleanup_media_entity; } diff --git a/drivers/staging/media/rkisp1/rkisp1-regs.h b/drivers/staging/media/rkisp1/rkisp1-regs.h index 46018f435b6f..9b8e616ea24c 100644 --- a/drivers/staging/media/rkisp1/rkisp1-regs.h +++ b/drivers/staging/media/rkisp1/rkisp1-regs.h @@ -398,7 +398,6 @@ #define RKISP1_CIF_ISP_AWB_YMAX_READ(x) (((x) >> 2) & 1) #define RKISP1_CIF_ISP_AWB_MODE_RGB_EN ((1 << 31) | (0x2 << 0)) #define RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN ((0 << 31) | (0x2 << 0)) -#define RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN ((0 << 31) | (0x2 << 0)) #define RKISP1_CIF_ISP_AWB_MODE_MASK_NONE 0xFFFFFFFC #define RKISP1_CIF_ISP_AWB_MODE_READ(x) ((x) & 3) /* ISP_AWB_GAIN_RB, ISP_AWB_GAIN_G */ diff --git a/drivers/staging/media/rkisp1/rkisp1-resizer.c b/drivers/staging/media/rkisp1/rkisp1-resizer.c index d049374413dc..c66d2a52fd71 100644 --- a/drivers/staging/media/rkisp1/rkisp1-resizer.c +++ b/drivers/staging/media/rkisp1/rkisp1-resizer.c @@ -437,8 +437,8 @@ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd, u32 pad = code->pad; int ret; - /* supported mbus codes are the same in isp sink pad */ - code->pad = RKISP1_ISP_PAD_SINK_VIDEO; + /* supported mbus codes are the same in isp video src pad */ + code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO; ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code, &dummy_cfg, code); @@ -542,7 +542,7 @@ static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz, which); sink_fmt->code = format->code; mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); - if (!mbus_info) { + if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) { sink_fmt->code = RKISP1_DEF_FMT; mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); } @@ -553,11 +553,11 @@ static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz, src_fmt->code = sink_fmt->code; sink_fmt->width = clamp_t(u32, format->width, - rsz->config->min_rsz_width, - rsz->config->max_rsz_width); + RKISP1_ISP_MIN_WIDTH, + RKISP1_ISP_MAX_WIDTH); sink_fmt->height = clamp_t(u32, format->height, - rsz->config->min_rsz_height, - rsz->config->max_rsz_height); + RKISP1_ISP_MIN_HEIGHT, + RKISP1_ISP_MAX_HEIGHT); *format = *sink_fmt; @@ -639,7 +639,7 @@ static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd, if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC) return -EINVAL; - dev_dbg(sd->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__, + dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__, sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height); mutex_lock(&rsz->ops_lock); @@ -735,7 +735,7 @@ static int rkisp1_rsz_register(struct rkisp1_resizer *rsz) rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC; mutex_init(&rsz->ops_lock); - ret = media_entity_pads_init(&sd->entity, 2, pads); + ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads); if (ret) return ret; diff --git a/drivers/staging/media/rkisp1/rkisp1-stats.c b/drivers/staging/media/rkisp1/rkisp1-stats.c index 6dfcbdc3deb8..87e4104d20dd 100644 --- a/drivers/staging/media/rkisp1/rkisp1-stats.c +++ b/drivers/staging/media/rkisp1/rkisp1-stats.c @@ -18,21 +18,6 @@ #define RKISP1_ISP_STATS_REQ_BUFS_MIN 2 #define RKISP1_ISP_STATS_REQ_BUFS_MAX 8 -enum rkisp1_isp_readout_cmd { - RKISP1_ISP_READOUT_MEAS, - RKISP1_ISP_READOUT_META, -}; - -struct rkisp1_isp_readout_work { - struct work_struct work; - struct rkisp1_stats *stats; - - unsigned int frame_id; - unsigned int isp_ris; - enum rkisp1_isp_readout_cmd readout; - struct vb2_buffer *vb; -}; - static int rkisp1_stats_enum_fmt_meta_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { @@ -133,9 +118,9 @@ static void rkisp1_stats_vb2_buf_queue(struct vb2_buffer *vb) stats_buf->vaddr[0] = vb2_plane_vaddr(vb, 0); - mutex_lock(&stats_dev->wq_lock); + spin_lock_irq(&stats_dev->lock); list_add_tail(&stats_buf->queue, &stats_dev->stat); - mutex_unlock(&stats_dev->wq_lock); + spin_unlock_irq(&stats_dev->lock); } static int rkisp1_stats_vb2_buf_prepare(struct vb2_buffer *vb) @@ -152,17 +137,10 @@ static void rkisp1_stats_vb2_stop_streaming(struct vb2_queue *vq) { struct rkisp1_stats *stats = vq->drv_priv; struct rkisp1_buffer *buf; - unsigned long flags; unsigned int i; - /* Make sure no new work queued in isr before draining wq */ - spin_lock_irqsave(&stats->irq_lock, flags); + spin_lock_irq(&stats->lock); stats->is_streaming = false; - spin_unlock_irqrestore(&stats->irq_lock, flags); - - drain_workqueue(stats->readout_wq); - - mutex_lock(&stats->wq_lock); for (i = 0; i < RKISP1_ISP_STATS_REQ_BUFS_MAX; i++) { if (list_empty(&stats->stat)) break; @@ -171,7 +149,7 @@ static void rkisp1_stats_vb2_stop_streaming(struct vb2_queue *vq) list_del(&buf->queue); vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); } - mutex_unlock(&stats->wq_lock); + spin_unlock_irq(&stats->lock); } static int @@ -253,7 +231,7 @@ static void rkisp1_stats_get_afc_meas(struct rkisp1_stats *stats, struct rkisp1_device *rkisp1 = stats->rkisp1; struct rkisp1_cif_isp_af_stat *af; - pbuf->meas_type = RKISP1_CIF_ISP_STAT_AFM_FIN; + pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AFM_FIN; af = &pbuf->params.af; af->window[0].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_A); @@ -325,8 +303,7 @@ static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats, } static void -rkisp1_stats_send_measurement(struct rkisp1_stats *stats, - struct rkisp1_isp_readout_work *meas_work) +rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris) { struct rkisp1_stat_buffer *cur_stat_buf; struct rkisp1_buffer *cur_buf = NULL; @@ -334,21 +311,12 @@ rkisp1_stats_send_measurement(struct rkisp1_stats *stats, atomic_read(&stats->rkisp1->isp.frame_sequence); u64 timestamp = ktime_get_ns(); - if (frame_sequence != meas_work->frame_id) { - dev_warn(stats->rkisp1->dev, - "Measurement late(%d, %d)\n", - frame_sequence, meas_work->frame_id); - frame_sequence = meas_work->frame_id; - } - - mutex_lock(&stats->wq_lock); /* get one empty buffer */ if (!list_empty(&stats->stat)) { cur_buf = list_first_entry(&stats->stat, struct rkisp1_buffer, queue); list_del(&cur_buf->queue); } - mutex_unlock(&stats->wq_lock); if (!cur_buf) return; @@ -356,26 +324,19 @@ rkisp1_stats_send_measurement(struct rkisp1_stats *stats, cur_stat_buf = (struct rkisp1_stat_buffer *)(cur_buf->vaddr[0]); - if (meas_work->isp_ris & RKISP1_CIF_ISP_AWB_DONE) { + if (isp_ris & RKISP1_CIF_ISP_AWB_DONE) rkisp1_stats_get_awb_meas(stats, cur_stat_buf); - cur_stat_buf->meas_type |= RKISP1_CIF_ISP_STAT_AWB; - } - if (meas_work->isp_ris & RKISP1_CIF_ISP_AFM_FIN) { + if (isp_ris & RKISP1_CIF_ISP_AFM_FIN) rkisp1_stats_get_afc_meas(stats, cur_stat_buf); - cur_stat_buf->meas_type |= RKISP1_CIF_ISP_STAT_AFM_FIN; - } - if (meas_work->isp_ris & RKISP1_CIF_ISP_EXP_END) { + if (isp_ris & RKISP1_CIF_ISP_EXP_END) { rkisp1_stats_get_aec_meas(stats, cur_stat_buf); rkisp1_stats_get_bls_meas(stats, cur_stat_buf); - cur_stat_buf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP; } - if (meas_work->isp_ris & RKISP1_CIF_ISP_HIST_MEASURE_RDY) { + if (isp_ris & RKISP1_CIF_ISP_HIST_MEASURE_RDY) rkisp1_stats_get_hst_meas(stats, cur_stat_buf); - cur_stat_buf->meas_type |= RKISP1_CIF_ISP_STAT_HIST; - } vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0, sizeof(struct rkisp1_stat_buffer)); @@ -384,64 +345,26 @@ rkisp1_stats_send_measurement(struct rkisp1_stats *stats, vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } -static void rkisp1_stats_readout_work(struct work_struct *work) -{ - struct rkisp1_isp_readout_work *readout_work = - container_of(work, struct rkisp1_isp_readout_work, work); - struct rkisp1_stats *stats = readout_work->stats; - - if (readout_work->readout == RKISP1_ISP_READOUT_MEAS) - rkisp1_stats_send_measurement(stats, readout_work); - - kfree(readout_work); -} - void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris) { - unsigned int frame_sequence = - atomic_read(&stats->rkisp1->isp.frame_sequence); struct rkisp1_device *rkisp1 = stats->rkisp1; - struct rkisp1_isp_readout_work *work; unsigned int isp_mis_tmp = 0; - u32 val; - spin_lock(&stats->irq_lock); + spin_lock(&stats->lock); - val = RKISP1_CIF_ISP_AWB_DONE | RKISP1_CIF_ISP_AFM_FIN | - RKISP1_CIF_ISP_EXP_END | RKISP1_CIF_ISP_HIST_MEASURE_RDY; - rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_ICR); + rkisp1_write(rkisp1, RKISP1_STATS_MEAS_MASK, RKISP1_CIF_ISP_ICR); isp_mis_tmp = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS); - if (isp_mis_tmp & - (RKISP1_CIF_ISP_AWB_DONE | RKISP1_CIF_ISP_AFM_FIN | - RKISP1_CIF_ISP_EXP_END | RKISP1_CIF_ISP_HIST_MEASURE_RDY)) + if (isp_mis_tmp & RKISP1_STATS_MEAS_MASK) rkisp1->debug.stats_error++; if (!stats->is_streaming) goto unlock; - if (isp_ris & (RKISP1_CIF_ISP_AWB_DONE | - RKISP1_CIF_ISP_AFM_FIN | - RKISP1_CIF_ISP_EXP_END | - RKISP1_CIF_ISP_HIST_MEASURE_RDY)) { - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (work) { - INIT_WORK(&work->work, - rkisp1_stats_readout_work); - work->readout = RKISP1_ISP_READOUT_MEAS; - work->stats = stats; - work->frame_id = frame_sequence; - work->isp_ris = isp_ris; - if (!queue_work(stats->readout_wq, - &work->work)) - kfree(work); - } else { - dev_err(stats->rkisp1->dev, - "Could not allocate work\n"); - } - } + if (isp_ris & RKISP1_STATS_MEAS_MASK) + rkisp1_stats_send_measurement(stats, isp_ris); unlock: - spin_unlock(&stats->irq_lock); + spin_unlock(&stats->lock); } static void rkisp1_init_stats(struct rkisp1_stats *stats) @@ -461,10 +384,9 @@ int rkisp1_stats_register(struct rkisp1_stats *stats, int ret; stats->rkisp1 = rkisp1; - mutex_init(&stats->wq_lock); mutex_init(&node->vlock); INIT_LIST_HEAD(&stats->stat); - spin_lock_init(&stats->irq_lock); + spin_lock_init(&stats->lock); strscpy(vdev->name, RKISP1_STATS_DEV_NAME, sizeof(vdev->name)); @@ -493,25 +415,13 @@ int rkisp1_stats_register(struct rkisp1_stats *stats, goto err_cleanup_media_entity; } - stats->readout_wq = alloc_workqueue("measurement_queue", - WQ_UNBOUND | WQ_MEM_RECLAIM, - 1); - - if (!stats->readout_wq) { - ret = -ENOMEM; - goto err_unreg_vdev; - } - return 0; -err_unreg_vdev: - video_unregister_device(vdev); err_cleanup_media_entity: media_entity_cleanup(&vdev->entity); err_release_queue: vb2_queue_release(vdev->queue); mutex_destroy(&node->vlock); - mutex_destroy(&stats->wq_lock); return ret; } @@ -520,10 +430,8 @@ void rkisp1_stats_unregister(struct rkisp1_stats *stats) struct rkisp1_vdev_node *node = &stats->vnode; struct video_device *vdev = &node->vdev; - destroy_workqueue(stats->readout_wq); video_unregister_device(vdev); media_entity_cleanup(&vdev->entity); vb2_queue_release(vdev->queue); mutex_destroy(&node->vlock); - mutex_destroy(&stats->wq_lock); } diff --git a/drivers/staging/media/rkisp1/uapi/rkisp1-config.h b/drivers/staging/media/rkisp1/uapi/rkisp1-config.h index ca0d031b14ac..8f9b061e5b6b 100644 --- a/drivers/staging/media/rkisp1/uapi/rkisp1-config.h +++ b/drivers/staging/media/rkisp1/uapi/rkisp1-config.h @@ -68,7 +68,7 @@ #define RKISP1_CIF_ISP_BLS_FIX_MASK 0x00001fff /* - * Automatic white balance measurments + * Automatic white balance measurements */ #define RKISP1_CIF_ISP_AWB_MAX_GRID 1 #define RKISP1_CIF_ISP_AWB_MAX_FRAMES 7 @@ -408,7 +408,7 @@ struct rkisp1_cif_isp_flt_config { /** * struct rkisp1_cif_isp_bdm_config - Configuration used by Bayer DeMosaic * - * @demosaic_th: threshod for bayer demosaicing texture detection + * @demosaic_th: threshold for bayer demosaicing texture detection */ struct rkisp1_cif_isp_bdm_config { __u8 demosaic_th; |