summaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/rkisp1
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/rkisp1')
-rw-r--r--drivers/staging/media/rkisp1/TODO1
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-capture.c56
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-common.h26
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-dev.c11
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-isp.c75
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-params.c2
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-regs.h1
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-resizer.c18
-rw-r--r--drivers/staging/media/rkisp1/rkisp1-stats.c126
-rw-r--r--drivers/staging/media/rkisp1/uapi/rkisp1-config.h4
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;