From cad151904379b302a62e8967b7db6ba2e883a212 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:05 +0100 Subject: [PATCH 001/252] media: fimc-lite: drop unused flite_hw_set_camera_polarity() Function flite_hw_set_camera_polarity() is not defined, so drop its declaration from the header. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h index c5656e902750..3b8af3ce1838 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h @@ -134,8 +134,6 @@ void flite_hw_capture_start(struct fimc_lite *dev); void flite_hw_capture_stop(struct fimc_lite *dev); void flite_hw_set_camera_bus(struct fimc_lite *dev, struct fimc_source_info *s_info); -void flite_hw_set_camera_polarity(struct fimc_lite *dev, - struct fimc_source_info *cam); void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f); void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f); From f4036d7eaeb17697c3a012c33e694e12256a6e07 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:06 +0100 Subject: [PATCH 002/252] media: fimc-lite: constify several pointers in function arguments Several functions do not modify pointed structure, thus the pointer can point to const data for additional safety and self-documenting intention of the function. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- .../platform/samsung/exynos4-is/fimc-lite-reg.c | 13 +++++++------ .../platform/samsung/exynos4-is/fimc-lite-reg.h | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c index 57996b4104b4..2483277a6cb0 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c @@ -124,7 +124,7 @@ static const u32 src_pixfmt_map[8][3] = { }; /* Set camera input pixel format and resolution */ -void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f) +void flite_hw_set_source_format(struct fimc_lite *dev, const struct flite_frame *f) { u32 pixelcode = f->fmt->mbus_code; int i = ARRAY_SIZE(src_pixfmt_map); @@ -155,7 +155,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f) } /* Set the camera host input window offsets (cropping) */ -void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f) +void flite_hw_set_window_offset(struct fimc_lite *dev, const struct flite_frame *f) { u32 hoff2, voff2; u32 cfg; @@ -186,7 +186,7 @@ static void flite_hw_set_camera_port(struct fimc_lite *dev, int id) /* Select serial or parallel bus, camera port (A,B) and set signals polarity */ void flite_hw_set_camera_bus(struct fimc_lite *dev, - struct fimc_source_info *si) + const struct fimc_source_info *si) { u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL); unsigned int flags = si->flags; @@ -226,7 +226,8 @@ static void flite_hw_set_pack12(struct fimc_lite *dev, int on) writel(cfg, dev->regs + FLITE_REG_CIODMAFMT); } -static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f) +static void flite_hw_set_out_order(struct fimc_lite *dev, + const struct flite_frame *f) { static const u32 pixcode[4][2] = { { MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR }, @@ -244,7 +245,7 @@ static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f) writel(cfg | pixcode[i][1], dev->regs + FLITE_REG_CIODMAFMT); } -void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f) +void flite_hw_set_dma_window(struct fimc_lite *dev, const struct flite_frame *f) { u32 cfg; @@ -294,7 +295,7 @@ void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index) } /* Enable/disable output DMA, set output pixel size and offsets (composition) */ -void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f, +void flite_hw_set_output_dma(struct fimc_lite *dev, const struct flite_frame *f, bool enable) { u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL); diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h index 3b8af3ce1838..c5ec36dfb2f9 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h @@ -133,13 +133,13 @@ void flite_hw_set_interrupt_mask(struct fimc_lite *dev); void flite_hw_capture_start(struct fimc_lite *dev); void flite_hw_capture_stop(struct fimc_lite *dev); void flite_hw_set_camera_bus(struct fimc_lite *dev, - struct fimc_source_info *s_info); -void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f); -void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f); + const struct fimc_source_info *s_info); +void flite_hw_set_window_offset(struct fimc_lite *dev, const struct flite_frame *f); +void flite_hw_set_source_format(struct fimc_lite *dev, const struct flite_frame *f); -void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f, +void flite_hw_set_output_dma(struct fimc_lite *dev, const struct flite_frame *f, bool enable); -void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f); +void flite_hw_set_dma_window(struct fimc_lite *dev, const struct flite_frame *f); void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on); void flite_hw_dump_regs(struct fimc_lite *dev, const char *label); void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf); From 185bc53683674f6bc2c1dafc93c6cc464ec31748 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:07 +0100 Subject: [PATCH 003/252] media: fimc-lite: constify pointers to v4l2_pix_format_mplane In few places functions do not modify pointed "struct v4l2_pix_format_mplane", thus the pointer can point to const data for additional safety and self-documenting intention of the function. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-lite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c index 7898c9bebb04..d1d860fa3454 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c @@ -738,7 +738,7 @@ static int fimc_lite_try_fmt_mplane(struct file *file, void *fh, static int fimc_lite_s_fmt_mplane(struct file *file, void *priv, struct v4l2_format *f) { - struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; + const struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; struct fimc_lite *fimc = video_drvdata(file); struct flite_frame *frame = &fimc->out_frame; const struct fimc_fmt *fmt = NULL; From a311c6084077c46023f722e388e30506afdaf26f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:08 +0100 Subject: [PATCH 004/252] media: fimc-is: drop unused fimc_vidioc_enum_fmt_mplane() Function fimc_vidioc_enum_fmt_mplane() is not defined, so drop its declaration from the header. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-core.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.h b/drivers/media/platform/samsung/exynos4-is/fimc-core.h index 2b0760add092..cc840e6e07a9 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.h @@ -610,8 +610,6 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, /* -----------------------------------------------------*/ /* fimc-core.c */ -int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv, - struct v4l2_fmtdesc *f); int fimc_ctrls_create(struct fimc_ctx *ctx); void fimc_ctrls_delete(struct fimc_ctx *ctx); void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active); From ab1270eeb6b2a7d0f82a94ae33dc3cd05d69e64a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:09 +0100 Subject: [PATCH 005/252] media: fimc-is: constify clock names Static array with clock names can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c index 0be687b01ce5..0c401c75c1e0 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c @@ -29,7 +29,7 @@ #include "fimc-reg.h" #include "media-dev.h" -static char *fimc_clocks[MAX_FIMC_CLOCKS] = { +static const char *fimc_clocks[MAX_FIMC_CLOCKS] = { "sclk_fimc", "fimc" }; From 764d5a74b1779d6b2b630b870c198d6bb4a0d23d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:10 +0100 Subject: [PATCH 006/252] media: fimc-is: constify several pointers in function arguments Several functions do not modify pointed structure, thus the pointer can point to const data for additional safety and self-documenting intention of the function. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- .../media/platform/samsung/exynos4-is/fimc-core.c | 6 +++--- .../media/platform/samsung/exynos4-is/fimc-core.h | 12 ++++++------ drivers/media/platform/samsung/exynos4-is/fimc-reg.c | 10 +++++----- drivers/media/platform/samsung/exynos4-is/fimc-reg.h | 10 +++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c index 0c401c75c1e0..4411b250d7f1 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c @@ -326,7 +326,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *priv) /* The color format (colplanes, memplanes) must be already configured. */ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, - struct fimc_frame *frame, struct fimc_addr *addr) + const struct fimc_frame *frame, struct fimc_addr *addr) { int ret = 0; u32 pix_size; @@ -670,7 +670,7 @@ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx) v4l2_ctrl_unlock(ctrl); } -void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f) +void __fimc_get_format(const struct fimc_frame *frame, struct v4l2_format *f) { struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; int i; @@ -695,7 +695,7 @@ void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f) * @height: requested pixel height * @pix: multi-plane format to adjust */ -void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, +void fimc_adjust_mplane_format(const struct fimc_fmt *fmt, u32 width, u32 height, struct v4l2_pix_format_mplane *pix) { u32 bytesperline = 0; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.h b/drivers/media/platform/samsung/exynos4-is/fimc-core.h index cc840e6e07a9..261c9aac2f7f 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.h @@ -515,7 +515,7 @@ static inline void set_frame_crop(struct fimc_frame *f, f->height = height; } -static inline u32 fimc_get_format_depth(struct fimc_fmt *ff) +static inline u32 fimc_get_format_depth(const struct fimc_fmt *ff) { u32 i, depth = 0; @@ -557,7 +557,7 @@ static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx) return ret; } -static inline int tiled_fmt(struct fimc_fmt *fmt) +static inline int tiled_fmt(const struct fimc_fmt *fmt) { return fmt->fourcc == V4L2_PIX_FMT_NV12MT; } @@ -575,7 +575,7 @@ static inline bool fimc_user_defined_mbus_fmt(u32 code) } /* Return the alpha component bit mask */ -static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt) +static inline int fimc_get_alpha_mask(const struct fimc_fmt *fmt) { switch (fmt->color) { case FIMC_FMT_RGB444: return 0x0f; @@ -614,8 +614,8 @@ int fimc_ctrls_create(struct fimc_ctx *ctx); void fimc_ctrls_delete(struct fimc_ctx *ctx); void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active); void fimc_alpha_ctrl_update(struct fimc_ctx *ctx); -void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f); -void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, +void __fimc_get_format(const struct fimc_frame *frame, struct v4l2_format *f); +void fimc_adjust_mplane_format(const struct fimc_fmt *fmt, u32 width, u32 height, struct v4l2_pix_format_mplane *pix); struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, unsigned int mask, int index); @@ -626,7 +626,7 @@ int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, int fimc_set_scaler_info(struct fimc_ctx *ctx); int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, - struct fimc_frame *frame, struct fimc_addr *addr); + const struct fimc_frame *frame, struct fimc_addr *addr); void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f); void fimc_set_yuv_order(struct fimc_ctx *ctx); void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf); diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c index 95165a2cc7d1..f20fb74dd0c6 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c @@ -526,7 +526,7 @@ void fimc_hw_set_output_path(struct fimc_ctx *ctx) writel(cfg, dev->regs + FIMC_REG_CISCCTRL); } -void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *addr) +void fimc_hw_set_input_addr(struct fimc_dev *dev, const struct fimc_addr *addr) { u32 cfg = readl(dev->regs + FIMC_REG_CIREAL_ISIZE); cfg |= FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS; @@ -541,7 +541,7 @@ void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *addr) } void fimc_hw_set_output_addr(struct fimc_dev *dev, - struct fimc_addr *addr, int index) + const struct fimc_addr *addr, int index) { int i = (index == -1) ? 0 : index; do { @@ -554,7 +554,7 @@ void fimc_hw_set_output_addr(struct fimc_dev *dev, } int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, - struct fimc_source_info *cam) + const struct fimc_source_info *cam) { u32 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL); @@ -648,7 +648,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc, return 0; } -void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f) +void fimc_hw_set_camera_offset(struct fimc_dev *fimc, const struct fimc_frame *f) { u32 hoff2, voff2; @@ -668,7 +668,7 @@ void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f) } int fimc_hw_set_camera_type(struct fimc_dev *fimc, - struct fimc_source_info *source) + const struct fimc_source_info *source) { struct fimc_vid_cap *vid_cap = &fimc->vid_cap; u32 csis_data_alignment = 32; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.h b/drivers/media/platform/samsung/exynos4-is/fimc-reg.h index b9b33aa1f12f..9714f4309655 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.h @@ -302,16 +302,16 @@ void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx); void fimc_hw_set_in_dma(struct fimc_ctx *ctx); void fimc_hw_set_input_path(struct fimc_ctx *ctx); void fimc_hw_set_output_path(struct fimc_ctx *ctx); -void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *addr); -void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *addr, +void fimc_hw_set_input_addr(struct fimc_dev *fimc, const struct fimc_addr *addr); +void fimc_hw_set_output_addr(struct fimc_dev *fimc, const struct fimc_addr *addr, int index); int fimc_hw_set_camera_source(struct fimc_dev *fimc, struct fimc_source_info *cam); -void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f); +void fimc_hw_set_camera_offset(struct fimc_dev *fimc, const struct fimc_frame *f); int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, - struct fimc_source_info *cam); + const struct fimc_source_info *cam); int fimc_hw_set_camera_type(struct fimc_dev *fimc, - struct fimc_source_info *cam); + const struct fimc_source_info *cam); void fimc_hw_clear_irq(struct fimc_dev *dev); void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on); void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on); From 6b659c7b10e3136286bd696b631667ee42499d0b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:11 +0100 Subject: [PATCH 007/252] media: fimc-is: constify local pointers to fimc_fmt Constify the local variable pointing to "struct fimc_fmt" to annotate the function is not modifying pointed data. This is the easy and obvious step of constifying all "struct fimc_fmt" instances. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-capture.c | 6 +++--- drivers/media/platform/samsung/exynos4-is/fimc-m2m.c | 4 ++-- drivers/media/platform/samsung/exynos4-is/fimc-reg.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c index 05cafba1c728..dde36e5be0c7 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c @@ -343,7 +343,7 @@ static int queue_setup(struct vb2_queue *vq, { struct fimc_ctx *ctx = vq->drv_priv; struct fimc_frame *frame = &ctx->d_frame; - struct fimc_fmt *fmt = frame->fmt; + const struct fimc_fmt *fmt = frame->fmt; unsigned long wh = frame->f_width * frame->f_height; int i; @@ -722,7 +722,7 @@ static int fimc_cap_querycap(struct file *file, void *priv, static int fimc_cap_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM | FMT_FLAGS_M2M, f->index); @@ -1460,7 +1460,7 @@ static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index); if (!fmt) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c index df8e2aa454d8..1918390a2469 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c @@ -237,7 +237,7 @@ static int fimc_m2m_querycap(struct file *file, void *fh, static int fimc_m2m_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type), f->index); @@ -266,7 +266,7 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f) struct fimc_dev *fimc = ctx->fimc_dev; const struct fimc_variant *variant = fimc->variant; struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; u32 max_w, mod_x, mod_y; if (!IS_M2M(f->type)) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c index f20fb74dd0c6..dbc43b703324 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c @@ -168,7 +168,7 @@ void fimc_hw_set_out_dma(struct fimc_ctx *ctx) struct fimc_dev *dev = ctx->fimc_dev; struct fimc_frame *frame = &ctx->d_frame; struct fimc_dma_offset *offset = &frame->dma_offset; - struct fimc_fmt *fmt = frame->fmt; + const struct fimc_fmt *fmt = frame->fmt; u32 cfg; /* Set the input dma offsets. */ From 17b8d951b54c7c62e44e13e64ded642dbef5fd34 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:12 +0100 Subject: [PATCH 008/252] media: fimc-is: constify fimc_formats array Pointers to elements of the static array "fimc_formats" with "struct fimc_fmt" are passed all around to various calls, but all of them do not modify pointed data. Constify the pointers everywhere which at the end allows to make static array "fimc_formats" const itself. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- .../samsung/exynos4-is/fimc-capture.c | 26 +++++++++---------- .../platform/samsung/exynos4-is/fimc-core.c | 11 ++++---- .../platform/samsung/exynos4-is/fimc-core.h | 9 ++++--- .../platform/samsung/exynos4-is/fimc-m2m.c | 7 ++--- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c index dde36e5be0c7..a3a677a3065f 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c @@ -559,9 +559,9 @@ static const struct v4l2_file_operations fimc_capture_fops = { * Format and crop negotiation helpers */ -static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, - u32 *width, u32 *height, - u32 *code, u32 *fourcc, int pad) +static const struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, + u32 *width, u32 *height, + u32 *code, u32 *fourcc, int pad) { bool rotation = ctx->rotation == 90 || ctx->rotation == 270; struct fimc_dev *fimc = ctx->fimc_dev; @@ -569,8 +569,8 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, const struct fimc_pix_limit *pl = var->pix_limit; struct fimc_frame *dst = &ctx->d_frame; u32 depth, min_w, max_w, min_h, align_h = 3; + const struct fimc_fmt *ffmt; u32 mask = FMT_FLAGS_CAM; - struct fimc_fmt *ffmt; /* Conversion from/to JPEG or User Defined format is not supported */ if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE && @@ -757,7 +757,7 @@ static struct media_entity *fimc_pipeline_get_head(struct media_entity *me) */ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, struct v4l2_mbus_framefmt *tfmt, - struct fimc_fmt **fmt_id, + const struct fimc_fmt **fmt_id, bool set) { struct fimc_dev *fimc = ctx->fimc_dev; @@ -768,8 +768,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx, : V4L2_SUBDEV_FORMAT_TRY, }; struct v4l2_mbus_framefmt *mf = &sfmt.format; + const struct fimc_fmt *ffmt; struct media_entity *me; - struct fimc_fmt *ffmt; struct media_pad *pad; int ret, i = 1; u32 fcc; @@ -903,8 +903,8 @@ static int fimc_cap_g_fmt_mplane(struct file *file, void *fh, */ static int __video_try_or_set_format(struct fimc_dev *fimc, struct v4l2_format *f, bool try, - struct fimc_fmt **inp_fmt, - struct fimc_fmt **out_fmt) + const struct fimc_fmt **inp_fmt, + const struct fimc_fmt **out_fmt) { struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; struct fimc_vid_cap *vc = &fimc->vid_cap; @@ -986,7 +986,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh, struct v4l2_format *f) { struct fimc_dev *fimc = video_drvdata(file); - struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL; + const struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL; return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt); } @@ -1012,7 +1012,7 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc, struct fimc_ctx *ctx = vc->ctx; struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; struct fimc_frame *ff = &ctx->d_frame; - struct fimc_fmt *inp_fmt = NULL; + const struct fimc_fmt *inp_fmt = NULL; int ret, i; if (vb2_is_busy(&fimc->vid_cap.vbq)) @@ -1519,7 +1519,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, struct fimc_vid_cap *vc = &fimc->vid_cap; struct fimc_ctx *ctx = vc->ctx; struct fimc_frame *ff; - struct fimc_fmt *ffmt; + const struct fimc_fmt *ffmt; dbg("pad%d: code: 0x%x, %dx%d", fmt->pad, mf->code, mf->width, mf->height); @@ -1715,9 +1715,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, { struct video_device *vfd = &fimc->vid_cap.ve.vdev; struct vb2_queue *q = &fimc->vid_cap.vbq; - struct fimc_ctx *ctx; struct fimc_vid_cap *vid_cap; - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; + struct fimc_ctx *ctx; int ret = -ENOMEM; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c index 4411b250d7f1..2a881bc770cf 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c @@ -33,7 +33,7 @@ static const char *fimc_clocks[MAX_FIMC_CLOCKS] = { "sclk_fimc", "fimc" }; -static struct fimc_fmt fimc_formats[] = { +static const struct fimc_fmt fimc_formats[] = { { .fourcc = V4L2_PIX_FMT_RGB565, .depth = { 16 }, @@ -180,7 +180,7 @@ static struct fimc_fmt fimc_formats[] = { }, }; -struct fimc_fmt *fimc_get_format(unsigned int index) +const struct fimc_fmt *fimc_get_format(unsigned int index) { if (index >= ARRAY_SIZE(fimc_formats)) return NULL; @@ -752,10 +752,11 @@ void fimc_adjust_mplane_format(const struct fimc_fmt *fmt, u32 width, u32 height * @mask: the color flags to match * @index: offset in the fimc_formats array, ignored if negative */ -struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, - unsigned int mask, int index) +const struct fimc_fmt *fimc_find_format(const u32 *pixelformat, + const u32 *mbus_code, + unsigned int mask, int index) { - struct fimc_fmt *fmt, *def_fmt = NULL; + const struct fimc_fmt *fmt, *def_fmt = NULL; unsigned int i; int id = 0; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.h b/drivers/media/platform/samsung/exynos4-is/fimc-core.h index 261c9aac2f7f..63385152a2ff 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.h @@ -257,7 +257,7 @@ struct fimc_frame { unsigned int bytesperline[VIDEO_MAX_PLANES]; struct fimc_addr addr; struct fimc_dma_offset dma_offset; - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; u8 alpha; }; @@ -617,9 +617,10 @@ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx); void __fimc_get_format(const struct fimc_frame *frame, struct v4l2_format *f); void fimc_adjust_mplane_format(const struct fimc_fmt *fmt, u32 width, u32 height, struct v4l2_pix_format_mplane *pix); -struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code, - unsigned int mask, int index); -struct fimc_fmt *fimc_get_format(unsigned int index); +const struct fimc_fmt *fimc_find_format(const u32 *pixelformat, + const u32 *mbus_code, + unsigned int mask, int index); +const struct fimc_fmt *fimc_get_format(unsigned int index); int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh, int dw, int dh, int rotation); diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c index 1918390a2469..e9023f64cfba 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c @@ -314,7 +314,8 @@ static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh, return fimc_try_fmt_mplane(ctx, f); } -static void __set_frame_format(struct fimc_frame *frame, struct fimc_fmt *fmt, +static void __set_frame_format(struct fimc_frame *frame, + const struct fimc_fmt *fmt, struct v4l2_pix_format_mplane *pixm) { int i; @@ -340,7 +341,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, { struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_dev *fimc = ctx->fimc_dev; - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; struct vb2_queue *vq; struct fimc_frame *frame; int ret; @@ -588,7 +589,7 @@ static int fimc_m2m_set_default_format(struct fimc_ctx *ctx) .sizeimage = 800 * 4 * 600, }, }; - struct fimc_fmt *fmt; + const struct fimc_fmt *fmt; fmt = fimc_find_format(&pixm.pixelformat, NULL, FMT_FLAGS_M2M, 0); if (!fmt) From f157398a2ae98c29f6ad0cbc9269dc0a8a2ef4aa Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:13 +0100 Subject: [PATCH 009/252] media: fimc-is: constify pointers to v4l2_pix_format_mplane In few places functions do not modify pointed "struct v4l2_pix_format_mplane", thus the pointer can point to const data for additional safety and self-documenting intention of the function. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-capture.c | 2 +- drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c | 2 +- drivers/media/platform/samsung/exynos4-is/fimc-m2m.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c index a3a677a3065f..7c2bcd5be933 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c @@ -1010,7 +1010,7 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc, { struct fimc_vid_cap *vc = &fimc->vid_cap; struct fimc_ctx *ctx = vc->ctx; - struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; + const struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; struct fimc_frame *ff = &ctx->d_frame; const struct fimc_fmt *inp_fmt = NULL; int ret, i; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c b/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c index 8fa26969c411..06c4352562b3 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c @@ -40,7 +40,7 @@ static int isp_video_capture_queue_setup(struct vb2_queue *vq, unsigned int sizes[], struct device *alloc_devs[]) { struct fimc_isp *isp = vb2_get_drv_priv(vq); - struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt; + const struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt; const struct fimc_fmt *fmt = isp->video_capture.format; unsigned int wh, i; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c index e9023f64cfba..e5829a457f3d 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c @@ -316,7 +316,7 @@ static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh, static void __set_frame_format(struct fimc_frame *frame, const struct fimc_fmt *fmt, - struct v4l2_pix_format_mplane *pixm) + const struct v4l2_pix_format_mplane *pixm) { int i; From 4303e2063e75a1fe668907ef26770bd1f4f38feb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:14 +0100 Subject: [PATCH 010/252] media: fimc-is: constify local pointers to fimc_dma_offset Constify the local variables pointing to "struct fimc_dma_offset" to annotate the function is not modifying pointed data. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c index dbc43b703324..0ed6e22e6c47 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c @@ -167,7 +167,7 @@ void fimc_hw_set_out_dma(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; struct fimc_frame *frame = &ctx->d_frame; - struct fimc_dma_offset *offset = &frame->dma_offset; + const struct fimc_dma_offset *offset = &frame->dma_offset; const struct fimc_fmt *fmt = frame->fmt; u32 cfg; @@ -421,7 +421,7 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; struct fimc_frame *frame = &ctx->s_frame; - struct fimc_dma_offset *offset = &frame->dma_offset; + const struct fimc_dma_offset *offset = &frame->dma_offset; u32 cfg; /* Set the pixel offsets. */ From 7d441e29896bf82c225e3743698430335b94ef4e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:15 +0100 Subject: [PATCH 011/252] media: fimc-is: constify local pointers to fimc_vid_cap Constify the local variables pointing to "struct fimc_vid_cap" to annotate the function is not modifying pointed data. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c index 0ed6e22e6c47..edff6e5179cf 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c @@ -598,7 +598,7 @@ static const struct mbus_pixfmt_desc pix_desc[] = { int fimc_hw_set_camera_source(struct fimc_dev *fimc, struct fimc_source_info *source) { - struct fimc_vid_cap *vc = &fimc->vid_cap; + const struct fimc_vid_cap *vc = &fimc->vid_cap; struct fimc_frame *f = &vc->ctx->s_frame; u32 bus_width, cfg = 0; int i; @@ -670,7 +670,7 @@ void fimc_hw_set_camera_offset(struct fimc_dev *fimc, const struct fimc_frame *f int fimc_hw_set_camera_type(struct fimc_dev *fimc, const struct fimc_source_info *source) { - struct fimc_vid_cap *vid_cap = &fimc->vid_cap; + const struct fimc_vid_cap *vid_cap = &fimc->vid_cap; u32 csis_data_alignment = 32; u32 cfg, tmp; From 12273a3295524afa50d5b6cd396b5ee23e7c96b6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 12:49:16 +0100 Subject: [PATCH 012/252] media: fimc-is: constify local pointers to fimc_frame Constify the local variables pointing to "struct fimc_frame" to annotate the function is not modifying pointed data. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- .../platform/samsung/exynos4-is/fimc-capture.c | 18 +++++++++--------- .../platform/samsung/exynos4-is/fimc-core.c | 4 ++-- .../platform/samsung/exynos4-is/fimc-m2m.c | 10 +++++----- .../platform/samsung/exynos4-is/fimc-reg.c | 18 +++++++++--------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c index 7c2bcd5be933..ffa4ea21387d 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c @@ -180,7 +180,7 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf) struct fimc_vid_cap *cap = &fimc->vid_cap; struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe); struct v4l2_subdev *csis = p->subdevs[IDX_CSIS]; - struct fimc_frame *f = &cap->ctx->d_frame; + const struct fimc_frame *f = &cap->ctx->d_frame; struct fimc_vid_buffer *v_buf; if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) { @@ -342,7 +342,7 @@ static int queue_setup(struct vb2_queue *vq, unsigned int sizes[], struct device *alloc_devs[]) { struct fimc_ctx *ctx = vq->drv_priv; - struct fimc_frame *frame = &ctx->d_frame; + const struct fimc_frame *frame = &ctx->d_frame; const struct fimc_fmt *fmt = frame->fmt; unsigned long wh = frame->f_width * frame->f_height; int i; @@ -567,7 +567,7 @@ static const struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, struct fimc_dev *fimc = ctx->fimc_dev; const struct fimc_variant *var = fimc->variant; const struct fimc_pix_limit *pl = var->pix_limit; - struct fimc_frame *dst = &ctx->d_frame; + const struct fimc_frame *dst = &ctx->d_frame; u32 depth, min_w, max_w, min_h, align_h = 3; const struct fimc_fmt *ffmt; u32 mask = FMT_FLAGS_CAM; @@ -644,7 +644,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx, struct fimc_dev *fimc = ctx->fimc_dev; const struct fimc_variant *var = fimc->variant; const struct fimc_pix_limit *pl = var->pix_limit; - struct fimc_frame *sink = &ctx->s_frame; + const struct fimc_frame *sink = &ctx->s_frame; u32 max_w, max_h, min_w = 0, min_h = 0, min_sz; u32 align_sz = 0, align_h = 4; u32 max_sc_h, max_sc_v; @@ -1132,7 +1132,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) /* Don't call FIMC subdev operation to avoid nested locking */ if (sd == &vc->subdev) { - struct fimc_frame *ff = &vc->ctx->s_frame; + const struct fimc_frame *ff = &vc->ctx->s_frame; sink_fmt.format.width = ff->f_width; sink_fmt.format.height = ff->f_height; sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0; @@ -1158,7 +1158,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) if (sd == p->subdevs[IDX_SENSOR] && fimc_user_defined_mbus_fmt(src_fmt.format.code)) { struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES]; - struct fimc_frame *frame = &vc->ctx->d_frame; + const struct fimc_frame *frame = &vc->ctx->d_frame; unsigned int i; ret = fimc_get_sensor_frame_desc(sd, plane_fmt, @@ -1263,7 +1263,7 @@ static int fimc_cap_g_selection(struct file *file, void *fh, { struct fimc_dev *fimc = video_drvdata(file); struct fimc_ctx *ctx = fimc->vid_cap.ctx; - struct fimc_frame *f = &ctx->s_frame; + const struct fimc_frame *f = &ctx->s_frame; if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1475,7 +1475,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, { struct fimc_dev *fimc = v4l2_get_subdevdata(sd); struct fimc_ctx *ctx = fimc->vid_cap.ctx; - struct fimc_frame *ff = &ctx->s_frame; + const struct fimc_frame *ff = &ctx->s_frame; struct v4l2_mbus_framefmt *mf; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { @@ -1582,7 +1582,7 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, { struct fimc_dev *fimc = v4l2_get_subdevdata(sd); struct fimc_ctx *ctx = fimc->vid_cap.ctx; - struct fimc_frame *f = &ctx->s_frame; + const struct fimc_frame *f = &ctx->s_frame; struct v4l2_rect *r = &sel->r; struct v4l2_rect *try_sel; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c index 2a881bc770cf..aae74b501a42 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c @@ -228,8 +228,8 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx) const struct fimc_variant *variant = ctx->fimc_dev->variant; struct device *dev = &ctx->fimc_dev->pdev->dev; struct fimc_scaler *sc = &ctx->scaler; - struct fimc_frame *s_frame = &ctx->s_frame; - struct fimc_frame *d_frame = &ctx->d_frame; + const struct fimc_frame *s_frame = &ctx->s_frame; + const struct fimc_frame *d_frame = &ctx->d_frame; int tx, ty, sx, sy; int ret; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c index e5829a457f3d..199997eec1cc 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c @@ -170,7 +170,7 @@ static int fimc_queue_setup(struct vb2_queue *vq, unsigned int sizes[], struct device *alloc_devs[]) { struct fimc_ctx *ctx = vb2_get_drv_priv(vq); - struct fimc_frame *f; + const struct fimc_frame *f; int i; f = ctx_get_frame(ctx, vq->type); @@ -192,7 +192,7 @@ static int fimc_queue_setup(struct vb2_queue *vq, static int fimc_buf_prepare(struct vb2_buffer *vb) { struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct fimc_frame *frame; + const struct fimc_frame *frame; int i; frame = ctx_get_frame(ctx, vb->vb2_queue->type); @@ -252,7 +252,7 @@ static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh, struct v4l2_format *f) { struct fimc_ctx *ctx = fh_to_ctx(fh); - struct fimc_frame *frame = ctx_get_frame(ctx, f->type); + const struct fimc_frame *frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) return PTR_ERR(frame); @@ -379,7 +379,7 @@ static int fimc_m2m_g_selection(struct file *file, void *fh, struct v4l2_selection *s) { struct fimc_ctx *ctx = fh_to_ctx(fh); - struct fimc_frame *frame; + const struct fimc_frame *frame; frame = ctx_get_frame(ctx, s->type); if (IS_ERR(frame)) @@ -429,7 +429,7 @@ static int fimc_m2m_try_selection(struct fimc_ctx *ctx, struct v4l2_selection *s) { struct fimc_dev *fimc = ctx->fimc_dev; - struct fimc_frame *f; + const struct fimc_frame *f; u32 min_size, halign, depth = 0; int i; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c index edff6e5179cf..b4ee39e471e7 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c @@ -105,7 +105,7 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx) { u32 cfg; struct fimc_dev *dev = ctx->fimc_dev; - struct fimc_frame *frame = &ctx->d_frame; + const struct fimc_frame *frame = &ctx->d_frame; dbg("w= %d, h= %d color: %d", frame->width, frame->height, frame->fmt->color); @@ -147,7 +147,7 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx) static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; - struct fimc_frame *frame = &ctx->d_frame; + const struct fimc_frame *frame = &ctx->d_frame; u32 cfg; cfg = (frame->f_height << 16) | frame->f_width; @@ -166,7 +166,7 @@ static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx) void fimc_hw_set_out_dma(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; - struct fimc_frame *frame = &ctx->d_frame; + const struct fimc_frame *frame = &ctx->d_frame; const struct fimc_dma_offset *offset = &frame->dma_offset; const struct fimc_fmt *fmt = frame->fmt; u32 cfg; @@ -248,8 +248,8 @@ static void fimc_hw_set_scaler(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; struct fimc_scaler *sc = &ctx->scaler; - struct fimc_frame *src_frame = &ctx->s_frame; - struct fimc_frame *dst_frame = &ctx->d_frame; + const struct fimc_frame *src_frame = &ctx->s_frame; + const struct fimc_frame *dst_frame = &ctx->d_frame; u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL); @@ -388,7 +388,7 @@ void fimc_hw_set_effect(struct fimc_ctx *ctx) void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; - struct fimc_frame *frame = &ctx->d_frame; + const struct fimc_frame *frame = &ctx->d_frame; u32 cfg; if (!(frame->fmt->flags & FMT_HAS_ALPHA)) @@ -403,7 +403,7 @@ void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx) static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; - struct fimc_frame *frame = &ctx->s_frame; + const struct fimc_frame *frame = &ctx->s_frame; u32 cfg_o = 0; u32 cfg_r = 0; @@ -420,7 +420,7 @@ static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx) void fimc_hw_set_in_dma(struct fimc_ctx *ctx) { struct fimc_dev *dev = ctx->fimc_dev; - struct fimc_frame *frame = &ctx->s_frame; + const struct fimc_frame *frame = &ctx->s_frame; const struct fimc_dma_offset *offset = &frame->dma_offset; u32 cfg; @@ -599,7 +599,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc, struct fimc_source_info *source) { const struct fimc_vid_cap *vc = &fimc->vid_cap; - struct fimc_frame *f = &vc->ctx->s_frame; + const struct fimc_frame *f = &vc->ctx->s_frame; u32 bus_width, cfg = 0; int i; From 8798f1a8e0cc5dc343a79a90fb0d8bbc55ba834d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:00 +0100 Subject: [PATCH 013/252] media: s5p-mfc: drop unused static s5p_mfc_cmds File-scope static variable "s5p_mfc_cmds" is not read after assignment, thus it can be dropped entirely. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c index 774c573dc075..196d8c99647b 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c @@ -12,14 +12,10 @@ #include "s5p_mfc_cmd_v5.h" #include "s5p_mfc_cmd_v6.h" -static struct s5p_mfc_hw_cmds *s5p_mfc_cmds; - void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev) { if (IS_MFCV6_PLUS(dev)) - s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v6(); + dev->mfc_cmds = s5p_mfc_init_hw_cmds_v6(); else - s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5(); - - dev->mfc_cmds = s5p_mfc_cmds; + dev->mfc_cmds = s5p_mfc_init_hw_cmds_v5(); } From 36588ba3a3dfd3c453c711479efbe5deaad8d068 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:01 +0100 Subject: [PATCH 014/252] media: s5p-mfc: drop unused static s5p_mfc_ops File-scope static variable "s5p_mfc_ops" is not read after assignment, thus it can be dropped entirely. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c index 673962301173..5ba791fa3676 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c @@ -14,18 +14,15 @@ #include "s5p_mfc_opr_v5.h" #include "s5p_mfc_opr_v6.h" -static struct s5p_mfc_hw_ops *s5p_mfc_ops; - void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev) { if (IS_MFCV6_PLUS(dev)) { - s5p_mfc_ops = s5p_mfc_init_hw_ops_v6(); + dev->mfc_ops = s5p_mfc_init_hw_ops_v6(); dev->warn_start = S5P_FIMV_ERR_WARNINGS_START_V6; } else { - s5p_mfc_ops = s5p_mfc_init_hw_ops_v5(); + dev->mfc_ops = s5p_mfc_init_hw_ops_v5(); dev->warn_start = S5P_FIMV_ERR_WARNINGS_START; } - dev->mfc_ops = s5p_mfc_ops; } void s5p_mfc_init_regs(struct s5p_mfc_dev *dev) From e12dcb89e8aa27ed3330ee78e64e9ab1242fe07b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:02 +0100 Subject: [PATCH 015/252] media: s5p-mfc: drop unused get_*_def_fmt declarations get_dec_def_fmt() and get_enc_def_fmt() do not have definitions, so their declarations are pointless. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h | 1 - drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h index 0c52ab46cff7..d4310966a0c2 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h @@ -12,7 +12,6 @@ const struct s5p_mfc_codec_ops *get_dec_codec_ops(void); struct vb2_ops *get_dec_queue_ops(void); const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void); -struct s5p_mfc_fmt *get_dec_def_fmt(bool src); int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx); void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx); void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx); diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h index 3f1b1a037a4f..0cf08b8d40ff 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h @@ -12,7 +12,6 @@ const struct s5p_mfc_codec_ops *get_enc_codec_ops(void); struct vb2_ops *get_enc_queue_ops(void); const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void); -struct s5p_mfc_fmt *get_enc_def_fmt(bool src); int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx); void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx); void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx); From dd761d3cf4d518db197c8e03e3447ddfdccdb27e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:03 +0100 Subject: [PATCH 016/252] media: s5p-mfc: constify fw_name strings Constify stored pointers to firmware names for code safety. These are not modified by the driver. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h index 59450b324f7d..cd4361ac6d5d 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h @@ -229,7 +229,7 @@ struct s5p_mfc_variant { unsigned int port_num; u32 version_bit; struct s5p_mfc_buf_size *buf_size; - char *fw_name[MFC_FW_MAX_VERSIONS]; + const char *fw_name[MFC_FW_MAX_VERSIONS]; const char *clk_names[MFC_MAX_CLOCKS]; int num_clocks; bool use_clock_gating; From e8cc4c0bc2a660fed4ad57be6635d88ccc490a05 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:04 +0100 Subject: [PATCH 017/252] media: s5p-mfc: constify s5p_mfc_buf_size structures Static "s5p_mfc_buf_size*" structures are not modified by the driver, so they can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- .../media/platform/samsung/s5p-mfc/s5p_mfc.c | 20 +++++++++---------- .../platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c | 2 +- .../platform/samsung/s5p-mfc/s5p_mfc_common.h | 4 ++-- .../platform/samsung/s5p-mfc/s5p_mfc_dec.c | 2 +- .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c | 6 +++--- .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c index fbb047eadf5a..2af166b84f7d 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c @@ -1520,14 +1520,14 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(s5p_mfc_suspend, s5p_mfc_resume) }; -static struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = { +static const struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = { .h264_ctx = MFC_H264_CTX_BUF_SIZE, .non_h264_ctx = MFC_CTX_BUF_SIZE, .dsc = DESC_BUF_SIZE, .shm = SHARED_BUF_SIZE, }; -static struct s5p_mfc_buf_size buf_size_v5 = { +static const struct s5p_mfc_buf_size buf_size_v5 = { .fw = MAX_FW_SIZE, .cpb = MAX_CPB_SIZE, .priv = &mfc_buf_size_v5, @@ -1544,7 +1544,7 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = { .use_clock_gating = true, }; -static struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = { +static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = { .dev_ctx = MFC_CTX_BUF_SIZE_V6, .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V6, .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V6, @@ -1552,7 +1552,7 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = { .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V6, }; -static struct s5p_mfc_buf_size buf_size_v6 = { +static const struct s5p_mfc_buf_size buf_size_v6 = { .fw = MAX_FW_SIZE_V6, .cpb = MAX_CPB_SIZE_V6, .priv = &mfc_buf_size_v6, @@ -1573,7 +1573,7 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = { .num_clocks = 1, }; -static struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = { +static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = { .dev_ctx = MFC_CTX_BUF_SIZE_V7, .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V7, .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V7, @@ -1581,7 +1581,7 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = { .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V7, }; -static struct s5p_mfc_buf_size buf_size_v7 = { +static const struct s5p_mfc_buf_size buf_size_v7 = { .fw = MAX_FW_SIZE_V7, .cpb = MAX_CPB_SIZE_V7, .priv = &mfc_buf_size_v7, @@ -1607,7 +1607,7 @@ static struct s5p_mfc_variant mfc_drvdata_v7_3250 = { .num_clocks = 2, }; -static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = { +static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = { .dev_ctx = MFC_CTX_BUF_SIZE_V8, .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V8, .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V8, @@ -1615,7 +1615,7 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = { .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V8, }; -static struct s5p_mfc_buf_size buf_size_v8 = { +static const struct s5p_mfc_buf_size buf_size_v8 = { .fw = MAX_FW_SIZE_V8, .cpb = MAX_CPB_SIZE_V8, .priv = &mfc_buf_size_v8, @@ -1641,7 +1641,7 @@ static struct s5p_mfc_variant mfc_drvdata_v8_5433 = { .num_clocks = 3, }; -static struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = { +static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = { .dev_ctx = MFC_CTX_BUF_SIZE_V10, .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V10, .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V10, @@ -1650,7 +1650,7 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = { .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V10, }; -static struct s5p_mfc_buf_size buf_size_v10 = { +static const struct s5p_mfc_buf_size buf_size_v10 = { .fw = MAX_FW_SIZE_V10, .cpb = MAX_CPB_SIZE_V10, .priv = &mfc_buf_size_v10, diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c index f8588e52dfc8..25c4719a5dd0 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c @@ -32,7 +32,7 @@ static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd, static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev) { struct s5p_mfc_cmd_args h2r_args; - struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; + const struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; int ret; ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_dev_context_buffer, dev); diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h index cd4361ac6d5d..77ebceeb65e8 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h @@ -221,14 +221,14 @@ struct s5p_mfc_buf_size_v6 { struct s5p_mfc_buf_size { unsigned int fw; unsigned int cpb; - void *priv; + const void *priv; }; struct s5p_mfc_variant { unsigned int version; unsigned int port_num; u32 version_bit; - struct s5p_mfc_buf_size *buf_size; + const struct s5p_mfc_buf_size *buf_size; const char *fw_name[MFC_FW_MAX_VERSIONS]; const char *clk_names[MFC_MAX_CLOCKS]; int num_clocks; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c index 3957f28d4547..ad7a868af6c3 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c @@ -445,7 +445,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); int ret = 0; struct v4l2_pix_format_mplane *pix_mp; - struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; + const struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; mfc_debug_enter(); ret = vidioc_try_fmt(file, priv, f); diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c index fcfaf125a5a1..37293e833b62 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c @@ -34,7 +34,7 @@ static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; + const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; int ret; ctx->dsc.size = buf_size->dsc; @@ -200,7 +200,7 @@ static void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx) static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; + const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; int ret; if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || @@ -345,7 +345,7 @@ static void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx) static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; + const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR); mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE); diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c index fd945211d28e..2573f101838c 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c @@ -383,7 +383,7 @@ static void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx) static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; + const struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; int ret; mfc_debug_enter(); @@ -443,7 +443,7 @@ static void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx) /* Allocate context buffers for SYS_INIT */ static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev) { - struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; + const struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; int ret; mfc_debug_enter(); @@ -587,7 +587,7 @@ static int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, { struct s5p_mfc_dev *dev = ctx->dev; const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; - struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; + const struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; mfc_debug_enter(); mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n" From 5451bbd3e3683ce171358124b52ed64b925cfb07 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:05 +0100 Subject: [PATCH 018/252] media: s5p-mfc: constify s5p_mfc_variant structures Static "s5p_mfc_variant" structures are not modified by the driver, so they can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c index 2af166b84f7d..910f195ac686 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c @@ -1533,7 +1533,7 @@ static const struct s5p_mfc_buf_size buf_size_v5 = { .priv = &mfc_buf_size_v5, }; -static struct s5p_mfc_variant mfc_drvdata_v5 = { +static const struct s5p_mfc_variant mfc_drvdata_v5 = { .version = MFC_VERSION, .version_bit = MFC_V5_BIT, .port_num = MFC_NUM_PORTS, @@ -1558,7 +1558,7 @@ static const struct s5p_mfc_buf_size buf_size_v6 = { .priv = &mfc_buf_size_v6, }; -static struct s5p_mfc_variant mfc_drvdata_v6 = { +static const struct s5p_mfc_variant mfc_drvdata_v6 = { .version = MFC_VERSION_V6, .version_bit = MFC_V6_BIT, .port_num = MFC_NUM_PORTS_V6, @@ -1587,7 +1587,7 @@ static const struct s5p_mfc_buf_size buf_size_v7 = { .priv = &mfc_buf_size_v7, }; -static struct s5p_mfc_variant mfc_drvdata_v7 = { +static const struct s5p_mfc_variant mfc_drvdata_v7 = { .version = MFC_VERSION_V7, .version_bit = MFC_V7_BIT, .port_num = MFC_NUM_PORTS_V7, @@ -1597,7 +1597,7 @@ static struct s5p_mfc_variant mfc_drvdata_v7 = { .num_clocks = 1, }; -static struct s5p_mfc_variant mfc_drvdata_v7_3250 = { +static const struct s5p_mfc_variant mfc_drvdata_v7_3250 = { .version = MFC_VERSION_V7, .version_bit = MFC_V7_BIT, .port_num = MFC_NUM_PORTS_V7, @@ -1621,7 +1621,7 @@ static const struct s5p_mfc_buf_size buf_size_v8 = { .priv = &mfc_buf_size_v8, }; -static struct s5p_mfc_variant mfc_drvdata_v8 = { +static const struct s5p_mfc_variant mfc_drvdata_v8 = { .version = MFC_VERSION_V8, .version_bit = MFC_V8_BIT, .port_num = MFC_NUM_PORTS_V8, @@ -1631,7 +1631,7 @@ static struct s5p_mfc_variant mfc_drvdata_v8 = { .num_clocks = 1, }; -static struct s5p_mfc_variant mfc_drvdata_v8_5433 = { +static const struct s5p_mfc_variant mfc_drvdata_v8_5433 = { .version = MFC_VERSION_V8, .version_bit = MFC_V8_BIT, .port_num = MFC_NUM_PORTS_V8, @@ -1656,7 +1656,7 @@ static const struct s5p_mfc_buf_size buf_size_v10 = { .priv = &mfc_buf_size_v10, }; -static struct s5p_mfc_variant mfc_drvdata_v10 = { +static const struct s5p_mfc_variant mfc_drvdata_v10 = { .version = MFC_VERSION_V10, .version_bit = MFC_V10_BIT, .port_num = MFC_NUM_PORTS_V10, From c76c43d77869adc1709693ba532fe7fb4f30aa45 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:06 +0100 Subject: [PATCH 019/252] media: s5p-mfc: constify s5p_mfc_hw_cmds structures Static "s5p_mfc_hw_cmds" structures are not modified by the driver, so they can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c | 4 ++-- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h | 2 +- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c | 4 ++-- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h | 2 +- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c index 327e54e70611..1fbf7ed5d4cc 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c @@ -148,7 +148,7 @@ static int s5p_mfc_close_inst_cmd_v5(struct s5p_mfc_ctx *ctx) } /* Initialize cmd function pointers for MFC v5 */ -static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = { +static const struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = { .cmd_host2risc = s5p_mfc_cmd_host2risc_v5, .sys_init_cmd = s5p_mfc_sys_init_cmd_v5, .sleep_cmd = s5p_mfc_sleep_cmd_v5, @@ -157,7 +157,7 @@ static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = { .close_inst_cmd = s5p_mfc_close_inst_cmd_v5, }; -struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void) +const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void) { return &s5p_mfc_cmds_v5; } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h index 6eafa514aebc..c626376053c4 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h @@ -11,6 +11,6 @@ #include "s5p_mfc_common.h" -struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void); +const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void); #endif /* S5P_MFC_CMD_H_ */ diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c index 25c4719a5dd0..740aa4dfae57 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c @@ -154,7 +154,7 @@ static int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx) } /* Initialize cmd function pointers for MFC v6 */ -static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = { +static const struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = { .cmd_host2risc = s5p_mfc_cmd_host2risc_v6, .sys_init_cmd = s5p_mfc_sys_init_cmd_v6, .sleep_cmd = s5p_mfc_sleep_cmd_v6, @@ -163,7 +163,7 @@ static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = { .close_inst_cmd = s5p_mfc_close_inst_cmd_v6, }; -struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void) +const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void) { return &s5p_mfc_cmds_v6; } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h index 9dc44460cc38..29083436f517 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h @@ -11,6 +11,6 @@ #include "s5p_mfc_common.h" -struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void); +const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void); #endif /* S5P_MFC_CMD_H_ */ diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h index 77ebceeb65e8..fd43c58848d4 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h @@ -341,7 +341,7 @@ struct s5p_mfc_dev { struct s5p_mfc_priv_buf ctx_buf; int warn_start; struct s5p_mfc_hw_ops *mfc_ops; - struct s5p_mfc_hw_cmds *mfc_cmds; + const struct s5p_mfc_hw_cmds *mfc_cmds; const struct s5p_mfc_regs *mfc_regs; enum s5p_mfc_fw_ver fw_ver; bool fw_get_done; From f0015b196ba495600c62ae659f99525cad132b4d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:07 +0100 Subject: [PATCH 020/252] media: s5p-mfc: constify s5p_mfc_hw_ops structures Static "s5p_mfc_hw_ops" structures are not modified by the driver, so they can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h | 2 +- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c | 4 ++-- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h | 2 +- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 4 ++-- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h index fd43c58848d4..4457dacc3c9c 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h @@ -340,7 +340,7 @@ struct s5p_mfc_dev { struct s5p_mfc_priv_buf ctx_buf; int warn_start; - struct s5p_mfc_hw_ops *mfc_ops; + const struct s5p_mfc_hw_ops *mfc_ops; const struct s5p_mfc_hw_cmds *mfc_cmds; const struct s5p_mfc_regs *mfc_regs; enum s5p_mfc_fw_ver fw_ver; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c index 37293e833b62..7a322c80f7c1 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c @@ -1593,7 +1593,7 @@ static unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx) } /* Initialize opr function pointers for MFC v5 */ -static struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = { +static const struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = { .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v5, .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v5, .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v5, @@ -1633,7 +1633,7 @@ static struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = { .get_crop_info_v = s5p_mfc_get_crop_info_v_v5, }; -struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void) +const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void) { return &s5p_mfc_ops_v5; } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h index b53d376ead60..0b98c619676e 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h @@ -78,5 +78,5 @@ enum MFC_SHM_OFS { FRAME_PACK_SEI_INFO = 0x17c, /* E */ }; -struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void); +const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void); #endif /* S5P_MFC_OPR_H_ */ diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c index 2573f101838c..07a999bd127f 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c @@ -2657,7 +2657,7 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) } /* Initialize opr function pointers for MFC v6 */ -static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = { +static const struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = { .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v6, .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v6, .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v6, @@ -2701,7 +2701,7 @@ static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = { .get_e_min_scratch_buf_size = s5p_mfc_get_e_min_scratch_buf_size, }; -struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void) +const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void) { return &s5p_mfc_ops_v6; } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h index 94ecb0e6e7c7..7fc1307675d8 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h @@ -51,6 +51,6 @@ #define FRAME_DELTA_DEFAULT 1 -struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void); +const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void); const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev); #endif /* S5P_MFC_OPR_V6_H_ */ From 028111b3d822e6552bde52a10ea24c7f074b2acf Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:08 +0100 Subject: [PATCH 021/252] media: s5p-mfc: constify s5p_mfc_fmt structures Static "s5p_mfc_fmt" structures are not modified by the driver, so they can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h | 4 ++-- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c | 6 +++--- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h index 4457dacc3c9c..0f6e260746c9 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h @@ -639,8 +639,8 @@ struct s5p_mfc_ctx { unsigned int int_err; wait_queue_head_t queue; - struct s5p_mfc_fmt *src_fmt; - struct s5p_mfc_fmt *dst_fmt; + const struct s5p_mfc_fmt *src_fmt; + const struct s5p_mfc_fmt *dst_fmt; struct vb2_queue vq_src; struct vb2_queue vq_dst; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c index ad7a868af6c3..b25ac2c89ff5 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c @@ -27,7 +27,7 @@ #include "s5p_mfc_opr.h" #include "s5p_mfc_pm.h" -static struct s5p_mfc_fmt formats[] = { +static const struct s5p_mfc_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_NV12MT_16X16, .codec_mode = S5P_MFC_CODEC_NONE, @@ -177,7 +177,7 @@ static struct s5p_mfc_fmt formats[] = { #define NUM_FORMATS ARRAY_SIZE(formats) /* Find selected format description */ -static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t) +static const struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t) { unsigned int i; @@ -406,7 +406,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) { struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_fmt *fmt; + const struct s5p_mfc_fmt *fmt; mfc_debug(2, "Type is %d\n", f->type); if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c index ef8bb40b9712..abc8fdeab305 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c @@ -30,7 +30,7 @@ #define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12M #define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264 -static struct s5p_mfc_fmt formats[] = { +static const struct s5p_mfc_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_NV12MT_16X16, .codec_mode = S5P_MFC_CODEC_NONE, @@ -111,7 +111,7 @@ static struct s5p_mfc_fmt formats[] = { }; #define NUM_FORMATS ARRAY_SIZE(formats) -static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t) +static const struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t) { unsigned int i; @@ -1431,7 +1431,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) { struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_fmt *fmt; + const struct s5p_mfc_fmt *fmt; struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -2392,7 +2392,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb) +static int check_vb_with_fmt(const struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb) { int i; From 4b9f9109690f6263c75693e1a5759abf86a0f7ce Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:09 +0100 Subject: [PATCH 022/252] media: s5p-mfc: constify struct structures Static "struct" structures are not modified by the driver, so they can be made const for code safety. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c | 4 ++-- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h | 2 +- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c | 4 ++-- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c index b25ac2c89ff5..345734a13d26 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c @@ -1159,7 +1159,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb) s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); } -static struct vb2_ops s5p_mfc_dec_qops = { +static const struct vb2_ops s5p_mfc_dec_qops = { .queue_setup = s5p_mfc_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, @@ -1174,7 +1174,7 @@ const struct s5p_mfc_codec_ops *get_dec_codec_ops(void) return &decoder_codec_ops; } -struct vb2_ops *get_dec_queue_ops(void) +const struct vb2_ops *get_dec_queue_ops(void) { return &s5p_mfc_dec_qops; } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h index d4310966a0c2..47a6eb9a8fc0 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h @@ -10,7 +10,7 @@ #define S5P_MFC_DEC_H_ const struct s5p_mfc_codec_ops *get_dec_codec_ops(void); -struct vb2_ops *get_dec_queue_ops(void); +const struct vb2_ops *get_dec_queue_ops(void); const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void); int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx); void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx); diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c index abc8fdeab305..81cbb36fb382 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c @@ -2650,7 +2650,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb) s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); } -static struct vb2_ops s5p_mfc_enc_qops = { +static const struct vb2_ops s5p_mfc_enc_qops = { .queue_setup = s5p_mfc_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, @@ -2666,7 +2666,7 @@ const struct s5p_mfc_codec_ops *get_enc_codec_ops(void) return &encoder_codec_ops; } -struct vb2_ops *get_enc_queue_ops(void) +const struct vb2_ops *get_enc_queue_ops(void) { return &s5p_mfc_enc_qops; } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h index 0cf08b8d40ff..62d6db67fd91 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h @@ -10,7 +10,7 @@ #define S5P_MFC_ENC_H_ const struct s5p_mfc_codec_ops *get_enc_codec_ops(void); -struct vb2_ops *get_enc_queue_ops(void); +const struct vb2_ops *get_enc_queue_ops(void); const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void); int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx); void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx); From 60a2a86fb8277ba2b8d26cd49222e92fea36a196 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:10 +0100 Subject: [PATCH 023/252] media: s5p-mfc: constify pointers to s5p_mfc_cmd_args In few places functions do not modify pointed "struct s5p_mfc_cmd_args", thus the pointer can point to const data for additional safety and self-documenting intention of the function. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h | 2 +- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c | 2 +- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h index 945d12fdceb7..172c5a63b58e 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h @@ -19,7 +19,7 @@ struct s5p_mfc_cmd_args { struct s5p_mfc_hw_cmds { int (*cmd_host2risc)(struct s5p_mfc_dev *dev, int cmd, - struct s5p_mfc_cmd_args *args); + const struct s5p_mfc_cmd_args *args); int (*sys_init_cmd)(struct s5p_mfc_dev *dev); int (*sleep_cmd)(struct s5p_mfc_dev *dev); int (*wakeup_cmd)(struct s5p_mfc_dev *dev); diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c index 1fbf7ed5d4cc..82ee6d300c73 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c @@ -14,7 +14,7 @@ /* This function is used to send a command to the MFC */ static int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd, - struct s5p_mfc_cmd_args *args) + const struct s5p_mfc_cmd_args *args) { int cur_cmd; unsigned long timeout; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c index 740aa4dfae57..47bc3014b5d8 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c @@ -15,7 +15,7 @@ #include "s5p_mfc_cmd_v6.h" static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd, - struct s5p_mfc_cmd_args *args) + const struct s5p_mfc_cmd_args *args) { mfc_debug(2, "Issue the command: %d\n", cmd); From 362af7abbfba9b36fc622f9d7bb96e2921832f2c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:11 +0100 Subject: [PATCH 024/252] media: s5p-mfc: constify local pointers to s5p_mfc_enc_params Constify the local variables pointing to "struct s5p_mfc_enc_params" and other encoding params to annotate the function is not modifying pointed data. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c | 14 +++++++------- .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c index 7a322c80f7c1..7dee61c8c0b6 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c @@ -676,7 +676,7 @@ static int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx) static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; unsigned int reg; unsigned int shm; @@ -759,8 +759,8 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264; unsigned int reg; unsigned int shm; @@ -916,8 +916,8 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; unsigned int reg; unsigned int shm; unsigned int framerate; @@ -995,8 +995,8 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; unsigned int reg; unsigned int shm; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c index 07a999bd127f..923d4b40dd67 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c @@ -863,7 +863,7 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; - struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; unsigned int reg = 0; mfc_debug_enter(); @@ -1349,8 +1349,8 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; unsigned int reg = 0; mfc_debug_enter(); @@ -1431,8 +1431,8 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; unsigned int reg = 0; mfc_debug_enter(); @@ -1501,8 +1501,8 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8; unsigned int reg = 0; unsigned int val = 0; @@ -1897,8 +1897,8 @@ static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; - struct s5p_mfc_enc_params *p = &ctx->enc_params; - struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; + const struct s5p_mfc_enc_params *p = &ctx->enc_params; + const struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; int i; if (p_h264->aso) { From 6b1e2e04b4515aa37e5fce529de975632f302819 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:12 +0100 Subject: [PATCH 025/252] media: s5p-mfc: drop useless clock refcnt debugging Drop useless debugging of clock enabl/disable counts, because core handles this much better. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c index 187849841a28..29b141d4a7a7 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c @@ -16,7 +16,6 @@ static struct s5p_mfc_pm *pm; static struct s5p_mfc_dev *p_dev; -static atomic_t clk_ref; int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) { @@ -49,7 +48,6 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) pm->clock_gate = pm->clocks[0]; pm_runtime_enable(pm->device); - atomic_set(&clk_ref, 0); return 0; } @@ -60,17 +58,11 @@ void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) int s5p_mfc_clock_on(void) { - atomic_inc(&clk_ref); - mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); - return clk_enable(pm->clock_gate); } void s5p_mfc_clock_off(void) { - atomic_dec(&clk_ref); - mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); - clk_disable(pm->clock_gate); } From 9e1b5ab82171cb30b79e0fdb75f5d9612c686c53 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:13 +0100 Subject: [PATCH 026/252] media: s5p-mfc: drop useless static s5p_mfc_dev in s5p_mfc_pm.c Pointer "struct s5p_mfc_dev" is stored in s5p_mfc_pm.c once and never used again. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c index 29b141d4a7a7..ecb3065c33c9 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c @@ -15,15 +15,12 @@ #include "s5p_mfc_pm.h" static struct s5p_mfc_pm *pm; -static struct s5p_mfc_dev *p_dev; int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) { int i; pm = &dev->pm; - p_dev = dev; - pm->num_clocks = dev->variant->num_clocks; pm->clk_names = dev->variant->clk_names; pm->device = &dev->plat_dev->dev; From c007ae835d3fccd5c85dab205918767a17040f2d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 24 Dec 2023 16:44:14 +0100 Subject: [PATCH 027/252] media: s5p-mfc: drop static device variable in s5p_mfc_pm.c Change the interface of power management functions in s5p_mfc_pm.c to accept the pointer to S5P MFC device structure. instead of relying on file-scope static variable. This makes code easier to read and modify in case more devices are added. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- .../media/platform/samsung/s5p-mfc/s5p_mfc.c | 42 +++++++++---------- .../platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 26 ++++++------ .../platform/samsung/s5p-mfc/s5p_mfc_dec.c | 8 ++-- .../platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c | 4 +- .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 8 ++-- .../platform/samsung/s5p-mfc/s5p_mfc_pm.c | 40 +++++++++--------- .../platform/samsung/s5p-mfc/s5p_mfc_pm.h | 8 ++-- 7 files changed, 67 insertions(+), 69 deletions(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c index 910f195ac686..50451984d59f 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c @@ -183,7 +183,7 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work) mfc_err("Error: some instance may be closing/opening\n"); spin_lock_irqsave(&dev->irqlock, flags); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); for (i = 0; i < MFC_NUM_CONTEXTS; i++) { ctx = dev->ctx[i]; @@ -211,9 +211,9 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work) mfc_err("Failed to reload FW\n"); goto unlock; } - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); ret = s5p_mfc_init_hw(dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); if (ret) mfc_err("Failed to reinit FW\n"); } @@ -393,7 +393,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); wake_up_ctx(ctx, reason, err); WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); return; } @@ -465,7 +465,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); wake_up_ctx(ctx, reason, err); WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); /* if suspending, wake up device and do not try_run again*/ if (test_bit(0, &dev->enter_suspend)) wake_up_dev(dev, reason, err); @@ -509,7 +509,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev, } WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); wake_up_dev(dev, reason, err); } @@ -565,7 +565,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); clear_work_bit(ctx); WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); wake_up_ctx(ctx, reason, err); } @@ -601,7 +601,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, } WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); wake_up(&ctx->queue); if (ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1) @@ -610,7 +610,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, } else { WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); wake_up(&ctx->queue); } @@ -638,7 +638,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx) WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); wake_up(&ctx->queue); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); } @@ -690,7 +690,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) } s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); wake_up_ctx(ctx, reason, err); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); } else { @@ -754,7 +754,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) if (test_and_clear_bit(0, &dev->hw_lock) == 0) mfc_err("Failed to unlock hw\n"); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); clear_work_bit(ctx); wake_up(&ctx->queue); @@ -841,20 +841,20 @@ static int s5p_mfc_open(struct file *file) dev->watchdog_timer.expires = jiffies + msecs_to_jiffies(MFC_WATCHDOG_INTERVAL); add_timer(&dev->watchdog_timer); - ret = s5p_mfc_power_on(); + ret = s5p_mfc_power_on(dev); if (ret < 0) { mfc_err("power on failed\n"); goto err_pwr_enable; } - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); ret = s5p_mfc_load_firmware(dev); if (ret) { - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); goto err_load_fw; } /* Init the FW */ ret = s5p_mfc_init_hw(dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); if (ret) goto err_init_hw; } @@ -931,7 +931,7 @@ static int s5p_mfc_open(struct file *file) err_load_fw: err_pwr_enable: if (dev->num_inst == 1) { - if (s5p_mfc_power_off() < 0) + if (s5p_mfc_power_off(dev) < 0) mfc_err("power off failed\n"); del_timer_sync(&dev->watchdog_timer); } @@ -963,7 +963,7 @@ static int s5p_mfc_release(struct file *file) vb2_queue_release(&ctx->vq_src); vb2_queue_release(&ctx->vq_dst); if (dev) { - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); /* Mark context as idle */ clear_work_bit_irqsave(ctx); @@ -983,12 +983,12 @@ static int s5p_mfc_release(struct file *file) mfc_debug(2, "Last instance\n"); s5p_mfc_deinit_hw(dev); del_timer_sync(&dev->watchdog_timer); - s5p_mfc_clock_off(); - if (s5p_mfc_power_off() < 0) + s5p_mfc_clock_off(dev); + if (s5p_mfc_power_off(dev) < 0) mfc_err("Power off failed\n"); } else { mfc_debug(2, "Shutting down clock\n"); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); } } if (dev) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c index 503487f34a80..625d77b2be0f 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c @@ -221,7 +221,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) /* 0. MFC reset */ mfc_debug(2, "MFC reset..\n"); - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); dev->risc_on = 0; ret = s5p_mfc_reset(dev); if (ret) { @@ -249,7 +249,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { mfc_err("Failed to load firmware\n"); s5p_mfc_reset(dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); return -EIO; } s5p_mfc_clean_dev_int_flags(dev); @@ -258,14 +258,14 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) if (ret) { mfc_err("Failed to send command to MFC - timeout\n"); s5p_mfc_reset(dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); return ret; } mfc_debug(2, "Ok, now will wait for completion of hardware init\n"); if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) { mfc_err("Failed to init hardware\n"); s5p_mfc_reset(dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); return -EIO; } dev->int_cond = 0; @@ -275,7 +275,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) mfc_err("Failed to init firmware - error: %d int: %d\n", dev->int_err, dev->int_type); s5p_mfc_reset(dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); return -EIO; } if (IS_MFCV6_PLUS(dev)) @@ -285,7 +285,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n", (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); mfc_debug_leave(); return 0; } @@ -294,12 +294,12 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) /* Deinitialize hardware */ void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev) { - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); s5p_mfc_reset(dev); s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); } int s5p_mfc_sleep(struct s5p_mfc_dev *dev) @@ -307,7 +307,7 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev) int ret; mfc_debug_enter(); - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); s5p_mfc_clean_dev_int_flags(dev); ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev); if (ret) { @@ -318,7 +318,7 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev) mfc_err("Failed to sleep\n"); return -EIO; } - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); dev->int_cond = 0; if (dev->int_err != 0 || dev->int_type != S5P_MFC_R2H_CMD_SLEEP_RET) { @@ -390,12 +390,12 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) mfc_debug_enter(); /* 0. MFC reset */ mfc_debug(2, "MFC reset..\n"); - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); dev->risc_on = 0; ret = s5p_mfc_reset(dev); if (ret) { mfc_err("Failed to reset MFC - timeout\n"); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); return ret; } mfc_debug(2, "Done MFC reset..\n"); @@ -410,7 +410,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) else ret = s5p_mfc_wait_wakeup(dev); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); if (ret) return ret; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c index 345734a13d26..91e102d4ec4e 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c @@ -496,7 +496,7 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, { int ret = 0; - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); if (reqbufs->count == 0) { mfc_debug(2, "Freeing buffers\n"); @@ -533,7 +533,7 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, ret = -EINVAL; } out: - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); if (ret) mfc_err("Failed allocating buffers for OUTPUT queue\n"); return ret; @@ -544,7 +544,7 @@ static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, { int ret = 0; - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); if (reqbufs->count == 0) { mfc_debug(2, "Freeing buffers\n"); @@ -587,7 +587,7 @@ static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, ret = -EINVAL; } out: - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); if (ret) mfc_err("Failed allocating buffers for CAPTURE queue\n"); return ret; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c index 7dee61c8c0b6..365f552e604b 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c @@ -1348,7 +1348,7 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) * Last frame has already been sent to MFC. * Now obtaining frames from MFC buffer */ - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); s5p_mfc_clean_ctx_int_flags(ctx); if (ctx->type == MFCINST_DECODER) { @@ -1424,7 +1424,7 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev) * scheduled, reduce the clock count as no one will * ever do this, because no interrupt related to this try_run * will ever come from hardware. */ - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); } } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c index 923d4b40dd67..73f7af674c01 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c @@ -2165,7 +2165,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) /* Last frame has already been sent to MFC * Now obtaining frames from MFC buffer */ - s5p_mfc_clock_on(); + s5p_mfc_clock_on(dev); s5p_mfc_clean_ctx_int_flags(ctx); if (ctx->type == MFCINST_DECODER) { @@ -2245,7 +2245,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) * scheduled, reduce the clock count as no one will * ever do this, because no interrupt related to this try_run * will ever come from hardware. */ - s5p_mfc_clock_off(); + s5p_mfc_clock_off(dev); } } @@ -2261,9 +2261,9 @@ s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned long ofs) { int ret; - s5p_mfc_clock_on(); + s5p_mfc_clock_on(ctx->dev); ret = readl((void __iomem *)ofs); - s5p_mfc_clock_off(); + s5p_mfc_clock_off(ctx->dev); return ret; } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c index ecb3065c33c9..ae4241408383 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c @@ -14,13 +14,11 @@ #include "s5p_mfc_debug.h" #include "s5p_mfc_pm.h" -static struct s5p_mfc_pm *pm; - int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) { + struct s5p_mfc_pm *pm = &dev->pm; int i; - pm = &dev->pm; pm->num_clocks = dev->variant->num_clocks; pm->clk_names = dev->variant->clk_names; pm->device = &dev->plat_dev->dev; @@ -50,58 +48,58 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) { - pm_runtime_disable(pm->device); + pm_runtime_disable(dev->pm.device); } -int s5p_mfc_clock_on(void) +int s5p_mfc_clock_on(struct s5p_mfc_dev *dev) { - return clk_enable(pm->clock_gate); + return clk_enable(dev->pm.clock_gate); } -void s5p_mfc_clock_off(void) +void s5p_mfc_clock_off(struct s5p_mfc_dev *dev) { - clk_disable(pm->clock_gate); + clk_disable(dev->pm.clock_gate); } -int s5p_mfc_power_on(void) +int s5p_mfc_power_on(struct s5p_mfc_dev *dev) { int i, ret = 0; - ret = pm_runtime_resume_and_get(pm->device); + ret = pm_runtime_resume_and_get(dev->pm.device); if (ret < 0) return ret; /* clock control */ - for (i = 0; i < pm->num_clocks; i++) { - ret = clk_prepare_enable(pm->clocks[i]); + for (i = 0; i < dev->pm.num_clocks; i++) { + ret = clk_prepare_enable(dev->pm.clocks[i]); if (ret < 0) { mfc_err("clock prepare failed for clock: %s\n", - pm->clk_names[i]); + dev->pm.clk_names[i]); goto err; } } /* prepare for software clock gating */ - clk_disable(pm->clock_gate); + clk_disable(dev->pm.clock_gate); return 0; err: while (--i >= 0) - clk_disable_unprepare(pm->clocks[i]); - pm_runtime_put(pm->device); + clk_disable_unprepare(dev->pm.clocks[i]); + pm_runtime_put(dev->pm.device); return ret; } -int s5p_mfc_power_off(void) +int s5p_mfc_power_off(struct s5p_mfc_dev *dev) { int i; /* finish software clock gating */ - clk_enable(pm->clock_gate); + clk_enable(dev->pm.clock_gate); - for (i = 0; i < pm->num_clocks; i++) - clk_disable_unprepare(pm->clocks[i]); + for (i = 0; i < dev->pm.num_clocks; i++) + clk_disable_unprepare(dev->pm.clocks[i]); - return pm_runtime_put_sync(pm->device); + return pm_runtime_put_sync(dev->pm.device); } diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h index 4159d2364e87..9c71036f0385 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h @@ -12,9 +12,9 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev); void s5p_mfc_final_pm(struct s5p_mfc_dev *dev); -int s5p_mfc_clock_on(void); -void s5p_mfc_clock_off(void); -int s5p_mfc_power_on(void); -int s5p_mfc_power_off(void); +int s5p_mfc_clock_on(struct s5p_mfc_dev *dev); +void s5p_mfc_clock_off(struct s5p_mfc_dev *dev); +int s5p_mfc_power_on(struct s5p_mfc_dev *dev); +int s5p_mfc_power_off(struct s5p_mfc_dev *dev); #endif /* S5P_MFC_PM_H_ */ From dcef3ed5b0d79f89018e31d55cf09f2c2f81392b Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 18 Dec 2023 17:24:48 -0700 Subject: [PATCH 028/252] staging: media: ipu3: Remove some excess struct member documentation Remove kerneldoc entries for struct members that do not exist, fixing these warnings: ./drivers/staging/media/ipu3/include/uapi/intel-ipu3.h:2522: warning: Excess struct member 'reserved1' description in 'ipu3_uapi_acc_param' ./drivers/staging/media/ipu3/include/uapi/intel-ipu3.h:2522: warning: Excess struct member 'reserved2' description in 'ipu3_uapi_acc_param' ./drivers/staging/media/ipu3/include/uapi/intel-ipu3.h:2778: warning: Excess struct member '__acc_osys' description in 'ipu3_uapi_flags' Signed-off-by: Jonathan Corbet Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/staging/media/ipu3/include/uapi/intel-ipu3.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h index caa358e0bae4..4aa2797f5e3c 100644 --- a/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h +++ b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h @@ -2485,11 +2485,9 @@ struct ipu3_uapi_anr_config { * &ipu3_uapi_yuvp1_y_ee_nr_config * @yds: y down scaler config. See &ipu3_uapi_yuvp1_yds_config * @chnr: chroma noise reduction config. See &ipu3_uapi_yuvp1_chnr_config - * @reserved1: reserved * @yds2: y channel down scaler config. See &ipu3_uapi_yuvp1_yds_config * @tcc: total color correction config as defined in struct * &ipu3_uapi_yuvp2_tcc_static_config - * @reserved2: reserved * @anr: advanced noise reduction config.See &ipu3_uapi_anr_config * @awb_fr: AWB filter response config. See ipu3_uapi_awb_fr_config * @ae: auto exposure config As specified by &ipu3_uapi_ae_config @@ -2724,7 +2722,6 @@ struct ipu3_uapi_obgrid_param { * @acc_ae: 0 = no update, 1 = update. * @acc_af: 0 = no update, 1 = update. * @acc_awb: 0 = no update, 1 = update. - * @__acc_osys: 0 = no update, 1 = update. * @reserved3: Not used. * @lin_vmem_params: 0 = no update, 1 = update. * @tnr3_vmem_params: 0 = no update, 1 = update. From 448699c522af9e3266f168c3f51f4c3713c7bee1 Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Fri, 5 Jan 2024 10:00:21 +0100 Subject: [PATCH 029/252] media: cadence: csi2rx: use match fwnode for media link Since commit 1029939b3782 ("media: v4l: async: Simplify async sub-device fwnode matching"), async connections are matched using the async sub-device fwnode, not that of the endpoint. Fix this by using the fwnode of the connection match to find the pad. Fixes: 1029939b3782 ("media: v4l: async: Simplify async sub-device fwnode matching") Signed-off-by: Julien Massot Reviewed-by: Jai Luthra Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/platform/cadence/cdns-csi2rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index fead5426830e..0ea5fa956fe9 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -468,7 +468,7 @@ static int csi2rx_async_bound(struct v4l2_async_notifier *notifier, struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); csi2rx->source_pad = media_entity_get_fwnode_pad(&s_subdev->entity, - s_subdev->fwnode, + asd->match.fwnode, MEDIA_PAD_FL_SOURCE); if (csi2rx->source_pad < 0) { dev_err(csi2rx->dev, "Couldn't find output pad for subdev %s\n", From 5b2a3687e440af6c237d5c8b9131d28f5a9550c0 Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Fri, 5 Jan 2024 10:00:22 +0100 Subject: [PATCH 030/252] media: cadence: csi2rx: add Y8_1X8 format Add support for MEDIA_BUS_FMT_Y8_1X8 format. Signed-off-by: Julien Massot Acked-by: Jai Luthra Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/platform/cadence/cdns-csi2rx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 0ea5fa956fe9..cdc63a6b394a 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -114,6 +114,7 @@ static const struct csi2rx_fmt formats[] = { { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, }, { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, }, { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, }, + { .code = MEDIA_BUS_FMT_Y8_1X8, .bpp = 8, }, { .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, }, { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, }, { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, }, From 24a4e4025d1a3d9b502d20b147a8baec8900eb24 Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Fri, 5 Jan 2024 10:00:23 +0100 Subject: [PATCH 031/252] media: ti: j721e-csi2rx: add GREY format Add Grey format to properly select RAW8 data type. Tested with a ST VG5661 sensor. Signed-off-by: Julien Massot Acked-by: Jai Luthra Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index 59b30fc43144..4048b2bd3885 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -158,6 +158,12 @@ static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = { .csi_dt = MIPI_CSI2_DT_RAW8, .bpp = 8, .size = SHIM_DMACNTX_SIZE_8, + }, { + .fourcc = V4L2_PIX_FMT_GREY, + .code = MEDIA_BUS_FMT_Y8_1X8, + .csi_dt = MIPI_CSI2_DT_RAW8, + .bpp = 8, + .size = SHIM_DMACNTX_SIZE_8, }, { .fourcc = V4L2_PIX_FMT_SBGGR10, .code = MEDIA_BUS_FMT_SBGGR10_1X10, From 77759eb0b895e6be7ab1fbbfdf064b6fea62b406 Mon Sep 17 00:00:00 2001 From: Jai Luthra Date: Fri, 5 Jan 2024 10:00:24 +0100 Subject: [PATCH 032/252] media: cadence: csi2rx: add support for RGB formats Add support for RGB565, RGB888 and BGR888 media bus formats. Signed-off-by: Jai Luthra Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/platform/cadence/cdns-csi2rx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index cdc63a6b394a..401d9a7c65f8 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -119,6 +119,9 @@ static const struct csi2rx_fmt formats[] = { { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, }, { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, }, { .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, }, + { .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, }, + { .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, }, + { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, }, }; static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code) From 5eb0ad467cb0cf8f9a6621d079a1f7ecd804153f Mon Sep 17 00:00:00 2001 From: Jai Luthra Date: Fri, 5 Jan 2024 10:00:25 +0100 Subject: [PATCH 033/252] media: ti: j721e-csi2rx: add support for RGB formats Add support for RGB565, RGB888 and BGR888 media bus formats. The pixel formats for these have a different byte-order than the MIPI bus formats, given the SHIM IP [1] unpacks them into memory as follows: MIPI RGB888 unpacks to: BYTE3 BYTE2 BYTE1 BYTE0 00000000 RRRRRRRR GGGGGGGG BBBBBBBB MIPI RGB565 unpacks to: BIT 15-11 BIT 10-5 BIT 4-0 RRRRR GGGGGG BBBBB [1]: AM62x TRM: 12.6.1.4.5 "CSI_RX_IF Data Memory Organization Details" Link: https://www.ti.com/lit/pdf/spruiv7 Signed-off-by: Jai Luthra Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- .../platform/ti/j721e-csi2rx/j721e-csi2rx.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c index 4048b2bd3885..2b078c5d7f5d 100644 --- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c @@ -188,6 +188,24 @@ static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = { .csi_dt = MIPI_CSI2_DT_RAW10, .bpp = 16, .size = SHIM_DMACNTX_SIZE_16, + }, { + .fourcc = V4L2_PIX_FMT_RGB565X, + .code = MEDIA_BUS_FMT_RGB565_1X16, + .csi_dt = MIPI_CSI2_DT_RGB565, + .bpp = 16, + .size = SHIM_DMACNTX_SIZE_16, + }, { + .fourcc = V4L2_PIX_FMT_XBGR32, + .code = MEDIA_BUS_FMT_RGB888_1X24, + .csi_dt = MIPI_CSI2_DT_RGB888, + .bpp = 32, + .size = SHIM_DMACNTX_SIZE_32, + }, { + .fourcc = V4L2_PIX_FMT_RGBX32, + .code = MEDIA_BUS_FMT_BGR888_1X24, + .csi_dt = MIPI_CSI2_DT_RGB888, + .bpp = 32, + .size = SHIM_DMACNTX_SIZE_32, }, /* More formats can be supported but they are not listed for now. */ From fc999dd90f2fc7cbbac261a9e80b972ab3146651 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 21 Dec 2023 16:39:57 +0000 Subject: [PATCH 034/252] media: v4l2-subdev: Fix spelling mistake "heigth" -> "height" There is a spelling mistake in a dev_err error message. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/i2c/alvium-csi2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/alvium-csi2.c b/drivers/media/i2c/alvium-csi2.c index 34ff7fad3877..389dac50fee9 100644 --- a/drivers/media/i2c/alvium-csi2.c +++ b/drivers/media/i2c/alvium-csi2.c @@ -1472,7 +1472,7 @@ static int alvium_get_hw_features_params(struct alvium_dev *alvium) ret = alvium_get_img_height_params(alvium); if (ret) { - dev_err(dev, "Fail to read img heigth regs\n"); + dev_err(dev, "Fail to read img height regs\n"); return ret; } From 2edfa0ea6bc229e4c3398e2ba002457989fcde4e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 14 Dec 2023 09:47:24 +0100 Subject: [PATCH 035/252] media: platform: xilinx: Fix Kconfig indentation Use proper indentation for Kconfig fragments - help part. Signed-off-by: Michal Simek Reviewed-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/platform/xilinx/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig index 93ef78bf62e6..601edd9acd5b 100644 --- a/drivers/media/platform/xilinx/Kconfig +++ b/drivers/media/platform/xilinx/Kconfig @@ -26,10 +26,10 @@ config VIDEO_XILINX_TPG depends on VIDEO_XILINX select VIDEO_XILINX_VTC help - Driver for the Xilinx Video Test Pattern Generator + Driver for the Xilinx Video Test Pattern Generator config VIDEO_XILINX_VTC tristate "Xilinx Video Timing Controller" depends on VIDEO_XILINX help - Driver for the Xilinx Video Timing Controller + Driver for the Xilinx Video Timing Controller From 999eb5f8107a8a1e5ff003ffca2e75dcbc30f7a7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 22 Dec 2023 21:07:07 -0800 Subject: [PATCH 036/252] media: media-entity.h: fix Excess kernel-doc description warnings Remove the @major: and @minor: lines to prevent the kernel-doc warnings: include/media/media-entity.h:376: warning: Excess struct member 'major' description in 'media_entity' include/media/media-entity.h:376: warning: Excess struct member 'minor' description in 'media_entity' Signed-off-by: Randy Dunlap Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- include/media/media-entity.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 2b6cd343ee9e..c79176ed6299 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -337,10 +337,6 @@ enum media_entity_type { * @info.dev: Contains device major and minor info. * @info.dev.major: device node major, if the device is a devnode. * @info.dev.minor: device node minor, if the device is a devnode. - * @major: Devnode major number (zero if not applicable). Kept just - * for backward compatibility. - * @minor: Devnode minor number (zero if not applicable). Kept just - * for backward compatibility. * * .. note:: * From c2716904918e99ca4b77354dd46ceec2d9ba2ff6 Mon Sep 17 00:00:00 2001 From: Changhuang Liang Date: Mon, 11 Dec 2023 01:43:29 -0800 Subject: [PATCH 037/252] media: cadence: csi2rx: Add enum_mbus_code pad ops Add enum_mbus_code ioctl so that user space can know what formats are supported to csi2rx. Signed-off-by: Changhuang Liang Reviewed-by: Julien Massot Tested-by: Julien Massot Reviewed-by: Jai Luthra Tested-by: Jai Luthra # [Test on sk-am62a] Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/platform/cadence/cdns-csi2rx.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 401d9a7c65f8..2d7b0508cc9a 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -393,6 +393,18 @@ static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable) return ret; } +static int csi2rx_enum_mbus_code(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *state, + struct v4l2_subdev_mbus_code_enum *code_enum) +{ + if (code_enum->index >= ARRAY_SIZE(formats)) + return -EINVAL; + + code_enum->code = formats[code_enum->index].code; + + return 0; +} + static int csi2rx_set_fmt(struct v4l2_subdev *subdev, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) @@ -443,6 +455,7 @@ static int csi2rx_init_state(struct v4l2_subdev *subdev, } static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = { + .enum_mbus_code = csi2rx_enum_mbus_code, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = csi2rx_set_fmt, }; From 87318b7092670d4086bfec115a0280a60c51c2dd Mon Sep 17 00:00:00 2001 From: Hidenori Kobayashi Date: Tue, 9 Jan 2024 17:09:09 +0900 Subject: [PATCH 038/252] media: staging: ipu3-imgu: Set fields before media_entity_pads_init() The imgu driver fails to probe with the following message because it does not set the pad's flags before calling media_entity_pads_init(). [ 14.596315] ipu3-imgu 0000:00:05.0: failed initialize subdev media entity (-22) [ 14.596322] ipu3-imgu 0000:00:05.0: failed to register subdev0 ret (-22) [ 14.596327] ipu3-imgu 0000:00:05.0: failed to register pipes (-22) [ 14.596331] ipu3-imgu 0000:00:05.0: failed to create V4L2 devices (-22) Fix the initialization order so that the driver probe succeeds. The ops initialization is also moved together for readability. Fixes: a0ca1627b450 ("media: staging/intel-ipu3: Add v4l2 driver based on media framework") Cc: # 6.7 Cc: Dan Carpenter Signed-off-by: Hidenori Kobayashi Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/staging/media/ipu3/ipu3-v4l2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index a66f034380c0..3df58eb3e882 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -1069,6 +1069,11 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu, struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; /* Initialize subdev media entity */ + imgu_sd->subdev.entity.ops = &imgu_media_ops; + for (i = 0; i < IMGU_NODE_NUM; i++) { + imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ? + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; + } r = media_entity_pads_init(&imgu_sd->subdev.entity, IMGU_NODE_NUM, imgu_sd->subdev_pads); if (r) { @@ -1076,11 +1081,6 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu, "failed initialize subdev media entity (%d)\n", r); return r; } - imgu_sd->subdev.entity.ops = &imgu_media_ops; - for (i = 0; i < IMGU_NODE_NUM; i++) { - imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ? - MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; - } /* Initialize subdev */ v4l2_subdev_init(&imgu_sd->subdev, &imgu_subdev_ops); @@ -1177,15 +1177,15 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, } /* Initialize media entities */ + node->vdev_pad.flags = node->output ? + MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK; + vdev->entity.ops = NULL; r = media_entity_pads_init(&vdev->entity, 1, &node->vdev_pad); if (r) { dev_err(dev, "failed initialize media entity (%d)\n", r); mutex_destroy(&node->lock); return r; } - node->vdev_pad.flags = node->output ? - MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK; - vdev->entity.ops = NULL; /* Initialize vbq */ vbq->type = node->vdev_fmt.type; From b97dc22b195f793b33ddc4a36853baa37555da6d Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 25 May 2023 14:12:04 +0300 Subject: [PATCH 039/252] media: ipu3-cio2: Further clean up async subdev link creation Use v4l2_create_fwnode_links_to_pad() to create links from async sub-devices to the CSI-2 receiver subdevs. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/pci/intel/ipu3/ipu3-cio2.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index ed08bf4178f0..83e29c56fe33 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1407,7 +1408,6 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier, static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) { struct cio2_device *cio2 = to_cio2_device(notifier); - struct device *dev = &cio2->pci_dev->dev; struct sensor_async_subdev *s_asd; struct v4l2_async_connection *asd; struct cio2_queue *q; @@ -1417,23 +1417,10 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier) s_asd = to_sensor_asd(asd); q = &cio2->queue[s_asd->csi2.port]; - ret = media_entity_get_fwnode_pad(&q->sensor->entity, - s_asd->asd.match.fwnode, - MEDIA_PAD_FL_SOURCE); - if (ret < 0) { - dev_err(dev, "no pad for endpoint %pfw (%d)\n", - s_asd->asd.match.fwnode, ret); + ret = v4l2_create_fwnode_links_to_pad(asd->sd, + &q->subdev_pads[CIO2_PAD_SINK], 0); + if (ret) return ret; - } - - ret = media_create_pad_link(&q->sensor->entity, ret, - &q->subdev.entity, CIO2_PAD_SINK, - 0); - if (ret) { - dev_err(dev, "failed to create link for %s (endpoint %pfw, error %d)\n", - q->sensor->name, s_asd->asd.match.fwnode, ret); - return ret; - } } return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev); @@ -1572,6 +1559,7 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q) v4l2_subdev_init(subdev, &cio2_subdev_ops); subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; subdev->owner = THIS_MODULE; + subdev->dev = dev; snprintf(subdev->name, sizeof(subdev->name), CIO2_ENTITY_NAME " %td", q - cio2->queue); subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; From 53aa6b38f10cc42136551acf115a8b04e013ec89 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 25 May 2023 14:17:58 +0300 Subject: [PATCH 040/252] media: v4l2-mc: Add debug prints for v4l2_fwnode_create_links_for_pad() Add relevant debug prints for v4l2_fwnode_create_links_for_pad(). This should help debugging when things go wrong. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/v4l2-core/v4l2-mc.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index 52d349e72b8c..4bb91359e3a9 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -337,12 +337,18 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd, src_idx = media_entity_get_fwnode_pad(&src_sd->entity, endpoint, MEDIA_PAD_FL_SOURCE); - if (src_idx < 0) + if (src_idx < 0) { + dev_dbg(src_sd->dev, "no source pad found for %pfw\n", + endpoint); continue; + } remote_ep = fwnode_graph_get_remote_endpoint(endpoint); - if (!remote_ep) + if (!remote_ep) { + dev_dbg(src_sd->dev, "no remote ep found for %pfw\n", + endpoint); continue; + } /* * ask the sink to verify it owns the remote endpoint, @@ -353,8 +359,12 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd, MEDIA_PAD_FL_SINK); fwnode_handle_put(remote_ep); - if (sink_idx < 0 || sink_idx != sink->index) + if (sink_idx < 0 || sink_idx != sink->index) { + dev_dbg(src_sd->dev, + "sink pad index mismatch or error (is %d, expected %u)\n", + sink_idx, sink->index); continue; + } /* * the source endpoint corresponds to one of its source pads, @@ -367,8 +377,13 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd, src = &src_sd->entity.pads[src_idx]; /* skip if link already exists */ - if (media_entity_find_link(src, sink)) + if (media_entity_find_link(src, sink)) { + dev_dbg(src_sd->dev, + "link %s:%d -> %s:%d already exists\n", + src_sd->entity.name, src_idx, + sink->entity->name, sink_idx); continue; + } dev_dbg(src_sd->dev, "creating link %s:%d -> %s:%d\n", src_sd->entity.name, src_idx, From 5fd593b8736c5e4d0164536e471cb04158b0ab61 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 21 Dec 2023 15:49:39 +0200 Subject: [PATCH 041/252] media: mc: Drop useless debug print on file handle release Drop a debug print in media_release(), which is a release callback for a file handle. Printing a debug message here is simply not necessary. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/mc/mc-devnode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 680fbb3a9340..9c8fe9335dc1 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -190,7 +190,6 @@ static int media_release(struct inode *inode, struct file *filp) return value is ignored. */ put_device(&devnode->dev); - pr_debug("%s: Media Release\n", __func__); return 0; } From eba5e4075505b758fb36967e83ba43d4b994a2e0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 10 Jan 2024 20:33:01 -0800 Subject: [PATCH 042/252] media: i2c: ar0521: fix spellos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix spelling mistakes as reported by codespell. Signed-off-by: Randy Dunlap Cc: Krzysztof Hałasa Cc: Shawn Guo Cc: Sascha Hauer Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/i2c/ar0521.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index c7d5fa532ae1..09331cf95c62 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -314,7 +314,7 @@ static void ar0521_calc_pll(struct ar0521_dev *sensor) * In the clock tree: * MIPI_CLK = PIXEL_CLOCK * bpp / 2 / 2 * - * Generic pixel_rate to bus clock frequencey equation: + * Generic pixel_rate to bus clock frequency equation: * MIPI_CLK = V4L2_CID_PIXEL_RATE * bpp / lanes / 2 * * From which we derive the PIXEL_CLOCK to use in the clock tree: @@ -327,7 +327,7 @@ static void ar0521_calc_pll(struct ar0521_dev *sensor) * * TODO: in case we have less data lanes we have to reduce the desired * VCO not to exceed the limits specified by the datasheet and - * consequentially reduce the obtained pixel clock. + * consequently reduce the obtained pixel clock. */ pixel_clock = AR0521_PIXEL_CLOCK_RATE * 2 / sensor->lane_count; bpp = ar0521_code_to_bpp(sensor); @@ -806,7 +806,7 @@ static const struct initial_reg { REGS(be(0x3F00), be(0x0017), /* 3F00: BM_T0 */ be(0x02DD), /* 3F02: BM_T1 */ - /* 3F04: if Ana_gain less than 2, use noise_floor0, multipl */ + /* 3F04: if Ana_gain less than 2, use noise_floor0, multiply */ be(0x0020), /* 3F06: if Ana_gain between 4 and 7, use noise_floor2 and */ be(0x0040), From 04447d48afd365a837e23cde631517f166045b9d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 22 Jan 2024 10:26:42 +0100 Subject: [PATCH 043/252] media: mediatek: vcodec: drop excess struct members descriptions Drop obsolete @wait_key_frame and @mv_joint struct member descriptions. This fixes two warnings: drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c:57: warning: Excess struct member 'wait_key_frame' description in 'vdec_vp8_slice_info' drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c:166: warning: Excess struct member 'mv_joint' description in 'vdec_vp9_slice_counts_map' Signed-off-by: Hans Verkuil Reviewed-by: Matthias Brugger --- .../platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c | 1 - .../platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c index f64b21c07169..f677e499fefa 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c @@ -37,7 +37,6 @@ * @bs_sz: bitstream size * @resolution_changed:resolution change flag 1 - changed, 0 - not change * @frame_header_type: current frame header type - * @wait_key_frame: wait key frame coming * @crc: used to check whether hardware's status is right * @reserved: reserved, currently unused */ diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c index 69d37b93bd35..cf48d09b78d7 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c @@ -141,7 +141,6 @@ struct vdec_vp9_slice_frame_counts { * @skip: skip counts. * @y_mode: Y prediction mode counts. * @filter: interpolation filter counts. - * @mv_joint: motion vector joint counts. * @sign: motion vector sign counts. * @classes: motion vector class counts. * @class0: motion vector class0 bit counts. From 592bb51d048c180ac9f5a52167548f18fe896a43 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 28 Dec 2023 22:43:25 +0100 Subject: [PATCH 044/252] media: atomisp: Adjust for v4l2_subdev_state handling changes in 6.8 The atomisp driver emulates a standard v4l2 device, which also works for non media-controller aware applications. Part of this requires making try_fmt calls on the sensor when a normal v4l2 app is making try_fmt calls on the /dev/video# mode. With the recent v4l2_subdev_state handling changes in 6.8 this no longer works, fixing this requires 2 changes: 1. The atomisp code was using its own internal v4l2_subdev_pad_config for this. Replace the internal v4l2_subdev_pad_config with allocating a full v4l2_subdev_state for storing the full try_fmt state. 2. The paths actually setting the fmt or crop selection now need to be passed the v4l2_subdev's active state, so that sensor drivers which are using the v4l2_subdev's active state to store their state keep working. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_cmd.c | 58 ++++++++++-------- .../media/atomisp/pci/atomisp_internal.h | 4 +- .../staging/media/atomisp/pci/atomisp_ioctl.c | 52 +++++++++------- .../staging/media/atomisp/pci/atomisp_v4l2.c | 59 ++++++++++++++----- 4 files changed, 111 insertions(+), 62 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index f44e6412f4e3..d0db2efe0045 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -3723,12 +3723,10 @@ void atomisp_get_padding(struct atomisp_device *isp, u32 width, u32 height, static int atomisp_set_crop(struct atomisp_device *isp, const struct v4l2_mbus_framefmt *format, + struct v4l2_subdev_state *sd_state, int which) { struct atomisp_input_subdev *input = &isp->inputs[isp->asd.input_curr]; - struct v4l2_subdev_state pad_state = { - .pads = &input->pad_cfg, - }; struct v4l2_subdev_selection sel = { .which = which, .target = V4L2_SEL_TGT_CROP, @@ -3754,7 +3752,7 @@ static int atomisp_set_crop(struct atomisp_device *isp, sel.r.left = ((input->native_rect.width - sel.r.width) / 2) & ~1; sel.r.top = ((input->native_rect.height - sel.r.height) / 2) & ~1; - ret = v4l2_subdev_call(input->camera, pad, set_selection, &pad_state, &sel); + ret = v4l2_subdev_call(input->camera, pad, set_selection, sd_state, &sel); if (ret) dev_err(isp->dev, "Error setting crop to %ux%u @%ux%u: %d\n", sel.r.width, sel.r.height, sel.r.left, sel.r.top, ret); @@ -3770,9 +3768,6 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f, const struct atomisp_format_bridge *fmt, *snr_fmt; struct atomisp_sub_device *asd = &isp->asd; struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; - struct v4l2_subdev_state pad_state = { - .pads = &input->pad_cfg, - }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -3809,11 +3804,16 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f, dev_dbg(isp->dev, "try_mbus_fmt: asking for %ux%u\n", format.format.width, format.format.height); - ret = atomisp_set_crop(isp, &format.format, V4L2_SUBDEV_FORMAT_TRY); - if (ret) - return ret; + v4l2_subdev_lock_state(input->try_sd_state); + + ret = atomisp_set_crop(isp, &format.format, input->try_sd_state, + V4L2_SUBDEV_FORMAT_TRY); + if (ret == 0) + ret = v4l2_subdev_call(input->camera, pad, set_fmt, + input->try_sd_state, &format); + + v4l2_subdev_unlock_state(input->try_sd_state); - ret = v4l2_subdev_call(input->camera, pad, set_fmt, &pad_state, &format); if (ret) return ret; @@ -4238,9 +4238,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p struct atomisp_device *isp = asd->isp; struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; const struct atomisp_format_bridge *format; - struct v4l2_subdev_state pad_state = { - .pads = &input->pad_cfg, - }; + struct v4l2_subdev_state *act_sd_state; struct v4l2_subdev_format vformat = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -4268,12 +4266,18 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p /* Disable dvs if resolution can't be supported by sensor */ if (asd->params.video_dis_en && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { - ret = atomisp_set_crop(isp, &vformat.format, V4L2_SUBDEV_FORMAT_TRY); - if (ret) - return ret; + v4l2_subdev_lock_state(input->try_sd_state); + + ret = atomisp_set_crop(isp, &vformat.format, input->try_sd_state, + V4L2_SUBDEV_FORMAT_TRY); + if (ret == 0) { + vformat.which = V4L2_SUBDEV_FORMAT_TRY; + ret = v4l2_subdev_call(input->camera, pad, set_fmt, + input->try_sd_state, &vformat); + } + + v4l2_subdev_unlock_state(input->try_sd_state); - vformat.which = V4L2_SUBDEV_FORMAT_TRY; - ret = v4l2_subdev_call(input->camera, pad, set_fmt, &pad_state, &vformat); if (ret) return ret; @@ -4291,12 +4295,18 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p } } - ret = atomisp_set_crop(isp, &vformat.format, V4L2_SUBDEV_FORMAT_ACTIVE); - if (ret) - return ret; + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); + + ret = atomisp_set_crop(isp, &vformat.format, act_sd_state, + V4L2_SUBDEV_FORMAT_ACTIVE); + if (ret == 0) { + vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE; + ret = v4l2_subdev_call(input->camera, pad, set_fmt, act_sd_state, &vformat); + } + + if (act_sd_state) + v4l2_subdev_unlock_state(act_sd_state); - vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE; - ret = v4l2_subdev_call(input->camera, pad, set_fmt, NULL, &vformat); if (ret) return ret; diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index f7b4bee9574b..d5b077e602ca 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -132,8 +132,8 @@ struct atomisp_input_subdev { /* Sensor rects for sensors which support crop */ struct v4l2_rect native_rect; struct v4l2_rect active_rect; - /* Sensor pad_cfg for which == V4L2_SUBDEV_FORMAT_TRY calls */ - struct v4l2_subdev_pad_config pad_cfg; + /* Sensor state for which == V4L2_SUBDEV_FORMAT_TRY calls */ + struct v4l2_subdev_state *try_sd_state; struct v4l2_subdev *motor; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index 01b7fa9b56a2..5b2d88c02d36 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -781,12 +781,20 @@ static int atomisp_enum_framesizes(struct file *file, void *priv, .which = V4L2_SUBDEV_FORMAT_ACTIVE, .code = input->code, }; + struct v4l2_subdev_state *act_sd_state; int ret; + if (!input->camera) + return -EINVAL; + if (input->crop_support) return atomisp_enum_framesizes_crop(isp, fsize); - ret = v4l2_subdev_call(input->camera, pad, enum_frame_size, NULL, &fse); + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); + ret = v4l2_subdev_call(input->camera, pad, enum_frame_size, + act_sd_state, &fse); + if (act_sd_state) + v4l2_subdev_unlock_state(act_sd_state); if (ret) return ret; @@ -803,18 +811,25 @@ static int atomisp_enum_frameintervals(struct file *file, void *priv, struct video_device *vdev = video_devdata(file); struct atomisp_device *isp = video_get_drvdata(vdev); struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; + struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; struct v4l2_subdev_frame_interval_enum fie = { - .code = atomisp_in_fmt_conv[0].code, + .code = atomisp_in_fmt_conv[0].code, .index = fival->index, .width = fival->width, .height = fival->height, .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; + struct v4l2_subdev_state *act_sd_state; int ret; - ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, - pad, enum_frame_interval, NULL, - &fie); + if (!input->camera) + return -EINVAL; + + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); + ret = v4l2_subdev_call(input->camera, pad, enum_frame_interval, + act_sd_state, &fie); + if (act_sd_state) + v4l2_subdev_unlock_state(act_sd_state); if (ret) return ret; @@ -830,30 +845,25 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh, struct video_device *vdev = video_devdata(file); struct atomisp_device *isp = video_get_drvdata(vdev); struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; + struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; const struct atomisp_format_bridge *format; - struct v4l2_subdev *camera; + struct v4l2_subdev_state *act_sd_state; unsigned int i, fi = 0; - int rval; + int ret; - camera = isp->inputs[asd->input_curr].camera; - if(!camera) { - dev_err(isp->dev, "%s(): camera is NULL, device is %s\n", - __func__, vdev->name); + if (!input->camera) return -EINVAL; - } - rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code); - if (rval == -ENOIOCTLCMD) { - dev_warn(isp->dev, - "enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n", - camera->name); - } - - if (rval) - return rval; + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); + ret = v4l2_subdev_call(input->camera, pad, enum_mbus_code, + act_sd_state, &code); + if (act_sd_state) + v4l2_subdev_unlock_state(act_sd_state); + if (ret) + return ret; for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) { format = &atomisp_output_fmts[i]; diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index c1c8501ec61f..547e1444ad97 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -862,6 +862,9 @@ static void atomisp_unregister_entities(struct atomisp_device *isp) v4l2_device_unregister(&isp->v4l2_dev); media_device_unregister(&isp->media_dev); media_device_cleanup(&isp->media_dev); + + for (i = 0; i < isp->input_cnt; i++) + __v4l2_subdev_state_free(isp->inputs[i].try_sd_state); } static int atomisp_register_entities(struct atomisp_device *isp) @@ -933,32 +936,49 @@ static int atomisp_register_entities(struct atomisp_device *isp) static void atomisp_init_sensor(struct atomisp_input_subdev *input) { + static struct lock_class_key try_sd_state_key; struct v4l2_subdev_mbus_code_enum mbus_code_enum = { }; struct v4l2_subdev_frame_size_enum fse = { }; - struct v4l2_subdev_state sd_state = { - .pads = &input->pad_cfg, - }; struct v4l2_subdev_selection sel = { }; + struct v4l2_subdev_state *try_sd_state, *act_sd_state; int i, err; + /* + * FIXME: Drivers are not supposed to use __v4l2_subdev_state_alloc() + * but atomisp needs this for try_fmt on its /dev/video# node since + * it emulates a normal v4l2 device there, passing through try_fmt / + * set_fmt to the sensor. + */ + try_sd_state = __v4l2_subdev_state_alloc(input->camera, + "atomisp:try_sd_state->lock", &try_sd_state_key); + if (IS_ERR(try_sd_state)) + return; + + input->try_sd_state = try_sd_state; + + act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); + mbus_code_enum.which = V4L2_SUBDEV_FORMAT_ACTIVE; - err = v4l2_subdev_call(input->camera, pad, enum_mbus_code, NULL, &mbus_code_enum); + err = v4l2_subdev_call(input->camera, pad, enum_mbus_code, + act_sd_state, &mbus_code_enum); if (!err) input->code = mbus_code_enum.code; sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; sel.target = V4L2_SEL_TGT_NATIVE_SIZE; - err = v4l2_subdev_call(input->camera, pad, get_selection, NULL, &sel); + err = v4l2_subdev_call(input->camera, pad, get_selection, + act_sd_state, &sel); if (err) - return; + goto unlock_act_sd_state; input->native_rect = sel.r; sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; sel.target = V4L2_SEL_TGT_CROP_DEFAULT; - err = v4l2_subdev_call(input->camera, pad, get_selection, NULL, &sel); + err = v4l2_subdev_call(input->camera, pad, get_selection, + act_sd_state, &sel); if (err) - return; + goto unlock_act_sd_state; input->active_rect = sel.r; @@ -973,7 +993,8 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input) fse.code = input->code; fse.which = V4L2_SUBDEV_FORMAT_ACTIVE; - err = v4l2_subdev_call(input->camera, pad, enum_frame_size, NULL, &fse); + err = v4l2_subdev_call(input->camera, pad, enum_frame_size, + act_sd_state, &fse); if (err) break; @@ -989,22 +1010,26 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input) * for padding, set the crop rect to cover the entire sensor instead * of only the default active area. * - * Do this for both try and active formats since the try_crop rect in - * pad_cfg may influence (clamp) future try_fmt calls with which == try. + * Do this for both try and active formats since the crop rect in + * try_sd_state may influence (clamp size) in calls with which == try. */ sel.which = V4L2_SUBDEV_FORMAT_TRY; sel.target = V4L2_SEL_TGT_CROP; sel.r = input->native_rect; - err = v4l2_subdev_call(input->camera, pad, set_selection, &sd_state, &sel); + v4l2_subdev_lock_state(input->try_sd_state); + err = v4l2_subdev_call(input->camera, pad, set_selection, + input->try_sd_state, &sel); + v4l2_subdev_unlock_state(input->try_sd_state); if (err) - return; + goto unlock_act_sd_state; sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; sel.target = V4L2_SEL_TGT_CROP; sel.r = input->native_rect; - err = v4l2_subdev_call(input->camera, pad, set_selection, NULL, &sel); + err = v4l2_subdev_call(input->camera, pad, set_selection, + act_sd_state, &sel); if (err) - return; + goto unlock_act_sd_state; dev_info(input->camera->dev, "Supports crop native %dx%d active %dx%d binning %d\n", input->native_rect.width, input->native_rect.height, @@ -1012,6 +1037,10 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input) input->binning_support); input->crop_support = true; + +unlock_act_sd_state: + if (act_sd_state) + v4l2_subdev_unlock_state(act_sd_state); } int atomisp_register_device_nodes(struct atomisp_device *isp) From 26b53392ca0e3c86df9a2bf7eb29a86a72377a37 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 29 Dec 2023 16:41:55 +0100 Subject: [PATCH 045/252] media: atomisp: Refactor sensor crop + fmt setting There are 3 code-paths all of 3 which need to do: 1. Get try or active state 2. lock state 3. Call atomisp_set_crop() 4. Call v4l2_subdev_call(input->camera, pad, set_fmt, state, fmt) 5. unlock state Change atomisp_set_crop into atomisp_set_crop_and_fmt() which does all of this and change the 3 code-paths which need this to use the new atomisp_set_crop_and_fmt() function. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_cmd.c | 141 +++++++----------- 1 file changed, 58 insertions(+), 83 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index d0db2efe0045..8593ba90605f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -3721,22 +3721,34 @@ void atomisp_get_padding(struct atomisp_device *isp, u32 width, u32 height, *padding_h = max_t(u32, *padding_h, min_pad_h); } -static int atomisp_set_crop(struct atomisp_device *isp, - const struct v4l2_mbus_framefmt *format, - struct v4l2_subdev_state *sd_state, - int which) +static int atomisp_set_crop_and_fmt(struct atomisp_device *isp, + struct v4l2_mbus_framefmt *ffmt, + int which) { struct atomisp_input_subdev *input = &isp->inputs[isp->asd.input_curr]; struct v4l2_subdev_selection sel = { .which = which, .target = V4L2_SEL_TGT_CROP, - .r.width = format->width, - .r.height = format->height, + .r.width = ffmt->width, + .r.height = ffmt->height, }; - int ret; + struct v4l2_subdev_format format = { + .which = which, + .format = *ffmt, + }; + struct v4l2_subdev_state *sd_state; + int ret = 0; + + if (!input->camera) + return -EINVAL; + + sd_state = (which == V4L2_SUBDEV_FORMAT_TRY) ? input->try_sd_state : + input->camera->active_state; + if (sd_state) + v4l2_subdev_lock_state(sd_state); if (!input->crop_support) - return 0; + goto set_fmt; /* Cropping is done before binning, when binning double the crop rect */ if (input->binning_support && sel.r.width <= (input->native_rect.width / 2) && @@ -3757,6 +3769,14 @@ static int atomisp_set_crop(struct atomisp_device *isp, dev_err(isp->dev, "Error setting crop to %ux%u @%ux%u: %d\n", sel.r.width, sel.r.height, sel.r.left, sel.r.top, ret); +set_fmt: + if (ret == 0) + ret = v4l2_subdev_call(input->camera, pad, set_fmt, sd_state, &format); + + if (sd_state) + v4l2_subdev_unlock_state(sd_state); + + *ffmt = format.format; return ret; } @@ -3767,16 +3787,10 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f, { const struct atomisp_format_bridge *fmt, *snr_fmt; struct atomisp_sub_device *asd = &isp->asd; - struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; - struct v4l2_subdev_format format = { - .which = V4L2_SUBDEV_FORMAT_TRY, - }; + struct v4l2_mbus_framefmt ffmt = { }; u32 padding_w, padding_h; int ret; - if (!input->camera) - return -EINVAL; - fmt = atomisp_get_format_bridge(f->pixelformat); /* Currently, raw formats are broken!!! */ if (!fmt || fmt->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) { @@ -3797,38 +3811,27 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f, * the set_fmt call, like atomisp_set_fmt_to_snr() does. */ atomisp_get_padding(isp, f->width, f->height, &padding_w, &padding_h); - v4l2_fill_mbus_format(&format.format, f, fmt->mbus_code); - format.format.width += padding_w; - format.format.height += padding_h; + v4l2_fill_mbus_format(&ffmt, f, fmt->mbus_code); + ffmt.width += padding_w; + ffmt.height += padding_h; - dev_dbg(isp->dev, "try_mbus_fmt: asking for %ux%u\n", - format.format.width, format.format.height); - - v4l2_subdev_lock_state(input->try_sd_state); - - ret = atomisp_set_crop(isp, &format.format, input->try_sd_state, - V4L2_SUBDEV_FORMAT_TRY); - if (ret == 0) - ret = v4l2_subdev_call(input->camera, pad, set_fmt, - input->try_sd_state, &format); - - v4l2_subdev_unlock_state(input->try_sd_state); + dev_dbg(isp->dev, "try_mbus_fmt: try %ux%u\n", ffmt.width, ffmt.height); + ret = atomisp_set_crop_and_fmt(isp, &ffmt, V4L2_SUBDEV_FORMAT_TRY); if (ret) return ret; - dev_dbg(isp->dev, "try_mbus_fmt: got %ux%u\n", - format.format.width, format.format.height); + dev_dbg(isp->dev, "try_mbus_fmt: got %ux%u\n", ffmt.width, ffmt.height); - snr_fmt = atomisp_get_format_bridge_from_mbus(format.format.code); + snr_fmt = atomisp_get_format_bridge_from_mbus(ffmt.code); if (!snr_fmt) { dev_err(isp->dev, "unknown sensor format 0x%8.8x\n", - format.format.code); + ffmt.code); return -EINVAL; } - f->width = format.format.width - padding_w; - f->height = format.format.height - padding_h; + f->width = ffmt.width - padding_w; + f->height = ffmt.height - padding_h; /* * If the format is jpeg or custom RAW, then the width and height will @@ -4236,28 +4239,22 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); struct atomisp_sub_device *asd = pipe->asd; struct atomisp_device *isp = asd->isp; - struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; const struct atomisp_format_bridge *format; - struct v4l2_subdev_state *act_sd_state; - struct v4l2_subdev_format vformat = { - .which = V4L2_SUBDEV_FORMAT_TRY, - }; - struct v4l2_mbus_framefmt *ffmt = &vformat.format; - struct v4l2_mbus_framefmt *req_ffmt; + struct v4l2_mbus_framefmt req_ffmt, ffmt = { }; struct atomisp_input_stream_info *stream_info = - (struct atomisp_input_stream_info *)ffmt->reserved; + (struct atomisp_input_stream_info *)&ffmt.reserved; int ret; format = atomisp_get_format_bridge(f->pixelformat); if (!format) return -EINVAL; - v4l2_fill_mbus_format(ffmt, f, format->mbus_code); - ffmt->height += asd->sink_pad_padding_h + dvs_env_h; - ffmt->width += asd->sink_pad_padding_w + dvs_env_w; + v4l2_fill_mbus_format(&ffmt, f, format->mbus_code); + ffmt.height += asd->sink_pad_padding_h + dvs_env_h; + ffmt.width += asd->sink_pad_padding_w + dvs_env_w; dev_dbg(isp->dev, "s_mbus_fmt: ask %ux%u (padding %ux%u, dvs %ux%u)\n", - ffmt->width, ffmt->height, asd->sink_pad_padding_w, asd->sink_pad_padding_h, + ffmt.width, ffmt.height, asd->sink_pad_padding_w, asd->sink_pad_padding_h, dvs_env_w, dvs_env_h); __atomisp_init_stream_info(ATOMISP_INPUT_STREAM_GENERAL, stream_info); @@ -4266,28 +4263,17 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p /* Disable dvs if resolution can't be supported by sensor */ if (asd->params.video_dis_en && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { - v4l2_subdev_lock_state(input->try_sd_state); - - ret = atomisp_set_crop(isp, &vformat.format, input->try_sd_state, - V4L2_SUBDEV_FORMAT_TRY); - if (ret == 0) { - vformat.which = V4L2_SUBDEV_FORMAT_TRY; - ret = v4l2_subdev_call(input->camera, pad, set_fmt, - input->try_sd_state, &vformat); - } - - v4l2_subdev_unlock_state(input->try_sd_state); - + ret = atomisp_set_crop_and_fmt(isp, &ffmt, V4L2_SUBDEV_FORMAT_TRY); if (ret) return ret; dev_dbg(isp->dev, "video dis: sensor width: %d, height: %d\n", - ffmt->width, ffmt->height); + ffmt.width, ffmt.height); - if (ffmt->width < req_ffmt->width || - ffmt->height < req_ffmt->height) { - req_ffmt->height -= dvs_env_h; - req_ffmt->width -= dvs_env_w; + if (ffmt.width < req_ffmt.width || + ffmt.height < req_ffmt.height) { + req_ffmt.height -= dvs_env_h; + req_ffmt.width -= dvs_env_w; ffmt = req_ffmt; dev_warn(isp->dev, "can not enable video dis due to sensor limitation."); @@ -4295,32 +4281,21 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p } } - act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); - - ret = atomisp_set_crop(isp, &vformat.format, act_sd_state, - V4L2_SUBDEV_FORMAT_ACTIVE); - if (ret == 0) { - vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE; - ret = v4l2_subdev_call(input->camera, pad, set_fmt, act_sd_state, &vformat); - } - - if (act_sd_state) - v4l2_subdev_unlock_state(act_sd_state); - + ret = atomisp_set_crop_and_fmt(isp, &ffmt, V4L2_SUBDEV_FORMAT_ACTIVE); if (ret) return ret; __atomisp_update_stream_env(asd, ATOMISP_INPUT_STREAM_GENERAL, stream_info); dev_dbg(isp->dev, "sensor width: %d, height: %d\n", - ffmt->width, ffmt->height); + ffmt.width, ffmt.height); - if (ffmt->width < ATOM_ISP_STEP_WIDTH || - ffmt->height < ATOM_ISP_STEP_HEIGHT) + if (ffmt.width < ATOM_ISP_STEP_WIDTH || + ffmt.height < ATOM_ISP_STEP_HEIGHT) return -EINVAL; if (asd->params.video_dis_en && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO && - (ffmt->width < req_ffmt->width || ffmt->height < req_ffmt->height)) { + (ffmt.width < req_ffmt.width || ffmt.height < req_ffmt.height)) { dev_warn(isp->dev, "can not enable video dis due to sensor limitation."); asd->params.video_dis_en = false; @@ -4328,9 +4303,9 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p atomisp_subdev_set_ffmt(&asd->subdev, NULL, V4L2_SUBDEV_FORMAT_ACTIVE, - ATOMISP_SUBDEV_PAD_SINK, ffmt); + ATOMISP_SUBDEV_PAD_SINK, &ffmt); - return css_input_resolution_changed(asd, ffmt); + return css_input_resolution_changed(asd, &ffmt); } int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) From 4d728df5f53946fc40dbfe73dcbe9470e751c1c0 Mon Sep 17 00:00:00 2001 From: Jonathan Bergh Date: Sat, 14 Oct 2023 10:35:45 +0200 Subject: [PATCH 046/252] media: atomisp: Removed duplicate comment and fixed comment format Fixed the following issues: * Removed a duplicate comment * Fixed up minor comment format issue Link: https://lore.kernel.org/r/20231014083545.173238-1-bergh.jonathan@gmail.com Signed-off-by: Jonathan Bergh Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/gc2235.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h index 55ea422291ba..ade28950db73 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.h +++ b/drivers/staging/media/atomisp/i2c/gc2235.h @@ -74,9 +74,6 @@ #define GC2235_COARSE_INTG_TIME_MIN 1 #define GC2235_COARSE_INTG_TIME_MAX_MARGIN 6 -/* - * GC2235 System control registers - */ /* * GC2235 System control registers */ @@ -167,7 +164,7 @@ enum gc2235_tok_type { GC2235_TOK_MASK = 0xfff0 }; -/** +/* * struct gc2235_reg - MI sensor register format * @type: type of the register * @reg: 8-bit offset to register From 3e1b116f9b277b3aa5a1c08696698931d20fb82d Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Mon, 18 Dec 2023 16:17:04 +0100 Subject: [PATCH 047/252] media: atomisp: Fix spelling mistakes in ia_css_irq.h The script checkpatch.pl reported spelling errors in ia_css_irq.h as below: ''' WARNING: Possible repeated word: 'in' /** the input system in in error */ WARNING: Possible repeated word: 'in' /** the input formatter in in error */ WARNING: Possible repeated word: 'in' /** the dma in in error */ ''' This patch corrects spelling errors, changing "in" to "is" in all three comments. Link: https://lore.kernel.org/r/20231218151704.449883-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/ia_css_irq.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/ia_css_irq.h b/drivers/staging/media/atomisp/pci/ia_css_irq.h index 26b1b3c8ba62..00e2fd1f9647 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_irq.h +++ b/drivers/staging/media/atomisp/pci/ia_css_irq.h @@ -84,11 +84,11 @@ enum ia_css_irq_info { IA_CSS_IRQ_INFO_ISP_BINARY_STATISTICS_READY = BIT(17), /** ISP binary statistics are ready */ IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR = BIT(18), - /** the input system in in error */ + /** the input system is in error */ IA_CSS_IRQ_INFO_IF_ERROR = BIT(19), - /** the input formatter in in error */ + /** the input formatter is in error */ IA_CSS_IRQ_INFO_DMA_ERROR = BIT(20), - /** the dma in in error */ + /** the dma is in error */ IA_CSS_IRQ_INFO_ISYS_EVENTS_READY = BIT(21), /** end-of-frame events are ready in the isys_event queue */ }; From 7d67e4d5a7fa8d0d6b9e4311f5b97b18f47d46a9 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Mon, 18 Dec 2023 16:32:00 +0100 Subject: [PATCH 048/252] media: atomisp: Fix a spelling mistake in sh_css_defs.h The script checkpatch.pl reported a spelling error in sh_css_defs.h as below: ''' WARNING: 'upto' may be misspelled - perhaps 'up to'? /* The FPGA system (vec_nelems == 16) only supports upto 5MP */ ^^^^ ''' This patch corrects a spelling error, changing "upto" to "up to". Link: https://lore.kernel.org/r/20231218153200.450148-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css_defs.h b/drivers/staging/media/atomisp/pci/sh_css_defs.h index 7eb10b226f0a..2afde974e75d 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_defs.h +++ b/drivers/staging/media/atomisp/pci/sh_css_defs.h @@ -131,7 +131,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] * invalid rows/columns that result from filter initialization are skipped. */ #define SH_CSS_MIN_DVS_ENVELOPE 12U -/* The FPGA system (vec_nelems == 16) only supports upto 5MP */ +/* The FPGA system (vec_nelems == 16) only supports up to 5MP */ #define SH_CSS_MAX_SENSOR_WIDTH 4608 #define SH_CSS_MAX_SENSOR_HEIGHT 3450 From ce1cfe023a575bd4d3b158a8c133099f72cc3dea Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 19 Dec 2023 15:39:29 +0100 Subject: [PATCH 049/252] media: atomisp: Remove redundant assignments to variables There are several variables that are being initialized with values that are never read, the assignment are redundant and can be removed. Cleans up cppcheck unreadVariable warnings. Link: https://lore.kernel.org/r/20231219143929.367929-1-colin.i.king@gmail.com Signed-off-by: Colin Ian King Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../atomisp/pci/base/circbuf/src/circbuf.c | 2 +- .../pci/runtime/pipeline/src/pipeline.c | 2 +- .../atomisp/pci/runtime/queue/src/queue.c | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c index d9f7c143794d..06f039236abc 100644 --- a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c +++ b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c @@ -207,7 +207,7 @@ bool ia_css_circbuf_increase_size( { u8 curr_size; u8 curr_end; - unsigned int i = 0; + unsigned int i; if (!cb || sz_delta == 0) return false; diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c index 3d8741e7d5ca..9d2b5f9cbb14 100644 --- a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c +++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c @@ -693,7 +693,7 @@ static void pipeline_init_defaults( static void ia_css_pipeline_set_zoom_stage(struct ia_css_pipeline *pipeline) { struct ia_css_pipeline_stage *stage = NULL; - int err = 0; + int err; assert(pipeline); if (pipeline->pipe_id == IA_CSS_PIPE_ID_PREVIEW) { diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c index 2f1c2df59f71..c4d4062206a2 100644 --- a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c +++ b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c @@ -81,7 +81,7 @@ int ia_css_queue_uninit(ia_css_queue_t *qhandle) int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item) { - int error = 0; + int error; if (!qhandle) return -EINVAL; @@ -138,7 +138,7 @@ int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item) int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item) { - int error = 0; + int error; if (!qhandle || NULL == item) return -EINVAL; @@ -193,7 +193,7 @@ int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item) int ia_css_queue_is_full(ia_css_queue_t *qhandle, bool *is_full) { - int error = 0; + int error; if ((!qhandle) || (!is_full)) return -EINVAL; @@ -225,7 +225,7 @@ int ia_css_queue_is_full(ia_css_queue_t *qhandle, bool *is_full) int ia_css_queue_get_free_space(ia_css_queue_t *qhandle, uint32_t *size) { - int error = 0; + int error; if ((!qhandle) || (!size)) return -EINVAL; @@ -257,7 +257,7 @@ int ia_css_queue_get_free_space(ia_css_queue_t *qhandle, uint32_t *size) int ia_css_queue_get_used_space(ia_css_queue_t *qhandle, uint32_t *size) { - int error = 0; + int error; if ((!qhandle) || (!size)) return -EINVAL; @@ -289,8 +289,8 @@ int ia_css_queue_get_used_space(ia_css_queue_t *qhandle, uint32_t *size) int ia_css_queue_peek(ia_css_queue_t *qhandle, u32 offset, uint32_t *element) { - u32 num_elems = 0; - int error = 0; + u32 num_elems; + int error; if ((!qhandle) || (!element)) return -EINVAL; @@ -338,7 +338,7 @@ int ia_css_queue_peek(ia_css_queue_t *qhandle, u32 offset, uint32_t *element) int ia_css_queue_is_empty(ia_css_queue_t *qhandle, bool *is_empty) { - int error = 0; + int error; if ((!qhandle) || (!is_empty)) return -EINVAL; @@ -370,7 +370,7 @@ int ia_css_queue_is_empty(ia_css_queue_t *qhandle, bool *is_empty) int ia_css_queue_get_size(ia_css_queue_t *qhandle, uint32_t *size) { - int error = 0; + int error; if ((!qhandle) || (!size)) return -EINVAL; From 0596ea5eeb667b3890e827ba5d9b966295fae277 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Fri, 22 Dec 2023 20:40:35 +0100 Subject: [PATCH 050/252] media: atomisp: Fix repeated "of" in isp2400_input_system_public.h The script checkpatch.pl reported repeated word 'of' in isp2400_input_system_public.h as below: ''' WARNING: Possible repeated word: 'of' /*! Read from a control register PORT[port_ID] of of RECEIVER[ID] ''' This patch removes one 'of'. Link: https://lore.kernel.org/r/20231222194036.1984-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/isp2400_input_system_public.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h index 447c7c5c55a1..523c948923f3 100644 --- a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h +++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h @@ -163,7 +163,7 @@ STORAGE_CLASS_INPUT_SYSTEM_H void receiver_port_reg_store( const hrt_address reg, const hrt_data value); -/*! Read from a control register PORT[port_ID] of of RECEIVER[ID] +/*! Read from a control register PORT[port_ID] of RECEIVER[ID] \param ID[in] RECEIVER identifier \param port_ID[in] mipi PORT identifier From 5201016d0190f0dd9ff98fde0fa9ba1e1368ec1b Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Fri, 22 Dec 2023 21:15:03 +0100 Subject: [PATCH 051/252] media: atomisp: Fix spelling mistake in isp2400_input_system_global.h The script checkpatch.pl reported a spelling error in isp2400_input_system_global.h as below: ''' WARNING: 'upto' may be misspelled - perhaps 'up to'? //MIPI allows upto 4 channels. ^^^^ ''' This patch corrects a spelling error, changing "upto" to "up to". Link: https://lore.kernel.org/r/20231222201503.2337-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/isp2400_input_system_global.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h index 61f23814e2fd..3ff61faf0621 100644 --- a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h +++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h @@ -19,7 +19,7 @@ #define N_CSI_PORTS (3) //AM: Use previous define for this. -//MIPI allows upto 4 channels. +//MIPI allows up to 4 channels. #define N_CHANNELS (4) // 12KB = 256bit x 384 words #define IB_CAPACITY_IN_WORDS (384) From 657d6ee589cf8acf886828f50518c38e374c7b27 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 07:04:22 +0100 Subject: [PATCH 052/252] media: atomisp: Fix spelling mistakes in circbuf.c codespell reported following spelling mistakes in circbuf.c as below: ''' ./circbuf.c:27: whehter ==> whether ./circbuf.c:132: offest ==> offset ''' This patch fixes these spelling mistakes. Link: https://lore.kernel.org/r/20231223060422.77789-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Acked-by: Randy Dunlap Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c index 06f039236abc..198c9f6e6191 100644 --- a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c +++ b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c @@ -24,7 +24,7 @@ **********************************************************************/ /* * @brief Read the oldest element from the circular buffer. - * Read the oldest element WITHOUT checking whehter the + * Read the oldest element WITHOUT checking whether the * circular buffer is empty or not. The oldest element is * also removed out from the circular buffer. * @@ -129,7 +129,7 @@ uint32_t ia_css_circbuf_extract(ia_css_circbuf_t *cb, int offset) u32 src_pos; u32 dest_pos; - /* get the maximum offest */ + /* get the maximum offset */ max_offset = ia_css_circbuf_get_offset(cb, cb->desc->start, cb->desc->end); max_offset--; From 90953ea685d2006421720d8a5fb0662fc61f1135 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 07:16:47 +0100 Subject: [PATCH 053/252] media: atomisp: Fix spelling mistake in ia_css_circbuf.h codespell reported following spelling mistake in ia_css_circbuf.h as below: ''' ./base/circbuf/interface/ia_css_circbuf.h:76: poistion ==> position ''' This patch fixes this spelling mistake. Link: https://lore.kernel.org/r/20231223061647.78669-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Acked-by: Randy Dunlap Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h index 0579deac5535..e9846951f4ed 100644 --- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h +++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h @@ -73,7 +73,7 @@ uint32_t ia_css_circbuf_pop( /** * @brief Extract a value out of the circular buffer. - * Get a value at an arbitrary poistion in the circular + * Get a value at an arbitrary position in the circular * buffer. The user should call "ia_css_circbuf_is_empty()" * to avoid accessing to an empty buffer. * From 8cf2ae5c2868956dfa09397e91925515cf1e6ba9 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 07:41:52 +0100 Subject: [PATCH 054/252] media: atomisp: Fix spelling mistakes in sh_css_mipi.c codespell reported following spelling mistake in sh_css_mipi.c as below: ''' ./sh_css_mipi.c:177: separatelly ==> separately ./sh_css_mipi.c:540: ofset ==> offset, of set ''' This patch fixes these spelling mistakes by changing "separatelly" to "separately" and "ofset" to "offset". Link: https://lore.kernel.org/r/20231223064152.79712-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css_mipi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c index b7c1e164ee24..6e11fd771938 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c +++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c @@ -174,7 +174,7 @@ ia_css_mipi_frame_calculate_size(const unsigned int width, mem_words = ((embedded_data_size_words + 7) >> 3) + mem_words_for_first_line + (((height + 1) >> 1) - 1) * mem_words_per_odd_line + - /* ceil (height/2) - 1 (first line is calculated separatelly) */ + /* ceil (height/2) - 1 (first line is calculated separately) */ (height >> 1) * mem_words_per_even_line + /* floor(height/2) */ mem_words_for_EOF; @@ -537,7 +537,7 @@ send_mipi_frames(struct ia_css_pipe *pipe) /* Hand-over the SP-internal mipi buffers */ for (i = 0; i < my_css.num_mipi_frames[port]; i++) { - /* Need to include the ofset for port. */ + /* Need to include the offset for port. */ sh_css_update_host2sp_mipi_frame(port * NUM_MIPI_FRAMES_PER_STREAM + i, my_css.mipi_frames[port][i]); sh_css_update_host2sp_mipi_metadata(port * NUM_MIPI_FRAMES_PER_STREAM + i, From b68a8c794667e2db78dc794092c9c6e6cbb7b360 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 08:11:57 +0100 Subject: [PATCH 055/252] media: atomisp: Fix spelling mistakes in queue.c codespell reported following spelling mistake in queue.c as below: ''' ./runtime/queue/src/queue.c:126: uncessary ==> unnecessary ./runtime/queue/src/queue.c:183: uncessary ==> unnecessary ''' This patch fixes these spelling mistakes. Link: https://lore.kernel.org/r/20231223071157.81082-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c index c4d4062206a2..0e430388b331 100644 --- a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c +++ b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c @@ -123,7 +123,7 @@ int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item) /* c. Store the queue object */ /* Set only fields requiring update with - * valid value. Avoids uncessary calls + * valid value. Avoids unnecessary calls * to load/store functions */ ignore_desc_flags = QUEUE_IGNORE_SIZE_START_STEP_FLAGS; @@ -180,7 +180,7 @@ int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item) /* c. Store the queue object */ /* Set only fields requiring update with - * valid value. Avoids uncessary calls + * valid value. Avoids unnecessary calls * to load/store functions */ ignore_desc_flags = QUEUE_IGNORE_SIZE_END_STEP_FLAGS; From 914ec2149f896f86c39d0fd21dae58207ecf37fb Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 08:22:45 +0100 Subject: [PATCH 056/252] media: atomisp: Fix spelling mistakes in rmgr_vbuf.c codespell reported following spelling mistake in rmgr_vbuf.cas below: ''' ./runtime/rmgr/src/rmgr_vbuf.c:201: succes ==> success ./runtime/rmgr/src/rmgr_vbuf.c:211: succes ==> success ./runtime/rmgr/src/rmgr_vbuf.c:215: succes ==> success ''' This patch fixes these spelling mistakes. It is good to use variable name that gives proper meaning and spelling error free. Link: https://lore.kernel.org/r/20231223072245.81630-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c index 2e07dab8bf51..1f24db77fe38 100644 --- a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c +++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c @@ -198,7 +198,7 @@ void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool, struct ia_css_rmgr_vbuf_handle **handle) { u32 i; - bool succes = false; + bool success = false; assert(pool); assert(pool->recycle); @@ -208,11 +208,11 @@ void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool, if (!pool->handles[i]) { ia_css_rmgr_refcount_retain_vbuf(handle); pool->handles[i] = *handle; - succes = true; + success = true; break; } } - assert(succes); + assert(success); } /* From ddef5a9175000410c0f16bda84428051e501b0ce Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 09:13:54 +0100 Subject: [PATCH 057/252] media: atomisp: Fix spelling mistakes in ia_css_macc_table.host.c codespell reported following spelling mistake in ia_css_macc_table.host.c below: ''' ./isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c:22: matix ==> matrix ./isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c:39: matix ==> matrix ''' This patch fixes these spelling mistakes. Link: https://lore.kernel.org/r/20231223081354.83318-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c index 946b074e8288..d25bf59273ba 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c +++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c @@ -19,7 +19,7 @@ /* Multi-Axes Color Correction table for ISP1. * 64values = 2x2matrix for 16area, [s2.13] - * ineffective: 16 of "identity 2x2 matix" {8192,0,0,8192} + * ineffective: 16 of "identity 2x2 matrix" {8192,0,0,8192} */ const struct ia_css_macc_table default_macc_table = { { @@ -36,7 +36,7 @@ const struct ia_css_macc_table default_macc_table = { /* Multi-Axes Color Correction table for ISP2. * 64values = 2x2matrix for 16area, [s1.12] - * ineffective: 16 of "identity 2x2 matix" {4096,0,0,4096} + * ineffective: 16 of "identity 2x2 matrix" {4096,0,0,4096} */ const struct ia_css_macc_table default_macc2_table = { { From 38c56d81741cd10c6724d74903641329af4108a7 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 09:31:57 +0100 Subject: [PATCH 058/252] media: atomisp: Fix spelling mistakes in ia_css_hdr_types.h codespell reported following spelling mistake in ia_css_hdr_types.h below: ''' ./isp/kernels/hdr/ia_css_hdr_types.h:60: paramterers ==> parameters ./isp/kernels/hdr/ia_css_hdr_types.h:62: Currenly ==> Currently ''' This patch fixes these spelling mistakes. Link: https://lore.kernel.org/r/20231223083157.84090-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h index 175c301ee96a..ecc98686f5cf 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h +++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h @@ -57,9 +57,9 @@ struct ia_css_hdr_exclusion_params { }; /** - * \brief HDR public paramterers. + * \brief HDR public parameters. * \details Struct with all parameters for HDR that can be seet from - * the CSS API. Currenly, only test parameters are defined. + * the CSS API. Currently, only test parameters are defined. */ struct ia_css_hdr_config { struct ia_css_hdr_irradiance_params irradiance; /** HDR irradiance parameters */ From 3b63b7db1d9298847c90905a426f589a7f9beaae Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 10:15:21 +0100 Subject: [PATCH 059/252] media: atomisp: Fix spelling mistake in binary.c codespell reported following spelling mistake in runtime/binary/src as below: ''' ./runtime/binary/src/binary.c:537: spcification ==> specification ''' This patch fixes thisspelling mistake. Link: https://lore.kernel.org/r/20231223091521.85467-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c index 0f3729e55e14..130662f8e768 100644 --- a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c +++ b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c @@ -534,7 +534,7 @@ ia_css_binary_uninit(void) { static int binary_grid_deci_factor_log2(int width, int height) { - /* 3A/Shading decimation factor spcification (at August 2008) + /* 3A/Shading decimation factor specification (at August 2008) * ------------------------------------------------------------------ * [Image Width (BQ)] [Decimation Factor (BQ)] [Resulting grid cells] * 1280 ?c 32 40 ?c From 89354baf8f151d34aab5b7e8f44e719165fa7d73 Mon Sep 17 00:00:00 2001 From: Dipendra Khadka Date: Sat, 23 Dec 2023 15:11:57 +0100 Subject: [PATCH 060/252] media: atomisp: Fix spelling mistake in ia_css_acc_types.h codespell reported spelling mistakes in ia_css_acc_types.h as below: ''' ia_css_acc_types.h:87: cummulative ==> cumulative ia_css_acc_types.h:411: descibes ==> describes ''' This patch fixes these spelling mistakes. Word "cummulative" is changed to "accumulation" and "descibes" to "describes". Link: https://lore.kernel.org/r/20231223141157.95501-1-kdipendra88@gmail.com Signed-off-by: Dipendra Khadka Reviewed-by: Randy Dunlap Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/ia_css_acc_types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h index d6e52b4971d6..f6838a8fc9d5 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h +++ b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h @@ -84,7 +84,7 @@ struct ia_css_blob_info { memory_offsets; /** offset wrt hdr in bytes */ u32 prog_name_offset; /** offset wrt hdr in bytes */ u32 size; /** Size of blob */ - u32 padding_size; /** total cummulative of bytes added due to section alignment */ + u32 padding_size; /** total accumulation of bytes added due to section alignment */ u32 icache_source; /** Position of icache in blob */ u32 icache_size; /** Size of icache section */ u32 icache_padding;/** bytes added due to icache section alignment */ @@ -408,7 +408,7 @@ struct ia_css_acc_sp { }; /* Acceleration firmware descriptor. - * This descriptor descibes either SP code (stand-alone), or + * This descriptor describes either SP code (stand-alone), or * ISP code (a separate pipeline stage). */ struct ia_css_acc_fw_hdr { From e49665636835cfee3f1844ae7125369bb381784b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 28 Dec 2023 21:28:07 +0100 Subject: [PATCH 061/252] media: atomisp: Remove s_routing subdev call sensor drivers do not implement the s_routing subdev call, so there is no use in calling it. Also the 3 0 arguments are not the arguments which a successful s_routing call is supposed to take. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index 5b2d88c02d36..bb8e5e883b50 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -666,14 +666,6 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input) return ret; } - /* select operating sensor */ - ret = v4l2_subdev_call(isp->inputs[input].camera, video, s_routing, - 0, 0, 0); - if (ret && (ret != -ENOIOCTLCMD)) { - dev_err(isp->dev, "Failed to select sensor\n"); - return ret; - } - if (!IS_ISP2401) { motor = isp->inputs[input].motor; } else { From 571f043d2ab24d314ec2516dc51e31d43977b2f8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 10 Nov 2023 17:48:48 +0100 Subject: [PATCH 062/252] media: atomisp: Remove remaining deferred firmware loading code There is a bunch of dead code left from the deferred firmware loading support which was removed in commit 8972ed6ea7a0 ("media: atomisp: Remove deferred firmware loading support"). Remove this dead code: - Remove the skip_fwload module parameter - Remove the now always NULL fw argument from ia_css_init() - Remove the fw_explicitly_loaded boolean from sh_css.c (this was always true now) - Adjust some function kernel-doc comments to match Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/pci/atomisp_compat_css20.c | 2 +- .../staging/media/atomisp/pci/atomisp_v4l2.c | 9 ----- .../media/atomisp/pci/ia_css_control.h | 29 +++++----------- .../media/atomisp/pci/ia_css_firmware.h | 6 ++-- drivers/staging/media/atomisp/pci/sh_css.c | 33 ++----------------- 5 files changed, 14 insertions(+), 65 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index 02f06294bbfe..6fe8b0b7467a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -757,7 +757,7 @@ int atomisp_css_init(struct atomisp_device *isp) return ret; /* Init ISP */ - err = ia_css_init(isp->dev, &isp->css_env.isp_css_env, NULL, + err = ia_css_init(isp->dev, &isp->css_env.isp_css_env, (uint32_t)mmu_base_addr, IA_CSS_IRQ_TYPE_PULSE); if (err) { dev_err(isp->dev, "css init failed --- bad firmware?\n"); diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 547e1444ad97..206fdaee5952 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -55,10 +55,6 @@ /* G-Min addition: pull this in from intel_mid_pm.h */ #define CSTATE_EXIT_LATENCY_C1 1 -static uint skip_fwload; -module_param(skip_fwload, uint, 0644); -MODULE_PARM_DESC(skip_fwload, "Skip atomisp firmware load"); - /* cross componnet debug message flag */ int dbg_level; module_param(dbg_level, int, 0644); @@ -1161,9 +1157,6 @@ atomisp_load_firmware(struct atomisp_device *isp) int rc; char *fw_path = NULL; - if (skip_fwload) - return NULL; - if (firmware_name[0] != '\0') { fw_path = firmware_name; } else { @@ -1591,8 +1584,6 @@ static void atomisp_pci_remove(struct pci_dev *pdev) atomisp_msi_irq_uninit(isp); atomisp_unregister_entities(isp); - - release_firmware(isp->firmware); } static const struct pci_device_id atomisp_pci_tbl[] = { diff --git a/drivers/staging/media/atomisp/pci/ia_css_control.h b/drivers/staging/media/atomisp/pci/ia_css_control.h index 88f031a63ba2..6a473459b346 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_control.h +++ b/drivers/staging/media/atomisp/pci/ia_css_control.h @@ -30,39 +30,28 @@ * environment in which the CSS code runs. This is * used for host side memory access and message * printing. May not be NULL. - * @param[in] fw Firmware package containing the firmware for all - * predefined ISP binaries. - * if fw is NULL the firmware must be loaded before - * through a call of ia_css_load_firmware * @param[in] l1_base Base index (isp2400) * of the L1 page table. This is a physical * address or index. * @param[in] irq_type The type of interrupt to be used (edge or level) - * @return Returns -EINVAL in case of any + * @return Returns -EINVAL in case of any * errors and 0 otherwise. * * This function initializes the API which includes allocating and initializing - * internal data structures. This also interprets the firmware package. All - * contents of this firmware package are copied into local data structures, so - * the fw pointer could be freed after this function completes. + * internal data structures. + * ia_css_load_firmware() must be called to load the firmware before calling + * this function. */ int ia_css_init(struct device *dev, - const struct ia_css_env *env, - const struct ia_css_fw *fw, - u32 l1_base, - enum ia_css_irq_type irq_type); + const struct ia_css_env *env, + u32 l1_base, + enum ia_css_irq_type irq_type); /* @brief Un-initialize the CSS API. * @return None * - * This function deallocates all memory that has been allocated by the CSS API - * Exception: if you explicitly loaded firmware through ia_css_load_firmware - * you need to call ia_css_unload_firmware to deallocate the memory reserved - * for the firmware. - * After this function is called, no other CSS functions should be called - * with the exception of ia_css_init which will re-initialize the CSS code, - * ia_css_unload_firmware to unload the firmware or ia_css_load_firmware - * to load new firmware + * This function deallocates all memory that has been allocated by the CSS API. + * After this function is called, no other CSS functions should be called. */ void ia_css_uninit(void); diff --git a/drivers/staging/media/atomisp/pci/ia_css_firmware.h b/drivers/staging/media/atomisp/pci/ia_css_firmware.h index 01d2faf557cf..d3a66128b4de 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_firmware.h +++ b/drivers/staging/media/atomisp/pci/ia_css_firmware.h @@ -46,10 +46,6 @@ struct device; * This function interprets the firmware package. All * contents of this firmware package are copied into local data structures, so * the fw pointer could be freed after this function completes. - * - * Rationale for this function is that it can be called before ia_css_init, and thus - * speeds up ia_css_init (ia_css_init is called each time a stream is created but the - * firmware only needs to be loaded once). */ int ia_css_load_firmware(struct device *dev, const struct ia_css_env *env, @@ -61,6 +57,8 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env, * This function unloads the firmware loaded by ia_css_load_firmware. * It is pointless to call this function if no firmware is loaded, * but it won't harm. Use this to deallocate all memory associated with the firmware. + * This function may only be called when the CSS API is in uninitialized state + * (e.g. after calling ia_css_uninit()). */ void ia_css_unload_firmware(void); diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index f35c90809414..1d1fbda75da1 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -174,8 +174,6 @@ static struct sh_css_hmm_buffer_record hmm_buffer_record[MAX_HMM_BUFFER_NUM]; #define GPIO_FLASH_PIN_MASK BIT(HIVE_GPIO_STROBE_TRIGGER_PIN) -static bool fw_explicitly_loaded; - /* * Local prototypes */ @@ -1360,7 +1358,6 @@ ia_css_unload_firmware(void) ia_css_binary_uninit(); sh_css_unload_firmware(); } - fw_explicitly_loaded = false; } static void @@ -1405,13 +1402,9 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env, my_css.flush = env->cpu_mem_env.flush; } - ia_css_unload_firmware(); /* in case we are called twice */ err = sh_css_load_firmware(dev, fw->data, fw->bytes); - if (!err) { + if (!err) err = ia_css_binary_init_infos(); - if (!err) - fw_explicitly_loaded = true; - } ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() leave\n"); return err; @@ -1419,9 +1412,7 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env, int ia_css_init(struct device *dev, const struct ia_css_env *env, - const struct ia_css_fw *fw, - u32 mmu_l1_base, - enum ia_css_irq_type irq_type) + u32 mmu_l1_base, enum ia_css_irq_type irq_type) { int err; ia_css_spctrl_cfg spctrl_cfg; @@ -1466,8 +1457,6 @@ ia_css_init(struct device *dev, const struct ia_css_env *env, /* Check struct ia_css_init_dmem_cfg */ COMPILATION_ERROR_IF(sizeof(struct ia_css_sp_init_dmem_cfg) != SIZE_OF_IA_CSS_SP_INIT_DMEM_CFG_STRUCT); - if (!fw && !fw_explicitly_loaded) - return -EINVAL; if (!env) return -EINVAL; @@ -1543,22 +1532,7 @@ ia_css_init(struct device *dev, const struct ia_css_env *env, IA_CSS_LEAVE_ERR(err); return err; } - if (fw) { - ia_css_unload_firmware(); /* in case we already had firmware loaded */ - err = sh_css_load_firmware(dev, fw->data, fw->bytes); - if (err) { - IA_CSS_LEAVE_ERR(err); - return err; - } - err = ia_css_binary_init_infos(); - if (err) { - IA_CSS_LEAVE_ERR(err); - return err; - } - fw_explicitly_loaded = false; - my_css_save.loaded_fw = (struct ia_css_fw *)fw; - } if (!sh_css_setup_spctrl_config(&sh_css_sp_fw, SP_PROG_NAME, &spctrl_cfg)) return -EINVAL; @@ -2163,9 +2137,6 @@ ia_css_uninit(void) ifmtr_set_if_blocking_mode_reset = true; } - if (!fw_explicitly_loaded) - ia_css_unload_firmware(); - ia_css_spctrl_unload_fw(SP0_ID); sh_css_sp_set_sp_running(false); /* check and free any remaining mipi frames */ From f18ae7203f6fdb0cfb408ab82807bcd700e33a96 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 26 Dec 2023 16:32:10 +0100 Subject: [PATCH 063/252] media: atomisp: Drop is_valid_device() function Now that a single build supports both the ISP 2400 and the ISP 2401 this function is no longer necessary. The main probe() already contains a similar switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) checking for a known device_id. Move the revision check into the main probe() and drop the is_valid_device() function. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_v4l2.c | 50 ++----------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 206fdaee5952..176b39906d10 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1192,48 +1192,6 @@ atomisp_load_firmware(struct atomisp_device *isp) return fw; } -/* - * Check for flags the driver was compiled with against the PCI - * device. Always returns true on other than ISP 2400. - */ -static bool is_valid_device(struct pci_dev *pdev, const struct pci_device_id *id) -{ - const char *name; - const char *product; - - product = dmi_get_system_info(DMI_PRODUCT_NAME); - - switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) { - case ATOMISP_PCI_DEVICE_SOC_MRFLD: - name = "Merrifield"; - break; - case ATOMISP_PCI_DEVICE_SOC_BYT: - name = "Baytrail"; - break; - case ATOMISP_PCI_DEVICE_SOC_ANN: - name = "Anniedale"; - break; - case ATOMISP_PCI_DEVICE_SOC_CHT: - name = "Cherrytrail"; - break; - default: - dev_err(&pdev->dev, "%s: unknown device ID %x04:%x04\n", - product, id->vendor, id->device); - return false; - } - - if (pdev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) { - dev_err(&pdev->dev, "%s revision %d is not unsupported\n", - name, pdev->revision); - return false; - } - - dev_info(&pdev->dev, "Detected %s version %d (ISP240%c) on %s\n", - name, pdev->revision, IS_ISP2401 ? '1' : '0', product); - - return true; -} - #define ATOM_ISP_PCI_BAR 0 static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -1244,9 +1202,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i int err, val; u32 irq; - if (!is_valid_device(pdev, id)) - return -ENODEV; - /* Pointer to struct device. */ atomisp_dev = &pdev->dev; @@ -1386,6 +1341,11 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i goto atomisp_dev_alloc_fail; } + if (pdev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) { + dev_err(&pdev->dev, "revision %d is not unsupported\n", pdev->revision); + return -ENODEV; + } + dev_info(&pdev->dev, "ISP HPLL frequency base = %d MHz\n", isp->hpll_freq); isp->max_isr_latency = ATOMISP_MAX_ISR_LATENCY; From 62c319a51bcfdc81ce31036dcffa5c5381b0ea54 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Nov 2023 21:29:28 +0100 Subject: [PATCH 064/252] media: atomisp: Call pcim_enable_device() and pcim_iomap_regions() later ATM the atomisp firmware is not available in linux-firmware, so most users will not have it installed. Move pcim_enable_device() and pcim_iomap_regions() down in atomisp_pci_probe() so that they are never called when the firmware is not there. This is a preparation patch for making the atomisp driver handle missing firmware better. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_v4l2.c | 45 +++++++++---------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 176b39906d10..0eea20704e66 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1209,33 +1209,16 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i if (!pdata) dev_warn(&pdev->dev, "no platform data available\n"); - err = pcim_enable_device(pdev); - if (err) { - dev_err(&pdev->dev, "Failed to enable CI ISP device (%d)\n", err); - return err; - } - start = pci_resource_start(pdev, ATOM_ISP_PCI_BAR); dev_dbg(&pdev->dev, "start: 0x%x\n", start); - err = pcim_iomap_regions(pdev, BIT(ATOM_ISP_PCI_BAR), pci_name(pdev)); - if (err) { - dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", err); - goto ioremap_fail; - } - isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); - if (!isp) { - err = -ENOMEM; - goto atomisp_dev_alloc_fail; - } + if (!isp) + return -ENOMEM; isp->dev = &pdev->dev; - isp->base = pcim_iomap_table(pdev)[ATOM_ISP_PCI_BAR]; isp->saved_regs.ispmmadr = start; - dev_dbg(&pdev->dev, "atomisp mmio base: %p\n", isp->base); - mutex_init(&isp->mutex); spin_lock_init(&isp->lock); @@ -1337,8 +1320,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i break; default: dev_err(&pdev->dev, "un-supported IUNIT device\n"); - err = -ENODEV; - goto atomisp_dev_alloc_fail; + return -ENODEV; } if (pdev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) { @@ -1364,6 +1346,20 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i goto fw_validation_fail; } + err = pcim_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Failed to enable ISP PCI device (%d)\n", err); + goto pci_enable_fail; + } + + err = pcim_iomap_regions(pdev, BIT(ATOM_ISP_PCI_BAR), pci_name(pdev)); + if (err) { + dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", err); + goto ioremap_fail; + } + + isp->base = pcim_iomap_table(pdev)[ATOM_ISP_PCI_BAR]; + pci_set_master(pdev); err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); @@ -1495,6 +1491,9 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i atomisp_msi_irq_uninit(isp); pci_free_irq_vectors(pdev); enable_msi_fail: + pcim_iounmap_regions(pdev, BIT(ATOM_ISP_PCI_BAR)); +ioremap_fail: +pci_enable_fail: fw_validation_fail: release_firmware(isp->firmware); load_fw_fail: @@ -1519,10 +1518,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power(isp, false)) dev_err(&pdev->dev, "Failed to switch off ISP\n"); -atomisp_dev_alloc_fail: - pcim_iounmap_regions(pdev, BIT(ATOM_ISP_PCI_BAR)); - -ioremap_fail: return err; } From 7f7b6b5da0d631bc141cf67b08d8c3826d579335 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 27 Dec 2023 21:45:48 +0100 Subject: [PATCH 065/252] media: atomisp: Fix probe error-exit path Fix probe error-exit path: -Add a missing ia_css_unload_firmware() call when v4l2_async_nf_register() fails -Add a missing pm_runtime_forbid() call to undo the pm_runtime_allow() call -Remove the unnecessary pcim_iounmap_regions() those are devm managed so they will get cleaned up automatically on an error exit from probe() -Rename the labels to avoid having multiple labels pointing to the same place in the error-exit path Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_v4l2.c | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 0eea20704e66..336c5a895ecc 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1337,25 +1337,25 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i if (!isp->firmware) { err = -ENOENT; dev_dbg(&pdev->dev, "Firmware load failed\n"); - goto load_fw_fail; + goto error_power_off; } err = sh_css_check_firmware_version(isp->dev, isp->firmware->data); if (err) { dev_dbg(&pdev->dev, "Firmware version check failed\n"); - goto fw_validation_fail; + goto error_release_firmware; } err = pcim_enable_device(pdev); if (err) { dev_err(&pdev->dev, "Failed to enable ISP PCI device (%d)\n", err); - goto pci_enable_fail; + goto error_release_firmware; } err = pcim_iomap_regions(pdev, BIT(ATOM_ISP_PCI_BAR), pci_name(pdev)); if (err) { dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", err); - goto ioremap_fail; + goto error_release_firmware; } isp->base = pcim_iomap_table(pdev)[ATOM_ISP_PCI_BAR]; @@ -1365,7 +1365,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); if (err < 0) { dev_err(&pdev->dev, "Failed to enable msi (%d)\n", err); - goto enable_msi_fail; + goto error_release_firmware; } atomisp_msi_irq_init(isp); @@ -1408,13 +1408,13 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i err = atomisp_initialize_modules(isp); if (err < 0) { dev_err(&pdev->dev, "atomisp_initialize_modules (%d)\n", err); - goto initialize_modules_fail; + goto error_irq_uninit; } err = atomisp_register_entities(isp); if (err < 0) { dev_err(&pdev->dev, "atomisp_register_entities failed (%d)\n", err); - goto register_entities_fail; + goto error_uninitialize_modules; } INIT_WORK(&isp->assert_recovery_work, atomisp_assert_recovery_work); @@ -1453,14 +1453,14 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i IRQF_SHARED, "isp_irq", isp); if (err) { dev_err(&pdev->dev, "Failed to request irq (%d)\n", err); - goto request_irq_fail; + goto error_unregister_entities; } /* Load firmware into ISP memory */ err = atomisp_css_load_firmware(isp); if (err) { dev_err(&pdev->dev, "Failed to init css.\n"); - goto css_init_fail; + goto error_free_irq; } /* Clear FW image from memory */ release_firmware(isp->firmware); @@ -1470,33 +1470,32 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i err = v4l2_async_nf_register(&isp->notifier); if (err) { dev_err(isp->dev, "failed to register async notifier : %d\n", err); - goto css_init_fail; + goto error_unload_firmware; } atomisp_drvfs_init(isp); return 0; -css_init_fail: +error_unload_firmware: + ia_css_unload_firmware(); +error_free_irq: devm_free_irq(&pdev->dev, pdev->irq, isp); -request_irq_fail: +error_unregister_entities: hmm_cleanup(); + pm_runtime_forbid(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); dev_pm_domain_set(&pdev->dev, NULL); atomisp_unregister_entities(isp); -register_entities_fail: +error_uninitialize_modules: atomisp_uninitialize_modules(isp); -initialize_modules_fail: +error_irq_uninit: cpu_latency_qos_remove_request(&isp->pm_qos); atomisp_msi_irq_uninit(isp); pci_free_irq_vectors(pdev); -enable_msi_fail: - pcim_iounmap_regions(pdev, BIT(ATOM_ISP_PCI_BAR)); -ioremap_fail: -pci_enable_fail: -fw_validation_fail: +error_release_firmware: release_firmware(isp->firmware); -load_fw_fail: +error_power_off: /* * Switch off ISP, as keeping it powered on would prevent * reaching S0ix states. From ba68b88da0a2e6d72ac92738dbad0a1934e2283d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 27 Dec 2023 22:47:45 +0100 Subject: [PATCH 066/252] media: atomisp: Fix atomisp_pci_remove() Fix atomisp_pci_remove(): -Remove uninformative "Removing atomisp driver" log message -Add missing devm_free_irq(), atomisp_uninitialize_modules() and pci_free_irq_vectors() calls -Move atomisp_msi_irq_uninit() down so that the remove() order is an exact mirror of the probe() order Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 336c5a895ecc..f3bd2c03dea5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1524,11 +1524,10 @@ static void atomisp_pci_remove(struct pci_dev *pdev) { struct atomisp_device *isp = pci_get_drvdata(pdev); - dev_info(&pdev->dev, "Removing atomisp driver\n"); - atomisp_drvfs_exit(); ia_css_unload_firmware(); + devm_free_irq(&pdev->dev, pdev->irq, isp); hmm_cleanup(); pm_runtime_forbid(&pdev->dev); @@ -1536,8 +1535,10 @@ static void atomisp_pci_remove(struct pci_dev *pdev) dev_pm_domain_set(&pdev->dev, NULL); cpu_latency_qos_remove_request(&isp->pm_qos); - atomisp_msi_irq_uninit(isp); atomisp_unregister_entities(isp); + atomisp_uninitialize_modules(isp); + atomisp_msi_irq_uninit(isp); + pci_free_irq_vectors(pdev); } static const struct pci_device_id atomisp_pci_tbl[] = { From 3a9ceebd8ffb2d6dca14ddf58a21c98b124713f9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 27 Dec 2023 23:02:40 +0100 Subject: [PATCH 067/252] media: atomisp: Group cpu_latency_qos_add_request() call together with other PM calls Group the cpu_latency_qos_add_request() call in probe() together with the other PM calls in probe(). This is a preparation patch for futher PM fixes / work. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index f3bd2c03dea5..7d99b53107b0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1370,8 +1370,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i atomisp_msi_irq_init(isp); - cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); - /* * for MRFLD, Software/firmware needs to write a 1 to bit 0 of * the register at CSI_RECEIVER_SELECTION_REG to enable SH CSI @@ -1440,6 +1438,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i isp->pm_domain.ops.suspend = atomisp_suspend; isp->pm_domain.ops.resume = atomisp_resume; + cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); dev_pm_domain_set(&pdev->dev, &isp->pm_domain); pm_runtime_put_noidle(&pdev->dev); @@ -1486,11 +1485,11 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i pm_runtime_forbid(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); dev_pm_domain_set(&pdev->dev, NULL); + cpu_latency_qos_remove_request(&isp->pm_qos); atomisp_unregister_entities(isp); error_uninitialize_modules: atomisp_uninitialize_modules(isp); error_irq_uninit: - cpu_latency_qos_remove_request(&isp->pm_qos); atomisp_msi_irq_uninit(isp); pci_free_irq_vectors(pdev); error_release_firmware: From 781bf4cee3c160a5ce97d86719675083a2f2a67c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 27 Dec 2023 23:20:11 +0100 Subject: [PATCH 068/252] media: atomisp: Fix probe()/remove() power-management Fix probe()/remove() power-management: -Currently the driver uses pm_runtime_put_noidle() and relies on userspace to open + close the /dev/video# node at least once to actually turn the ISP off. Replace the pm_runtime_put_noidle() with pm_runtime_put_sync() to make sure that the device is turned off without relying on userspace for this. This also ensures that atomisp_css_init() is run (by atomisp_power_on()) if the first userspace process opening /dev/video# wants to do more then just query the v4l2-caps. As part of this change move the pm setup code in probe() to just before calling v4l2_async_nf_register() which registers the /dev/* nodes, so that the device is left on for the entirety of the probe() function. -Remove the turning off of the atomisp from the exit-error path, the PCI subsystem and subsequent probe() attempts expect the device to be in the on state when probe() fails. This also fixes the atomisp driver causing the system to hang / freeze when its firmware is missing. This freeze is caused by an unidentified bug in the power-off on exit-error code which is now removed. -Make sure that remove() properly powers on the device by replacing pm_runtime_get_noresume() with pm_runtime_get_sync. The PCI subsystem and subsequent probe() attempts expect the device to be in the on state after unbinding the driver. -Note this also swaps the order of put()/allow() and forbid()/get() so that the sync versions actually work by calling allow() before put() and forbid() after get() Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_v4l2.c | 98 +++++++------------ 1 file changed, 37 insertions(+), 61 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 7d99b53107b0..6e8c9add35f9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1200,7 +1200,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i struct atomisp_device *isp; unsigned int start; int err, val; - u32 irq; /* Pointer to struct device. */ atomisp_dev = &pdev->dev; @@ -1334,11 +1333,8 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i /* Load isp firmware from user space */ isp->firmware = atomisp_load_firmware(isp); - if (!isp->firmware) { - err = -ENOENT; - dev_dbg(&pdev->dev, "Firmware load failed\n"); - goto error_power_off; - } + if (!isp->firmware) + return -ENOENT; err = sh_css_check_firmware_version(isp->dev, isp->firmware->data); if (err) { @@ -1420,30 +1416,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i /* save the iunit context only once after all the values are init'ed. */ atomisp_save_iunit_reg(isp); - /* - * The atomisp does not use standard PCI power-management through the - * PCI config space. Instead this driver directly tells the P-Unit to - * disable the ISP over the IOSF. The standard PCI subsystem pm_ops will - * try to access the config space before (resume) / after (suspend) this - * driver has turned the ISP on / off, resulting in the following errors: - * - * "Unable to change power state from D0 to D3hot, device inaccessible" - * "Unable to change power state from D3cold to D0, device inaccessible" - * - * To avoid these errors override the pm_domain so that all the PCI - * subsys suspend / resume handling is skipped. - */ - isp->pm_domain.ops.runtime_suspend = atomisp_power_off; - isp->pm_domain.ops.runtime_resume = atomisp_power_on; - isp->pm_domain.ops.suspend = atomisp_suspend; - isp->pm_domain.ops.resume = atomisp_resume; - - cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); - dev_pm_domain_set(&pdev->dev, &isp->pm_domain); - - pm_runtime_put_noidle(&pdev->dev); - pm_runtime_allow(&pdev->dev); - /* Init ISP memory management */ hmm_init(); @@ -1466,6 +1438,30 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i isp->firmware = NULL; isp->css_env.isp_css_fw.data = NULL; + /* + * The atomisp does not use standard PCI power-management through the + * PCI config space. Instead this driver directly tells the P-Unit to + * disable the ISP over the IOSF. The standard PCI subsystem pm_ops will + * try to access the config space before (resume) / after (suspend) this + * driver has turned the ISP on / off, resulting in the following errors: + * + * "Unable to change power state from D0 to D3hot, device inaccessible" + * "Unable to change power state from D3cold to D0, device inaccessible" + * + * To avoid these errors override the pm_domain so that all the PCI + * subsys suspend / resume handling is skipped. + */ + isp->pm_domain.ops.runtime_suspend = atomisp_power_off; + isp->pm_domain.ops.runtime_resume = atomisp_power_on; + isp->pm_domain.ops.suspend = atomisp_suspend; + isp->pm_domain.ops.resume = atomisp_resume; + + cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); + dev_pm_domain_set(&pdev->dev, &isp->pm_domain); + + pm_runtime_allow(&pdev->dev); + pm_runtime_put_sync_suspend(&pdev->dev); + err = v4l2_async_nf_register(&isp->notifier); if (err) { dev_err(isp->dev, "failed to register async notifier : %d\n", err); @@ -1477,15 +1473,15 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i return 0; error_unload_firmware: + pm_runtime_get_sync(&pdev->dev); + pm_runtime_forbid(&pdev->dev); + dev_pm_domain_set(&pdev->dev, NULL); + cpu_latency_qos_remove_request(&isp->pm_qos); ia_css_unload_firmware(); error_free_irq: devm_free_irq(&pdev->dev, pdev->irq, isp); error_unregister_entities: hmm_cleanup(); - pm_runtime_forbid(&pdev->dev); - pm_runtime_get_noresume(&pdev->dev); - dev_pm_domain_set(&pdev->dev, NULL); - cpu_latency_qos_remove_request(&isp->pm_qos); atomisp_unregister_entities(isp); error_uninitialize_modules: atomisp_uninitialize_modules(isp); @@ -1494,28 +1490,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i pci_free_irq_vectors(pdev); error_release_firmware: release_firmware(isp->firmware); -error_power_off: - /* - * Switch off ISP, as keeping it powered on would prevent - * reaching S0ix states. - * - * The following lines have been copied from atomisp suspend path - */ - - pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); - irq &= BIT(INTR_IIR); - pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); - - pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq); - irq &= ~BIT(INTR_IER); - pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq); - - atomisp_msi_irq_uninit(isp); - - /* Address later when we worry about the ...field chips */ - if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power(isp, false)) - dev_err(&pdev->dev, "Failed to switch off ISP\n"); - return err; } @@ -1525,15 +1499,17 @@ static void atomisp_pci_remove(struct pci_dev *pdev) atomisp_drvfs_exit(); + pm_runtime_get_sync(&pdev->dev); + pm_runtime_forbid(&pdev->dev); + dev_pm_domain_set(&pdev->dev, NULL); + cpu_latency_qos_remove_request(&isp->pm_qos); + + /* Undo ia_css_init() from atomisp_power_on() */ + atomisp_css_uninit(isp); ia_css_unload_firmware(); devm_free_irq(&pdev->dev, pdev->irq, isp); hmm_cleanup(); - pm_runtime_forbid(&pdev->dev); - pm_runtime_get_noresume(&pdev->dev); - dev_pm_domain_set(&pdev->dev, NULL); - cpu_latency_qos_remove_request(&isp->pm_qos); - atomisp_unregister_entities(isp); atomisp_uninitialize_modules(isp); atomisp_msi_irq_uninit(isp); From b03301870d9b5b2e24bb2037d23101556e76d242 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 29 Dec 2023 22:04:43 +0100 Subject: [PATCH 069/252] media: atomisp: Replace atomisp_drvfs attr with using driver.dev_groups attr sysfs attributes preferably should not be manually be registered but instead the driver.groups / driver.dev_groups driver struct members should be used to have the driver core handle this in a race free manner. Using driver.groups would be the most direct replacement for driver_[add|remove]_file, but some of the attributes actually need access to the struct atomisp_device (*), so as part of modernizing this part of the atomisp driver this change also makes the sysfs attribute device attributes instead of driver attributes. *) Before this change accessing these attributes without the driver having bound would result in a NULL pointer deref, this commit fixes this. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_drvfs.c | 148 +++++++----------- .../staging/media/atomisp/pci/atomisp_drvfs.h | 5 +- .../staging/media/atomisp/pci/atomisp_v4l2.c | 9 +- 3 files changed, 62 insertions(+), 100 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c index 1df534bf54d3..293171da1266 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c +++ b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c @@ -27,31 +27,17 @@ #include "hmm/hmm.h" #include "ia_css_debug.h" +#define OPTION_BIN_LIST BIT(0) +#define OPTION_BIN_RUN BIT(1) +#define OPTION_VALID (OPTION_BIN_LIST | OPTION_BIN_RUN) + /* - * _iunit_debug: - * dbglvl: iunit css driver trace level * dbgopt: iunit debug option: * bit 0: binary list * bit 1: running binary * bit 2: memory statistic -*/ -struct _iunit_debug { - struct device_driver *drv; - struct atomisp_device *isp; - unsigned int dbglvl; - unsigned int dbgfun; - unsigned int dbgopt; -}; - -#define OPTION_BIN_LIST BIT(0) -#define OPTION_BIN_RUN BIT(1) -#define OPTION_VALID (OPTION_BIN_LIST \ - | OPTION_BIN_RUN) - -static struct _iunit_debug iunit_debug = { - .dbglvl = 0, - .dbgopt = OPTION_BIN_LIST, -}; + */ +unsigned int dbgopt = OPTION_BIN_LIST; static inline int iunit_dump_dbgopt(struct atomisp_device *isp, unsigned int opt) @@ -88,34 +74,44 @@ static inline int iunit_dump_dbgopt(struct atomisp_device *isp, return ret; } -static ssize_t iunit_dbglvl_show(struct device_driver *drv, char *buf) +static ssize_t dbglvl_show(struct device *dev, struct device_attribute *attr, + char *buf) { - iunit_debug.dbglvl = dbg_level; - return sysfs_emit(buf, "dtrace level:%u\n", iunit_debug.dbglvl); + unsigned int dbglvl = ia_css_debug_get_dtrace_level(); + + return sysfs_emit(buf, "dtrace level:%u\n", dbglvl); } -static ssize_t iunit_dbglvl_store(struct device_driver *drv, const char *buf, - size_t size) +static ssize_t dbglvl_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) { - if (kstrtouint(buf, 10, &iunit_debug.dbglvl) - || iunit_debug.dbglvl < 1 - || iunit_debug.dbglvl > 9) { + unsigned int dbglvl; + int ret; + + ret = kstrtouint(buf, 10, &dbglvl); + if (ret) + return ret; + + if (dbglvl < 1 || dbglvl > 9) return -ERANGE; - } - ia_css_debug_set_dtrace_level(iunit_debug.dbglvl); + ia_css_debug_set_dtrace_level(dbglvl); return size; } +static DEVICE_ATTR_RW(dbglvl); -static ssize_t iunit_dbgfun_show(struct device_driver *drv, char *buf) +static ssize_t dbgfun_show(struct device *dev, struct device_attribute *attr, + char *buf) { - iunit_debug.dbgfun = atomisp_get_css_dbgfunc(); - return sysfs_emit(buf, "dbgfun opt:%u\n", iunit_debug.dbgfun); + unsigned int dbgfun = atomisp_get_css_dbgfunc(); + + return sysfs_emit(buf, "dbgfun opt:%u\n", dbgfun); } -static ssize_t iunit_dbgfun_store(struct device_driver *drv, const char *buf, - size_t size) +static ssize_t dbgfun_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) { + struct atomisp_device *isp = dev_get_drvdata(dev); unsigned int opt; int ret; @@ -123,23 +119,20 @@ static ssize_t iunit_dbgfun_store(struct device_driver *drv, const char *buf, if (ret) return ret; - ret = atomisp_set_css_dbgfunc(iunit_debug.isp, opt); - if (ret) - return ret; + return atomisp_set_css_dbgfunc(isp, opt); +} +static DEVICE_ATTR_RW(dbgfun); - iunit_debug.dbgfun = opt; - - return size; +static ssize_t dbgopt_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "option:0x%x\n", dbgopt); } -static ssize_t iunit_dbgopt_show(struct device_driver *drv, char *buf) -{ - return sysfs_emit(buf, "option:0x%x\n", iunit_debug.dbgopt); -} - -static ssize_t iunit_dbgopt_store(struct device_driver *drv, const char *buf, - size_t size) +static ssize_t dbgopt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) { + struct atomisp_device *isp = dev_get_drvdata(dev); unsigned int opt; int ret; @@ -147,56 +140,27 @@ static ssize_t iunit_dbgopt_store(struct device_driver *drv, const char *buf, if (ret) return ret; - iunit_debug.dbgopt = opt; - ret = iunit_dump_dbgopt(iunit_debug.isp, iunit_debug.dbgopt); + dbgopt = opt; + ret = iunit_dump_dbgopt(isp, dbgopt); if (ret) return ret; return size; } +static DEVICE_ATTR_RW(dbgopt); -static const struct driver_attribute iunit_drvfs_attrs[] = { - __ATTR(dbglvl, 0644, iunit_dbglvl_show, iunit_dbglvl_store), - __ATTR(dbgfun, 0644, iunit_dbgfun_show, iunit_dbgfun_store), - __ATTR(dbgopt, 0644, iunit_dbgopt_show, iunit_dbgopt_store), +static struct attribute *dbg_attrs[] = { + &dev_attr_dbglvl.attr, + &dev_attr_dbgfun.attr, + &dev_attr_dbgopt.attr, + NULL }; -static int iunit_drvfs_create_files(struct device_driver *drv) -{ - int i, ret = 0; +static const struct attribute_group dbg_attr_group = { + .attrs = dbg_attrs, +}; - for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++) - ret |= driver_create_file(drv, &iunit_drvfs_attrs[i]); - - return ret; -} - -static void iunit_drvfs_remove_files(struct device_driver *drv) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++) - driver_remove_file(drv, &iunit_drvfs_attrs[i]); -} - -int atomisp_drvfs_init(struct atomisp_device *isp) -{ - struct device_driver *drv = isp->dev->driver; - int ret; - - iunit_debug.isp = isp; - iunit_debug.drv = drv; - - ret = iunit_drvfs_create_files(iunit_debug.drv); - if (ret) { - dev_err(isp->dev, "drvfs_create_files error: %d\n", ret); - iunit_drvfs_remove_files(iunit_debug.drv); - } - - return ret; -} - -void atomisp_drvfs_exit(void) -{ - iunit_drvfs_remove_files(iunit_debug.drv); -} +const struct attribute_group *dbg_attr_groups[] = { + &dbg_attr_group, + NULL +}; diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h b/drivers/staging/media/atomisp/pci/atomisp_drvfs.h index 8f4cc722b881..8495cc133c06 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h +++ b/drivers/staging/media/atomisp/pci/atomisp_drvfs.h @@ -19,7 +19,8 @@ #ifndef __ATOMISP_DRVFS_H__ #define __ATOMISP_DRVFS_H__ -int atomisp_drvfs_init(struct atomisp_device *isp); -void atomisp_drvfs_exit(void); +#include + +extern const struct attribute_group *dbg_attr_groups[]; #endif /* __ATOMISP_DRVFS_H__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 6e8c9add35f9..0c78c1d82659 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1468,8 +1468,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i goto error_unload_firmware; } - atomisp_drvfs_init(isp); - return 0; error_unload_firmware: @@ -1497,8 +1495,6 @@ static void atomisp_pci_remove(struct pci_dev *pdev) { struct atomisp_device *isp = pci_get_drvdata(pdev); - atomisp_drvfs_exit(); - pm_runtime_get_sync(&pdev->dev); pm_runtime_forbid(&pdev->dev); dev_pm_domain_set(&pdev->dev, NULL); @@ -1529,11 +1525,12 @@ static const struct pci_device_id atomisp_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ATOMISP_PCI_DEVICE_SOC_CHT)}, {0,} }; - MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl); - static struct pci_driver atomisp_pci_driver = { + .driver = { + .dev_groups = dbg_attr_groups, + }, .name = "atomisp-isp2", .id_table = atomisp_pci_tbl, .probe = atomisp_pci_probe, From 25752a62312f5a5001ed4939a0cbb19c5bae692f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 29 Dec 2023 23:14:20 +0100 Subject: [PATCH 070/252] media: atomisp: Move power-management [un]init into atomisp_pm_[un]init() Move the power-management setup and cleanup code into atomisp_pm_[un]init() helper functions. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_v4l2.c | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 0c78c1d82659..f44be2d656a8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1192,6 +1192,41 @@ atomisp_load_firmware(struct atomisp_device *isp) return fw; } +static void atomisp_pm_init(struct atomisp_device *isp) +{ + /* + * The atomisp does not use standard PCI power-management through the + * PCI config space. Instead this driver directly tells the P-Unit to + * disable the ISP over the IOSF. The standard PCI subsystem pm_ops will + * try to access the config space before (resume) / after (suspend) this + * driver has turned the ISP on / off, resulting in the following errors: + * + * "Unable to change power state from D0 to D3hot, device inaccessible" + * "Unable to change power state from D3cold to D0, device inaccessible" + * + * To avoid these errors override the pm_domain so that all the PCI + * subsys suspend / resume handling is skipped. + */ + isp->pm_domain.ops.runtime_suspend = atomisp_power_off; + isp->pm_domain.ops.runtime_resume = atomisp_power_on; + isp->pm_domain.ops.suspend = atomisp_suspend; + isp->pm_domain.ops.resume = atomisp_resume; + + cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); + dev_pm_domain_set(isp->dev, &isp->pm_domain); + + pm_runtime_allow(isp->dev); + pm_runtime_put_sync_suspend(isp->dev); +} + +static void atomisp_pm_uninit(struct atomisp_device *isp) +{ + pm_runtime_get_sync(isp->dev); + pm_runtime_forbid(isp->dev); + dev_pm_domain_set(isp->dev, NULL); + cpu_latency_qos_remove_request(&isp->pm_qos); +} + #define ATOM_ISP_PCI_BAR 0 static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -1438,29 +1473,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i isp->firmware = NULL; isp->css_env.isp_css_fw.data = NULL; - /* - * The atomisp does not use standard PCI power-management through the - * PCI config space. Instead this driver directly tells the P-Unit to - * disable the ISP over the IOSF. The standard PCI subsystem pm_ops will - * try to access the config space before (resume) / after (suspend) this - * driver has turned the ISP on / off, resulting in the following errors: - * - * "Unable to change power state from D0 to D3hot, device inaccessible" - * "Unable to change power state from D3cold to D0, device inaccessible" - * - * To avoid these errors override the pm_domain so that all the PCI - * subsys suspend / resume handling is skipped. - */ - isp->pm_domain.ops.runtime_suspend = atomisp_power_off; - isp->pm_domain.ops.runtime_resume = atomisp_power_on; - isp->pm_domain.ops.suspend = atomisp_suspend; - isp->pm_domain.ops.resume = atomisp_resume; - - cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE); - dev_pm_domain_set(&pdev->dev, &isp->pm_domain); - - pm_runtime_allow(&pdev->dev); - pm_runtime_put_sync_suspend(&pdev->dev); + atomisp_pm_init(isp); err = v4l2_async_nf_register(&isp->notifier); if (err) { @@ -1471,10 +1484,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i return 0; error_unload_firmware: - pm_runtime_get_sync(&pdev->dev); - pm_runtime_forbid(&pdev->dev); - dev_pm_domain_set(&pdev->dev, NULL); - cpu_latency_qos_remove_request(&isp->pm_qos); + atomisp_pm_uninit(isp); ia_css_unload_firmware(); error_free_irq: devm_free_irq(&pdev->dev, pdev->irq, isp); @@ -1495,10 +1505,7 @@ static void atomisp_pci_remove(struct pci_dev *pdev) { struct atomisp_device *isp = pci_get_drvdata(pdev); - pm_runtime_get_sync(&pdev->dev); - pm_runtime_forbid(&pdev->dev); - dev_pm_domain_set(&pdev->dev, NULL); - cpu_latency_qos_remove_request(&isp->pm_qos); + atomisp_pm_uninit(isp); /* Undo ia_css_init() from atomisp_power_on() */ atomisp_css_uninit(isp); From a6be73e97facfdc1d4e3117afcbc6fdbaeae7726 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 30 Dec 2023 15:31:41 +0100 Subject: [PATCH 071/252] media: atomisp: Bind and do power-management without firmware The ISP needs to be turned off in a special manner for the SoC to be able to reach S0i3 during suspend. When the firmware is missing still bind to the PCI device and run in pm-only mode which takes care of turning the ISP off (including turning it off again if the firmware has turned it on during resume). In this new pm-only mode the atomisp driver works exactly the same as the non-staging, pm-only drivers/platform/x86/intel/atomisp2/pm.c driver. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/pci/atomisp_internal.h | 1 + .../staging/media/atomisp/pci/atomisp_v4l2.c | 32 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index d5b077e602ca..bba9bc64d447 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -192,6 +192,7 @@ struct atomisp_device { struct dev_pm_domain pm_domain; struct pm_qos_request pm_qos; s32 max_isr_latency; + bool pm_only; struct atomisp_mipi_csi2_device csi2_port[ATOMISP_CAMERA_NR_PORTS]; struct atomisp_tpg_device tpg; diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index f44be2d656a8..7e241f4e9e93 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -548,7 +548,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable) dev_dbg(isp->dev, "IUNIT power-%s.\n", enable ? "on" : "off"); /* WA for P-Unit, if DVFS enabled, ISP timeout observed */ - if (IS_CHT && enable) { + if (IS_CHT && enable && !isp->pm_only) { punit_ddr_dvfs_enable(false); msleep(20); } @@ -558,7 +558,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable) val, MRFLD_ISPSSPM0_ISPSSC_MASK); /* WA:Enable DVFS */ - if (IS_CHT && !enable) + if (IS_CHT && !enable && !isp->pm_only) punit_ddr_dvfs_enable(true); /* @@ -601,11 +601,15 @@ int atomisp_power_off(struct device *dev) int ret; u32 reg; - atomisp_css_uninit(isp); + if (isp->pm_only) { + pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, 0); + } else { + atomisp_css_uninit(isp); - ret = atomisp_mrfld_pre_power_down(isp); - if (ret) - return ret; + ret = atomisp_mrfld_pre_power_down(isp); + if (ret) + return ret; + } /* * MRFLD IUNIT DPHY is located in an always-power-on island @@ -634,6 +638,9 @@ int atomisp_power_on(struct device *dev) pci_restore_state(to_pci_dev(dev)); cpu_latency_qos_update_request(&isp->pm_qos, isp->max_isr_latency); + if (isp->pm_only) + return 0; + /*restore register values for iUnit and iUnitPHY registers*/ if (isp->saved_regs.pcicmdsts) atomisp_restore_iunit_reg(isp); @@ -1252,6 +1259,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i isp->dev = &pdev->dev; isp->saved_regs.ispmmadr = start; + isp->asd.isp = isp; mutex_init(&isp->mutex); spin_lock_init(&isp->lock); @@ -1368,8 +1376,13 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i /* Load isp firmware from user space */ isp->firmware = atomisp_load_firmware(isp); - if (!isp->firmware) - return -ENOENT; + if (!isp->firmware) { + /* No firmware continue in pm-only mode for S0i3 support */ + dev_info(&pdev->dev, "Continuing in power-management only mode\n"); + isp->pm_only = true; + atomisp_pm_init(isp); + return 0; + } err = sh_css_check_firmware_version(isp->dev, isp->firmware->data); if (err) { @@ -1507,6 +1520,9 @@ static void atomisp_pci_remove(struct pci_dev *pdev) atomisp_pm_uninit(isp); + if (isp->pm_only) + return; + /* Undo ia_css_init() from atomisp_power_on() */ atomisp_css_uninit(isp); ia_css_unload_firmware(); From ace440e6db33330b40afbb7c2c85a6b1399f3baa Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 30 Dec 2023 15:37:54 +0100 Subject: [PATCH 072/252] media: atomisp: Remove unnecessary msleep(10) from atomisp_mrfld_power() error path Remove unnecessary msleep(10) from atomisp_mrfld_power() error-exit path, the success exit from atomisp_mrfld_power() happens if a test succeeds inside the do { } while loop above the msleep(). The error-exit path with the removed msleep is only hit it the power-on is not reflected in the iUNIT ISPSSPM0 status bits after a timeout of 50 ms. Sleeping an extra 10 ms in the timeout path makes little sense. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 7e241f4e9e93..f736e54c7df3 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -587,9 +587,6 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable) usleep_range(100, 150); } while (1); - if (enable) - msleep(10); - dev_err(isp->dev, "IUNIT power-%s timeout.\n", enable ? "on" : "off"); return -EBUSY; } From e072ded7045018b776e52e559138fb7dc9aed573 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 31 Dec 2023 11:00:21 +0100 Subject: [PATCH 073/252] media: atomisp: Update TODO Remove the TODO items for using the main (drivers/media/i2c) ov2680 and ov5693 drivers and removing the atomisp specific ones, this has been done. Remove the TODO item for gracefully handling missing firmware the "media: atomisp: Bind and do power-management without firmware" changes have fixed this. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/TODO | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/media/atomisp/TODO b/drivers/staging/media/atomisp/TODO index d99cc898cd99..bfef99997a1d 100644 --- a/drivers/staging/media/atomisp/TODO +++ b/drivers/staging/media/atomisp/TODO @@ -29,16 +29,6 @@ TODO 1. Items which MUST be fixed before the driver can be moved out of staging: -* The atomisp ov2680 and ov5693 sensor drivers bind to the same hw-ids as - the standard ov2680 and ov5693 drivers under drivers/media/i2c, which - conflicts. Drop the atomisp private ov2680 and ov5693 drivers: - * Port various ov2680 improvements from atomisp_ov2680.c to regular ov2680.c - and switch to regular ov2680 driver - * Make atomisp work with the regular ov5693 driver and drop atomisp_ov5693 - -* Fix atomisp causing the whole machine to hang in its probe() error-exit - path taken in the firmware missing case - * Remove/disable private IOCTLs * Remove/disable custom v4l2-ctrls From e280d1a0eb93354c46f503700b38d3660c34b3dd Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:27 +0100 Subject: [PATCH 074/252] media: platform: mtk-mdp3: add support second sets of MMSYS The MT8195 chipset features two MMSYS subsets: VPPSYS0 and VPPSYS1. These subsets coordinate and control the clock, power, and register settings required for the components of MDP3. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mdp_cfg_data.c | 44 ++++++------- .../platform/mediatek/mdp3/mtk-mdp3-comp.h | 1 + .../platform/mediatek/mdp3/mtk-mdp3-core.c | 63 ++++++++++++++++--- .../platform/mediatek/mdp3/mtk-mdp3-core.h | 18 +++++- 4 files changed, 93 insertions(+), 33 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c index 502eeae0bfdc..fcc582292b77 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c @@ -73,75 +73,75 @@ static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = { static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = { [MDP_COMP_WPEI] = { - {MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI}, + {MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_WPEO] = { - {MDP_COMP_TYPE_EXTO, 2, MT8183_MDP_COMP_WPEO}, + {MDP_COMP_TYPE_EXTO, 2, MT8183_MDP_COMP_WPEO, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_WPEI2] = { - {MDP_COMP_TYPE_WPEI, 1, MT8183_MDP_COMP_WPEI2}, + {MDP_COMP_TYPE_WPEI, 1, MT8183_MDP_COMP_WPEI2, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_WPEO2] = { - {MDP_COMP_TYPE_EXTO, 3, MT8183_MDP_COMP_WPEO2}, + {MDP_COMP_TYPE_EXTO, 3, MT8183_MDP_COMP_WPEO2, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_ISP_IMGI] = { - {MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI}, + {MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI, MDP_MM_SUBSYS_0}, {0, 0, 4} }, [MDP_COMP_ISP_IMGO] = { - {MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO}, + {MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO, MDP_MM_SUBSYS_0}, {0, 0, 4} }, [MDP_COMP_ISP_IMG2O] = { - {MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O}, + {MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_CAMIN] = { - {MDP_COMP_TYPE_DL_PATH, 0, MT8183_MDP_COMP_CAMIN}, + {MDP_COMP_TYPE_DL_PATH, 0, MT8183_MDP_COMP_CAMIN, MDP_MM_SUBSYS_0}, {2, 2, 1} }, [MDP_COMP_CAMIN2] = { - {MDP_COMP_TYPE_DL_PATH, 1, MT8183_MDP_COMP_CAMIN2}, + {MDP_COMP_TYPE_DL_PATH, 1, MT8183_MDP_COMP_CAMIN2, MDP_MM_SUBSYS_0}, {2, 4, 1} }, [MDP_COMP_RDMA0] = { - {MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0}, + {MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0, MDP_MM_SUBSYS_0}, {2, 0, 0} }, [MDP_COMP_CCORR0] = { - {MDP_COMP_TYPE_CCORR, 0, MT8183_MDP_COMP_CCORR0}, + {MDP_COMP_TYPE_CCORR, 0, MT8183_MDP_COMP_CCORR0, MDP_MM_SUBSYS_0}, {1, 0, 0} }, [MDP_COMP_RSZ0] = { - {MDP_COMP_TYPE_RSZ, 0, MT8183_MDP_COMP_RSZ0}, + {MDP_COMP_TYPE_RSZ, 0, MT8183_MDP_COMP_RSZ0, MDP_MM_SUBSYS_0}, {1, 0, 0} }, [MDP_COMP_RSZ1] = { - {MDP_COMP_TYPE_RSZ, 1, MT8183_MDP_COMP_RSZ1}, + {MDP_COMP_TYPE_RSZ, 1, MT8183_MDP_COMP_RSZ1, MDP_MM_SUBSYS_0}, {1, 0, 0} }, [MDP_COMP_TDSHP0] = { - {MDP_COMP_TYPE_TDSHP, 0, MT8183_MDP_COMP_TDSHP0}, + {MDP_COMP_TYPE_TDSHP, 0, MT8183_MDP_COMP_TDSHP0, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_PATH0_SOUT] = { - {MDP_COMP_TYPE_PATH, 0, MT8183_MDP_COMP_PATH0_SOUT}, + {MDP_COMP_TYPE_PATH, 0, MT8183_MDP_COMP_PATH0_SOUT, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_PATH1_SOUT] = { - {MDP_COMP_TYPE_PATH, 1, MT8183_MDP_COMP_PATH1_SOUT}, + {MDP_COMP_TYPE_PATH, 1, MT8183_MDP_COMP_PATH1_SOUT, MDP_MM_SUBSYS_0}, {0, 0, 0} }, [MDP_COMP_WROT0] = { - {MDP_COMP_TYPE_WROT, 0, MT8183_MDP_COMP_WROT0}, + {MDP_COMP_TYPE_WROT, 0, MT8183_MDP_COMP_WROT0, MDP_MM_SUBSYS_0}, {1, 0, 0} }, [MDP_COMP_WDMA] = { - {MDP_COMP_TYPE_WDMA, 0, MT8183_MDP_COMP_WDMA}, + {MDP_COMP_TYPE_WDMA, 0, MT8183_MDP_COMP_WDMA, MDP_MM_SUBSYS_0}, {1, 0, 0} }, }; @@ -402,10 +402,10 @@ static const struct mdp_limit mt8183_mdp_def_limit = { }; static const struct mdp_pipe_info mt8183_pipe_info[] = { - [MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, 0}, - [MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, 1}, - [MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, 2}, - [MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, 3} + [MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, MDP_MM_SUBSYS_0, 0}, + [MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, MDP_MM_SUBSYS_0, 1}, + [MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, MDP_MM_SUBSYS_0, 2}, + [MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, MDP_MM_SUBSYS_0, 3} }; const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h index 20d2bcb77ef9..e89c51e1edb7 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h @@ -138,6 +138,7 @@ struct mdp_comp_match { enum mdp_comp_type type; u32 alias_id; s32 inner_id; + s32 subsys_id; }; /* Used to describe the item order in MDP property */ diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index 94f4ed78523b..8cd0f11fc290 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -26,9 +26,10 @@ static const struct of_device_id mdp_of_ids[] = { MODULE_DEVICE_TABLE(of, mdp_of_ids); static struct platform_device *__get_pdev_by_id(struct platform_device *pdev, + struct platform_device *from, enum mdp_infra_id id) { - struct device_node *node; + struct device_node *node, *f = NULL; struct platform_device *mdp_pdev = NULL; const struct mtk_mdp_driver_data *mdp_data; const char *compat; @@ -46,9 +47,14 @@ static struct platform_device *__get_pdev_by_id(struct platform_device *pdev, dev_err(&pdev->dev, "have no driver data to find node\n"); return NULL; } - compat = mdp_data->mdp_probe_infra[id].compatible; - node = of_find_compatible_node(NULL, NULL, compat); + compat = mdp_data->mdp_probe_infra[id].compatible; + if (strlen(compat) == 0) + return NULL; + + if (from) + f = from->dev.of_node; + node = of_find_compatible_node(f, NULL, compat); if (WARN_ON(!node)) { dev_err(&pdev->dev, "find node from id %d failed\n", id); return NULL; @@ -148,6 +154,46 @@ void mdp_video_device_release(struct video_device *vdev) kfree(mdp); } +static int mdp_mm_subsys_deploy(struct mdp_dev *mdp, enum mdp_infra_id id) +{ + struct platform_device *mm_pdev = NULL; + struct device **dev; + int i; + + if (!mdp) + return -EINVAL; + + for (i = 0; i < MDP_MM_SUBSYS_MAX; i++) { + const char *compat; + enum mdp_infra_id sub_id = id + i; + + switch (id) { + case MDP_INFRA_MMSYS: + dev = &mdp->mm_subsys[i].mmsys; + break; + default: + dev_err(&mdp->pdev->dev, "Unknown infra id %d", id); + return -EINVAL; + } + + /* + * Not every chip has multiple multimedia subsystems, so + * the config may be null. + */ + compat = mdp->mdp_data->mdp_probe_infra[sub_id].compatible; + if (strlen(compat) == 0) + continue; + + mm_pdev = __get_pdev_by_id(mdp->pdev, mm_pdev, sub_id); + if (WARN_ON(!mm_pdev)) + return -ENODEV; + + *dev = &mm_pdev->dev; + } + + return 0; +} + static int mdp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -164,14 +210,11 @@ static int mdp_probe(struct platform_device *pdev) mdp->pdev = pdev; mdp->mdp_data = of_device_get_match_data(&pdev->dev); - mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MMSYS); - if (!mm_pdev) { - ret = -ENODEV; + ret = mdp_mm_subsys_deploy(mdp, MDP_INFRA_MMSYS); + if (ret) goto err_destroy_device; - } - mdp->mdp_mmsys = &mm_pdev->dev; - mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MUTEX); + mm_pdev = __get_pdev_by_id(pdev, NULL, MDP_INFRA_MUTEX); if (WARN_ON(!mm_pdev)) { ret = -ENODEV; goto err_destroy_device; @@ -210,7 +253,7 @@ static int mdp_probe(struct platform_device *pdev) mdp->scp = scp_get(pdev); if (!mdp->scp) { - mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_SCP); + mm_pdev = __get_pdev_by_id(pdev, NULL, MDP_INFRA_SCP); if (WARN_ON(!mm_pdev)) { dev_err(&pdev->dev, "Could not get scp device\n"); ret = -ENODEV; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index 7e21d226ceb8..7a7cdd0ce968 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -19,12 +19,23 @@ #define MDP_PHANDLE_NAME "mediatek,mdp3" enum mdp_infra_id { + /* + * Due to the sequential nature of function "mdp_mm_subsys_deploy", + * adding new enum. necessitates careful consideration. + */ MDP_INFRA_MMSYS, + MDP_INFRA_MMSYS2, MDP_INFRA_MUTEX, MDP_INFRA_SCP, MDP_INFRA_MAX }; +enum mdp_mm_subsys_id { + MDP_MM_SUBSYS_0, + MDP_MM_SUBSYS_1, + MDP_MM_SUBSYS_MAX, +}; + enum mdp_buffer_usage { MDP_BUFFER_USAGE_HW_READ, MDP_BUFFER_USAGE_MDP, @@ -65,9 +76,13 @@ struct mtk_mdp_driver_data { unsigned int pipe_info_len; }; +struct mdp_mm_subsys { + struct device *mmsys; +}; + struct mdp_dev { struct platform_device *pdev; - struct device *mdp_mmsys; + struct mdp_mm_subsys mm_subsys[MDP_MM_SUBSYS_MAX]; struct mtk_mutex *mdp_mutex[MDP_PIPE_MAX]; struct mdp_comp *comp[MDP_MAX_COMP_COUNT]; const struct mtk_mdp_driver_data *mdp_data; @@ -96,6 +111,7 @@ struct mdp_dev { struct mdp_pipe_info { enum mdp_pipe_id pipe_id; + enum mdp_mm_subsys_id sub_id; u32 mutex_id; }; From ee0d0dbb80f6bd812db80f369562fd85d3ac567c Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:28 +0100 Subject: [PATCH 075/252] media: platform: mtk-mdp3: add support second sets of MUTEX After setting up the second set of MMSYS (VPPSYS1), it is necessary to have a corresponding second set of MUTEX (MUTEX2) to assist in handling SOF/EOF. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 57 +++++++++++-------- .../platform/mediatek/mdp3/mtk-mdp3-core.c | 51 ++++++++++++----- .../platform/mediatek/mdp3/mtk-mdp3-core.h | 4 +- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 6adac857a477..67c8fcc3eda9 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -44,15 +44,21 @@ static bool is_output_disabled(int p_id, const struct img_compparam *param, u32 return (count < num) ? (dis_output || dis_tile) : true; } +static struct mtk_mutex *__get_mutex(const struct mdp_dev *mdp_dev, + const struct mdp_pipe_info *p) +{ + return mdp_dev->mm_subsys[p->sub_id].mdp_mutex[p->mutex_id]; +} + static int mdp_path_subfrm_require(const struct mdp_path *path, struct mdp_cmdq_cmd *cmd, - s32 *mutex_id, u32 count) + struct mdp_pipe_info *p, u32 count) { const int p_id = path->mdp_dev->mdp_data->mdp_plat_id; const struct mdp_comp_ctx *ctx; const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data; struct device *dev = &path->mdp_dev->pdev->dev; - struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex; + struct mtk_mutex *mutex; int id, index; u32 num_comp = 0; @@ -77,7 +83,8 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, dev_err(dev, "Unknown pipeline and no mutex is assigned"); return -EINVAL; } - *mutex_id = data->pipe_info[index].mutex_id; + memcpy(p, &data->pipe_info[index], sizeof(struct mdp_pipe_info)); + mutex = __get_mutex(path->mdp_dev, p); /* Set mutex mod */ for (index = 0; index < num_comp; index++) { @@ -85,29 +92,28 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, if (is_output_disabled(p_id, ctx->param, count)) continue; id = ctx->comp->public_id; - mtk_mutex_write_mod(mutex[*mutex_id], - data->mdp_mutex_table_idx[id], false); + mtk_mutex_write_mod(mutex, data->mdp_mutex_table_idx[id], false); + } - mtk_mutex_write_sof(mutex[*mutex_id], - MUTEX_SOF_IDX_SINGLE_MODE); + mtk_mutex_write_sof(mutex, MUTEX_SOF_IDX_SINGLE_MODE); return 0; } static int mdp_path_subfrm_run(const struct mdp_path *path, struct mdp_cmdq_cmd *cmd, - s32 *mutex_id, u32 count) + struct mdp_pipe_info *p, u32 count) { const int p_id = path->mdp_dev->mdp_data->mdp_plat_id; const struct mdp_comp_ctx *ctx; struct device *dev = &path->mdp_dev->pdev->dev; - struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex; + struct mtk_mutex *mutex; int index; u32 num_comp = 0; s32 event; - if (-1 == *mutex_id) { + if (-1 == p->mutex_id) { dev_err(dev, "Incorrect mutex id"); return -EINVAL; } @@ -127,7 +133,8 @@ static int mdp_path_subfrm_run(const struct mdp_path *path, } /* Enable the mutex */ - mtk_mutex_enable_by_cmdq(mutex[*mutex_id], (void *)&cmd->pkt); + mutex = __get_mutex(path->mdp_dev, p); + mtk_mutex_enable_by_cmdq(mutex, (void *)&cmd->pkt); /* Wait SOF events and clear mutex modules (optional) */ for (index = 0; index < num_comp; index++) { @@ -174,7 +181,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, const struct img_mmsys_ctrl *ctrl = NULL; const struct img_mux *set; struct mdp_comp_ctx *ctx; - s32 mutex_id; + struct mdp_pipe_info pipe; int index, ret; u32 num_comp = 0; @@ -185,7 +192,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, ctrl = CFG_ADDR(MT8183, path->config, ctrls[count]); /* Acquire components */ - ret = mdp_path_subfrm_require(path, cmd, &mutex_id, count); + ret = mdp_path_subfrm_require(path, cmd, &pipe, count); if (ret) return ret; /* Enable mux settings */ @@ -204,7 +211,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, return ret; } /* Run components */ - ret = mdp_path_subfrm_run(path, cmd, &mutex_id, count); + ret = mdp_path_subfrm_run(path, cmd, &pipe, count); if (ret) return ret; /* Wait components done */ @@ -328,13 +335,13 @@ static void mdp_auto_release_work(struct work_struct *work) { struct mdp_cmdq_cmd *cmd; struct mdp_dev *mdp; - int id; + struct mtk_mutex *mutex; cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work); mdp = cmd->mdp; - id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - mtk_mutex_unprepare(mdp->mdp_mutex[id]); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0]); + mtk_mutex_unprepare(mutex); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); @@ -354,7 +361,6 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) struct cmdq_cb_data *data; struct mdp_dev *mdp; struct device *dev; - int id; if (!mssg) { pr_info("%s:no callback data\n", __func__); @@ -379,9 +385,11 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) INIT_WORK(&cmd->auto_release_work, mdp_auto_release_work); if (!queue_work(mdp->clock_wq, &cmd->auto_release_work)) { + struct mtk_mutex *mutex; + dev_err(dev, "%s:queue_work fail!\n", __func__); - id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - mtk_mutex_unprepare(mdp->mdp_mutex[id]); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0]); + mtk_mutex_unprepare(mutex); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); @@ -403,6 +411,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) struct mdp_comp *comps = NULL; struct device *dev = &mdp->pdev->dev; const int p_id = mdp->mdp_data->mdp_plat_id; + struct mtk_mutex *mutex = NULL; int i, ret; u32 num_comp = 0; @@ -440,8 +449,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) goto err_free_comps; } - i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - ret = mtk_mutex_prepare(mdp->mdp_mutex[i]); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0]); + ret = mtk_mutex_prepare(mutex); if (ret) { dev_err(dev, "Fail to enable mutex clk\n"); goto err_free_path; @@ -506,8 +515,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); err_free_path: - i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id; - mtk_mutex_unprepare(mdp->mdp_mutex[i]); + if (mutex) + mtk_mutex_unprepare(mutex); kfree(path); err_free_comps: kfree(comps); diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index 8cd0f11fc290..4802b20d7f20 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -146,8 +146,17 @@ void mdp_video_device_release(struct video_device *vdev) vb2_dma_contig_clear_max_seg_size(&mdp->pdev->dev); mdp_comp_destroy(mdp); - for (i = 0; i < MDP_PIPE_MAX; i++) - mtk_mutex_put(mdp->mdp_mutex[i]); + for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) { + enum mdp_mm_subsys_id idx; + struct mtk_mutex *m; + u32 m_id; + + idx = mdp->mdp_data->pipe_info[i].sub_id; + m_id = mdp->mdp_data->pipe_info[i].mutex_id; + m = mdp->mm_subsys[idx].mdp_mutex[m_id]; + if (!IS_ERR_OR_NULL(m)) + mtk_mutex_put(m); + } mdp_vpu_shared_mem_free(&mdp->vpu); v4l2_m2m_release(mdp->m2m_dev); @@ -171,6 +180,9 @@ static int mdp_mm_subsys_deploy(struct mdp_dev *mdp, enum mdp_infra_id id) case MDP_INFRA_MMSYS: dev = &mdp->mm_subsys[i].mmsys; break; + case MDP_INFRA_MUTEX: + dev = &mdp->mm_subsys[i].mutex; + break; default: dev_err(&mdp->pdev->dev, "Unknown infra id %d", id); return -EINVAL; @@ -214,18 +226,24 @@ static int mdp_probe(struct platform_device *pdev) if (ret) goto err_destroy_device; - mm_pdev = __get_pdev_by_id(pdev, NULL, MDP_INFRA_MUTEX); - if (WARN_ON(!mm_pdev)) { - ret = -ENODEV; + ret = mdp_mm_subsys_deploy(mdp, MDP_INFRA_MUTEX); + if (ret) goto err_destroy_device; - } + for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) { + enum mdp_mm_subsys_id idx; + struct mtk_mutex **m; + + idx = mdp->mdp_data->pipe_info[i].sub_id; mutex_id = mdp->mdp_data->pipe_info[i].mutex_id; - if (!IS_ERR_OR_NULL(mdp->mdp_mutex[mutex_id])) + m = &mdp->mm_subsys[idx].mdp_mutex[mutex_id]; + + if (!IS_ERR_OR_NULL(*m)) continue; - mdp->mdp_mutex[mutex_id] = mtk_mutex_get(&mm_pdev->dev); - if (IS_ERR(mdp->mdp_mutex[mutex_id])) { - ret = PTR_ERR(mdp->mdp_mutex[mutex_id]); + + *m = mtk_mutex_get(mdp->mm_subsys[idx].mutex); + if (IS_ERR(*m)) { + ret = PTR_ERR(*m); goto err_free_mutex; } } @@ -309,9 +327,16 @@ static int mdp_probe(struct platform_device *pdev) err_deinit_comp: mdp_comp_destroy(mdp); err_free_mutex: - for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) - if (!IS_ERR_OR_NULL(mdp->mdp_mutex[i])) - mtk_mutex_put(mdp->mdp_mutex[i]); + for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) { + enum mdp_mm_subsys_id idx; + struct mtk_mutex *m; + + idx = mdp->mdp_data->pipe_info[i].sub_id; + mutex_id = mdp->mdp_data->pipe_info[i].mutex_id; + m = mdp->mm_subsys[idx].mdp_mutex[mutex_id]; + if (!IS_ERR_OR_NULL(m)) + mtk_mutex_put(m); + } err_destroy_device: kfree(mdp); err_return: diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index 7a7cdd0ce968..fde2c0b95def 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -26,6 +26,7 @@ enum mdp_infra_id { MDP_INFRA_MMSYS, MDP_INFRA_MMSYS2, MDP_INFRA_MUTEX, + MDP_INFRA_MUTEX2, MDP_INFRA_SCP, MDP_INFRA_MAX }; @@ -78,12 +79,13 @@ struct mtk_mdp_driver_data { struct mdp_mm_subsys { struct device *mmsys; + struct device *mutex; + struct mtk_mutex *mdp_mutex[MDP_PIPE_MAX]; }; struct mdp_dev { struct platform_device *pdev; struct mdp_mm_subsys mm_subsys[MDP_MM_SUBSYS_MAX]; - struct mtk_mutex *mdp_mutex[MDP_PIPE_MAX]; struct mdp_comp *comp[MDP_MAX_COMP_COUNT]; const struct mtk_mdp_driver_data *mdp_data; From d9b52f735668183ecb1d127881135af4c150e39d Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:29 +0100 Subject: [PATCH 076/252] media: platform: mtk-mdp3: introduce more pipelines from MT8195 Increasing the number of sets built by MMSYS and MUTEX in MT8195 will enable the creation of more pipelines in MDP3. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 80 ++++++++++++------- .../platform/mediatek/mdp3/mtk-mdp3-core.h | 7 ++ 2 files changed, 60 insertions(+), 27 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 67c8fcc3eda9..31930ddbc828 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -50,6 +50,43 @@ static struct mtk_mutex *__get_mutex(const struct mdp_dev *mdp_dev, return mdp_dev->mm_subsys[p->sub_id].mdp_mutex[p->mutex_id]; } +static enum mdp_pipe_id __get_pipe(const struct mdp_dev *mdp_dev, + enum mtk_mdp_comp_id id) +{ + enum mdp_pipe_id pipe_id; + + switch (id) { + case MDP_COMP_RDMA0: + pipe_id = MDP_PIPE_RDMA0; + break; + case MDP_COMP_ISP_IMGI: + pipe_id = MDP_PIPE_IMGI; + break; + case MDP_COMP_WPEI: + pipe_id = MDP_PIPE_WPEI; + break; + case MDP_COMP_WPEI2: + pipe_id = MDP_PIPE_WPEI2; + break; + case MDP_COMP_RDMA1: + pipe_id = MDP_PIPE_RDMA1; + break; + case MDP_COMP_RDMA2: + pipe_id = MDP_PIPE_RDMA2; + break; + case MDP_COMP_RDMA3: + pipe_id = MDP_PIPE_RDMA3; + break; + default: + /* Avoid exceptions when operating MUTEX */ + pipe_id = MDP_PIPE_RDMA0; + dev_err(&mdp_dev->pdev->dev, "Unknown pipeline id %d", id); + break; + } + + return pipe_id; +} + static int mdp_path_subfrm_require(const struct mdp_path *path, struct mdp_cmdq_cmd *cmd, struct mdp_pipe_info *p, u32 count) @@ -57,7 +94,6 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, const int p_id = path->mdp_dev->mdp_data->mdp_plat_id; const struct mdp_comp_ctx *ctx; const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data; - struct device *dev = &path->mdp_dev->pdev->dev; struct mtk_mutex *mutex; int id, index; u32 num_comp = 0; @@ -66,23 +102,7 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, num_comp = CFG_GET(MT8183, path->config, num_components); /* Decide which mutex to use based on the current pipeline */ - switch (path->comps[0].comp->public_id) { - case MDP_COMP_RDMA0: - index = MDP_PIPE_RDMA0; - break; - case MDP_COMP_ISP_IMGI: - index = MDP_PIPE_IMGI; - break; - case MDP_COMP_WPEI: - index = MDP_PIPE_WPEI; - break; - case MDP_COMP_WPEI2: - index = MDP_PIPE_WPEI2; - break; - default: - dev_err(dev, "Unknown pipeline and no mutex is assigned"); - return -EINVAL; - } + index = __get_pipe(path->mdp_dev, path->comps[0].comp->public_id); memcpy(p, &data->pipe_info[index], sizeof(struct mdp_pipe_info)); mutex = __get_mutex(path->mdp_dev, p); @@ -336,11 +356,13 @@ static void mdp_auto_release_work(struct work_struct *work) struct mdp_cmdq_cmd *cmd; struct mdp_dev *mdp; struct mtk_mutex *mutex; + enum mdp_pipe_id pipe_id; cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work); mdp = cmd->mdp; - mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0]); + pipe_id = __get_pipe(mdp, cmd->comps[0].public_id); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]); mtk_mutex_unprepare(mutex); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); @@ -361,6 +383,7 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) struct cmdq_cb_data *data; struct mdp_dev *mdp; struct device *dev; + enum mdp_pipe_id pipe_id; if (!mssg) { pr_info("%s:no callback data\n", __func__); @@ -388,7 +411,8 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) struct mtk_mutex *mutex; dev_err(dev, "%s:queue_work fail!\n", __func__); - mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0]); + pipe_id = __get_pipe(mdp, cmd->comps[0].public_id); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]); mtk_mutex_unprepare(mutex); mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); @@ -412,6 +436,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) struct device *dev = &mdp->pdev->dev; const int p_id = mdp->mdp_data->mdp_plat_id; struct mtk_mutex *mutex = NULL; + enum mdp_pipe_id pipe_id; int i, ret; u32 num_comp = 0; @@ -449,13 +474,6 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) goto err_free_comps; } - mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0]); - ret = mtk_mutex_prepare(mutex); - if (ret) { - dev_err(dev, "Fail to enable mutex clk\n"); - goto err_free_path; - } - path->mdp_dev = mdp; path->config = param->config; path->param = param->param; @@ -475,6 +493,14 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) goto err_free_path; } + pipe_id = __get_pipe(mdp, path->comps[0].comp->public_id); + mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]); + ret = mtk_mutex_prepare(mutex); + if (ret) { + dev_err(dev, "Fail to enable mutex clk\n"); + goto err_free_path; + } + ret = mdp_path_config(mdp, cmd, path); if (ret) { dev_err(dev, "mdp_path_config error\n"); diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index fde2c0b95def..ece6509666fd 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -59,6 +59,13 @@ enum mdp_pipe_id { MDP_PIPE_WPEI2, MDP_PIPE_IMGI, MDP_PIPE_RDMA0, + MDP_PIPE_RDMA1, + MDP_PIPE_RDMA2, + MDP_PIPE_RDMA3, + MDP_PIPE_SPLIT, + MDP_PIPE_SPLIT2, + MDP_PIPE_VPP0_SOUT, + MDP_PIPE_VPP1_SOUT, MDP_PIPE_MAX }; From 73e00953c3601008a7f500e25a1767b1012b2091 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:30 +0100 Subject: [PATCH 077/252] media: platform: mtk-mdp3: introduce more MDP3 components Add configuration of more components in MT8195 MDP3. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mdp_reg_aal.h | 25 ++++++ .../platform/mediatek/mdp3/mdp_reg_color.h | 31 +++++++ .../media/platform/mediatek/mdp3/mdp_reg_fg.h | 23 +++++ .../platform/mediatek/mdp3/mdp_reg_hdr.h | 31 +++++++ .../platform/mediatek/mdp3/mdp_reg_merge.h | 25 ++++++ .../platform/mediatek/mdp3/mdp_reg_ovl.h | 25 ++++++ .../platform/mediatek/mdp3/mdp_reg_pad.h | 21 +++++ .../platform/mediatek/mdp3/mdp_reg_rdma.h | 24 ++++++ .../platform/mediatek/mdp3/mdp_reg_rsz.h | 2 + .../platform/mediatek/mdp3/mdp_reg_tdshp.h | 34 ++++++++ .../platform/mediatek/mdp3/mdp_reg_wrot.h | 8 ++ .../platform/mediatek/mdp3/mtk-mdp3-comp.h | 85 +++++++++++++++---- 12 files changed, 318 insertions(+), 16 deletions(-) create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_color.h create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h new file mode 100644 index 000000000000..4b9513e54543 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_AAL_H__ +#define __MDP_REG_AAL_H__ + +#define MDP_AAL_EN (0x000) +#define MDP_AAL_CFG (0x020) +#define MDP_AAL_SIZE (0x030) +#define MDP_AAL_OUTPUT_SIZE (0x034) +#define MDP_AAL_OUTPUT_OFFSET (0x038) +#define MDP_AAL_CFG_MAIN (0x200) + +/* MASK */ +#define MDP_AAL_EN_MASK (0x01) +#define MDP_AAL_CFG_MASK (0x70FF00B3) +#define MDP_AAL_SIZE_MASK (0x1FFF1FFF) +#define MDP_AAL_OUTPUT_SIZE_MASK (0x1FFF1FFF) +#define MDP_AAL_OUTPUT_OFFSET_MASK (0x0FF00FF) +#define MDP_AAL_CFG_MAIN_MASK (0x0FE) + +#endif // __MDP_REG_AAL_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_color.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_color.h new file mode 100644 index 000000000000..f72503975b24 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_color.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_COLOR_H__ +#define __MDP_REG_COLOR_H__ + +#define MDP_COLOR_WIN_X_MAIN (0x40C) +#define MDP_COLOR_WIN_Y_MAIN (0x410) +#define MDP_COLOR_START (0xC00) +#define MDP_COLOR_INTEN (0xC04) +#define MDP_COLOR_OUT_SEL (0xC0C) +#define MDP_COLOR_INTERNAL_IP_WIDTH (0xC50) +#define MDP_COLOR_INTERNAL_IP_HEIGHT (0xC54) +#define MDP_COLOR_CM1_EN (0xC60) +#define MDP_COLOR_CM2_EN (0xCA0) + +/* MASK */ +#define MDP_COLOR_WIN_X_MAIN_MASK (0xFFFFFFFF) +#define MDP_COLOR_WIN_Y_MAIN_MASK (0xFFFFFFFF) +#define MDP_COLOR_START_MASK (0x0FF013F) +#define MDP_COLOR_INTEN_MASK (0x07) +#define MDP_COLOR_OUT_SEL_MASK (0x0777) +#define MDP_COLOR_INTERNAL_IP_WIDTH_MASK (0x03FFF) +#define MDP_COLOR_INTERNAL_IP_HEIGHT_MASK (0x03FFF) +#define MDP_COLOR_CM1_EN_MASK (0x03) +#define MDP_COLOR_CM2_EN_MASK (0x017) + +#endif // __MDP_REG_COLOR_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h new file mode 100644 index 000000000000..d90bcad33a59 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_FG_H__ +#define __MDP_REG_FG_H__ + +#define MDP_FG_TRIGGER (0x0) +#define MDP_FG_FG_CTRL_0 (0x20) +#define MDP_FG_FG_CK_EN (0x24) +#define MDP_FG_TILE_INFO_0 (0x418) +#define MDP_FG_TILE_INFO_1 (0x41c) + +/* MASK */ +#define MDP_FG_TRIGGER_MASK (0x00000007) +#define MDP_FG_FG_CTRL_0_MASK (0x00000033) +#define MDP_FG_FG_CK_EN_MASK (0x0000000F) +#define MDP_FG_TILE_INFO_0_MASK (0xFFFFFFFF) +#define MDP_FG_TILE_INFO_1_MASK (0xFFFFFFFF) + +#endif //__MDP_REG_FG_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h new file mode 100644 index 000000000000..c19fbba39fc0 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_HDR_H__ +#define __MDP_REG_HDR_H__ + +#define MDP_HDR_TOP (0x000) +#define MDP_HDR_RELAY (0x004) +#define MDP_HDR_SIZE_0 (0x014) +#define MDP_HDR_SIZE_1 (0x018) +#define MDP_HDR_SIZE_2 (0x01C) +#define MDP_HDR_HIST_CTRL_0 (0x020) +#define MDP_HDR_HIST_CTRL_1 (0x024) +#define MDP_HDR_HIST_ADDR (0x0DC) +#define MDP_HDR_TILE_POS (0x118) + +/* MASK */ +#define MDP_HDR_RELAY_MASK (0x01) +#define MDP_HDR_TOP_MASK (0xFF0FEB6D) +#define MDP_HDR_SIZE_0_MASK (0x1FFF1FFF) +#define MDP_HDR_SIZE_1_MASK (0x1FFF1FFF) +#define MDP_HDR_SIZE_2_MASK (0x1FFF1FFF) +#define MDP_HDR_HIST_CTRL_0_MASK (0x1FFF1FFF) +#define MDP_HDR_HIST_CTRL_1_MASK (0x1FFF1FFF) +#define MDP_HDR_HIST_ADDR_MASK (0xBF3F2F3F) +#define MDP_HDR_TILE_POS_MASK (0x1FFF1FFF) + +#endif // __MDP_REG_HDR_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h new file mode 100644 index 000000000000..46be27e2a656 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_MERGE_H__ +#define __MDP_REG_MERGE_H__ + +#define MDP_MERGE_ENABLE (0x000) +#define MDP_MERGE_CFG_0 (0x010) +#define MDP_MERGE_CFG_4 (0x020) +#define MDP_MERGE_CFG_12 (0x040) +#define MDP_MERGE_CFG_24 (0x070) +#define MDP_MERGE_CFG_25 (0x074) + +/* MASK */ +#define MDP_MERGE_ENABLE_MASK (0xFFFFFFFF) +#define MDP_MERGE_CFG_0_MASK (0xFFFFFFFF) +#define MDP_MERGE_CFG_4_MASK (0xFFFFFFFF) +#define MDP_MERGE_CFG_12_MASK (0xFFFFFFFF) +#define MDP_MERGE_CFG_24_MASK (0xFFFFFFFF) +#define MDP_MERGE_CFG_25_MASK (0xFFFFFFFF) + +#endif //__MDP_REG_MERGE_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h new file mode 100644 index 000000000000..21d2d0323293 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_OVL_H__ +#define __MDP_REG_OVL_H__ + +#define MDP_OVL_EN (0x00c) +#define MDP_OVL_ROI_SIZE (0x020) +#define MDP_OVL_DP_CON (0x024) +#define MDP_OVL_SRC_CON (0x02c) +#define MDP_OVL_L0_CON (0x030) +#define MDP_OVL_L0_SRC_SIZE (0x038) + +/* MASK */ +#define MDP_OVL_DP_CON_MASK (0x0FFFFFFF) +#define MDP_OVL_EN_MASK (0xB07D07B1) +#define MDP_OVL_L0_CON_MASK (0xFFFFFFFF) +#define MDP_OVL_L0_SRC_SIZE_MASK (0x1FFF1FFF) +#define MDP_OVL_ROI_SIZE_MASK (0x1FFF1FFF) +#define MDP_OVL_SRC_CON_MASK (0x0000031F) + +#endif //__MDP_REG_OVL_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h new file mode 100644 index 000000000000..0e89f1db19ed --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_PAD_H__ +#define __MDP_REG_PAD_H__ + +#define MDP_PAD_CON (0x000) +#define MDP_PAD_PIC_SIZE (0x004) +#define MDP_PAD_W_SIZE (0x008) +#define MDP_PAD_H_SIZE (0x00c) + +/* MASK */ +#define MDP_PAD_CON_MASK (0x00000007) +#define MDP_PAD_PIC_SIZE_MASK (0xFFFFFFFF) +#define MDP_PAD_W_SIZE_MASK (0x1FFF1FFF) +#define MDP_PAD_H_SIZE_MASK (0x1FFF1FFF) + +#endif // __MDP_REG_PAD_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h index be4065e252d3..0affb2a3b958 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h @@ -26,6 +26,18 @@ #define MDP_RDMA_SRC_OFFSET_2 0x128 #define MDP_RDMA_SRC_OFFSET_0_P 0x148 #define MDP_RDMA_TRANSFORM_0 0x200 +#define MDP_RDMA_DMABUF_CON_0 0x240 +#define MDP_RDMA_ULTRA_TH_HIGH_CON_0 0x248 +#define MDP_RDMA_ULTRA_TH_LOW_CON_0 0x250 +#define MDP_RDMA_DMABUF_CON_1 0x258 +#define MDP_RDMA_ULTRA_TH_HIGH_CON_1 0x260 +#define MDP_RDMA_ULTRA_TH_LOW_CON_1 0x268 +#define MDP_RDMA_DMABUF_CON_2 0x270 +#define MDP_RDMA_ULTRA_TH_HIGH_CON_2 0x278 +#define MDP_RDMA_ULTRA_TH_LOW_CON_2 0x280 +#define MDP_RDMA_DMABUF_CON_3 0x288 +#define MDP_RDMA_ULTRA_TH_HIGH_CON_3 0x290 +#define MDP_RDMA_ULTRA_TH_LOW_CON_3 0x298 #define MDP_RDMA_RESV_DUMMY_0 0x2a0 #define MDP_RDMA_MON_STA_1 0x408 #define MDP_RDMA_SRC_BASE_0 0xf00 @@ -54,6 +66,18 @@ #define MDP_RDMA_SRC_OFFSET_2_MASK 0xffffffff #define MDP_RDMA_SRC_OFFSET_0_P_MASK 0xffffffff #define MDP_RDMA_TRANSFORM_0_MASK 0xff110777 +#define MDP_RDMA_DMABUF_CON_0_MASK 0x0fff00ff +#define MDP_RDMA_ULTRA_TH_HIGH_CON_0_MASK 0x3fffffff +#define MDP_RDMA_ULTRA_TH_LOW_CON_0_MASK 0x3fffffff +#define MDP_RDMA_DMABUF_CON_1_MASK 0x0f7f007f +#define MDP_RDMA_ULTRA_TH_HIGH_CON_1_MASK 0x3fffffff +#define MDP_RDMA_ULTRA_TH_LOW_CON_1_MASK 0x3fffffff +#define MDP_RDMA_DMABUF_CON_2_MASK 0x0f3f003f +#define MDP_RDMA_ULTRA_TH_HIGH_CON_2_MASK 0x3fffffff +#define MDP_RDMA_ULTRA_TH_LOW_CON_2_MASK 0x3fffffff +#define MDP_RDMA_DMABUF_CON_3_MASK 0x0f3f003f +#define MDP_RDMA_ULTRA_TH_HIGH_CON_3_MASK 0x3fffffff +#define MDP_RDMA_ULTRA_TH_LOW_CON_3_MASK 0x3fffffff #define MDP_RDMA_RESV_DUMMY_0_MASK 0xffffffff #define MDP_RDMA_MON_STA_1_MASK 0xffffffff #define MDP_RDMA_SRC_BASE_0_MASK 0xffffffff diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h index 484f6d60641f..187531db8e3b 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h @@ -20,6 +20,7 @@ #define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET 0x02c #define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET 0x030 #define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET 0x034 +#define RSZ_ETC_CONTROL 0x22c /* MASK */ #define PRZ_ENABLE_MASK 0x00010001 @@ -35,5 +36,6 @@ #define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET_MASK 0x001fffff #define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET_MASK 0x0000ffff #define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET_MASK 0x001fffff +#define RSZ_ETC_CONTROL_MASK 0xff770000 #endif // __MDP_REG_RSZ_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h new file mode 100644 index 000000000000..83b5f9b432d8 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_REG_TDSHP_H__ +#define __MDP_REG_TDSHP_H__ + +#define MDP_HIST_CFG_00 (0x064) +#define MDP_HIST_CFG_01 (0x068) +#define MDP_TDSHP_CTRL (0x100) +#define MDP_TDSHP_CFG (0x110) +#define MDP_TDSHP_INPUT_SIZE (0x120) +#define MDP_TDSHP_OUTPUT_OFFSET (0x124) +#define MDP_TDSHP_OUTPUT_SIZE (0x128) +#define MDP_LUMA_HIST_INIT (0x200) +#define MDP_DC_TWO_D_W1_RESULT_INIT (0x260) +#define MDP_CONTOUR_HIST_INIT (0x398) + +/* MASK */ +#define MDP_HIST_CFG_00_MASK (0xFFFFFFFF) +#define MDP_HIST_CFG_01_MASK (0xFFFFFFFF) +#define MDP_LUMA_HIST_MASK (0xFFFFFFFF) +#define MDP_TDSHP_CTRL_MASK (0x07) +#define MDP_TDSHP_CFG_MASK (0x03F7) +#define MDP_TDSHP_INPUT_SIZE_MASK (0x1FFF1FFF) +#define MDP_TDSHP_OUTPUT_OFFSET_MASK (0x0FF00FF) +#define MDP_TDSHP_OUTPUT_SIZE_MASK (0x1FFF1FFF) +#define MDP_LUMA_HIST_INIT_MASK (0xFFFFFFFF) +#define MDP_DC_TWO_D_W1_RESULT_INIT_MASK (0x007FFFFF) +#define MDP_CONTOUR_HIST_INIT_MASK (0xFFFFFFFF) + +#endif // __MDP_REG_TDSHP_H__ diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h index 6d3ff0e2b672..b6f016d2c29d 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h +++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h @@ -17,14 +17,18 @@ #define VIDO_STRIDE 0x030 #define VIDO_OFST_ADDR_C 0x038 #define VIDO_STRIDE_C 0x03c +#define VIDO_CTRL_2 0x048 #define VIDO_DITHER 0x054 #define VIDO_STRIDE_V 0x06c #define VIDO_OFST_ADDR_V 0x068 #define VIDO_RSV_1 0x070 +#define VIDO_DMA_PREULTRA 0x074 #define VIDO_IN_SIZE 0x078 #define VIDO_ROT_EN 0x07c #define VIDO_FIFO_TEST 0x080 #define VIDO_MAT_CTRL 0x084 +#define VIDO_SCAN_10BIT 0x0dc +#define VIDO_PENDING_ZERO 0x0e0 #define VIDO_BASE_ADDR 0xf00 #define VIDO_BASE_ADDR_C 0xf04 #define VIDO_BASE_ADDR_V 0xf08 @@ -40,14 +44,18 @@ #define VIDO_STRIDE_MASK 0x0000ffff #define VIDO_OFST_ADDR_C_MASK 0x0fffffff #define VIDO_STRIDE_C_MASK 0x0000ffff +#define VIDO_CTRL_2_MASK 0x0000000f #define VIDO_DITHER_MASK 0xff000001 #define VIDO_STRIDE_V_MASK 0x0000ffff #define VIDO_OFST_ADDR_V_MASK 0x0fffffff #define VIDO_RSV_1_MASK 0xffffffff +#define VIDO_DMA_PREULTRA_MASK 0x00ffffff #define VIDO_IN_SIZE_MASK 0x1fff1fff #define VIDO_ROT_EN_MASK 0x00000001 #define VIDO_FIFO_TEST_MASK 0x00000fff #define VIDO_MAT_CTRL_MASK 0x000000f3 +#define VIDO_SCAN_10BIT_MASK 0x0000000f +#define VIDO_PENDING_ZERO_MASK 0x07ffffff #define VIDO_BASE_ADDR_MASK 0xffffffff #define VIDO_BASE_ADDR_C_MASK 0xffffffff #define VIDO_BASE_ADDR_V_MASK 0xffffffff diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h index e89c51e1edb7..e6cbc6ab6bae 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h @@ -84,22 +84,66 @@ enum mtk_mdp_comp_id { MDP_COMP_CAMIN, /* 9 */ MDP_COMP_CAMIN2, /* 10 */ MDP_COMP_RDMA0, /* 11 */ - MDP_COMP_AAL0, /* 12 */ - MDP_COMP_CCORR0, /* 13 */ - MDP_COMP_RSZ0, /* 14 */ - MDP_COMP_RSZ1, /* 15 */ - MDP_COMP_TDSHP0, /* 16 */ - MDP_COMP_COLOR0, /* 17 */ - MDP_COMP_PATH0_SOUT, /* 18 */ - MDP_COMP_PATH1_SOUT, /* 19 */ - MDP_COMP_WROT0, /* 20 */ - MDP_COMP_WDMA, /* 21 */ - - /* Dummy Engine */ - MDP_COMP_RDMA1, /* 22 */ - MDP_COMP_RSZ2, /* 23 */ - MDP_COMP_TDSHP1, /* 24 */ - MDP_COMP_WROT1, /* 25 */ + MDP_COMP_RDMA1, /* 12 */ + MDP_COMP_RDMA2, /* 13 */ + MDP_COMP_RDMA3, /* 14 */ + MDP_COMP_AAL0, /* 15 */ + MDP_COMP_AAL1, /* 16 */ + MDP_COMP_AAL2, /* 17 */ + MDP_COMP_AAL3, /* 18 */ + MDP_COMP_CCORR0, /* 19 */ + MDP_COMP_RSZ0, /* 20 */ + MDP_COMP_RSZ1, /* 21 */ + MDP_COMP_RSZ2, /* 22 */ + MDP_COMP_RSZ3, /* 23 */ + MDP_COMP_TDSHP0, /* 24 */ + MDP_COMP_TDSHP1, /* 25 */ + MDP_COMP_TDSHP2, /* 26 */ + MDP_COMP_TDSHP3, /* 27 */ + MDP_COMP_COLOR0, /* 28 */ + MDP_COMP_COLOR1, /* 29 */ + MDP_COMP_COLOR2, /* 30 */ + MDP_COMP_COLOR3, /* 31 */ + MDP_COMP_PATH0_SOUT, /* 32 */ + MDP_COMP_PATH1_SOUT, /* 33 */ + MDP_COMP_WROT0, /* 34 */ + MDP_COMP_WROT1, /* 35 */ + MDP_COMP_WROT2, /* 36 */ + MDP_COMP_WROT3, /* 37 */ + MDP_COMP_WDMA, /* 38 */ + MDP_COMP_SPLIT, /* 39 */ + MDP_COMP_SPLIT2, /* 40 */ + MDP_COMP_STITCH, /* 41 */ + MDP_COMP_FG0, /* 42 */ + MDP_COMP_FG1, /* 43 */ + MDP_COMP_FG2, /* 44 */ + MDP_COMP_FG3, /* 45 */ + MDP_COMP_TO_SVPP2MOUT, /* 46 */ + MDP_COMP_TO_SVPP3MOUT, /* 47 */ + MDP_COMP_TO_WARP0MOUT, /* 48 */ + MDP_COMP_TO_WARP1MOUT, /* 49 */ + MDP_COMP_VPP0_SOUT, /* 50 */ + MDP_COMP_VPP1_SOUT, /* 51 */ + MDP_COMP_PQ0_SOUT, /* 52 */ + MDP_COMP_PQ1_SOUT, /* 53 */ + MDP_COMP_HDR0, /* 54 */ + MDP_COMP_HDR1, /* 55 */ + MDP_COMP_HDR2, /* 56 */ + MDP_COMP_HDR3, /* 57 */ + MDP_COMP_OVL0, /* 58 */ + MDP_COMP_OVL1, /* 59 */ + MDP_COMP_PAD0, /* 60 */ + MDP_COMP_PAD1, /* 61 */ + MDP_COMP_PAD2, /* 62 */ + MDP_COMP_PAD3, /* 63 */ + MDP_COMP_TCC0, /* 64 */ + MDP_COMP_TCC1, /* 65 */ + MDP_COMP_MERGE2, /* 66 */ + MDP_COMP_MERGE3, /* 67 */ + MDP_COMP_VDO0DL0, /* 68 */ + MDP_COMP_VDO1DL0, /* 69 */ + MDP_COMP_VDO0DL1, /* 70 */ + MDP_COMP_VDO1DL1, /* 71 */ MDP_MAX_COMP_COUNT /* ALWAYS keep at the end */ }; @@ -117,12 +161,21 @@ enum mdp_comp_type { MDP_COMP_TYPE_COLOR, MDP_COMP_TYPE_DRE, MDP_COMP_TYPE_CCORR, + MDP_COMP_TYPE_AAL, + MDP_COMP_TYPE_TCC, MDP_COMP_TYPE_HDR, + MDP_COMP_TYPE_SPLIT, + MDP_COMP_TYPE_STITCH, + MDP_COMP_TYPE_FG, + MDP_COMP_TYPE_OVL, + MDP_COMP_TYPE_PAD, + MDP_COMP_TYPE_MERGE, MDP_COMP_TYPE_IMGI, MDP_COMP_TYPE_WPEI, MDP_COMP_TYPE_EXTO, /* External path */ MDP_COMP_TYPE_DL_PATH, /* Direct-link path */ + MDP_COMP_TYPE_DUMMY, MDP_COMP_TYPE_COUNT /* ALWAYS keep at the end */ }; From 92cdfc39af1b8f582b21f863ccd9983b9813b554 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:31 +0100 Subject: [PATCH 078/252] media: platform: mtk-mdp3: add checks for dummy components Some components act as bridges only and do not require full configuration. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mdp_cfg_data.c | 8 +++ .../platform/mediatek/mdp3/mtk-mdp3-cfg.h | 1 + .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 58 ++++++++++++++++++- .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 9 ++- 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c index fcc582292b77..fe92c0474bfa 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c @@ -451,3 +451,11 @@ enum mtk_mdp_comp_id mdp_cfg_get_id_public(struct mdp_dev *mdp_dev, s32 inner_id err_public_id: return public_id; } + +bool mdp_cfg_comp_is_dummy(struct mdp_dev *mdp_dev, s32 inner_id) +{ + enum mtk_mdp_comp_id id = mdp_cfg_get_id_public(mdp_dev, inner_id); + enum mdp_comp_type type = mdp_dev->mdp_data->comp_data[id].match.type; + + return (type == MDP_COMP_TYPE_DUMMY); +} diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h index dee57cc4a954..dfffc72868e4 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h @@ -16,5 +16,6 @@ enum mtk_mdp_comp_id; s32 mdp_cfg_get_id_inner(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id); enum mtk_mdp_comp_id mdp_cfg_get_id_public(struct mdp_dev *mdp_dev, s32 id); +bool mdp_cfg_comp_is_dummy(struct mdp_dev *mdp_dev, s32 inner_id); #endif /* __MTK_MDP3_CFG_H__ */ diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 31930ddbc828..a81caf5f472c 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -6,6 +6,7 @@ #include #include +#include "mtk-mdp3-cfg.h" #include "mtk-mdp3-cmdq.h" #include "mtk-mdp3-comp.h" #include "mtk-mdp3-core.h" @@ -108,6 +109,12 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, /* Set mutex mod */ for (index = 0; index < num_comp; index++) { + s32 inner_id = MDP_COMP_NONE; + + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -132,6 +139,7 @@ static int mdp_path_subfrm_run(const struct mdp_path *path, int index; u32 num_comp = 0; s32 event; + s32 inner_id = MDP_COMP_NONE; if (-1 == p->mutex_id) { dev_err(dev, "Incorrect mutex id"); @@ -144,6 +152,10 @@ static int mdp_path_subfrm_run(const struct mdp_path *path, /* Wait WROT SRAM shared to DISP RDMA */ /* Clear SOF event for each engine */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -158,6 +170,10 @@ static int mdp_path_subfrm_run(const struct mdp_path *path, /* Wait SOF events and clear mutex modules (optional) */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -183,6 +199,12 @@ static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path) return -EINVAL; for (index = 0; index < num_comp; index++) { + s32 inner_id = MDP_COMP_NONE; + + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; if (CFG_CHECK(MT8183, p_id)) param = (void *)CFG_ADDR(MT8183, path->config, components[index]); ret = mdp_comp_ctx_config(mdp, &path->comps[index], @@ -204,6 +226,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, struct mdp_pipe_info pipe; int index, ret; u32 num_comp = 0; + s32 inner_id = MDP_COMP_NONE; if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); @@ -223,6 +246,10 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, } /* Config sub-frame information */ for (index = (num_comp - 1); index >= 0; index--) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -236,6 +263,10 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, return ret; /* Wait components done */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; @@ -245,6 +276,10 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, } /* Advance to the next sub-frame */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; ret = call_op(ctx, advance_subfrm, cmd, count); if (ret) @@ -268,6 +303,7 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, int index, count, ret; u32 num_comp = 0; u32 num_sub = 0; + s32 inner_id = MDP_COMP_NONE; if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); @@ -278,6 +314,10 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, /* Config path frame */ /* Reset components */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; ret = call_op(ctx, init_comp, cmd); if (ret) @@ -289,6 +329,11 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, u32 out = 0; ctx = &path->comps[index]; + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; + if (CFG_CHECK(MT8183, p_id)) out = CFG_COMP(MT8183, ctx->param, outputs[0]); @@ -306,6 +351,10 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, } /* Post processing information */ for (index = 0; index < num_comp; index++) { + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) + continue; ctx = &path->comps[index]; ret = call_op(ctx, post_process, cmd); if (ret) @@ -508,9 +557,16 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) } cmdq_pkt_finalize(&cmd->pkt); - for (i = 0; i < num_comp; i++) + for (i = 0; i < num_comp; i++) { + s32 inner_id = MDP_COMP_NONE; + + if (CFG_CHECK(MT8183, p_id)) + inner_id = CFG_GET(MT8183, path->config, components[i].type); + if (mdp_cfg_comp_is_dummy(mdp, inner_id)) + continue; memcpy(&comps[i], path->comps[i].comp, sizeof(struct mdp_comp)); + } mdp->cmdq_clt->client.rx_callback = mdp_handle_cmdq_callback; cmd->mdp = mdp; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index 575c8d52acd1..93df2e013438 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -853,6 +853,9 @@ int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num) int i, ret; for (i = 0; i < num; i++) { + /* Bypass the dummy component*/ + if (!comps[i].mdp_dev) + continue; ret = mdp_comp_clock_on(dev, &comps[i]); if (ret) return ret; @@ -865,8 +868,12 @@ void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num) { int i; - for (i = 0; i < num; i++) + for (i = 0; i < num; i++) { + /* Bypass the dummy component*/ + if (!comps[i].mdp_dev) + continue; mdp_comp_clock_off(dev, &comps[i]); + } } static int mdp_get_subsys_id(struct mdp_dev *mdp, struct device *dev, From 4294b9d6c8c40501e2dd824f6aad3f0b981cedf1 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:32 +0100 Subject: [PATCH 079/252] media: platform: mtk-mdp3: avoid multiple driver registrations The amount of MDP3 driver probes is determined by the registered clocks of MMSYS. Since MT8195 MDP3 utilizes VPPSYS0 and VPPSYS1, it's necessary to prevent multiple driver registrations. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c | 1 + drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c | 8 ++++++++ drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h | 1 + 3 files changed, 10 insertions(+) diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c index fe92c0474bfa..6f77c33074ec 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c @@ -410,6 +410,7 @@ static const struct mdp_pipe_info mt8183_pipe_info[] = { const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { .mdp_plat_id = MT8183, + .mdp_con_res = 0x14001000, .mdp_probe_infra = mt8183_mdp_probe_infra, .mdp_cfg = &mt8183_plat_cfg, .mdp_mutex_table_idx = mt8183_mutex_idx, diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index 4802b20d7f20..6ddb5e075f5d 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -211,6 +211,7 @@ static int mdp_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct mdp_dev *mdp; struct platform_device *mm_pdev; + struct resource *res; int ret, i, mutex_id; mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); @@ -222,6 +223,12 @@ static int mdp_probe(struct platform_device *pdev) mdp->pdev = pdev; mdp->mdp_data = of_device_get_match_data(&pdev->dev); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res->start != mdp->mdp_data->mdp_con_res) { + platform_set_drvdata(pdev, mdp); + goto success_return; + } + ret = mdp_mm_subsys_deploy(mdp, MDP_INFRA_MMSYS); if (ret) goto err_destroy_device; @@ -311,6 +318,7 @@ static int mdp_probe(struct platform_device *pdev) goto err_unregister_device; } +success_return: dev_dbg(dev, "mdp-%d registered successfully\n", pdev->id); return 0; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index ece6509666fd..22d1b17ef2fc 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -71,6 +71,7 @@ enum mdp_pipe_id { struct mtk_mdp_driver_data { const int mdp_plat_id; + const resource_size_t mdp_con_res; const struct of_device_id *mdp_probe_infra; const struct mdp_platform_config *mdp_cfg; const u32 *mdp_mutex_table_idx; From bd2fac0048ed09480eecd82d86cefedcf0167399 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:33 +0100 Subject: [PATCH 080/252] media: platform: mtk-mdp3: extend GCE event waiting in RDMA and WROT Support for multiple RDMA/WROT waits for GCE events. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mdp_cfg_data.c | 2 ++ .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 27 +++++++++++++------ .../platform/mediatek/mdp3/mtk-mdp3-core.h | 2 ++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c index 6f77c33074ec..3834efe54e17 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c @@ -56,8 +56,10 @@ static const struct mdp_platform_config mt8183_plat_cfg = { .rdma_support_10bit = true, .rdma_rsz1_sram_sharing = true, .rdma_upsample_repeat_only = true, + .rdma_event_num = 1, .rsz_disable_dcm_small_sample = false, .wrot_filter_constraint = false, + .wrot_event_num = 1, }; static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = { diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index 93df2e013438..ed6092e1666f 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -251,14 +251,20 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx, static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) { + const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx); struct device *dev = &ctx->comp->mdp_dev->pdev->dev; phys_addr_t base = ctx->comp->reg_base; u8 subsys_id = ctx->comp->subsys_id; - if (ctx->comp->alias_id == 0) - MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); - else - dev_err(dev, "Do not support RDMA1_DONE event\n"); + if (!mdp_cfg) + return -EINVAL; + + if (ctx->comp->alias_id >= mdp_cfg->rdma_event_num) { + dev_err(dev, "Invalid RDMA event %d\n", ctx->comp->alias_id); + return -EINVAL; + } + + MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); /* Disable RDMA */ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0)); @@ -553,10 +559,15 @@ static int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) phys_addr_t base = ctx->comp->reg_base; u8 subsys_id = ctx->comp->subsys_id; - if (ctx->comp->alias_id == 0) - MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); - else - dev_err(dev, "Do not support WROT1_DONE event\n"); + if (!mdp_cfg) + return -EINVAL; + + if (ctx->comp->alias_id >= mdp_cfg->wrot_event_num) { + dev_err(dev, "Invalid WROT event %d!\n", ctx->comp->alias_id); + return -EINVAL; + } + + MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); if (mdp_cfg && mdp_cfg->wrot_filter_constraint) MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0, diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index 22d1b17ef2fc..e57c415a1c78 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -49,8 +49,10 @@ struct mdp_platform_config { bool rdma_support_10bit; bool rdma_rsz1_sram_sharing; bool rdma_upsample_repeat_only; + u32 rdma_event_num; bool rsz_disable_dcm_small_sample; bool wrot_filter_constraint; + u32 wrot_event_num; }; /* indicate which mutex is used by each pipepline */ From d97fd41e83f4468e1abb58b0a706456bc7f65162 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:34 +0100 Subject: [PATCH 081/252] media: platform: mtk-mdp3: add support for blending multiple components Certain chips can combine several components to form complex virtual units with advanced functions. These components require simultaneous configuration of their MODs and clocks. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 12 ++++++-- .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 29 +++++++++++++++++-- .../platform/mediatek/mdp3/mtk-mdp3-comp.h | 7 +++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index a81caf5f472c..f0c5f5abeb23 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -110,17 +110,25 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, /* Set mutex mod */ for (index = 0; index < num_comp; index++) { s32 inner_id = MDP_COMP_NONE; + const u32 *mutex_idx; + const struct mdp_comp_blend *b; if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; + ctx = &path->comps[index]; if (is_output_disabled(p_id, ctx->param, count)) continue; - id = ctx->comp->public_id; - mtk_mutex_write_mod(mutex, data->mdp_mutex_table_idx[id], false); + mutex_idx = data->mdp_mutex_table_idx; + id = ctx->comp->public_id; + mtk_mutex_write_mod(mutex, mutex_idx[id], false); + + b = &data->comp_data[id].blend; + if (b && b->aid_mod) + mtk_mutex_write_mod(mutex, mutex_idx[b->b_id], false); } mtk_mutex_write_sof(mutex, MUTEX_SOF_IDX_SINGLE_MODE); diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index ed6092e1666f..e97630b7867c 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -864,12 +864,26 @@ int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num) int i, ret; for (i = 0; i < num; i++) { + struct mdp_dev *m = comps[i].mdp_dev; + enum mtk_mdp_comp_id id; + const struct mdp_comp_blend *b; + /* Bypass the dummy component*/ - if (!comps[i].mdp_dev) + if (!m) continue; + ret = mdp_comp_clock_on(dev, &comps[i]); if (ret) return ret; + + id = comps[i].public_id; + b = &m->mdp_data->comp_data[id].blend; + + if (b && b->aid_clk) { + ret = mdp_comp_clock_on(dev, m->comp[b->b_id]); + if (ret) + return ret; + } } return 0; @@ -880,10 +894,21 @@ void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num) int i; for (i = 0; i < num; i++) { + struct mdp_dev *m = comps[i].mdp_dev; + enum mtk_mdp_comp_id id; + const struct mdp_comp_blend *b; + /* Bypass the dummy component*/ - if (!comps[i].mdp_dev) + if (!m) continue; + mdp_comp_clock_off(dev, &comps[i]); + + id = comps[i].public_id; + b = &m->mdp_data->comp_data[id].blend; + + if (b && b->aid_clk) + mdp_comp_clock_off(dev, m->comp[b->b_id]); } } diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h index e6cbc6ab6bae..3e5d2da1c807 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h @@ -201,9 +201,16 @@ struct mdp_comp_info { u32 dts_reg_ofst; }; +struct mdp_comp_blend { + enum mtk_mdp_comp_id b_id; + bool aid_mod; + bool aid_clk; +}; + struct mdp_comp_data { struct mdp_comp_match match; struct mdp_comp_info info; + struct mdp_comp_blend blend; }; struct mdp_comp_ops; From adce64c4cef6f08ac6fa51546d94d3a49a66144f Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:35 +0100 Subject: [PATCH 082/252] media: platform: mtk-mdp3: add mt8195 platform configuration Add MT8195 MDP3 basic configuration in file "mdp_cfg_data.c" and corresponding driver data. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mdp_cfg_data.c | 666 ++++++++++++++++++ .../platform/mediatek/mdp3/mtk-img-ipi.h | 1 + .../platform/mediatek/mdp3/mtk-mdp3-cfg.h | 1 + .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 36 + .../platform/mediatek/mdp3/mtk-mdp3-core.c | 6 + .../platform/mediatek/mdp3/mtk-mdp3-core.h | 6 + 6 files changed, 716 insertions(+) diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c index 3834efe54e17..9ee3931d31e3 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c @@ -46,12 +46,91 @@ enum mt8183_mdp_comp_id { MT8183_MDP_COMP_WROT1, /* 25 */ }; +enum mt8195_mdp_comp_id { + /* MT8195 Comp id */ + /* ISP */ + MT8195_MDP_COMP_WPEI = 0, + MT8195_MDP_COMP_WPEO, /* 1 */ + MT8195_MDP_COMP_WPEI2, /* 2 */ + MT8195_MDP_COMP_WPEO2, /* 3 */ + + /* MDP */ + MT8195_MDP_COMP_CAMIN, /* 4 */ + MT8195_MDP_COMP_CAMIN2, /* 5 */ + MT8195_MDP_COMP_SPLIT, /* 6 */ + MT8195_MDP_COMP_SPLIT2, /* 7 */ + MT8195_MDP_COMP_RDMA0, /* 8 */ + MT8195_MDP_COMP_RDMA1, /* 9 */ + MT8195_MDP_COMP_RDMA2, /* 10 */ + MT8195_MDP_COMP_RDMA3, /* 11 */ + MT8195_MDP_COMP_STITCH, /* 12 */ + MT8195_MDP_COMP_FG0, /* 13 */ + MT8195_MDP_COMP_FG1, /* 14 */ + MT8195_MDP_COMP_FG2, /* 15 */ + MT8195_MDP_COMP_FG3, /* 16 */ + MT8195_MDP_COMP_TO_SVPP2MOUT, /* 17 */ + MT8195_MDP_COMP_TO_SVPP3MOUT, /* 18 */ + MT8195_MDP_COMP_TO_WARP0MOUT, /* 19 */ + MT8195_MDP_COMP_TO_WARP1MOUT, /* 20 */ + MT8195_MDP_COMP_VPP0_SOUT, /* 21 */ + MT8195_MDP_COMP_VPP1_SOUT, /* 22 */ + MT8195_MDP_COMP_PQ0_SOUT, /* 23 */ + MT8195_MDP_COMP_PQ1_SOUT, /* 24 */ + MT8195_MDP_COMP_HDR0, /* 25 */ + MT8195_MDP_COMP_HDR1, /* 26 */ + MT8195_MDP_COMP_HDR2, /* 27 */ + MT8195_MDP_COMP_HDR3, /* 28 */ + MT8195_MDP_COMP_AAL0, /* 29 */ + MT8195_MDP_COMP_AAL1, /* 30 */ + MT8195_MDP_COMP_AAL2, /* 31 */ + MT8195_MDP_COMP_AAL3, /* 32 */ + MT8195_MDP_COMP_RSZ0, /* 33 */ + MT8195_MDP_COMP_RSZ1, /* 34 */ + MT8195_MDP_COMP_RSZ2, /* 35 */ + MT8195_MDP_COMP_RSZ3, /* 36 */ + MT8195_MDP_COMP_TDSHP0, /* 37 */ + MT8195_MDP_COMP_TDSHP1, /* 38 */ + MT8195_MDP_COMP_TDSHP2, /* 39 */ + MT8195_MDP_COMP_TDSHP3, /* 40 */ + MT8195_MDP_COMP_COLOR0, /* 41 */ + MT8195_MDP_COMP_COLOR1, /* 42 */ + MT8195_MDP_COMP_COLOR2, /* 43 */ + MT8195_MDP_COMP_COLOR3, /* 44 */ + MT8195_MDP_COMP_OVL0, /* 45 */ + MT8195_MDP_COMP_OVL1, /* 46 */ + MT8195_MDP_COMP_PAD0, /* 47 */ + MT8195_MDP_COMP_PAD1, /* 48 */ + MT8195_MDP_COMP_PAD2, /* 49 */ + MT8195_MDP_COMP_PAD3, /* 50 */ + MT8195_MDP_COMP_TCC0, /* 51 */ + MT8195_MDP_COMP_TCC1, /* 52 */ + MT8195_MDP_COMP_WROT0, /* 53 */ + MT8195_MDP_COMP_WROT1, /* 54 */ + MT8195_MDP_COMP_WROT2, /* 55 */ + MT8195_MDP_COMP_WROT3, /* 56 */ + MT8195_MDP_COMP_MERGE2, /* 57 */ + MT8195_MDP_COMP_MERGE3, /* 58 */ + + MT8195_MDP_COMP_VDO0DL0, /* 59 */ + MT8195_MDP_COMP_VDO1DL0, /* 60 */ + MT8195_MDP_COMP_VDO0DL1, /* 61 */ + MT8195_MDP_COMP_VDO1DL1, /* 62 */ +}; + static const struct of_device_id mt8183_mdp_probe_infra[MDP_INFRA_MAX] = { [MDP_INFRA_MMSYS] = { .compatible = "mediatek,mt8183-mmsys" }, [MDP_INFRA_MUTEX] = { .compatible = "mediatek,mt8183-disp-mutex" }, [MDP_INFRA_SCP] = { .compatible = "mediatek,mt8183-scp" } }; +static const struct of_device_id mt8195_mdp_probe_infra[MDP_INFRA_MAX] = { + [MDP_INFRA_MMSYS] = { .compatible = "mediatek,mt8195-vppsys0" }, + [MDP_INFRA_MMSYS2] = { .compatible = "mediatek,mt8195-vppsys1" }, + [MDP_INFRA_MUTEX] = { .compatible = "mediatek,mt8195-vpp-mutex" }, + [MDP_INFRA_MUTEX2] = { .compatible = "mediatek,mt8195-vpp-mutex" }, + [MDP_INFRA_SCP] = { .compatible = "mediatek,mt8195-scp" } +}; + static const struct mdp_platform_config mt8183_plat_cfg = { .rdma_support_10bit = true, .rdma_rsz1_sram_sharing = true, @@ -62,6 +141,21 @@ static const struct mdp_platform_config mt8183_plat_cfg = { .wrot_event_num = 1, }; +static const struct mdp_platform_config mt8195_plat_cfg = { + .rdma_support_10bit = true, + .rdma_rsz1_sram_sharing = false, + .rdma_upsample_repeat_only = false, + .rdma_esl_setting = true, + .rdma_event_num = 4, + .rsz_disable_dcm_small_sample = false, + .rsz_etc_control = true, + .wrot_filter_constraint = false, + .wrot_event_num = 4, + .tdshp_hist_num = 17, + .tdshp_constrain = true, + .tdshp_contour = true, +}; + static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = { [MDP_COMP_RDMA0] = MUTEX_MOD_IDX_MDP_RDMA0, [MDP_COMP_RSZ0] = MUTEX_MOD_IDX_MDP_RSZ0, @@ -73,6 +167,52 @@ static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = { [MDP_COMP_CCORR0] = MUTEX_MOD_IDX_MDP_CCORR0, }; +static const u32 mt8195_mutex_idx[MDP_MAX_COMP_COUNT] = { + [MDP_COMP_RDMA0] = MUTEX_MOD_IDX_MDP_RDMA0, + [MDP_COMP_RDMA1] = MUTEX_MOD_IDX_MDP_RDMA1, + [MDP_COMP_RDMA2] = MUTEX_MOD_IDX_MDP_RDMA2, + [MDP_COMP_RDMA3] = MUTEX_MOD_IDX_MDP_RDMA3, + [MDP_COMP_STITCH] = MUTEX_MOD_IDX_MDP_STITCH0, + [MDP_COMP_FG0] = MUTEX_MOD_IDX_MDP_FG0, + [MDP_COMP_FG1] = MUTEX_MOD_IDX_MDP_FG1, + [MDP_COMP_FG2] = MUTEX_MOD_IDX_MDP_FG2, + [MDP_COMP_FG3] = MUTEX_MOD_IDX_MDP_FG3, + [MDP_COMP_HDR0] = MUTEX_MOD_IDX_MDP_HDR0, + [MDP_COMP_HDR1] = MUTEX_MOD_IDX_MDP_HDR1, + [MDP_COMP_HDR2] = MUTEX_MOD_IDX_MDP_HDR2, + [MDP_COMP_HDR3] = MUTEX_MOD_IDX_MDP_HDR3, + [MDP_COMP_AAL0] = MUTEX_MOD_IDX_MDP_AAL0, + [MDP_COMP_AAL1] = MUTEX_MOD_IDX_MDP_AAL1, + [MDP_COMP_AAL2] = MUTEX_MOD_IDX_MDP_AAL2, + [MDP_COMP_AAL3] = MUTEX_MOD_IDX_MDP_AAL3, + [MDP_COMP_RSZ0] = MUTEX_MOD_IDX_MDP_RSZ0, + [MDP_COMP_RSZ1] = MUTEX_MOD_IDX_MDP_RSZ1, + [MDP_COMP_RSZ2] = MUTEX_MOD_IDX_MDP_RSZ2, + [MDP_COMP_RSZ3] = MUTEX_MOD_IDX_MDP_RSZ3, + [MDP_COMP_MERGE2] = MUTEX_MOD_IDX_MDP_MERGE2, + [MDP_COMP_MERGE3] = MUTEX_MOD_IDX_MDP_MERGE3, + [MDP_COMP_TDSHP0] = MUTEX_MOD_IDX_MDP_TDSHP0, + [MDP_COMP_TDSHP1] = MUTEX_MOD_IDX_MDP_TDSHP1, + [MDP_COMP_TDSHP2] = MUTEX_MOD_IDX_MDP_TDSHP2, + [MDP_COMP_TDSHP3] = MUTEX_MOD_IDX_MDP_TDSHP3, + [MDP_COMP_COLOR0] = MUTEX_MOD_IDX_MDP_COLOR0, + [MDP_COMP_COLOR1] = MUTEX_MOD_IDX_MDP_COLOR1, + [MDP_COMP_COLOR2] = MUTEX_MOD_IDX_MDP_COLOR2, + [MDP_COMP_COLOR3] = MUTEX_MOD_IDX_MDP_COLOR3, + [MDP_COMP_OVL0] = MUTEX_MOD_IDX_MDP_OVL0, + [MDP_COMP_OVL1] = MUTEX_MOD_IDX_MDP_OVL1, + [MDP_COMP_PAD0] = MUTEX_MOD_IDX_MDP_PAD0, + [MDP_COMP_PAD1] = MUTEX_MOD_IDX_MDP_PAD1, + [MDP_COMP_PAD2] = MUTEX_MOD_IDX_MDP_PAD2, + [MDP_COMP_PAD3] = MUTEX_MOD_IDX_MDP_PAD3, + [MDP_COMP_TCC0] = MUTEX_MOD_IDX_MDP_TCC0, + [MDP_COMP_TCC1] = MUTEX_MOD_IDX_MDP_TCC1, + [MDP_COMP_WROT0] = MUTEX_MOD_IDX_MDP_WROT0, + [MDP_COMP_WROT1] = MUTEX_MOD_IDX_MDP_WROT1, + [MDP_COMP_WROT2] = MUTEX_MOD_IDX_MDP_WROT2, + [MDP_COMP_WROT3] = MUTEX_MOD_IDX_MDP_WROT3, +}; + static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = { [MDP_COMP_WPEI] = { {MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI, MDP_MM_SUBSYS_0}, @@ -148,6 +288,263 @@ static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = { }, }; +static const struct mdp_comp_data mt8195_mdp_comp_data[MDP_MAX_COMP_COUNT] = { + [MDP_COMP_WPEI] = { + {MDP_COMP_TYPE_WPEI, 0, MT8195_MDP_COMP_WPEI, MDP_MM_SUBSYS_0}, + {0, 0, 0} + }, + [MDP_COMP_WPEO] = { + {MDP_COMP_TYPE_EXTO, 2, MT8195_MDP_COMP_WPEO, MDP_MM_SUBSYS_0}, + {0, 0, 0} + }, + [MDP_COMP_WPEI2] = { + {MDP_COMP_TYPE_WPEI, 1, MT8195_MDP_COMP_WPEI2, MDP_MM_SUBSYS_0}, + {0, 0, 0} + }, + [MDP_COMP_WPEO2] = { + {MDP_COMP_TYPE_EXTO, 3, MT8195_MDP_COMP_WPEO2, MDP_MM_SUBSYS_0}, + {0, 0, 0} + }, + [MDP_COMP_CAMIN] = { + {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_CAMIN, MDP_MM_SUBSYS_0}, + {3, 3, 0} + }, + [MDP_COMP_CAMIN2] = { + {MDP_COMP_TYPE_DL_PATH, 1, MT8195_MDP_COMP_CAMIN2, MDP_MM_SUBSYS_0}, + {3, 6, 0} + }, + [MDP_COMP_SPLIT] = { + {MDP_COMP_TYPE_SPLIT, 0, MT8195_MDP_COMP_SPLIT, MDP_MM_SUBSYS_1}, + {7, 0, 0} + }, + [MDP_COMP_SPLIT2] = { + {MDP_COMP_TYPE_SPLIT, 1, MT8195_MDP_COMP_SPLIT2, MDP_MM_SUBSYS_1}, + {7, 0, 0} + }, + [MDP_COMP_RDMA0] = { + {MDP_COMP_TYPE_RDMA, 0, MT8195_MDP_COMP_RDMA0, MDP_MM_SUBSYS_0}, + {3, 0, 0} + }, + [MDP_COMP_RDMA1] = { + {MDP_COMP_TYPE_RDMA, 1, MT8195_MDP_COMP_RDMA1, MDP_MM_SUBSYS_1}, + {3, 0, 0} + }, + [MDP_COMP_RDMA2] = { + {MDP_COMP_TYPE_RDMA, 2, MT8195_MDP_COMP_RDMA2, MDP_MM_SUBSYS_1}, + {3, 0, 0} + }, + [MDP_COMP_RDMA3] = { + {MDP_COMP_TYPE_RDMA, 3, MT8195_MDP_COMP_RDMA3, MDP_MM_SUBSYS_1}, + {3, 0, 0} + }, + [MDP_COMP_STITCH] = { + {MDP_COMP_TYPE_STITCH, 0, MT8195_MDP_COMP_STITCH, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_FG0] = { + {MDP_COMP_TYPE_FG, 0, MT8195_MDP_COMP_FG0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_FG1] = { + {MDP_COMP_TYPE_FG, 1, MT8195_MDP_COMP_FG1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_FG2] = { + {MDP_COMP_TYPE_FG, 2, MT8195_MDP_COMP_FG2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_FG3] = { + {MDP_COMP_TYPE_FG, 3, MT8195_MDP_COMP_FG3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_HDR0] = { + {MDP_COMP_TYPE_HDR, 0, MT8195_MDP_COMP_HDR0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_HDR1] = { + {MDP_COMP_TYPE_HDR, 1, MT8195_MDP_COMP_HDR1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_HDR2] = { + {MDP_COMP_TYPE_HDR, 2, MT8195_MDP_COMP_HDR2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_HDR3] = { + {MDP_COMP_TYPE_HDR, 3, MT8195_MDP_COMP_HDR3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_AAL0] = { + {MDP_COMP_TYPE_AAL, 0, MT8195_MDP_COMP_AAL0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_AAL1] = { + {MDP_COMP_TYPE_AAL, 1, MT8195_MDP_COMP_AAL1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_AAL2] = { + {MDP_COMP_TYPE_AAL, 2, MT8195_MDP_COMP_AAL2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_AAL3] = { + {MDP_COMP_TYPE_AAL, 3, MT8195_MDP_COMP_AAL3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_RSZ0] = { + {MDP_COMP_TYPE_RSZ, 0, MT8195_MDP_COMP_RSZ0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_RSZ1] = { + {MDP_COMP_TYPE_RSZ, 1, MT8195_MDP_COMP_RSZ1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_RSZ2] = { + {MDP_COMP_TYPE_RSZ, 2, MT8195_MDP_COMP_RSZ2, MDP_MM_SUBSYS_1}, + {2, 0, 0}, + {MDP_COMP_MERGE2, true, true} + }, + [MDP_COMP_RSZ3] = { + {MDP_COMP_TYPE_RSZ, 3, MT8195_MDP_COMP_RSZ3, MDP_MM_SUBSYS_1}, + {2, 0, 0}, + {MDP_COMP_MERGE3, true, true} + }, + [MDP_COMP_TDSHP0] = { + {MDP_COMP_TYPE_TDSHP, 0, MT8195_MDP_COMP_TDSHP0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_TDSHP1] = { + {MDP_COMP_TYPE_TDSHP, 1, MT8195_MDP_COMP_TDSHP1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_TDSHP2] = { + {MDP_COMP_TYPE_TDSHP, 2, MT8195_MDP_COMP_TDSHP2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_TDSHP3] = { + {MDP_COMP_TYPE_TDSHP, 3, MT8195_MDP_COMP_TDSHP3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_COLOR0] = { + {MDP_COMP_TYPE_COLOR, 0, MT8195_MDP_COMP_COLOR0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_COLOR1] = { + {MDP_COMP_TYPE_COLOR, 1, MT8195_MDP_COMP_COLOR1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_COLOR2] = { + {MDP_COMP_TYPE_COLOR, 2, MT8195_MDP_COMP_COLOR2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_COLOR3] = { + {MDP_COMP_TYPE_COLOR, 3, MT8195_MDP_COMP_COLOR3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_OVL0] = { + {MDP_COMP_TYPE_OVL, 0, MT8195_MDP_COMP_OVL0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_OVL1] = { + {MDP_COMP_TYPE_OVL, 1, MT8195_MDP_COMP_OVL1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_PAD0] = { + {MDP_COMP_TYPE_PAD, 0, MT8195_MDP_COMP_PAD0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_PAD1] = { + {MDP_COMP_TYPE_PAD, 1, MT8195_MDP_COMP_PAD1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_PAD2] = { + {MDP_COMP_TYPE_PAD, 2, MT8195_MDP_COMP_PAD2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_PAD3] = { + {MDP_COMP_TYPE_PAD, 3, MT8195_MDP_COMP_PAD3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_TCC0] = { + {MDP_COMP_TYPE_TCC, 0, MT8195_MDP_COMP_TCC0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_TCC1] = { + {MDP_COMP_TYPE_TCC, 1, MT8195_MDP_COMP_TCC1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_WROT0] = { + {MDP_COMP_TYPE_WROT, 0, MT8195_MDP_COMP_WROT0, MDP_MM_SUBSYS_0}, + {1, 0, 0} + }, + [MDP_COMP_WROT1] = { + {MDP_COMP_TYPE_WROT, 1, MT8195_MDP_COMP_WROT1, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_WROT2] = { + {MDP_COMP_TYPE_WROT, 2, MT8195_MDP_COMP_WROT2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_WROT3] = { + {MDP_COMP_TYPE_WROT, 3, MT8195_MDP_COMP_WROT3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_MERGE2] = { + {MDP_COMP_TYPE_MERGE, 0, MT8195_MDP_COMP_MERGE2, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_MERGE3] = { + {MDP_COMP_TYPE_MERGE, 1, MT8195_MDP_COMP_MERGE3, MDP_MM_SUBSYS_1}, + {1, 0, 0} + }, + [MDP_COMP_PQ0_SOUT] = { + {MDP_COMP_TYPE_DUMMY, 0, MT8195_MDP_COMP_PQ0_SOUT, MDP_MM_SUBSYS_0}, + {0, 0, 0} + }, + [MDP_COMP_PQ1_SOUT] = { + {MDP_COMP_TYPE_DUMMY, 1, MT8195_MDP_COMP_PQ1_SOUT, MDP_MM_SUBSYS_1}, + {0, 0, 0} + }, + [MDP_COMP_TO_WARP0MOUT] = { + {MDP_COMP_TYPE_DUMMY, 2, MT8195_MDP_COMP_TO_WARP0MOUT, MDP_MM_SUBSYS_0}, + {0, 0, 0} + }, + [MDP_COMP_TO_WARP1MOUT] = { + {MDP_COMP_TYPE_DUMMY, 3, MT8195_MDP_COMP_TO_WARP1MOUT, MDP_MM_SUBSYS_0}, + {0, 0, 0} + }, + [MDP_COMP_TO_SVPP2MOUT] = { + {MDP_COMP_TYPE_DUMMY, 4, MT8195_MDP_COMP_TO_SVPP2MOUT, MDP_MM_SUBSYS_1}, + {0, 0, 0} + }, + [MDP_COMP_TO_SVPP3MOUT] = { + {MDP_COMP_TYPE_DUMMY, 5, MT8195_MDP_COMP_TO_SVPP3MOUT, MDP_MM_SUBSYS_1}, + {0, 0, 0} + }, + [MDP_COMP_VPP0_SOUT] = { + {MDP_COMP_TYPE_PATH, 0, MT8195_MDP_COMP_VPP0_SOUT, MDP_MM_SUBSYS_1}, + {4, 9, 0} + }, + [MDP_COMP_VPP1_SOUT] = { + {MDP_COMP_TYPE_PATH, 1, MT8195_MDP_COMP_VPP1_SOUT, MDP_MM_SUBSYS_0}, + {2, 13, 0} + }, + [MDP_COMP_VDO0DL0] = { + {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO0DL0, MDP_MM_SUBSYS_1}, + {1, 15, 0} + }, + [MDP_COMP_VDO1DL0] = { + {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO1DL0, MDP_MM_SUBSYS_1}, + {1, 17, 0} + }, + [MDP_COMP_VDO0DL1] = { + {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO0DL1, MDP_MM_SUBSYS_1}, + {1, 18, 0} + }, + [MDP_COMP_VDO1DL1] = { + {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO1DL1, MDP_MM_SUBSYS_1}, + {1, 16, 0} + }, +}; + static const struct of_device_id mt8183_sub_comp_dt_ids[] = { { .compatible = "mediatek,mt8183-mdp3-wdma", @@ -159,6 +556,10 @@ static const struct of_device_id mt8183_sub_comp_dt_ids[] = { {} }; +static const struct of_device_id mt8195_sub_comp_dt_ids[] = { + {} +}; + /* * All 10-bit related formats are not added in the basic format list, * please add the corresponding format settings before use. @@ -384,6 +785,222 @@ static const struct mdp_format mt8183_formats[] = { } }; +static const struct mdp_format mt8195_formats[] = { + { + .pixelformat = V4L2_PIX_FMT_GREY, + .mdp_color = MDP_COLOR_GREY, + .depth = { 8 }, + .row_depth = { 8 }, + .num_planes = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_RGB565X, + .mdp_color = MDP_COLOR_BGR565, + .depth = { 16 }, + .row_depth = { 16 }, + .num_planes = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_RGB565, + .mdp_color = MDP_COLOR_RGB565, + .depth = { 16 }, + .row_depth = { 16 }, + .num_planes = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_RGB24, + .mdp_color = MDP_COLOR_RGB888, + .depth = { 24 }, + .row_depth = { 24 }, + .num_planes = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_BGR24, + .mdp_color = MDP_COLOR_BGR888, + .depth = { 24 }, + .row_depth = { 24 }, + .num_planes = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_ABGR32, + .mdp_color = MDP_COLOR_BGRA8888, + .depth = { 32 }, + .row_depth = { 32 }, + .num_planes = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_ARGB32, + .mdp_color = MDP_COLOR_ARGB8888, + .depth = { 32 }, + .row_depth = { 32 }, + .num_planes = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_UYVY, + .mdp_color = MDP_COLOR_UYVY, + .depth = { 16 }, + .row_depth = { 16 }, + .num_planes = 1, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_VYUY, + .mdp_color = MDP_COLOR_VYUY, + .depth = { 16 }, + .row_depth = { 16 }, + .num_planes = 1, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YUYV, + .mdp_color = MDP_COLOR_YUYV, + .depth = { 16 }, + .row_depth = { 16 }, + .num_planes = 1, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YVYU, + .mdp_color = MDP_COLOR_YVYU, + .depth = { 16 }, + .row_depth = { 16 }, + .num_planes = 1, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YUV420, + .mdp_color = MDP_COLOR_I420, + .depth = { 12 }, + .row_depth = { 8 }, + .num_planes = 1, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YVU420, + .mdp_color = MDP_COLOR_YV12, + .depth = { 12 }, + .row_depth = { 8 }, + .num_planes = 1, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_NV12, + .mdp_color = MDP_COLOR_NV12, + .depth = { 12 }, + .row_depth = { 8 }, + .num_planes = 1, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_NV21, + .mdp_color = MDP_COLOR_NV21, + .depth = { 12 }, + .row_depth = { 8 }, + .num_planes = 1, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_NV16, + .mdp_color = MDP_COLOR_NV16, + .depth = { 16 }, + .row_depth = { 8 }, + .num_planes = 1, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_NV61, + .mdp_color = MDP_COLOR_NV61, + .depth = { 16 }, + .row_depth = { 8 }, + .num_planes = 1, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_NV12M, + .mdp_color = MDP_COLOR_NV12, + .depth = { 8, 4 }, + .row_depth = { 8, 8 }, + .num_planes = 2, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_MM21, + .mdp_color = MDP_COLOR_420_BLK, + .depth = { 8, 4 }, + .row_depth = { 8, 8 }, + .num_planes = 2, + .walign = 6, + .halign = 6, + .flags = MDP_FMT_FLAG_OUTPUT, + }, { + .pixelformat = V4L2_PIX_FMT_NV21M, + .mdp_color = MDP_COLOR_NV21, + .depth = { 8, 4 }, + .row_depth = { 8, 8 }, + .num_planes = 2, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_NV16M, + .mdp_color = MDP_COLOR_NV16, + .depth = { 8, 8 }, + .row_depth = { 8, 8 }, + .num_planes = 2, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_NV61M, + .mdp_color = MDP_COLOR_NV61, + .depth = { 8, 8 }, + .row_depth = { 8, 8 }, + .num_planes = 2, + .walign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YUV420M, + .mdp_color = MDP_COLOR_I420, + .depth = { 8, 2, 2 }, + .row_depth = { 8, 4, 4 }, + .num_planes = 3, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YVU420M, + .mdp_color = MDP_COLOR_YV12, + .depth = { 8, 2, 2 }, + .row_depth = { 8, 4, 4 }, + .num_planes = 3, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YUV422M, + .mdp_color = MDP_COLOR_I422, + .depth = { 8, 4, 4 }, + .row_depth = { 8, 4, 4 }, + .num_planes = 3, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + }, { + .pixelformat = V4L2_PIX_FMT_YVU422M, + .mdp_color = MDP_COLOR_YV16, + .depth = { 8, 4, 4 }, + .row_depth = { 8, 4, 4 }, + .num_planes = 3, + .walign = 1, + .halign = 1, + .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE, + } +}; + static const struct mdp_limit mt8183_mdp_def_limit = { .out_limit = { .wmin = 16, @@ -403,6 +1020,25 @@ static const struct mdp_limit mt8183_mdp_def_limit = { .v_scale_down_max = 128, }; +static const struct mdp_limit mt8195_mdp_def_limit = { + .out_limit = { + .wmin = 64, + .hmin = 64, + .wmax = 8192, + .hmax = 8192, + }, + .cap_limit = { + .wmin = 64, + .hmin = 64, + .wmax = 8192, + .hmax = 8192, + }, + .h_scale_up_max = 64, + .v_scale_up_max = 64, + .h_scale_down_max = 128, + .v_scale_down_max = 128, +}; + static const struct mdp_pipe_info mt8183_pipe_info[] = { [MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, MDP_MM_SUBSYS_0, 0}, [MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, MDP_MM_SUBSYS_0, 1}, @@ -410,6 +1046,20 @@ static const struct mdp_pipe_info mt8183_pipe_info[] = { [MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, MDP_MM_SUBSYS_0, 3} }; +static const struct mdp_pipe_info mt8195_pipe_info[] = { + [MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, MDP_MM_SUBSYS_0, 0}, + [MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, MDP_MM_SUBSYS_0, 1}, + [MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, MDP_MM_SUBSYS_0, 2}, + [MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, MDP_MM_SUBSYS_0, 3}, + [MDP_PIPE_RDMA1] = {MDP_PIPE_RDMA1, MDP_MM_SUBSYS_1, 0}, + [MDP_PIPE_RDMA2] = {MDP_PIPE_RDMA2, MDP_MM_SUBSYS_1, 1}, + [MDP_PIPE_RDMA3] = {MDP_PIPE_RDMA3, MDP_MM_SUBSYS_1, 2}, + [MDP_PIPE_SPLIT] = {MDP_PIPE_SPLIT, MDP_MM_SUBSYS_1, 3}, + [MDP_PIPE_SPLIT2] = {MDP_PIPE_SPLIT2, MDP_MM_SUBSYS_1, 4}, + [MDP_PIPE_VPP1_SOUT] = {MDP_PIPE_VPP1_SOUT, MDP_MM_SUBSYS_0, 4}, + [MDP_PIPE_VPP0_SOUT] = {MDP_PIPE_VPP0_SOUT, MDP_MM_SUBSYS_1, 5}, +}; + const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { .mdp_plat_id = MT8183, .mdp_con_res = 0x14001000, @@ -426,6 +1076,22 @@ const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { .pipe_info_len = ARRAY_SIZE(mt8183_pipe_info), }; +const struct mtk_mdp_driver_data mt8195_mdp_driver_data = { + .mdp_plat_id = MT8195, + .mdp_con_res = 0x14001000, + .mdp_probe_infra = mt8195_mdp_probe_infra, + .mdp_sub_comp_dt_ids = mt8195_sub_comp_dt_ids, + .mdp_cfg = &mt8195_plat_cfg, + .mdp_mutex_table_idx = mt8195_mutex_idx, + .comp_data = mt8195_mdp_comp_data, + .comp_data_len = ARRAY_SIZE(mt8195_mdp_comp_data), + .format = mt8195_formats, + .format_len = ARRAY_SIZE(mt8195_formats), + .def_limit = &mt8195_mdp_def_limit, + .pipe_info = mt8195_pipe_info, + .pipe_info_len = ARRAY_SIZE(mt8195_pipe_info), +}; + s32 mdp_cfg_get_id_inner(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id) { if (!mdp_dev) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h index 22b8b9a10ef7..08fb0853bcd5 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h @@ -115,6 +115,7 @@ struct img_frameparam { /* Platform config indicator */ #define MT8183 8183 +#define MT8195 8195 #define CFG_CHECK(plat, p_id) ((plat) == (p_id)) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h index dfffc72868e4..49cdf45f6e59 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h @@ -10,6 +10,7 @@ #include extern const struct mtk_mdp_driver_data mt8183_mdp_driver_data; +extern const struct mtk_mdp_driver_data mt8195_mdp_driver_data; struct mdp_dev; enum mtk_mdp_comp_id; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index e97630b7867c..600fec7d2f7f 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -773,6 +773,42 @@ static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = { }, { .compatible = "mediatek,mt8183-mdp3-wdma", .data = (void *)MDP_COMP_TYPE_WDMA, + }, { + .compatible = "mediatek,mt8195-mdp3-rdma", + .data = (void *)MDP_COMP_TYPE_RDMA, + }, { + .compatible = "mediatek,mt8195-mdp3-split", + .data = (void *)MDP_COMP_TYPE_SPLIT, + }, { + .compatible = "mediatek,mt8195-mdp3-stitch", + .data = (void *)MDP_COMP_TYPE_STITCH, + }, { + .compatible = "mediatek,mt8195-mdp3-fg", + .data = (void *)MDP_COMP_TYPE_FG, + }, { + .compatible = "mediatek,mt8195-mdp3-hdr", + .data = (void *)MDP_COMP_TYPE_HDR, + }, { + .compatible = "mediatek,mt8195-mdp3-aal", + .data = (void *)MDP_COMP_TYPE_AAL, + }, { + .compatible = "mediatek,mt8195-mdp3-merge", + .data = (void *)MDP_COMP_TYPE_MERGE, + }, { + .compatible = "mediatek,mt8195-mdp3-tdshp", + .data = (void *)MDP_COMP_TYPE_TDSHP, + }, { + .compatible = "mediatek,mt8195-mdp3-color", + .data = (void *)MDP_COMP_TYPE_COLOR, + }, { + .compatible = "mediatek,mt8195-mdp3-ovl", + .data = (void *)MDP_COMP_TYPE_OVL, + }, { + .compatible = "mediatek,mt8195-mdp3-padding", + .data = (void *)MDP_COMP_TYPE_PAD, + }, { + .compatible = "mediatek,mt8195-mdp3-tcc", + .data = (void *)MDP_COMP_TYPE_TCC, }, {} }; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index 6ddb5e075f5d..a6c71fd9e5bf 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -21,6 +21,12 @@ static const struct of_device_id mdp_of_ids[] = { { .compatible = "mediatek,mt8183-mdp3-rdma", .data = &mt8183_mdp_driver_data, }, + { .compatible = "mediatek,mt8195-mdp3-rdma", + .data = &mt8195_mdp_driver_data, + }, + { .compatible = "mediatek,mt8195-mdp3-wrot", + .data = &mt8195_mdp_driver_data, + }, {}, }; MODULE_DEVICE_TABLE(of, mdp_of_ids); diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index e57c415a1c78..d6484d17b09f 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -49,10 +49,16 @@ struct mdp_platform_config { bool rdma_support_10bit; bool rdma_rsz1_sram_sharing; bool rdma_upsample_repeat_only; + bool rdma_esl_setting; u32 rdma_event_num; bool rsz_disable_dcm_small_sample; + bool rsz_etc_control; bool wrot_filter_constraint; + bool wrot_support_10bit; u32 wrot_event_num; + u32 tdshp_hist_num; + bool tdshp_constrain; + bool tdshp_contour; }; /* indicate which mutex is used by each pipepline */ From 51d918d62b0facd7be0d8d1ad66a8c6c589f34b3 Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:36 +0100 Subject: [PATCH 083/252] media: platform: mtk-mdp3: add mt8195 shared memory configurations The configuration of the MT8195 components in the shared memory is defined in the header file "mdp_sm_mt8195.h". Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mdp_sm_mt8195.h | 283 ++++++++++++++++++ .../platform/mediatek/mdp3/mtk-img-ipi.h | 3 + 2 files changed, 286 insertions(+) create mode 100644 drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h diff --git a/drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h b/drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h new file mode 100644 index 000000000000..b09f48222d24 --- /dev/null +++ b/drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h @@ -0,0 +1,283 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023 MediaTek Inc. + * Author: Ping-Hsun Wu + */ + +#ifndef __MDP_SM_MT8195_H__ +#define __MDP_SM_MT8195_H__ + +#include "mtk-mdp3-type.h" + +/* + * ISP-MDP generic output information + * MD5 of the target SCP prebuild: + * a49ec487e458b5971880f1b63dc2a9d5 + */ + +#define IMG_MAX_SUBFRAMES_8195 20 + +struct img_comp_frame_8195 { + u32 output_disable; + u32 bypass; + u32 in_width; + u32 in_height; + u32 out_width; + u32 out_height; + struct img_crop crop; + u32 in_total_width; + u32 out_total_width; +} __packed; + +struct img_comp_subfrm_8195 { + u32 tile_disable; + struct img_region in; + struct img_region out; + struct img_offset luma; + struct img_offset chroma; + s32 out_vertical; /* Output vertical index */ + s32 out_horizontal; /* Output horizontal index */ +} __packed; + +struct mdp_rdma_subfrm_8195 { + u32 offset[IMG_MAX_PLANES]; + u32 offset_0_p; + u32 src; + u32 clip; + u32 clip_ofst; + u32 in_tile_xleft; + u32 in_tile_ytop; +} __packed; + +struct mdp_rdma_data_8195 { + u32 src_ctrl; + u32 comp_ctrl; + u32 control; + u32 iova[IMG_MAX_PLANES]; + u32 iova_end[IMG_MAX_PLANES]; + u32 mf_bkgd; + u32 mf_bkgd_in_pxl; + u32 sf_bkgd; + u32 ufo_dec_y; + u32 ufo_dec_c; + u32 transform; + u32 dmabuf_con0; + u32 ultra_th_high_con0; + u32 ultra_th_low_con0; + u32 dmabuf_con1; + u32 ultra_th_high_con1; + u32 ultra_th_low_con1; + u32 dmabuf_con2; + u32 ultra_th_high_con2; + u32 ultra_th_low_con2; + u32 dmabuf_con3; + struct mdp_rdma_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_fg_subfrm_8195 { + u32 info_0; + u32 info_1; +} __packed; + +struct mdp_fg_data_8195 { + u32 ctrl_0; + u32 ck_en; + struct mdp_fg_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_hdr_subfrm_8195 { + u32 win_size; + u32 src; + u32 clip_ofst0; + u32 clip_ofst1; + u32 hist_ctrl_0; + u32 hist_ctrl_1; + u32 hdr_top; + u32 hist_addr; +} __packed; + +struct mdp_hdr_data_8195 { + u32 top; + u32 relay; + struct mdp_hdr_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_aal_subfrm_8195 { + u32 src; + u32 clip; + u32 clip_ofst; +} __packed; + +struct mdp_aal_data_8195 { + u32 cfg_main; + u32 cfg; + struct mdp_aal_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_rsz_subfrm_8195 { + u32 control2; + u32 src; + u32 clip; + u32 hdmirx_en; + u32 luma_h_int_ofst; + u32 luma_h_sub_ofst; + u32 luma_v_int_ofst; + u32 luma_v_sub_ofst; + u32 chroma_h_int_ofst; + u32 chroma_h_sub_ofst; + u32 rsz_switch; + u32 merge_cfg; +} __packed; + +struct mdp_rsz_data_8195 { + u32 coeff_step_x; + u32 coeff_step_y; + u32 control1; + u32 control2; + u32 etc_control; + u32 prz_enable; + u32 ibse_softclip; + u32 tap_adapt; + u32 ibse_gaincontrol1; + u32 ibse_gaincontrol2; + u32 ibse_ylevel_1; + u32 ibse_ylevel_2; + u32 ibse_ylevel_3; + u32 ibse_ylevel_4; + u32 ibse_ylevel_5; + struct mdp_rsz_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_tdshp_subfrm_8195 { + u32 src; + u32 clip; + u32 clip_ofst; + u32 hist_cfg_0; + u32 hist_cfg_1; +} __packed; + +struct mdp_tdshp_data_8195 { + u32 cfg; + struct mdp_tdshp_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_color_subfrm_8195 { + u32 in_hsize; + u32 in_vsize; +} __packed; + +struct mdp_color_data_8195 { + u32 start; + struct mdp_color_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_ovl_subfrm_8195 { + u32 L0_src_size; + u32 roi_size; +} __packed; + +struct mdp_ovl_data_8195 { + u32 L0_con; + u32 src_con; + struct mdp_ovl_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_pad_subfrm_8195 { + u32 pic_size; +} __packed; + +struct mdp_pad_data_8195 { + struct mdp_pad_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_tcc_subfrm_8195 { + u32 pic_size; +} __packed; + +struct mdp_tcc_data_8195 { + struct mdp_tcc_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_wrot_subfrm_8195 { + u32 offset[IMG_MAX_PLANES]; + u32 src; + u32 clip; + u32 clip_ofst; + u32 main_buf; +} __packed; + +struct mdp_wrot_data_8195 { + u32 iova[IMG_MAX_PLANES]; + u32 control; + u32 stride[IMG_MAX_PLANES]; + u32 mat_ctrl; + u32 fifo_test; + u32 filter; + u32 pre_ultra; + u32 framesize; + u32 afbc_yuvtrans; + u32 scan_10bit; + u32 pending_zero; + u32 bit_number; + u32 pvric; + u32 vpp02vpp1; + struct mdp_wrot_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct mdp_wdma_subfrm_8195 { + u32 offset[IMG_MAX_PLANES]; + u32 src; + u32 clip; + u32 clip_ofst; +} __packed; + +struct mdp_wdma_data_8195 { + u32 wdma_cfg; + u32 iova[IMG_MAX_PLANES]; + u32 w_in_byte; + u32 uv_stride; + struct mdp_wdma_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct isp_data_8195 { + u64 dl_flags; /* 1 << (enum mdp_comp_type) */ + u32 smxi_iova[4]; + u32 cq_idx; + u32 cq_iova; + u32 tpipe_iova[IMG_MAX_SUBFRAMES_8195]; +} __packed; + +struct img_compparam_8195 { + u32 type; /* enum mdp_comp_id */ + u32 id; /* engine alias_id */ + u32 input; + u32 outputs[IMG_MAX_HW_OUTPUTS]; + u32 num_outputs; + struct img_comp_frame_8195 frame; + struct img_comp_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195]; + u32 num_subfrms; + union { + struct mdp_rdma_data_8195 rdma; + struct mdp_fg_data_8195 fg; + struct mdp_hdr_data_8195 hdr; + struct mdp_aal_data_8195 aal; + struct mdp_rsz_data_8195 rsz; + struct mdp_tdshp_data_8195 tdshp; + struct mdp_color_data_8195 color; + struct mdp_ovl_data_8195 ovl; + struct mdp_pad_data_8195 pad; + struct mdp_tcc_data_8195 tcc; + struct mdp_wrot_data_8195 wrot; + struct mdp_wdma_data_8195 wdma; + struct isp_data_8195 isp; + }; +} __packed; + +struct img_config_8195 { + struct img_compparam_8195 components[IMG_MAX_COMPONENTS]; + u32 num_components; + struct img_mmsys_ctrl ctrls[IMG_MAX_SUBFRAMES_8195]; + u32 num_subfrms; +} __packed; + +#endif /* __MDP_SM_MT8195_H__ */ diff --git a/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h index 08fb0853bcd5..f83ac408306e 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h @@ -10,6 +10,7 @@ #include #include "mdp_sm_mt8183.h" +#include "mdp_sm_mt8195.h" #include "mtk-mdp3-type.h" /* ISP-MDP generic input information */ @@ -138,12 +139,14 @@ struct img_frameparam { struct img_config { union { struct img_config_8183 config_8183; + struct img_config_8195 config_8195; }; } __packed; struct img_compparam { union { struct img_compparam_8183 comp_8183; + struct img_compparam_8195 comp_8195; }; } __packed; From 0e9bd2fcda5dfc0d703c659d4b7ba2cf07dfdb9f Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:37 +0100 Subject: [PATCH 084/252] media: platform: mtk-mdp3: add mt8195 MDP3 component settings Extend the component settings used in MT8195 MDP3. Additionally, it is crucial to read all component settings in a specific manner to ensure that shared memory data structure lengths are aligned across different platforms. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 57 ++ .../platform/mediatek/mdp3/mtk-mdp3-comp.c | 798 +++++++++++++++++- 2 files changed, 851 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index f0c5f5abeb23..8114c288da9c 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -40,6 +40,10 @@ static bool is_output_disabled(int p_id, const struct img_compparam *param, u32 num = CFG_COMP(MT8183, param, num_subfrms); dis_output = CFG_COMP(MT8183, param, frame.output_disable); dis_tile = CFG_COMP(MT8183, param, frame.output_disable); + } else if (CFG_CHECK(MT8195, p_id)) { + num = CFG_COMP(MT8195, param, num_subfrms); + dis_output = CFG_COMP(MT8195, param, frame.output_disable); + dis_tile = CFG_COMP(MT8195, param, frame.output_disable); } return (count < num) ? (dis_output || dis_tile) : true; @@ -101,6 +105,8 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); /* Decide which mutex to use based on the current pipeline */ index = __get_pipe(path->mdp_dev, path->comps[0].comp->public_id); @@ -115,6 +121,9 @@ static int mdp_path_subfrm_require(const struct mdp_path *path, if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; @@ -156,12 +165,17 @@ static int mdp_path_subfrm_run(const struct mdp_path *path, if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); /* Wait WROT SRAM shared to DISP RDMA */ /* Clear SOF event for each engine */ for (index = 0; index < num_comp; index++) { if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; ctx = &path->comps[index]; @@ -180,6 +194,9 @@ static int mdp_path_subfrm_run(const struct mdp_path *path, for (index = 0; index < num_comp; index++) { if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; ctx = &path->comps[index]; @@ -202,6 +219,8 @@ static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path) if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); if (num_comp < 1) return -EINVAL; @@ -211,10 +230,15 @@ static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path) if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; if (CFG_CHECK(MT8183, p_id)) param = (void *)CFG_ADDR(MT8183, path->config, components[index]); + else if (CFG_CHECK(MT8195, p_id)) + param = (void *)CFG_ADDR(MT8195, path->config, components[index]); ret = mdp_comp_ctx_config(mdp, &path->comps[index], param, path->param); if (ret) @@ -238,9 +262,13 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); if (CFG_CHECK(MT8183, p_id)) ctrl = CFG_ADDR(MT8183, path->config, ctrls[count]); + else if (CFG_CHECK(MT8195, p_id)) + ctrl = CFG_ADDR(MT8195, path->config, ctrls[count]); /* Acquire components */ ret = mdp_path_subfrm_require(path, cmd, &pipe, count); @@ -256,6 +284,9 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, for (index = (num_comp - 1); index >= 0; index--) { if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; ctx = &path->comps[index]; @@ -273,6 +304,9 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, for (index = 0; index < num_comp; index++) { if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; ctx = &path->comps[index]; @@ -286,6 +320,9 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd, for (index = 0; index < num_comp; index++) { if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; ctx = &path->comps[index]; @@ -315,15 +352,22 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, if (CFG_CHECK(MT8183, p_id)) num_comp = CFG_GET(MT8183, path->config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, path->config, num_components); if (CFG_CHECK(MT8183, p_id)) num_sub = CFG_GET(MT8183, path->config, num_subfrms); + else if (CFG_CHECK(MT8195, p_id)) + num_sub = CFG_GET(MT8195, path->config, num_subfrms); /* Config path frame */ /* Reset components */ for (index = 0; index < num_comp; index++) { if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; ctx = &path->comps[index]; @@ -339,11 +383,16 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, ctx = &path->comps[index]; if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; if (CFG_CHECK(MT8183, p_id)) out = CFG_COMP(MT8183, ctx->param, outputs[0]); + else if (CFG_CHECK(MT8195, p_id)) + out = CFG_COMP(MT8195, ctx->param, outputs[0]); compose = path->composes[out]; ret = call_op(ctx, config_frame, cmd, compose); @@ -361,6 +410,9 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd, for (index = 0; index < num_comp; index++) { if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[index].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[index].type); + if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id)) continue; ctx = &path->comps[index]; @@ -515,6 +567,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) if (CFG_CHECK(MT8183, p_id)) { num_comp = CFG_GET(MT8183, param->config, num_components); + } else if (CFG_CHECK(MT8195, p_id)) { + num_comp = CFG_GET(MT8195, param->config, num_components); } else { ret = -EINVAL; goto err_destroy_pkt; @@ -570,6 +624,9 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) if (CFG_CHECK(MT8183, p_id)) inner_id = CFG_GET(MT8183, path->config, components[i].type); + else if (CFG_CHECK(MT8195, p_id)) + inner_id = CFG_GET(MT8195, path->config, components[i].type); + if (mdp_cfg_comp_is_dummy(mdp, inner_id)) continue; memcpy(&comps[i], path->comps[i].comp, diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c index 600fec7d2f7f..8f62fb167156 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -13,11 +13,19 @@ #include "mtk-mdp3-core.h" #include "mtk-mdp3-regs.h" -#include "mdp_reg_rdma.h" +#include "mdp_reg_aal.h" #include "mdp_reg_ccorr.h" +#include "mdp_reg_color.h" +#include "mdp_reg_fg.h" +#include "mdp_reg_hdr.h" +#include "mdp_reg_merge.h" +#include "mdp_reg_ovl.h" +#include "mdp_reg_pad.h" +#include "mdp_reg_rdma.h" #include "mdp_reg_rsz.h" -#include "mdp_reg_wrot.h" +#include "mdp_reg_tdshp.h" #include "mdp_reg_wdma.h" +#include "mdp_reg_wrot.h" static u32 mdp_comp_alias_id[MDP_COMP_TYPE_COUNT]; static int p_id; @@ -85,6 +93,7 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx, bool en_ufo = MDP_COLOR_IS_UFP(colorformat); phys_addr_t base = ctx->comp->reg_base; u8 subsys_id = ctx->comp->subsys_id; + u32 rdma_con_mask = 0; u32 reg = 0; if (mdp_cfg && mdp_cfg->rdma_support_10bit) { @@ -105,6 +114,8 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx, /* Setup source frame info */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.src_ctrl); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.src_ctrl); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg, 0x03C8FE0F); @@ -113,69 +124,163 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx, /* Setup source buffer base */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_y); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_y); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_c); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_c); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C, reg, 0xFFFFFFFF); + /* Set 10bit source frame pitch */ if (block10bit) { if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd_in_pxl); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd_in_pxl); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL, reg, 0x001FFFFF); } } - if (CFG_CHECK(MT8183, p_id)) + if (CFG_CHECK(MT8183, p_id)) { reg = CFG_COMP(MT8183, ctx->param, rdma.control); + rdma_con_mask = 0x1110; + } else if (CFG_CHECK(MT8195, p_id)) { + reg = CFG_COMP(MT8195, ctx->param, rdma.control); + rdma_con_mask = 0x1130; + } MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, reg, - 0x1110); + rdma_con_mask); + /* Setup source buffer base */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova[0]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.iova[0]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova[1]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.iova[1]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova[2]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.iova[2]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg, 0xFFFFFFFF); + /* Setup source buffer end */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[0]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[0]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[1]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[1]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[2]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[2]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2, reg, 0xFFFFFFFF); + /* Setup source frame pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, reg, 0x001FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.sf_bkgd); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.sf_bkgd); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE, reg, 0x001FFFFF); + /* Setup color transform */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.transform); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.transform); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0, reg, 0x0F110000); + if (!mdp_cfg || !mdp_cfg->rdma_esl_setting) + goto rdma_config_done; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_0, + reg, 0x0FFF00FF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_0, + reg, 0x3FFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_0, + reg, 0x3FFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con1); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_1, + reg, 0x0F7F007F); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con1); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_1, + reg, 0x3FFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con1); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_1, + reg, 0x3FFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con2); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_2, + reg, 0x0F3F003F); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con2); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_2, + reg, 0x3FFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con2); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_2, + reg, 0x3FFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con3); + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_3, + reg, 0x0F3F003F); + +rdma_config_done: return 0; } @@ -197,6 +302,8 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx, /* Set Y pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[0]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[0]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0, reg, 0xFFFFFFFF); @@ -205,6 +312,8 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx, if (mdp_cfg->rdma_support_10bit && block10bit && en_ufo) { if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset_0_p); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset_0_p); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0_P, reg, 0xFFFFFFFF); @@ -214,32 +323,49 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx, /* Set U pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[1]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[1]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1, reg, 0xFFFFFFFF); + /* Set V pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[2]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[2]); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2, reg, 0xFFFFFFFF); + /* Set source size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].src); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].src); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg, 0x1FFF1FFF); + /* Set target size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE, reg, 0x1FFF1FFF); + /* Set crop offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip_ofst); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip_ofst); MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1, reg, 0x003F001F); if (CFG_CHECK(MT8183, p_id)) { csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right); + } else if (CFG_CHECK(MT8195, p_id)) { + csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left); + csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right); } if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only) if ((csf_r - csf_l + 1) > 320) @@ -289,6 +415,14 @@ static int init_rsz(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16)); /* Enable RSZ */ MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0)); + + if (CFG_CHECK(MT8195, p_id)) { + struct device *dev; + + dev = ctx->comp->mdp_dev->mm_subsys[MDP_MM_SUBSYS_1].mmsys; + mtk_mmsys_vpp_rsz_dcm_config(dev, true, NULL); + } + return 0; } @@ -296,13 +430,19 @@ static int config_rsz_frame(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd, const struct v4l2_rect *compose) { + const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx); phys_addr_t base = ctx->comp->reg_base; u8 subsys_id = ctx->comp->subsys_id; bool bypass = FALSE; u32 reg = 0; + if (mdp_cfg && mdp_cfg->rsz_etc_control) + MM_REG_WRITE(cmd, subsys_id, base, RSZ_ETC_CONTROL, 0x0, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) bypass = CFG_COMP(MT8183, ctx->param, frame.bypass); + else if (CFG_CHECK(MT8195, p_id)) + bypass = CFG_COMP(MT8195, ctx->param, frame.bypass); if (bypass) { /* Disable RSZ */ @@ -312,20 +452,32 @@ static int config_rsz_frame(struct mdp_comp_ctx *ctx, if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.control1); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.control1); MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, reg, 0x03FFFDF3); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.control2); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.control2); MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 0x0FFFC290); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_x); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_x); MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP, reg, 0x007FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_y); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_y); MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP, reg, 0x007FFFFF); + return 0; } @@ -337,19 +489,28 @@ static int config_rsz_subfrm(struct mdp_comp_ctx *ctx, u8 subsys_id = ctx->comp->subsys_id; u32 csf_l = 0, csf_r = 0; u32 reg = 0; + u32 id; if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].control2); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].control2); MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 0x00003800); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].src); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].src); MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg, 0xFFFFFFFF); if (CFG_CHECK(MT8183, p_id)) { csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right); + } else if (CFG_CHECK(MT8195, p_id)) { + csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left); + csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right); } if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample) if ((csf_r - csf_l + 1) <= 16) @@ -358,37 +519,99 @@ static int config_rsz_subfrm(struct mdp_comp_ctx *ctx, if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left); MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET, reg, 0xFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left_subpix); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left_subpix); MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET, reg, 0x1FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top); MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET, reg, 0xFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top_subpix); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top_subpix); MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET, reg, 0x1FFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left); MM_REG_WRITE(cmd, subsys_id, base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET, reg, 0xFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left_subpix); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left_subpix); MM_REG_WRITE(cmd, subsys_id, base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET, reg, 0x1FFFFF); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].clip); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].clip); MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8195, p_id)) { + struct device *dev; + struct mdp_comp *merge; + const struct mtk_mdp_driver_data *data = ctx->comp->mdp_dev->mdp_data; + enum mtk_mdp_comp_id public_id = ctx->comp->public_id; + + switch (public_id) { + case MDP_COMP_RSZ2: + merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE2]; + break; + case MDP_COMP_RSZ3: + merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE3]; + break; + default: + goto rsz_subfrm_done; + } + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].rsz_switch); + + id = data->comp_data[public_id].match.alias_id; + dev = ctx->comp->mdp_dev->mm_subsys[MDP_MM_SUBSYS_1].mmsys; + mtk_mmsys_vpp_rsz_merge_config(dev, id, reg, NULL); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].merge_cfg); + MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, + MDP_MERGE_CFG_0, reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, + MDP_MERGE_CFG_4, reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, + MDP_MERGE_CFG_24, reg, 0xFFFFFFFF); + MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, + MDP_MERGE_CFG_25, reg, 0xFFFFFFFF); + + /* Bypass mode */ + MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, + MDP_MERGE_CFG_12, BIT(0), 0xFFFFFFFF); + MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, + MDP_MERGE_ENABLE, BIT(0), 0xFFFFFFFF); + } + +rsz_subfrm_done: return 0; } @@ -405,6 +628,9 @@ static int advance_rsz_subfrm(struct mdp_comp_ctx *ctx, if (CFG_CHECK(MT8183, p_id)) { csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right); + } else if (CFG_CHECK(MT8195, p_id)) { + csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left); + csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right); } if ((csf_r - csf_l + 1) <= 16) @@ -431,6 +657,11 @@ static int init_wrot(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) /* Reset WROT */ MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0)); MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0)); + + /* Reset setting */ + if (CFG_CHECK(MT8195, p_id)) + MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, 0x0, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0)); MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0)); return 0; @@ -448,57 +679,118 @@ static int config_wrot_frame(struct mdp_comp_ctx *ctx, /* Write frame base address */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.iova[0]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.iova[0]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.iova[1]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.iova[1]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg, 0xFFFFFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.iova[2]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.iova[2]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg, 0xFFFFFFFF); + + if (mdp_cfg && mdp_cfg->wrot_support_10bit) { + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.scan_10bit); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_SCAN_10BIT, + reg, 0x0000000F); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.pending_zero); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_PENDING_ZERO, + reg, 0x04000000); + } + + if (CFG_CHECK(MT8195, p_id)) { + reg = CFG_COMP(MT8195, ctx->param, wrot.bit_number); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL_2, + reg, 0x00000007); + } + /* Write frame related registers */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.control); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.control); MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, reg, 0xF131510F); + + /* Write pre-ultra threshold */ + if (CFG_CHECK(MT8195, p_id)) { + reg = CFG_COMP(MT8195, ctx->param, wrot.pre_ultra); + MM_REG_WRITE(cmd, subsys_id, base, VIDO_DMA_PREULTRA, reg, + 0x00FFFFFF); + } + /* Write frame Y pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.stride[0]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.stride[0]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, reg, 0x0000FFFF); + /* Write frame UV pitch */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.stride[1]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.stride[1]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, reg, 0xFFFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.stride[2]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.stride[2]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, reg, 0xFFFF); + /* Write matrix control */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.mat_ctrl); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.mat_ctrl); MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3); /* Set the fixed ALPHA as 0xFF */ MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000, 0xFF000000); + /* Set VIDO_EOL_SEL */ MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31)); + /* Set VIDO_FIFO_TEST */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.fifo_test); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.fifo_test); + if (reg != 0) MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST, reg, 0xFFF); + /* Filter enable */ if (mdp_cfg && mdp_cfg->wrot_filter_constraint) { if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.filter); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.filter); MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, reg, 0x77); + + /* Turn off WROT DMA DCM */ + if (CFG_CHECK(MT8195, p_id)) + MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, + (0x1 << 23) + (0x1 << 20), 0x900000); } return 0; @@ -514,35 +806,54 @@ static int config_wrot_subfrm(struct mdp_comp_ctx *ctx, /* Write Y pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[0]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[0]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR, reg, 0x0FFFFFFF); + /* Write U pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[1]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[1]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C, reg, 0x0FFFFFFF); + /* Write V pixel offset */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[2]); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[2]); MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V, reg, 0x0FFFFFFF); + /* Write source size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].src); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].src); MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, reg, 0x1FFF1FFF); + /* Write target size */ if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip); MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, reg, 0x1FFF1FFF); + if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip_ofst); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip_ofst); MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, reg, 0x1FFF1FFF); if (CFG_CHECK(MT8183, p_id)) reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].main_buf); + else if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].main_buf); MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, reg, 0x1FFF7F00); @@ -708,6 +1019,171 @@ static const struct mdp_comp_ops wdma_ops = { .wait_comp_event = wait_wdma_event, }; +static int reset_luma_hist(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx); + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 hist_num, i; + + if (!mdp_cfg) + return -EINVAL; + + hist_num = mdp_cfg->tdshp_hist_num; + + /* Reset histogram */ + for (i = 0; i <= hist_num; i++) + MM_REG_WRITE_MASK(cmd, subsys_id, base, + (MDP_LUMA_HIST_INIT + (i << 2)), + 0, 0xFFFFFFFF); + + if (mdp_cfg->tdshp_constrain) + MM_REG_WRITE(cmd, subsys_id, base, + MDP_DC_TWO_D_W1_RESULT_INIT, 0, 0xFFFFFFFF); + + if (mdp_cfg->tdshp_contour) + for (i = 0; i < hist_num; i++) + MM_REG_WRITE_MASK(cmd, subsys_id, base, + (MDP_CONTOUR_HIST_INIT + (i << 2)), + 0, 0xFFFFFFFF); + + return 0; +} + +static int init_tdshp(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CTRL, BIT(0), BIT(0)); + /* Enable FIFO */ + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, BIT(1), BIT(1)); + + return reset_luma_hist(ctx, cmd); +} + +static int config_tdshp_frame(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, + const struct v4l2_rect *compose) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, tdshp.cfg); + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, reg, BIT(0)); + + return 0; +} + +static int config_tdshp_subfrm(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, u32 index) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].src); + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_INPUT_SIZE, + reg, MDP_TDSHP_INPUT_SIZE_MASK); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip_ofst); + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_OFFSET, + reg, 0x00FF00FF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip); + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_SIZE, + reg, MDP_TDSHP_OUTPUT_SIZE_MASK); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_00, reg, 0xFFFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_1); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_01, reg, 0xFFFFFFFF); + + return 0; +} + +static const struct mdp_comp_ops tdshp_ops = { + .get_comp_flag = get_comp_flag, + .init_comp = init_tdshp, + .config_frame = config_tdshp_frame, + .config_subfrm = config_tdshp_subfrm, +}; + +static int init_color(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + + MM_REG_WRITE(cmd, subsys_id, base, + MDP_COLOR_START, 0x1, BIT(1) | BIT(0)); + MM_REG_WRITE(cmd, subsys_id, base, + MDP_COLOR_WIN_X_MAIN, 0xFFFF0000, 0xFFFFFFFF); + MM_REG_WRITE(cmd, subsys_id, base, + MDP_COLOR_WIN_Y_MAIN, 0xFFFF0000, 0xFFFFFFFF); + + /* Reset color matrix */ + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM1_EN, 0x0, BIT(0)); + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM2_EN, 0x0, BIT(0)); + + /* Enable interrupt */ + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTEN, 0x7, 0x7); + + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_OUT_SEL, 0x333, 0x333); + + return 0; +} + +static int config_color_frame(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, + const struct v4l2_rect *compose) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, color.start); + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_START, + reg, MDP_COLOR_START_MASK); + + return 0; +} + +static int config_color_subfrm(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, u32 index) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_hsize); + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_WIDTH, + reg, 0x00003FFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_vsize); + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_HEIGHT, + reg, 0x00003FFF); + + return 0; +} + +static const struct mdp_comp_ops color_ops = { + .get_comp_flag = get_comp_flag, + .init_comp = init_color, + .config_frame = config_color_frame, + .config_subfrm = config_color_subfrm, +}; + static int init_ccorr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) { phys_addr_t base = ctx->comp->reg_base; @@ -749,12 +1225,318 @@ static const struct mdp_comp_ops ccorr_ops = { .config_subfrm = config_ccorr_subfrm, }; +static int init_aal(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + + /* Always set MDP_AAL enable to 1 */ + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_EN, BIT(0), BIT(0)); + + return 0; +} + +static int config_aal_frame(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, + const struct v4l2_rect *compose) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, aal.cfg_main); + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG_MAIN, reg, BIT(7)); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, aal.cfg); + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG, reg, BIT(0)); + + return 0; +} + +static int config_aal_subfrm(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, u32 index) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].src); + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_SIZE, + reg, MDP_AAL_SIZE_MASK); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip_ofst); + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_OFFSET, + reg, 0x00FF00FF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip); + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_SIZE, + reg, MDP_AAL_OUTPUT_SIZE_MASK); + + return 0; +} + +static const struct mdp_comp_ops aal_ops = { + .get_comp_flag = get_comp_flag, + .init_comp = init_aal, + .config_frame = config_aal_frame, + .config_subfrm = config_aal_subfrm, +}; + +static int init_hdr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + + /* Always set MDP_HDR enable to 1 */ + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, BIT(0), BIT(0)); + + return 0; +} + +static int config_hdr_frame(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, + const struct v4l2_rect *compose) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.top); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(29) | BIT(28)); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.relay); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_RELAY, reg, BIT(0)); + + return 0; +} + +static int config_hdr_subfrm(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, u32 index) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].win_size); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TILE_POS, + reg, MDP_HDR_TILE_POS_MASK); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].src); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_0, reg, 0x1FFF1FFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_1, reg, 0x1FFF1FFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst1); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_2, reg, 0x1FFF1FFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_0, reg, 0x00003FFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_1); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_1, reg, 0x00003FFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hdr_top); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(6) | BIT(5)); + + /* Enable histogram */ + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_addr); + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_ADDR, reg, BIT(9)); + + return 0; +} + +static const struct mdp_comp_ops hdr_ops = { + .get_comp_flag = get_comp_flag, + .init_comp = init_hdr, + .config_frame = config_hdr_frame, + .config_subfrm = config_hdr_subfrm, +}; + +static int init_fg(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, BIT(2), BIT(2)); + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, 0x0, BIT(2)); + + return 0; +} + +static int config_fg_frame(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, + const struct v4l2_rect *compose) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, fg.ctrl_0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CTRL_0, reg, BIT(0)); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, fg.ck_en); + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CK_EN, reg, 0x7); + + return 0; +} + +static int config_fg_subfrm(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, u32 index) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_0); + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_0, reg, 0xFFFFFFFF); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_1); + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_1, reg, 0xFFFFFFFF); + + return 0; +} + +static const struct mdp_comp_ops fg_ops = { + .get_comp_flag = get_comp_flag, + .init_comp = init_fg, + .config_frame = config_fg_frame, + .config_subfrm = config_fg_subfrm, +}; + +static int init_ovl(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_EN, + BIT(0), MDP_OVL_EN_MASK); + + /* Set to relay mode */ + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON, + BIT(9), MDP_OVL_SRC_CON_MASK); + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_DP_CON, + BIT(0), MDP_OVL_DP_CON_MASK); + + return 0; +} + +static int config_ovl_frame(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, + const struct v4l2_rect *compose) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, ovl.L0_con); + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_CON, reg, BIT(29) | BIT(28)); + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, ovl.src_con); + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON, reg, BIT(0)); + + return 0; +} + +static int config_ovl_subfrm(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, u32 index) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].L0_src_size); + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_SRC_SIZE, + reg, MDP_OVL_L0_SRC_SIZE_MASK); + + /* Setup output size */ + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].roi_size); + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_ROI_SIZE, + reg, MDP_OVL_ROI_SIZE_MASK); + + return 0; +} + +static const struct mdp_comp_ops ovl_ops = { + .get_comp_flag = get_comp_flag, + .init_comp = init_ovl, + .config_frame = config_ovl_frame, + .config_subfrm = config_ovl_subfrm, +}; + +static int init_pad(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_CON, + BIT(1), MDP_PAD_CON_MASK); + /* Reset */ + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_W_SIZE, + 0, MDP_PAD_W_SIZE_MASK); + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_H_SIZE, + 0, MDP_PAD_H_SIZE_MASK); + + return 0; +} + +static int config_pad_subfrm(struct mdp_comp_ctx *ctx, + struct mdp_cmdq_cmd *cmd, u32 index) +{ + phys_addr_t base = ctx->comp->reg_base; + u16 subsys_id = ctx->comp->subsys_id; + u32 reg = 0; + + if (CFG_CHECK(MT8195, p_id)) + reg = CFG_COMP(MT8195, ctx->param, pad.subfrms[index].pic_size); + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_PIC_SIZE, + reg, MDP_PAD_PIC_SIZE_MASK); + + return 0; +} + +static const struct mdp_comp_ops pad_ops = { + .get_comp_flag = get_comp_flag, + .init_comp = init_pad, + .config_subfrm = config_pad_subfrm, +}; + static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = { [MDP_COMP_TYPE_RDMA] = &rdma_ops, [MDP_COMP_TYPE_RSZ] = &rsz_ops, [MDP_COMP_TYPE_WROT] = &wrot_ops, [MDP_COMP_TYPE_WDMA] = &wdma_ops, + [MDP_COMP_TYPE_TDSHP] = &tdshp_ops, + [MDP_COMP_TYPE_COLOR] = &color_ops, [MDP_COMP_TYPE_CCORR] = &ccorr_ops, + [MDP_COMP_TYPE_AAL] = &aal_ops, + [MDP_COMP_TYPE_HDR] = &hdr_ops, + [MDP_COMP_TYPE_FG] = &fg_ops, + [MDP_COMP_TYPE_OVL] = &ovl_ops, + [MDP_COMP_TYPE_PAD] = &pad_ops, }; static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = { @@ -1253,6 +2035,8 @@ int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx, if (CFG_CHECK(MT8183, p_id)) arg = CFG_COMP(MT8183, param, type); + else if (CFG_CHECK(MT8195, p_id)) + arg = CFG_COMP(MT8195, param, type); else return -EINVAL; public_id = mdp_cfg_get_id_public(mdp, arg); @@ -1270,16 +2054,22 @@ int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx, ctx->param = param; if (CFG_CHECK(MT8183, p_id)) arg = CFG_COMP(MT8183, param, input); + else if (CFG_CHECK(MT8195, p_id)) + arg = CFG_COMP(MT8195, param, input); else return -EINVAL; ctx->input = &frame->inputs[arg]; if (CFG_CHECK(MT8183, p_id)) idx = CFG_COMP(MT8183, param, num_outputs); + else if (CFG_CHECK(MT8195, p_id)) + idx = CFG_COMP(MT8195, param, num_outputs); else return -EINVAL; for (i = 0; i < idx; i++) { if (CFG_CHECK(MT8183, p_id)) arg = CFG_COMP(MT8183, param, outputs[i]); + else if (CFG_CHECK(MT8195, p_id)) + arg = CFG_COMP(MT8195, param, outputs[i]); else return -EINVAL; ctx->outputs[i] = &frame->outputs[arg]; From 9288eae430cbc4de82e82f295ccf7c5d877c0c2b Mon Sep 17 00:00:00 2001 From: Moudy Ho Date: Wed, 20 Dec 2023 11:18:38 +0100 Subject: [PATCH 085/252] media: platform: mtk-mdp3: add support for parallel pipe to improve FPS In some chips, MDP3 has the ability to utilize two pipelines to parallelly process a single frame. To enable this feature, multiple CMDQ clients and packets need to be configured at the same time. Signed-off-by: Moudy Ho Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Sebastian Fricke Signed-off-by: Mauro Carvalho Chehab --- .../platform/mediatek/mdp3/mdp_cfg_data.c | 8 + .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c | 188 +++++++++++++----- .../platform/mediatek/mdp3/mtk-mdp3-cmdq.h | 1 + .../platform/mediatek/mdp3/mtk-mdp3-core.c | 18 +- .../platform/mediatek/mdp3/mtk-mdp3-core.h | 12 +- .../platform/mediatek/mdp3/mtk-mdp3-m2m.c | 15 ++ .../platform/mediatek/mdp3/mtk-mdp3-regs.c | 18 ++ .../platform/mediatek/mdp3/mtk-mdp3-regs.h | 1 + .../platform/mediatek/mdp3/mtk-mdp3-vpu.c | 3 +- 9 files changed, 208 insertions(+), 56 deletions(-) diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c index 9ee3931d31e3..ecca52b45307 100644 --- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c +++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c @@ -1060,6 +1060,11 @@ static const struct mdp_pipe_info mt8195_pipe_info[] = { [MDP_PIPE_VPP0_SOUT] = {MDP_PIPE_VPP0_SOUT, MDP_MM_SUBSYS_1, 5}, }; +static const struct v4l2_rect mt8195_mdp_pp_criteria = { + .width = 1920, + .height = 1080, +}; + const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { .mdp_plat_id = MT8183, .mdp_con_res = 0x14001000, @@ -1074,6 +1079,7 @@ const struct mtk_mdp_driver_data mt8183_mdp_driver_data = { .def_limit = &mt8183_mdp_def_limit, .pipe_info = mt8183_pipe_info, .pipe_info_len = ARRAY_SIZE(mt8183_pipe_info), + .pp_used = MDP_PP_USED_1, }; const struct mtk_mdp_driver_data mt8195_mdp_driver_data = { @@ -1090,6 +1096,8 @@ const struct mtk_mdp_driver_data mt8195_mdp_driver_data = { .def_limit = &mt8195_mdp_def_limit, .pipe_info = mt8195_pipe_info, .pipe_info_len = ARRAY_SIZE(mt8195_pipe_info), + .pp_criteria = &mt8195_mdp_pp_criteria, + .pp_used = MDP_PP_USED_2, }; s32 mdp_cfg_get_id_inner(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index 8114c288da9c..1d64bac34b90 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -55,6 +55,16 @@ static struct mtk_mutex *__get_mutex(const struct mdp_dev *mdp_dev, return mdp_dev->mm_subsys[p->sub_id].mdp_mutex[p->mutex_id]; } +static u8 __get_pp_num(enum mdp_stream_type type) +{ + switch (type) { + case MDP_STREAM_TYPE_DUAL_BITBLT: + return MDP_PP_USED_2; + default: + return MDP_PP_USED_1; + } +} + static enum mdp_pipe_id __get_pipe(const struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id) { @@ -92,6 +102,44 @@ static enum mdp_pipe_id __get_pipe(const struct mdp_dev *mdp_dev, return pipe_id; } +static struct img_config *__get_config_offset(struct mdp_dev *mdp, + struct mdp_cmdq_param *param, + u8 pp_idx) +{ + const int p_id = mdp->mdp_data->mdp_plat_id; + struct device *dev = &mdp->pdev->dev; + void *cfg_c, *cfg_n; + long bound = mdp->vpu.config_size; + + if (pp_idx >= mdp->mdp_data->pp_used) + goto err_param; + + if (CFG_CHECK(MT8183, p_id)) + cfg_c = CFG_OFST(MT8183, param->config, pp_idx); + else if (CFG_CHECK(MT8195, p_id)) + cfg_c = CFG_OFST(MT8195, param->config, pp_idx); + else + goto err_param; + + if (CFG_CHECK(MT8183, p_id)) + cfg_n = CFG_OFST(MT8183, param->config, pp_idx + 1); + else if (CFG_CHECK(MT8195, p_id)) + cfg_n = CFG_OFST(MT8195, param->config, pp_idx + 1); + else + goto err_param; + + if ((long)cfg_n - (long)mdp->vpu.config > bound) { + dev_err(dev, "config offset %ld OOB %ld\n", (long)cfg_n, bound); + cfg_c = ERR_PTR(-EFAULT); + } + + return (struct img_config *)cfg_c; + +err_param: + cfg_c = ERR_PTR(-EINVAL); + return (struct img_config *)cfg_c; +} + static int mdp_path_subfrm_require(const struct mdp_path *path, struct mdp_cmdq_cmd *cmd, struct mdp_pipe_info *p, u32 count) @@ -476,8 +524,19 @@ static void mdp_auto_release_work(struct work_struct *work) mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); - atomic_dec(&mdp->job_count); - wake_up(&mdp->callback_wq); + if (atomic_dec_and_test(&mdp->job_count)) { + if (cmd->mdp_ctx) + mdp_m2m_job_finish(cmd->mdp_ctx); + + if (cmd->user_cmdq_cb) { + struct cmdq_cb_data user_cb_data; + + user_cb_data.sta = cmd->data->sta; + user_cb_data.pkt = cmd->data->pkt; + cmd->user_cmdq_cb(user_cb_data); + } + wake_up(&mdp->callback_wq); + } mdp_cmdq_pkt_destroy(&cmd->pkt); kfree(cmd->comps); @@ -501,20 +560,10 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) data = (struct cmdq_cb_data *)mssg; cmd = container_of(data->pkt, struct mdp_cmdq_cmd, pkt); + cmd->data = data; mdp = cmd->mdp; dev = &mdp->pdev->dev; - if (cmd->mdp_ctx) - mdp_m2m_job_finish(cmd->mdp_ctx); - - if (cmd->user_cmdq_cb) { - struct cmdq_cb_data user_cb_data; - - user_cb_data.sta = data->sta; - user_cb_data.pkt = data->pkt; - cmd->user_cmdq_cb(user_cb_data); - } - INIT_WORK(&cmd->auto_release_work, mdp_auto_release_work); if (!queue_work(mdp->clock_wq, &cmd->auto_release_work)) { struct mtk_mutex *mutex; @@ -526,8 +575,8 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, cmd->num_comps); - atomic_dec(&mdp->job_count); - wake_up(&mdp->callback_wq); + if (atomic_dec_and_test(&mdp->job_count)) + wake_up(&mdp->callback_wq); mdp_cmdq_pkt_destroy(&cmd->pkt); kfree(cmd->comps); @@ -537,31 +586,41 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg) } } -int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) +static struct mdp_cmdq_cmd *mdp_cmdq_prepare(struct mdp_dev *mdp, + struct mdp_cmdq_param *param, + u8 pp_idx) { struct mdp_path *path = NULL; struct mdp_cmdq_cmd *cmd = NULL; struct mdp_comp *comps = NULL; struct device *dev = &mdp->pdev->dev; const int p_id = mdp->mdp_data->mdp_plat_id; + struct img_config *config; struct mtk_mutex *mutex = NULL; enum mdp_pipe_id pipe_id; - int i, ret; - u32 num_comp = 0; + int i, ret = -ECANCELED; + u32 num_comp; - atomic_inc(&mdp->job_count); - if (atomic_read(&mdp->suspended)) { - atomic_dec(&mdp->job_count); - return -ECANCELED; + config = __get_config_offset(mdp, param, pp_idx); + if (IS_ERR(config)) { + ret = PTR_ERR(config); + goto err_uninit; } + if (CFG_CHECK(MT8183, p_id)) + num_comp = CFG_GET(MT8183, config, num_components); + else if (CFG_CHECK(MT8195, p_id)) + num_comp = CFG_GET(MT8195, config, num_components); + else + goto err_uninit; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) { ret = -ENOMEM; - goto err_cancel_job; + goto err_uninit; } - ret = mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K); + ret = mdp_cmdq_pkt_create(mdp->cmdq_clt[pp_idx], &cmd->pkt, SZ_16K); if (ret) goto err_free_cmd; @@ -586,7 +645,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) } path->mdp_dev = mdp; - path->config = param->config; + path->config = config; path->param = param->param; for (i = 0; i < param->param->num_outputs; i++) { path->bounds[i].left = 0; @@ -600,7 +659,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) } ret = mdp_path_ctx_init(mdp, path); if (ret) { - dev_err(dev, "mdp_path_ctx_init error\n"); + dev_err(dev, "mdp_path_ctx_init error %d\n", pp_idx); goto err_free_path; } @@ -608,13 +667,13 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]); ret = mtk_mutex_prepare(mutex); if (ret) { - dev_err(dev, "Fail to enable mutex clk\n"); + dev_err(dev, "Fail to enable mutex %d clk\n", pp_idx); goto err_free_path; } ret = mdp_path_config(mdp, cmd, path); if (ret) { - dev_err(dev, "mdp_path_config error\n"); + dev_err(dev, "mdp_path_config error %d\n", pp_idx); goto err_free_path; } cmdq_pkt_finalize(&cmd->pkt); @@ -633,7 +692,7 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) sizeof(struct mdp_comp)); } - mdp->cmdq_clt->client.rx_callback = mdp_handle_cmdq_callback; + mdp->cmdq_clt[pp_idx]->client.rx_callback = mdp_handle_cmdq_callback; cmd->mdp = mdp; cmd->user_cmdq_cb = param->cmdq_cb; cmd->user_cb_data = param->cb_data; @@ -641,26 +700,9 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) cmd->num_comps = num_comp; cmd->mdp_ctx = param->mdp_ctx; - ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps); - if (ret) - goto err_free_path; - - dma_sync_single_for_device(mdp->cmdq_clt->chan->mbox->dev, - cmd->pkt.pa_base, cmd->pkt.cmd_buf_size, - DMA_TO_DEVICE); - ret = mbox_send_message(mdp->cmdq_clt->chan, &cmd->pkt); - if (ret < 0) { - dev_err(dev, "mbox send message fail %d!\n", ret); - goto err_clock_off; - } - mbox_client_txdone(mdp->cmdq_clt->chan, 0); - kfree(path); - return 0; + return cmd; -err_clock_off: - mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps, - cmd->num_comps); err_free_path: if (mutex) mtk_mutex_unprepare(mutex); @@ -671,8 +713,58 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) mdp_cmdq_pkt_destroy(&cmd->pkt); err_free_cmd: kfree(cmd); +err_uninit: + return ERR_PTR(ret); +} + +int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param) +{ + struct mdp_cmdq_cmd *cmd[MDP_PP_MAX] = {NULL}; + struct device *dev = &mdp->pdev->dev; + int i, ret; + u8 pp_used = __get_pp_num(param->param->type); + + atomic_set(&mdp->job_count, pp_used); + if (atomic_read(&mdp->suspended)) { + atomic_set(&mdp->job_count, 0); + return -ECANCELED; + } + + for (i = 0; i < pp_used; i++) { + cmd[i] = mdp_cmdq_prepare(mdp, param, i); + if (IS_ERR_OR_NULL(cmd[i])) { + ret = PTR_ERR(cmd[i]); + goto err_cancel_job; + } + } + + for (i = 0; i < pp_used; i++) { + ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd[i]->comps, cmd[i]->num_comps); + if (ret) + goto err_clock_off; + } + + for (i = 0; i < pp_used; i++) { + dma_sync_single_for_device(mdp->cmdq_clt[i]->chan->mbox->dev, + cmd[i]->pkt.pa_base, cmd[i]->pkt.cmd_buf_size, + DMA_TO_DEVICE); + + ret = mbox_send_message(mdp->cmdq_clt[i]->chan, &cmd[i]->pkt); + if (ret < 0) { + dev_err(dev, "mbox send message fail %d!\n", ret); + i = pp_used; + goto err_clock_off; + } + mbox_client_txdone(mdp->cmdq_clt[i]->chan, 0); + } + return 0; + +err_clock_off: + while (--i >= 0) + mdp_comp_clocks_off(&mdp->pdev->dev, cmd[i]->comps, + cmd[i]->num_comps); err_cancel_job: - atomic_dec(&mdp->job_count); + atomic_set(&mdp->job_count, 0); return ret; } diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h index 43475b862ddb..53a30ad7e0b0 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h @@ -29,6 +29,7 @@ struct mdp_cmdq_cmd { struct cmdq_pkt pkt; s32 *event; struct mdp_dev *mdp; + struct cmdq_cb_data *data; void (*user_cmdq_cb)(struct cmdq_cb_data data); void *user_cb_data; struct mdp_comp *comps; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index a6c71fd9e5bf..5209f531ef8d 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -142,6 +142,10 @@ void mdp_video_device_release(struct video_device *vdev) struct mdp_dev *mdp = (struct mdp_dev *)video_get_drvdata(vdev); int i; + for (i = 0; i < mdp->mdp_data->pp_used; i++) + if (mdp->cmdq_clt[i]) + cmdq_mbox_destroy(mdp->cmdq_clt[i]); + scp_put(mdp->scp); destroy_workqueue(mdp->job_wq); @@ -299,10 +303,12 @@ static int mdp_probe(struct platform_device *pdev) mutex_init(&mdp->vpu_lock); mutex_init(&mdp->m2m_lock); - mdp->cmdq_clt = cmdq_mbox_create(dev, 0); - if (IS_ERR(mdp->cmdq_clt)) { - ret = PTR_ERR(mdp->cmdq_clt); - goto err_put_scp; + for (i = 0; i < mdp->mdp_data->pp_used; i++) { + mdp->cmdq_clt[i] = cmdq_mbox_create(dev, i); + if (IS_ERR(mdp->cmdq_clt[i])) { + ret = PTR_ERR(mdp->cmdq_clt[i]); + goto err_mbox_destroy; + } } init_waitqueue_head(&mdp->callback_wq); @@ -331,8 +337,8 @@ static int mdp_probe(struct platform_device *pdev) err_unregister_device: v4l2_device_unregister(&mdp->v4l2_dev); err_mbox_destroy: - cmdq_mbox_destroy(mdp->cmdq_clt); -err_put_scp: + while (--i >= 0) + cmdq_mbox_destroy(mdp->cmdq_clt[i]); scp_put(mdp->scp); err_destroy_clock_wq: destroy_workqueue(mdp->clock_wq); diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h index d6484d17b09f..8c09e984fd01 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h @@ -77,6 +77,14 @@ enum mdp_pipe_id { MDP_PIPE_MAX }; +/* MDP parallel pipe control */ +enum { + MDP_PP_USED_1 = 1, + MDP_PP_USED_2 = 2, +}; + +#define MDP_PP_MAX MDP_PP_USED_2 + struct mtk_mdp_driver_data { const int mdp_plat_id; const resource_size_t mdp_con_res; @@ -91,6 +99,8 @@ struct mtk_mdp_driver_data { const struct mdp_limit *def_limit; const struct mdp_pipe_info *pipe_info; unsigned int pipe_info_len; + const struct v4l2_rect *pp_criteria; + const u8 pp_used; }; struct mdp_mm_subsys { @@ -115,7 +125,7 @@ struct mdp_dev { s32 vpu_count; u32 id_count; struct ida mdp_ida; - struct cmdq_client *cmdq_clt; + struct cmdq_client *cmdq_clt[MDP_PP_MAX]; wait_queue_head_t callback_wq; struct v4l2_device v4l2_dev; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c index a298c1b15b9e..35a8b059bde5 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c @@ -87,6 +87,9 @@ static void mdp_m2m_device_run(void *priv) dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); mdp_set_dst_config(¶m.outputs[0], frame, &dst_vb->vb2_buf); + if (mdp_check_pp_enable(ctx->mdp_dev, frame)) + param.type = MDP_STREAM_TYPE_DUAL_BITBLT; + ret = mdp_vpu_process(&ctx->mdp_dev->vpu, ¶m); if (ret) { dev_err(&ctx->mdp_dev->pdev->dev, @@ -101,6 +104,18 @@ static void mdp_m2m_device_run(void *priv) task.cb_data = NULL; task.mdp_ctx = ctx; + if (atomic_read(&ctx->mdp_dev->job_count)) { + ret = wait_event_timeout(ctx->mdp_dev->callback_wq, + !atomic_read(&ctx->mdp_dev->job_count), + 2 * HZ); + if (ret == 0) { + dev_err(&ctx->mdp_dev->pdev->dev, + "%d jobs not yet done\n", + atomic_read(&ctx->mdp_dev->job_count)); + goto worker_end; + } + } + ret = mdp_cmdq_send(ctx->mdp_dev, &task); if (ret) { dev_err(&ctx->mdp_dev->pdev->dev, diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c index 9b436b911d92..657356f87743 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c @@ -304,6 +304,24 @@ int mdp_check_scaling_ratio(const struct v4l2_rect *crop, return 0; } +bool mdp_check_pp_enable(struct mdp_dev *mdp, struct mdp_frame *frame) +{ + u32 s, r1, r2; + + if (!mdp || !frame) + return false; + + if (!mdp->mdp_data->pp_criteria) + return false; + + s = mdp->mdp_data->pp_criteria->width * + mdp->mdp_data->pp_criteria->height; + r1 = frame->crop.c.width * frame->crop.c.height; + r2 = frame->compose.width * frame->compose.height; + + return (r1 >= s || r2 >= s); +} + /* Stride that is accepted by MDP HW */ static u32 mdp_fmt_get_stride(const struct mdp_format *fmt, u32 bytesperline, unsigned int plane) diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h index e9ab8ac2c0e8..b0c8f9f00820 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h @@ -368,6 +368,7 @@ int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r, int mdp_check_scaling_ratio(const struct v4l2_rect *crop, const struct v4l2_rect *compose, s32 rotation, const struct mdp_limit *limit); +bool mdp_check_pp_enable(struct mdp_dev *mdp, struct mdp_frame *frame); void mdp_set_src_config(struct img_input *in, struct mdp_frame *frame, struct vb2_buffer *vb); void mdp_set_dst_config(struct img_output *out, diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c index 49fc2e9d45dd..da3a892ad867 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c @@ -198,6 +198,7 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp, }; struct mdp_dev *mdp = vpu_to_mdp(vpu); int err; + u8 pp_num = mdp->mdp_data->pp_used; init_completion(&vpu->ipi_acked); vpu->scp = scp; @@ -211,7 +212,7 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp, mutex_lock(vpu->lock); vpu->work_size = ALIGN(vpu->work_size, 64); vpu->param_size = ALIGN(sizeof(struct img_ipi_frameparam), 64); - vpu->config_size = ALIGN(sizeof(struct img_config), 64); + vpu->config_size = ALIGN(sizeof(struct img_config) * pp_num, 64); err = mdp_vpu_shared_mem_alloc(vpu); mutex_unlock(vpu->lock); if (err) { From 60314831d2942b6eab974af74d2238dffc321359 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 10 Jan 2024 11:46:38 +0100 Subject: [PATCH 086/252] media: dt-bindings: media: Document STM32MP25 VDEC & VENC video codecs Add STM32MP25 VDEC video decoder & VENC video encoder bindings. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Hugues Fruchet Signed-off-by: Mauro Carvalho Chehab --- .../media/st,stm32mp25-video-codec.yaml | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml new file mode 100644 index 000000000000..b8611bc8756c --- /dev/null +++ b/Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/st,stm32mp25-video-codec.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: STMicroelectronics STM32MP25 VDEC video decoder & VENC video encoder + +maintainers: + - Hugues Fruchet + +description: + The STMicroelectronics STM32MP25 SOCs embeds a VDEC video hardware + decoder peripheral based on Verisilicon VC8000NanoD IP (former Hantro G1) + and a VENC video hardware encoder peripheral based on Verisilicon + VC8000NanoE IP (former Hantro H1). + +properties: + compatible: + enum: + - st,stm32mp25-vdec + - st,stm32mp25-venc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + #include + video-codec@580d0000 { + compatible = "st,stm32mp25-vdec"; + reg = <0x580d0000 0x3c8>; + interrupts = ; + clocks = <&ck_icn_p_vdec>; + }; From 46c4dffb74a477aba4d741118beb90c8dfaa9939 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 10 Jan 2024 11:46:39 +0100 Subject: [PATCH 087/252] media: hantro: add support for STM32MP25 VDEC Add support for STM32MP25 VDEC video hardware decoder. Support of H264/VP8 decoding. No post-processor support. VDEC has its own reset/clock/irq. Successfully tested up to full HD. Reviewed-by: Nicolas Dufresne Signed-off-by: Hugues Fruchet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/verisilicon/Kconfig | 14 ++- drivers/media/platform/verisilicon/Makefile | 3 + .../media/platform/verisilicon/hantro_drv.c | 3 + .../media/platform/verisilicon/hantro_hw.h | 1 + .../platform/verisilicon/stm32mp25_vpu_hw.c | 96 +++++++++++++++++++ 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c diff --git a/drivers/media/platform/verisilicon/Kconfig b/drivers/media/platform/verisilicon/Kconfig index 24b927d8f182..9a34d14c6e40 100644 --- a/drivers/media/platform/verisilicon/Kconfig +++ b/drivers/media/platform/verisilicon/Kconfig @@ -4,7 +4,7 @@ comment "Verisilicon media platform drivers" config VIDEO_HANTRO tristate "Hantro VPU driver" - depends on ARCH_MXC || ARCH_ROCKCHIP || ARCH_AT91 || ARCH_SUNXI || COMPILE_TEST + depends on ARCH_MXC || ARCH_ROCKCHIP || ARCH_AT91 || ARCH_SUNXI || ARCH_STM32 || COMPILE_TEST depends on V4L_MEM2MEM_DRIVERS depends on VIDEO_DEV select MEDIA_CONTROLLER @@ -15,8 +15,8 @@ config VIDEO_HANTRO select V4L2_VP9 help Support for the Hantro IP based Video Processing Units present on - Rockchip and NXP i.MX8M SoCs, which accelerate video and image - encoding and decoding. + Rockchip, NXP i.MX8M and STM32MP25 SoCs, which accelerate video + and image encoding and decoding. To compile this driver as a module, choose M here: the module will be called hantro-vpu. @@ -51,3 +51,11 @@ config VIDEO_HANTRO_SUNXI default y help Enable support for H6 SoC. + +config VIDEO_HANTRO_STM32MP25 + bool "Hantro STM32MP25 support" + depends on VIDEO_HANTRO + depends on ARCH_STM32 || COMPILE_TEST + default y + help + Enable support for STM32MP25 SoCs. diff --git a/drivers/media/platform/verisilicon/Makefile b/drivers/media/platform/verisilicon/Makefile index 6ad2ef885920..eb38a1833b02 100644 --- a/drivers/media/platform/verisilicon/Makefile +++ b/drivers/media/platform/verisilicon/Makefile @@ -39,3 +39,6 @@ hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \ hantro-vpu-$(CONFIG_VIDEO_HANTRO_SUNXI) += \ sunxi_vpu_hw.o + +hantro-vpu-$(CONFIG_VIDEO_HANTRO_STM32MP25) += \ + stm32mp25_vpu_hw.o diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c index db3df6cc4513..fe8e2240324c 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -735,6 +735,9 @@ static const struct of_device_id of_hantro_match[] = { #endif #ifdef CONFIG_VIDEO_HANTRO_SUNXI { .compatible = "allwinner,sun50i-h6-vpu-g2", .data = &sunxi_vpu_variant, }, +#endif +#ifdef CONFIG_VIDEO_HANTRO_STM32MP25 + { .compatible = "st,stm32mp25-vdec", .data = &stm32mp25_vdec_variant, }, #endif { /* sentinel */ } }; diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h index 9aec8a79acdc..0b4806f67630 100644 --- a/drivers/media/platform/verisilicon/hantro_hw.h +++ b/drivers/media/platform/verisilicon/hantro_hw.h @@ -408,6 +408,7 @@ extern const struct hantro_variant rk3568_vpu_variant; extern const struct hantro_variant rk3588_vpu981_variant; extern const struct hantro_variant sama5d4_vdec_variant; extern const struct hantro_variant sunxi_vpu_variant; +extern const struct hantro_variant stm32mp25_vdec_variant; extern const struct hantro_postproc_ops hantro_g1_postproc_ops; extern const struct hantro_postproc_ops hantro_g2_postproc_ops; diff --git a/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c b/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c new file mode 100644 index 000000000000..6af6edcb6650 --- /dev/null +++ b/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * STM32MP25 video codec driver + * + * Copyright (C) STMicroelectronics SA 2024 + * Authors: Hugues Fruchet + * for STMicroelectronics. + * + */ + +#include "hantro.h" + +/* + * Supported formats. + */ + +static const struct hantro_fmt stm32mp25_vdec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_VP8_FRAME, + .codec_mode = HANTRO_MODE_VP8_DEC, + .max_depth = 2, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_H264_SLICE, + .codec_mode = HANTRO_MODE_H264_DEC, + .max_depth = 2, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, + }, +}; + +/* + * Supported codec ops. + */ + +static const struct hantro_codec_ops stm32mp25_vdec_codec_ops[] = { + [HANTRO_MODE_VP8_DEC] = { + .run = hantro_g1_vp8_dec_run, + .reset = hantro_g1_reset, + .init = hantro_vp8_dec_init, + .exit = hantro_vp8_dec_exit, + }, + [HANTRO_MODE_H264_DEC] = { + .run = hantro_g1_h264_dec_run, + .reset = hantro_g1_reset, + .init = hantro_h264_dec_init, + .exit = hantro_h264_dec_exit, + }, +}; + +/* + * Variants. + */ + +static const struct hantro_irq stm32mp25_vdec_irqs[] = { + { "vdec", hantro_g1_irq }, +}; + +static const char * const stm32mp25_vdec_clk_names[] = { "vdec-clk" }; + +const struct hantro_variant stm32mp25_vdec_variant = { + .dec_fmts = stm32mp25_vdec_fmts, + .num_dec_fmts = ARRAY_SIZE(stm32mp25_vdec_fmts), + .codec = HANTRO_VP8_DECODER | HANTRO_H264_DECODER, + .codec_ops = stm32mp25_vdec_codec_ops, + .irqs = stm32mp25_vdec_irqs, + .num_irqs = ARRAY_SIZE(stm32mp25_vdec_irqs), + .clk_names = stm32mp25_vdec_clk_names, + .num_clocks = ARRAY_SIZE(stm32mp25_vdec_clk_names), +}; From b0fb9ca30a67edeb8baf6b64014904ebb8ccf0e2 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 10 Jan 2024 11:46:40 +0100 Subject: [PATCH 088/252] media: hantro: add support for STM32MP25 VENC Add support for STM32MP25 VENC video hardware encoder. Support of JPEG encoding. VENC has its own reset/clock/irq. Reviewed-by: Nicolas Dufresne Signed-off-by: Hugues Fruchet Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/verisilicon/hantro_drv.c | 1 + .../media/platform/verisilicon/hantro_hw.h | 1 + .../platform/verisilicon/stm32mp25_vpu_hw.c | 90 +++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c index fe8e2240324c..34b123dafd89 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -738,6 +738,7 @@ static const struct of_device_id of_hantro_match[] = { #endif #ifdef CONFIG_VIDEO_HANTRO_STM32MP25 { .compatible = "st,stm32mp25-vdec", .data = &stm32mp25_vdec_variant, }, + { .compatible = "st,stm32mp25-venc", .data = &stm32mp25_venc_variant, }, #endif { /* sentinel */ } }; diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h index 0b4806f67630..7737320cc8cc 100644 --- a/drivers/media/platform/verisilicon/hantro_hw.h +++ b/drivers/media/platform/verisilicon/hantro_hw.h @@ -409,6 +409,7 @@ extern const struct hantro_variant rk3588_vpu981_variant; extern const struct hantro_variant sama5d4_vdec_variant; extern const struct hantro_variant sunxi_vpu_variant; extern const struct hantro_variant stm32mp25_vdec_variant; +extern const struct hantro_variant stm32mp25_venc_variant; extern const struct hantro_postproc_ops hantro_g1_postproc_ops; extern const struct hantro_postproc_ops hantro_g2_postproc_ops; diff --git a/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c b/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c index 6af6edcb6650..833821120b20 100644 --- a/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c +++ b/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c @@ -9,6 +9,8 @@ */ #include "hantro.h" +#include "hantro_jpeg.h" +#include "hantro_h1_regs.h" /* * Supported formats. @@ -55,6 +57,67 @@ static const struct hantro_fmt stm32mp25_vdec_fmts[] = { }, }; +static const struct hantro_fmt stm32mp25_venc_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_YUV420M, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420P, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420SP, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUYV422, + }, + { + .fourcc = V4L2_PIX_FMT_UYVY, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_UYVY422, + }, + { + .fourcc = V4L2_PIX_FMT_JPEG, + .codec_mode = HANTRO_MODE_JPEG_ENC, + .max_depth = 2, + .header_size = JPEG_HEADER_SIZE, + .frmsize = { + .min_width = 96, + .max_width = FMT_4K_WIDTH, + .step_width = MB_DIM, + .min_height = 96, + .max_height = FMT_4K_HEIGHT, + .step_height = MB_DIM, + }, + }, +}; + +static irqreturn_t stm32mp25_venc_irq(int irq, void *dev_id) +{ + struct hantro_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status; + + status = vepu_read(vpu, H1_REG_INTERRUPT); + state = (status & H1_REG_INTERRUPT_FRAME_RDY) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vepu_write(vpu, H1_REG_INTERRUPT_BIT, H1_REG_INTERRUPT); + + hantro_irq_done(vpu, state); + + return IRQ_HANDLED; +} + +static void stm32mp25_venc_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + + reset_control_reset(vpu->resets); +} + /* * Supported codec ops. */ @@ -74,6 +137,14 @@ static const struct hantro_codec_ops stm32mp25_vdec_codec_ops[] = { }, }; +static const struct hantro_codec_ops stm32mp25_venc_codec_ops[] = { + [HANTRO_MODE_JPEG_ENC] = { + .run = hantro_h1_jpeg_enc_run, + .reset = stm32mp25_venc_reset, + .done = hantro_h1_jpeg_enc_done, + }, +}; + /* * Variants. */ @@ -94,3 +165,22 @@ const struct hantro_variant stm32mp25_vdec_variant = { .clk_names = stm32mp25_vdec_clk_names, .num_clocks = ARRAY_SIZE(stm32mp25_vdec_clk_names), }; + +static const struct hantro_irq stm32mp25_venc_irqs[] = { + { "venc", stm32mp25_venc_irq }, +}; + +static const char * const stm32mp25_venc_clk_names[] = { + "venc-clk" +}; + +const struct hantro_variant stm32mp25_venc_variant = { + .enc_fmts = stm32mp25_venc_fmts, + .num_enc_fmts = ARRAY_SIZE(stm32mp25_venc_fmts), + .codec = HANTRO_JPEG_ENCODER, + .codec_ops = stm32mp25_venc_codec_ops, + .irqs = stm32mp25_venc_irqs, + .num_irqs = ARRAY_SIZE(stm32mp25_venc_irqs), + .clk_names = stm32mp25_venc_clk_names, + .num_clocks = ARRAY_SIZE(stm32mp25_venc_clk_names) +}; From d96a6119e332f4ae5cdd55698da68d372aede2d0 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 10 Jan 2024 11:46:41 +0100 Subject: [PATCH 089/252] media: arm64: dts: st: add video decoder support to stm32mp255 Add VDEC hardware video decoder support to STM32MP255. Signed-off-by: Hugues Fruchet Signed-off-by: Mauro Carvalho Chehab --- arch/arm64/boot/dts/st/stm32mp251.dtsi | 6 ++++++ arch/arm64/boot/dts/st/stm32mp255.dtsi | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi index 96859d098ef8..8fc7e9199499 100644 --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi @@ -52,6 +52,12 @@ ck_icn_ls_mcu: ck-icn-ls-mcu { compatible = "fixed-clock"; clock-frequency = <200000000>; }; + + ck_icn_p_vdec: ck-icn-p-vdec { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <200000000>; + }; }; firmware { diff --git a/arch/arm64/boot/dts/st/stm32mp255.dtsi b/arch/arm64/boot/dts/st/stm32mp255.dtsi index e6fa596211f5..aea5096dac3c 100644 --- a/arch/arm64/boot/dts/st/stm32mp255.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp255.dtsi @@ -6,4 +6,14 @@ #include "stm32mp253.dtsi" / { + soc@0 { + rifsc: rifsc-bus@42080000 { + vdec: vdec@480d0000 { + compatible = "st,stm32mp25-vdec"; + reg = <0x480d0000 0x3c8>; + interrupts = ; + clocks = <&ck_icn_p_vdec>; + }; + }; + }; }; From 87f7f576e3d83fffbd067b058ad77e012a32b3de Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 10 Jan 2024 11:46:42 +0100 Subject: [PATCH 090/252] media: arm64: dts: st: add video encoder support to stm32mp255 Add VENC hardware video encoder support to STM32MP255. Signed-off-by: Hugues Fruchet Signed-off-by: Mauro Carvalho Chehab --- arch/arm64/boot/dts/st/stm32mp251.dtsi | 6 ++++++ arch/arm64/boot/dts/st/stm32mp255.dtsi | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi index 8fc7e9199499..5dd4f3580a60 100644 --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi @@ -58,6 +58,12 @@ ck_icn_p_vdec: ck-icn-p-vdec { compatible = "fixed-clock"; clock-frequency = <200000000>; }; + + ck_icn_p_venc: ck-icn-p-venc { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <200000000>; + }; }; firmware { diff --git a/arch/arm64/boot/dts/st/stm32mp255.dtsi b/arch/arm64/boot/dts/st/stm32mp255.dtsi index aea5096dac3c..17f197c5b22b 100644 --- a/arch/arm64/boot/dts/st/stm32mp255.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp255.dtsi @@ -14,6 +14,13 @@ vdec: vdec@480d0000 { interrupts = ; clocks = <&ck_icn_p_vdec>; }; + + venc: venc@480e0000 { + compatible = "st,stm32mp25-venc"; + reg = <0x480e0000 0x800>; + interrupts = ; + clocks = <&ck_icn_ls_mcu>; + }; }; }; }; From c06983f853bc58eafe05f75dfd7e8bdafba3cd8c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 5 Jan 2024 11:59:22 +0100 Subject: [PATCH 091/252] media: Documentation: Rework CCS driver documentation Drop duplicated UAPI specific portions of the CCS (kernel) documentation and fix a spelling error in UAPI documentation previously fixed in driver documentation. Also add references both ways. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../driver-api/media/drivers/ccs/ccs.rst | 51 ++----------------- .../userspace-api/media/drivers/ccs.rst | 6 ++- 2 files changed, 9 insertions(+), 48 deletions(-) diff --git a/Documentation/driver-api/media/drivers/ccs/ccs.rst b/Documentation/driver-api/media/drivers/ccs/ccs.rst index 776eec72bc80..5d4451339b7f 100644 --- a/Documentation/driver-api/media/drivers/ccs/ccs.rst +++ b/Documentation/driver-api/media/drivers/ccs/ccs.rst @@ -2,59 +2,16 @@ .. include:: +.. _media-ccs-driver: + MIPI CCS camera sensor driver ============================= The MIPI CCS camera sensor driver is a generic driver for `MIPI CCS `_ compliant -camera sensors. It exposes three sub-devices representing the pixel array, -the binner and the scaler. +camera sensors. -As the capabilities of individual devices vary, the driver exposes -interfaces based on the capabilities that exist in hardware. - -Pixel Array sub-device ----------------------- - -The pixel array sub-device represents the camera sensor's pixel matrix, as well -as analogue crop functionality present in many compliant devices. The analogue -crop is configured using the ``V4L2_SEL_TGT_CROP`` on the source pad (0) of the -entity. The size of the pixel matrix can be obtained by getting the -``V4L2_SEL_TGT_NATIVE_SIZE`` target. - -Binner ------- - -The binner sub-device represents the binning functionality on the sensor. For -that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the -sink pad (0). - -Additionally, if a device has no scaler or digital crop functionality, the -source pad (1) exposes another digital crop selection rectangle that can only -crop at the end of the lines and frames. - -Scaler ------- - -The scaler sub-device represents the digital crop and scaling functionality of -the sensor. The V4L2 selection target ``V4L2_SEL_TGT_CROP`` is used to -configure the digital crop on the sink pad (0) when digital crop is supported. -Scaling is configured using selection target ``V4L2_SEL_TGT_COMPOSE`` on the -sink pad (0) as well. - -Additionally, if the scaler sub-device exists, its source pad (1) exposes -another digital crop selection rectangle that can only crop at the end of the -lines and frames. - -Digital and analogue crop -------------------------- - -Digital crop functionality is referred to as cropping that effectively works by -dropping some data on the floor. Analogue crop, on the other hand, means that -the cropped information is never retrieved. In case of camera sensors, the -analogue data is never read from the pixel matrix that are outside the -configured selection rectangle that designates crop. The difference has an -effect in device timing and likely also in power consumption. +Also see :ref:`the CCS driver UAPI documentation `. CCS static data --------------- diff --git a/Documentation/userspace-api/media/drivers/ccs.rst b/Documentation/userspace-api/media/drivers/ccs.rst index 161cb65f4d98..03015b33d5ab 100644 --- a/Documentation/userspace-api/media/drivers/ccs.rst +++ b/Documentation/userspace-api/media/drivers/ccs.rst @@ -2,6 +2,8 @@ .. include:: +.. _media-ccs-uapi: + MIPI CCS camera sensor driver ============================= @@ -13,6 +15,8 @@ the binner and the scaler. As the capabilities of individual devices vary, the driver exposes interfaces based on the capabilities that exist in hardware. +Also see :ref:`the CCS driver kernel documentation `. + Pixel Array sub-device ---------------------- @@ -30,7 +34,7 @@ that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the sink pad (0). Additionally, if a device has no scaler or digital crop functionality, the -source pad (1) expses another digital crop selection rectangle that can only +source pad (1) exposes another digital crop selection rectangle that can only crop at the end of the lines and frames. Scaler From 24b41af1f1d203d86b3fb8f4b0e28157908f49dc Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 10 Jan 2024 10:01:11 +0100 Subject: [PATCH 092/252] media: tc358743: register v4l2 async device only after successful setup Ensure the device has been setup correctly before registering the v4l2 async device, thus allowing userspace to access. Signed-off-by: Alexander Stein Reviewed-by: Robert Foss Fixes: 4c5211a10039 ("[media] tc358743: register v4l2 asynchronous subdevice") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tc358743.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 2785935da497..558152575d10 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -2091,9 +2091,6 @@ static int tc358743_probe(struct i2c_client *client) state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24; sd->dev = &client->dev; - err = v4l2_async_register_subdev(sd); - if (err < 0) - goto err_hdl; mutex_init(&state->confctl_mutex); @@ -2151,6 +2148,10 @@ static int tc358743_probe(struct i2c_client *client) if (err) goto err_work_queues; + err = v4l2_async_register_subdev(sd); + if (err < 0) + goto err_work_queues; + v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); From 9a6d7f2ba2b928a939763938e87dc6722f2d43fa Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Fri, 12 Jan 2024 10:52:28 +0100 Subject: [PATCH 093/252] media: i2c: st-vgxy61: Convert to CCI register access helpers Use the new common CCI register access helpers to replace the private register access helpers in the st-vgxy61 driver. This simplifies the driver by reducing the amount of code. st-vgxy61 devices use little endianness arrangement, therefore the driver uses the CCI_REGx_LE registers definition. Signed-off-by: Julien Massot Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/st-vgxy61.c | 388 +++++++++++++--------------------- 2 files changed, 153 insertions(+), 236 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 4c3435921f19..9d9b52d93131 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -658,6 +658,7 @@ config VIDEO_S5K6A3 config VIDEO_ST_VGXY61 tristate "ST VGXY61 sensor support" + select V4L2_CCI_I2C depends on OF && GPIOLIB help This is a Video4Linux2 sensor driver for the ST VGXY61 diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c index e4d37a197724..2d64466d7ecf 100644 --- a/drivers/media/i2c/st-vgxy61.c +++ b/drivers/media/i2c/st-vgxy61.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -19,79 +20,74 @@ #include #include +#include #include #include #include #include #include -#define VGXY61_REG_8BIT(n) ((1 << 16) | (n)) -#define VGXY61_REG_16BIT(n) ((2 << 16) | (n)) -#define VGXY61_REG_32BIT(n) ((4 << 16) | (n)) -#define VGXY61_REG_SIZE_SHIFT 16 -#define VGXY61_REG_ADDR_MASK 0xffff - -#define VGXY61_REG_MODEL_ID VGXY61_REG_16BIT(0x0000) +#define VGXY61_REG_MODEL_ID CCI_REG16_LE(0x0000) #define VG5661_MODEL_ID 0x5661 #define VG5761_MODEL_ID 0x5761 -#define VGXY61_REG_REVISION VGXY61_REG_16BIT(0x0002) -#define VGXY61_REG_FWPATCH_REVISION VGXY61_REG_16BIT(0x0014) -#define VGXY61_REG_FWPATCH_START_ADDR VGXY61_REG_8BIT(0x2000) -#define VGXY61_REG_SYSTEM_FSM VGXY61_REG_8BIT(0x0020) +#define VGXY61_REG_REVISION CCI_REG16_LE(0x0002) +#define VGXY61_REG_FWPATCH_REVISION CCI_REG16_LE(0x0014) +#define VGXY61_REG_FWPATCH_START_ADDR CCI_REG8(0x2000) +#define VGXY61_REG_SYSTEM_FSM CCI_REG8(0x0020) #define VGXY61_SYSTEM_FSM_SW_STBY 0x03 #define VGXY61_SYSTEM_FSM_STREAMING 0x04 -#define VGXY61_REG_NVM VGXY61_REG_8BIT(0x0023) +#define VGXY61_REG_NVM CCI_REG8(0x0023) #define VGXY61_NVM_OK 0x04 -#define VGXY61_REG_STBY VGXY61_REG_8BIT(0x0201) +#define VGXY61_REG_STBY CCI_REG8(0x0201) #define VGXY61_STBY_NO_REQ 0 #define VGXY61_STBY_REQ_TMP_READ BIT(2) -#define VGXY61_REG_STREAMING VGXY61_REG_8BIT(0x0202) +#define VGXY61_REG_STREAMING CCI_REG8(0x0202) #define VGXY61_STREAMING_NO_REQ 0 #define VGXY61_STREAMING_REQ_STOP BIT(0) #define VGXY61_STREAMING_REQ_START BIT(1) -#define VGXY61_REG_EXT_CLOCK VGXY61_REG_32BIT(0x0220) -#define VGXY61_REG_CLK_PLL_PREDIV VGXY61_REG_8BIT(0x0224) -#define VGXY61_REG_CLK_SYS_PLL_MULT VGXY61_REG_8BIT(0x0225) -#define VGXY61_REG_GPIO_0_CTRL VGXY61_REG_8BIT(0x0236) -#define VGXY61_REG_GPIO_1_CTRL VGXY61_REG_8BIT(0x0237) -#define VGXY61_REG_GPIO_2_CTRL VGXY61_REG_8BIT(0x0238) -#define VGXY61_REG_GPIO_3_CTRL VGXY61_REG_8BIT(0x0239) -#define VGXY61_REG_SIGNALS_POLARITY_CTRL VGXY61_REG_8BIT(0x023b) -#define VGXY61_REG_LINE_LENGTH VGXY61_REG_16BIT(0x0300) -#define VGXY61_REG_ORIENTATION VGXY61_REG_8BIT(0x0302) -#define VGXY61_REG_VT_CTRL VGXY61_REG_8BIT(0x0304) -#define VGXY61_REG_FORMAT_CTRL VGXY61_REG_8BIT(0x0305) -#define VGXY61_REG_OIF_CTRL VGXY61_REG_16BIT(0x0306) -#define VGXY61_REG_OIF_ROI0_CTRL VGXY61_REG_8BIT(0x030a) -#define VGXY61_REG_ROI0_START_H VGXY61_REG_16BIT(0x0400) -#define VGXY61_REG_ROI0_START_V VGXY61_REG_16BIT(0x0402) -#define VGXY61_REG_ROI0_END_H VGXY61_REG_16BIT(0x0404) -#define VGXY61_REG_ROI0_END_V VGXY61_REG_16BIT(0x0406) -#define VGXY61_REG_PATGEN_CTRL VGXY61_REG_32BIT(0x0440) +#define VGXY61_REG_EXT_CLOCK CCI_REG32_LE(0x0220) +#define VGXY61_REG_CLK_PLL_PREDIV CCI_REG8(0x0224) +#define VGXY61_REG_CLK_SYS_PLL_MULT CCI_REG8(0x0225) +#define VGXY61_REG_GPIO_0_CTRL CCI_REG8(0x0236) +#define VGXY61_REG_GPIO_1_CTRL CCI_REG8(0x0237) +#define VGXY61_REG_GPIO_2_CTRL CCI_REG8(0x0238) +#define VGXY61_REG_GPIO_3_CTRL CCI_REG8(0x0239) +#define VGXY61_REG_SIGNALS_POLARITY_CTRL CCI_REG8(0x023b) +#define VGXY61_REG_LINE_LENGTH CCI_REG16_LE(0x0300) +#define VGXY61_REG_ORIENTATION CCI_REG8(0x0302) +#define VGXY61_REG_VT_CTRL CCI_REG8(0x0304) +#define VGXY61_REG_FORMAT_CTRL CCI_REG8(0x0305) +#define VGXY61_REG_OIF_CTRL CCI_REG16_LE(0x0306) +#define VGXY61_REG_OIF_ROI0_CTRL CCI_REG8(0x030a) +#define VGXY61_REG_ROI0_START_H CCI_REG16_LE(0x0400) +#define VGXY61_REG_ROI0_START_V CCI_REG16_LE(0x0402) +#define VGXY61_REG_ROI0_END_H CCI_REG16_LE(0x0404) +#define VGXY61_REG_ROI0_END_V CCI_REG16_LE(0x0406) +#define VGXY61_REG_PATGEN_CTRL CCI_REG32_LE(0x0440) #define VGXY61_PATGEN_LONG_ENABLE BIT(16) #define VGXY61_PATGEN_SHORT_ENABLE BIT(0) #define VGXY61_PATGEN_LONG_TYPE_SHIFT 18 #define VGXY61_PATGEN_SHORT_TYPE_SHIFT 4 -#define VGXY61_REG_FRAME_CONTENT_CTRL VGXY61_REG_8BIT(0x0478) -#define VGXY61_REG_COARSE_EXPOSURE_LONG VGXY61_REG_16BIT(0x0500) -#define VGXY61_REG_COARSE_EXPOSURE_SHORT VGXY61_REG_16BIT(0x0504) -#define VGXY61_REG_ANALOG_GAIN VGXY61_REG_8BIT(0x0508) -#define VGXY61_REG_DIGITAL_GAIN_LONG VGXY61_REG_16BIT(0x050a) -#define VGXY61_REG_DIGITAL_GAIN_SHORT VGXY61_REG_16BIT(0x0512) -#define VGXY61_REG_FRAME_LENGTH VGXY61_REG_16BIT(0x051a) -#define VGXY61_REG_SIGNALS_CTRL VGXY61_REG_16BIT(0x0522) +#define VGXY61_REG_FRAME_CONTENT_CTRL CCI_REG8(0x0478) +#define VGXY61_REG_COARSE_EXPOSURE_LONG CCI_REG16_LE(0x0500) +#define VGXY61_REG_COARSE_EXPOSURE_SHORT CCI_REG16_LE(0x0504) +#define VGXY61_REG_ANALOG_GAIN CCI_REG8(0x0508) +#define VGXY61_REG_DIGITAL_GAIN_LONG CCI_REG16_LE(0x050a) +#define VGXY61_REG_DIGITAL_GAIN_SHORT CCI_REG16_LE(0x0512) +#define VGXY61_REG_FRAME_LENGTH CCI_REG16_LE(0x051a) +#define VGXY61_REG_SIGNALS_CTRL CCI_REG16_LE(0x0522) #define VGXY61_SIGNALS_GPIO_ID_SHIFT 4 -#define VGXY61_REG_READOUT_CTRL VGXY61_REG_8BIT(0x0530) -#define VGXY61_REG_HDR_CTRL VGXY61_REG_8BIT(0x0532) -#define VGXY61_REG_PATGEN_LONG_DATA_GR VGXY61_REG_16BIT(0x092c) -#define VGXY61_REG_PATGEN_LONG_DATA_R VGXY61_REG_16BIT(0x092e) -#define VGXY61_REG_PATGEN_LONG_DATA_B VGXY61_REG_16BIT(0x0930) -#define VGXY61_REG_PATGEN_LONG_DATA_GB VGXY61_REG_16BIT(0x0932) -#define VGXY61_REG_PATGEN_SHORT_DATA_GR VGXY61_REG_16BIT(0x0950) -#define VGXY61_REG_PATGEN_SHORT_DATA_R VGXY61_REG_16BIT(0x0952) -#define VGXY61_REG_PATGEN_SHORT_DATA_B VGXY61_REG_16BIT(0x0954) -#define VGXY61_REG_PATGEN_SHORT_DATA_GB VGXY61_REG_16BIT(0x0956) -#define VGXY61_REG_BYPASS_CTRL VGXY61_REG_8BIT(0x0a60) +#define VGXY61_REG_READOUT_CTRL CCI_REG8(0x0530) +#define VGXY61_REG_HDR_CTRL CCI_REG8(0x0532) +#define VGXY61_REG_PATGEN_LONG_DATA_GR CCI_REG16_LE(0x092c) +#define VGXY61_REG_PATGEN_LONG_DATA_R CCI_REG16_LE(0x092e) +#define VGXY61_REG_PATGEN_LONG_DATA_B CCI_REG16_LE(0x0930) +#define VGXY61_REG_PATGEN_LONG_DATA_GB CCI_REG16_LE(0x0932) +#define VGXY61_REG_PATGEN_SHORT_DATA_GR CCI_REG16_LE(0x0950) +#define VGXY61_REG_PATGEN_SHORT_DATA_R CCI_REG16_LE(0x0952) +#define VGXY61_REG_PATGEN_SHORT_DATA_B CCI_REG16_LE(0x0954) +#define VGXY61_REG_PATGEN_SHORT_DATA_GB CCI_REG16_LE(0x0956) +#define VGXY61_REG_BYPASS_CTRL CCI_REG8(0x0a60) #define VGX661_WIDTH 1464 #define VGX661_HEIGHT 1104 @@ -384,6 +380,7 @@ static const struct vgxy61_mode_info vgx761_mode_data[] = { struct vgxy61_dev { struct i2c_client *i2c_client; + struct regmap *regmap; struct v4l2_subdev sd; struct media_pad pad; struct regulator_bulk_data supplies[ARRAY_SIZE(vgxy61_supply_name)]; @@ -510,82 +507,6 @@ static unsigned int get_chunk_size(struct vgxy61_dev *sensor) return max(max_write_len, 1); } -static int vgxy61_read_multiple(struct vgxy61_dev *sensor, u32 reg, - unsigned int len) -{ - struct i2c_client *client = sensor->i2c_client; - struct i2c_msg msg[2]; - u8 buf[2]; - u8 val[sizeof(u32)] = {0}; - int ret; - - if (len > sizeof(u32)) - return -EINVAL; - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - - msg[1].addr = client->addr; - msg[1].flags = client->flags | I2C_M_RD; - msg[1].buf = val; - msg[1].len = len; - - ret = i2c_transfer(client->adapter, msg, 2); - if (ret < 0) { - dev_dbg(&client->dev, "%s: %x i2c_transfer, reg: %x => %d\n", - __func__, client->addr, reg, ret); - return ret; - } - - return get_unaligned_le32(val); -} - -static inline int vgxy61_read_reg(struct vgxy61_dev *sensor, u32 reg) -{ - return vgxy61_read_multiple(sensor, reg & VGXY61_REG_ADDR_MASK, - (reg >> VGXY61_REG_SIZE_SHIFT) & 7); -} - -static int vgxy61_write_multiple(struct vgxy61_dev *sensor, u32 reg, - const u8 *data, unsigned int len, int *err) -{ - struct i2c_client *client = sensor->i2c_client; - struct i2c_msg msg; - u8 buf[VGXY61_WRITE_MULTIPLE_CHUNK_MAX + 2]; - unsigned int i; - int ret; - - if (err && *err) - return *err; - - if (len > VGXY61_WRITE_MULTIPLE_CHUNK_MAX) - return -EINVAL; - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - for (i = 0; i < len; i++) - buf[i + 2] = data[i]; - - msg.addr = client->addr; - msg.flags = client->flags; - msg.buf = buf; - msg.len = len + 2; - - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret < 0) { - dev_dbg(&client->dev, "%s: i2c_transfer, reg: %x => %d\n", - __func__, reg, ret); - if (err) - *err = ret; - return ret; - } - - return 0; -} - static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg, unsigned int nb, const u8 *array) { @@ -595,7 +516,8 @@ static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg, while (nb) { sz = min(nb, chunk_size); - ret = vgxy61_write_multiple(sensor, reg, array, sz, NULL); + ret = regmap_bulk_write(sensor->regmap, CCI_REG_ADDR(reg), + array, sz); if (ret < 0) return ret; nb -= sz; @@ -606,24 +528,17 @@ static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg, return 0; } -static inline int vgxy61_write_reg(struct vgxy61_dev *sensor, u32 reg, u32 val, - int *err) -{ - return vgxy61_write_multiple(sensor, reg & VGXY61_REG_ADDR_MASK, - (u8 *)&val, - (reg >> VGXY61_REG_SIZE_SHIFT) & 7, err); -} - static int vgxy61_poll_reg(struct vgxy61_dev *sensor, u32 reg, u8 poll_val, unsigned int timeout_ms) { const unsigned int loop_delay_ms = 10; + u64 val; int ret; - return read_poll_timeout(vgxy61_read_reg, ret, - ((ret < 0) || (ret == poll_val)), + return read_poll_timeout(cci_read, ret, + ((ret < 0) || (val == poll_val)), loop_delay_ms * 1000, timeout_ms * 1000, - false, sensor, reg); + false, sensor->regmap, reg, &val, NULL); } static int vgxy61_wait_state(struct vgxy61_dev *sensor, int state, @@ -662,11 +577,11 @@ static int vgxy61_apply_exposure(struct vgxy61_dev *sensor) int ret = 0; /* We first set expo to zero to avoid forbidden parameters couple */ - vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_SHORT, 0, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_LONG, - sensor->expo_long, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_SHORT, - sensor->expo_short, &ret); + cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_SHORT, 0, &ret); + cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_LONG, + sensor->expo_long, &ret); + cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_SHORT, + sensor->expo_short, &ret); return ret; } @@ -827,8 +742,8 @@ static int vgxy61_update_analog_gain(struct vgxy61_dev *sensor, u32 target) sensor->analog_gain = target; if (sensor->streaming) - return vgxy61_write_reg(sensor, VGXY61_REG_ANALOG_GAIN, target, - NULL); + return cci_write(sensor->regmap, VGXY61_REG_ANALOG_GAIN, target, + NULL); return 0; } @@ -842,10 +757,10 @@ static int vgxy61_apply_digital_gain(struct vgxy61_dev *sensor, * DIGITAL_GAIN_SHORT_CH0 is enough to configure the gain of all * four sub pixels. */ - vgxy61_write_reg(sensor, VGXY61_REG_DIGITAL_GAIN_LONG, digital_gain, - &ret); - vgxy61_write_reg(sensor, VGXY61_REG_DIGITAL_GAIN_SHORT, digital_gain, - &ret); + cci_write(sensor->regmap, VGXY61_REG_DIGITAL_GAIN_LONG, digital_gain, + &ret); + cci_write(sensor->regmap, VGXY61_REG_DIGITAL_GAIN_SHORT, digital_gain, + &ret); return ret; } @@ -870,7 +785,7 @@ static int vgxy61_apply_patgen(struct vgxy61_dev *sensor, u32 index) if (pattern) reg |= VGXY61_PATGEN_LONG_ENABLE | VGXY61_PATGEN_SHORT_ENABLE; - return vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_CTRL, reg, NULL); + return cci_write(sensor->regmap, VGXY61_REG_PATGEN_CTRL, reg, NULL); } static int vgxy61_update_patgen(struct vgxy61_dev *sensor, u32 pattern) @@ -887,15 +802,13 @@ static int vgxy61_apply_gpiox_strobe_mode(struct vgxy61_dev *sensor, unsigned int idx) { static const u8 index2val[] = {0x0, 0x1, 0x3}; - int reg; + u16 mask, val; - reg = vgxy61_read_reg(sensor, VGXY61_REG_SIGNALS_CTRL); - if (reg < 0) - return reg; - reg &= ~(0xf << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT)); - reg |= index2val[mode] << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT); + mask = 0xf << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT); + val = index2val[mode] << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT); - return vgxy61_write_reg(sensor, VGXY61_REG_SIGNALS_CTRL, reg, NULL); + return cci_update_bits(sensor->regmap, VGXY61_REG_SIGNALS_CTRL, + mask, val, NULL); } static int vgxy61_update_gpios_strobe_mode(struct vgxy61_dev *sensor, @@ -940,12 +853,12 @@ static int vgxy61_update_gpios_strobe_polarity(struct vgxy61_dev *sensor, if (sensor->streaming) return -EBUSY; - vgxy61_write_reg(sensor, VGXY61_REG_GPIO_0_CTRL, polarity << 1, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_GPIO_1_CTRL, polarity << 1, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_GPIO_2_CTRL, polarity << 1, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_GPIO_3_CTRL, polarity << 1, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_SIGNALS_POLARITY_CTRL, polarity, - &ret); + cci_write(sensor->regmap, VGXY61_REG_GPIO_0_CTRL, polarity << 1, &ret); + cci_write(sensor->regmap, VGXY61_REG_GPIO_1_CTRL, polarity << 1, &ret); + cci_write(sensor->regmap, VGXY61_REG_GPIO_2_CTRL, polarity << 1, &ret); + cci_write(sensor->regmap, VGXY61_REG_GPIO_3_CTRL, polarity << 1, &ret); + cci_write(sensor->regmap, VGXY61_REG_SIGNALS_POLARITY_CTRL, polarity, + &ret); return ret; } @@ -1057,8 +970,8 @@ static int vgxy61_update_exposure(struct vgxy61_dev *sensor, u16 new_expo_long, static int vgxy61_apply_framelength(struct vgxy61_dev *sensor) { - return vgxy61_write_reg(sensor, VGXY61_REG_FRAME_LENGTH, - sensor->frame_length, NULL); + return cci_write(sensor->regmap, VGXY61_REG_FRAME_LENGTH, + sensor->frame_length, NULL); } static int vgxy61_update_vblank(struct vgxy61_dev *sensor, u16 vblank, @@ -1086,8 +999,8 @@ static int vgxy61_apply_hdr(struct vgxy61_dev *sensor, { static const u8 index2val[] = {0x1, 0x4, 0xa}; - return vgxy61_write_reg(sensor, VGXY61_REG_HDR_CTRL, index2val[index], - NULL); + return cci_write(sensor->regmap, VGXY61_REG_HDR_CTRL, index2val[index], + NULL); } static int vgxy61_update_hdr(struct vgxy61_dev *sensor, @@ -1133,16 +1046,16 @@ static int vgxy61_apply_settings(struct vgxy61_dev *sensor) if (ret) return ret; - ret = vgxy61_write_reg(sensor, VGXY61_REG_ANALOG_GAIN, - sensor->analog_gain, NULL); + ret = cci_write(sensor->regmap, VGXY61_REG_ANALOG_GAIN, + sensor->analog_gain, NULL); if (ret) return ret; ret = vgxy61_apply_digital_gain(sensor, sensor->digital_gain); if (ret) return ret; - ret = vgxy61_write_reg(sensor, VGXY61_REG_ORIENTATION, - sensor->hflip | (sensor->vflip << 1), NULL); + ret = cci_write(sensor->regmap, VGXY61_REG_ORIENTATION, + sensor->hflip | (sensor->vflip << 1), NULL); if (ret) return ret; @@ -1174,19 +1087,19 @@ static int vgxy61_stream_enable(struct vgxy61_dev *sensor) if (ret) return ret; - vgxy61_write_reg(sensor, VGXY61_REG_FORMAT_CTRL, - get_bpp_by_code(sensor->fmt.code), &ret); - vgxy61_write_reg(sensor, VGXY61_REG_OIF_ROI0_CTRL, - get_data_type_by_code(sensor->fmt.code), &ret); + cci_write(sensor->regmap, VGXY61_REG_FORMAT_CTRL, + get_bpp_by_code(sensor->fmt.code), &ret); + cci_write(sensor->regmap, VGXY61_REG_OIF_ROI0_CTRL, + get_data_type_by_code(sensor->fmt.code), &ret); - vgxy61_write_reg(sensor, VGXY61_REG_READOUT_CTRL, - sensor->current_mode->bin_mode, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_ROI0_START_H, crop->left, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_ROI0_END_H, - crop->left + crop->width - 1, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_ROI0_START_V, crop->top, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_ROI0_END_V, - crop->top + crop->height - 1, &ret); + cci_write(sensor->regmap, VGXY61_REG_READOUT_CTRL, + sensor->current_mode->bin_mode, &ret); + cci_write(sensor->regmap, VGXY61_REG_ROI0_START_H, crop->left, &ret); + cci_write(sensor->regmap, VGXY61_REG_ROI0_END_H, + crop->left + crop->width - 1, &ret); + cci_write(sensor->regmap, VGXY61_REG_ROI0_START_V, crop->top, &ret); + cci_write(sensor->regmap, VGXY61_REG_ROI0_END_V, + crop->top + crop->height - 1, &ret); if (ret) goto err_rpm_put; @@ -1194,8 +1107,8 @@ static int vgxy61_stream_enable(struct vgxy61_dev *sensor) if (ret) goto err_rpm_put; - ret = vgxy61_write_reg(sensor, VGXY61_REG_STREAMING, - VGXY61_STREAMING_REQ_START, NULL); + ret = cci_write(sensor->regmap, VGXY61_REG_STREAMING, + VGXY61_STREAMING_REQ_START, NULL); if (ret) goto err_rpm_put; @@ -1225,8 +1138,8 @@ static int vgxy61_stream_disable(struct vgxy61_dev *sensor) struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); int ret; - ret = vgxy61_write_reg(sensor, VGXY61_REG_STREAMING, - VGXY61_STREAMING_REQ_STOP, NULL); + ret = cci_write(sensor->regmap, VGXY61_REG_STREAMING, + VGXY61_STREAMING_REQ_STOP, NULL); if (ret) goto err_str_dis; @@ -1582,7 +1495,7 @@ static int vgxy61_configure(struct vgxy61_dev *sensor) { u32 sensor_freq; u8 prediv, mult; - int line_length; + u64 line_length; int ret = 0; compute_pll_parameters_by_freq(sensor->clk_freq, &prediv, &mult); @@ -1592,28 +1505,28 @@ static int vgxy61_configure(struct vgxy61_dev *sensor) /* Video timing ISP path (pixel clock) requires 804/5 mhz = 160 mhz */ sensor->pclk = sensor_freq / 5; - line_length = vgxy61_read_reg(sensor, VGXY61_REG_LINE_LENGTH); - if (line_length < 0) - return line_length; - sensor->line_length = line_length; - vgxy61_write_reg(sensor, VGXY61_REG_EXT_CLOCK, sensor->clk_freq, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_CLK_PLL_PREDIV, prediv, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_CLK_SYS_PLL_MULT, mult, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_OIF_CTRL, sensor->oif_ctrl, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_FRAME_CONTENT_CTRL, 0, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_BYPASS_CTRL, 4, &ret); + cci_read(sensor->regmap, VGXY61_REG_LINE_LENGTH, &line_length, &ret); + if (ret < 0) + return ret; + sensor->line_length = (u16)line_length; + cci_write(sensor->regmap, VGXY61_REG_EXT_CLOCK, sensor->clk_freq, &ret); + cci_write(sensor->regmap, VGXY61_REG_CLK_PLL_PREDIV, prediv, &ret); + cci_write(sensor->regmap, VGXY61_REG_CLK_SYS_PLL_MULT, mult, &ret); + cci_write(sensor->regmap, VGXY61_REG_OIF_CTRL, sensor->oif_ctrl, &ret); + cci_write(sensor->regmap, VGXY61_REG_FRAME_CONTENT_CTRL, 0, &ret); + cci_write(sensor->regmap, VGXY61_REG_BYPASS_CTRL, 4, &ret); if (ret) return ret; vgxy61_update_gpios_strobe_polarity(sensor, sensor->gpios_polarity); /* Set pattern generator solid to middle value */ - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_GR, 0x800, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_R, 0x800, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_B, 0x800, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_GB, 0x800, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_GR, 0x800, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_R, 0x800, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_B, 0x800, &ret); - vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_GB, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_GR, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_R, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_B, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_GB, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_GR, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_R, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_B, 0x800, &ret); + cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_GB, 0x800, &ret); if (ret) return ret; @@ -1623,37 +1536,33 @@ static int vgxy61_configure(struct vgxy61_dev *sensor) static int vgxy61_patch(struct vgxy61_dev *sensor) { struct i2c_client *client = sensor->i2c_client; - int patch, ret; + u64 patch; + int ret; ret = vgxy61_write_array(sensor, VGXY61_REG_FWPATCH_START_ADDR, sizeof(patch_array), patch_array); - if (ret) - return ret; - - ret = vgxy61_write_reg(sensor, VGXY61_REG_STBY, 0x10, NULL); + cci_write(sensor->regmap, VGXY61_REG_STBY, 0x10, &ret); if (ret) return ret; ret = vgxy61_poll_reg(sensor, VGXY61_REG_STBY, 0, VGXY61_TIMEOUT_MS); - if (ret) + cci_read(sensor->regmap, VGXY61_REG_FWPATCH_REVISION, &patch, &ret); + if (ret < 0) return ret; - patch = vgxy61_read_reg(sensor, VGXY61_REG_FWPATCH_REVISION); - if (patch < 0) - return patch; - if (patch != (VGXY61_FWPATCH_REVISION_MAJOR << 12) + (VGXY61_FWPATCH_REVISION_MINOR << 8) + VGXY61_FWPATCH_REVISION_MICRO) { - dev_err(&client->dev, "bad patch version expected %d.%d.%d got %d.%d.%d\n", + dev_err(&client->dev, + "bad patch version expected %d.%d.%d got %u.%u.%u\n", VGXY61_FWPATCH_REVISION_MAJOR, VGXY61_FWPATCH_REVISION_MINOR, VGXY61_FWPATCH_REVISION_MICRO, - patch >> 12, (patch >> 8) & 0x0f, patch & 0xff); + (u16)patch >> 12, ((u16)patch >> 8) & 0x0f, (u16)patch & 0xff); return -ENODEV; } - dev_dbg(&client->dev, "patch %d.%d.%d applied\n", - patch >> 12, (patch >> 8) & 0x0f, patch & 0xff); + dev_dbg(&client->dev, "patch %u.%u.%u applied\n", + (u16)patch >> 12, ((u16)patch >> 8) & 0x0f, (u16)patch & 0xff); return 0; } @@ -1661,11 +1570,12 @@ static int vgxy61_patch(struct vgxy61_dev *sensor) static int vgxy61_detect_cut_version(struct vgxy61_dev *sensor) { struct i2c_client *client = sensor->i2c_client; - int device_rev; + u64 device_rev; + int ret; - device_rev = vgxy61_read_reg(sensor, VGXY61_REG_REVISION); - if (device_rev < 0) - return device_rev; + ret = cci_read(sensor->regmap, VGXY61_REG_REVISION, &device_rev, NULL); + if (ret < 0) + return ret; switch (device_rev >> 8) { case 0xA: @@ -1687,17 +1597,17 @@ static int vgxy61_detect_cut_version(struct vgxy61_dev *sensor) static int vgxy61_detect(struct vgxy61_dev *sensor) { struct i2c_client *client = sensor->i2c_client; - int id = 0; - int ret, st; + u64 st, id = 0; + int ret; - id = vgxy61_read_reg(sensor, VGXY61_REG_MODEL_ID); - if (id < 0) - return id; + ret = cci_read(sensor->regmap, VGXY61_REG_MODEL_ID, &id, NULL); + if (ret < 0) + return ret; if (id != VG5661_MODEL_ID && id != VG5761_MODEL_ID) { - dev_warn(&client->dev, "Unsupported sensor id %x\n", id); + dev_warn(&client->dev, "Unsupported sensor id %x\n", (u16)id); return -ENODEV; } - dev_dbg(&client->dev, "detected sensor id = 0x%04x\n", id); + dev_dbg(&client->dev, "detected sensor id = 0x%04x\n", (u16)id); sensor->id = id; ret = vgxy61_wait_state(sensor, VGXY61_SYSTEM_FSM_SW_STBY, @@ -1705,11 +1615,11 @@ static int vgxy61_detect(struct vgxy61_dev *sensor) if (ret) return ret; - st = vgxy61_read_reg(sensor, VGXY61_REG_NVM); - if (st < 0) + ret = cci_read(sensor->regmap, VGXY61_REG_NVM, &st, NULL); + if (ret < 0) return st; if (st != VGXY61_NVM_OK) - dev_warn(&client->dev, "Bad nvm state got %d\n", st); + dev_warn(&client->dev, "Bad nvm state got %u\n", (u8)st); ret = vgxy61_detect_cut_version(sensor); if (ret) @@ -1832,6 +1742,12 @@ static int vgxy61_probe(struct i2c_client *client) sensor->analog_gain = 0; sensor->digital_gain = 256; + sensor->regmap = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(sensor->regmap)) { + ret = PTR_ERR(sensor->regmap); + return dev_err_probe(dev, ret, "Failed to init regmap\n"); + } + handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0); if (!handle) { dev_err(dev, "handle node not found\n"); From 58ab1f9e140006e9e5686640f1773260038fe889 Mon Sep 17 00:00:00 2001 From: Julien Massot Date: Thu, 11 Jan 2024 14:20:03 +0100 Subject: [PATCH 094/252] media: v4l2: cci: print leading 0 on error In some error cases leading '0' for register address were missing. Fixes: 613cbb91e9ce ("media: Add MIPI CCI register access helper functions") Signed-off-by: Julien Massot Reviewed-by: Hans de Goede Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-cci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c index 10005c80f43b..ee3475bed37f 100644 --- a/drivers/media/v4l2-core/v4l2-cci.c +++ b/drivers/media/v4l2-core/v4l2-cci.c @@ -32,7 +32,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err) ret = regmap_bulk_read(map, reg, buf, len); if (ret) { - dev_err(regmap_get_device(map), "Error reading reg 0x%4x: %d\n", + dev_err(regmap_get_device(map), "Error reading reg 0x%04x: %d\n", reg, ret); goto out; } @@ -131,7 +131,7 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err) ret = regmap_bulk_write(map, reg, buf, len); if (ret) - dev_err(regmap_get_device(map), "Error writing reg 0x%4x: %d\n", + dev_err(regmap_get_device(map), "Error writing reg 0x%04x: %d\n", reg, ret); out: From d5df1c7f3f83f7a440f9a73d97f02f33a351ea9e Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 17 Jan 2024 08:39:35 +0100 Subject: [PATCH 095/252] media: i2c: imx415: Convert to new CCI register access helpers Use the new common CCI register access helpers to replace the private register access helpers in the imx415 driver. Signed-off-by: Alexander Stein Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/imx415.c | 407 +++++++++++++++---------------------- 2 files changed, 170 insertions(+), 238 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 9d9b52d93131..56f276b920ab 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -224,6 +224,7 @@ config VIDEO_IMX412 config VIDEO_IMX415 tristate "Sony IMX415 sensor support" depends on OF_GPIO + select V4L2_CCI_I2C help This is a Video4Linux2 sensor driver for the Sony IMX415 camera. diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c index 1e5f20c3ed82..e52437fb5087 100644 --- a/drivers/media/i2c/imx415.c +++ b/drivers/media/i2c/imx415.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -28,76 +29,65 @@ #define IMX415_NUM_CLK_PARAM_REGS 11 -#define IMX415_REG_8BIT(n) ((1 << 16) | (n)) -#define IMX415_REG_16BIT(n) ((2 << 16) | (n)) -#define IMX415_REG_24BIT(n) ((3 << 16) | (n)) -#define IMX415_REG_SIZE_SHIFT 16 -#define IMX415_REG_ADDR_MASK 0xffff - -#define IMX415_MODE IMX415_REG_8BIT(0x3000) +#define IMX415_MODE CCI_REG8(0x3000) #define IMX415_MODE_OPERATING (0) #define IMX415_MODE_STANDBY BIT(0) -#define IMX415_REGHOLD IMX415_REG_8BIT(0x3001) +#define IMX415_REGHOLD CCI_REG8(0x3001) #define IMX415_REGHOLD_INVALID (0) #define IMX415_REGHOLD_VALID BIT(0) -#define IMX415_XMSTA IMX415_REG_8BIT(0x3002) +#define IMX415_XMSTA CCI_REG8(0x3002) #define IMX415_XMSTA_START (0) #define IMX415_XMSTA_STOP BIT(0) -#define IMX415_BCWAIT_TIME IMX415_REG_16BIT(0x3008) -#define IMX415_CPWAIT_TIME IMX415_REG_16BIT(0x300A) -#define IMX415_WINMODE IMX415_REG_8BIT(0x301C) -#define IMX415_ADDMODE IMX415_REG_8BIT(0x3022) -#define IMX415_REVERSE IMX415_REG_8BIT(0x3030) +#define IMX415_BCWAIT_TIME CCI_REG16_LE(0x3008) +#define IMX415_CPWAIT_TIME CCI_REG16_LE(0x300a) +#define IMX415_WINMODE CCI_REG8(0x301c) +#define IMX415_ADDMODE CCI_REG8(0x3022) +#define IMX415_REVERSE CCI_REG8(0x3030) #define IMX415_HREVERSE_SHIFT (0) #define IMX415_VREVERSE_SHIFT BIT(0) -#define IMX415_ADBIT IMX415_REG_8BIT(0x3031) -#define IMX415_MDBIT IMX415_REG_8BIT(0x3032) -#define IMX415_SYS_MODE IMX415_REG_8BIT(0x3033) -#define IMX415_OUTSEL IMX415_REG_8BIT(0x30C0) -#define IMX415_DRV IMX415_REG_8BIT(0x30C1) -#define IMX415_VMAX IMX415_REG_24BIT(0x3024) -#define IMX415_HMAX IMX415_REG_16BIT(0x3028) -#define IMX415_SHR0 IMX415_REG_24BIT(0x3050) -#define IMX415_GAIN_PCG_0 IMX415_REG_16BIT(0x3090) +#define IMX415_ADBIT CCI_REG8(0x3031) +#define IMX415_MDBIT CCI_REG8(0x3032) +#define IMX415_SYS_MODE CCI_REG8(0x3033) +#define IMX415_OUTSEL CCI_REG8(0x30c0) +#define IMX415_DRV CCI_REG8(0x30c1) +#define IMX415_VMAX CCI_REG24_LE(0x3024) +#define IMX415_HMAX CCI_REG16_LE(0x3028) +#define IMX415_SHR0 CCI_REG24_LE(0x3050) +#define IMX415_GAIN_PCG_0 CCI_REG16_LE(0x3090) #define IMX415_AGAIN_MIN 0 #define IMX415_AGAIN_MAX 100 #define IMX415_AGAIN_STEP 1 -#define IMX415_BLKLEVEL IMX415_REG_16BIT(0x30E2) +#define IMX415_BLKLEVEL CCI_REG16_LE(0x30e2) #define IMX415_BLKLEVEL_DEFAULT 50 -#define IMX415_TPG_EN_DUOUT IMX415_REG_8BIT(0x30E4) -#define IMX415_TPG_PATSEL_DUOUT IMX415_REG_8BIT(0x30E6) -#define IMX415_TPG_COLORWIDTH IMX415_REG_8BIT(0x30E8) -#define IMX415_TESTCLKEN_MIPI IMX415_REG_8BIT(0x3110) -#define IMX415_INCKSEL1 IMX415_REG_8BIT(0x3115) -#define IMX415_INCKSEL2 IMX415_REG_8BIT(0x3116) -#define IMX415_INCKSEL3 IMX415_REG_16BIT(0x3118) -#define IMX415_INCKSEL4 IMX415_REG_16BIT(0x311A) -#define IMX415_INCKSEL5 IMX415_REG_8BIT(0x311E) -#define IMX415_DIG_CLP_MODE IMX415_REG_8BIT(0x32C8) -#define IMX415_WRJ_OPEN IMX415_REG_8BIT(0x3390) -#define IMX415_SENSOR_INFO IMX415_REG_16BIT(0x3F12) -#define IMX415_SENSOR_INFO_MASK 0xFFF +#define IMX415_TPG_EN_DUOUT CCI_REG8(0x30e4) +#define IMX415_TPG_PATSEL_DUOUT CCI_REG8(0x30e6) +#define IMX415_TPG_COLORWIDTH CCI_REG8(0x30e8) +#define IMX415_TESTCLKEN_MIPI CCI_REG8(0x3110) +#define IMX415_INCKSEL1 CCI_REG8(0x3115) +#define IMX415_INCKSEL2 CCI_REG8(0x3116) +#define IMX415_INCKSEL3 CCI_REG16_LE(0x3118) +#define IMX415_INCKSEL4 CCI_REG16_LE(0x311a) +#define IMX415_INCKSEL5 CCI_REG8(0x311e) +#define IMX415_DIG_CLP_MODE CCI_REG8(0x32c8) +#define IMX415_WRJ_OPEN CCI_REG8(0x3390) +#define IMX415_SENSOR_INFO CCI_REG16_LE(0x3f12) +#define IMX415_SENSOR_INFO_MASK 0xfff #define IMX415_CHIP_ID 0x514 -#define IMX415_LANEMODE IMX415_REG_16BIT(0x4001) +#define IMX415_LANEMODE CCI_REG16_LE(0x4001) #define IMX415_LANEMODE_2 1 #define IMX415_LANEMODE_4 3 -#define IMX415_TXCLKESC_FREQ IMX415_REG_16BIT(0x4004) -#define IMX415_INCKSEL6 IMX415_REG_8BIT(0x400C) -#define IMX415_TCLKPOST IMX415_REG_16BIT(0x4018) -#define IMX415_TCLKPREPARE IMX415_REG_16BIT(0x401A) -#define IMX415_TCLKTRAIL IMX415_REG_16BIT(0x401C) -#define IMX415_TCLKZERO IMX415_REG_16BIT(0x401E) -#define IMX415_THSPREPARE IMX415_REG_16BIT(0x4020) -#define IMX415_THSZERO IMX415_REG_16BIT(0x4022) -#define IMX415_THSTRAIL IMX415_REG_16BIT(0x4024) -#define IMX415_THSEXIT IMX415_REG_16BIT(0x4026) -#define IMX415_TLPX IMX415_REG_16BIT(0x4028) -#define IMX415_INCKSEL7 IMX415_REG_8BIT(0x4074) - -struct imx415_reg { - u32 address; - u32 val; -}; +#define IMX415_TXCLKESC_FREQ CCI_REG16_LE(0x4004) +#define IMX415_INCKSEL6 CCI_REG8(0x400c) +#define IMX415_TCLKPOST CCI_REG16_LE(0x4018) +#define IMX415_TCLKPREPARE CCI_REG16_LE(0x401a) +#define IMX415_TCLKTRAIL CCI_REG16_LE(0x401c) +#define IMX415_TCLKZERO CCI_REG16_LE(0x401e) +#define IMX415_THSPREPARE CCI_REG16_LE(0x4020) +#define IMX415_THSZERO CCI_REG16_LE(0x4022) +#define IMX415_THSTRAIL CCI_REG16_LE(0x4024) +#define IMX415_THSEXIT CCI_REG16_LE(0x4026) +#define IMX415_TLPX CCI_REG16_LE(0x4028) +#define IMX415_INCKSEL7 CCI_REG8(0x4074) static const char *const imx415_supply_names[] = { "dvdd", @@ -118,7 +108,7 @@ static const s64 link_freq_menu_items[] = { struct imx415_clk_params { u64 lane_rate; u64 inck; - struct imx415_reg regs[IMX415_NUM_CLK_PARAM_REGS]; + struct cci_reg_sequence regs[IMX415_NUM_CLK_PARAM_REGS]; }; /* INCK Settings - includes all lane rate and INCK dependent registers */ @@ -201,7 +191,7 @@ static const struct imx415_clk_params imx415_clk_params[] = { }; /* all-pixel 2-lane 720 Mbps 15.74 Hz mode */ -static const struct imx415_reg imx415_mode_2_720[] = { +static const struct cci_reg_sequence imx415_mode_2_720[] = { { IMX415_VMAX, 0x08CA }, { IMX415_HMAX, 0x07F0 }, { IMX415_LANEMODE, IMX415_LANEMODE_2 }, @@ -217,7 +207,7 @@ static const struct imx415_reg imx415_mode_2_720[] = { }; /* all-pixel 2-lane 1440 Mbps 30.01 Hz mode */ -static const struct imx415_reg imx415_mode_2_1440[] = { +static const struct cci_reg_sequence imx415_mode_2_1440[] = { { IMX415_VMAX, 0x08CA }, { IMX415_HMAX, 0x042A }, { IMX415_LANEMODE, IMX415_LANEMODE_2 }, @@ -233,7 +223,7 @@ static const struct imx415_reg imx415_mode_2_1440[] = { }; /* all-pixel 4-lane 891 Mbps 30 Hz mode */ -static const struct imx415_reg imx415_mode_4_891[] = { +static const struct cci_reg_sequence imx415_mode_4_891[] = { { IMX415_VMAX, 0x08CA }, { IMX415_HMAX, 0x044C }, { IMX415_LANEMODE, IMX415_LANEMODE_4 }, @@ -250,7 +240,7 @@ static const struct imx415_reg imx415_mode_4_891[] = { struct imx415_mode_reg_list { u32 num_of_regs; - const struct imx415_reg *regs; + const struct cci_reg_sequence *regs; }; /* @@ -323,11 +313,6 @@ static const struct imx415_mode supported_modes[] = { }, }; -static const struct regmap_config imx415_regmap_config = { - .reg_bits = 16, - .val_bits = 8, -}; - static const char *const imx415_test_pattern_menu[] = { "disabled", "solid black", @@ -369,7 +354,7 @@ struct imx415 { * This table includes fixed register settings and a bunch of undocumented * registers that have to be set to another value than default. */ -static const struct imx415_reg imx415_init_table[] = { +static const struct cci_reg_sequence imx415_init_table[] = { /* use all-pixel readout mode, no flip */ { IMX415_WINMODE, 0x00 }, { IMX415_ADDMODE, 0x00 }, @@ -382,77 +367,77 @@ static const struct imx415_reg imx415_init_table[] = { { IMX415_DRV, 0x00 }, /* SONY magic registers */ - { IMX415_REG_8BIT(0x32D4), 0x21 }, - { IMX415_REG_8BIT(0x32EC), 0xA1 }, - { IMX415_REG_8BIT(0x3452), 0x7F }, - { IMX415_REG_8BIT(0x3453), 0x03 }, - { IMX415_REG_8BIT(0x358A), 0x04 }, - { IMX415_REG_8BIT(0x35A1), 0x02 }, - { IMX415_REG_8BIT(0x36BC), 0x0C }, - { IMX415_REG_8BIT(0x36CC), 0x53 }, - { IMX415_REG_8BIT(0x36CD), 0x00 }, - { IMX415_REG_8BIT(0x36CE), 0x3C }, - { IMX415_REG_8BIT(0x36D0), 0x8C }, - { IMX415_REG_8BIT(0x36D1), 0x00 }, - { IMX415_REG_8BIT(0x36D2), 0x71 }, - { IMX415_REG_8BIT(0x36D4), 0x3C }, - { IMX415_REG_8BIT(0x36D6), 0x53 }, - { IMX415_REG_8BIT(0x36D7), 0x00 }, - { IMX415_REG_8BIT(0x36D8), 0x71 }, - { IMX415_REG_8BIT(0x36DA), 0x8C }, - { IMX415_REG_8BIT(0x36DB), 0x00 }, - { IMX415_REG_8BIT(0x3724), 0x02 }, - { IMX415_REG_8BIT(0x3726), 0x02 }, - { IMX415_REG_8BIT(0x3732), 0x02 }, - { IMX415_REG_8BIT(0x3734), 0x03 }, - { IMX415_REG_8BIT(0x3736), 0x03 }, - { IMX415_REG_8BIT(0x3742), 0x03 }, - { IMX415_REG_8BIT(0x3862), 0xE0 }, - { IMX415_REG_8BIT(0x38CC), 0x30 }, - { IMX415_REG_8BIT(0x38CD), 0x2F }, - { IMX415_REG_8BIT(0x395C), 0x0C }, - { IMX415_REG_8BIT(0x3A42), 0xD1 }, - { IMX415_REG_8BIT(0x3A4C), 0x77 }, - { IMX415_REG_8BIT(0x3AE0), 0x02 }, - { IMX415_REG_8BIT(0x3AEC), 0x0C }, - { IMX415_REG_8BIT(0x3B00), 0x2E }, - { IMX415_REG_8BIT(0x3B06), 0x29 }, - { IMX415_REG_8BIT(0x3B98), 0x25 }, - { IMX415_REG_8BIT(0x3B99), 0x21 }, - { IMX415_REG_8BIT(0x3B9B), 0x13 }, - { IMX415_REG_8BIT(0x3B9C), 0x13 }, - { IMX415_REG_8BIT(0x3B9D), 0x13 }, - { IMX415_REG_8BIT(0x3B9E), 0x13 }, - { IMX415_REG_8BIT(0x3BA1), 0x00 }, - { IMX415_REG_8BIT(0x3BA2), 0x06 }, - { IMX415_REG_8BIT(0x3BA3), 0x0B }, - { IMX415_REG_8BIT(0x3BA4), 0x10 }, - { IMX415_REG_8BIT(0x3BA5), 0x14 }, - { IMX415_REG_8BIT(0x3BA6), 0x18 }, - { IMX415_REG_8BIT(0x3BA7), 0x1A }, - { IMX415_REG_8BIT(0x3BA8), 0x1A }, - { IMX415_REG_8BIT(0x3BA9), 0x1A }, - { IMX415_REG_8BIT(0x3BAC), 0xED }, - { IMX415_REG_8BIT(0x3BAD), 0x01 }, - { IMX415_REG_8BIT(0x3BAE), 0xF6 }, - { IMX415_REG_8BIT(0x3BAF), 0x02 }, - { IMX415_REG_8BIT(0x3BB0), 0xA2 }, - { IMX415_REG_8BIT(0x3BB1), 0x03 }, - { IMX415_REG_8BIT(0x3BB2), 0xE0 }, - { IMX415_REG_8BIT(0x3BB3), 0x03 }, - { IMX415_REG_8BIT(0x3BB4), 0xE0 }, - { IMX415_REG_8BIT(0x3BB5), 0x03 }, - { IMX415_REG_8BIT(0x3BB6), 0xE0 }, - { IMX415_REG_8BIT(0x3BB7), 0x03 }, - { IMX415_REG_8BIT(0x3BB8), 0xE0 }, - { IMX415_REG_8BIT(0x3BBA), 0xE0 }, - { IMX415_REG_8BIT(0x3BBC), 0xDA }, - { IMX415_REG_8BIT(0x3BBE), 0x88 }, - { IMX415_REG_8BIT(0x3BC0), 0x44 }, - { IMX415_REG_8BIT(0x3BC2), 0x7B }, - { IMX415_REG_8BIT(0x3BC4), 0xA2 }, - { IMX415_REG_8BIT(0x3BC8), 0xBD }, - { IMX415_REG_8BIT(0x3BCA), 0xBD }, + { CCI_REG8(0x32D4), 0x21 }, + { CCI_REG8(0x32EC), 0xA1 }, + { CCI_REG8(0x3452), 0x7F }, + { CCI_REG8(0x3453), 0x03 }, + { CCI_REG8(0x358A), 0x04 }, + { CCI_REG8(0x35A1), 0x02 }, + { CCI_REG8(0x36BC), 0x0C }, + { CCI_REG8(0x36CC), 0x53 }, + { CCI_REG8(0x36CD), 0x00 }, + { CCI_REG8(0x36CE), 0x3C }, + { CCI_REG8(0x36D0), 0x8C }, + { CCI_REG8(0x36D1), 0x00 }, + { CCI_REG8(0x36D2), 0x71 }, + { CCI_REG8(0x36D4), 0x3C }, + { CCI_REG8(0x36D6), 0x53 }, + { CCI_REG8(0x36D7), 0x00 }, + { CCI_REG8(0x36D8), 0x71 }, + { CCI_REG8(0x36DA), 0x8C }, + { CCI_REG8(0x36DB), 0x00 }, + { CCI_REG8(0x3724), 0x02 }, + { CCI_REG8(0x3726), 0x02 }, + { CCI_REG8(0x3732), 0x02 }, + { CCI_REG8(0x3734), 0x03 }, + { CCI_REG8(0x3736), 0x03 }, + { CCI_REG8(0x3742), 0x03 }, + { CCI_REG8(0x3862), 0xE0 }, + { CCI_REG8(0x38CC), 0x30 }, + { CCI_REG8(0x38CD), 0x2F }, + { CCI_REG8(0x395C), 0x0C }, + { CCI_REG8(0x3A42), 0xD1 }, + { CCI_REG8(0x3A4C), 0x77 }, + { CCI_REG8(0x3AE0), 0x02 }, + { CCI_REG8(0x3AEC), 0x0C }, + { CCI_REG8(0x3B00), 0x2E }, + { CCI_REG8(0x3B06), 0x29 }, + { CCI_REG8(0x3B98), 0x25 }, + { CCI_REG8(0x3B99), 0x21 }, + { CCI_REG8(0x3B9B), 0x13 }, + { CCI_REG8(0x3B9C), 0x13 }, + { CCI_REG8(0x3B9D), 0x13 }, + { CCI_REG8(0x3B9E), 0x13 }, + { CCI_REG8(0x3BA1), 0x00 }, + { CCI_REG8(0x3BA2), 0x06 }, + { CCI_REG8(0x3BA3), 0x0B }, + { CCI_REG8(0x3BA4), 0x10 }, + { CCI_REG8(0x3BA5), 0x14 }, + { CCI_REG8(0x3BA6), 0x18 }, + { CCI_REG8(0x3BA7), 0x1A }, + { CCI_REG8(0x3BA8), 0x1A }, + { CCI_REG8(0x3BA9), 0x1A }, + { CCI_REG8(0x3BAC), 0xED }, + { CCI_REG8(0x3BAD), 0x01 }, + { CCI_REG8(0x3BAE), 0xF6 }, + { CCI_REG8(0x3BAF), 0x02 }, + { CCI_REG8(0x3BB0), 0xA2 }, + { CCI_REG8(0x3BB1), 0x03 }, + { CCI_REG8(0x3BB2), 0xE0 }, + { CCI_REG8(0x3BB3), 0x03 }, + { CCI_REG8(0x3BB4), 0xE0 }, + { CCI_REG8(0x3BB5), 0x03 }, + { CCI_REG8(0x3BB6), 0xE0 }, + { CCI_REG8(0x3BB7), 0x03 }, + { CCI_REG8(0x3BB8), 0xE0 }, + { CCI_REG8(0x3BBA), 0xE0 }, + { CCI_REG8(0x3BBC), 0xDA }, + { CCI_REG8(0x3BBE), 0x88 }, + { CCI_REG8(0x3BC0), 0x44 }, + { CCI_REG8(0x3BC2), 0x7B }, + { CCI_REG8(0x3BC4), 0xA2 }, + { CCI_REG8(0x3BC8), 0xBD }, + { CCI_REG8(0x3BCA), 0xBD }, }; static inline struct imx415 *to_imx415(struct v4l2_subdev *sd) @@ -460,74 +445,26 @@ static inline struct imx415 *to_imx415(struct v4l2_subdev *sd) return container_of(sd, struct imx415, subdev); } -static int imx415_read(struct imx415 *sensor, u32 addr) -{ - u8 data[3] = { 0 }; - int ret; - - ret = regmap_raw_read(sensor->regmap, addr & IMX415_REG_ADDR_MASK, data, - (addr >> IMX415_REG_SIZE_SHIFT) & 3); - if (ret < 0) - return ret; - - return (data[2] << 16) | (data[1] << 8) | data[0]; -} - -static int imx415_write(struct imx415 *sensor, u32 addr, u32 value) -{ - u8 data[3] = { value & 0xff, (value >> 8) & 0xff, value >> 16 }; - int ret; - - ret = regmap_raw_write(sensor->regmap, addr & IMX415_REG_ADDR_MASK, - data, (addr >> IMX415_REG_SIZE_SHIFT) & 3); - if (ret < 0) - dev_err_ratelimited(sensor->dev, - "%u-bit write to 0x%04x failed: %d\n", - ((addr >> IMX415_REG_SIZE_SHIFT) & 3) * 8, - addr & IMX415_REG_ADDR_MASK, ret); - - return 0; -} - static int imx415_set_testpattern(struct imx415 *sensor, int val) { - int ret; + int ret = 0; if (val) { - ret = imx415_write(sensor, IMX415_BLKLEVEL, 0x00); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_TPG_EN_DUOUT, 0x01); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_TPG_PATSEL_DUOUT, val - 1); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_TPG_COLORWIDTH, 0x01); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_TESTCLKEN_MIPI, 0x20); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_DIG_CLP_MODE, 0x00); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_WRJ_OPEN, 0x00); + cci_write(sensor->regmap, IMX415_BLKLEVEL, 0x00, &ret); + cci_write(sensor->regmap, IMX415_TPG_EN_DUOUT, 0x01, &ret); + cci_write(sensor->regmap, IMX415_TPG_PATSEL_DUOUT, + val - 1, &ret); + cci_write(sensor->regmap, IMX415_TPG_COLORWIDTH, 0x01, &ret); + cci_write(sensor->regmap, IMX415_TESTCLKEN_MIPI, 0x20, &ret); + cci_write(sensor->regmap, IMX415_DIG_CLP_MODE, 0x00, &ret); + cci_write(sensor->regmap, IMX415_WRJ_OPEN, 0x00, &ret); } else { - ret = imx415_write(sensor, IMX415_BLKLEVEL, - IMX415_BLKLEVEL_DEFAULT); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_TPG_EN_DUOUT, 0x00); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_TESTCLKEN_MIPI, 0x00); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_DIG_CLP_MODE, 0x01); - if (ret) - return ret; - ret = imx415_write(sensor, IMX415_WRJ_OPEN, 0x01); + cci_write(sensor->regmap, IMX415_BLKLEVEL, + IMX415_BLKLEVEL_DEFAULT, &ret); + cci_write(sensor->regmap, IMX415_TPG_EN_DUOUT, 0x00, &ret); + cci_write(sensor->regmap, IMX415_TESTCLKEN_MIPI, 0x00, &ret); + cci_write(sensor->regmap, IMX415_DIG_CLP_MODE, 0x01, &ret); + cci_write(sensor->regmap, IMX415_WRJ_OPEN, 0x01, &ret); } return 0; } @@ -553,19 +490,21 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl) /* clamp the exposure value to VMAX. */ vmax = format->height + sensor->vblank->cur.val; ctrl->val = min_t(int, ctrl->val, vmax); - ret = imx415_write(sensor, IMX415_SHR0, vmax - ctrl->val); + ret = cci_write(sensor->regmap, IMX415_SHR0, + vmax - ctrl->val, NULL); break; case V4L2_CID_ANALOGUE_GAIN: /* analogue gain in 0.3 dB step size */ - ret = imx415_write(sensor, IMX415_GAIN_PCG_0, ctrl->val); + ret = cci_write(sensor->regmap, IMX415_GAIN_PCG_0, + ctrl->val, NULL); break; case V4L2_CID_HFLIP: case V4L2_CID_VFLIP: flip = (sensor->hflip->val << IMX415_HREVERSE_SHIFT) | (sensor->vflip->val << IMX415_VREVERSE_SHIFT); - ret = imx415_write(sensor, IMX415_REVERSE, flip); + ret = cci_write(sensor->regmap, IMX415_REVERSE, flip, NULL); break; case V4L2_CID_TEST_PATTERN: @@ -679,8 +618,6 @@ static int imx415_ctrls_init(struct imx415 *sensor) static int imx415_set_mode(struct imx415 *sensor, int mode) { - const struct imx415_reg *reg; - unsigned int i; int ret = 0; if (mode >= ARRAY_SIZE(supported_modes)) { @@ -688,34 +625,29 @@ static int imx415_set_mode(struct imx415 *sensor, int mode) return -EINVAL; } - for (i = 0; i < supported_modes[mode].reg_list.num_of_regs; ++i) { - reg = &supported_modes[mode].reg_list.regs[i]; - ret = imx415_write(sensor, reg->address, reg->val); - if (ret) - return ret; - } + cci_multi_reg_write(sensor->regmap, + supported_modes[mode].reg_list.regs, + supported_modes[mode].reg_list.num_of_regs, + &ret); - for (i = 0; i < IMX415_NUM_CLK_PARAM_REGS; ++i) { - reg = &sensor->clk_params->regs[i]; - ret = imx415_write(sensor, reg->address, reg->val); - if (ret) - return ret; - } + cci_multi_reg_write(sensor->regmap, + sensor->clk_params->regs, + IMX415_NUM_CLK_PARAM_REGS, + &ret); return 0; } static int imx415_setup(struct imx415 *sensor, struct v4l2_subdev_state *state) { - unsigned int i; int ret; - for (i = 0; i < ARRAY_SIZE(imx415_init_table); ++i) { - ret = imx415_write(sensor, imx415_init_table[i].address, - imx415_init_table[i].val); - if (ret) - return ret; - } + ret = cci_multi_reg_write(sensor->regmap, + imx415_init_table, + ARRAY_SIZE(imx415_init_table), + NULL); + if (ret) + return ret; return imx415_set_mode(sensor, sensor->cur_mode); } @@ -724,7 +656,8 @@ static int imx415_wakeup(struct imx415 *sensor) { int ret; - ret = imx415_write(sensor, IMX415_MODE, IMX415_MODE_OPERATING); + ret = cci_write(sensor->regmap, IMX415_MODE, + IMX415_MODE_OPERATING, NULL); if (ret) return ret; @@ -743,21 +676,18 @@ static int imx415_stream_on(struct imx415 *sensor) int ret; ret = imx415_wakeup(sensor); - if (ret) - return ret; - - return imx415_write(sensor, IMX415_XMSTA, IMX415_XMSTA_START); + return cci_write(sensor->regmap, IMX415_XMSTA, + IMX415_XMSTA_START, &ret); } static int imx415_stream_off(struct imx415 *sensor) { int ret; - ret = imx415_write(sensor, IMX415_XMSTA, IMX415_XMSTA_STOP); - if (ret) - return ret; - - return imx415_write(sensor, IMX415_MODE, IMX415_MODE_STANDBY); + ret = cci_write(sensor->regmap, IMX415_XMSTA, + IMX415_XMSTA_STOP, NULL); + return cci_write(sensor->regmap, IMX415_MODE, + IMX415_MODE_STANDBY, &ret); } static int imx415_s_stream(struct v4l2_subdev *sd, int enable) @@ -992,6 +922,7 @@ static void imx415_power_off(struct imx415 *sensor) static int imx415_identify_model(struct imx415 *sensor) { int model, ret; + u64 chip_id; /* * While most registers can be read when the sensor is in standby, this @@ -1002,14 +933,14 @@ static int imx415_identify_model(struct imx415 *sensor) return dev_err_probe(sensor->dev, ret, "failed to get sensor out of standby\n"); - ret = imx415_read(sensor, IMX415_SENSOR_INFO); + ret = cci_read(sensor->regmap, IMX415_SENSOR_INFO, &chip_id, NULL); if (ret < 0) { dev_err_probe(sensor->dev, ret, "failed to read sensor information\n"); goto done; } - model = ret & IMX415_SENSOR_INFO_MASK; + model = chip_id & IMX415_SENSOR_INFO_MASK; switch (model) { case IMX415_CHIP_ID: @@ -1024,7 +955,7 @@ static int imx415_identify_model(struct imx415 *sensor) ret = 0; done: - imx415_write(sensor, IMX415_MODE, IMX415_MODE_STANDBY); + cci_write(sensor->regmap, IMX415_MODE, IMX415_MODE_STANDBY, &ret); return ret; } @@ -1173,7 +1104,7 @@ static int imx415_probe(struct i2c_client *client) if (ret) return ret; - sensor->regmap = devm_regmap_init_i2c(client, &imx415_regmap_config); + sensor->regmap = devm_cci_regmap_init_i2c(client, 16); if (IS_ERR(sensor->regmap)) return PTR_ERR(sensor->regmap); From b814b5b2ec2d327b79e415c1baa5eecdf9aa786b Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 17 Jan 2024 08:39:36 +0100 Subject: [PATCH 096/252] media: i2c: imx415: Add more clock configurations Complete the list from "INCK Setting" section in IMX415-AAQR-C (Rev. E19504, 2019/05/21). For consistency suffix all lane rate values by UL, which is needed for 2376000000 anyway. Signed-off-by: Alexander Stein Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx415.c | 265 ++++++++++++++++++++++++++++++++++++- 1 file changed, 260 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c index e52437fb5087..a20b0db330d3 100644 --- a/drivers/media/i2c/imx415.c +++ b/drivers/media/i2c/imx415.c @@ -114,7 +114,7 @@ struct imx415_clk_params { /* INCK Settings - includes all lane rate and INCK dependent registers */ static const struct imx415_clk_params imx415_clk_params[] = { { - .lane_rate = 594000000, + .lane_rate = 594000000UL, .inck = 27000000, .regs[0] = { IMX415_BCWAIT_TIME, 0x05D }, .regs[1] = { IMX415_CPWAIT_TIME, 0x042 }, @@ -129,7 +129,37 @@ static const struct imx415_clk_params imx415_clk_params[] = { .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 }, }, { - .lane_rate = 720000000, + .lane_rate = 594000000UL, + .inck = 37125000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x07F }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x05B }, + .regs[2] = { IMX415_SYS_MODE, 0x7 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x24 }, + .regs[5] = { IMX415_INCKSEL3, 0x080 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x24 }, + .regs[8] = { IMX415_INCKSEL6, 0x0 }, + .regs[9] = { IMX415_INCKSEL7, 0x1 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0984 }, + }, + { + .lane_rate = 594000000UL, + .inck = 74250000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 }, + .regs[2] = { IMX415_SYS_MODE, 0x7 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x080 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x0 }, + .regs[9] = { IMX415_INCKSEL7, 0x1 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 }, + }, + { + .lane_rate = 720000000UL, .inck = 24000000, .regs[0] = { IMX415_BCWAIT_TIME, 0x054 }, .regs[1] = { IMX415_CPWAIT_TIME, 0x03B }, @@ -144,7 +174,22 @@ static const struct imx415_clk_params imx415_clk_params[] = { .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0600 }, }, { - .lane_rate = 891000000, + .lane_rate = 720000000UL, + .inck = 72000000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0F8 }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B0 }, + .regs[2] = { IMX415_SYS_MODE, 0x9 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x0A0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x0 }, + .regs[9] = { IMX415_INCKSEL7, 0x1 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1200 }, + }, + { + .lane_rate = 891000000UL, .inck = 27000000, .regs[0] = { IMX415_BCWAIT_TIME, 0x05D }, .regs[1] = { IMX415_CPWAIT_TIME, 0x042 }, @@ -159,7 +204,37 @@ static const struct imx415_clk_params imx415_clk_params[] = { .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 }, }, { - .lane_rate = 1440000000, + .lane_rate = 891000000UL, + .inck = 37125000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x07F }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x05B }, + .regs[2] = { IMX415_SYS_MODE, 0x5 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x24 }, + .regs[5] = { IMX415_INCKSEL3, 0x0C0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x24 }, + .regs[8] = { IMX415_INCKSEL6, 0x0 }, + .regs[9] = { IMX415_INCKSEL7, 0x1 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 }, + }, + { + .lane_rate = 891000000UL, + .inck = 74250000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 }, + .regs[2] = { IMX415_SYS_MODE, 0x5 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x0C0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x0 }, + .regs[9] = { IMX415_INCKSEL7, 0x1 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 }, + }, + { + .lane_rate = 1440000000UL, .inck = 24000000, .regs[0] = { IMX415_BCWAIT_TIME, 0x054 }, .regs[1] = { IMX415_CPWAIT_TIME, 0x03B }, @@ -174,7 +249,22 @@ static const struct imx415_clk_params imx415_clk_params[] = { .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0600 }, }, { - .lane_rate = 1485000000, + .lane_rate = 1440000000UL, + .inck = 72000000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0F8 }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B0 }, + .regs[2] = { IMX415_SYS_MODE, 0x8 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x0A0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1200 }, + }, + { + .lane_rate = 1485000000UL, .inck = 27000000, .regs[0] = { IMX415_BCWAIT_TIME, 0x05D }, .regs[1] = { IMX415_CPWAIT_TIME, 0x042 }, @@ -188,6 +278,171 @@ static const struct imx415_clk_params imx415_clk_params[] = { .regs[9] = { IMX415_INCKSEL7, 0x0 }, .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 }, }, + { + .lane_rate = 1485000000UL, + .inck = 37125000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x07F }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x05B }, + .regs[2] = { IMX415_SYS_MODE, 0x8 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x24 }, + .regs[5] = { IMX415_INCKSEL3, 0x0A0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x24 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 }, + }, + { + .lane_rate = 1485000000UL, + .inck = 74250000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 }, + .regs[2] = { IMX415_SYS_MODE, 0x8 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x0A0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 }, + }, + { + .lane_rate = 1782000000UL, + .inck = 27000000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x05D }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x042 }, + .regs[2] = { IMX415_SYS_MODE, 0x4 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x23 }, + .regs[5] = { IMX415_INCKSEL3, 0x0C6 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E7 }, + .regs[7] = { IMX415_INCKSEL5, 0x23 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 }, + }, + { + .lane_rate = 1782000000UL, + .inck = 37125000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x07F }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x05B }, + .regs[2] = { IMX415_SYS_MODE, 0x4 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x24 }, + .regs[5] = { IMX415_INCKSEL3, 0x0C0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x24 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 }, + }, + { + .lane_rate = 1782000000UL, + .inck = 74250000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 }, + .regs[2] = { IMX415_SYS_MODE, 0x4 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x0C0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 }, + }, + { + .lane_rate = 2079000000UL, + .inck = 27000000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x05D }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x042 }, + .regs[2] = { IMX415_SYS_MODE, 0x2 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x23 }, + .regs[5] = { IMX415_INCKSEL3, 0x0E7 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E7 }, + .regs[7] = { IMX415_INCKSEL5, 0x23 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 }, + }, + { + .lane_rate = 2079000000UL, + .inck = 37125000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x07F }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x05B }, + .regs[2] = { IMX415_SYS_MODE, 0x2 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x24 }, + .regs[5] = { IMX415_INCKSEL3, 0x0E0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x24 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 }, + }, + { + .lane_rate = 2079000000UL, + .inck = 74250000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 }, + .regs[2] = { IMX415_SYS_MODE, 0x2 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x0E0 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 }, + }, + { + .lane_rate = 2376000000UL, + .inck = 27000000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x05D }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x042 }, + .regs[2] = { IMX415_SYS_MODE, 0x0 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x23 }, + .regs[5] = { IMX415_INCKSEL3, 0x108 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E7 }, + .regs[7] = { IMX415_INCKSEL5, 0x23 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 }, + }, + { + .lane_rate = 2376000000UL, + .inck = 37125000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x07F }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x05B }, + .regs[2] = { IMX415_SYS_MODE, 0x0 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x24 }, + .regs[5] = { IMX415_INCKSEL3, 0x100 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x24 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 }, + }, + { + .lane_rate = 2376000000UL, + .inck = 74250000, + .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF }, + .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 }, + .regs[2] = { IMX415_SYS_MODE, 0x0 }, + .regs[3] = { IMX415_INCKSEL1, 0x00 }, + .regs[4] = { IMX415_INCKSEL2, 0x28 }, + .regs[5] = { IMX415_INCKSEL3, 0x100 }, + .regs[6] = { IMX415_INCKSEL4, 0x0E0 }, + .regs[7] = { IMX415_INCKSEL5, 0x28 }, + .regs[8] = { IMX415_INCKSEL6, 0x1 }, + .regs[9] = { IMX415_INCKSEL7, 0x0 }, + .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 }, + }, }; /* all-pixel 2-lane 720 Mbps 15.74 Hz mode */ From 575dd95d24fb895d3f11372f74458fb083dad7f8 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 17 Jan 2024 04:07:30 +0100 Subject: [PATCH 097/252] media: i2c: imx214: convert to use maple tree register cache The maple tree register cache is based on a much more modern data structure than the rbtree cache and makes optimisation choices which are probably more appropriate for modern systems than those made by the rbtree cache. Signed-off-by: Bo Liu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx214.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index b148b1bd2bc3..10b6ad66d126 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -968,7 +968,7 @@ static const struct v4l2_subdev_internal_ops imx214_internal_ops = { static const struct regmap_config sensor_regmap_config = { .reg_bits = 16, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static int imx214_get_regulators(struct device *dev, struct imx214 *imx214) From 7591701bdc964b601ccf35797e57f2788a3ce1eb Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 17 Jan 2024 04:08:25 +0100 Subject: [PATCH 098/252] media: i2c: imx274: convert to use maple tree register cache The maple tree register cache is based on a much more modern data structure than the rbtree cache and makes optimisation choices which are probably more appropriate for modern systems than those made by the rbtree cache. Signed-off-by: Bo Liu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx274.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c index 352da68b8b41..3800de974e8a 100644 --- a/drivers/media/i2c/imx274.c +++ b/drivers/media/i2c/imx274.c @@ -151,7 +151,7 @@ struct reg_8 { static const struct regmap_config imx274_regmap_config = { .reg_bits = 16, .val_bits = 8, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; /* From a45e0e762459bf4212c094c085806c5a43988019 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 17 Jan 2024 04:11:05 +0100 Subject: [PATCH 099/252] media: i2c: mt9v032: convert to use maple tree register cache The maple tree register cache is based on a much more modern data structure than the rbtree cache and makes optimisation choices which are probably more appropriate for modern systems than those made by the rbtree cache. Signed-off-by: Bo Liu Reviewed-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9v032.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 3ca76eeae7ff..6dfbd1c56c22 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -988,7 +988,7 @@ static const struct regmap_config mt9v032_regmap_config = { .reg_bits = 8, .val_bits = 16, .max_register = 0xff, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; /* ----------------------------------------------------------------------------- From a48a824fbc032b8cc80a508b6d2bf925a39b7930 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 17 Jan 2024 04:11:34 +0100 Subject: [PATCH 100/252] media: i2c: tvp5150: convert to use maple tree register cache The maple tree register cache is based on a much more modern data structure than the rbtree cache and makes optimisation choices which are probably more appropriate for modern systems than those made by the rbtree cache. Signed-off-by: Bo Liu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 9fc586cfdcd8..64b91aa3c82a 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -1817,7 +1817,7 @@ static struct regmap_config tvp5150_config = { .val_bits = 8, .max_register = 0xff, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .rd_table = &tvp5150_readable_table, .volatile_reg = tvp5150_volatile_reg, From 7378c257db6ae3886c2b300cb62737660dd695a1 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 17 Jan 2024 04:10:24 +0100 Subject: [PATCH 101/252] media: i2c: max2175: convert to use maple tree register cache The maple tree register cache is based on a much more modern data structure than the rbtree cache and makes optimisation choices which are probably more appropriate for modern systems than those made by the rbtree cache. Signed-off-by: Bo Liu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max2175.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c index 70c2a2948fd4..cd73d2096ae4 100644 --- a/drivers/media/i2c/max2175.c +++ b/drivers/media/i2c/max2175.c @@ -257,7 +257,7 @@ static const struct regmap_config max2175_regmap_config = { .reg_defaults = max2175_reg_defaults, .num_reg_defaults = ARRAY_SIZE(max2175_reg_defaults), .volatile_table = &max2175_volatile_regs, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; struct max2175 { From 45db5c214c71419f4ec41300c3b6a1d5e62cb042 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 17 Jan 2024 04:09:10 +0100 Subject: [PATCH 102/252] media: i2c: isl7998x: convert to use maple tree register cache The maple tree register cache is based on a much more modern data structure than the rbtree cache and makes optimisation choices which are probably more appropriate for modern systems than those made by the rbtree cache. Signed-off-by: Bo Liu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/isl7998x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/isl7998x.c b/drivers/media/i2c/isl7998x.c index 89e13ebbce0c..c7089035bbc1 100644 --- a/drivers/media/i2c/isl7998x.c +++ b/drivers/media/i2c/isl7998x.c @@ -1337,7 +1337,7 @@ static const struct regmap_config isl7998x_regmap = { .rd_table = &isl7998x_readable_table, .wr_table = &isl7998x_writeable_table, .volatile_table = &isl7998x_volatile_table, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static int isl7998x_mc_init(struct isl7998x *isl7998x) From a68e88e2cf9e4f3bec1783d686beb2439f4a26e0 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 8 Jan 2024 16:18:02 +0100 Subject: [PATCH 103/252] media: v4l: Add a helper for setting up link-frequencies control Add a helper for obtaining supported link frequencies in form most drivers need them. The result is a bitmap of supported controls. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-common.c | 47 +++++++++++++++++++++++++++ include/media/v4l2-common.h | 25 ++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 273d83de2a87..d34d210908d9 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -585,3 +585,50 @@ u32 v4l2_fraction_to_interval(u32 numerator, u32 denominator) return denominator ? numerator * multiplier / denominator : 0; } EXPORT_SYMBOL_GPL(v4l2_fraction_to_interval); + +int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, + unsigned int num_of_fw_link_freqs, + const s64 *driver_link_freqs, + unsigned int num_of_driver_link_freqs, + unsigned long *bitmap) +{ + unsigned int i; + + *bitmap = 0; + + if (!num_of_fw_link_freqs) { + dev_err(dev, "no link frequencies in firmware\n"); + return -ENODATA; + } + + for (i = 0; i < num_of_fw_link_freqs; i++) { + unsigned int j; + + for (j = 0; j < num_of_driver_link_freqs; j++) { + if (fw_link_freqs[i] != driver_link_freqs[j]) + continue; + + dev_dbg(dev, "enabling link frequency %lld Hz\n", + driver_link_freqs[j]); + *bitmap |= BIT(j); + break; + } + } + + if (!*bitmap) { + dev_err(dev, "no matching link frequencies found\n"); + + dev_dbg(dev, "specified in firmware:\n"); + for (i = 0; i < num_of_fw_link_freqs; i++) + dev_dbg(dev, "\t%llu Hz\n", fw_link_freqs[i]); + + dev_dbg(dev, "driver supported:\n"); + for (i = 0; i < num_of_driver_link_freqs; i++) + dev_dbg(dev, "\t%lld Hz\n", driver_link_freqs[i]); + + return -ENOENT; + } + + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap); diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index acf5be24a5ca..cd2163f24f8a 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -547,6 +547,31 @@ void v4l2_simplify_fraction(u32 *numerator, u32 *denominator, unsigned int n_terms, unsigned int threshold); u32 v4l2_fraction_to_interval(u32 numerator, u32 denominator); +/** + * v4l2_link_freq_to_bitmap - Figure out platform-supported link frequencies + * @dev: The struct device + * @fw_link_freqs: Array of link frequencies from firmware + * @num_of_fw_link_freqs: Number of entries in @fw_link_freqs + * @driver_link_freqs: Array of link frequencies supported by the driver + * @num_of_driver_link_freqs: Number of entries in @driver_link_freqs + * @bitmap: Bitmap of driver-supported link frequencies found in @fw_link_freqs + * + * This function checks which driver-supported link frequencies are enabled in + * system firmware and sets the corresponding bits in @bitmap (after first + * zeroing it). + * + * Return values: + * 0: Success + * -ENOENT: No match found between driver-supported link frequencies and + * those available in firmware. + * -ENODATA: No link frequencies were specified in firmware. + */ +int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, + unsigned int num_of_fw_link_freqs, + const s64 *driver_link_freqs, + unsigned int num_of_driver_link_freqs, + unsigned long *bitmap); + static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf) { /* From afa6f62e46df5385e318a8f38382e8cc5564c377 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 8 Jan 2024 16:18:03 +0100 Subject: [PATCH 104/252] media: imx334: Use v4l2_link_freq_to_bitmap helper Use the v4l2_link_freq_to_bitmap() helper to figure out which driver-supported link frequencies can be used on a given system. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx334.c | 41 +++++++++++--------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c index 6725b3e2a73e..40863d87d341 100644 --- a/drivers/media/i2c/imx334.c +++ b/drivers/media/i2c/imx334.c @@ -136,7 +136,7 @@ struct imx334_mode { * @vblank: Vertical blanking in lines * @cur_mode: Pointer to current selected sensor mode * @mutex: Mutex for serializing sensor controls - * @menu_skip_mask: Menu skip mask for link_freq_ctrl + * @link_freq_bitmap: Menu bitmap for link_freq_ctrl * @cur_code: current selected format code */ struct imx334 { @@ -158,7 +158,7 @@ struct imx334 { u32 vblank; const struct imx334_mode *cur_mode; struct mutex mutex; - unsigned long menu_skip_mask; + unsigned long link_freq_bitmap; u32 cur_code; }; @@ -954,9 +954,9 @@ static int imx334_init_state(struct v4l2_subdev *sd, imx334_fill_pad_format(imx334, imx334->cur_mode, &fmt); __v4l2_ctrl_modify_range(imx334->link_freq_ctrl, 0, - __fls(imx334->menu_skip_mask), - ~(imx334->menu_skip_mask), - __ffs(imx334->menu_skip_mask)); + __fls(imx334->link_freq_bitmap), + ~(imx334->link_freq_bitmap), + __ffs(imx334->link_freq_bitmap)); mutex_unlock(&imx334->mutex); @@ -1112,7 +1112,6 @@ static int imx334_parse_hw_config(struct imx334 *imx334) }; struct fwnode_handle *ep; unsigned long rate; - unsigned int i, j; int ret; if (!fwnode) @@ -1157,26 +1156,10 @@ static int imx334_parse_hw_config(struct imx334 *imx334) goto done_endpoint_free; } - if (!bus_cfg.nr_of_link_frequencies) { - dev_err(imx334->dev, "no link frequencies defined"); - ret = -EINVAL; - goto done_endpoint_free; - } - - for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { - for (j = 0; j < ARRAY_SIZE(link_freq); j++) { - if (bus_cfg.link_frequencies[i] == link_freq[j]) { - set_bit(j, &imx334->menu_skip_mask); - break; - } - } - - if (j == ARRAY_SIZE(link_freq)) { - ret = dev_err_probe(imx334->dev, -EINVAL, - "no supported link freq found\n"); - goto done_endpoint_free; - } - } + ret = v4l2_link_freq_to_bitmap(imx334->dev, bus_cfg.link_frequencies, + bus_cfg.nr_of_link_frequencies, + link_freq, ARRAY_SIZE(link_freq), + &imx334->link_freq_bitmap); done_endpoint_free: v4l2_fwnode_endpoint_free(&bus_cfg); @@ -1310,8 +1293,8 @@ static int imx334_init_controls(struct imx334 *imx334) imx334->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx334_ctrl_ops, V4L2_CID_LINK_FREQ, - __fls(imx334->menu_skip_mask), - __ffs(imx334->menu_skip_mask), + __fls(imx334->link_freq_bitmap), + __ffs(imx334->link_freq_bitmap), link_freq); if (imx334->link_freq_ctrl) @@ -1386,7 +1369,7 @@ static int imx334_probe(struct i2c_client *client) } /* Set default mode to max resolution */ - imx334->cur_mode = &supported_modes[__ffs(imx334->menu_skip_mask)]; + imx334->cur_mode = &supported_modes[__ffs(imx334->link_freq_bitmap)]; imx334->cur_code = imx334_mbus_codes[0]; imx334->vblank = imx334->cur_mode->vblank; From 726a09c1b6890887b7388745a26c8e93867780ca Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 8 Jan 2024 16:18:04 +0100 Subject: [PATCH 105/252] media: imx319: Use v4l2_link_freq_to_bitmap helper Use the v4l2_link_freq_to_bitmap() helper to figure out which driver-supported link freq can be used on a given system. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx319.c | 53 ++++++++++---------------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index e47eff672e0c..8fe3933f3146 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -70,7 +70,7 @@ #define IMX319_REG_ORIENTATION 0x0101 /* default link frequency and external clock */ -#define IMX319_LINK_FREQ_DEFAULT 482400000 +#define IMX319_LINK_FREQ_DEFAULT 482400000LL #define IMX319_EXT_CLK 19200000 #define IMX319_LINK_FREQ_INDEX 0 @@ -107,8 +107,7 @@ struct imx319_mode { struct imx319_hwcfg { u32 ext_clk; /* sensor external clk */ - s64 *link_freqs; /* CSI-2 link frequencies */ - unsigned int nr_of_link_freqs; + unsigned long link_freq_bitmap; }; struct imx319 { @@ -129,7 +128,6 @@ struct imx319 { const struct imx319_mode *cur_mode; struct imx319_hwcfg *hwcfg; - s64 link_def_freq; /* CSI-2 link default frequency */ /* * Mutex for serialized access: @@ -1654,7 +1652,10 @@ static const char * const imx319_test_pattern_menu[] = { "Pseudorandom Sequence (PN9)", }; -/* supported link frequencies */ +/* + * When adding more than the one below, make sure the disallowed ones will + * actually be disabled in the LINK_FREQ control. + */ static const s64 link_freq_menu_items[] = { IMX319_LINK_FREQ_DEFAULT, }; @@ -2058,7 +2059,7 @@ imx319_set_pad_format(struct v4l2_subdev *sd, *framefmt = fmt->format; } else { imx319->cur_mode = mode; - pixel_rate = imx319->link_def_freq * 2 * 4; + pixel_rate = IMX319_LINK_FREQ_DEFAULT * 2 * 4; do_div(pixel_rate, 10); __v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate); /* Update limits and set FPS to default */ @@ -2255,7 +2256,7 @@ static int imx319_init_controls(struct imx319 *imx319) imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ - pixel_rate = imx319->link_def_freq * 2 * 4; + pixel_rate = IMX319_LINK_FREQ_DEFAULT * 2 * 4; do_div(pixel_rate, 10); /* By default, PIXEL_RATE is read only */ imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops, @@ -2332,7 +2333,6 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev) }; struct fwnode_handle *ep; struct fwnode_handle *fwnode = dev_fwnode(dev); - unsigned int i; int ret; if (!fwnode) @@ -2364,23 +2364,13 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev) goto out_err; } - dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies); - if (!bus_cfg.nr_of_link_frequencies) { - dev_warn(dev, "no link frequencies defined"); + ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies, + bus_cfg.nr_of_link_frequencies, + link_freq_menu_items, + ARRAY_SIZE(link_freq_menu_items), + &cfg->link_freq_bitmap); + if (ret) goto out_err; - } - - cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies; - cfg->link_freqs = devm_kcalloc(dev, - bus_cfg.nr_of_link_frequencies + 1, - sizeof(*cfg->link_freqs), GFP_KERNEL); - if (!cfg->link_freqs) - goto out_err; - - for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { - cfg->link_freqs[i] = bus_cfg.link_frequencies[i]; - dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]); - } v4l2_fwnode_endpoint_free(&bus_cfg); fwnode_handle_put(ep); @@ -2397,7 +2387,6 @@ static int imx319_probe(struct i2c_client *client) struct imx319 *imx319; bool full_power; int ret; - u32 i; imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL); if (!imx319) @@ -2425,20 +2414,6 @@ static int imx319_probe(struct i2c_client *client) goto error_probe; } - imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX]; - for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) { - if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) { - dev_dbg(&client->dev, "link freq index %d matched", i); - break; - } - } - - if (i == imx319->hwcfg->nr_of_link_freqs) { - dev_err(&client->dev, "no link frequency supported"); - ret = -EINVAL; - goto error_probe; - } - /* Set default mode to max resolution */ imx319->cur_mode = &supported_modes[0]; From f19cd265662df9bd6415bb71a23124486e85b117 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 8 Jan 2024 16:18:05 +0100 Subject: [PATCH 106/252] media: imx355: Use v4l2_link_freq_to_bitmap helper Use the v4l2_link_freq_to_bitmap() helper to figure out which driver-supported link freq can be used on a given system. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx355.c | 53 ++++++++++---------------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index 8c995c58743a..7e9c2f65fa08 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -56,7 +56,7 @@ #define IMX355_REG_ORIENTATION 0x0101 /* default link frequency and external clock */ -#define IMX355_LINK_FREQ_DEFAULT 360000000 +#define IMX355_LINK_FREQ_DEFAULT 360000000LL #define IMX355_EXT_CLK 19200000 #define IMX355_LINK_FREQ_INDEX 0 @@ -93,8 +93,7 @@ struct imx355_mode { struct imx355_hwcfg { u32 ext_clk; /* sensor external clk */ - s64 *link_freqs; /* CSI-2 link frequencies */ - unsigned int nr_of_link_freqs; + unsigned long link_freq_bitmap; }; struct imx355 { @@ -115,7 +114,6 @@ struct imx355 { const struct imx355_mode *cur_mode; struct imx355_hwcfg *hwcfg; - s64 link_def_freq; /* CSI-2 link default frequency */ /* * Mutex for serialized access: @@ -879,7 +877,10 @@ static const char * const imx355_test_pattern_menu[] = { "Pseudorandom Sequence (PN9)", }; -/* supported link frequencies */ +/* + * When adding more than the one below, make sure the disallowed ones will + * actually be disabled in the LINK_FREQ control. + */ static const s64 link_freq_menu_items[] = { IMX355_LINK_FREQ_DEFAULT, }; @@ -1356,7 +1357,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd, *framefmt = fmt->format; } else { imx355->cur_mode = mode; - pixel_rate = imx355->link_def_freq * 2 * 4; + pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4; do_div(pixel_rate, 10); __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate); /* Update limits and set FPS to default */ @@ -1543,7 +1544,7 @@ static int imx355_init_controls(struct imx355 *imx355) imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ - pixel_rate = imx355->link_def_freq * 2 * 4; + pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4; do_div(pixel_rate, 10); /* By default, PIXEL_RATE is read only */ imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, @@ -1620,7 +1621,6 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev) }; struct fwnode_handle *ep; struct fwnode_handle *fwnode = dev_fwnode(dev); - unsigned int i; int ret; if (!fwnode) @@ -1652,23 +1652,13 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev) goto out_err; } - dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies); - if (!bus_cfg.nr_of_link_frequencies) { - dev_warn(dev, "no link frequencies defined"); + ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies, + bus_cfg.nr_of_link_frequencies, + link_freq_menu_items, + ARRAY_SIZE(link_freq_menu_items), + &cfg->link_freq_bitmap); + if (ret) goto out_err; - } - - cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies; - cfg->link_freqs = devm_kcalloc(dev, - bus_cfg.nr_of_link_frequencies + 1, - sizeof(*cfg->link_freqs), GFP_KERNEL); - if (!cfg->link_freqs) - goto out_err; - - for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { - cfg->link_freqs[i] = bus_cfg.link_frequencies[i]; - dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]); - } v4l2_fwnode_endpoint_free(&bus_cfg); fwnode_handle_put(ep); @@ -1684,7 +1674,6 @@ static int imx355_probe(struct i2c_client *client) { struct imx355 *imx355; int ret; - u32 i; imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL); if (!imx355) @@ -1709,20 +1698,6 @@ static int imx355_probe(struct i2c_client *client) goto error_probe; } - imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX]; - for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) { - if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) { - dev_dbg(&client->dev, "link freq index %d matched", i); - break; - } - } - - if (i == imx355->hwcfg->nr_of_link_freqs) { - dev_err(&client->dev, "no link frequency supported"); - ret = -EINVAL; - goto error_probe; - } - /* Set default mode to max resolution */ imx355->cur_mode = &supported_modes[0]; From b1a42fde6e077ec2fdeac1bcbcf464210c5aa682 Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Mon, 22 Jan 2024 03:54:34 +0100 Subject: [PATCH 107/252] media: ov08x40: Avoid sensor probing in D0 state When the system enters the D0 state and attempt to probe the device, another component, such as LED, will also be pulled high due to the hardware design. It's advisable to keep the device being probed in a different D state. Signed-off-by: Jason Chen Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov08x40.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index abbb0b774d43..1f9a63cdf996 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -2432,6 +2432,9 @@ struct ov08x40 { /* Mutex for serialized access */ struct mutex mutex; + + /* True if the device has been identified */ + bool identified; }; #define to_ov08x40(_sd) container_of(_sd, struct ov08x40, sd) @@ -2948,6 +2951,9 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x) int ret; u32 val; + if (ov08x->identified) + return 0; + ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID, OV08X40_REG_VALUE_24BIT, &val); if (ret) @@ -2956,9 +2962,11 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x) if (val != OV08X40_CHIP_ID) { dev_err(&client->dev, "chip id mismatch: %x!=%x\n", OV08X40_CHIP_ID, val); - return -EIO; + return -ENXIO; } + ov08x->identified = true; + return 0; } @@ -3175,6 +3183,7 @@ static int ov08x40_probe(struct i2c_client *client) { struct ov08x40 *ov08x; int ret; + bool full_power; /* Check HW config */ ret = ov08x40_check_hwcfg(&client->dev); @@ -3190,11 +3199,14 @@ static int ov08x40_probe(struct i2c_client *client) /* Initialize subdev */ v4l2_i2c_subdev_init(&ov08x->sd, client, &ov08x40_subdev_ops); - /* Check module identity */ - ret = ov08x40_identify_module(ov08x); - if (ret) { - dev_err(&client->dev, "failed to find sensor: %d\n", ret); - return ret; + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + /* Check module identity */ + ret = ov08x40_identify_module(ov08x); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d\n", ret); + return ret; + } } /* Set default mode to max resolution */ @@ -3222,11 +3234,8 @@ static int ov08x40_probe(struct i2c_client *client) if (ret < 0) goto error_media_entity; - /* - * Device is already turned on by i2c-core with ACPI domain PM. - * Enable runtime PM and turn off the device. - */ - pm_runtime_set_active(&client->dev); + if (full_power) + pm_runtime_set_active(&client->dev); pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); @@ -3270,6 +3279,7 @@ static struct i2c_driver ov08x40_i2c_driver = { }, .probe = ov08x40_probe, .remove = ov08x40_remove, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; module_i2c_driver(ov08x40_i2c_driver); From eea8f730df15dd41341b2904748a89895f20032b Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Wed, 18 Oct 2023 07:58:41 +0200 Subject: [PATCH 108/252] media: ov08x40: Modify the tline calculation in different modes ov08x40 quad bayer sensor ISP has the following work modes: - normal mode: full size - 2x2 binned mode: binning size In normal and binned modes, different tline calculations are applied. - normal mode: Tline value needs to be doubled as per the vendor's update. Tline time = 2 * HTS / SCLK Exposure unit : 1 * HTS = 0.5 Tline - 2x2 binned mode: Tline time = 1 * HTS / SCLK Exposure unit : 1 * HTS = 1 Tline Signed-off-by: Jason Chen Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov08x40.c | 66 ++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 1f9a63cdf996..010a6017e1ad 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -34,7 +34,7 @@ /* V_TIMING internal */ #define OV08X40_REG_VTS 0x380e -#define OV08X40_VTS_30FPS 0x1388 +#define OV08X40_VTS_30FPS 0x09c4 /* the VTS need to be half in normal mode */ #define OV08X40_VTS_BIN_30FPS 0x115c #define OV08X40_VTS_MAX 0x7fff @@ -44,8 +44,9 @@ /* Exposure control */ #define OV08X40_REG_EXPOSURE 0x3500 -#define OV08X40_EXPOSURE_MAX_MARGIN 31 -#define OV08X40_EXPOSURE_MIN 1 +#define OV08X40_EXPOSURE_MAX_MARGIN 8 +#define OV08X40_EXPOSURE_BIN_MAX_MARGIN 2 +#define OV08X40_EXPOSURE_MIN 4 #define OV08X40_EXPOSURE_STEP 1 #define OV08X40_EXPOSURE_DEFAULT 0x40 @@ -126,13 +127,17 @@ struct ov08x40_mode { u32 vts_def; u32 vts_min; - /* HTS */ - u32 hts; + /* Line Length Pixels */ + u32 llp; /* Index of Link frequency config to be used */ u32 link_freq_index; /* Default register values */ struct ov08x40_reg_list reg_list; + + /* Exposure calculation */ + u16 exposure_margin; + u16 exposure_shift; }; static const struct ov08x40_reg mipi_data_rate_800mbps[] = { @@ -2354,7 +2359,7 @@ static const char * const ov08x40_test_pattern_menu[] = { /* Configurations for supported link frequencies */ #define OV08X40_LINK_FREQ_400MHZ 400000000ULL - +#define OV08X40_SCLK_96MHZ 96000000ULL #define OV08X40_EXT_CLK 19200000 #define OV08X40_DATA_LANES 4 @@ -2392,26 +2397,30 @@ static const struct ov08x40_mode supported_modes[] = { .height = 2416, .vts_def = OV08X40_VTS_30FPS, .vts_min = OV08X40_VTS_30FPS, - .hts = 640, + .llp = 0x10aa, /* in normal mode, tline time = 2 * HTS / SCLK */ .lanes = 4, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_3856x2416_regs), .regs = mode_3856x2416_regs, }, .link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX, + .exposure_shift = 1, + .exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN, }, { .width = 1928, .height = 1208, .vts_def = OV08X40_VTS_BIN_30FPS, .vts_min = OV08X40_VTS_BIN_30FPS, - .hts = 720, + .llp = 0x960, .lanes = 4, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_1928x1208_regs), .regs = mode_1928x1208_regs, }, .link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX, + .exposure_shift = 0, + .exposure_margin = OV08X40_EXPOSURE_BIN_MAX_MARGIN, }, }; @@ -2667,13 +2676,23 @@ static int ov08x40_set_ctrl(struct v4l2_ctrl *ctrl) struct ov08x40, ctrl_handler); struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd); s64 max; + int exp; + int fll; int ret = 0; /* Propagate change of current control to all related controls */ switch (ctrl->id) { case V4L2_CID_VBLANK: /* Update max exposure while meeting expected vblanking */ - max = ov08x->cur_mode->height + ctrl->val - OV08X40_EXPOSURE_MAX_MARGIN; + /* + * because in normal mode, 1 HTS = 0.5 tline + * fps = sclk / hts / vts + * so the vts value needs to be double + */ + max = ((ov08x->cur_mode->height + ctrl->val) << + ov08x->cur_mode->exposure_shift) - + ov08x->cur_mode->exposure_margin; + __v4l2_ctrl_modify_range(ov08x->exposure, ov08x->exposure->minimum, max, ov08x->exposure->step, max); @@ -2697,15 +2716,20 @@ static int ov08x40_set_ctrl(struct v4l2_ctrl *ctrl) ret = ov08x40_update_digital_gain(ov08x, ctrl->val); break; case V4L2_CID_EXPOSURE: + exp = (ctrl->val << ov08x->cur_mode->exposure_shift) - + ov08x->cur_mode->exposure_margin; + ret = ov08x40_write_reg(ov08x, OV08X40_REG_EXPOSURE, OV08X40_REG_VALUE_24BIT, - ctrl->val); + exp); break; case V4L2_CID_VBLANK: + fll = ((ov08x->cur_mode->height + ctrl->val) << + ov08x->cur_mode->exposure_shift); + ret = ov08x40_write_reg(ov08x, OV08X40_REG_VTS, OV08X40_REG_VALUE_16BIT, - ov08x->cur_mode->height - + ctrl->val); + fll); break; case V4L2_CID_TEST_PATTERN: ret = ov08x40_enable_test_pattern(ov08x, ctrl->val); @@ -2815,6 +2839,7 @@ ov08x40_set_pad_format(struct v4l2_subdev *sd, s64 h_blank; s64 pixel_rate; s64 link_freq; + u64 steps; mutex_lock(&ov08x->mutex); @@ -2842,13 +2867,22 @@ ov08x40_set_pad_format(struct v4l2_subdev *sd, ov08x->cur_mode->height; vblank_min = ov08x->cur_mode->vts_min - ov08x->cur_mode->height; + + /* + * The frame length line should be aligned to a multiple of 4, + * as provided by the sensor vendor, in normal mode. + */ + steps = mode->exposure_shift == 1 ? 4 : 1; + __v4l2_ctrl_modify_range(ov08x->vblank, vblank_min, OV08X40_VTS_MAX - ov08x->cur_mode->height, - 1, + steps, vblank_def); __v4l2_ctrl_s_ctrl(ov08x->vblank, vblank_def); - h_blank = ov08x->cur_mode->hts; + + h_blank = ov08x->cur_mode->llp - ov08x->cur_mode->width; + __v4l2_ctrl_modify_range(ov08x->hblank, h_blank, h_blank, 1, h_blank); } @@ -3043,7 +3077,8 @@ static int ov08x40_init_controls(struct ov08x40 *ov08x) OV08X40_VTS_MAX - mode->height, 1, vblank_def); - hblank = ov08x->cur_mode->hts; + hblank = ov08x->cur_mode->llp - ov08x->cur_mode->width; + ov08x->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov08x40_ctrl_ops, V4L2_CID_HBLANK, hblank, hblank, 1, hblank); @@ -3285,6 +3320,7 @@ static struct i2c_driver ov08x40_i2c_driver = { module_i2c_driver(ov08x40_i2c_driver); MODULE_AUTHOR("Jason Chen "); +MODULE_AUTHOR("Qingwu Zhang "); MODULE_AUTHOR("Shawn Tu"); MODULE_DESCRIPTION("OmniVision OV08X40 sensor driver"); MODULE_LICENSE("GPL"); From feb8831be9d468ee961289c6a275536a1ee0011c Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Wed, 24 Jan 2024 15:43:01 +0100 Subject: [PATCH 109/252] media: ov08x40: Reduce start streaming time Because video duration involves calculating the streaming time, and i2c communication incurs too many XTALK register settings every 4 bytes with i2c START and STOP. So we have opted switch to the i2c burst method. This method involves writing the XTALK registers in the order of the register block. The start streaming time can be reduced from around 400ms to 150ms [Sakari Ailus: Drop unneeded dev_dbg().] Signed-off-by: Jason Chen Reviewed-by: Sergey Senozhatsky Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/video-interfaces.yaml | 2 +- arch/arm/boot/dts/ti/omap/omap3-n9.dts | 2 +- drivers/media/i2c/ov08x40.c | 1209 +---------------- 3 files changed, 59 insertions(+), 1154 deletions(-) diff --git a/Documentation/devicetree/bindings/media/video-interfaces.yaml b/Documentation/devicetree/bindings/media/video-interfaces.yaml index 26e3e7d7c67b..ea511f2fed98 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.yaml +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml @@ -190,7 +190,7 @@ properties: Allow MIPI CSI-2 non-continuous clock mode. link-frequencies: - $ref: /schemas/types.yaml#/definitions/uint64-array + $ref: /schemas/types.yaml#/definitions/uint32-array description: Allowed data bus frequencies. For MIPI CSI-2, for instance, this is the actual frequency of the bus, not bits per clock per lane value. An array diff --git a/arch/arm/boot/dts/ti/omap/omap3-n9.dts b/arch/arm/boot/dts/ti/omap/omap3-n9.dts index a3cf3f443785..728a8fcf25b3 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-n9.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-n9.dts @@ -26,7 +26,7 @@ smia_1: camera@10 { flash-leds = <&as3645a_flash &as3645a_indicator>; port { smia_1_1: endpoint { - link-frequencies = /bits/ 64 <199200000 210000000 499200000>; + link-frequencies = /bits/ 32 <199200000 210000000 499200000>; clock-lanes = <0>; data-lanes = <1 2>; remote-endpoint = <&csi2a_ep>; diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 010a6017e1ad..48df077522ad 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022 Intel Corporation. +#include #include #include #include @@ -95,6 +96,12 @@ /* Vertical Window Offset */ #define OV08X40_REG_V_WIN_OFFSET 0x3813 +/* Burst Register */ +#define OV08X40_REG_XTALK_FIRST_A 0x5a80 +#define OV08X40_REG_XTALK_LAST_A 0x5b9f +#define OV08X40_REG_XTALK_FIRST_B 0x5bc0 +#define OV08X40_REG_XTALK_LAST_B 0x5f1f + enum { OV08X40_LINK_FREQ_400MHZ_INDEX, }; @@ -670,1158 +677,6 @@ static const struct ov08x40_reg mode_3856x2416_regs[] = { {0x3502, 0x10}, {0x3508, 0x0f}, {0x3509, 0x80}, - {0x5a80, 0x75}, - {0x5a81, 0x75}, - {0x5a82, 0x75}, - {0x5a83, 0x75}, - {0x5a84, 0x75}, - {0x5a85, 0x75}, - {0x5a86, 0x75}, - {0x5a87, 0x75}, - {0x5a88, 0x75}, - {0x5a89, 0x75}, - {0x5a8a, 0x75}, - {0x5a8b, 0x75}, - {0x5a8c, 0x75}, - {0x5a8d, 0x75}, - {0x5a8e, 0x75}, - {0x5a8f, 0x75}, - {0x5a90, 0x75}, - {0x5a91, 0x75}, - {0x5a92, 0x75}, - {0x5a93, 0x75}, - {0x5a94, 0x75}, - {0x5a95, 0x75}, - {0x5a96, 0x75}, - {0x5a97, 0x75}, - {0x5a98, 0x75}, - {0x5a99, 0x75}, - {0x5a9a, 0x75}, - {0x5a9b, 0x75}, - {0x5a9c, 0x75}, - {0x5a9d, 0x75}, - {0x5a9e, 0x75}, - {0x5a9f, 0x75}, - {0x5aa0, 0x75}, - {0x5aa1, 0x75}, - {0x5aa2, 0x75}, - {0x5aa3, 0x75}, - {0x5aa4, 0x75}, - {0x5aa5, 0x75}, - {0x5aa6, 0x75}, - {0x5aa7, 0x75}, - {0x5aa8, 0x75}, - {0x5aa9, 0x75}, - {0x5aaa, 0x75}, - {0x5aab, 0x75}, - {0x5aac, 0x75}, - {0x5aad, 0x75}, - {0x5aae, 0x75}, - {0x5aaf, 0x75}, - {0x5ab0, 0x75}, - {0x5ab1, 0x75}, - {0x5ab2, 0x75}, - {0x5ab3, 0x75}, - {0x5ab4, 0x75}, - {0x5ab5, 0x75}, - {0x5ab6, 0x75}, - {0x5ab7, 0x75}, - {0x5ab8, 0x75}, - {0x5ab9, 0x75}, - {0x5aba, 0x75}, - {0x5abb, 0x75}, - {0x5abc, 0x75}, - {0x5abd, 0x75}, - {0x5abe, 0x75}, - {0x5abf, 0x75}, - {0x5ac0, 0x75}, - {0x5ac1, 0x75}, - {0x5ac2, 0x75}, - {0x5ac3, 0x75}, - {0x5ac4, 0x75}, - {0x5ac5, 0x75}, - {0x5ac6, 0x75}, - {0x5ac7, 0x75}, - {0x5ac8, 0x75}, - {0x5ac9, 0x75}, - {0x5aca, 0x75}, - {0x5acb, 0x75}, - {0x5acc, 0x75}, - {0x5acd, 0x75}, - {0x5ace, 0x75}, - {0x5acf, 0x75}, - {0x5ad0, 0x75}, - {0x5ad1, 0x75}, - {0x5ad2, 0x75}, - {0x5ad3, 0x75}, - {0x5ad4, 0x75}, - {0x5ad5, 0x75}, - {0x5ad6, 0x75}, - {0x5ad7, 0x75}, - {0x5ad8, 0x75}, - {0x5ad9, 0x75}, - {0x5ada, 0x75}, - {0x5adb, 0x75}, - {0x5adc, 0x75}, - {0x5add, 0x75}, - {0x5ade, 0x75}, - {0x5adf, 0x75}, - {0x5ae0, 0x75}, - {0x5ae1, 0x75}, - {0x5ae2, 0x75}, - {0x5ae3, 0x75}, - {0x5ae4, 0x75}, - {0x5ae5, 0x75}, - {0x5ae6, 0x75}, - {0x5ae7, 0x75}, - {0x5ae8, 0x75}, - {0x5ae9, 0x75}, - {0x5aea, 0x75}, - {0x5aeb, 0x75}, - {0x5aec, 0x75}, - {0x5aed, 0x75}, - {0x5aee, 0x75}, - {0x5aef, 0x75}, - {0x5af0, 0x75}, - {0x5af1, 0x75}, - {0x5af2, 0x75}, - {0x5af3, 0x75}, - {0x5af4, 0x75}, - {0x5af5, 0x75}, - {0x5af6, 0x75}, - {0x5af7, 0x75}, - {0x5af8, 0x75}, - {0x5af9, 0x75}, - {0x5afa, 0x75}, - {0x5afb, 0x75}, - {0x5afc, 0x75}, - {0x5afd, 0x75}, - {0x5afe, 0x75}, - {0x5aff, 0x75}, - {0x5b00, 0x75}, - {0x5b01, 0x75}, - {0x5b02, 0x75}, - {0x5b03, 0x75}, - {0x5b04, 0x75}, - {0x5b05, 0x75}, - {0x5b06, 0x75}, - {0x5b07, 0x75}, - {0x5b08, 0x75}, - {0x5b09, 0x75}, - {0x5b0a, 0x75}, - {0x5b0b, 0x75}, - {0x5b0c, 0x75}, - {0x5b0d, 0x75}, - {0x5b0e, 0x75}, - {0x5b0f, 0x75}, - {0x5b10, 0x75}, - {0x5b11, 0x75}, - {0x5b12, 0x75}, - {0x5b13, 0x75}, - {0x5b14, 0x75}, - {0x5b15, 0x75}, - {0x5b16, 0x75}, - {0x5b17, 0x75}, - {0x5b18, 0x75}, - {0x5b19, 0x75}, - {0x5b1a, 0x75}, - {0x5b1b, 0x75}, - {0x5b1c, 0x75}, - {0x5b1d, 0x75}, - {0x5b1e, 0x75}, - {0x5b1f, 0x75}, - {0x5b20, 0x75}, - {0x5b21, 0x75}, - {0x5b22, 0x75}, - {0x5b23, 0x75}, - {0x5b24, 0x75}, - {0x5b25, 0x75}, - {0x5b26, 0x75}, - {0x5b27, 0x75}, - {0x5b28, 0x75}, - {0x5b29, 0x75}, - {0x5b2a, 0x75}, - {0x5b2b, 0x75}, - {0x5b2c, 0x75}, - {0x5b2d, 0x75}, - {0x5b2e, 0x75}, - {0x5b2f, 0x75}, - {0x5b30, 0x75}, - {0x5b31, 0x75}, - {0x5b32, 0x75}, - {0x5b33, 0x75}, - {0x5b34, 0x75}, - {0x5b35, 0x75}, - {0x5b36, 0x75}, - {0x5b37, 0x75}, - {0x5b38, 0x75}, - {0x5b39, 0x75}, - {0x5b3a, 0x75}, - {0x5b3b, 0x75}, - {0x5b3c, 0x75}, - {0x5b3d, 0x75}, - {0x5b3e, 0x75}, - {0x5b3f, 0x75}, - {0x5b40, 0x75}, - {0x5b41, 0x75}, - {0x5b42, 0x75}, - {0x5b43, 0x75}, - {0x5b44, 0x75}, - {0x5b45, 0x75}, - {0x5b46, 0x75}, - {0x5b47, 0x75}, - {0x5b48, 0x75}, - {0x5b49, 0x75}, - {0x5b4a, 0x75}, - {0x5b4b, 0x75}, - {0x5b4c, 0x75}, - {0x5b4d, 0x75}, - {0x5b4e, 0x75}, - {0x5b4f, 0x75}, - {0x5b50, 0x75}, - {0x5b51, 0x75}, - {0x5b52, 0x75}, - {0x5b53, 0x75}, - {0x5b54, 0x75}, - {0x5b55, 0x75}, - {0x5b56, 0x75}, - {0x5b57, 0x75}, - {0x5b58, 0x75}, - {0x5b59, 0x75}, - {0x5b5a, 0x75}, - {0x5b5b, 0x75}, - {0x5b5c, 0x75}, - {0x5b5d, 0x75}, - {0x5b5e, 0x75}, - {0x5b5f, 0x75}, - {0x5b60, 0x75}, - {0x5b61, 0x75}, - {0x5b62, 0x75}, - {0x5b63, 0x75}, - {0x5b64, 0x75}, - {0x5b65, 0x75}, - {0x5b66, 0x75}, - {0x5b67, 0x75}, - {0x5b68, 0x75}, - {0x5b69, 0x75}, - {0x5b6a, 0x75}, - {0x5b6b, 0x75}, - {0x5b6c, 0x75}, - {0x5b6d, 0x75}, - {0x5b6e, 0x75}, - {0x5b6f, 0x75}, - {0x5b70, 0x75}, - {0x5b71, 0x75}, - {0x5b72, 0x75}, - {0x5b73, 0x75}, - {0x5b74, 0x75}, - {0x5b75, 0x75}, - {0x5b76, 0x75}, - {0x5b77, 0x75}, - {0x5b78, 0x75}, - {0x5b79, 0x75}, - {0x5b7a, 0x75}, - {0x5b7b, 0x75}, - {0x5b7c, 0x75}, - {0x5b7d, 0x75}, - {0x5b7e, 0x75}, - {0x5b7f, 0x75}, - {0x5b80, 0x75}, - {0x5b81, 0x75}, - {0x5b82, 0x75}, - {0x5b83, 0x75}, - {0x5b84, 0x75}, - {0x5b85, 0x75}, - {0x5b86, 0x75}, - {0x5b87, 0x75}, - {0x5b88, 0x75}, - {0x5b89, 0x75}, - {0x5b8a, 0x75}, - {0x5b8b, 0x75}, - {0x5b8c, 0x75}, - {0x5b8d, 0x75}, - {0x5b8e, 0x75}, - {0x5b8f, 0x75}, - {0x5b90, 0x75}, - {0x5b91, 0x75}, - {0x5b92, 0x75}, - {0x5b93, 0x75}, - {0x5b94, 0x75}, - {0x5b95, 0x75}, - {0x5b96, 0x75}, - {0x5b97, 0x75}, - {0x5b98, 0x75}, - {0x5b99, 0x75}, - {0x5b9a, 0x75}, - {0x5b9b, 0x75}, - {0x5b9c, 0x75}, - {0x5b9d, 0x75}, - {0x5b9e, 0x75}, - {0x5b9f, 0x75}, - {0x5bc0, 0x75}, - {0x5bc1, 0x75}, - {0x5bc2, 0x75}, - {0x5bc3, 0x75}, - {0x5bc4, 0x75}, - {0x5bc5, 0x75}, - {0x5bc6, 0x75}, - {0x5bc7, 0x75}, - {0x5bc8, 0x75}, - {0x5bc9, 0x75}, - {0x5bca, 0x75}, - {0x5bcb, 0x75}, - {0x5bcc, 0x75}, - {0x5bcd, 0x75}, - {0x5bce, 0x75}, - {0x5bcf, 0x75}, - {0x5bd0, 0x75}, - {0x5bd1, 0x75}, - {0x5bd2, 0x75}, - {0x5bd3, 0x75}, - {0x5bd4, 0x75}, - {0x5bd5, 0x75}, - {0x5bd6, 0x75}, - {0x5bd7, 0x75}, - {0x5bd8, 0x75}, - {0x5bd9, 0x75}, - {0x5bda, 0x75}, - {0x5bdb, 0x75}, - {0x5bdc, 0x75}, - {0x5bdd, 0x75}, - {0x5bde, 0x75}, - {0x5bdf, 0x75}, - {0x5be0, 0x75}, - {0x5be1, 0x75}, - {0x5be2, 0x75}, - {0x5be3, 0x75}, - {0x5be4, 0x75}, - {0x5be5, 0x75}, - {0x5be6, 0x75}, - {0x5be7, 0x75}, - {0x5be8, 0x75}, - {0x5be9, 0x75}, - {0x5bea, 0x75}, - {0x5beb, 0x75}, - {0x5bec, 0x75}, - {0x5bed, 0x75}, - {0x5bee, 0x75}, - {0x5bef, 0x75}, - {0x5bf0, 0x75}, - {0x5bf1, 0x75}, - {0x5bf2, 0x75}, - {0x5bf3, 0x75}, - {0x5bf4, 0x75}, - {0x5bf5, 0x75}, - {0x5bf6, 0x75}, - {0x5bf7, 0x75}, - {0x5bf8, 0x75}, - {0x5bf9, 0x75}, - {0x5bfa, 0x75}, - {0x5bfb, 0x75}, - {0x5bfc, 0x75}, - {0x5bfd, 0x75}, - {0x5bfe, 0x75}, - {0x5bff, 0x75}, - {0x5c00, 0x75}, - {0x5c01, 0x75}, - {0x5c02, 0x75}, - {0x5c03, 0x75}, - {0x5c04, 0x75}, - {0x5c05, 0x75}, - {0x5c06, 0x75}, - {0x5c07, 0x75}, - {0x5c08, 0x75}, - {0x5c09, 0x75}, - {0x5c0a, 0x75}, - {0x5c0b, 0x75}, - {0x5c0c, 0x75}, - {0x5c0d, 0x75}, - {0x5c0e, 0x75}, - {0x5c0f, 0x75}, - {0x5c10, 0x75}, - {0x5c11, 0x75}, - {0x5c12, 0x75}, - {0x5c13, 0x75}, - {0x5c14, 0x75}, - {0x5c15, 0x75}, - {0x5c16, 0x75}, - {0x5c17, 0x75}, - {0x5c18, 0x75}, - {0x5c19, 0x75}, - {0x5c1a, 0x75}, - {0x5c1b, 0x75}, - {0x5c1c, 0x75}, - {0x5c1d, 0x75}, - {0x5c1e, 0x75}, - {0x5c1f, 0x75}, - {0x5c20, 0x75}, - {0x5c21, 0x75}, - {0x5c22, 0x75}, - {0x5c23, 0x75}, - {0x5c24, 0x75}, - {0x5c25, 0x75}, - {0x5c26, 0x75}, - {0x5c27, 0x75}, - {0x5c28, 0x75}, - {0x5c29, 0x75}, - {0x5c2a, 0x75}, - {0x5c2b, 0x75}, - {0x5c2c, 0x75}, - {0x5c2d, 0x75}, - {0x5c2e, 0x75}, - {0x5c2f, 0x75}, - {0x5c30, 0x75}, - {0x5c31, 0x75}, - {0x5c32, 0x75}, - {0x5c33, 0x75}, - {0x5c34, 0x75}, - {0x5c35, 0x75}, - {0x5c36, 0x75}, - {0x5c37, 0x75}, - {0x5c38, 0x75}, - {0x5c39, 0x75}, - {0x5c3a, 0x75}, - {0x5c3b, 0x75}, - {0x5c3c, 0x75}, - {0x5c3d, 0x75}, - {0x5c3e, 0x75}, - {0x5c3f, 0x75}, - {0x5c40, 0x75}, - {0x5c41, 0x75}, - {0x5c42, 0x75}, - {0x5c43, 0x75}, - {0x5c44, 0x75}, - {0x5c45, 0x75}, - {0x5c46, 0x75}, - {0x5c47, 0x75}, - {0x5c48, 0x75}, - {0x5c49, 0x75}, - {0x5c4a, 0x75}, - {0x5c4b, 0x75}, - {0x5c4c, 0x75}, - {0x5c4d, 0x75}, - {0x5c4e, 0x75}, - {0x5c4f, 0x75}, - {0x5c50, 0x75}, - {0x5c51, 0x75}, - {0x5c52, 0x75}, - {0x5c53, 0x75}, - {0x5c54, 0x75}, - {0x5c55, 0x75}, - {0x5c56, 0x75}, - {0x5c57, 0x75}, - {0x5c58, 0x75}, - {0x5c59, 0x75}, - {0x5c5a, 0x75}, - {0x5c5b, 0x75}, - {0x5c5c, 0x75}, - {0x5c5d, 0x75}, - {0x5c5e, 0x75}, - {0x5c5f, 0x75}, - {0x5c60, 0x75}, - {0x5c61, 0x75}, - {0x5c62, 0x75}, - {0x5c63, 0x75}, - {0x5c64, 0x75}, - {0x5c65, 0x75}, - {0x5c66, 0x75}, - {0x5c67, 0x75}, - {0x5c68, 0x75}, - {0x5c69, 0x75}, - {0x5c6a, 0x75}, - {0x5c6b, 0x75}, - {0x5c6c, 0x75}, - {0x5c6d, 0x75}, - {0x5c6e, 0x75}, - {0x5c6f, 0x75}, - {0x5c70, 0x75}, - {0x5c71, 0x75}, - {0x5c72, 0x75}, - {0x5c73, 0x75}, - {0x5c74, 0x75}, - {0x5c75, 0x75}, - {0x5c76, 0x75}, - {0x5c77, 0x75}, - {0x5c78, 0x75}, - {0x5c79, 0x75}, - {0x5c7a, 0x75}, - {0x5c7b, 0x75}, - {0x5c7c, 0x75}, - {0x5c7d, 0x75}, - {0x5c7e, 0x75}, - {0x5c7f, 0x75}, - {0x5c80, 0x75}, - {0x5c81, 0x75}, - {0x5c82, 0x75}, - {0x5c83, 0x75}, - {0x5c84, 0x75}, - {0x5c85, 0x75}, - {0x5c86, 0x75}, - {0x5c87, 0x75}, - {0x5c88, 0x75}, - {0x5c89, 0x75}, - {0x5c8a, 0x75}, - {0x5c8b, 0x75}, - {0x5c8c, 0x75}, - {0x5c8d, 0x75}, - {0x5c8e, 0x75}, - {0x5c8f, 0x75}, - {0x5c90, 0x75}, - {0x5c91, 0x75}, - {0x5c92, 0x75}, - {0x5c93, 0x75}, - {0x5c94, 0x75}, - {0x5c95, 0x75}, - {0x5c96, 0x75}, - {0x5c97, 0x75}, - {0x5c98, 0x75}, - {0x5c99, 0x75}, - {0x5c9a, 0x75}, - {0x5c9b, 0x75}, - {0x5c9c, 0x75}, - {0x5c9d, 0x75}, - {0x5c9e, 0x75}, - {0x5c9f, 0x75}, - {0x5ca0, 0x75}, - {0x5ca1, 0x75}, - {0x5ca2, 0x75}, - {0x5ca3, 0x75}, - {0x5ca4, 0x75}, - {0x5ca5, 0x75}, - {0x5ca6, 0x75}, - {0x5ca7, 0x75}, - {0x5ca8, 0x75}, - {0x5ca9, 0x75}, - {0x5caa, 0x75}, - {0x5cab, 0x75}, - {0x5cac, 0x75}, - {0x5cad, 0x75}, - {0x5cae, 0x75}, - {0x5caf, 0x75}, - {0x5cb0, 0x75}, - {0x5cb1, 0x75}, - {0x5cb2, 0x75}, - {0x5cb3, 0x75}, - {0x5cb4, 0x75}, - {0x5cb5, 0x75}, - {0x5cb6, 0x75}, - {0x5cb7, 0x75}, - {0x5cb8, 0x75}, - {0x5cb9, 0x75}, - {0x5cba, 0x75}, - {0x5cbb, 0x75}, - {0x5cbc, 0x75}, - {0x5cbd, 0x75}, - {0x5cbe, 0x75}, - {0x5cbf, 0x75}, - {0x5cc0, 0x75}, - {0x5cc1, 0x75}, - {0x5cc2, 0x75}, - {0x5cc3, 0x75}, - {0x5cc4, 0x75}, - {0x5cc5, 0x75}, - {0x5cc6, 0x75}, - {0x5cc7, 0x75}, - {0x5cc8, 0x75}, - {0x5cc9, 0x75}, - {0x5cca, 0x75}, - {0x5ccb, 0x75}, - {0x5ccc, 0x75}, - {0x5ccd, 0x75}, - {0x5cce, 0x75}, - {0x5ccf, 0x75}, - {0x5cd0, 0x75}, - {0x5cd1, 0x75}, - {0x5cd2, 0x75}, - {0x5cd3, 0x75}, - {0x5cd4, 0x75}, - {0x5cd5, 0x75}, - {0x5cd6, 0x75}, - {0x5cd7, 0x75}, - {0x5cd8, 0x75}, - {0x5cd9, 0x75}, - {0x5cda, 0x75}, - {0x5cdb, 0x75}, - {0x5cdc, 0x75}, - {0x5cdd, 0x75}, - {0x5cde, 0x75}, - {0x5cdf, 0x75}, - {0x5ce0, 0x75}, - {0x5ce1, 0x75}, - {0x5ce2, 0x75}, - {0x5ce3, 0x75}, - {0x5ce4, 0x75}, - {0x5ce5, 0x75}, - {0x5ce6, 0x75}, - {0x5ce7, 0x75}, - {0x5ce8, 0x75}, - {0x5ce9, 0x75}, - {0x5cea, 0x75}, - {0x5ceb, 0x75}, - {0x5cec, 0x75}, - {0x5ced, 0x75}, - {0x5cee, 0x75}, - {0x5cef, 0x75}, - {0x5cf0, 0x75}, - {0x5cf1, 0x75}, - {0x5cf2, 0x75}, - {0x5cf3, 0x75}, - {0x5cf4, 0x75}, - {0x5cf5, 0x75}, - {0x5cf6, 0x75}, - {0x5cf7, 0x75}, - {0x5cf8, 0x75}, - {0x5cf9, 0x75}, - {0x5cfa, 0x75}, - {0x5cfb, 0x75}, - {0x5cfc, 0x75}, - {0x5cfd, 0x75}, - {0x5cfe, 0x75}, - {0x5cff, 0x75}, - {0x5d00, 0x75}, - {0x5d01, 0x75}, - {0x5d02, 0x75}, - {0x5d03, 0x75}, - {0x5d04, 0x75}, - {0x5d05, 0x75}, - {0x5d06, 0x75}, - {0x5d07, 0x75}, - {0x5d08, 0x75}, - {0x5d09, 0x75}, - {0x5d0a, 0x75}, - {0x5d0b, 0x75}, - {0x5d0c, 0x75}, - {0x5d0d, 0x75}, - {0x5d0e, 0x75}, - {0x5d0f, 0x75}, - {0x5d10, 0x75}, - {0x5d11, 0x75}, - {0x5d12, 0x75}, - {0x5d13, 0x75}, - {0x5d14, 0x75}, - {0x5d15, 0x75}, - {0x5d16, 0x75}, - {0x5d17, 0x75}, - {0x5d18, 0x75}, - {0x5d19, 0x75}, - {0x5d1a, 0x75}, - {0x5d1b, 0x75}, - {0x5d1c, 0x75}, - {0x5d1d, 0x75}, - {0x5d1e, 0x75}, - {0x5d1f, 0x75}, - {0x5d20, 0x75}, - {0x5d21, 0x75}, - {0x5d22, 0x75}, - {0x5d23, 0x75}, - {0x5d24, 0x75}, - {0x5d25, 0x75}, - {0x5d26, 0x75}, - {0x5d27, 0x75}, - {0x5d28, 0x75}, - {0x5d29, 0x75}, - {0x5d2a, 0x75}, - {0x5d2b, 0x75}, - {0x5d2c, 0x75}, - {0x5d2d, 0x75}, - {0x5d2e, 0x75}, - {0x5d2f, 0x75}, - {0x5d30, 0x75}, - {0x5d31, 0x75}, - {0x5d32, 0x75}, - {0x5d33, 0x75}, - {0x5d34, 0x75}, - {0x5d35, 0x75}, - {0x5d36, 0x75}, - {0x5d37, 0x75}, - {0x5d38, 0x75}, - {0x5d39, 0x75}, - {0x5d3a, 0x75}, - {0x5d3b, 0x75}, - {0x5d3c, 0x75}, - {0x5d3d, 0x75}, - {0x5d3e, 0x75}, - {0x5d3f, 0x75}, - {0x5d40, 0x75}, - {0x5d41, 0x75}, - {0x5d42, 0x75}, - {0x5d43, 0x75}, - {0x5d44, 0x75}, - {0x5d45, 0x75}, - {0x5d46, 0x75}, - {0x5d47, 0x75}, - {0x5d48, 0x75}, - {0x5d49, 0x75}, - {0x5d4a, 0x75}, - {0x5d4b, 0x75}, - {0x5d4c, 0x75}, - {0x5d4d, 0x75}, - {0x5d4e, 0x75}, - {0x5d4f, 0x75}, - {0x5d50, 0x75}, - {0x5d51, 0x75}, - {0x5d52, 0x75}, - {0x5d53, 0x75}, - {0x5d54, 0x75}, - {0x5d55, 0x75}, - {0x5d56, 0x75}, - {0x5d57, 0x75}, - {0x5d58, 0x75}, - {0x5d59, 0x75}, - {0x5d5a, 0x75}, - {0x5d5b, 0x75}, - {0x5d5c, 0x75}, - {0x5d5d, 0x75}, - {0x5d5e, 0x75}, - {0x5d5f, 0x75}, - {0x5d60, 0x75}, - {0x5d61, 0x75}, - {0x5d62, 0x75}, - {0x5d63, 0x75}, - {0x5d64, 0x75}, - {0x5d65, 0x75}, - {0x5d66, 0x75}, - {0x5d67, 0x75}, - {0x5d68, 0x75}, - {0x5d69, 0x75}, - {0x5d6a, 0x75}, - {0x5d6b, 0x75}, - {0x5d6c, 0x75}, - {0x5d6d, 0x75}, - {0x5d6e, 0x75}, - {0x5d6f, 0x75}, - {0x5d70, 0x75}, - {0x5d71, 0x75}, - {0x5d72, 0x75}, - {0x5d73, 0x75}, - {0x5d74, 0x75}, - {0x5d75, 0x75}, - {0x5d76, 0x75}, - {0x5d77, 0x75}, - {0x5d78, 0x75}, - {0x5d79, 0x75}, - {0x5d7a, 0x75}, - {0x5d7b, 0x75}, - {0x5d7c, 0x75}, - {0x5d7d, 0x75}, - {0x5d7e, 0x75}, - {0x5d7f, 0x75}, - {0x5d80, 0x75}, - {0x5d81, 0x75}, - {0x5d82, 0x75}, - {0x5d83, 0x75}, - {0x5d84, 0x75}, - {0x5d85, 0x75}, - {0x5d86, 0x75}, - {0x5d87, 0x75}, - {0x5d88, 0x75}, - {0x5d89, 0x75}, - {0x5d8a, 0x75}, - {0x5d8b, 0x75}, - {0x5d8c, 0x75}, - {0x5d8d, 0x75}, - {0x5d8e, 0x75}, - {0x5d8f, 0x75}, - {0x5d90, 0x75}, - {0x5d91, 0x75}, - {0x5d92, 0x75}, - {0x5d93, 0x75}, - {0x5d94, 0x75}, - {0x5d95, 0x75}, - {0x5d96, 0x75}, - {0x5d97, 0x75}, - {0x5d98, 0x75}, - {0x5d99, 0x75}, - {0x5d9a, 0x75}, - {0x5d9b, 0x75}, - {0x5d9c, 0x75}, - {0x5d9d, 0x75}, - {0x5d9e, 0x75}, - {0x5d9f, 0x75}, - {0x5da0, 0x75}, - {0x5da1, 0x75}, - {0x5da2, 0x75}, - {0x5da3, 0x75}, - {0x5da4, 0x75}, - {0x5da5, 0x75}, - {0x5da6, 0x75}, - {0x5da7, 0x75}, - {0x5da8, 0x75}, - {0x5da9, 0x75}, - {0x5daa, 0x75}, - {0x5dab, 0x75}, - {0x5dac, 0x75}, - {0x5dad, 0x75}, - {0x5dae, 0x75}, - {0x5daf, 0x75}, - {0x5db0, 0x75}, - {0x5db1, 0x75}, - {0x5db2, 0x75}, - {0x5db3, 0x75}, - {0x5db4, 0x75}, - {0x5db5, 0x75}, - {0x5db6, 0x75}, - {0x5db7, 0x75}, - {0x5db8, 0x75}, - {0x5db9, 0x75}, - {0x5dba, 0x75}, - {0x5dbb, 0x75}, - {0x5dbc, 0x75}, - {0x5dbd, 0x75}, - {0x5dbe, 0x75}, - {0x5dbf, 0x75}, - {0x5dc0, 0x75}, - {0x5dc1, 0x75}, - {0x5dc2, 0x75}, - {0x5dc3, 0x75}, - {0x5dc4, 0x75}, - {0x5dc5, 0x75}, - {0x5dc6, 0x75}, - {0x5dc7, 0x75}, - {0x5dc8, 0x75}, - {0x5dc9, 0x75}, - {0x5dca, 0x75}, - {0x5dcb, 0x75}, - {0x5dcc, 0x75}, - {0x5dcd, 0x75}, - {0x5dce, 0x75}, - {0x5dcf, 0x75}, - {0x5dd0, 0x75}, - {0x5dd1, 0x75}, - {0x5dd2, 0x75}, - {0x5dd3, 0x75}, - {0x5dd4, 0x75}, - {0x5dd5, 0x75}, - {0x5dd6, 0x75}, - {0x5dd7, 0x75}, - {0x5dd8, 0x75}, - {0x5dd9, 0x75}, - {0x5dda, 0x75}, - {0x5ddb, 0x75}, - {0x5ddc, 0x75}, - {0x5ddd, 0x75}, - {0x5dde, 0x75}, - {0x5ddf, 0x75}, - {0x5de0, 0x75}, - {0x5de1, 0x75}, - {0x5de2, 0x75}, - {0x5de3, 0x75}, - {0x5de4, 0x75}, - {0x5de5, 0x75}, - {0x5de6, 0x75}, - {0x5de7, 0x75}, - {0x5de8, 0x75}, - {0x5de9, 0x75}, - {0x5dea, 0x75}, - {0x5deb, 0x75}, - {0x5dec, 0x75}, - {0x5ded, 0x75}, - {0x5dee, 0x75}, - {0x5def, 0x75}, - {0x5df0, 0x75}, - {0x5df1, 0x75}, - {0x5df2, 0x75}, - {0x5df3, 0x75}, - {0x5df4, 0x75}, - {0x5df5, 0x75}, - {0x5df6, 0x75}, - {0x5df7, 0x75}, - {0x5df8, 0x75}, - {0x5df9, 0x75}, - {0x5dfa, 0x75}, - {0x5dfb, 0x75}, - {0x5dfc, 0x75}, - {0x5dfd, 0x75}, - {0x5dfe, 0x75}, - {0x5dff, 0x75}, - {0x5e00, 0x75}, - {0x5e01, 0x75}, - {0x5e02, 0x75}, - {0x5e03, 0x75}, - {0x5e04, 0x75}, - {0x5e05, 0x75}, - {0x5e06, 0x75}, - {0x5e07, 0x75}, - {0x5e08, 0x75}, - {0x5e09, 0x75}, - {0x5e0a, 0x75}, - {0x5e0b, 0x75}, - {0x5e0c, 0x75}, - {0x5e0d, 0x75}, - {0x5e0e, 0x75}, - {0x5e0f, 0x75}, - {0x5e10, 0x75}, - {0x5e11, 0x75}, - {0x5e12, 0x75}, - {0x5e13, 0x75}, - {0x5e14, 0x75}, - {0x5e15, 0x75}, - {0x5e16, 0x75}, - {0x5e17, 0x75}, - {0x5e18, 0x75}, - {0x5e19, 0x75}, - {0x5e1a, 0x75}, - {0x5e1b, 0x75}, - {0x5e1c, 0x75}, - {0x5e1d, 0x75}, - {0x5e1e, 0x75}, - {0x5e1f, 0x75}, - {0x5e20, 0x75}, - {0x5e21, 0x75}, - {0x5e22, 0x75}, - {0x5e23, 0x75}, - {0x5e24, 0x75}, - {0x5e25, 0x75}, - {0x5e26, 0x75}, - {0x5e27, 0x75}, - {0x5e28, 0x75}, - {0x5e29, 0x75}, - {0x5e2a, 0x75}, - {0x5e2b, 0x75}, - {0x5e2c, 0x75}, - {0x5e2d, 0x75}, - {0x5e2e, 0x75}, - {0x5e2f, 0x75}, - {0x5e30, 0x75}, - {0x5e31, 0x75}, - {0x5e32, 0x75}, - {0x5e33, 0x75}, - {0x5e34, 0x75}, - {0x5e35, 0x75}, - {0x5e36, 0x75}, - {0x5e37, 0x75}, - {0x5e38, 0x75}, - {0x5e39, 0x75}, - {0x5e3a, 0x75}, - {0x5e3b, 0x75}, - {0x5e3c, 0x75}, - {0x5e3d, 0x75}, - {0x5e3e, 0x75}, - {0x5e3f, 0x75}, - {0x5e40, 0x75}, - {0x5e41, 0x75}, - {0x5e42, 0x75}, - {0x5e43, 0x75}, - {0x5e44, 0x75}, - {0x5e45, 0x75}, - {0x5e46, 0x75}, - {0x5e47, 0x75}, - {0x5e48, 0x75}, - {0x5e49, 0x75}, - {0x5e4a, 0x75}, - {0x5e4b, 0x75}, - {0x5e4c, 0x75}, - {0x5e4d, 0x75}, - {0x5e4e, 0x75}, - {0x5e4f, 0x75}, - {0x5e50, 0x75}, - {0x5e51, 0x75}, - {0x5e52, 0x75}, - {0x5e53, 0x75}, - {0x5e54, 0x75}, - {0x5e55, 0x75}, - {0x5e56, 0x75}, - {0x5e57, 0x75}, - {0x5e58, 0x75}, - {0x5e59, 0x75}, - {0x5e5a, 0x75}, - {0x5e5b, 0x75}, - {0x5e5c, 0x75}, - {0x5e5d, 0x75}, - {0x5e5e, 0x75}, - {0x5e5f, 0x75}, - {0x5e60, 0x75}, - {0x5e61, 0x75}, - {0x5e62, 0x75}, - {0x5e63, 0x75}, - {0x5e64, 0x75}, - {0x5e65, 0x75}, - {0x5e66, 0x75}, - {0x5e67, 0x75}, - {0x5e68, 0x75}, - {0x5e69, 0x75}, - {0x5e6a, 0x75}, - {0x5e6b, 0x75}, - {0x5e6c, 0x75}, - {0x5e6d, 0x75}, - {0x5e6e, 0x75}, - {0x5e6f, 0x75}, - {0x5e70, 0x75}, - {0x5e71, 0x75}, - {0x5e72, 0x75}, - {0x5e73, 0x75}, - {0x5e74, 0x75}, - {0x5e75, 0x75}, - {0x5e76, 0x75}, - {0x5e77, 0x75}, - {0x5e78, 0x75}, - {0x5e79, 0x75}, - {0x5e7a, 0x75}, - {0x5e7b, 0x75}, - {0x5e7c, 0x75}, - {0x5e7d, 0x75}, - {0x5e7e, 0x75}, - {0x5e7f, 0x75}, - {0x5e80, 0x75}, - {0x5e81, 0x75}, - {0x5e82, 0x75}, - {0x5e83, 0x75}, - {0x5e84, 0x75}, - {0x5e85, 0x75}, - {0x5e86, 0x75}, - {0x5e87, 0x75}, - {0x5e88, 0x75}, - {0x5e89, 0x75}, - {0x5e8a, 0x75}, - {0x5e8b, 0x75}, - {0x5e8c, 0x75}, - {0x5e8d, 0x75}, - {0x5e8e, 0x75}, - {0x5e8f, 0x75}, - {0x5e90, 0x75}, - {0x5e91, 0x75}, - {0x5e92, 0x75}, - {0x5e93, 0x75}, - {0x5e94, 0x75}, - {0x5e95, 0x75}, - {0x5e96, 0x75}, - {0x5e97, 0x75}, - {0x5e98, 0x75}, - {0x5e99, 0x75}, - {0x5e9a, 0x75}, - {0x5e9b, 0x75}, - {0x5e9c, 0x75}, - {0x5e9d, 0x75}, - {0x5e9e, 0x75}, - {0x5e9f, 0x75}, - {0x5ea0, 0x75}, - {0x5ea1, 0x75}, - {0x5ea2, 0x75}, - {0x5ea3, 0x75}, - {0x5ea4, 0x75}, - {0x5ea5, 0x75}, - {0x5ea6, 0x75}, - {0x5ea7, 0x75}, - {0x5ea8, 0x75}, - {0x5ea9, 0x75}, - {0x5eaa, 0x75}, - {0x5eab, 0x75}, - {0x5eac, 0x75}, - {0x5ead, 0x75}, - {0x5eae, 0x75}, - {0x5eaf, 0x75}, - {0x5eb0, 0x75}, - {0x5eb1, 0x75}, - {0x5eb2, 0x75}, - {0x5eb3, 0x75}, - {0x5eb4, 0x75}, - {0x5eb5, 0x75}, - {0x5eb6, 0x75}, - {0x5eb7, 0x75}, - {0x5eb8, 0x75}, - {0x5eb9, 0x75}, - {0x5eba, 0x75}, - {0x5ebb, 0x75}, - {0x5ebc, 0x75}, - {0x5ebd, 0x75}, - {0x5ebe, 0x75}, - {0x5ebf, 0x75}, - {0x5ec0, 0x75}, - {0x5ec1, 0x75}, - {0x5ec2, 0x75}, - {0x5ec3, 0x75}, - {0x5ec4, 0x75}, - {0x5ec5, 0x75}, - {0x5ec6, 0x75}, - {0x5ec7, 0x75}, - {0x5ec8, 0x75}, - {0x5ec9, 0x75}, - {0x5eca, 0x75}, - {0x5ecb, 0x75}, - {0x5ecc, 0x75}, - {0x5ecd, 0x75}, - {0x5ece, 0x75}, - {0x5ecf, 0x75}, - {0x5ed0, 0x75}, - {0x5ed1, 0x75}, - {0x5ed2, 0x75}, - {0x5ed3, 0x75}, - {0x5ed4, 0x75}, - {0x5ed5, 0x75}, - {0x5ed6, 0x75}, - {0x5ed7, 0x75}, - {0x5ed8, 0x75}, - {0x5ed9, 0x75}, - {0x5eda, 0x75}, - {0x5edb, 0x75}, - {0x5edc, 0x75}, - {0x5edd, 0x75}, - {0x5ede, 0x75}, - {0x5edf, 0x75}, - {0x5ee0, 0x75}, - {0x5ee1, 0x75}, - {0x5ee2, 0x75}, - {0x5ee3, 0x75}, - {0x5ee4, 0x75}, - {0x5ee5, 0x75}, - {0x5ee6, 0x75}, - {0x5ee7, 0x75}, - {0x5ee8, 0x75}, - {0x5ee9, 0x75}, - {0x5eea, 0x75}, - {0x5eeb, 0x75}, - {0x5eec, 0x75}, - {0x5eed, 0x75}, - {0x5eee, 0x75}, - {0x5eef, 0x75}, - {0x5ef0, 0x75}, - {0x5ef1, 0x75}, - {0x5ef2, 0x75}, - {0x5ef3, 0x75}, - {0x5ef4, 0x75}, - {0x5ef5, 0x75}, - {0x5ef6, 0x75}, - {0x5ef7, 0x75}, - {0x5ef8, 0x75}, - {0x5ef9, 0x75}, - {0x5efa, 0x75}, - {0x5efb, 0x75}, - {0x5efc, 0x75}, - {0x5efd, 0x75}, - {0x5efe, 0x75}, - {0x5eff, 0x75}, - {0x5f00, 0x75}, - {0x5f01, 0x75}, - {0x5f02, 0x75}, - {0x5f03, 0x75}, - {0x5f04, 0x75}, - {0x5f05, 0x75}, - {0x5f06, 0x75}, - {0x5f07, 0x75}, - {0x5f08, 0x75}, - {0x5f09, 0x75}, - {0x5f0a, 0x75}, - {0x5f0b, 0x75}, - {0x5f0c, 0x75}, - {0x5f0d, 0x75}, - {0x5f0e, 0x75}, - {0x5f0f, 0x75}, - {0x5f10, 0x75}, - {0x5f11, 0x75}, - {0x5f12, 0x75}, - {0x5f13, 0x75}, - {0x5f14, 0x75}, - {0x5f15, 0x75}, - {0x5f16, 0x75}, - {0x5f17, 0x75}, - {0x5f18, 0x75}, - {0x5f19, 0x75}, - {0x5f1a, 0x75}, - {0x5f1b, 0x75}, - {0x5f1c, 0x75}, - {0x5f1d, 0x75}, - {0x5f1e, 0x75}, - {0x5f1f, 0x75}, }; static const struct ov08x40_reg mode_1928x1208_regs[] = { @@ -2484,6 +1339,40 @@ static int ov08x40_read_reg(struct ov08x40 *ov08x, return 0; } +static int ov08x40_burst_fill_regs(struct ov08x40 *ov08x, u16 first_reg, + u16 last_reg, u8 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd); + struct i2c_msg msgs; + size_t i, num_regs; + int ret; + + num_regs = last_reg - first_reg + 1; + msgs.addr = client->addr; + msgs.flags = 0; + msgs.len = 2 + num_regs; + msgs.buf = kmalloc(msgs.len, GFP_KERNEL); + + if (!msgs.buf) + return -ENOMEM; + + put_unaligned_be16(first_reg, msgs.buf); + + for (i = 0; i < num_regs; ++i) + msgs.buf[2 + i] = val; + + ret = i2c_transfer(client->adapter, &msgs, 1); + + kfree(msgs.buf); + + if (ret != 1) { + dev_err(&client->dev, "Failed regs transferred: %d\n", ret); + return -EIO; + } + + return 0; +} + /* Write registers up to 4 at a time */ static int ov08x40_write_reg(struct ov08x40 *ov08x, u16 reg, u32 len, u32 __val) @@ -2924,6 +1813,22 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x) return ret; } + /* Use i2c burst to write register on full size registers */ + if (ov08x->cur_mode->exposure_shift == 1) { + ret = ov08x40_burst_fill_regs(ov08x, OV08X40_REG_XTALK_FIRST_A, + OV08X40_REG_XTALK_LAST_A, 0x75); + if (ret == 0) + ret = ov08x40_burst_fill_regs(ov08x, + OV08X40_REG_XTALK_FIRST_B, + OV08X40_REG_XTALK_LAST_B, + 0x75); + } + + if (ret) { + dev_err(&client->dev, "%s failed to set regs\n", __func__); + return ret; + } + /* Apply customized values from user */ ret = __v4l2_ctrl_handler_setup(ov08x->sd.ctrl_handler); if (ret) From 35546945e5e5cce825d2b92e1ecc3f4ac70ec1dc Mon Sep 17 00:00:00 2001 From: "Duc-Long, Le" Date: Sat, 14 Oct 2023 20:19:46 -0400 Subject: [PATCH 110/252] media: tc358746: fix the pll calculating function Following formula of Pll_clk in 5.2 section, 50th page of TC358746AXBG/748XBG/748IXBG Functional Specification Rev 1.1 document. The formula of fout is as below: fout = refclk * mul / (prediv * postdiv) Remove "p" to avoid using 2 times of prediv in pll calculating function. Signed-off-by: Duc-Long, Le Signed-off-by: Hans Verkuil --- drivers/media/i2c/tc358746.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c index 106de4271d2e..d676adc4401b 100644 --- a/drivers/media/i2c/tc358746.c +++ b/drivers/media/i2c/tc358746.c @@ -843,14 +843,14 @@ static unsigned long tc358746_find_pll_settings(struct tc358746 *tc358746, if (fin < 4 * HZ_PER_MHZ || fin > 40 * HZ_PER_MHZ) continue; - tmp = fout * p * postdiv; + tmp = fout * postdiv; do_div(tmp, fin); mul = tmp; if (mul > 511) continue; tmp = mul * fin; - do_div(tmp, p * postdiv); + do_div(tmp, postdiv); delta = abs(fout - tmp); if (delta < min_delta) { From 15126b916e39b0cb67026b0af3c014bfeb1f76b3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 19 Oct 2023 08:58:49 +0200 Subject: [PATCH 111/252] media: pci: cx23885: check cx23885_vdev_init() return cx23885_vdev_init() can return a NULL pointer, but that pointer is used in the next line without a check. Add a NULL pointer check and go to the error unwind if it is NULL. Signed-off-by: Hans Verkuil Reported-by: Sicong Huang --- drivers/media/pci/cx23885/cx23885-video.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 42fdcf992e48..7d4a409c433e 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -1354,6 +1354,10 @@ int cx23885_video_register(struct cx23885_dev *dev) /* register Video device */ dev->video_dev = cx23885_vdev_init(dev, dev->pci, &cx23885_video_template, "video"); + if (!dev->video_dev) { + err = -ENOMEM; + goto fail_unreg; + } dev->video_dev->queue = &dev->vb2_vidq; dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE; @@ -1382,6 +1386,10 @@ int cx23885_video_register(struct cx23885_dev *dev) /* register VBI device */ dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, &cx23885_vbi_template, "vbi"); + if (!dev->vbi_dev) { + err = -ENOMEM; + goto fail_unreg; + } dev->vbi_dev->queue = &dev->vb2_vbiq; dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE; From fd4f587389e1202ab5737977c11f09ea56bbd1b2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 15 Dec 2023 10:38:29 +0100 Subject: [PATCH 112/252] media: vidioc-subdev-g-client-cap.rst: document struct v4l2_subdev_client_capability The struct v4l2_subdev_client_capability was never actually documented, only the capability flags were documented. Add this. Signed-off-by: Hans Verkuil --- .../media/v4l/vidioc-subdev-g-client-cap.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst index 810b6a859dc8..da4a358ce762 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst @@ -61,6 +61,21 @@ been accepted. A common case for the kernel not accepting a capability is that the kernel is older than the headers the userspace uses, and thus the capability is unknown to the kernel. +.. tabularcolumns:: |p{1.5cm}|p{2.9cm}|p{12.9cm}| + +.. c:type:: v4l2_subdev_client_capability + +.. flat-table:: struct v4l2_subdev_client_capability + :header-rows: 0 + :stub-columns: 0 + :widths: 3 4 20 + + * - __u64 + - ``capabilities`` + - Sub-device client capabilities of the opened device. + +.. tabularcolumns:: |p{6.8cm}|p{2.4cm}|p{8.1cm}| + .. flat-table:: Client Capabilities :header-rows: 1 From c82523aca798e891fd1d29fce24c4d394fd64483 Mon Sep 17 00:00:00 2001 From: renjun wang Date: Sat, 16 Dec 2023 12:18:05 +0800 Subject: [PATCH 113/252] media: verisilicon: Fix some typos Function hantro_g1_h264_dec_prepare_table() does not exist, should be replaced with hantro_h264_dec_init(). The register name av1_ulticore_tile_col confused sometimes, although not be used corrently. The correct name should be av1_multicore_tile_col. Signed-off-by: renjun wang Signed-off-by: Hans Verkuil --- drivers/media/platform/verisilicon/hantro_g1_h264_dec.c | 2 +- drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c | 2 +- drivers/media/platform/verisilicon/rockchip_vpu981_regs.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c b/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c index 9de7f05eff2a..ad5c1a6634f5 100644 --- a/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c @@ -243,7 +243,7 @@ static void set_buffers(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf) vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DIR_MV); } - /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */ + /* Auxiliary buffer prepared in hantro_h264_dec_init(). */ vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, G1_REG_ADDR_QTABLE); } diff --git a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c index 46c1a83bcc4e..6da87f5184bc 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c @@ -460,7 +460,7 @@ static void set_buffers(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf) vdpu_write_relaxed(vpu, dst_dma + offset, VDPU_REG_DIR_MV_BASE); } - /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */ + /* Auxiliary buffer prepared in hantro_h264_dec_init(). */ vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, VDPU_REG_QTABLE_BASE); } diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h b/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h index 182e6c830ff6..850ff0f84424 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h @@ -118,7 +118,7 @@ #define av1_mcomp_filt_type AV1_DEC_REG(11, 8, 0x7) #define av1_multicore_expect_context_update AV1_DEC_REG(11, 11, 0x1) #define av1_multicore_sbx_offset AV1_DEC_REG(11, 12, 0x7f) -#define av1_ulticore_tile_col AV1_DEC_REG(11, 19, 0x7f) +#define av1_multicore_tile_col AV1_DEC_REG(11, 19, 0x7f) #define av1_transform_mode AV1_DEC_REG(11, 27, 0x7) #define av1_dec_tile_size_mag AV1_DEC_REG(11, 30, 0x3) From 36d503ad547d1c75758a6fcdbec2806f1b6aeb41 Mon Sep 17 00:00:00 2001 From: Gui-Dong Han <2045gemini@gmail.com> Date: Fri, 22 Dec 2023 13:50:30 +0800 Subject: [PATCH 114/252] media: xc4000: Fix atomicity violation in xc4000_get_frequency In xc4000_get_frequency(): *freq = priv->freq_hz + priv->freq_offset; The code accesses priv->freq_hz and priv->freq_offset without holding any lock. In xc4000_set_params(): // Code that updates priv->freq_hz and priv->freq_offset ... xc4000_get_frequency() and xc4000_set_params() may execute concurrently, risking inconsistent reads of priv->freq_hz and priv->freq_offset. Since these related data may update during reading, it can result in incorrect frequency calculation, leading to atomicity violations. This possible bug is found by an experimental static analysis tool developed by our team, BassCheck[1]. This tool analyzes the locking APIs to extract function pairs that can be concurrently executed, and then analyzes the instructions in the paired functions to identify possible concurrency bugs including data races and atomicity violations. The above possible bug is reported when our tool analyzes the source code of Linux 6.2. To address this issue, it is proposed to add a mutex lock pair in xc4000_get_frequency() to ensure atomicity. With this patch applied, our tool no longer reports the possible bug, with the kernel configuration allyesconfig for x86_64. Due to the lack of associated hardware, we cannot test the patch in runtime testing, and just verify it according to the code logic. [1] https://sites.google.com/view/basscheck/ Fixes: 4c07e32884ab ("[media] xc4000: Fix get_frequency()") Cc: stable@vger.kernel.org Reported-by: BassCheck Signed-off-by: Gui-Dong Han <2045gemini@gmail.com> Signed-off-by: Hans Verkuil --- drivers/media/tuners/xc4000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c index 57ded9ff3f04..29bc63021c5a 100644 --- a/drivers/media/tuners/xc4000.c +++ b/drivers/media/tuners/xc4000.c @@ -1515,10 +1515,10 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) { struct xc4000_priv *priv = fe->tuner_priv; + mutex_lock(&priv->lock); *freq = priv->freq_hz + priv->freq_offset; if (debug) { - mutex_lock(&priv->lock); if ((priv->cur_fw.type & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) { u16 snr = 0; @@ -1529,8 +1529,8 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) return 0; } } - mutex_unlock(&priv->lock); } + mutex_unlock(&priv->lock); dprintk(1, "%s()\n", __func__); From 4a87348b50cf27263e73e0829eb0fab6d47d377a Mon Sep 17 00:00:00 2001 From: Bhavin Sharma Date: Tue, 2 Jan 2024 19:36:40 +0530 Subject: [PATCH 115/252] media: adv7180: Fix cppcheck errors ERROR: else should follow close brace '}' Signed-off-by: Bhavin Sharma Signed-off-by: Hans Verkuil --- drivers/media/i2c/adv7180.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 409b9a37f018..4829cbe32419 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1057,11 +1057,11 @@ static int adv7182_init(struct adv7180_state *state) ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x17); } - } - else + } else { adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x07); + } adv7180_write(state, ADV7180_REG_OUTPUT_CONTROL, 0x0c); adv7180_write(state, ADV7180_REG_CTRL_2, 0x40); } From 8b9911e553e762ebbe626270ce11b008736f1848 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Fri, 5 Jan 2024 13:54:37 +0100 Subject: [PATCH 116/252] media: videobuf2: Fix doc comment The documented struct member is called "planes" rather than "vb2_plane". While at it, make the comments order follow struct members order. Fixes: 2b1413245550 ("media: vb2-core: Improve kernel-doc markups") Signed-off-by: Andrzej Pietrasiewicz Acked-by: Tomasz Figa Signed-off-by: Hans Verkuil --- include/media/videobuf2-core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 56719a26a46c..d9c6b5d4e990 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -271,11 +271,11 @@ struct vb2_buffer { * skips cache sync/invalidation. * skip_cache_sync_on_finish: when set buffer's ->finish() function * skips cache sync/invalidation. + * planes: per-plane information; do not change * queued_entry: entry on the queued buffers list, which holds * all buffers queued from userspace * done_entry: entry on the list that stores all buffers ready * to be dequeued to userspace - * vb2_plane: per-plane information; do not change */ enum vb2_buffer_state state; unsigned int synced:1; From fd61d77a3d28444b2635f0c8b5a2ecd6a4d94026 Mon Sep 17 00:00:00 2001 From: Nikita Zhandarovich Date: Fri, 12 Jan 2024 05:42:26 -0800 Subject: [PATCH 117/252] media: em28xx: annotate unchecked call to media_device_register() Static analyzers generate alerts for an unchecked call to `media_device_register()`. However, in this case, the device will work reliably without the media controller API. Add a comment above the call to prevent future unnecessary changes. Suggested-by: Mauro Carvalho Chehab Fixes: 37ecc7b1278f ("[media] em28xx: add media controller support") Signed-off-by: Nikita Zhandarovich Signed-off-by: Hans Verkuil --- drivers/media/usb/em28xx/em28xx-cards.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 4d037c92af7c..bae76023cf71 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -4094,6 +4094,10 @@ static int em28xx_usb_probe(struct usb_interface *intf, * topology will likely change after the load of the em28xx subdrivers. */ #ifdef CONFIG_MEDIA_CONTROLLER + /* + * No need to check the return value, the device will still be + * usable without media controller API. + */ retval = media_device_register(dev->media_dev); #endif From 8674fd635f287a0652ae1459f6ebb15bc82c2707 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 17 Jan 2024 12:44:03 +0100 Subject: [PATCH 118/252] media: cx231xx: controls are from another device, mark this The last argument of v4l2_ctrl_add_handler() indicates whether the controls you add are from a control handler owned by another driver (true) or from the same driver (false). In this case the last argument was incorrectly set to false. The controls come from the cx25840 subdev. Signed-off-by: Hans Verkuil --- drivers/media/usb/cx231xx/cx231xx-417.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 3b75d062e602..343a4433ed24 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -1759,7 +1759,7 @@ int cx231xx_417_register(struct cx231xx *dev) dev->mpeg_ctrl_handler.ops = &cx231xx_ops; if (dev->sd_cx25840) v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl, - dev->sd_cx25840->ctrl_handler, NULL, false); + dev->sd_cx25840->ctrl_handler, NULL, true); if (dev->mpeg_ctrl_handler.hdl.error) { err = dev->mpeg_ctrl_handler.hdl.error; dprintk(3, "%s: can't add cx25840 controls\n", dev->name); From 9801b5b28c6929139d6fceeee8d739cc67bb2739 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 17 Jan 2024 15:52:04 +0100 Subject: [PATCH 119/252] media: v4l2-ctrls: show all owned controls in log_status VIDIOC_LOG_STATUS will log the controls owned by the driver. But the code didn't take into account the case where a single driver creates multiple control handlers. A good example is the vivid driver, but others use it as well. Modify v4l2_ctrl_handler_log_status() so that it really shows all controls owned by this driver. Signed-off-by: Hans Verkuil --- drivers/media/v4l2-core/v4l2-ctrls-core.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index a662fb60f73f..0accb96001db 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -2503,7 +2503,8 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) EXPORT_SYMBOL(v4l2_ctrl_handler_setup); /* Log the control name and value */ -static void log_ctrl(const struct v4l2_ctrl *ctrl, +static void log_ctrl(const struct v4l2_ctrl_handler *hdl, + struct v4l2_ctrl *ctrl, const char *prefix, const char *colon) { if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY)) @@ -2513,7 +2514,11 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl, pr_info("%s%s%s: ", prefix, colon, ctrl->name); + if (ctrl->handler != hdl) + v4l2_ctrl_lock(ctrl); ctrl->type_ops->log(ctrl); + if (ctrl->handler != hdl) + v4l2_ctrl_unlock(ctrl); if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_GRABBED | @@ -2532,7 +2537,7 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl, void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, const char *prefix) { - struct v4l2_ctrl *ctrl; + struct v4l2_ctrl_ref *ref; const char *colon = ""; int len; @@ -2544,9 +2549,12 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, if (len && prefix[len - 1] != ' ') colon = ": "; mutex_lock(hdl->lock); - list_for_each_entry(ctrl, &hdl->ctrls, node) - if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) - log_ctrl(ctrl, prefix, colon); + list_for_each_entry(ref, &hdl->ctrl_refs, node) { + if (ref->from_other_dev || + (ref->ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) + continue; + log_ctrl(hdl, ref->ctrl, prefix, colon); + } mutex_unlock(hdl->lock); } EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); From ce5d241c3ad4568c12842168288993234345c0eb Mon Sep 17 00:00:00 2001 From: Nini Song Date: Thu, 25 Jan 2024 21:28:45 +0800 Subject: [PATCH 120/252] media: cec: core: remove length check of Timer Status The valid_la is used to check the length requirements, including special cases of Timer Status. If the length is shorter than 5, that means no Duration Available is returned, the message will be forced to be invalid. However, the description of Duration Available in the spec is that this parameter may be returned when these cases, or that it can be optionally return when these cases. The key words in the spec description are flexible choices. Remove the special length check of Timer Status to fit the spec which is not compulsory about that. Signed-off-by: Nini Song Signed-off-by: Hans Verkuil --- drivers/media/cec/core/cec-adap.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c index 5741adf09a2e..559a172ebc6c 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c @@ -1151,20 +1151,6 @@ void cec_received_msg_ts(struct cec_adapter *adap, if (valid_la && min_len) { /* These messages have special length requirements */ switch (cmd) { - case CEC_MSG_TIMER_STATUS: - if (msg->msg[2] & 0x10) { - switch (msg->msg[2] & 0xf) { - case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE: - case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE: - if (msg->len < 5) - valid_la = false; - break; - } - } else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) { - if (msg->len < 5) - valid_la = false; - } - break; case CEC_MSG_RECORD_ON: switch (msg->msg[2]) { case CEC_OP_RECORD_SRC_OWN: From 27b9e36d0e08fdbb5b406260dcfe0cb59342593f Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:01 +0000 Subject: [PATCH 121/252] media: videodev2.h: Fix kerneldoc Named nested unions need their prefix: https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html#nested-structs-unions Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Tested-by: Randy Dunlap Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Hans Verkuil --- include/uapi/linux/videodev2.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 68e7ac178cc2..a8015e5e7fa4 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1041,13 +1041,13 @@ struct v4l2_requestbuffers { * struct v4l2_plane - plane info for multi-planar buffers * @bytesused: number of bytes occupied by data in the plane (payload) * @length: size of this plane (NOT the payload) in bytes - * @mem_offset: when memory in the associated struct v4l2_buffer is + * @m.mem_offset: when memory in the associated struct v4l2_buffer is * V4L2_MEMORY_MMAP, equals the offset from the start of * the device memory for this plane (or is a "cookie" that * should be passed to mmap() called on the video node) - * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer + * @m.userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer * pointing to this plane - * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file + * @m.fd: when memory is V4L2_MEMORY_DMABUF, a userspace file * descriptor associated with this plane * @m: union of @mem_offset, @userptr and @fd * @data_offset: offset in the plane to the start of data; usually 0, @@ -1085,14 +1085,14 @@ struct v4l2_plane { * @sequence: sequence count of this frame * @memory: enum v4l2_memory; the method, in which the actual video data is * passed - * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; + * @m.offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; * offset from the start of the device memory for this plane, * (or a "cookie" that should be passed to mmap() as offset) - * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; + * @m.userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; * a userspace pointer pointing to this buffer - * @fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF; + * @m.fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF; * a userspace file descriptor associated with this buffer - * @planes: for multiplanar buffers; userspace pointer to the array of plane + * @m.planes: for multiplanar buffers; userspace pointer to the array of plane * info structs for this buffer * @m: union of @offset, @userptr, @planes and @fd * @length: size in bytes of the buffer (NOT its payload) for single-plane @@ -2423,15 +2423,15 @@ struct v4l2_meta_format { /** * struct v4l2_format - stream data format - * @type: enum v4l2_buf_type; type of the data stream - * @pix: definition of an image format - * @pix_mp: definition of a multiplanar image format - * @win: definition of an overlaid image - * @vbi: raw VBI capture or output parameters - * @sliced: sliced VBI capture or output parameters - * @raw_data: placeholder for future extensions and custom formats - * @fmt: union of @pix, @pix_mp, @win, @vbi, @sliced, @sdr, @meta - * and @raw_data + * @type: enum v4l2_buf_type; type of the data stream + * @fmt.pix: definition of an image format + * @fmt.pix_mp: definition of a multiplanar image format + * @fmt.win: definition of an overlaid image + * @fmt.vbi: raw VBI capture or output parameters + * @fmt.sliced: sliced VBI capture or output parameters + * @fmt.raw_data: placeholder for future extensions and custom formats + * @fmt: union of @pix, @pix_mp, @win, @vbi, @sliced, @sdr, + * @meta and @raw_data */ struct v4l2_format { __u32 type; From f26d914262311b24723a3891a4a6f2ca6ac54ae2 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:03 +0000 Subject: [PATCH 122/252] media: cec.h: Fix kerneldoc The fields are gone, remove their documentation. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- include/media/cec.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/media/cec.h b/include/media/cec.h index d77982685116..10c9cf6058b7 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -224,8 +224,6 @@ struct cec_adap_ops { * @notifier: CEC notifier * @pin: CEC pin status struct * @cec_dir: debugfs cec directory - * @status_file: debugfs cec status file - * @error_inj_file: debugfs cec error injection file * @sequence: transmit sequence counter * @input_phys: remote control input_phys name * From d7f4cdc0647014f938ad06cd679d9ad3da070a3e Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:04 +0000 Subject: [PATCH 123/252] media: pci: dt315.h: Fix kerneldoc The field is gone, remove it. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/media/pci/dt3155/dt3155.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/pci/dt3155/dt3155.h b/drivers/media/pci/dt3155/dt3155.h index c9ce79cb5566..ce1835d9691e 100644 --- a/drivers/media/pci/dt3155/dt3155.h +++ b/drivers/media/pci/dt3155/dt3155.h @@ -162,7 +162,6 @@ * @height: frame height * @input: current input * @sequence: frame counter - * @stats: statistics structure * @regs: local copy of mmio base register * @csr2: local copy of csr2 register * @config: local copy of config register From afe81e20905c8eda5dfd5248c096e3b9240db9fc Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:05 +0000 Subject: [PATCH 124/252] media: i2c: css-quirk.h: Fix kerneldoc Kerneldoc does not seem to understand that embed doc: drivers/media/i2c/ccs/ccs-quirk.h:50: warning: Excess struct member 'write' description in 'ccs_quirk' drivers/media/i2c/ccs/ccs-quirk.h:50: warning: Excess struct member 'reg' description in 'ccs_quirk' drivers/media/i2c/ccs/ccs-quirk.h:50: warning: Excess struct member 'val' description in 'ccs_quirk' Convert into a standard doc. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs/ccs-quirk.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-quirk.h b/drivers/media/i2c/ccs/ccs-quirk.h index 0b1a64958d71..392c97109617 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.h +++ b/drivers/media/i2c/ccs/ccs-quirk.h @@ -28,11 +28,11 @@ struct ccs_sensor; * @reg_access: Register access quirk. The quirk may divert the access * to another register, or no register at all. * - * @write: Is this read (false) or write (true) access? - * @reg: Pointer to the register to access - * @value: Register value, set by the caller on write, or + * -write: Is this read (false) or write (true) access? + * -reg: Pointer to the register to access + * -val: Register value, set by the caller on write, or * by the quirk on read - * @return: 0 on success, -ENOIOCTLCMD if no register + * -return: 0 on success, -ENOIOCTLCMD if no register * access may be done by the caller (default read * value is zero), else negative error code on error * @flags: Quirk flags From 8adb1062a4950723d573e9984510406b11d397ca Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:06 +0000 Subject: [PATCH 125/252] media: i2c: adv748: Fix kerneldoc The field is gone, remove the documentation. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Reviewed-by: Kieran Bingham Signed-off-by: Hans Verkuil --- drivers/media/i2c/adv748x/adv748x.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 6f90f78f58cf..d2b5e722e997 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -173,7 +173,6 @@ struct adv748x_afe { * * @endpoints: parsed device node endpoints for each port * - * @i2c_addresses: I2C Page addresses * @i2c_clients: I2C clients for the page accesses * @regmap: regmap configuration pages. * From 9e806522183234ac71896d00e09d39e0d0c7b3a7 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:07 +0000 Subject: [PATCH 126/252] media: mediatek: jpeg: Fix kerneldoc The field is gone, remove the documentation for it. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Hans Verkuil --- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h index 8ba6e757e11a..8877eb39e807 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h @@ -144,7 +144,6 @@ struct mtk_jpegdec_clk { * @jpegenc_irq: jpeg encode irq num * @job_timeout_work: encode timeout workqueue * @hw_param: jpeg encode hw parameters - * @hw_rdy: record hw ready * @hw_state: record hw state * @hw_lock: spinlock protecting the hw device resource */ From 6ee25f7912cfd4fa9ec62977aa48c7aec2879879 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:08 +0000 Subject: [PATCH 127/252] media: mediatek: vcodec: Fix kerneldoc Those fields have been removed. They do not need to be documented. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Hans Verkuil --- drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h | 1 - drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h | 1 - drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h index ece27c880e50..1af075fc0194 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h @@ -39,7 +39,6 @@ struct vdec_fb { /** * struct mtk_video_dec_buf - Private data related to each VB2 buffer. * @m2m_buf: M2M buffer - * @list: link list * @used: Capture buffer contain decoded frame data and keep in * codec data structure * @queued_in_vb2: Capture buffer is queue in vb2 diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h index fbb3f34a73f0..aa7d08afc2f4 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h @@ -22,7 +22,6 @@ struct mtk_vcodec_dec_ctx; * in place of inst_addr in messages. * @signaled : 1 - Host has received ack message from VPU, 0 - not received * @ctx : context for v4l2 layer integration - * @dev : platform device of VPU * @wq : wait queue to wait VPU message ack * @handler : ipi handler for each decoder * @codec_type : use codec type to separate different codecs diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h index 82246401ed4a..908d8179b2d2 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h @@ -26,7 +26,6 @@ /** * struct mtk_video_enc_buf - Private data related to each VB2 buffer. * @m2m_buf: M2M buffer - * @list: list that buffer link to * @param_change: Types of encode parameter change before encoding this * buffer * @enc_params: Encode parameters changed before encode this buffer From 147577fa0a785037e9b8217fa12480128dba4c64 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:09 +0000 Subject: [PATCH 128/252] media: verisilicon: Fix kerneldoc The field is not part of the structure. Remove the doc. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/media/platform/verisilicon/hantro.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 6f5eb975d0e3..811260dc3c77 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -237,7 +237,6 @@ struct hantro_dev { * @codec_ops: Set of operations related to codec mode. * @postproc: Post-processing context. * @h264_dec: H.264-decoding context. - * @jpeg_enc: JPEG-encoding context. * @mpeg2_dec: MPEG-2-decoding context. * @vp8_dec: VP8-decoding context. * @hevc_dec: HEVC-decoding context. From 52a55df78fbff37309fe4f8b4cd4cf7751a13614 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:10 +0000 Subject: [PATCH 129/252] media: qcom: venus: Fix kerneldoc Remove doc for missing field. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/media/platform/qcom/venus/core.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 4a633261ece4..a39986ce79f1 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -428,7 +428,6 @@ enum venus_inst_modes { * @error: an error returned during last HFI sync operation * @session_error: a flag rised by HFI interface in case of session error * @ops: HFI operations - * @priv: a private for HFI operations callbacks * @session_type: the type of the session (decoder or encoder) * @hprop: a union used as a holder by get property * @core_acquired: the Core has been acquired From 0e01357e94435649263cdfdb62f1cc7f6669ec21 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:11 +0000 Subject: [PATCH 130/252] media: samsung: exynos4-is: Fix kerneldoc Remove doc from missing fields. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/exynos4-is/fimc-lite.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite.h b/drivers/media/platform/samsung/exynos4-is/fimc-lite.h index ddf29e0b5b1c..2d96fb00a5c6 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-lite.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite.h @@ -117,8 +117,6 @@ struct flite_buffer { * @ctrl_handler: v4l2 control handler * @test_pattern: test pattern controls * @index: FIMC-LITE platform device index - * @pipeline: video capture pipeline data structure - * @pipeline_ops: media pipeline ops for the video node driver * @slock: spinlock protecting this data structure and the hw registers * @lock: mutex serializing video device and the subdev operations * @clock: FIMC-LITE gate clock @@ -134,7 +132,6 @@ struct flite_buffer { * @active_buf_q: the queue head of buffers scheduled in hardware * @vb_queue: vb2 buffers queue * @buf_index: helps to keep track of the DMA start address register index - * @active_buf_count: number of video buffers scheduled in hardware * @frame_count: the captured frames counter * @reqbufs_count: the number of buffers requested with REQBUFS ioctl * @events: event info From 0e7835767e2accf63b9c4fcdf3fedafceff56eb8 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:12 +0000 Subject: [PATCH 131/252] media: samsung: s5p-mfc: Fix kerneldoc Remove doc from missing fields. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h index 0f6e260746c9..3cc2a4f5c40a 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h @@ -612,7 +612,6 @@ struct s5p_mfc_codec_ops { * @chroma_dpb_size: dpb buffer size for chroma * @me_buffer_size: size of the motion estimation buffer * @tmv_buffer_size: size of temporal predictor motion vector buffer - * @frame_type: used to force the type of the next encoded frame * @ref_queue: list of the reference buffers for encoding * @force_frame_type: encoder's frame type forcing control * @ref_queue_cnt: number of the buffers in the reference list From 3edcdd61ea6794e92cb04f9873aab23bdd632145 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:13 +0000 Subject: [PATCH 132/252] media: dvb-usb: Fix kerneldoc Remove kerneldoc from missing fields. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/media/usb/dvb-usb/dvb-usb.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h index 0990aa4a17bb..cbb0541d4dc1 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb.h +++ b/drivers/media/usb/dvb-usb/dvb-usb.h @@ -126,8 +126,6 @@ struct usb_data_stream_properties { * @caps: capabilities of the DVB USB device. * @pid_filter_count: number of PID filter position in the optional hardware * PID-filter. - * @num_frontends: number of frontends of the DVB USB adapter. - * @frontend_ctrl: called to power on/off active frontend. * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the * device (not URB submitting/killing). * This callback will be called without data URBs being active - data URBs From 0284641e888df3ebd064c362f91e9e9d3e813663 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 26 Jan 2024 23:16:15 +0000 Subject: [PATCH 133/252] media: staging: meson: Fix kerneldoc Remove documentation from missing field. Signed-off-by: Ricardo Ribalda Reviewed-by: Randy Dunlap Signed-off-by: Hans Verkuil --- drivers/staging/media/meson/vdec/vdec.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/meson/vdec/vdec.h b/drivers/staging/media/meson/vdec/vdec.h index 0906b8fb5cc6..258685177700 100644 --- a/drivers/staging/media/meson/vdec/vdec.h +++ b/drivers/staging/media/meson/vdec/vdec.h @@ -101,7 +101,6 @@ struct amvdec_core { * @conf_esparser: mandatory call to let the vdec configure the ESPARSER * @vififo_level: mandatory call to get the current amount of data * in the VIFIFO - * @use_offsets: mandatory call. Returns 1 if the VDEC supports vififo offsets */ struct amvdec_ops { int (*start)(struct amvdec_session *sess); From 6c1a584a15d6ee35fa3448b84379150b401eb148 Mon Sep 17 00:00:00 2001 From: Aakarsh Jain Date: Wed, 31 Jan 2024 12:37:41 +0530 Subject: [PATCH 134/252] MAINTAINERS: Add entry for Samsung MFC DT Schema Add device tree schema entry for Samsung MFC. Signed-off-by: Aakarsh Jain Signed-off-by: Hans Verkuil --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8999497011a2..1a89e0d2ac61 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2752,6 +2752,7 @@ M: Andrzej Hajda L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-media@vger.kernel.org S: Maintained +F: Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml F: drivers/media/platform/samsung/s5p-mfc/ ARM/SOCFPGA ARCHITECTURE From 8cf9c5051076e0eb958f4361d50d8b0c3ee6691c Mon Sep 17 00:00:00 2001 From: Zhipeng Lu Date: Thu, 1 Feb 2024 20:47:53 +0800 Subject: [PATCH 135/252] media: v4l2-tpg: fix some memleaks in tpg_alloc In tpg_alloc, resources should be deallocated in each and every error-handling paths, since they are allocated in for statements. Otherwise there would be memleaks because tpg_free is called only when tpg_alloc return 0. Fixes: 63881df94d3e ("[media] vivid: add the Test Pattern Generator") Signed-off-by: Zhipeng Lu Signed-off-by: Hans Verkuil --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 52 +++++++++++++++---- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index a366566f22c3..642c48e8c1f5 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -113,6 +113,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) { unsigned pat; unsigned plane; + int ret = 0; tpg->max_line_width = max_w; for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) { @@ -121,14 +122,18 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) tpg->lines[pat][plane] = vzalloc(array3_size(max_w, 2, pixelsz)); - if (!tpg->lines[pat][plane]) - return -ENOMEM; + if (!tpg->lines[pat][plane]) { + ret = -ENOMEM; + goto free_lines; + } if (plane == 0) continue; tpg->downsampled_lines[pat][plane] = vzalloc(array3_size(max_w, 2, pixelsz)); - if (!tpg->downsampled_lines[pat][plane]) - return -ENOMEM; + if (!tpg->downsampled_lines[pat][plane]) { + ret = -ENOMEM; + goto free_lines; + } } } for (plane = 0; plane < TPG_MAX_PLANES; plane++) { @@ -136,18 +141,45 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) tpg->contrast_line[plane] = vzalloc(array_size(pixelsz, max_w)); - if (!tpg->contrast_line[plane]) - return -ENOMEM; + if (!tpg->contrast_line[plane]) { + ret = -ENOMEM; + goto free_contrast_line; + } tpg->black_line[plane] = vzalloc(array_size(pixelsz, max_w)); - if (!tpg->black_line[plane]) - return -ENOMEM; + if (!tpg->black_line[plane]) { + ret = -ENOMEM; + goto free_contrast_line; + } tpg->random_line[plane] = vzalloc(array3_size(max_w, 2, pixelsz)); - if (!tpg->random_line[plane]) - return -ENOMEM; + if (!tpg->random_line[plane]) { + ret = -ENOMEM; + goto free_contrast_line; + } } return 0; + +free_contrast_line: + for (plane = 0; plane < TPG_MAX_PLANES; plane++) { + vfree(tpg->contrast_line[plane]); + vfree(tpg->black_line[plane]); + vfree(tpg->random_line[plane]); + tpg->contrast_line[plane] = NULL; + tpg->black_line[plane] = NULL; + tpg->random_line[plane] = NULL; + } +free_lines: + for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) + for (plane = 0; plane < TPG_MAX_PLANES; plane++) { + vfree(tpg->lines[pat][plane]); + tpg->lines[pat][plane] = NULL; + if (plane == 0) + continue; + vfree(tpg->downsampled_lines[pat][plane]); + tpg->downsampled_lines[pat][plane] = NULL; + } + return ret; } EXPORT_SYMBOL_GPL(tpg_alloc); From 8f94b49a5b5d386c038e355bef6347298aabd211 Mon Sep 17 00:00:00 2001 From: Zhipeng Lu Date: Thu, 1 Feb 2024 20:48:44 +0800 Subject: [PATCH 136/252] media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity The entity->name (i.e. name) is allocated in v4l2_m2m_register_entity but isn't freed in its following error-handling paths. This patch adds such deallocation to prevent memleak of entity->name. Fixes: be2fff656322 ("media: add helpers for memory-to-memory media controller") Signed-off-by: Zhipeng Lu Signed-off-by: Hans Verkuil --- drivers/media/v4l2-core/v4l2-mem2mem.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 9e983176542b..75517134a5e9 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -1087,11 +1087,17 @@ static int v4l2_m2m_register_entity(struct media_device *mdev, entity->function = function; ret = media_entity_pads_init(entity, num_pads, pads); - if (ret) + if (ret) { + kfree(entity->name); + entity->name = NULL; return ret; + } ret = media_device_register_entity(mdev, entity); - if (ret) + if (ret) { + kfree(entity->name); + entity->name = NULL; return ret; + } return 0; } From 83d48b5d39261be16902872367e89a0d1a874b0d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 2 Feb 2024 09:25:44 +0100 Subject: [PATCH 137/252] media: v4l2-common.h: kerneldoc: correctly format return values Building the kerneldoc resulted in two errors: Documentation/media/driver-api/v4l2-common:6: ./include/media/v4l2-common.h:566: ERROR: Unexpected indentation. Documentation/media/driver-api/v4l2-common:6: ./include/media/v4l2-common.h:567: WARNING: Block quote ends without a blank line; unexpected unindent. Format v4l2_link_freq_to_bitmap according to the kerneldoc standard. The v4l2_fill_pixfmt_mp function also had incorrect return value formatting, although that didn't report an error/warning, but it looked ugly in the generated documentation. So fix that one as well. Signed-off-by: Hans Verkuil Fixes: a68e88e2cf9e ("media: v4l: Add a helper for setting up link-frequencies control") Acked-by: Sakari Ailus --- include/media/v4l2-common.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index cd2163f24f8a..ffed604bc29a 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -536,9 +536,10 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, * V4L2_CID_LINK_FREQ control implemented by the transmitter, or value * calculated based on the V4L2_CID_PIXEL_RATE implemented by the transmitter. * - * Returns link frequency on success, otherwise a negative error code: - * -ENOENT: Link frequency or pixel rate control not found - * -EINVAL: Invalid link frequency value + * Return: + * * >0: Link frequency + * * %-ENOENT: Link frequency or pixel rate control not found + * * %-EINVAL: Invalid link frequency value */ s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul, unsigned int div); @@ -560,11 +561,11 @@ u32 v4l2_fraction_to_interval(u32 numerator, u32 denominator); * system firmware and sets the corresponding bits in @bitmap (after first * zeroing it). * - * Return values: - * 0: Success - * -ENOENT: No match found between driver-supported link frequencies and - * those available in firmware. - * -ENODATA: No link frequencies were specified in firmware. + * Return: + * * %0: Success + * * %-ENOENT: No match found between driver-supported link frequencies and + * those available in firmware. + * * %-ENODATA: No link frequencies were specified in firmware. */ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, unsigned int num_of_fw_link_freqs, From 9590d1a03df53d2f95876085dc4dd3afa8454843 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 2 Feb 2024 10:21:20 +0100 Subject: [PATCH 138/252] media: atomisp: make dbgopt static This fixes a sparse warning: drivers/staging/media/atomisp/pci/atomisp_drvfs.c:40:14: warning: symbol 'dbgopt' was not declared. Should it be static? Signed-off-by: Hans Verkuil --- drivers/staging/media/atomisp/pci/atomisp_drvfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c index 293171da1266..ba7dd569a55a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c +++ b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c @@ -37,7 +37,7 @@ * bit 1: running binary * bit 2: memory statistic */ -unsigned int dbgopt = OPTION_BIN_LIST; +static unsigned int dbgopt = OPTION_BIN_LIST; static inline int iunit_dump_dbgopt(struct atomisp_device *isp, unsigned int opt) From cfe0c5e3d928cfa326952a47e70aaf4bc82756c4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 2 Feb 2024 11:17:30 +0100 Subject: [PATCH 139/252] media: atomisp: don't use sizeof(NULL) Check the size of another pointer instead of NULL. This fixes this smatch warning: drivers/staging/media/atomisp/pci/sh_css.c:3609 ia_css_pipe_enqueue_buffer() warn: sizeof(NUMBER)? Signed-off-by: Hans Verkuil --- drivers/staging/media/atomisp/pci/sh_css.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 1d1fbda75da1..938a4ea89c59 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -3606,7 +3606,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, assert(pipeline || pipe_id == IA_CSS_PIPE_ID_COPY); - assert(sizeof(NULL) <= sizeof(ddr_buffer.kernel_ptr)); + assert(sizeof(void *) <= sizeof(ddr_buffer.kernel_ptr)); ddr_buffer.kernel_ptr = HOST_ADDRESS(NULL); ddr_buffer.cookie_ptr = buffer->driver_cookie; ddr_buffer.timing_data = buffer->timing_data; From c9cd7308d64b13741ee03be81836a324fc4d657d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 2 Feb 2024 16:23:25 -0600 Subject: [PATCH 140/252] media: dt-bindings: techwell,tw9900: Fix port schema ref The port@0 node doesn't define any extra properties in the port or endpoint nodes, so the $ref should be to "/properties/port" instead as it restricts extra properties. Fixes: 0f82ffa9a295 ("media: dt-bindings: media: i2c: Add bindings for TW9900") Signed-off-by: Rob Herring Signed-off-by: Hans Verkuil --- .../devicetree/bindings/media/i2c/techwell,tw9900.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml b/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml index e37317f81072..c9673391afdb 100644 --- a/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml +++ b/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml @@ -36,7 +36,7 @@ properties: properties: port@0: - $ref: /schemas/graph.yaml#/$defs/port-base + $ref: /schemas/graph.yaml#/properties/port description: Analog input port properties: From e76681afdc02b3ee0417d2f47825624697afe249 Mon Sep 17 00:00:00 2001 From: Dorcas Anono Litunya Date: Sat, 3 Feb 2024 11:58:05 +0300 Subject: [PATCH 141/252] documentation: media: vivid: Modify typo in documentation Correct the default value of node_type vivid parameter to 0xe1d3d. Signed-off-by: Dorcas Anono Litunya Signed-off-by: Hans Verkuil --- Documentation/admin-guide/media/vivid.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index 58ac25b2c385..b6f658c0997e 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -60,7 +60,7 @@ all configurable using the following module options: - node_types: which devices should each driver instance create. An array of - hexadecimal values, one for each instance. The default is 0x1d3d. + hexadecimal values, one for each instance. The default is 0xe1d3d. Each value is a bitmask with the following meaning: - bit 0: Video Capture node From 009d312a3fd93a2bfed93d7a1c76e1f362384f08 Mon Sep 17 00:00:00 2001 From: "Ricardo B. Marliere" Date: Sat, 3 Feb 2024 12:31:26 -0300 Subject: [PATCH 142/252] media: cec: make cec_bus_type const Now that the driver core can properly handle constant struct bus_type, move the cec_bus_type variable to be a constant structure as well, placing it into read-only memory which can not be modified at runtime. Cc: Greg Kroah-Hartman Suggested-by: Greg Kroah-Hartman Signed-off-by: Ricardo B. Marliere Reviewed-by: Greg Kroah-Hartman Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/cec/core/cec-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index 7e153c5cad04..5a54db839e5d 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -93,7 +93,7 @@ static void cec_devnode_release(struct device *cd) cec_delete_adapter(to_cec_adapter(devnode)); } -static struct bus_type cec_bus_type = { +static const struct bus_type cec_bus_type = { .name = CEC_NAME, }; From e248cde98470ca3d9449e2b744b11279681f8e18 Mon Sep 17 00:00:00 2001 From: "Ricardo B. Marliere" Date: Sat, 3 Feb 2024 12:31:27 -0300 Subject: [PATCH 143/252] media: media-devnode: make media_bus_type const Now that the driver core can properly handle constant struct bus_type, move the media_bus_type variable to be a constant structure as well, placing it into read-only memory which can not be modified at runtime. Cc: Greg Kroah-Hartman Suggested-by: Greg Kroah-Hartman Signed-off-by: Ricardo B. Marliere Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/mc/mc-devnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c index 9c8fe9335dc1..7f67825c8757 100644 --- a/drivers/media/mc/mc-devnode.c +++ b/drivers/media/mc/mc-devnode.c @@ -63,7 +63,7 @@ static void media_devnode_release(struct device *cd) pr_debug("%s: Media Devnode Deallocated\n", __func__); } -static struct bus_type media_bus_type = { +static const struct bus_type media_bus_type = { .name = MEDIA_NAME, }; From 78f0daa026d4c5e192d31801d1be6caf88250220 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 14 Jan 2024 15:55:40 +0200 Subject: [PATCH 144/252] media: mc: Add local pad to pipeline regardless of the link state When building pipelines by following links, the media_pipeline_explore_next_link() function only traverses enabled links. The remote pad of a disabled link is not added to the pipeline, and neither is the local pad. While the former is correct as disabled links should not be followed, not adding the local pad breaks processing of the MEDIA_PAD_FL_MUST_CONNECT flag. The MEDIA_PAD_FL_MUST_CONNECT flag is checked in the __media_pipeline_start() function that iterates over all pads after populating the pipeline. If the pad is not present, the check gets skipped, rendering it useless. Fix this by adding the local pad of all links regardless of their state, only skipping the remote pad for disabled links. Cc: stable@vger.kernel.org # 6.1 Fixes: ae219872834a ("media: mc: entity: Rewrite media_pipeline_start()") Reported-by: Frieder Schrempf Closes: https://lore.kernel.org/linux-media/7658a15a-80c5-219f-2477-2a94ba6c6ba1@kontron.de Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/mc/mc-entity.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 543a392f8635..a6f28366106f 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -620,13 +620,6 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, link->source->entity->name, link->source->index, link->sink->entity->name, link->sink->index); - /* Skip links that are not enabled. */ - if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { - dev_dbg(walk->mdev->dev, - "media pipeline: skipping link (disabled)\n"); - return 0; - } - /* Get the local pad and remote pad. */ if (link->source->entity == pad->entity) { local = link->source; @@ -648,13 +641,20 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, } /* - * Add the local and remote pads of the link to the pipeline and push - * them to the stack, if they're not already present. + * Add the local pad of the link to the pipeline and push it to the + * stack, if not already present. */ ret = media_pipeline_add_pad(pipe, walk, local); if (ret) return ret; + /* Similarly, add the remote pad, but only if the link is enabled. */ + if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { + dev_dbg(walk->mdev->dev, + "media pipeline: skipping link (disabled)\n"); + return 0; + } + ret = media_pipeline_add_pad(pipe, walk, remote); if (ret) return ret; From 422f7af75d03d50895938d38bc9cb8be759c440f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 15 Jan 2024 00:24:12 +0200 Subject: [PATCH 145/252] media: mc: Fix flags handling when creating pad links The media_create_pad_link() function doesn't correctly clear reject link type flags, nor does it set the DATA_LINK flag. It only works because the MEDIA_LNK_FL_DATA_LINK flag's value is 0. Fix it by returning an error if any link type flag is set. This doesn't introduce any regression, as nobody calls the media_create_pad_link() function with link type flags (easily checked by grepping for the flag in the source code, there are very few hits). Set the MEDIA_LNK_FL_DATA_LINK explicitly, which is a no-op that the compiler will optimize out, but is still useful to make the code more explicit and easier to understand. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/mc/mc-entity.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index a6f28366106f..7839e3f68efa 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -1092,6 +1092,11 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_link *link; struct media_link *backlink; + if (flags & MEDIA_LNK_FL_LINK_TYPE) + return -EINVAL; + + flags |= MEDIA_LNK_FL_DATA_LINK; + if (WARN_ON(!source || !sink) || WARN_ON(source_pad >= source->num_pads) || WARN_ON(sink_pad >= sink->num_pads)) @@ -1107,7 +1112,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, link->source = &source->pads[source_pad]; link->sink = &sink->pads[sink_pad]; - link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK; + link->flags = flags; /* Initialize graph object embedded at the new link */ media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK, From eb2f932100288dbb881eadfed02e1459c6b9504c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 1 Dec 2023 16:06:04 +0100 Subject: [PATCH 146/252] media: nxp: imx8-isi: Check whether crossbar pad is non-NULL before access When translating source to sink streams in the crossbar subdev, the driver tries to locate the remote subdev connected to the sink pad. The remote pad may be NULL, if userspace tries to enable a stream that ends at an unconnected crossbar sink. When that occurs, the driver dereferences the NULL pad, leading to a crash. Prevent the crash by checking if the pad is NULL before using it, and return an error if it is. Cc: stable@vger.kernel.org # 6.1 Fixes: cf21f328fcaf ("media: nxp: Add i.MX8 ISI driver") Signed-off-by: Marek Vasut Reviewed-by: Kieran Bingham Reviewed-by: Fabio Estevam Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20231201150614.63300-1-marex@denx.de Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c index 575f17337388..1bb1334ec6f2 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c @@ -160,8 +160,14 @@ mxc_isi_crossbar_xlate_streams(struct mxc_isi_crossbar *xbar, } pad = media_pad_remote_pad_first(&xbar->pads[sink_pad]); - sd = media_entity_to_v4l2_subdev(pad->entity); + if (!pad) { + dev_dbg(xbar->isi->dev, + "no pad connected to crossbar input %u\n", + sink_pad); + return ERR_PTR(-EPIPE); + } + sd = media_entity_to_v4l2_subdev(pad->entity); if (!sd) { dev_dbg(xbar->isi->dev, "no entity connected to crossbar input %u\n", From baeddf94aa61879b118f2faa37ed126d772670cc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 15 Jan 2024 00:30:02 +0200 Subject: [PATCH 147/252] media: mc: Add num_links flag to media_pad Maintain a counter of the links connected to a pad in the media_pad structure. This helps checking if a pad is connected to anything, which will be used in the pipeline building code. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/mc/mc-entity.c | 6 ++++++ include/media/media-entity.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 7839e3f68efa..c2d8f59b62c1 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -1038,6 +1038,9 @@ static void __media_entity_remove_link(struct media_entity *entity, /* Remove the reverse links for a data link. */ if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) { + link->source->num_links--; + link->sink->num_links--; + if (link->source->entity == entity) remote = link->sink->entity; else @@ -1143,6 +1146,9 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, sink->num_links++; source->num_links++; + link->source->num_links++; + link->sink->num_links++; + return 0; } EXPORT_SYMBOL_GPL(media_create_pad_link); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index c79176ed6299..0393b23129eb 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -225,6 +225,7 @@ enum media_pad_signal_type { * @graph_obj: Embedded structure containing the media object common data * @entity: Entity this pad belongs to * @index: Pad index in the entity pads array, numbered from 0 to n + * @num_links: Number of links connected to this pad * @sig_type: Type of the signal inside a media pad * @flags: Pad flags, as defined in * :ref:`include/uapi/linux/media.h ` @@ -236,6 +237,7 @@ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ struct media_entity *entity; u16 index; + u16 num_links; enum media_pad_signal_type sig_type; unsigned long flags; From 9ec9109cf9f611e3ec9ed0355afcc7aae5e73176 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 15 Jan 2024 00:30:02 +0200 Subject: [PATCH 148/252] media: mc: Rename pad variable to clarify intent The pad local variable in the media_pipeline_explore_next_link() function is used to store the pad through which the entity has been reached. Rename it to origin to reflect that and make the code easier to read. This will be even more important in subsequent commits when expanding the function with additional logic. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/mc/mc-entity.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index c2d8f59b62c1..5907925ffd89 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -605,13 +605,13 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, struct media_pipeline_walk *walk) { struct media_pipeline_walk_entry *entry = media_pipeline_walk_top(walk); - struct media_pad *pad; + struct media_pad *origin; struct media_link *link; struct media_pad *local; struct media_pad *remote; int ret; - pad = entry->pad; + origin = entry->pad; link = list_entry(entry->links, typeof(*link), list); media_pipeline_walk_pop(walk); @@ -621,7 +621,7 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, link->sink->entity->name, link->sink->index); /* Get the local pad and remote pad. */ - if (link->source->entity == pad->entity) { + if (link->source->entity == origin->entity) { local = link->source; remote = link->sink; } else { @@ -633,8 +633,9 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, * Skip links that originate from a different pad than the incoming pad * that is not connected internally in the entity to the incoming pad. */ - if (pad != local && - !media_entity_has_pad_interdep(pad->entity, pad->index, local->index)) { + if (origin != local && + !media_entity_has_pad_interdep(origin->entity, origin->index, + local->index)) { dev_dbg(walk->mdev->dev, "media pipeline: skipping link (no route)\n"); return 0; From b3decc5ce7d778224d266423b542326ad469cb5f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 15 Jan 2024 01:04:52 +0200 Subject: [PATCH 149/252] media: mc: Expand MUST_CONNECT flag to always require an enabled link The MEDIA_PAD_FL_MUST_CONNECT flag indicates that the pad requires an enabled link to stream, but only if it has any link at all. This makes little sense, as if a pad is part of a pipeline, there are very few use cases for an active link to be mandatory only if links exist at all. A review of in-tree drivers confirms they all need an enabled link for pads marked with the MEDIA_PAD_FL_MUST_CONNECT flag. Expand the scope of the flag by rejecting pads that have no links at all. This requires modifying the pipeline build code to add those pads to the pipeline. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil --- .../media/mediactl/media-types.rst | 11 ++-- drivers/media/mc/mc-entity.c | 53 +++++++++++++++---- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst b/Documentation/userspace-api/media/mediactl/media-types.rst index 0ffeece1e0c8..6332e8395263 100644 --- a/Documentation/userspace-api/media/mediactl/media-types.rst +++ b/Documentation/userspace-api/media/mediactl/media-types.rst @@ -375,12 +375,11 @@ Types and flags used to represent the media graph elements are origins of links. * - ``MEDIA_PAD_FL_MUST_CONNECT`` - - If this flag is set and the pad is linked to any other pad, then - at least one of those links must be enabled for the entity to be - able to stream. There could be temporary reasons (e.g. device - configuration dependent) for the pad to need enabled links even - when this flag isn't set; the absence of the flag doesn't imply - there is none. + - If this flag is set, then for this pad to be able to stream, it must + be connected by at least one enabled link. There could be temporary + reasons (e.g. device configuration dependent) for the pad to need + enabled links even when this flag isn't set; the absence of the flag + doesn't imply there is none. One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE`` diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 5907925ffd89..0e28b9a7936e 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -535,14 +535,15 @@ static int media_pipeline_walk_push(struct media_pipeline_walk *walk, /* * Move the top entry link cursor to the next link. If all links of the entry - * have been visited, pop the entry itself. + * have been visited, pop the entry itself. Return true if the entry has been + * popped. */ -static void media_pipeline_walk_pop(struct media_pipeline_walk *walk) +static bool media_pipeline_walk_pop(struct media_pipeline_walk *walk) { struct media_pipeline_walk_entry *entry; if (WARN_ON(walk->stack.top < 0)) - return; + return false; entry = media_pipeline_walk_top(walk); @@ -552,7 +553,7 @@ static void media_pipeline_walk_pop(struct media_pipeline_walk *walk) walk->stack.top); walk->stack.top--; - return; + return true; } entry->links = entry->links->next; @@ -560,6 +561,8 @@ static void media_pipeline_walk_pop(struct media_pipeline_walk *walk) dev_dbg(walk->mdev->dev, "media pipeline: moved entry %u to next link\n", walk->stack.top); + + return false; } /* Free all memory allocated while walking the pipeline. */ @@ -609,11 +612,12 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, struct media_link *link; struct media_pad *local; struct media_pad *remote; + bool last_link; int ret; origin = entry->pad; link = list_entry(entry->links, typeof(*link), list); - media_pipeline_walk_pop(walk); + last_link = media_pipeline_walk_pop(walk); dev_dbg(walk->mdev->dev, "media pipeline: exploring link '%s':%u -> '%s':%u\n", @@ -638,7 +642,7 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, local->index)) { dev_dbg(walk->mdev->dev, "media pipeline: skipping link (no route)\n"); - return 0; + goto done; } /* @@ -653,13 +657,44 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe, if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { dev_dbg(walk->mdev->dev, "media pipeline: skipping link (disabled)\n"); - return 0; + goto done; } ret = media_pipeline_add_pad(pipe, walk, remote); if (ret) return ret; +done: + /* + * If we're done iterating over links, iterate over pads of the entity. + * This is necessary to discover pads that are not connected with any + * link. Those are dead ends from a pipeline exploration point of view, + * but are still part of the pipeline and need to be added to enable + * proper validation. + */ + if (!last_link) + return 0; + + dev_dbg(walk->mdev->dev, + "media pipeline: adding unconnected pads of '%s'\n", + local->entity->name); + + media_entity_for_each_pad(origin->entity, local) { + /* + * Skip the origin pad (already handled), pad that have links + * (already discovered through iterating over links) and pads + * not internally connected. + */ + if (origin == local || !local->num_links || + !media_entity_has_pad_interdep(origin->entity, origin->index, + local->index)) + continue; + + ret = media_pipeline_add_pad(pipe, walk, local); + if (ret) + return ret; + } + return 0; } @@ -771,7 +806,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad, struct media_pad *pad = ppad->pad; struct media_entity *entity = pad->entity; bool has_enabled_link = false; - bool has_link = false; struct media_link *link; dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name, @@ -801,7 +835,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad, /* Record if the pad has links and enabled links. */ if (link->flags & MEDIA_LNK_FL_ENABLED) has_enabled_link = true; - has_link = true; /* * Validate the link if it's enabled and has the @@ -839,7 +872,7 @@ __must_check int __media_pipeline_start(struct media_pad *pad, * 3. If the pad has the MEDIA_PAD_FL_MUST_CONNECT flag set, * ensure that it has either no link or an enabled link. */ - if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && has_link && + if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && !has_enabled_link) { dev_dbg(mdev->dev, "Pad '%s':%u must be connected by an enabled link\n", From 9b71021b2ea537632b01e51e3f003df24a637858 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 15 Jan 2024 04:16:29 +0200 Subject: [PATCH 150/252] media: nxp: imx8-isi: Mark all crossbar sink pads as MUST_CONNECT All the sink pads of the crossbar switch require an active link if they're part of the pipeline. Mark them with the MEDIA_PAD_FL_MUST_CONNECT flag to fail pipeline validation if they're not connected. This allows removing a manual check when translating streams. Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil --- .../media/platform/nxp/imx8-isi/imx8-isi-crossbar.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c index 1bb1334ec6f2..93a55c97cd17 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c @@ -160,13 +160,6 @@ mxc_isi_crossbar_xlate_streams(struct mxc_isi_crossbar *xbar, } pad = media_pad_remote_pad_first(&xbar->pads[sink_pad]); - if (!pad) { - dev_dbg(xbar->isi->dev, - "no pad connected to crossbar input %u\n", - sink_pad); - return ERR_PTR(-EPIPE); - } - sd = media_entity_to_v4l2_subdev(pad->entity); if (!sd) { dev_dbg(xbar->isi->dev, @@ -475,7 +468,8 @@ int mxc_isi_crossbar_init(struct mxc_isi_dev *isi) } for (i = 0; i < xbar->num_sinks; ++i) - xbar->pads[i].flags = MEDIA_PAD_FL_SINK; + xbar->pads[i].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT; for (i = 0; i < xbar->num_sources; ++i) xbar->pads[i + xbar->num_sinks].flags = MEDIA_PAD_FL_SOURCE; From ee171dc5050212ea8677ed5cb777746cf00d72d9 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Sun, 28 Jan 2024 16:13:56 +0000 Subject: [PATCH 151/252] media: nxp: imx8-isi: Factor out a variable gcc-11 seems to believe that the coeffs variable can be used uninitialized. Refactor the code and remove the cscen variable to convince gcc that we are doing a good job. drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c:218:20: warning: 'coeffs' may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Ricardo Ribalda Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20240128-gcc-11-warnings-v1-1-52bbdf492049@chromium.org Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c index 19e80b95ffea..5623914f95e6 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c @@ -215,8 +215,7 @@ static void mxc_isi_channel_set_csc(struct mxc_isi_pipe *pipe, [MXC_ISI_ENC_RGB] = "RGB", [MXC_ISI_ENC_YUV] = "YUV", }; - const u32 *coeffs; - bool cscen = true; + const u32 *coeffs = NULL; u32 val; val = mxc_isi_read(pipe, CHNL_IMG_CTRL); @@ -235,14 +234,13 @@ static void mxc_isi_channel_set_csc(struct mxc_isi_pipe *pipe, val |= CHNL_IMG_CTRL_CSC_MODE(CHNL_IMG_CTRL_CSC_MODE_RGB2YCBCR); } else { /* Bypass CSC */ - cscen = false; val |= CHNL_IMG_CTRL_CSC_BYPASS; } dev_dbg(pipe->isi->dev, "CSC: %s -> %s\n", encodings[in_encoding], encodings[out_encoding]); - if (cscen) { + if (coeffs) { mxc_isi_write(pipe, CHNL_CSC_COEFF0, coeffs[0]); mxc_isi_write(pipe, CHNL_CSC_COEFF1, coeffs[1]); mxc_isi_write(pipe, CHNL_CSC_COEFF2, coeffs[2]); @@ -253,7 +251,7 @@ static void mxc_isi_channel_set_csc(struct mxc_isi_pipe *pipe, mxc_isi_write(pipe, CHNL_IMG_CTRL, val); - *bypass = !cscen; + *bypass = !coeffs; } void mxc_isi_channel_set_alpha(struct mxc_isi_pipe *pipe, u8 alpha) From b83e2a91426ae4ee545e93a7dd61f03c3b5a417c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sun, 4 Feb 2024 23:50:12 +0200 Subject: [PATCH 152/252] Revert "media: ov08x40: Reduce start streaming time" This reverts commit feb8831be9d468ee961289c6a275536a1ee0011c. Commit feb8831be9d468ee961289c6a275536a1ee0011c contained unintentional changes to Documentation/devicetree/bindings/media/video-interfaces.yaml and arch/arm/boot/dts/ti/omap/omap3-n9.dts. Revert the entire patch. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- .../bindings/media/video-interfaces.yaml | 2 +- arch/arm/boot/dts/ti/omap/omap3-n9.dts | 2 +- drivers/media/i2c/ov08x40.c | 1209 ++++++++++++++++- 3 files changed, 1154 insertions(+), 59 deletions(-) diff --git a/Documentation/devicetree/bindings/media/video-interfaces.yaml b/Documentation/devicetree/bindings/media/video-interfaces.yaml index ea511f2fed98..26e3e7d7c67b 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.yaml +++ b/Documentation/devicetree/bindings/media/video-interfaces.yaml @@ -190,7 +190,7 @@ properties: Allow MIPI CSI-2 non-continuous clock mode. link-frequencies: - $ref: /schemas/types.yaml#/definitions/uint32-array + $ref: /schemas/types.yaml#/definitions/uint64-array description: Allowed data bus frequencies. For MIPI CSI-2, for instance, this is the actual frequency of the bus, not bits per clock per lane value. An array diff --git a/arch/arm/boot/dts/ti/omap/omap3-n9.dts b/arch/arm/boot/dts/ti/omap/omap3-n9.dts index 728a8fcf25b3..a3cf3f443785 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-n9.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-n9.dts @@ -26,7 +26,7 @@ smia_1: camera@10 { flash-leds = <&as3645a_flash &as3645a_indicator>; port { smia_1_1: endpoint { - link-frequencies = /bits/ 32 <199200000 210000000 499200000>; + link-frequencies = /bits/ 64 <199200000 210000000 499200000>; clock-lanes = <0>; data-lanes = <1 2>; remote-endpoint = <&csi2a_ep>; diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 48df077522ad..010a6017e1ad 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022 Intel Corporation. -#include #include #include #include @@ -96,12 +95,6 @@ /* Vertical Window Offset */ #define OV08X40_REG_V_WIN_OFFSET 0x3813 -/* Burst Register */ -#define OV08X40_REG_XTALK_FIRST_A 0x5a80 -#define OV08X40_REG_XTALK_LAST_A 0x5b9f -#define OV08X40_REG_XTALK_FIRST_B 0x5bc0 -#define OV08X40_REG_XTALK_LAST_B 0x5f1f - enum { OV08X40_LINK_FREQ_400MHZ_INDEX, }; @@ -677,6 +670,1158 @@ static const struct ov08x40_reg mode_3856x2416_regs[] = { {0x3502, 0x10}, {0x3508, 0x0f}, {0x3509, 0x80}, + {0x5a80, 0x75}, + {0x5a81, 0x75}, + {0x5a82, 0x75}, + {0x5a83, 0x75}, + {0x5a84, 0x75}, + {0x5a85, 0x75}, + {0x5a86, 0x75}, + {0x5a87, 0x75}, + {0x5a88, 0x75}, + {0x5a89, 0x75}, + {0x5a8a, 0x75}, + {0x5a8b, 0x75}, + {0x5a8c, 0x75}, + {0x5a8d, 0x75}, + {0x5a8e, 0x75}, + {0x5a8f, 0x75}, + {0x5a90, 0x75}, + {0x5a91, 0x75}, + {0x5a92, 0x75}, + {0x5a93, 0x75}, + {0x5a94, 0x75}, + {0x5a95, 0x75}, + {0x5a96, 0x75}, + {0x5a97, 0x75}, + {0x5a98, 0x75}, + {0x5a99, 0x75}, + {0x5a9a, 0x75}, + {0x5a9b, 0x75}, + {0x5a9c, 0x75}, + {0x5a9d, 0x75}, + {0x5a9e, 0x75}, + {0x5a9f, 0x75}, + {0x5aa0, 0x75}, + {0x5aa1, 0x75}, + {0x5aa2, 0x75}, + {0x5aa3, 0x75}, + {0x5aa4, 0x75}, + {0x5aa5, 0x75}, + {0x5aa6, 0x75}, + {0x5aa7, 0x75}, + {0x5aa8, 0x75}, + {0x5aa9, 0x75}, + {0x5aaa, 0x75}, + {0x5aab, 0x75}, + {0x5aac, 0x75}, + {0x5aad, 0x75}, + {0x5aae, 0x75}, + {0x5aaf, 0x75}, + {0x5ab0, 0x75}, + {0x5ab1, 0x75}, + {0x5ab2, 0x75}, + {0x5ab3, 0x75}, + {0x5ab4, 0x75}, + {0x5ab5, 0x75}, + {0x5ab6, 0x75}, + {0x5ab7, 0x75}, + {0x5ab8, 0x75}, + {0x5ab9, 0x75}, + {0x5aba, 0x75}, + {0x5abb, 0x75}, + {0x5abc, 0x75}, + {0x5abd, 0x75}, + {0x5abe, 0x75}, + {0x5abf, 0x75}, + {0x5ac0, 0x75}, + {0x5ac1, 0x75}, + {0x5ac2, 0x75}, + {0x5ac3, 0x75}, + {0x5ac4, 0x75}, + {0x5ac5, 0x75}, + {0x5ac6, 0x75}, + {0x5ac7, 0x75}, + {0x5ac8, 0x75}, + {0x5ac9, 0x75}, + {0x5aca, 0x75}, + {0x5acb, 0x75}, + {0x5acc, 0x75}, + {0x5acd, 0x75}, + {0x5ace, 0x75}, + {0x5acf, 0x75}, + {0x5ad0, 0x75}, + {0x5ad1, 0x75}, + {0x5ad2, 0x75}, + {0x5ad3, 0x75}, + {0x5ad4, 0x75}, + {0x5ad5, 0x75}, + {0x5ad6, 0x75}, + {0x5ad7, 0x75}, + {0x5ad8, 0x75}, + {0x5ad9, 0x75}, + {0x5ada, 0x75}, + {0x5adb, 0x75}, + {0x5adc, 0x75}, + {0x5add, 0x75}, + {0x5ade, 0x75}, + {0x5adf, 0x75}, + {0x5ae0, 0x75}, + {0x5ae1, 0x75}, + {0x5ae2, 0x75}, + {0x5ae3, 0x75}, + {0x5ae4, 0x75}, + {0x5ae5, 0x75}, + {0x5ae6, 0x75}, + {0x5ae7, 0x75}, + {0x5ae8, 0x75}, + {0x5ae9, 0x75}, + {0x5aea, 0x75}, + {0x5aeb, 0x75}, + {0x5aec, 0x75}, + {0x5aed, 0x75}, + {0x5aee, 0x75}, + {0x5aef, 0x75}, + {0x5af0, 0x75}, + {0x5af1, 0x75}, + {0x5af2, 0x75}, + {0x5af3, 0x75}, + {0x5af4, 0x75}, + {0x5af5, 0x75}, + {0x5af6, 0x75}, + {0x5af7, 0x75}, + {0x5af8, 0x75}, + {0x5af9, 0x75}, + {0x5afa, 0x75}, + {0x5afb, 0x75}, + {0x5afc, 0x75}, + {0x5afd, 0x75}, + {0x5afe, 0x75}, + {0x5aff, 0x75}, + {0x5b00, 0x75}, + {0x5b01, 0x75}, + {0x5b02, 0x75}, + {0x5b03, 0x75}, + {0x5b04, 0x75}, + {0x5b05, 0x75}, + {0x5b06, 0x75}, + {0x5b07, 0x75}, + {0x5b08, 0x75}, + {0x5b09, 0x75}, + {0x5b0a, 0x75}, + {0x5b0b, 0x75}, + {0x5b0c, 0x75}, + {0x5b0d, 0x75}, + {0x5b0e, 0x75}, + {0x5b0f, 0x75}, + {0x5b10, 0x75}, + {0x5b11, 0x75}, + {0x5b12, 0x75}, + {0x5b13, 0x75}, + {0x5b14, 0x75}, + {0x5b15, 0x75}, + {0x5b16, 0x75}, + {0x5b17, 0x75}, + {0x5b18, 0x75}, + {0x5b19, 0x75}, + {0x5b1a, 0x75}, + {0x5b1b, 0x75}, + {0x5b1c, 0x75}, + {0x5b1d, 0x75}, + {0x5b1e, 0x75}, + {0x5b1f, 0x75}, + {0x5b20, 0x75}, + {0x5b21, 0x75}, + {0x5b22, 0x75}, + {0x5b23, 0x75}, + {0x5b24, 0x75}, + {0x5b25, 0x75}, + {0x5b26, 0x75}, + {0x5b27, 0x75}, + {0x5b28, 0x75}, + {0x5b29, 0x75}, + {0x5b2a, 0x75}, + {0x5b2b, 0x75}, + {0x5b2c, 0x75}, + {0x5b2d, 0x75}, + {0x5b2e, 0x75}, + {0x5b2f, 0x75}, + {0x5b30, 0x75}, + {0x5b31, 0x75}, + {0x5b32, 0x75}, + {0x5b33, 0x75}, + {0x5b34, 0x75}, + {0x5b35, 0x75}, + {0x5b36, 0x75}, + {0x5b37, 0x75}, + {0x5b38, 0x75}, + {0x5b39, 0x75}, + {0x5b3a, 0x75}, + {0x5b3b, 0x75}, + {0x5b3c, 0x75}, + {0x5b3d, 0x75}, + {0x5b3e, 0x75}, + {0x5b3f, 0x75}, + {0x5b40, 0x75}, + {0x5b41, 0x75}, + {0x5b42, 0x75}, + {0x5b43, 0x75}, + {0x5b44, 0x75}, + {0x5b45, 0x75}, + {0x5b46, 0x75}, + {0x5b47, 0x75}, + {0x5b48, 0x75}, + {0x5b49, 0x75}, + {0x5b4a, 0x75}, + {0x5b4b, 0x75}, + {0x5b4c, 0x75}, + {0x5b4d, 0x75}, + {0x5b4e, 0x75}, + {0x5b4f, 0x75}, + {0x5b50, 0x75}, + {0x5b51, 0x75}, + {0x5b52, 0x75}, + {0x5b53, 0x75}, + {0x5b54, 0x75}, + {0x5b55, 0x75}, + {0x5b56, 0x75}, + {0x5b57, 0x75}, + {0x5b58, 0x75}, + {0x5b59, 0x75}, + {0x5b5a, 0x75}, + {0x5b5b, 0x75}, + {0x5b5c, 0x75}, + {0x5b5d, 0x75}, + {0x5b5e, 0x75}, + {0x5b5f, 0x75}, + {0x5b60, 0x75}, + {0x5b61, 0x75}, + {0x5b62, 0x75}, + {0x5b63, 0x75}, + {0x5b64, 0x75}, + {0x5b65, 0x75}, + {0x5b66, 0x75}, + {0x5b67, 0x75}, + {0x5b68, 0x75}, + {0x5b69, 0x75}, + {0x5b6a, 0x75}, + {0x5b6b, 0x75}, + {0x5b6c, 0x75}, + {0x5b6d, 0x75}, + {0x5b6e, 0x75}, + {0x5b6f, 0x75}, + {0x5b70, 0x75}, + {0x5b71, 0x75}, + {0x5b72, 0x75}, + {0x5b73, 0x75}, + {0x5b74, 0x75}, + {0x5b75, 0x75}, + {0x5b76, 0x75}, + {0x5b77, 0x75}, + {0x5b78, 0x75}, + {0x5b79, 0x75}, + {0x5b7a, 0x75}, + {0x5b7b, 0x75}, + {0x5b7c, 0x75}, + {0x5b7d, 0x75}, + {0x5b7e, 0x75}, + {0x5b7f, 0x75}, + {0x5b80, 0x75}, + {0x5b81, 0x75}, + {0x5b82, 0x75}, + {0x5b83, 0x75}, + {0x5b84, 0x75}, + {0x5b85, 0x75}, + {0x5b86, 0x75}, + {0x5b87, 0x75}, + {0x5b88, 0x75}, + {0x5b89, 0x75}, + {0x5b8a, 0x75}, + {0x5b8b, 0x75}, + {0x5b8c, 0x75}, + {0x5b8d, 0x75}, + {0x5b8e, 0x75}, + {0x5b8f, 0x75}, + {0x5b90, 0x75}, + {0x5b91, 0x75}, + {0x5b92, 0x75}, + {0x5b93, 0x75}, + {0x5b94, 0x75}, + {0x5b95, 0x75}, + {0x5b96, 0x75}, + {0x5b97, 0x75}, + {0x5b98, 0x75}, + {0x5b99, 0x75}, + {0x5b9a, 0x75}, + {0x5b9b, 0x75}, + {0x5b9c, 0x75}, + {0x5b9d, 0x75}, + {0x5b9e, 0x75}, + {0x5b9f, 0x75}, + {0x5bc0, 0x75}, + {0x5bc1, 0x75}, + {0x5bc2, 0x75}, + {0x5bc3, 0x75}, + {0x5bc4, 0x75}, + {0x5bc5, 0x75}, + {0x5bc6, 0x75}, + {0x5bc7, 0x75}, + {0x5bc8, 0x75}, + {0x5bc9, 0x75}, + {0x5bca, 0x75}, + {0x5bcb, 0x75}, + {0x5bcc, 0x75}, + {0x5bcd, 0x75}, + {0x5bce, 0x75}, + {0x5bcf, 0x75}, + {0x5bd0, 0x75}, + {0x5bd1, 0x75}, + {0x5bd2, 0x75}, + {0x5bd3, 0x75}, + {0x5bd4, 0x75}, + {0x5bd5, 0x75}, + {0x5bd6, 0x75}, + {0x5bd7, 0x75}, + {0x5bd8, 0x75}, + {0x5bd9, 0x75}, + {0x5bda, 0x75}, + {0x5bdb, 0x75}, + {0x5bdc, 0x75}, + {0x5bdd, 0x75}, + {0x5bde, 0x75}, + {0x5bdf, 0x75}, + {0x5be0, 0x75}, + {0x5be1, 0x75}, + {0x5be2, 0x75}, + {0x5be3, 0x75}, + {0x5be4, 0x75}, + {0x5be5, 0x75}, + {0x5be6, 0x75}, + {0x5be7, 0x75}, + {0x5be8, 0x75}, + {0x5be9, 0x75}, + {0x5bea, 0x75}, + {0x5beb, 0x75}, + {0x5bec, 0x75}, + {0x5bed, 0x75}, + {0x5bee, 0x75}, + {0x5bef, 0x75}, + {0x5bf0, 0x75}, + {0x5bf1, 0x75}, + {0x5bf2, 0x75}, + {0x5bf3, 0x75}, + {0x5bf4, 0x75}, + {0x5bf5, 0x75}, + {0x5bf6, 0x75}, + {0x5bf7, 0x75}, + {0x5bf8, 0x75}, + {0x5bf9, 0x75}, + {0x5bfa, 0x75}, + {0x5bfb, 0x75}, + {0x5bfc, 0x75}, + {0x5bfd, 0x75}, + {0x5bfe, 0x75}, + {0x5bff, 0x75}, + {0x5c00, 0x75}, + {0x5c01, 0x75}, + {0x5c02, 0x75}, + {0x5c03, 0x75}, + {0x5c04, 0x75}, + {0x5c05, 0x75}, + {0x5c06, 0x75}, + {0x5c07, 0x75}, + {0x5c08, 0x75}, + {0x5c09, 0x75}, + {0x5c0a, 0x75}, + {0x5c0b, 0x75}, + {0x5c0c, 0x75}, + {0x5c0d, 0x75}, + {0x5c0e, 0x75}, + {0x5c0f, 0x75}, + {0x5c10, 0x75}, + {0x5c11, 0x75}, + {0x5c12, 0x75}, + {0x5c13, 0x75}, + {0x5c14, 0x75}, + {0x5c15, 0x75}, + {0x5c16, 0x75}, + {0x5c17, 0x75}, + {0x5c18, 0x75}, + {0x5c19, 0x75}, + {0x5c1a, 0x75}, + {0x5c1b, 0x75}, + {0x5c1c, 0x75}, + {0x5c1d, 0x75}, + {0x5c1e, 0x75}, + {0x5c1f, 0x75}, + {0x5c20, 0x75}, + {0x5c21, 0x75}, + {0x5c22, 0x75}, + {0x5c23, 0x75}, + {0x5c24, 0x75}, + {0x5c25, 0x75}, + {0x5c26, 0x75}, + {0x5c27, 0x75}, + {0x5c28, 0x75}, + {0x5c29, 0x75}, + {0x5c2a, 0x75}, + {0x5c2b, 0x75}, + {0x5c2c, 0x75}, + {0x5c2d, 0x75}, + {0x5c2e, 0x75}, + {0x5c2f, 0x75}, + {0x5c30, 0x75}, + {0x5c31, 0x75}, + {0x5c32, 0x75}, + {0x5c33, 0x75}, + {0x5c34, 0x75}, + {0x5c35, 0x75}, + {0x5c36, 0x75}, + {0x5c37, 0x75}, + {0x5c38, 0x75}, + {0x5c39, 0x75}, + {0x5c3a, 0x75}, + {0x5c3b, 0x75}, + {0x5c3c, 0x75}, + {0x5c3d, 0x75}, + {0x5c3e, 0x75}, + {0x5c3f, 0x75}, + {0x5c40, 0x75}, + {0x5c41, 0x75}, + {0x5c42, 0x75}, + {0x5c43, 0x75}, + {0x5c44, 0x75}, + {0x5c45, 0x75}, + {0x5c46, 0x75}, + {0x5c47, 0x75}, + {0x5c48, 0x75}, + {0x5c49, 0x75}, + {0x5c4a, 0x75}, + {0x5c4b, 0x75}, + {0x5c4c, 0x75}, + {0x5c4d, 0x75}, + {0x5c4e, 0x75}, + {0x5c4f, 0x75}, + {0x5c50, 0x75}, + {0x5c51, 0x75}, + {0x5c52, 0x75}, + {0x5c53, 0x75}, + {0x5c54, 0x75}, + {0x5c55, 0x75}, + {0x5c56, 0x75}, + {0x5c57, 0x75}, + {0x5c58, 0x75}, + {0x5c59, 0x75}, + {0x5c5a, 0x75}, + {0x5c5b, 0x75}, + {0x5c5c, 0x75}, + {0x5c5d, 0x75}, + {0x5c5e, 0x75}, + {0x5c5f, 0x75}, + {0x5c60, 0x75}, + {0x5c61, 0x75}, + {0x5c62, 0x75}, + {0x5c63, 0x75}, + {0x5c64, 0x75}, + {0x5c65, 0x75}, + {0x5c66, 0x75}, + {0x5c67, 0x75}, + {0x5c68, 0x75}, + {0x5c69, 0x75}, + {0x5c6a, 0x75}, + {0x5c6b, 0x75}, + {0x5c6c, 0x75}, + {0x5c6d, 0x75}, + {0x5c6e, 0x75}, + {0x5c6f, 0x75}, + {0x5c70, 0x75}, + {0x5c71, 0x75}, + {0x5c72, 0x75}, + {0x5c73, 0x75}, + {0x5c74, 0x75}, + {0x5c75, 0x75}, + {0x5c76, 0x75}, + {0x5c77, 0x75}, + {0x5c78, 0x75}, + {0x5c79, 0x75}, + {0x5c7a, 0x75}, + {0x5c7b, 0x75}, + {0x5c7c, 0x75}, + {0x5c7d, 0x75}, + {0x5c7e, 0x75}, + {0x5c7f, 0x75}, + {0x5c80, 0x75}, + {0x5c81, 0x75}, + {0x5c82, 0x75}, + {0x5c83, 0x75}, + {0x5c84, 0x75}, + {0x5c85, 0x75}, + {0x5c86, 0x75}, + {0x5c87, 0x75}, + {0x5c88, 0x75}, + {0x5c89, 0x75}, + {0x5c8a, 0x75}, + {0x5c8b, 0x75}, + {0x5c8c, 0x75}, + {0x5c8d, 0x75}, + {0x5c8e, 0x75}, + {0x5c8f, 0x75}, + {0x5c90, 0x75}, + {0x5c91, 0x75}, + {0x5c92, 0x75}, + {0x5c93, 0x75}, + {0x5c94, 0x75}, + {0x5c95, 0x75}, + {0x5c96, 0x75}, + {0x5c97, 0x75}, + {0x5c98, 0x75}, + {0x5c99, 0x75}, + {0x5c9a, 0x75}, + {0x5c9b, 0x75}, + {0x5c9c, 0x75}, + {0x5c9d, 0x75}, + {0x5c9e, 0x75}, + {0x5c9f, 0x75}, + {0x5ca0, 0x75}, + {0x5ca1, 0x75}, + {0x5ca2, 0x75}, + {0x5ca3, 0x75}, + {0x5ca4, 0x75}, + {0x5ca5, 0x75}, + {0x5ca6, 0x75}, + {0x5ca7, 0x75}, + {0x5ca8, 0x75}, + {0x5ca9, 0x75}, + {0x5caa, 0x75}, + {0x5cab, 0x75}, + {0x5cac, 0x75}, + {0x5cad, 0x75}, + {0x5cae, 0x75}, + {0x5caf, 0x75}, + {0x5cb0, 0x75}, + {0x5cb1, 0x75}, + {0x5cb2, 0x75}, + {0x5cb3, 0x75}, + {0x5cb4, 0x75}, + {0x5cb5, 0x75}, + {0x5cb6, 0x75}, + {0x5cb7, 0x75}, + {0x5cb8, 0x75}, + {0x5cb9, 0x75}, + {0x5cba, 0x75}, + {0x5cbb, 0x75}, + {0x5cbc, 0x75}, + {0x5cbd, 0x75}, + {0x5cbe, 0x75}, + {0x5cbf, 0x75}, + {0x5cc0, 0x75}, + {0x5cc1, 0x75}, + {0x5cc2, 0x75}, + {0x5cc3, 0x75}, + {0x5cc4, 0x75}, + {0x5cc5, 0x75}, + {0x5cc6, 0x75}, + {0x5cc7, 0x75}, + {0x5cc8, 0x75}, + {0x5cc9, 0x75}, + {0x5cca, 0x75}, + {0x5ccb, 0x75}, + {0x5ccc, 0x75}, + {0x5ccd, 0x75}, + {0x5cce, 0x75}, + {0x5ccf, 0x75}, + {0x5cd0, 0x75}, + {0x5cd1, 0x75}, + {0x5cd2, 0x75}, + {0x5cd3, 0x75}, + {0x5cd4, 0x75}, + {0x5cd5, 0x75}, + {0x5cd6, 0x75}, + {0x5cd7, 0x75}, + {0x5cd8, 0x75}, + {0x5cd9, 0x75}, + {0x5cda, 0x75}, + {0x5cdb, 0x75}, + {0x5cdc, 0x75}, + {0x5cdd, 0x75}, + {0x5cde, 0x75}, + {0x5cdf, 0x75}, + {0x5ce0, 0x75}, + {0x5ce1, 0x75}, + {0x5ce2, 0x75}, + {0x5ce3, 0x75}, + {0x5ce4, 0x75}, + {0x5ce5, 0x75}, + {0x5ce6, 0x75}, + {0x5ce7, 0x75}, + {0x5ce8, 0x75}, + {0x5ce9, 0x75}, + {0x5cea, 0x75}, + {0x5ceb, 0x75}, + {0x5cec, 0x75}, + {0x5ced, 0x75}, + {0x5cee, 0x75}, + {0x5cef, 0x75}, + {0x5cf0, 0x75}, + {0x5cf1, 0x75}, + {0x5cf2, 0x75}, + {0x5cf3, 0x75}, + {0x5cf4, 0x75}, + {0x5cf5, 0x75}, + {0x5cf6, 0x75}, + {0x5cf7, 0x75}, + {0x5cf8, 0x75}, + {0x5cf9, 0x75}, + {0x5cfa, 0x75}, + {0x5cfb, 0x75}, + {0x5cfc, 0x75}, + {0x5cfd, 0x75}, + {0x5cfe, 0x75}, + {0x5cff, 0x75}, + {0x5d00, 0x75}, + {0x5d01, 0x75}, + {0x5d02, 0x75}, + {0x5d03, 0x75}, + {0x5d04, 0x75}, + {0x5d05, 0x75}, + {0x5d06, 0x75}, + {0x5d07, 0x75}, + {0x5d08, 0x75}, + {0x5d09, 0x75}, + {0x5d0a, 0x75}, + {0x5d0b, 0x75}, + {0x5d0c, 0x75}, + {0x5d0d, 0x75}, + {0x5d0e, 0x75}, + {0x5d0f, 0x75}, + {0x5d10, 0x75}, + {0x5d11, 0x75}, + {0x5d12, 0x75}, + {0x5d13, 0x75}, + {0x5d14, 0x75}, + {0x5d15, 0x75}, + {0x5d16, 0x75}, + {0x5d17, 0x75}, + {0x5d18, 0x75}, + {0x5d19, 0x75}, + {0x5d1a, 0x75}, + {0x5d1b, 0x75}, + {0x5d1c, 0x75}, + {0x5d1d, 0x75}, + {0x5d1e, 0x75}, + {0x5d1f, 0x75}, + {0x5d20, 0x75}, + {0x5d21, 0x75}, + {0x5d22, 0x75}, + {0x5d23, 0x75}, + {0x5d24, 0x75}, + {0x5d25, 0x75}, + {0x5d26, 0x75}, + {0x5d27, 0x75}, + {0x5d28, 0x75}, + {0x5d29, 0x75}, + {0x5d2a, 0x75}, + {0x5d2b, 0x75}, + {0x5d2c, 0x75}, + {0x5d2d, 0x75}, + {0x5d2e, 0x75}, + {0x5d2f, 0x75}, + {0x5d30, 0x75}, + {0x5d31, 0x75}, + {0x5d32, 0x75}, + {0x5d33, 0x75}, + {0x5d34, 0x75}, + {0x5d35, 0x75}, + {0x5d36, 0x75}, + {0x5d37, 0x75}, + {0x5d38, 0x75}, + {0x5d39, 0x75}, + {0x5d3a, 0x75}, + {0x5d3b, 0x75}, + {0x5d3c, 0x75}, + {0x5d3d, 0x75}, + {0x5d3e, 0x75}, + {0x5d3f, 0x75}, + {0x5d40, 0x75}, + {0x5d41, 0x75}, + {0x5d42, 0x75}, + {0x5d43, 0x75}, + {0x5d44, 0x75}, + {0x5d45, 0x75}, + {0x5d46, 0x75}, + {0x5d47, 0x75}, + {0x5d48, 0x75}, + {0x5d49, 0x75}, + {0x5d4a, 0x75}, + {0x5d4b, 0x75}, + {0x5d4c, 0x75}, + {0x5d4d, 0x75}, + {0x5d4e, 0x75}, + {0x5d4f, 0x75}, + {0x5d50, 0x75}, + {0x5d51, 0x75}, + {0x5d52, 0x75}, + {0x5d53, 0x75}, + {0x5d54, 0x75}, + {0x5d55, 0x75}, + {0x5d56, 0x75}, + {0x5d57, 0x75}, + {0x5d58, 0x75}, + {0x5d59, 0x75}, + {0x5d5a, 0x75}, + {0x5d5b, 0x75}, + {0x5d5c, 0x75}, + {0x5d5d, 0x75}, + {0x5d5e, 0x75}, + {0x5d5f, 0x75}, + {0x5d60, 0x75}, + {0x5d61, 0x75}, + {0x5d62, 0x75}, + {0x5d63, 0x75}, + {0x5d64, 0x75}, + {0x5d65, 0x75}, + {0x5d66, 0x75}, + {0x5d67, 0x75}, + {0x5d68, 0x75}, + {0x5d69, 0x75}, + {0x5d6a, 0x75}, + {0x5d6b, 0x75}, + {0x5d6c, 0x75}, + {0x5d6d, 0x75}, + {0x5d6e, 0x75}, + {0x5d6f, 0x75}, + {0x5d70, 0x75}, + {0x5d71, 0x75}, + {0x5d72, 0x75}, + {0x5d73, 0x75}, + {0x5d74, 0x75}, + {0x5d75, 0x75}, + {0x5d76, 0x75}, + {0x5d77, 0x75}, + {0x5d78, 0x75}, + {0x5d79, 0x75}, + {0x5d7a, 0x75}, + {0x5d7b, 0x75}, + {0x5d7c, 0x75}, + {0x5d7d, 0x75}, + {0x5d7e, 0x75}, + {0x5d7f, 0x75}, + {0x5d80, 0x75}, + {0x5d81, 0x75}, + {0x5d82, 0x75}, + {0x5d83, 0x75}, + {0x5d84, 0x75}, + {0x5d85, 0x75}, + {0x5d86, 0x75}, + {0x5d87, 0x75}, + {0x5d88, 0x75}, + {0x5d89, 0x75}, + {0x5d8a, 0x75}, + {0x5d8b, 0x75}, + {0x5d8c, 0x75}, + {0x5d8d, 0x75}, + {0x5d8e, 0x75}, + {0x5d8f, 0x75}, + {0x5d90, 0x75}, + {0x5d91, 0x75}, + {0x5d92, 0x75}, + {0x5d93, 0x75}, + {0x5d94, 0x75}, + {0x5d95, 0x75}, + {0x5d96, 0x75}, + {0x5d97, 0x75}, + {0x5d98, 0x75}, + {0x5d99, 0x75}, + {0x5d9a, 0x75}, + {0x5d9b, 0x75}, + {0x5d9c, 0x75}, + {0x5d9d, 0x75}, + {0x5d9e, 0x75}, + {0x5d9f, 0x75}, + {0x5da0, 0x75}, + {0x5da1, 0x75}, + {0x5da2, 0x75}, + {0x5da3, 0x75}, + {0x5da4, 0x75}, + {0x5da5, 0x75}, + {0x5da6, 0x75}, + {0x5da7, 0x75}, + {0x5da8, 0x75}, + {0x5da9, 0x75}, + {0x5daa, 0x75}, + {0x5dab, 0x75}, + {0x5dac, 0x75}, + {0x5dad, 0x75}, + {0x5dae, 0x75}, + {0x5daf, 0x75}, + {0x5db0, 0x75}, + {0x5db1, 0x75}, + {0x5db2, 0x75}, + {0x5db3, 0x75}, + {0x5db4, 0x75}, + {0x5db5, 0x75}, + {0x5db6, 0x75}, + {0x5db7, 0x75}, + {0x5db8, 0x75}, + {0x5db9, 0x75}, + {0x5dba, 0x75}, + {0x5dbb, 0x75}, + {0x5dbc, 0x75}, + {0x5dbd, 0x75}, + {0x5dbe, 0x75}, + {0x5dbf, 0x75}, + {0x5dc0, 0x75}, + {0x5dc1, 0x75}, + {0x5dc2, 0x75}, + {0x5dc3, 0x75}, + {0x5dc4, 0x75}, + {0x5dc5, 0x75}, + {0x5dc6, 0x75}, + {0x5dc7, 0x75}, + {0x5dc8, 0x75}, + {0x5dc9, 0x75}, + {0x5dca, 0x75}, + {0x5dcb, 0x75}, + {0x5dcc, 0x75}, + {0x5dcd, 0x75}, + {0x5dce, 0x75}, + {0x5dcf, 0x75}, + {0x5dd0, 0x75}, + {0x5dd1, 0x75}, + {0x5dd2, 0x75}, + {0x5dd3, 0x75}, + {0x5dd4, 0x75}, + {0x5dd5, 0x75}, + {0x5dd6, 0x75}, + {0x5dd7, 0x75}, + {0x5dd8, 0x75}, + {0x5dd9, 0x75}, + {0x5dda, 0x75}, + {0x5ddb, 0x75}, + {0x5ddc, 0x75}, + {0x5ddd, 0x75}, + {0x5dde, 0x75}, + {0x5ddf, 0x75}, + {0x5de0, 0x75}, + {0x5de1, 0x75}, + {0x5de2, 0x75}, + {0x5de3, 0x75}, + {0x5de4, 0x75}, + {0x5de5, 0x75}, + {0x5de6, 0x75}, + {0x5de7, 0x75}, + {0x5de8, 0x75}, + {0x5de9, 0x75}, + {0x5dea, 0x75}, + {0x5deb, 0x75}, + {0x5dec, 0x75}, + {0x5ded, 0x75}, + {0x5dee, 0x75}, + {0x5def, 0x75}, + {0x5df0, 0x75}, + {0x5df1, 0x75}, + {0x5df2, 0x75}, + {0x5df3, 0x75}, + {0x5df4, 0x75}, + {0x5df5, 0x75}, + {0x5df6, 0x75}, + {0x5df7, 0x75}, + {0x5df8, 0x75}, + {0x5df9, 0x75}, + {0x5dfa, 0x75}, + {0x5dfb, 0x75}, + {0x5dfc, 0x75}, + {0x5dfd, 0x75}, + {0x5dfe, 0x75}, + {0x5dff, 0x75}, + {0x5e00, 0x75}, + {0x5e01, 0x75}, + {0x5e02, 0x75}, + {0x5e03, 0x75}, + {0x5e04, 0x75}, + {0x5e05, 0x75}, + {0x5e06, 0x75}, + {0x5e07, 0x75}, + {0x5e08, 0x75}, + {0x5e09, 0x75}, + {0x5e0a, 0x75}, + {0x5e0b, 0x75}, + {0x5e0c, 0x75}, + {0x5e0d, 0x75}, + {0x5e0e, 0x75}, + {0x5e0f, 0x75}, + {0x5e10, 0x75}, + {0x5e11, 0x75}, + {0x5e12, 0x75}, + {0x5e13, 0x75}, + {0x5e14, 0x75}, + {0x5e15, 0x75}, + {0x5e16, 0x75}, + {0x5e17, 0x75}, + {0x5e18, 0x75}, + {0x5e19, 0x75}, + {0x5e1a, 0x75}, + {0x5e1b, 0x75}, + {0x5e1c, 0x75}, + {0x5e1d, 0x75}, + {0x5e1e, 0x75}, + {0x5e1f, 0x75}, + {0x5e20, 0x75}, + {0x5e21, 0x75}, + {0x5e22, 0x75}, + {0x5e23, 0x75}, + {0x5e24, 0x75}, + {0x5e25, 0x75}, + {0x5e26, 0x75}, + {0x5e27, 0x75}, + {0x5e28, 0x75}, + {0x5e29, 0x75}, + {0x5e2a, 0x75}, + {0x5e2b, 0x75}, + {0x5e2c, 0x75}, + {0x5e2d, 0x75}, + {0x5e2e, 0x75}, + {0x5e2f, 0x75}, + {0x5e30, 0x75}, + {0x5e31, 0x75}, + {0x5e32, 0x75}, + {0x5e33, 0x75}, + {0x5e34, 0x75}, + {0x5e35, 0x75}, + {0x5e36, 0x75}, + {0x5e37, 0x75}, + {0x5e38, 0x75}, + {0x5e39, 0x75}, + {0x5e3a, 0x75}, + {0x5e3b, 0x75}, + {0x5e3c, 0x75}, + {0x5e3d, 0x75}, + {0x5e3e, 0x75}, + {0x5e3f, 0x75}, + {0x5e40, 0x75}, + {0x5e41, 0x75}, + {0x5e42, 0x75}, + {0x5e43, 0x75}, + {0x5e44, 0x75}, + {0x5e45, 0x75}, + {0x5e46, 0x75}, + {0x5e47, 0x75}, + {0x5e48, 0x75}, + {0x5e49, 0x75}, + {0x5e4a, 0x75}, + {0x5e4b, 0x75}, + {0x5e4c, 0x75}, + {0x5e4d, 0x75}, + {0x5e4e, 0x75}, + {0x5e4f, 0x75}, + {0x5e50, 0x75}, + {0x5e51, 0x75}, + {0x5e52, 0x75}, + {0x5e53, 0x75}, + {0x5e54, 0x75}, + {0x5e55, 0x75}, + {0x5e56, 0x75}, + {0x5e57, 0x75}, + {0x5e58, 0x75}, + {0x5e59, 0x75}, + {0x5e5a, 0x75}, + {0x5e5b, 0x75}, + {0x5e5c, 0x75}, + {0x5e5d, 0x75}, + {0x5e5e, 0x75}, + {0x5e5f, 0x75}, + {0x5e60, 0x75}, + {0x5e61, 0x75}, + {0x5e62, 0x75}, + {0x5e63, 0x75}, + {0x5e64, 0x75}, + {0x5e65, 0x75}, + {0x5e66, 0x75}, + {0x5e67, 0x75}, + {0x5e68, 0x75}, + {0x5e69, 0x75}, + {0x5e6a, 0x75}, + {0x5e6b, 0x75}, + {0x5e6c, 0x75}, + {0x5e6d, 0x75}, + {0x5e6e, 0x75}, + {0x5e6f, 0x75}, + {0x5e70, 0x75}, + {0x5e71, 0x75}, + {0x5e72, 0x75}, + {0x5e73, 0x75}, + {0x5e74, 0x75}, + {0x5e75, 0x75}, + {0x5e76, 0x75}, + {0x5e77, 0x75}, + {0x5e78, 0x75}, + {0x5e79, 0x75}, + {0x5e7a, 0x75}, + {0x5e7b, 0x75}, + {0x5e7c, 0x75}, + {0x5e7d, 0x75}, + {0x5e7e, 0x75}, + {0x5e7f, 0x75}, + {0x5e80, 0x75}, + {0x5e81, 0x75}, + {0x5e82, 0x75}, + {0x5e83, 0x75}, + {0x5e84, 0x75}, + {0x5e85, 0x75}, + {0x5e86, 0x75}, + {0x5e87, 0x75}, + {0x5e88, 0x75}, + {0x5e89, 0x75}, + {0x5e8a, 0x75}, + {0x5e8b, 0x75}, + {0x5e8c, 0x75}, + {0x5e8d, 0x75}, + {0x5e8e, 0x75}, + {0x5e8f, 0x75}, + {0x5e90, 0x75}, + {0x5e91, 0x75}, + {0x5e92, 0x75}, + {0x5e93, 0x75}, + {0x5e94, 0x75}, + {0x5e95, 0x75}, + {0x5e96, 0x75}, + {0x5e97, 0x75}, + {0x5e98, 0x75}, + {0x5e99, 0x75}, + {0x5e9a, 0x75}, + {0x5e9b, 0x75}, + {0x5e9c, 0x75}, + {0x5e9d, 0x75}, + {0x5e9e, 0x75}, + {0x5e9f, 0x75}, + {0x5ea0, 0x75}, + {0x5ea1, 0x75}, + {0x5ea2, 0x75}, + {0x5ea3, 0x75}, + {0x5ea4, 0x75}, + {0x5ea5, 0x75}, + {0x5ea6, 0x75}, + {0x5ea7, 0x75}, + {0x5ea8, 0x75}, + {0x5ea9, 0x75}, + {0x5eaa, 0x75}, + {0x5eab, 0x75}, + {0x5eac, 0x75}, + {0x5ead, 0x75}, + {0x5eae, 0x75}, + {0x5eaf, 0x75}, + {0x5eb0, 0x75}, + {0x5eb1, 0x75}, + {0x5eb2, 0x75}, + {0x5eb3, 0x75}, + {0x5eb4, 0x75}, + {0x5eb5, 0x75}, + {0x5eb6, 0x75}, + {0x5eb7, 0x75}, + {0x5eb8, 0x75}, + {0x5eb9, 0x75}, + {0x5eba, 0x75}, + {0x5ebb, 0x75}, + {0x5ebc, 0x75}, + {0x5ebd, 0x75}, + {0x5ebe, 0x75}, + {0x5ebf, 0x75}, + {0x5ec0, 0x75}, + {0x5ec1, 0x75}, + {0x5ec2, 0x75}, + {0x5ec3, 0x75}, + {0x5ec4, 0x75}, + {0x5ec5, 0x75}, + {0x5ec6, 0x75}, + {0x5ec7, 0x75}, + {0x5ec8, 0x75}, + {0x5ec9, 0x75}, + {0x5eca, 0x75}, + {0x5ecb, 0x75}, + {0x5ecc, 0x75}, + {0x5ecd, 0x75}, + {0x5ece, 0x75}, + {0x5ecf, 0x75}, + {0x5ed0, 0x75}, + {0x5ed1, 0x75}, + {0x5ed2, 0x75}, + {0x5ed3, 0x75}, + {0x5ed4, 0x75}, + {0x5ed5, 0x75}, + {0x5ed6, 0x75}, + {0x5ed7, 0x75}, + {0x5ed8, 0x75}, + {0x5ed9, 0x75}, + {0x5eda, 0x75}, + {0x5edb, 0x75}, + {0x5edc, 0x75}, + {0x5edd, 0x75}, + {0x5ede, 0x75}, + {0x5edf, 0x75}, + {0x5ee0, 0x75}, + {0x5ee1, 0x75}, + {0x5ee2, 0x75}, + {0x5ee3, 0x75}, + {0x5ee4, 0x75}, + {0x5ee5, 0x75}, + {0x5ee6, 0x75}, + {0x5ee7, 0x75}, + {0x5ee8, 0x75}, + {0x5ee9, 0x75}, + {0x5eea, 0x75}, + {0x5eeb, 0x75}, + {0x5eec, 0x75}, + {0x5eed, 0x75}, + {0x5eee, 0x75}, + {0x5eef, 0x75}, + {0x5ef0, 0x75}, + {0x5ef1, 0x75}, + {0x5ef2, 0x75}, + {0x5ef3, 0x75}, + {0x5ef4, 0x75}, + {0x5ef5, 0x75}, + {0x5ef6, 0x75}, + {0x5ef7, 0x75}, + {0x5ef8, 0x75}, + {0x5ef9, 0x75}, + {0x5efa, 0x75}, + {0x5efb, 0x75}, + {0x5efc, 0x75}, + {0x5efd, 0x75}, + {0x5efe, 0x75}, + {0x5eff, 0x75}, + {0x5f00, 0x75}, + {0x5f01, 0x75}, + {0x5f02, 0x75}, + {0x5f03, 0x75}, + {0x5f04, 0x75}, + {0x5f05, 0x75}, + {0x5f06, 0x75}, + {0x5f07, 0x75}, + {0x5f08, 0x75}, + {0x5f09, 0x75}, + {0x5f0a, 0x75}, + {0x5f0b, 0x75}, + {0x5f0c, 0x75}, + {0x5f0d, 0x75}, + {0x5f0e, 0x75}, + {0x5f0f, 0x75}, + {0x5f10, 0x75}, + {0x5f11, 0x75}, + {0x5f12, 0x75}, + {0x5f13, 0x75}, + {0x5f14, 0x75}, + {0x5f15, 0x75}, + {0x5f16, 0x75}, + {0x5f17, 0x75}, + {0x5f18, 0x75}, + {0x5f19, 0x75}, + {0x5f1a, 0x75}, + {0x5f1b, 0x75}, + {0x5f1c, 0x75}, + {0x5f1d, 0x75}, + {0x5f1e, 0x75}, + {0x5f1f, 0x75}, }; static const struct ov08x40_reg mode_1928x1208_regs[] = { @@ -1339,40 +2484,6 @@ static int ov08x40_read_reg(struct ov08x40 *ov08x, return 0; } -static int ov08x40_burst_fill_regs(struct ov08x40 *ov08x, u16 first_reg, - u16 last_reg, u8 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd); - struct i2c_msg msgs; - size_t i, num_regs; - int ret; - - num_regs = last_reg - first_reg + 1; - msgs.addr = client->addr; - msgs.flags = 0; - msgs.len = 2 + num_regs; - msgs.buf = kmalloc(msgs.len, GFP_KERNEL); - - if (!msgs.buf) - return -ENOMEM; - - put_unaligned_be16(first_reg, msgs.buf); - - for (i = 0; i < num_regs; ++i) - msgs.buf[2 + i] = val; - - ret = i2c_transfer(client->adapter, &msgs, 1); - - kfree(msgs.buf); - - if (ret != 1) { - dev_err(&client->dev, "Failed regs transferred: %d\n", ret); - return -EIO; - } - - return 0; -} - /* Write registers up to 4 at a time */ static int ov08x40_write_reg(struct ov08x40 *ov08x, u16 reg, u32 len, u32 __val) @@ -1813,22 +2924,6 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x) return ret; } - /* Use i2c burst to write register on full size registers */ - if (ov08x->cur_mode->exposure_shift == 1) { - ret = ov08x40_burst_fill_regs(ov08x, OV08X40_REG_XTALK_FIRST_A, - OV08X40_REG_XTALK_LAST_A, 0x75); - if (ret == 0) - ret = ov08x40_burst_fill_regs(ov08x, - OV08X40_REG_XTALK_FIRST_B, - OV08X40_REG_XTALK_LAST_B, - 0x75); - } - - if (ret) { - dev_err(&client->dev, "%s failed to set regs\n", __func__); - return ret; - } - /* Apply customized values from user */ ret = __v4l2_ctrl_handler_setup(ov08x->sd.ctrl_handler); if (ret) From 8f667d2023844f3a2631c686f970b2f04c7fe7ec Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Wed, 24 Jan 2024 15:43:01 +0100 Subject: [PATCH 153/252] media: ov08x40: Reduce start streaming time Because video duration involves calculating the streaming time, and i2c communication incurs too many XTALK register settings every 4 bytes with i2c START and STOP. So we have opted switch to the i2c burst method. This method involves writing the XTALK registers in the order of the register block. The start streaming time can be reduced from around 400ms to 150ms [Sakari Ailus: Drop unneeded dev_dbg().] Signed-off-by: Jason Chen Reviewed-by: Sergey Senozhatsky Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/i2c/ov08x40.c | 1209 ++--------------------------------- 1 file changed, 57 insertions(+), 1152 deletions(-) diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 010a6017e1ad..48df077522ad 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2022 Intel Corporation. +#include #include #include #include @@ -95,6 +96,12 @@ /* Vertical Window Offset */ #define OV08X40_REG_V_WIN_OFFSET 0x3813 +/* Burst Register */ +#define OV08X40_REG_XTALK_FIRST_A 0x5a80 +#define OV08X40_REG_XTALK_LAST_A 0x5b9f +#define OV08X40_REG_XTALK_FIRST_B 0x5bc0 +#define OV08X40_REG_XTALK_LAST_B 0x5f1f + enum { OV08X40_LINK_FREQ_400MHZ_INDEX, }; @@ -670,1158 +677,6 @@ static const struct ov08x40_reg mode_3856x2416_regs[] = { {0x3502, 0x10}, {0x3508, 0x0f}, {0x3509, 0x80}, - {0x5a80, 0x75}, - {0x5a81, 0x75}, - {0x5a82, 0x75}, - {0x5a83, 0x75}, - {0x5a84, 0x75}, - {0x5a85, 0x75}, - {0x5a86, 0x75}, - {0x5a87, 0x75}, - {0x5a88, 0x75}, - {0x5a89, 0x75}, - {0x5a8a, 0x75}, - {0x5a8b, 0x75}, - {0x5a8c, 0x75}, - {0x5a8d, 0x75}, - {0x5a8e, 0x75}, - {0x5a8f, 0x75}, - {0x5a90, 0x75}, - {0x5a91, 0x75}, - {0x5a92, 0x75}, - {0x5a93, 0x75}, - {0x5a94, 0x75}, - {0x5a95, 0x75}, - {0x5a96, 0x75}, - {0x5a97, 0x75}, - {0x5a98, 0x75}, - {0x5a99, 0x75}, - {0x5a9a, 0x75}, - {0x5a9b, 0x75}, - {0x5a9c, 0x75}, - {0x5a9d, 0x75}, - {0x5a9e, 0x75}, - {0x5a9f, 0x75}, - {0x5aa0, 0x75}, - {0x5aa1, 0x75}, - {0x5aa2, 0x75}, - {0x5aa3, 0x75}, - {0x5aa4, 0x75}, - {0x5aa5, 0x75}, - {0x5aa6, 0x75}, - {0x5aa7, 0x75}, - {0x5aa8, 0x75}, - {0x5aa9, 0x75}, - {0x5aaa, 0x75}, - {0x5aab, 0x75}, - {0x5aac, 0x75}, - {0x5aad, 0x75}, - {0x5aae, 0x75}, - {0x5aaf, 0x75}, - {0x5ab0, 0x75}, - {0x5ab1, 0x75}, - {0x5ab2, 0x75}, - {0x5ab3, 0x75}, - {0x5ab4, 0x75}, - {0x5ab5, 0x75}, - {0x5ab6, 0x75}, - {0x5ab7, 0x75}, - {0x5ab8, 0x75}, - {0x5ab9, 0x75}, - {0x5aba, 0x75}, - {0x5abb, 0x75}, - {0x5abc, 0x75}, - {0x5abd, 0x75}, - {0x5abe, 0x75}, - {0x5abf, 0x75}, - {0x5ac0, 0x75}, - {0x5ac1, 0x75}, - {0x5ac2, 0x75}, - {0x5ac3, 0x75}, - {0x5ac4, 0x75}, - {0x5ac5, 0x75}, - {0x5ac6, 0x75}, - {0x5ac7, 0x75}, - {0x5ac8, 0x75}, - {0x5ac9, 0x75}, - {0x5aca, 0x75}, - {0x5acb, 0x75}, - {0x5acc, 0x75}, - {0x5acd, 0x75}, - {0x5ace, 0x75}, - {0x5acf, 0x75}, - {0x5ad0, 0x75}, - {0x5ad1, 0x75}, - {0x5ad2, 0x75}, - {0x5ad3, 0x75}, - {0x5ad4, 0x75}, - {0x5ad5, 0x75}, - {0x5ad6, 0x75}, - {0x5ad7, 0x75}, - {0x5ad8, 0x75}, - {0x5ad9, 0x75}, - {0x5ada, 0x75}, - {0x5adb, 0x75}, - {0x5adc, 0x75}, - {0x5add, 0x75}, - {0x5ade, 0x75}, - {0x5adf, 0x75}, - {0x5ae0, 0x75}, - {0x5ae1, 0x75}, - {0x5ae2, 0x75}, - {0x5ae3, 0x75}, - {0x5ae4, 0x75}, - {0x5ae5, 0x75}, - {0x5ae6, 0x75}, - {0x5ae7, 0x75}, - {0x5ae8, 0x75}, - {0x5ae9, 0x75}, - {0x5aea, 0x75}, - {0x5aeb, 0x75}, - {0x5aec, 0x75}, - {0x5aed, 0x75}, - {0x5aee, 0x75}, - {0x5aef, 0x75}, - {0x5af0, 0x75}, - {0x5af1, 0x75}, - {0x5af2, 0x75}, - {0x5af3, 0x75}, - {0x5af4, 0x75}, - {0x5af5, 0x75}, - {0x5af6, 0x75}, - {0x5af7, 0x75}, - {0x5af8, 0x75}, - {0x5af9, 0x75}, - {0x5afa, 0x75}, - {0x5afb, 0x75}, - {0x5afc, 0x75}, - {0x5afd, 0x75}, - {0x5afe, 0x75}, - {0x5aff, 0x75}, - {0x5b00, 0x75}, - {0x5b01, 0x75}, - {0x5b02, 0x75}, - {0x5b03, 0x75}, - {0x5b04, 0x75}, - {0x5b05, 0x75}, - {0x5b06, 0x75}, - {0x5b07, 0x75}, - {0x5b08, 0x75}, - {0x5b09, 0x75}, - {0x5b0a, 0x75}, - {0x5b0b, 0x75}, - {0x5b0c, 0x75}, - {0x5b0d, 0x75}, - {0x5b0e, 0x75}, - {0x5b0f, 0x75}, - {0x5b10, 0x75}, - {0x5b11, 0x75}, - {0x5b12, 0x75}, - {0x5b13, 0x75}, - {0x5b14, 0x75}, - {0x5b15, 0x75}, - {0x5b16, 0x75}, - {0x5b17, 0x75}, - {0x5b18, 0x75}, - {0x5b19, 0x75}, - {0x5b1a, 0x75}, - {0x5b1b, 0x75}, - {0x5b1c, 0x75}, - {0x5b1d, 0x75}, - {0x5b1e, 0x75}, - {0x5b1f, 0x75}, - {0x5b20, 0x75}, - {0x5b21, 0x75}, - {0x5b22, 0x75}, - {0x5b23, 0x75}, - {0x5b24, 0x75}, - {0x5b25, 0x75}, - {0x5b26, 0x75}, - {0x5b27, 0x75}, - {0x5b28, 0x75}, - {0x5b29, 0x75}, - {0x5b2a, 0x75}, - {0x5b2b, 0x75}, - {0x5b2c, 0x75}, - {0x5b2d, 0x75}, - {0x5b2e, 0x75}, - {0x5b2f, 0x75}, - {0x5b30, 0x75}, - {0x5b31, 0x75}, - {0x5b32, 0x75}, - {0x5b33, 0x75}, - {0x5b34, 0x75}, - {0x5b35, 0x75}, - {0x5b36, 0x75}, - {0x5b37, 0x75}, - {0x5b38, 0x75}, - {0x5b39, 0x75}, - {0x5b3a, 0x75}, - {0x5b3b, 0x75}, - {0x5b3c, 0x75}, - {0x5b3d, 0x75}, - {0x5b3e, 0x75}, - {0x5b3f, 0x75}, - {0x5b40, 0x75}, - {0x5b41, 0x75}, - {0x5b42, 0x75}, - {0x5b43, 0x75}, - {0x5b44, 0x75}, - {0x5b45, 0x75}, - {0x5b46, 0x75}, - {0x5b47, 0x75}, - {0x5b48, 0x75}, - {0x5b49, 0x75}, - {0x5b4a, 0x75}, - {0x5b4b, 0x75}, - {0x5b4c, 0x75}, - {0x5b4d, 0x75}, - {0x5b4e, 0x75}, - {0x5b4f, 0x75}, - {0x5b50, 0x75}, - {0x5b51, 0x75}, - {0x5b52, 0x75}, - {0x5b53, 0x75}, - {0x5b54, 0x75}, - {0x5b55, 0x75}, - {0x5b56, 0x75}, - {0x5b57, 0x75}, - {0x5b58, 0x75}, - {0x5b59, 0x75}, - {0x5b5a, 0x75}, - {0x5b5b, 0x75}, - {0x5b5c, 0x75}, - {0x5b5d, 0x75}, - {0x5b5e, 0x75}, - {0x5b5f, 0x75}, - {0x5b60, 0x75}, - {0x5b61, 0x75}, - {0x5b62, 0x75}, - {0x5b63, 0x75}, - {0x5b64, 0x75}, - {0x5b65, 0x75}, - {0x5b66, 0x75}, - {0x5b67, 0x75}, - {0x5b68, 0x75}, - {0x5b69, 0x75}, - {0x5b6a, 0x75}, - {0x5b6b, 0x75}, - {0x5b6c, 0x75}, - {0x5b6d, 0x75}, - {0x5b6e, 0x75}, - {0x5b6f, 0x75}, - {0x5b70, 0x75}, - {0x5b71, 0x75}, - {0x5b72, 0x75}, - {0x5b73, 0x75}, - {0x5b74, 0x75}, - {0x5b75, 0x75}, - {0x5b76, 0x75}, - {0x5b77, 0x75}, - {0x5b78, 0x75}, - {0x5b79, 0x75}, - {0x5b7a, 0x75}, - {0x5b7b, 0x75}, - {0x5b7c, 0x75}, - {0x5b7d, 0x75}, - {0x5b7e, 0x75}, - {0x5b7f, 0x75}, - {0x5b80, 0x75}, - {0x5b81, 0x75}, - {0x5b82, 0x75}, - {0x5b83, 0x75}, - {0x5b84, 0x75}, - {0x5b85, 0x75}, - {0x5b86, 0x75}, - {0x5b87, 0x75}, - {0x5b88, 0x75}, - {0x5b89, 0x75}, - {0x5b8a, 0x75}, - {0x5b8b, 0x75}, - {0x5b8c, 0x75}, - {0x5b8d, 0x75}, - {0x5b8e, 0x75}, - {0x5b8f, 0x75}, - {0x5b90, 0x75}, - {0x5b91, 0x75}, - {0x5b92, 0x75}, - {0x5b93, 0x75}, - {0x5b94, 0x75}, - {0x5b95, 0x75}, - {0x5b96, 0x75}, - {0x5b97, 0x75}, - {0x5b98, 0x75}, - {0x5b99, 0x75}, - {0x5b9a, 0x75}, - {0x5b9b, 0x75}, - {0x5b9c, 0x75}, - {0x5b9d, 0x75}, - {0x5b9e, 0x75}, - {0x5b9f, 0x75}, - {0x5bc0, 0x75}, - {0x5bc1, 0x75}, - {0x5bc2, 0x75}, - {0x5bc3, 0x75}, - {0x5bc4, 0x75}, - {0x5bc5, 0x75}, - {0x5bc6, 0x75}, - {0x5bc7, 0x75}, - {0x5bc8, 0x75}, - {0x5bc9, 0x75}, - {0x5bca, 0x75}, - {0x5bcb, 0x75}, - {0x5bcc, 0x75}, - {0x5bcd, 0x75}, - {0x5bce, 0x75}, - {0x5bcf, 0x75}, - {0x5bd0, 0x75}, - {0x5bd1, 0x75}, - {0x5bd2, 0x75}, - {0x5bd3, 0x75}, - {0x5bd4, 0x75}, - {0x5bd5, 0x75}, - {0x5bd6, 0x75}, - {0x5bd7, 0x75}, - {0x5bd8, 0x75}, - {0x5bd9, 0x75}, - {0x5bda, 0x75}, - {0x5bdb, 0x75}, - {0x5bdc, 0x75}, - {0x5bdd, 0x75}, - {0x5bde, 0x75}, - {0x5bdf, 0x75}, - {0x5be0, 0x75}, - {0x5be1, 0x75}, - {0x5be2, 0x75}, - {0x5be3, 0x75}, - {0x5be4, 0x75}, - {0x5be5, 0x75}, - {0x5be6, 0x75}, - {0x5be7, 0x75}, - {0x5be8, 0x75}, - {0x5be9, 0x75}, - {0x5bea, 0x75}, - {0x5beb, 0x75}, - {0x5bec, 0x75}, - {0x5bed, 0x75}, - {0x5bee, 0x75}, - {0x5bef, 0x75}, - {0x5bf0, 0x75}, - {0x5bf1, 0x75}, - {0x5bf2, 0x75}, - {0x5bf3, 0x75}, - {0x5bf4, 0x75}, - {0x5bf5, 0x75}, - {0x5bf6, 0x75}, - {0x5bf7, 0x75}, - {0x5bf8, 0x75}, - {0x5bf9, 0x75}, - {0x5bfa, 0x75}, - {0x5bfb, 0x75}, - {0x5bfc, 0x75}, - {0x5bfd, 0x75}, - {0x5bfe, 0x75}, - {0x5bff, 0x75}, - {0x5c00, 0x75}, - {0x5c01, 0x75}, - {0x5c02, 0x75}, - {0x5c03, 0x75}, - {0x5c04, 0x75}, - {0x5c05, 0x75}, - {0x5c06, 0x75}, - {0x5c07, 0x75}, - {0x5c08, 0x75}, - {0x5c09, 0x75}, - {0x5c0a, 0x75}, - {0x5c0b, 0x75}, - {0x5c0c, 0x75}, - {0x5c0d, 0x75}, - {0x5c0e, 0x75}, - {0x5c0f, 0x75}, - {0x5c10, 0x75}, - {0x5c11, 0x75}, - {0x5c12, 0x75}, - {0x5c13, 0x75}, - {0x5c14, 0x75}, - {0x5c15, 0x75}, - {0x5c16, 0x75}, - {0x5c17, 0x75}, - {0x5c18, 0x75}, - {0x5c19, 0x75}, - {0x5c1a, 0x75}, - {0x5c1b, 0x75}, - {0x5c1c, 0x75}, - {0x5c1d, 0x75}, - {0x5c1e, 0x75}, - {0x5c1f, 0x75}, - {0x5c20, 0x75}, - {0x5c21, 0x75}, - {0x5c22, 0x75}, - {0x5c23, 0x75}, - {0x5c24, 0x75}, - {0x5c25, 0x75}, - {0x5c26, 0x75}, - {0x5c27, 0x75}, - {0x5c28, 0x75}, - {0x5c29, 0x75}, - {0x5c2a, 0x75}, - {0x5c2b, 0x75}, - {0x5c2c, 0x75}, - {0x5c2d, 0x75}, - {0x5c2e, 0x75}, - {0x5c2f, 0x75}, - {0x5c30, 0x75}, - {0x5c31, 0x75}, - {0x5c32, 0x75}, - {0x5c33, 0x75}, - {0x5c34, 0x75}, - {0x5c35, 0x75}, - {0x5c36, 0x75}, - {0x5c37, 0x75}, - {0x5c38, 0x75}, - {0x5c39, 0x75}, - {0x5c3a, 0x75}, - {0x5c3b, 0x75}, - {0x5c3c, 0x75}, - {0x5c3d, 0x75}, - {0x5c3e, 0x75}, - {0x5c3f, 0x75}, - {0x5c40, 0x75}, - {0x5c41, 0x75}, - {0x5c42, 0x75}, - {0x5c43, 0x75}, - {0x5c44, 0x75}, - {0x5c45, 0x75}, - {0x5c46, 0x75}, - {0x5c47, 0x75}, - {0x5c48, 0x75}, - {0x5c49, 0x75}, - {0x5c4a, 0x75}, - {0x5c4b, 0x75}, - {0x5c4c, 0x75}, - {0x5c4d, 0x75}, - {0x5c4e, 0x75}, - {0x5c4f, 0x75}, - {0x5c50, 0x75}, - {0x5c51, 0x75}, - {0x5c52, 0x75}, - {0x5c53, 0x75}, - {0x5c54, 0x75}, - {0x5c55, 0x75}, - {0x5c56, 0x75}, - {0x5c57, 0x75}, - {0x5c58, 0x75}, - {0x5c59, 0x75}, - {0x5c5a, 0x75}, - {0x5c5b, 0x75}, - {0x5c5c, 0x75}, - {0x5c5d, 0x75}, - {0x5c5e, 0x75}, - {0x5c5f, 0x75}, - {0x5c60, 0x75}, - {0x5c61, 0x75}, - {0x5c62, 0x75}, - {0x5c63, 0x75}, - {0x5c64, 0x75}, - {0x5c65, 0x75}, - {0x5c66, 0x75}, - {0x5c67, 0x75}, - {0x5c68, 0x75}, - {0x5c69, 0x75}, - {0x5c6a, 0x75}, - {0x5c6b, 0x75}, - {0x5c6c, 0x75}, - {0x5c6d, 0x75}, - {0x5c6e, 0x75}, - {0x5c6f, 0x75}, - {0x5c70, 0x75}, - {0x5c71, 0x75}, - {0x5c72, 0x75}, - {0x5c73, 0x75}, - {0x5c74, 0x75}, - {0x5c75, 0x75}, - {0x5c76, 0x75}, - {0x5c77, 0x75}, - {0x5c78, 0x75}, - {0x5c79, 0x75}, - {0x5c7a, 0x75}, - {0x5c7b, 0x75}, - {0x5c7c, 0x75}, - {0x5c7d, 0x75}, - {0x5c7e, 0x75}, - {0x5c7f, 0x75}, - {0x5c80, 0x75}, - {0x5c81, 0x75}, - {0x5c82, 0x75}, - {0x5c83, 0x75}, - {0x5c84, 0x75}, - {0x5c85, 0x75}, - {0x5c86, 0x75}, - {0x5c87, 0x75}, - {0x5c88, 0x75}, - {0x5c89, 0x75}, - {0x5c8a, 0x75}, - {0x5c8b, 0x75}, - {0x5c8c, 0x75}, - {0x5c8d, 0x75}, - {0x5c8e, 0x75}, - {0x5c8f, 0x75}, - {0x5c90, 0x75}, - {0x5c91, 0x75}, - {0x5c92, 0x75}, - {0x5c93, 0x75}, - {0x5c94, 0x75}, - {0x5c95, 0x75}, - {0x5c96, 0x75}, - {0x5c97, 0x75}, - {0x5c98, 0x75}, - {0x5c99, 0x75}, - {0x5c9a, 0x75}, - {0x5c9b, 0x75}, - {0x5c9c, 0x75}, - {0x5c9d, 0x75}, - {0x5c9e, 0x75}, - {0x5c9f, 0x75}, - {0x5ca0, 0x75}, - {0x5ca1, 0x75}, - {0x5ca2, 0x75}, - {0x5ca3, 0x75}, - {0x5ca4, 0x75}, - {0x5ca5, 0x75}, - {0x5ca6, 0x75}, - {0x5ca7, 0x75}, - {0x5ca8, 0x75}, - {0x5ca9, 0x75}, - {0x5caa, 0x75}, - {0x5cab, 0x75}, - {0x5cac, 0x75}, - {0x5cad, 0x75}, - {0x5cae, 0x75}, - {0x5caf, 0x75}, - {0x5cb0, 0x75}, - {0x5cb1, 0x75}, - {0x5cb2, 0x75}, - {0x5cb3, 0x75}, - {0x5cb4, 0x75}, - {0x5cb5, 0x75}, - {0x5cb6, 0x75}, - {0x5cb7, 0x75}, - {0x5cb8, 0x75}, - {0x5cb9, 0x75}, - {0x5cba, 0x75}, - {0x5cbb, 0x75}, - {0x5cbc, 0x75}, - {0x5cbd, 0x75}, - {0x5cbe, 0x75}, - {0x5cbf, 0x75}, - {0x5cc0, 0x75}, - {0x5cc1, 0x75}, - {0x5cc2, 0x75}, - {0x5cc3, 0x75}, - {0x5cc4, 0x75}, - {0x5cc5, 0x75}, - {0x5cc6, 0x75}, - {0x5cc7, 0x75}, - {0x5cc8, 0x75}, - {0x5cc9, 0x75}, - {0x5cca, 0x75}, - {0x5ccb, 0x75}, - {0x5ccc, 0x75}, - {0x5ccd, 0x75}, - {0x5cce, 0x75}, - {0x5ccf, 0x75}, - {0x5cd0, 0x75}, - {0x5cd1, 0x75}, - {0x5cd2, 0x75}, - {0x5cd3, 0x75}, - {0x5cd4, 0x75}, - {0x5cd5, 0x75}, - {0x5cd6, 0x75}, - {0x5cd7, 0x75}, - {0x5cd8, 0x75}, - {0x5cd9, 0x75}, - {0x5cda, 0x75}, - {0x5cdb, 0x75}, - {0x5cdc, 0x75}, - {0x5cdd, 0x75}, - {0x5cde, 0x75}, - {0x5cdf, 0x75}, - {0x5ce0, 0x75}, - {0x5ce1, 0x75}, - {0x5ce2, 0x75}, - {0x5ce3, 0x75}, - {0x5ce4, 0x75}, - {0x5ce5, 0x75}, - {0x5ce6, 0x75}, - {0x5ce7, 0x75}, - {0x5ce8, 0x75}, - {0x5ce9, 0x75}, - {0x5cea, 0x75}, - {0x5ceb, 0x75}, - {0x5cec, 0x75}, - {0x5ced, 0x75}, - {0x5cee, 0x75}, - {0x5cef, 0x75}, - {0x5cf0, 0x75}, - {0x5cf1, 0x75}, - {0x5cf2, 0x75}, - {0x5cf3, 0x75}, - {0x5cf4, 0x75}, - {0x5cf5, 0x75}, - {0x5cf6, 0x75}, - {0x5cf7, 0x75}, - {0x5cf8, 0x75}, - {0x5cf9, 0x75}, - {0x5cfa, 0x75}, - {0x5cfb, 0x75}, - {0x5cfc, 0x75}, - {0x5cfd, 0x75}, - {0x5cfe, 0x75}, - {0x5cff, 0x75}, - {0x5d00, 0x75}, - {0x5d01, 0x75}, - {0x5d02, 0x75}, - {0x5d03, 0x75}, - {0x5d04, 0x75}, - {0x5d05, 0x75}, - {0x5d06, 0x75}, - {0x5d07, 0x75}, - {0x5d08, 0x75}, - {0x5d09, 0x75}, - {0x5d0a, 0x75}, - {0x5d0b, 0x75}, - {0x5d0c, 0x75}, - {0x5d0d, 0x75}, - {0x5d0e, 0x75}, - {0x5d0f, 0x75}, - {0x5d10, 0x75}, - {0x5d11, 0x75}, - {0x5d12, 0x75}, - {0x5d13, 0x75}, - {0x5d14, 0x75}, - {0x5d15, 0x75}, - {0x5d16, 0x75}, - {0x5d17, 0x75}, - {0x5d18, 0x75}, - {0x5d19, 0x75}, - {0x5d1a, 0x75}, - {0x5d1b, 0x75}, - {0x5d1c, 0x75}, - {0x5d1d, 0x75}, - {0x5d1e, 0x75}, - {0x5d1f, 0x75}, - {0x5d20, 0x75}, - {0x5d21, 0x75}, - {0x5d22, 0x75}, - {0x5d23, 0x75}, - {0x5d24, 0x75}, - {0x5d25, 0x75}, - {0x5d26, 0x75}, - {0x5d27, 0x75}, - {0x5d28, 0x75}, - {0x5d29, 0x75}, - {0x5d2a, 0x75}, - {0x5d2b, 0x75}, - {0x5d2c, 0x75}, - {0x5d2d, 0x75}, - {0x5d2e, 0x75}, - {0x5d2f, 0x75}, - {0x5d30, 0x75}, - {0x5d31, 0x75}, - {0x5d32, 0x75}, - {0x5d33, 0x75}, - {0x5d34, 0x75}, - {0x5d35, 0x75}, - {0x5d36, 0x75}, - {0x5d37, 0x75}, - {0x5d38, 0x75}, - {0x5d39, 0x75}, - {0x5d3a, 0x75}, - {0x5d3b, 0x75}, - {0x5d3c, 0x75}, - {0x5d3d, 0x75}, - {0x5d3e, 0x75}, - {0x5d3f, 0x75}, - {0x5d40, 0x75}, - {0x5d41, 0x75}, - {0x5d42, 0x75}, - {0x5d43, 0x75}, - {0x5d44, 0x75}, - {0x5d45, 0x75}, - {0x5d46, 0x75}, - {0x5d47, 0x75}, - {0x5d48, 0x75}, - {0x5d49, 0x75}, - {0x5d4a, 0x75}, - {0x5d4b, 0x75}, - {0x5d4c, 0x75}, - {0x5d4d, 0x75}, - {0x5d4e, 0x75}, - {0x5d4f, 0x75}, - {0x5d50, 0x75}, - {0x5d51, 0x75}, - {0x5d52, 0x75}, - {0x5d53, 0x75}, - {0x5d54, 0x75}, - {0x5d55, 0x75}, - {0x5d56, 0x75}, - {0x5d57, 0x75}, - {0x5d58, 0x75}, - {0x5d59, 0x75}, - {0x5d5a, 0x75}, - {0x5d5b, 0x75}, - {0x5d5c, 0x75}, - {0x5d5d, 0x75}, - {0x5d5e, 0x75}, - {0x5d5f, 0x75}, - {0x5d60, 0x75}, - {0x5d61, 0x75}, - {0x5d62, 0x75}, - {0x5d63, 0x75}, - {0x5d64, 0x75}, - {0x5d65, 0x75}, - {0x5d66, 0x75}, - {0x5d67, 0x75}, - {0x5d68, 0x75}, - {0x5d69, 0x75}, - {0x5d6a, 0x75}, - {0x5d6b, 0x75}, - {0x5d6c, 0x75}, - {0x5d6d, 0x75}, - {0x5d6e, 0x75}, - {0x5d6f, 0x75}, - {0x5d70, 0x75}, - {0x5d71, 0x75}, - {0x5d72, 0x75}, - {0x5d73, 0x75}, - {0x5d74, 0x75}, - {0x5d75, 0x75}, - {0x5d76, 0x75}, - {0x5d77, 0x75}, - {0x5d78, 0x75}, - {0x5d79, 0x75}, - {0x5d7a, 0x75}, - {0x5d7b, 0x75}, - {0x5d7c, 0x75}, - {0x5d7d, 0x75}, - {0x5d7e, 0x75}, - {0x5d7f, 0x75}, - {0x5d80, 0x75}, - {0x5d81, 0x75}, - {0x5d82, 0x75}, - {0x5d83, 0x75}, - {0x5d84, 0x75}, - {0x5d85, 0x75}, - {0x5d86, 0x75}, - {0x5d87, 0x75}, - {0x5d88, 0x75}, - {0x5d89, 0x75}, - {0x5d8a, 0x75}, - {0x5d8b, 0x75}, - {0x5d8c, 0x75}, - {0x5d8d, 0x75}, - {0x5d8e, 0x75}, - {0x5d8f, 0x75}, - {0x5d90, 0x75}, - {0x5d91, 0x75}, - {0x5d92, 0x75}, - {0x5d93, 0x75}, - {0x5d94, 0x75}, - {0x5d95, 0x75}, - {0x5d96, 0x75}, - {0x5d97, 0x75}, - {0x5d98, 0x75}, - {0x5d99, 0x75}, - {0x5d9a, 0x75}, - {0x5d9b, 0x75}, - {0x5d9c, 0x75}, - {0x5d9d, 0x75}, - {0x5d9e, 0x75}, - {0x5d9f, 0x75}, - {0x5da0, 0x75}, - {0x5da1, 0x75}, - {0x5da2, 0x75}, - {0x5da3, 0x75}, - {0x5da4, 0x75}, - {0x5da5, 0x75}, - {0x5da6, 0x75}, - {0x5da7, 0x75}, - {0x5da8, 0x75}, - {0x5da9, 0x75}, - {0x5daa, 0x75}, - {0x5dab, 0x75}, - {0x5dac, 0x75}, - {0x5dad, 0x75}, - {0x5dae, 0x75}, - {0x5daf, 0x75}, - {0x5db0, 0x75}, - {0x5db1, 0x75}, - {0x5db2, 0x75}, - {0x5db3, 0x75}, - {0x5db4, 0x75}, - {0x5db5, 0x75}, - {0x5db6, 0x75}, - {0x5db7, 0x75}, - {0x5db8, 0x75}, - {0x5db9, 0x75}, - {0x5dba, 0x75}, - {0x5dbb, 0x75}, - {0x5dbc, 0x75}, - {0x5dbd, 0x75}, - {0x5dbe, 0x75}, - {0x5dbf, 0x75}, - {0x5dc0, 0x75}, - {0x5dc1, 0x75}, - {0x5dc2, 0x75}, - {0x5dc3, 0x75}, - {0x5dc4, 0x75}, - {0x5dc5, 0x75}, - {0x5dc6, 0x75}, - {0x5dc7, 0x75}, - {0x5dc8, 0x75}, - {0x5dc9, 0x75}, - {0x5dca, 0x75}, - {0x5dcb, 0x75}, - {0x5dcc, 0x75}, - {0x5dcd, 0x75}, - {0x5dce, 0x75}, - {0x5dcf, 0x75}, - {0x5dd0, 0x75}, - {0x5dd1, 0x75}, - {0x5dd2, 0x75}, - {0x5dd3, 0x75}, - {0x5dd4, 0x75}, - {0x5dd5, 0x75}, - {0x5dd6, 0x75}, - {0x5dd7, 0x75}, - {0x5dd8, 0x75}, - {0x5dd9, 0x75}, - {0x5dda, 0x75}, - {0x5ddb, 0x75}, - {0x5ddc, 0x75}, - {0x5ddd, 0x75}, - {0x5dde, 0x75}, - {0x5ddf, 0x75}, - {0x5de0, 0x75}, - {0x5de1, 0x75}, - {0x5de2, 0x75}, - {0x5de3, 0x75}, - {0x5de4, 0x75}, - {0x5de5, 0x75}, - {0x5de6, 0x75}, - {0x5de7, 0x75}, - {0x5de8, 0x75}, - {0x5de9, 0x75}, - {0x5dea, 0x75}, - {0x5deb, 0x75}, - {0x5dec, 0x75}, - {0x5ded, 0x75}, - {0x5dee, 0x75}, - {0x5def, 0x75}, - {0x5df0, 0x75}, - {0x5df1, 0x75}, - {0x5df2, 0x75}, - {0x5df3, 0x75}, - {0x5df4, 0x75}, - {0x5df5, 0x75}, - {0x5df6, 0x75}, - {0x5df7, 0x75}, - {0x5df8, 0x75}, - {0x5df9, 0x75}, - {0x5dfa, 0x75}, - {0x5dfb, 0x75}, - {0x5dfc, 0x75}, - {0x5dfd, 0x75}, - {0x5dfe, 0x75}, - {0x5dff, 0x75}, - {0x5e00, 0x75}, - {0x5e01, 0x75}, - {0x5e02, 0x75}, - {0x5e03, 0x75}, - {0x5e04, 0x75}, - {0x5e05, 0x75}, - {0x5e06, 0x75}, - {0x5e07, 0x75}, - {0x5e08, 0x75}, - {0x5e09, 0x75}, - {0x5e0a, 0x75}, - {0x5e0b, 0x75}, - {0x5e0c, 0x75}, - {0x5e0d, 0x75}, - {0x5e0e, 0x75}, - {0x5e0f, 0x75}, - {0x5e10, 0x75}, - {0x5e11, 0x75}, - {0x5e12, 0x75}, - {0x5e13, 0x75}, - {0x5e14, 0x75}, - {0x5e15, 0x75}, - {0x5e16, 0x75}, - {0x5e17, 0x75}, - {0x5e18, 0x75}, - {0x5e19, 0x75}, - {0x5e1a, 0x75}, - {0x5e1b, 0x75}, - {0x5e1c, 0x75}, - {0x5e1d, 0x75}, - {0x5e1e, 0x75}, - {0x5e1f, 0x75}, - {0x5e20, 0x75}, - {0x5e21, 0x75}, - {0x5e22, 0x75}, - {0x5e23, 0x75}, - {0x5e24, 0x75}, - {0x5e25, 0x75}, - {0x5e26, 0x75}, - {0x5e27, 0x75}, - {0x5e28, 0x75}, - {0x5e29, 0x75}, - {0x5e2a, 0x75}, - {0x5e2b, 0x75}, - {0x5e2c, 0x75}, - {0x5e2d, 0x75}, - {0x5e2e, 0x75}, - {0x5e2f, 0x75}, - {0x5e30, 0x75}, - {0x5e31, 0x75}, - {0x5e32, 0x75}, - {0x5e33, 0x75}, - {0x5e34, 0x75}, - {0x5e35, 0x75}, - {0x5e36, 0x75}, - {0x5e37, 0x75}, - {0x5e38, 0x75}, - {0x5e39, 0x75}, - {0x5e3a, 0x75}, - {0x5e3b, 0x75}, - {0x5e3c, 0x75}, - {0x5e3d, 0x75}, - {0x5e3e, 0x75}, - {0x5e3f, 0x75}, - {0x5e40, 0x75}, - {0x5e41, 0x75}, - {0x5e42, 0x75}, - {0x5e43, 0x75}, - {0x5e44, 0x75}, - {0x5e45, 0x75}, - {0x5e46, 0x75}, - {0x5e47, 0x75}, - {0x5e48, 0x75}, - {0x5e49, 0x75}, - {0x5e4a, 0x75}, - {0x5e4b, 0x75}, - {0x5e4c, 0x75}, - {0x5e4d, 0x75}, - {0x5e4e, 0x75}, - {0x5e4f, 0x75}, - {0x5e50, 0x75}, - {0x5e51, 0x75}, - {0x5e52, 0x75}, - {0x5e53, 0x75}, - {0x5e54, 0x75}, - {0x5e55, 0x75}, - {0x5e56, 0x75}, - {0x5e57, 0x75}, - {0x5e58, 0x75}, - {0x5e59, 0x75}, - {0x5e5a, 0x75}, - {0x5e5b, 0x75}, - {0x5e5c, 0x75}, - {0x5e5d, 0x75}, - {0x5e5e, 0x75}, - {0x5e5f, 0x75}, - {0x5e60, 0x75}, - {0x5e61, 0x75}, - {0x5e62, 0x75}, - {0x5e63, 0x75}, - {0x5e64, 0x75}, - {0x5e65, 0x75}, - {0x5e66, 0x75}, - {0x5e67, 0x75}, - {0x5e68, 0x75}, - {0x5e69, 0x75}, - {0x5e6a, 0x75}, - {0x5e6b, 0x75}, - {0x5e6c, 0x75}, - {0x5e6d, 0x75}, - {0x5e6e, 0x75}, - {0x5e6f, 0x75}, - {0x5e70, 0x75}, - {0x5e71, 0x75}, - {0x5e72, 0x75}, - {0x5e73, 0x75}, - {0x5e74, 0x75}, - {0x5e75, 0x75}, - {0x5e76, 0x75}, - {0x5e77, 0x75}, - {0x5e78, 0x75}, - {0x5e79, 0x75}, - {0x5e7a, 0x75}, - {0x5e7b, 0x75}, - {0x5e7c, 0x75}, - {0x5e7d, 0x75}, - {0x5e7e, 0x75}, - {0x5e7f, 0x75}, - {0x5e80, 0x75}, - {0x5e81, 0x75}, - {0x5e82, 0x75}, - {0x5e83, 0x75}, - {0x5e84, 0x75}, - {0x5e85, 0x75}, - {0x5e86, 0x75}, - {0x5e87, 0x75}, - {0x5e88, 0x75}, - {0x5e89, 0x75}, - {0x5e8a, 0x75}, - {0x5e8b, 0x75}, - {0x5e8c, 0x75}, - {0x5e8d, 0x75}, - {0x5e8e, 0x75}, - {0x5e8f, 0x75}, - {0x5e90, 0x75}, - {0x5e91, 0x75}, - {0x5e92, 0x75}, - {0x5e93, 0x75}, - {0x5e94, 0x75}, - {0x5e95, 0x75}, - {0x5e96, 0x75}, - {0x5e97, 0x75}, - {0x5e98, 0x75}, - {0x5e99, 0x75}, - {0x5e9a, 0x75}, - {0x5e9b, 0x75}, - {0x5e9c, 0x75}, - {0x5e9d, 0x75}, - {0x5e9e, 0x75}, - {0x5e9f, 0x75}, - {0x5ea0, 0x75}, - {0x5ea1, 0x75}, - {0x5ea2, 0x75}, - {0x5ea3, 0x75}, - {0x5ea4, 0x75}, - {0x5ea5, 0x75}, - {0x5ea6, 0x75}, - {0x5ea7, 0x75}, - {0x5ea8, 0x75}, - {0x5ea9, 0x75}, - {0x5eaa, 0x75}, - {0x5eab, 0x75}, - {0x5eac, 0x75}, - {0x5ead, 0x75}, - {0x5eae, 0x75}, - {0x5eaf, 0x75}, - {0x5eb0, 0x75}, - {0x5eb1, 0x75}, - {0x5eb2, 0x75}, - {0x5eb3, 0x75}, - {0x5eb4, 0x75}, - {0x5eb5, 0x75}, - {0x5eb6, 0x75}, - {0x5eb7, 0x75}, - {0x5eb8, 0x75}, - {0x5eb9, 0x75}, - {0x5eba, 0x75}, - {0x5ebb, 0x75}, - {0x5ebc, 0x75}, - {0x5ebd, 0x75}, - {0x5ebe, 0x75}, - {0x5ebf, 0x75}, - {0x5ec0, 0x75}, - {0x5ec1, 0x75}, - {0x5ec2, 0x75}, - {0x5ec3, 0x75}, - {0x5ec4, 0x75}, - {0x5ec5, 0x75}, - {0x5ec6, 0x75}, - {0x5ec7, 0x75}, - {0x5ec8, 0x75}, - {0x5ec9, 0x75}, - {0x5eca, 0x75}, - {0x5ecb, 0x75}, - {0x5ecc, 0x75}, - {0x5ecd, 0x75}, - {0x5ece, 0x75}, - {0x5ecf, 0x75}, - {0x5ed0, 0x75}, - {0x5ed1, 0x75}, - {0x5ed2, 0x75}, - {0x5ed3, 0x75}, - {0x5ed4, 0x75}, - {0x5ed5, 0x75}, - {0x5ed6, 0x75}, - {0x5ed7, 0x75}, - {0x5ed8, 0x75}, - {0x5ed9, 0x75}, - {0x5eda, 0x75}, - {0x5edb, 0x75}, - {0x5edc, 0x75}, - {0x5edd, 0x75}, - {0x5ede, 0x75}, - {0x5edf, 0x75}, - {0x5ee0, 0x75}, - {0x5ee1, 0x75}, - {0x5ee2, 0x75}, - {0x5ee3, 0x75}, - {0x5ee4, 0x75}, - {0x5ee5, 0x75}, - {0x5ee6, 0x75}, - {0x5ee7, 0x75}, - {0x5ee8, 0x75}, - {0x5ee9, 0x75}, - {0x5eea, 0x75}, - {0x5eeb, 0x75}, - {0x5eec, 0x75}, - {0x5eed, 0x75}, - {0x5eee, 0x75}, - {0x5eef, 0x75}, - {0x5ef0, 0x75}, - {0x5ef1, 0x75}, - {0x5ef2, 0x75}, - {0x5ef3, 0x75}, - {0x5ef4, 0x75}, - {0x5ef5, 0x75}, - {0x5ef6, 0x75}, - {0x5ef7, 0x75}, - {0x5ef8, 0x75}, - {0x5ef9, 0x75}, - {0x5efa, 0x75}, - {0x5efb, 0x75}, - {0x5efc, 0x75}, - {0x5efd, 0x75}, - {0x5efe, 0x75}, - {0x5eff, 0x75}, - {0x5f00, 0x75}, - {0x5f01, 0x75}, - {0x5f02, 0x75}, - {0x5f03, 0x75}, - {0x5f04, 0x75}, - {0x5f05, 0x75}, - {0x5f06, 0x75}, - {0x5f07, 0x75}, - {0x5f08, 0x75}, - {0x5f09, 0x75}, - {0x5f0a, 0x75}, - {0x5f0b, 0x75}, - {0x5f0c, 0x75}, - {0x5f0d, 0x75}, - {0x5f0e, 0x75}, - {0x5f0f, 0x75}, - {0x5f10, 0x75}, - {0x5f11, 0x75}, - {0x5f12, 0x75}, - {0x5f13, 0x75}, - {0x5f14, 0x75}, - {0x5f15, 0x75}, - {0x5f16, 0x75}, - {0x5f17, 0x75}, - {0x5f18, 0x75}, - {0x5f19, 0x75}, - {0x5f1a, 0x75}, - {0x5f1b, 0x75}, - {0x5f1c, 0x75}, - {0x5f1d, 0x75}, - {0x5f1e, 0x75}, - {0x5f1f, 0x75}, }; static const struct ov08x40_reg mode_1928x1208_regs[] = { @@ -2484,6 +1339,40 @@ static int ov08x40_read_reg(struct ov08x40 *ov08x, return 0; } +static int ov08x40_burst_fill_regs(struct ov08x40 *ov08x, u16 first_reg, + u16 last_reg, u8 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd); + struct i2c_msg msgs; + size_t i, num_regs; + int ret; + + num_regs = last_reg - first_reg + 1; + msgs.addr = client->addr; + msgs.flags = 0; + msgs.len = 2 + num_regs; + msgs.buf = kmalloc(msgs.len, GFP_KERNEL); + + if (!msgs.buf) + return -ENOMEM; + + put_unaligned_be16(first_reg, msgs.buf); + + for (i = 0; i < num_regs; ++i) + msgs.buf[2 + i] = val; + + ret = i2c_transfer(client->adapter, &msgs, 1); + + kfree(msgs.buf); + + if (ret != 1) { + dev_err(&client->dev, "Failed regs transferred: %d\n", ret); + return -EIO; + } + + return 0; +} + /* Write registers up to 4 at a time */ static int ov08x40_write_reg(struct ov08x40 *ov08x, u16 reg, u32 len, u32 __val) @@ -2924,6 +1813,22 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x) return ret; } + /* Use i2c burst to write register on full size registers */ + if (ov08x->cur_mode->exposure_shift == 1) { + ret = ov08x40_burst_fill_regs(ov08x, OV08X40_REG_XTALK_FIRST_A, + OV08X40_REG_XTALK_LAST_A, 0x75); + if (ret == 0) + ret = ov08x40_burst_fill_regs(ov08x, + OV08X40_REG_XTALK_FIRST_B, + OV08X40_REG_XTALK_LAST_B, + 0x75); + } + + if (ret) { + dev_err(&client->dev, "%s failed to set regs\n", __func__); + return ret; + } + /* Apply customized values from user */ ret = __v4l2_ctrl_handler_setup(ov08x->sd.ctrl_handler); if (ret) From 102fb77c2deb0df3683ef8ff7a6f4cf91dc456e2 Mon Sep 17 00:00:00 2001 From: Philipp Stanner Date: Thu, 2 Nov 2023 20:16:34 +0100 Subject: [PATCH 154/252] media: drivers/media/dvb-core: copy user arrays safely At several positions in dvb_frontend.c, memdup_user() is utilized to copy userspace arrays. This is done without overflow checks. Use the new wrapper memdup_array_user() to copy the arrays more safely. Link: https://lore.kernel.org/linux-media/20231102191633.52592-2-pstanner@redhat.com Suggested-by: Dave Airlie Signed-off-by: Philipp Stanner Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 9293b058ab99..93d3378a0df4 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2168,7 +2168,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd, if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; - tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp)); + tvp = memdup_array_user(compat_ptr(tvps->props), + tvps->num, sizeof(*tvp)); if (IS_ERR(tvp)) return PTR_ERR(tvp); @@ -2199,7 +2200,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd, if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; - tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp)); + tvp = memdup_array_user(compat_ptr(tvps->props), + tvps->num, sizeof(*tvp)); if (IS_ERR(tvp)) return PTR_ERR(tvp); @@ -2379,7 +2381,8 @@ static int dvb_get_property(struct dvb_frontend *fe, struct file *file, if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS) return -EINVAL; - tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); + tvp = memdup_array_user((void __user *)tvps->props, + tvps->num, sizeof(*tvp)); if (IS_ERR(tvp)) return PTR_ERR(tvp); @@ -2457,7 +2460,8 @@ static int dvb_frontend_handle_ioctl(struct file *file, if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; - tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); + tvp = memdup_array_user((void __user *)tvps->props, + tvps->num, sizeof(*tvp)); if (IS_ERR(tvp)) return PTR_ERR(tvp); From b1d47b27110438282f0b56738628347d9b915f53 Mon Sep 17 00:00:00 2001 From: XueBing Chen Date: Thu, 11 Jan 2024 11:58:56 +0100 Subject: [PATCH 155/252] media: cx24110: clean up some coding style issues Fix the following errors reported by checkpatch: ERROR: "foo* bar" should be "foo *bar" ERROR: spaces required around that '=' (ctx:VxV) ERROR: space required after that ',' (ctx:VxV) Link: https://lore.kernel.org/linux-media/20240111105856.14655-1-chenxb_99091@126.com Signed-off-by: XueBing Chen Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/cx24110.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c index 9aeea089756f..65dd9b72ea55 100644 --- a/drivers/media/dvb-frontends/cx24110.c +++ b/drivers/media/dvb-frontends/cx24110.c @@ -224,13 +224,13 @@ static enum fe_code_rate cx24110_get_fec(struct cx24110_state *state) } } -static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) +static int cx24110_set_symbolrate (struct cx24110_state *state, u32 srate) { /* fixme (low): add error handling */ u32 ratio; u32 tmp, fclk, BDRI; - static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; + static const u32 bands[] = {5000000UL, 15000000UL, 90999000UL/2}; int i; dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate); From 2350d4d4c819cccbc8a1b636c8b069fdf059685e Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 11 Jan 2024 22:33:44 +0100 Subject: [PATCH 156/252] media: dvb-frontends/dvb-pll: Remove usage of the deprecated ida_simple_xx() API ida_alloc() and ida_free() should be preferred to the deprecated ida_simple_get() and ida_simple_remove(). Note that the upper limit of ida_simple_get() is exclusive, but the one of ida_alloc_max() is inclusive. So a -1 has been added when needed. Link: https://lore.kernel.org/linux-media/920639b9e05775eea56ecb9cd5ed38ad292a96a8.1705008803.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christophe JAILLET Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/dvb-pll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index ef697ab6bc2e..1775a4aa0a18 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c @@ -796,7 +796,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, b1[0] = 0; msg.buf = b1; - nr = ida_simple_get(&pll_ida, 0, DVB_PLL_MAX, GFP_KERNEL); + nr = ida_alloc_max(&pll_ida, DVB_PLL_MAX - 1, GFP_KERNEL); if (nr < 0) { kfree(b1); return NULL; @@ -862,7 +862,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, return fe; out: kfree(b1); - ida_simple_remove(&pll_ida, nr); + ida_free(&pll_ida, nr); return NULL; } @@ -905,7 +905,7 @@ static void dvb_pll_remove(struct i2c_client *client) struct dvb_frontend *fe = i2c_get_clientdata(client); struct dvb_pll_priv *priv = fe->tuner_priv; - ida_simple_remove(&pll_ida, priv->nr); + ida_free(&pll_ida, priv->nr); dvb_pll_release(fe); } From 2386ae062c647a6ee5f93d2581b45d48cce677e3 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 16 Jan 2024 12:50:02 +0100 Subject: [PATCH 157/252] media: dvb: remove redundant assignment to variable ret The variable ret is being assigned a value but it isn't being read afterwards. The assignment is redundant and so ret can be removed. Also add spaces after , to clean up checkpatch warnings. Cleans up clang scan build warning: warning: Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret' [deadcode.DeadStores] Link: https://lore.kernel.org/linux-media/20240116115002.2265367-1-colin.i.king@gmail.com Signed-off-by: Colin Ian King Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/bcm3510.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c index b3f5c49accaf..27f1de21f571 100644 --- a/drivers/media/dvb-frontends/bcm3510.c +++ b/drivers/media/dvb-frontends/bcm3510.c @@ -797,7 +797,6 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, struct i2c_adapter *i2c) { struct bcm3510_state* state = NULL; - int ret; bcm3510_register_value v; /* allocate memory for the internal state */ @@ -816,7 +815,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, mutex_init(&state->hab_mutex); - if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) + if (bcm3510_readB(state, 0xe0, &v) < 0) goto error; deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER); From 7976b003e8bd0f95187e7f7f841ad6501b4c3f01 Mon Sep 17 00:00:00 2001 From: Stefan Herdler Date: Mon, 29 Jan 2024 00:32:45 +0100 Subject: [PATCH 158/252] media: docs: uAPI: dvb/osd: completing the documentation The existing documentation of the legacy DVB Decoder API was incomplete. Revising the documentation, adding missing parts and arranging the documentation files new. This patch contains the documentation of osd.h. Link: https://lore.kernel.org/linux-media/20240128233249.32794-3-herdler@nurfuerspam.de Signed-off-by: Stefan Herdler Signed-off-by: Mauro Carvalho Chehab --- .../media/dvb/legacy_dvb_osd.rst | 883 ++++++++++++++++++ 1 file changed, 883 insertions(+) create mode 100644 Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst new file mode 100644 index 000000000000..179b66a8016a --- /dev/null +++ b/Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst @@ -0,0 +1,883 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0 + +.. c:namespace:: dtv.legacy.osd + +.. _dvb_osd: + +============== +DVB OSD Device +============== + +.. attention:: Do **not** use in new drivers! + See: :ref:`legacy_dvb_decoder_notes` + +The DVB OSD device controls the OnScreen-Display of the AV7110 based +DVB-cards with hardware MPEG2 decoder. It can be accessed through +``/dev/dvb/adapter?/osd0``. +Data types and ioctl definitions can be accessed by including +``linux/dvb/osd.h`` in your application. + +The OSD is not a frame-buffer like on many other cards. +It is a kind of canvas one can draw on. +The color-depth is limited depending on the memory size installed. +An appropriate palette of colors has to be set up. +The installed memory size can be identified with the `OSD_GET_CAPABILITY`_ +ioctl. + +OSD Data Types +============== + +OSD_Command +----------- + +Synopsis +~~~~~~~~ + +.. code-block:: c + + typedef enum { + /* All functions return -2 on "not open" */ + OSD_Close = 1, + OSD_Open, + OSD_Show, + OSD_Hide, + OSD_Clear, + OSD_Fill, + OSD_SetColor, + OSD_SetPalette, + OSD_SetTrans, + OSD_SetPixel, + OSD_GetPixel, + OSD_SetRow, + OSD_SetBlock, + OSD_FillRow, + OSD_FillBlock, + OSD_Line, + OSD_Query, + OSD_Test, + OSD_Text, + OSD_SetWindow, + OSD_MoveWindow, + OSD_OpenRaw, + } OSD_Command; + +Commands +~~~~~~~~ + +.. note:: All functions return -2 on "not open" + +.. flat-table:: + :header-rows: 1 + :stub-columns: 0 + + - .. + + - Command + + - | Used variables of ``struct`` `osd_cmd_t`_. + | Usage{variable} if alternative use. + + - :cspan:`2` Description + + + + - .. + + - ``OSD_Close`` + + - - + + - | Disables OSD and releases the buffers. + | Returns 0 on success. + + - .. + + - ``OSD_Open`` + + - | x0,y0,x1,y1, + | BitPerPixel[2/4/8]{color&0x0F}, + | mix[0..15]{color&0xF0} + + - | Opens OSD with this size and bit depth + | Returns 0 on success, + | -1 on DRAM allocation error, + | -2 on "already open". + + - .. + + - ``OSD_Show`` + + - - + + - | Enables OSD mode. + | Returns 0 on success. + + - .. + + - ``OSD_Hide`` + + - - + + - | Disables OSD mode. + | Returns 0 on success. + + - .. + + - ``OSD_Clear`` + + - - + + - | Sets all pixel to color 0. + | Returns 0 on success. + + - .. + + - ``OSD_Fill`` + + - color + + - | Sets all pixel to color . + | Returns 0 on success. + + - .. + + - ``OSD_SetColor`` + + - | color, + | R{x0},G{y0},B{x1}, + | opacity{y1} + + - | Set palette entry to , and apply + | R,G,B: 0..255 + | R=Red, G=Green, B=Blue + | opacity=0: pixel opacity 0% (only video pixel shows) + | opacity=1..254: pixel opacity as specified in header + | opacity=255: pixel opacity 100% (only OSD pixel shows) + | Returns 0 on success, -1 on error. + + - .. + + - ``OSD_SetPalette`` + + - | firstcolor{color}, + | lastcolor{x0},data + + - | Set a number of entries in the palette. + | Sets the entries "firstcolor" through "lastcolor" from the + array "data". + | Data has 4 byte for each color: + | R,G,B, and a opacity value: 0->transparent, 1..254->mix, + 255->pixel + + - .. + + - ``OSD_SetTrans`` + + - transparency{color} + + - | Sets transparency of mixed pixel (0..15). + | Returns 0 on success. + + - .. + + - ``OSD_SetPixel`` + + - x0,y0,color + + - | Sets pixel , to color number . + | Returns 0 on success, -1 on error. + + - .. + + - ``OSD_GetPixel`` + + - x0,y0 + + - | Returns color number of pixel ,, or -1. + | Command currently not supported by the AV7110! + + - .. + + - ``OSD_SetRow`` + + - x0,y0,x1,data + + - | Fills pixels x0,y through x1,y with the content of data[]. + | Returns 0 on success, -1 on clipping all pixel (no pixel + drawn). + + - .. + + - ``OSD_SetBlock`` + + - | x0,y0,x1,y1, + | increment{color}, + | data + + - | Fills pixels x0,y0 through x1,y1 with the content of data[]. + | Inc contains the width of one line in the data block, + | inc<=0 uses block width as line width. + | Returns 0 on success, -1 on clipping all pixel. + + - .. + + - ``OSD_FillRow`` + + - x0,y0,x1,color + + - | Fills pixels x0,y through x1,y with the color . + | Returns 0 on success, -1 on clipping all pixel. + + - .. + + - ``OSD_FillBlock`` + + - x0,y0,x1,y1,color + + - | Fills pixels x0,y0 through x1,y1 with the color . + | Returns 0 on success, -1 on clipping all pixel. + + - .. + + - ``OSD_Line`` + + - x0,y0,x1,y1,color + + - | Draw a line from x0,y0 to x1,y1 with the color . + | Returns 0 on success. + + - .. + + - ``OSD_Query`` + + - | x0,y0,x1,y1, + | xasp{color}; yasp=11 + + - | Fills parameters with the picture dimensions and the pixel + aspect ratio. + | Returns 0 on success. + | Command currently not supported by the AV7110! + + - .. + + - ``OSD_Test`` + + - - + + - | Draws a test picture. + | For debugging purposes only. + | Returns 0 on success. + - .. + + - ``OSD_Text`` + + - x0,y0,size,color,text + + - Draws a text at position x0,y0 with the color . + + - .. + + - ``OSD_SetWindow`` + + - x0 + + - Set window with number 0` chapter. + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + - .. + + - ``EINVAL`` + + - Command is out of range. + + +----- + + +OSD_GET_CAPABILITY +------------------ + +Synopsis +~~~~~~~~ + +.. c:macro:: OSD_GET_CAPABILITY + +.. code-block:: c + + int ioctl(int fd, int request = OSD_GET_CAPABILITY, + struct osd_cap_t *cap) + +Arguments +~~~~~~~~~ + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + - .. + + - ``int fd`` + + - :cspan:`1` File descriptor returned by a previous call + to `open()`_. + + - .. + + - ``int request`` + + - Equals ``OSD_GET_CAPABILITY`` for this command. + + - .. + + - ``unsigned int *cap`` + + - Pointer to the location of the structure `osd_cap_t`_ for this + command. + +Description +~~~~~~~~~~~ + +.. attention:: Do **not** use in new drivers! + See: :ref:`legacy_dvb_decoder_notes` + +This ioctl is used to get the capabilities of the OSD of the AV7110 based +DVB-decoder-card in use. + +.. note:: + The structure osd_cap_t has to be setup by the user and passed to the + driver. + +Return Value +~~~~~~~~~~~~ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + + - .. + + - ``EINVAL`` + + - Unsupported capability. + + +----- + + +open() +------ + +Synopsis +~~~~~~~~ + +.. code-block:: c + + #include + +.. c:function:: int open(const char *deviceName, int flags) + +Arguments +~~~~~~~~~ + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + - .. + + - ``const char *deviceName`` + + - Name of specific OSD device. + + - .. + + - :rspan:`3` ``int flags`` + + - :cspan:`1` A bit-wise OR of the following flags: + + - .. + + - ``O_RDONLY`` + + - read-only access + + - .. + + - ``O_RDWR`` + + - read/write access + + - .. + + - ``O_NONBLOCK`` + - | Open in non-blocking mode + | (blocking mode is the default) + +Description +~~~~~~~~~~~ + +This system call opens a named OSD device (e.g. +``/dev/dvb/adapter?/osd0``) for subsequent use. + +Return Value +~~~~~~~~~~~~ + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + - .. + + - ``ENODEV`` + + - Device driver not loaded/available. + + - .. + + - ``EINTERNAL`` + + - Internal error. + + - .. + + - ``EBUSY`` + + - Device or resource busy. + + - .. + + - ``EINVAL`` + + - Invalid argument. + + +----- + + +close() +------- + +Synopsis +~~~~~~~~ + +.. c:function:: int close(int fd) + +Arguments +~~~~~~~~~ + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + - .. + + - ``int fd`` + + - :cspan:`1` File descriptor returned by a previous call + to `open()`_ . + +Description +~~~~~~~~~~~ + +This system call closes a previously opened OSD device. + +Return Value +~~~~~~~~~~~~ + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + - .. + + - ``EBADF`` + + - fd is not a valid open file descriptor. From 2c7ff90604093c5c6df6a29565daf3a3b108bde4 Mon Sep 17 00:00:00 2001 From: Stefan Herdler Date: Mon, 29 Jan 2024 00:32:46 +0100 Subject: [PATCH 159/252] media: docs: uAPI: dvb/audio: completing the documentation (data types) The existing documentation of the legacy DVB Decoder API was incomplete. Revising the documentation, adding missing parts and arranging the documentation files new. This patch contains the documentation of the data types defined in audio.h. Link: https://lore.kernel.org/linux-media/20240128233249.32794-4-herdler@nurfuerspam.de Signed-off-by: Stefan Herdler Signed-off-by: Mauro Carvalho Chehab --- .../media/dvb/legacy_dvb_audio.rst | 447 ++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst new file mode 100644 index 000000000000..d15088748f55 --- /dev/null +++ b/Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst @@ -0,0 +1,447 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0 + +.. c:namespace:: dtv.legacy.audio + +.. _dvb_audio: + +================ +DVB Audio Device +================ + +.. attention:: Do **not** use in new drivers! + See: :ref:`legacy_dvb_decoder_notes` + +The DVB audio device controls the MPEG2 audio decoder of the DVB +hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data +types and ioctl definitions can be accessed by including +``linux/dvb/audio.h`` in your application. + +Please note that most DVB cards don’t have their own MPEG decoder, which +results in the omission of the audio and video device. + +These ioctls were also used by V4L2 to control MPEG decoders implemented +in V4L2. The use of these ioctls for that purpose has been made obsolete +and proper V4L2 ioctls or controls have been created to replace that +functionality. Use :ref:`V4L2 ioctls