Commit 9a28dbd6 authored by Jacob Chen's avatar Jacob Chen Committed by Mauro Carvalho Chehab

media: staging: rkisp1: add capture device for statistics

Add the capture video driver for rockchip isp1 statistics block.
Signed-off-by: default avatarJacob Chen <jacob2.chen@rock-chips.com>
Signed-off-by: default avatarShunqian Zheng <zhengsq@rock-chips.com>
Signed-off-by: default avatarYichong Zhong <zyc@rock-chips.com>
Signed-off-by: default avatarJacob Chen <cc@rock-chips.com>
Signed-off-by: default avatarEddie Cai <eddie.cai.linux@gmail.com>
Signed-off-by: default avatarJeffy Chen <jeffy.chen@rock-chips.com>
Signed-off-by: default avatarAllon Huang <allon.huang@rock-chips.com>
Signed-off-by: default avatarTomasz Figa <tfiga@chromium.org>
Signed-off-by: default avatarHelen Koike <helen.koike@collabora.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 8e2be317
...@@ -3,4 +3,5 @@ rockchip-isp1-objs += rkisp1-capture.o \ ...@@ -3,4 +3,5 @@ rockchip-isp1-objs += rkisp1-capture.o \
rkisp1-common.o \ rkisp1-common.o \
rkisp1-dev.o \ rkisp1-dev.o \
rkisp1-isp.o \ rkisp1-isp.o \
rkisp1-resizer.o rkisp1-resizer.o \
rkisp1-stats.o
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <media/videobuf2-v4l2.h> #include <media/videobuf2-v4l2.h>
#include "rkisp1-regs.h" #include "rkisp1-regs.h"
#include "uapi/rkisp1-config.h"
#define RKISP1_ISP_MAX_WIDTH 4032 #define RKISP1_ISP_MAX_WIDTH 4032
#define RKISP1_ISP_MAX_HEIGHT 3024 #define RKISP1_ISP_MAX_HEIGHT 3024
...@@ -174,6 +175,26 @@ struct rkisp1_capture { ...@@ -174,6 +175,26 @@ struct rkisp1_capture {
} pix; } pix;
}; };
/*
* struct rkisp1_stats - ISP Statistics device
*
* @irq_lock: buffer queue lock
* @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;
struct list_head stat;
struct v4l2_format vdev_fmt;
bool is_streaming;
struct workqueue_struct *readout_wq;
struct mutex wq_lock;
};
struct rkisp1_resizer { struct rkisp1_resizer {
struct v4l2_subdev sd; struct v4l2_subdev sd;
enum rkisp1_stream_id id; enum rkisp1_stream_id id;
...@@ -189,6 +210,7 @@ struct rkisp1_debug { ...@@ -189,6 +210,7 @@ struct rkisp1_debug {
unsigned long data_loss; unsigned long data_loss;
unsigned long pic_size_error; unsigned long pic_size_error;
unsigned long mipi_error; unsigned long mipi_error;
unsigned long stats_error;
unsigned long stop_timeout[2]; unsigned long stop_timeout[2];
unsigned long frame_drop[2]; unsigned long frame_drop[2];
}; };
...@@ -199,6 +221,7 @@ struct rkisp1_debug { ...@@ -199,6 +221,7 @@ struct rkisp1_debug {
* @active_sensor: sensor in-use, set when streaming on * @active_sensor: sensor in-use, set when streaming on
* @isp: ISP sub-device * @isp: ISP sub-device
* @rkisp1_capture: capture video device * @rkisp1_capture: capture video device
* @stats: ISP statistics output device
*/ */
struct rkisp1_device { struct rkisp1_device {
void __iomem *base_addr; void __iomem *base_addr;
...@@ -214,6 +237,7 @@ struct rkisp1_device { ...@@ -214,6 +237,7 @@ struct rkisp1_device {
struct rkisp1_isp isp; struct rkisp1_isp isp;
struct rkisp1_resizer resizer_devs[2]; struct rkisp1_resizer resizer_devs[2];
struct rkisp1_capture capture_devs[2]; struct rkisp1_capture capture_devs[2];
struct rkisp1_stats stats;
struct media_pipeline pipe; struct media_pipeline pipe;
struct vb2_alloc_ctx *alloc_ctx; struct vb2_alloc_ctx *alloc_ctx;
struct rkisp1_debug debug; struct rkisp1_debug debug;
...@@ -262,6 +286,7 @@ const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code); ...@@ -262,6 +286,7 @@ const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code);
void rkisp1_isp_isr(struct rkisp1_device *rkisp1); void rkisp1_isp_isr(struct rkisp1_device *rkisp1);
void rkisp1_mipi_isr(struct rkisp1_device *rkisp1); void rkisp1_mipi_isr(struct rkisp1_device *rkisp1);
void rkisp1_capture_isr(struct rkisp1_device *rkisp1); void rkisp1_capture_isr(struct rkisp1_device *rkisp1);
void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1); int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1);
void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1); void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1);
...@@ -269,4 +294,9 @@ void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1); ...@@ -269,4 +294,9 @@ void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1);
int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1); int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1);
void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1); void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1);
int rkisp1_stats_register(struct rkisp1_stats *stats,
struct v4l2_device *v4l2_dev,
struct rkisp1_device *rkisp1);
void rkisp1_stats_unregister(struct rkisp1_stats *stats);
#endif /* _RKISP1_COMMON_H */ #endif /* _RKISP1_COMMON_H */
...@@ -57,6 +57,14 @@ ...@@ -57,6 +57,14 @@
* | DMA |------------------------------------+ Self Picture Path * | DMA |------------------------------------+ Self Picture Path
* +--------+ * +--------+
* *
* rkisp1-stats.c
* |===============|
* +---------------+
* | |
* | ISP |
* | |
* +---------------+
*
* *
* Media Topology * Media Topology
* -------------- * --------------
...@@ -74,14 +82,14 @@ ...@@ -74,14 +82,14 @@
* +----------+ |------+------| * +----------+ |------+------|
* | ISP | * | ISP |
* |------+------| * |------+------|
* +-------------| 2 | 3 | * +-------------| 2 | 3 |----------+
* | +------+------+ * | +------+------+ |
* | | * | | |
* v v * v v v
* +- ---------+ +-----------+ * +- ---------+ +-----------+ +-----------+
* | 0 | | 0 | * | 0 | | 0 | | stats |
* ------------- ------------- * ------------- ------------- | (capture) |
* | Resizer | | Resizer | * | Resizer | | Resizer | +-----------+
* ------------| ------------| * ------------| ------------|
* | 1 | | 1 | * | 1 | | 1 |
* +-----------+ +-----------+ * +-----------+ +-----------+
...@@ -156,7 +164,11 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1) ...@@ -156,7 +164,11 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
return ret; return ret;
} }
return 0; /* 3A stats links */
source = &rkisp1->isp.sd.entity;
sink = &rkisp1->stats.vnode.vdev.entity;
return media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_STATS,
sink, 0, flags);
} }
static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier, static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
...@@ -336,14 +348,20 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1) ...@@ -336,14 +348,20 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
if (ret) if (ret)
goto err_unreg_resizer_devs; goto err_unreg_resizer_devs;
ret = rkisp1_stats_register(&rkisp1->stats, &rkisp1->v4l2_dev, rkisp1);
if (ret)
goto err_unreg_capture_devs;
ret = rkisp1_subdev_notifier(rkisp1); ret = rkisp1_subdev_notifier(rkisp1);
if (ret) { if (ret) {
dev_err(rkisp1->dev, dev_err(rkisp1->dev,
"Failed to register subdev notifier(%d)\n", ret); "Failed to register subdev notifier(%d)\n", ret);
goto err_unreg_capture_devs; goto err_unreg_stats;
} }
return 0; return 0;
err_unreg_stats:
rkisp1_stats_unregister(&rkisp1->stats);
err_unreg_capture_devs: err_unreg_capture_devs:
rkisp1_capture_devs_unregister(rkisp1); rkisp1_capture_devs_unregister(rkisp1);
err_unreg_resizer_devs: err_unreg_resizer_devs:
...@@ -408,6 +426,8 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1) ...@@ -408,6 +426,8 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
&debug->pic_size_error); &debug->pic_size_error);
debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir, debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir,
&debug->mipi_error); &debug->mipi_error);
debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir,
&debug->stats_error);
debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir, debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir,
&debug->stop_timeout[RKISP1_MAINPATH]); &debug->stop_timeout[RKISP1_MAINPATH]);
debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir, debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir,
...@@ -509,6 +529,7 @@ static int rkisp1_remove(struct platform_device *pdev) ...@@ -509,6 +529,7 @@ static int rkisp1_remove(struct platform_device *pdev)
v4l2_async_notifier_unregister(&rkisp1->notifier); v4l2_async_notifier_unregister(&rkisp1->notifier);
v4l2_async_notifier_cleanup(&rkisp1->notifier); v4l2_async_notifier_cleanup(&rkisp1->notifier);
rkisp1_stats_unregister(&rkisp1->stats);
rkisp1_capture_devs_unregister(rkisp1); rkisp1_capture_devs_unregister(rkisp1);
rkisp1_resizer_devs_unregister(rkisp1); rkisp1_resizer_devs_unregister(rkisp1);
rkisp1_isp_unregister(rkisp1); rkisp1_isp_unregister(rkisp1);
......
...@@ -1130,4 +1130,16 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1) ...@@ -1130,4 +1130,16 @@ void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
/* keep track of data_loss in debugfs */ /* keep track of data_loss in debugfs */
rkisp1->debug.data_loss++; rkisp1->debug.data_loss++;
} }
if (status & RKISP1_CIF_ISP_FRAME) {
u32 isp_ris;
/* 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))
rkisp1_stats_isr(&rkisp1->stats, isp_ris);
}
} }
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment