--- /dev/null
+# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip-isp1.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC Image Signal Processing unit v1
+
+maintainers:
+ - Helen Koike <helen.koike@collabora.com>
+
+description: |
+ Rockchip ISP1 is the Camera interface for the Rockchip series of SoCs
+ which contains image processing, scaling, and compression functions.
+
+properties:
+ compatible:
+ const: rockchip,rk3399-cif-isp
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 3
+ items:
+ # isp0 and isp1
+ - description: ISP clock
+ - description: ISP AXI clock
+ - description: ISP AHB clock
+ # only for isp1
+ - description: ISP Pixel clock
+
+ clock-names:
+ minItems: 3
+ items:
+ # isp0 and isp1
+ - const: isp
+ - const: aclk
+ - const: hclk
+ # only for isp1
+ - const: pclk_isp
+
+ iommus:
+ maxItems: 1
+
+ phys:
+ maxItems: 1
+ description: phandle for the PHY port
+
+ phy-names:
+ const: dphy
+
+ power-domains:
+ maxItems: 1
+
+ # See ./video-interfaces.txt for details
+ ports:
+ type: object
+ additionalProperties: false
+
+ properties:
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ port@0:
+ type: object
+ description: connection point for sensors at MIPI-DPHY RX0
+ additionalProperties: false
+
+ properties:
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ reg:
+ const: 0
+
+ patternProperties:
+ endpoint:
+ type: object
+ additionalProperties: false
+
+ properties:
+ reg:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ remote-endpoint: true
+
+ required:
+ - reg
+ - "#address-cells"
+ - "#size-cells"
+
+ required:
+ - "#address-cells"
+ - "#size-cells"
+ - port@0
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - iommus
+ - phys
+ - phy-names
+ - power-domains
+ - ports
+
+if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3399-cif-isp
+then:
+ properties:
+ clocks:
+ minItems: 3
+ maxItems: 4
+ clock-names:
+ minItems: 3
+ maxItems: 4
+
+additionalProperties: false
+
+examples:
+ - |
+
+ #include <dt-bindings/clock/rk3399-cru.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/rk3399-power.h>
+
+ parent0: parent {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ isp0: isp0@ff910000 {
+ compatible = "rockchip,rk3399-cif-isp";
+ reg = <0x0 0xff910000 0x0 0x4000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_ISP0>,
+ <&cru ACLK_ISP0_WRAPPER>,
+ <&cru HCLK_ISP0_WRAPPER>;
+ clock-names = "isp", "aclk", "hclk";
+ iommus = <&isp0_mmu>;
+ phys = <&dphy>;
+ phy-names = "dphy";
+ power-domains = <&power RK3399_PD_ISP0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mipi_in_wcam: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&wcam_out>;
+ data-lanes = <1 2>;
+ };
+
+ mipi_in_ucam: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&ucam_out>;
+ data-lanes = <1>;
+ };
+ };
+ };
+ };
+
+ i2c7: i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wcam: camera@36 {
+ compatible = "ovti,ov5695";
+ reg = <0x36>;
+
+ port {
+ wcam_out: endpoint {
+ remote-endpoint = <&mipi_in_wcam>;
+ data-lanes = <1 2>;
+ };
+ };
+ };
+
+ ucam: camera@3c {
+ compatible = "ovti,ov2685";
+ reg = <0x3c>;
+
+ port {
+ ucam_out: endpoint {
+ remote-endpoint = <&mipi_in_ucam>;
+ data-lanes = <1>;
+ };
+ };
+ };
+ };
+ };
rkisp1 uAPI data types
======================
-.. kernel-doc:: drivers/staging/media/rkisp1/uapi/rkisp1-config.h
+.. kernel-doc:: include/uapi/linux/rkisp1-config.h
M: Helen Koike <helen.koike@collabora.com>
M: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
L: linux-media@vger.kernel.org
+L: linux-rockchip@lists.infradead.org
S: Maintained
F: Documentation/admin-guide/media/rkisp1.rst
+F: Documentation/devicetree/bindings/media/rockchip-isp1.yaml
F: Documentation/userspace-api/media/v4l/pixfmt-meta-rkisp1.rst
-F: drivers/staging/media/rkisp1/
+F: drivers/media/platform/rockchip/rkisp1
+F: include/uapi/linux/rkisp1-config.h
ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
M: Jacob Chen <jacob-chen@iotwrt.com>
help
This is a v4l2 driver for the Renesas CEU Interface
+config VIDEO_ROCKCHIP_ISP1
+ tristate "Rockchip Image Signal Processing v1 Unit driver"
+ depends on VIDEO_V4L2 && OF
+ depends on ARCH_ROCKCHIP || COMPILE_TEST
+ select MEDIA_CONTROLLER
+ select VIDEO_V4L2_SUBDEV_API
+ select VIDEOBUF2_DMA_CONTIG
+ select VIDEOBUF2_VMALLOC
+ select V4L2_FWNODE
+ select GENERIC_PHY_MIPI_DPHY
+ default n
+ help
+ Enable this to support the Image Signal Processing (ISP) module
+ present in RK3399 SoCs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called rockchip-isp1.
+
source "drivers/media/platform/exynos4-is/Kconfig"
source "drivers/media/platform/am437x/Kconfig"
source "drivers/media/platform/xilinx/Kconfig"
obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
+obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip/rkisp1/
obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/
obj-y += omap/
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip-isp1.o
+rockchip-isp1-objs += rkisp1-capture.o \
+ rkisp1-common.o \
+ rkisp1-dev.o \
+ rkisp1-isp.o \
+ rkisp1-resizer.o \
+ rkisp1-stats.o \
+ rkisp1-params.o
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - V4l capture device
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "rkisp1-common.h"
+
+/*
+ * NOTE: There are two capture video devices in rkisp1, selfpath and mainpath.
+ *
+ * differences between selfpath and mainpath
+ * available mp sink input: isp
+ * available sp sink input : isp, dma(TODO)
+ * available mp sink pad fmts: yuv422, raw
+ * available sp sink pad fmts: yuv422, yuv420......
+ * available mp source fmts: yuv, raw, jpeg(TODO)
+ * available sp source fmts: yuv, rgb
+ */
+
+#define RKISP1_SP_DEV_NAME RKISP1_DRIVER_NAME "_selfpath"
+#define RKISP1_MP_DEV_NAME RKISP1_DRIVER_NAME "_mainpath"
+
+#define RKISP1_MIN_BUFFERS_NEEDED 3
+
+enum rkisp1_plane {
+ RKISP1_PLANE_Y = 0,
+ RKISP1_PLANE_CB = 1,
+ RKISP1_PLANE_CR = 2
+};
+
+/*
+ * @fourcc: pixel format
+ * @fmt_type: helper filed for pixel format
+ * @uv_swap: if cb cr swaped, for yuv
+ * @write_format: defines how YCbCr self picture data is written to memory
+ * @output_format: defines sp output format
+ * @mbus: the mbus code on the src resizer pad that matches the pixel format
+ */
+struct rkisp1_capture_fmt_cfg {
+ u32 fourcc;
+ u8 uv_swap;
+ u32 write_format;
+ u32 output_format;
+ u32 mbus;
+};
+
+struct rkisp1_capture_ops {
+ void (*config)(struct rkisp1_capture *cap);
+ void (*stop)(struct rkisp1_capture *cap);
+ void (*enable)(struct rkisp1_capture *cap);
+ void (*disable)(struct rkisp1_capture *cap);
+ void (*set_data_path)(struct rkisp1_capture *cap);
+ bool (*is_stopped)(struct rkisp1_capture *cap);
+};
+
+struct rkisp1_capture_config {
+ const struct rkisp1_capture_fmt_cfg *fmts;
+ int fmt_size;
+ struct {
+ u32 y_size_init;
+ u32 cb_size_init;
+ u32 cr_size_init;
+ u32 y_base_ad_init;
+ u32 cb_base_ad_init;
+ u32 cr_base_ad_init;
+ u32 y_offs_cnt_init;
+ u32 cb_offs_cnt_init;
+ u32 cr_offs_cnt_init;
+ } mi;
+};
+
+/*
+ * The supported pixel formats for mainpath. NOTE, pixel formats with identical 'mbus'
+ * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
+ */
+static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
+ /* yuv422 */
+ {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV16,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV61,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YVU422M,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ },
+ /* yuv400 */
+ {
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ },
+ /* yuv420 */
+ {
+ .fourcc = V4L2_PIX_FMT_NV21,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV21M,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV12M,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YVU420,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ },
+ /* raw */
+ {
+ .fourcc = V4L2_PIX_FMT_SRGGB8,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGRBG8,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGBRG8,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SRGGB10,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGRBG10,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGBRG10,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SBGGR10,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SRGGB12,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGRBG12,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGBRG12,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SBGGR12,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
+ },
+};
+
+/*
+ * The supported pixel formats for selfpath. NOTE, pixel formats with identical 'mbus'
+ * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
+ */
+static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
+ /* yuv422 */
+ {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV16,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV61,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YVU422M,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ },
+ /* yuv400 */
+ {
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV400,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ },
+ /* rgb */
+ {
+ .fourcc = V4L2_PIX_FMT_XBGR32,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ },
+ /* yuv420 */
+ {
+ .fourcc = V4L2_PIX_FMT_NV21,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV21M,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV12M,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .uv_swap = 0,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YVU420,
+ .uv_swap = 1,
+ .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
+ .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
+ .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
+ },
+};
+
+static const struct rkisp1_capture_config rkisp1_capture_config_mp = {
+ .fmts = rkisp1_mp_fmts,
+ .fmt_size = ARRAY_SIZE(rkisp1_mp_fmts),
+ .mi = {
+ .y_size_init = RKISP1_CIF_MI_MP_Y_SIZE_INIT,
+ .cb_size_init = RKISP1_CIF_MI_MP_CB_SIZE_INIT,
+ .cr_size_init = RKISP1_CIF_MI_MP_CR_SIZE_INIT,
+ .y_base_ad_init = RKISP1_CIF_MI_MP_Y_BASE_AD_INIT,
+ .cb_base_ad_init = RKISP1_CIF_MI_MP_CB_BASE_AD_INIT,
+ .cr_base_ad_init = RKISP1_CIF_MI_MP_CR_BASE_AD_INIT,
+ .y_offs_cnt_init = RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT,
+ .cb_offs_cnt_init = RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT,
+ .cr_offs_cnt_init = RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT,
+ },
+};
+
+static const struct rkisp1_capture_config rkisp1_capture_config_sp = {
+ .fmts = rkisp1_sp_fmts,
+ .fmt_size = ARRAY_SIZE(rkisp1_sp_fmts),
+ .mi = {
+ .y_size_init = RKISP1_CIF_MI_SP_Y_SIZE_INIT,
+ .cb_size_init = RKISP1_CIF_MI_SP_CB_SIZE_INIT,
+ .cr_size_init = RKISP1_CIF_MI_SP_CR_SIZE_INIT,
+ .y_base_ad_init = RKISP1_CIF_MI_SP_Y_BASE_AD_INIT,
+ .cb_base_ad_init = RKISP1_CIF_MI_SP_CB_BASE_AD_INIT,
+ .cr_base_ad_init = RKISP1_CIF_MI_SP_CR_BASE_AD_INIT,
+ .y_offs_cnt_init = RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT,
+ .cb_offs_cnt_init = RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT,
+ .cr_offs_cnt_init = RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT,
+ },
+};
+
+static inline struct rkisp1_vdev_node *
+rkisp1_vdev_to_node(struct video_device *vdev)
+{
+ return container_of(vdev, struct rkisp1_vdev_node, vdev);
+}
+
+int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ const struct rkisp1_capture_fmt_cfg *fmts = cap->config->fmts;
+ /*
+ * initialize curr_mbus to non existing mbus code 0 to ensure it is
+ * different from fmts[0].mbus
+ */
+ u32 curr_mbus = 0;
+ int i, n = 0;
+
+ for (i = 0; i < cap->config->fmt_size; i++) {
+ if (fmts[i].mbus == curr_mbus)
+ continue;
+
+ curr_mbus = fmts[i].mbus;
+ if (n++ == code->index) {
+ code->code = curr_mbus;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+/* ----------------------------------------------------------------------------
+ * Stream operations for self-picture path (sp) and main-picture path (mp)
+ */
+
+static void rkisp1_mi_config_ctrl(struct rkisp1_capture *cap)
+{
+ u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+ mi_ctrl &= ~GENMASK(17, 16);
+ mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64;
+
+ mi_ctrl &= ~GENMASK(19, 18);
+ mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64;
+
+ mi_ctrl |= RKISP1_CIF_MI_CTRL_INIT_BASE_EN |
+ RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN;
+
+ rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static u32 rkisp1_pixfmt_comp_size(const struct v4l2_pix_format_mplane *pixm,
+ unsigned int component)
+{
+ /*
+ * If packed format, then plane_fmt[0].sizeimage is the sum of all
+ * components, so we need to calculate just the size of Y component.
+ * See rkisp1_fill_pixfmt().
+ */
+ if (!component && pixm->num_planes == 1)
+ return pixm->plane_fmt[0].bytesperline * pixm->height;
+ return pixm->plane_fmt[component].sizeimage;
+}
+
+static void rkisp1_irq_frame_end_enable(struct rkisp1_capture *cap)
+{
+ u32 mi_imsc = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_IMSC);
+
+ mi_imsc |= RKISP1_CIF_MI_FRAME(cap);
+ rkisp1_write(cap->rkisp1, mi_imsc, RKISP1_CIF_MI_IMSC);
+}
+
+static void rkisp1_mp_config(struct rkisp1_capture *cap)
+{
+ const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+ struct rkisp1_device *rkisp1 = cap->rkisp1;
+ u32 reg;
+
+ rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
+ cap->config->mi.y_size_init);
+ rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
+ cap->config->mi.cb_size_init);
+ rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
+ cap->config->mi.cr_size_init);
+
+ rkisp1_irq_frame_end_enable(cap);
+
+ /* set uv swapping for semiplanar formats */
+ if (cap->pix.info->comp_planes == 2) {
+ reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+ if (cap->pix.cfg->uv_swap)
+ reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
+ else
+ reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
+ rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+ }
+
+ rkisp1_mi_config_ctrl(cap);
+
+ reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
+ reg &= ~RKISP1_MI_CTRL_MP_FMT_MASK;
+ reg |= cap->pix.cfg->write_format;
+ rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
+
+ reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
+ reg |= RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE;
+ rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_sp_config(struct rkisp1_capture *cap)
+{
+ const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+ struct rkisp1_device *rkisp1 = cap->rkisp1;
+ u32 mi_ctrl, reg;
+
+ rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
+ cap->config->mi.y_size_init);
+ rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
+ cap->config->mi.cb_size_init);
+ rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
+ cap->config->mi.cr_size_init);
+
+ rkisp1_write(rkisp1, pixm->width, RKISP1_CIF_MI_SP_Y_PIC_WIDTH);
+ rkisp1_write(rkisp1, pixm->height, RKISP1_CIF_MI_SP_Y_PIC_HEIGHT);
+ rkisp1_write(rkisp1, cap->sp_y_stride, RKISP1_CIF_MI_SP_Y_LLENGTH);
+
+ rkisp1_irq_frame_end_enable(cap);
+
+ /* set uv swapping for semiplanar formats */
+ if (cap->pix.info->comp_planes == 2) {
+ reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+ if (cap->pix.cfg->uv_swap)
+ reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
+ else
+ reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
+ rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
+ }
+
+ rkisp1_mi_config_ctrl(cap);
+
+ mi_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
+ mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
+ mi_ctrl |= cap->pix.cfg->write_format |
+ RKISP1_MI_CTRL_SP_INPUT_YUV422 |
+ cap->pix.cfg->output_format |
+ RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
+ rkisp1_write(rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_mp_disable(struct rkisp1_capture *cap)
+{
+ u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+ mi_ctrl &= ~(RKISP1_CIF_MI_CTRL_MP_ENABLE |
+ RKISP1_CIF_MI_CTRL_RAW_ENABLE);
+ rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_sp_disable(struct rkisp1_capture *cap)
+{
+ u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+ mi_ctrl &= ~RKISP1_CIF_MI_CTRL_SP_ENABLE;
+ rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_mp_enable(struct rkisp1_capture *cap)
+{
+ u32 mi_ctrl;
+
+ rkisp1_mp_disable(cap);
+
+ mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+ if (v4l2_is_format_bayer(cap->pix.info))
+ mi_ctrl |= RKISP1_CIF_MI_CTRL_RAW_ENABLE;
+ /* YUV */
+ else
+ mi_ctrl |= RKISP1_CIF_MI_CTRL_MP_ENABLE;
+
+ rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_sp_enable(struct rkisp1_capture *cap)
+{
+ u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
+
+ mi_ctrl |= RKISP1_CIF_MI_CTRL_SP_ENABLE;
+ rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
+}
+
+static void rkisp1_mp_sp_stop(struct rkisp1_capture *cap)
+{
+ if (!cap->is_streaming)
+ return;
+ rkisp1_write(cap->rkisp1,
+ RKISP1_CIF_MI_FRAME(cap), RKISP1_CIF_MI_ICR);
+ cap->ops->disable(cap);
+}
+
+static bool rkisp1_mp_is_stopped(struct rkisp1_capture *cap)
+{
+ u32 en = RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED |
+ RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED;
+
+ return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) & en);
+}
+
+static bool rkisp1_sp_is_stopped(struct rkisp1_capture *cap)
+{
+ return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) &
+ RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED);
+}
+
+static void rkisp1_mp_set_data_path(struct rkisp1_capture *cap)
+{
+ u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
+
+ dpcl = dpcl | RKISP1_CIF_VI_DPCL_CHAN_MODE_MP |
+ RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI;
+ rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
+}
+
+static void rkisp1_sp_set_data_path(struct rkisp1_capture *cap)
+{
+ u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
+
+ dpcl |= RKISP1_CIF_VI_DPCL_CHAN_MODE_SP;
+ rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
+}
+
+static struct rkisp1_capture_ops rkisp1_capture_ops_mp = {
+ .config = rkisp1_mp_config,
+ .enable = rkisp1_mp_enable,
+ .disable = rkisp1_mp_disable,
+ .stop = rkisp1_mp_sp_stop,
+ .set_data_path = rkisp1_mp_set_data_path,
+ .is_stopped = rkisp1_mp_is_stopped,
+};
+
+static struct rkisp1_capture_ops rkisp1_capture_ops_sp = {
+ .config = rkisp1_sp_config,
+ .enable = rkisp1_sp_enable,
+ .disable = rkisp1_sp_disable,
+ .stop = rkisp1_mp_sp_stop,
+ .set_data_path = rkisp1_sp_set_data_path,
+ .is_stopped = rkisp1_sp_is_stopped,
+};
+
+/* ----------------------------------------------------------------------------
+ * Frame buffer operations
+ */
+
+static int rkisp1_dummy_buf_create(struct rkisp1_capture *cap)
+{
+ const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+ struct rkisp1_dummy_buffer *dummy_buf = &cap->buf.dummy;
+
+ dummy_buf->size = max3(rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
+ rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
+ rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
+
+ /* The driver never access vaddr, no mapping is required */
+ dummy_buf->vaddr = dma_alloc_attrs(cap->rkisp1->dev,
+ dummy_buf->size,
+ &dummy_buf->dma_addr,
+ GFP_KERNEL,
+ DMA_ATTR_NO_KERNEL_MAPPING);
+ if (!dummy_buf->vaddr)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap)
+{
+ dma_free_attrs(cap->rkisp1->dev,
+ cap->buf.dummy.size, cap->buf.dummy.vaddr,
+ cap->buf.dummy.dma_addr, DMA_ATTR_NO_KERNEL_MAPPING);
+}
+
+static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
+{
+ cap->buf.curr = cap->buf.next;
+ cap->buf.next = NULL;
+
+ if (!list_empty(&cap->buf.queue)) {
+ u32 *buff_addr;
+
+ cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue);
+ list_del(&cap->buf.next->queue);
+
+ buff_addr = cap->buf.next->buff_addr;
+
+ rkisp1_write(cap->rkisp1,
+ buff_addr[RKISP1_PLANE_Y],
+ cap->config->mi.y_base_ad_init);
+ rkisp1_write(cap->rkisp1,
+ buff_addr[RKISP1_PLANE_CB],
+ cap->config->mi.cb_base_ad_init);
+ rkisp1_write(cap->rkisp1,
+ buff_addr[RKISP1_PLANE_CR],
+ cap->config->mi.cr_base_ad_init);
+ } else {
+ /*
+ * Use the dummy space allocated by dma_alloc_coherent to
+ * throw data if there is no available buffer.
+ */
+ rkisp1_write(cap->rkisp1,
+ cap->buf.dummy.dma_addr,
+ cap->config->mi.y_base_ad_init);
+ rkisp1_write(cap->rkisp1,
+ cap->buf.dummy.dma_addr,
+ cap->config->mi.cb_base_ad_init);
+ rkisp1_write(cap->rkisp1,
+ cap->buf.dummy.dma_addr,
+ cap->config->mi.cr_base_ad_init);
+ }
+
+ /* Set plane offsets */
+ rkisp1_write(cap->rkisp1, 0, cap->config->mi.y_offs_cnt_init);
+ rkisp1_write(cap->rkisp1, 0, cap->config->mi.cb_offs_cnt_init);
+ rkisp1_write(cap->rkisp1, 0, cap->config->mi.cr_offs_cnt_init);
+}
+
+/*
+ * This function is called when a frame end comes. The next frame
+ * is processing and we should set up buffer for next-next frame,
+ * otherwise it will overflow.
+ */
+static void rkisp1_handle_buffer(struct rkisp1_capture *cap)
+{
+ struct rkisp1_isp *isp = &cap->rkisp1->isp;
+ struct rkisp1_buffer *curr_buf;
+
+ spin_lock(&cap->buf.lock);
+ curr_buf = cap->buf.curr;
+
+ if (curr_buf) {
+ curr_buf->vb.sequence = isp->frame_sequence;
+ curr_buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns();
+ curr_buf->vb.field = V4L2_FIELD_NONE;
+ vb2_buffer_done(&curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+ } else {
+ cap->rkisp1->debug.frame_drop[cap->id]++;
+ }
+
+ rkisp1_set_next_buf(cap);
+ spin_unlock(&cap->buf.lock);
+}
+
+void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
+{
+ unsigned int i;
+ u32 status;
+
+ status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS);
+ rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR);
+
+ for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
+ struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
+
+ if (!(status & RKISP1_CIF_MI_FRAME(cap)))
+ continue;
+ if (!cap->is_stopping) {
+ rkisp1_handle_buffer(cap);
+ continue;
+ }
+ /*
+ * Make sure stream is actually stopped, whose state
+ * can be read from the shadow register, before
+ * wake_up() thread which would immediately free all
+ * frame buffers. stop() takes effect at the next
+ * frame end that sync the configurations to shadow
+ * regs.
+ */
+ if (!cap->ops->is_stopped(cap)) {
+ cap->ops->stop(cap);
+ continue;
+ }
+ cap->is_stopping = false;
+ cap->is_streaming = false;
+ wake_up(&cap->done);
+ }
+}
+
+/* ----------------------------------------------------------------------------
+ * Vb2 operations
+ */
+
+static int rkisp1_vb2_queue_setup(struct vb2_queue *queue,
+ unsigned int *num_buffers,
+ unsigned int *num_planes,
+ unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ struct rkisp1_capture *cap = queue->drv_priv;
+ const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+ unsigned int i;
+
+ if (*num_planes) {
+ if (*num_planes != pixm->num_planes)
+ return -EINVAL;
+
+ for (i = 0; i < pixm->num_planes; i++)
+ if (sizes[i] < pixm->plane_fmt[i].sizeimage)
+ return -EINVAL;
+ } else {
+ *num_planes = pixm->num_planes;
+ for (i = 0; i < pixm->num_planes; i++)
+ sizes[i] = pixm->plane_fmt[i].sizeimage;
+ }
+
+ return 0;
+}
+
+static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct rkisp1_buffer *ispbuf =
+ container_of(vbuf, struct rkisp1_buffer, vb);
+ struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
+ const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
+ unsigned int i;
+
+ memset(ispbuf->buff_addr, 0, sizeof(ispbuf->buff_addr));
+ for (i = 0; i < pixm->num_planes; i++)
+ ispbuf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+
+ /* Convert to non-MPLANE */
+ if (pixm->num_planes == 1) {
+ ispbuf->buff_addr[RKISP1_PLANE_CB] =
+ ispbuf->buff_addr[RKISP1_PLANE_Y] +
+ rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y);
+ ispbuf->buff_addr[RKISP1_PLANE_CR] =
+ ispbuf->buff_addr[RKISP1_PLANE_CB] +
+ rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB);
+ }
+
+ /*
+ * uv swap can be supported for planar formats by switching
+ * the address of cb and cr
+ */
+ if (cap->pix.info->comp_planes == 3 && cap->pix.cfg->uv_swap)
+ swap(ispbuf->buff_addr[RKISP1_PLANE_CR],
+ ispbuf->buff_addr[RKISP1_PLANE_CB]);
+
+ spin_lock_irq(&cap->buf.lock);
+ list_add_tail(&ispbuf->queue, &cap->buf.queue);
+ spin_unlock_irq(&cap->buf.lock);
+}
+
+static int rkisp1_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+ struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
+ unsigned int i;
+
+ for (i = 0; i < cap->pix.fmt.num_planes; i++) {
+ unsigned long size = cap->pix.fmt.plane_fmt[i].sizeimage;
+
+ if (vb2_plane_size(vb, i) < size) {
+ dev_err(cap->rkisp1->dev,
+ "User buffer too small (%ld < %ld)\n",
+ vb2_plane_size(vb, i), size);
+ return -EINVAL;
+ }
+ vb2_set_plane_payload(vb, i, size);
+ }
+
+ return 0;
+}
+
+static void rkisp1_return_all_buffers(struct rkisp1_capture *cap,
+ enum vb2_buffer_state state)
+{
+ struct rkisp1_buffer *buf;
+
+ spin_lock_irq(&cap->buf.lock);
+ if (cap->buf.curr) {
+ vb2_buffer_done(&cap->buf.curr->vb.vb2_buf, state);
+ cap->buf.curr = NULL;
+ }
+ if (cap->buf.next) {
+ vb2_buffer_done(&cap->buf.next->vb.vb2_buf, state);
+ cap->buf.next = NULL;
+ }
+ while (!list_empty(&cap->buf.queue)) {
+ buf = list_first_entry(&cap->buf.queue,
+ struct rkisp1_buffer, queue);
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb.vb2_buf, state);
+ }
+ spin_unlock_irq(&cap->buf.lock);
+}
+
+/*
+ * Most of registers inside rockchip ISP1 have shadow register since
+ * they must be not be changed during processing a frame.
+ * Usually, each sub-module updates its shadow register after
+ * processing the last pixel of a frame.
+ */
+static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
+{
+ struct rkisp1_device *rkisp1 = cap->rkisp1;
+ struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
+
+ cap->ops->set_data_path(cap);
+ cap->ops->config(cap);
+
+ /* Setup a buffer for the next frame */
+ spin_lock_irq(&cap->buf.lock);
+ rkisp1_set_next_buf(cap);
+ cap->ops->enable(cap);
+ /* It's safe to config ACTIVE and SHADOW regs for the
+ * first stream. While when the second is starting, do NOT
+ * force update because it also update the first one.
+ *
+ * The latter case would drop one more buf(that is 2) since
+ * there's not buf in shadow when the second FE received. This's
+ * also required because the second FE maybe corrupt especially
+ * when run at 120fps.
+ */
+ if (!other->is_streaming) {
+ /* force cfg update */
+ rkisp1_write(rkisp1,
+ RKISP1_CIF_MI_INIT_SOFT_UPD, RKISP1_CIF_MI_INIT);
+ rkisp1_set_next_buf(cap);
+ }
+ spin_unlock_irq(&cap->buf.lock);
+ cap->is_streaming = true;
+}
+
+static void rkisp1_cap_stream_disable(struct rkisp1_capture *cap)
+{
+ int ret;
+
+ /* Stream should stop in interrupt. If it dosn't, stop it by force. */
+ cap->is_stopping = true;
+ ret = wait_event_timeout(cap->done,
+ !cap->is_streaming,
+ msecs_to_jiffies(1000));
+ if (!ret) {
+ cap->rkisp1->debug.stop_timeout[cap->id]++;
+ cap->ops->stop(cap);
+ cap->is_stopping = false;
+ cap->is_streaming = false;
+ }
+}
+
+/*
+ * rkisp1_pipeline_stream_disable - disable nodes in the pipeline
+ *
+ * Call s_stream(false) in the reverse order from
+ * rkisp1_pipeline_stream_enable() and disable the DMA engine.
+ * Should be called before media_pipeline_stop()
+ */
+static void rkisp1_pipeline_stream_disable(struct rkisp1_capture *cap)
+ __must_hold(&cap->rkisp1->stream_lock)
+{
+ struct rkisp1_device *rkisp1 = cap->rkisp1;
+
+ rkisp1_cap_stream_disable(cap);
+
+ /*
+ * If the other capture is streaming, isp and sensor nodes shouldn't
+ * be disabled, skip them.
+ */
+ if (rkisp1->pipe.streaming_count < 2) {
+ v4l2_subdev_call(rkisp1->active_sensor->sd, video, s_stream,
+ false);
+ v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, false);
+ }
+
+ v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video, s_stream,
+ false);
+}
+
+/*
+ * rkisp1_pipeline_stream_enable - enable nodes in the pipeline
+ *
+ * Enable the DMA Engine and call s_stream(true) through the pipeline.
+ * Should be called after media_pipeline_start()
+ */
+static int rkisp1_pipeline_stream_enable(struct rkisp1_capture *cap)
+ __must_hold(&cap->rkisp1->stream_lock)
+{
+ struct rkisp1_device *rkisp1 = cap->rkisp1;
+ int ret;
+
+ rkisp1_cap_stream_enable(cap);
+
+ ret = v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video,
+ s_stream, true);
+ if (ret)
+ goto err_disable_cap;
+
+ /*
+ * If the other capture is streaming, isp and sensor nodes are already
+ * enabled, skip them.
+ */
+ if (rkisp1->pipe.streaming_count > 1)
+ return 0;
+
+ ret = v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, true);
+ if (ret)
+ goto err_disable_rsz;
+
+ ret = v4l2_subdev_call(rkisp1->active_sensor->sd, video, s_stream,
+ true);
+ if (ret)
+ goto err_disable_isp;
+
+ return 0;
+
+err_disable_isp:
+ v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, false);
+err_disable_rsz:
+ v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video, s_stream,
+ false);
+err_disable_cap:
+ rkisp1_cap_stream_disable(cap);
+
+ return ret;
+}
+
+static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue)
+{
+ struct rkisp1_capture *cap = queue->drv_priv;
+ struct rkisp1_vdev_node *node = &cap->vnode;
+ struct rkisp1_device *rkisp1 = cap->rkisp1;
+ int ret;
+
+ mutex_lock(&cap->rkisp1->stream_lock);
+
+ rkisp1_pipeline_stream_disable(cap);
+
+ rkisp1_return_all_buffers(cap, VB2_BUF_STATE_ERROR);
+
+ v4l2_pipeline_pm_put(&node->vdev.entity);
+ ret = pm_runtime_put(rkisp1->dev);
+ if (ret < 0)
+ dev_err(rkisp1->dev, "power down failed error:%d\n", ret);
+
+ rkisp1_dummy_buf_destroy(cap);
+
+ media_pipeline_stop(&node->vdev.entity);
+
+ mutex_unlock(&cap->rkisp1->stream_lock);
+}
+
+static int
+rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
+{
+ struct rkisp1_capture *cap = queue->drv_priv;
+ struct media_entity *entity = &cap->vnode.vdev.entity;
+ int ret;
+
+ mutex_lock(&cap->rkisp1->stream_lock);
+
+ ret = media_pipeline_start(entity, &cap->rkisp1->pipe);
+ if (ret) {
+ dev_err(cap->rkisp1->dev, "start pipeline failed %d\n", ret);
+ goto err_ret_buffers;
+ }
+
+ ret = rkisp1_dummy_buf_create(cap);
+ if (ret)
+ goto err_pipeline_stop;
+
+ ret = pm_runtime_get_sync(cap->rkisp1->dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(cap->rkisp1->dev);
+ dev_err(cap->rkisp1->dev, "power up failed %d\n", ret);
+ goto err_destroy_dummy;
+ }
+ ret = v4l2_pipeline_pm_get(entity);
+ if (ret) {
+ dev_err(cap->rkisp1->dev, "open cif pipeline failed %d\n", ret);
+ goto err_pipe_pm_put;
+ }
+
+ ret = rkisp1_pipeline_stream_enable(cap);
+ if (ret)
+ goto err_v4l2_pm_put;
+
+ mutex_unlock(&cap->rkisp1->stream_lock);
+
+ return 0;
+
+err_v4l2_pm_put:
+ v4l2_pipeline_pm_put(entity);
+err_pipe_pm_put:
+ pm_runtime_put(cap->rkisp1->dev);
+err_destroy_dummy:
+ rkisp1_dummy_buf_destroy(cap);
+err_pipeline_stop:
+ media_pipeline_stop(entity);
+err_ret_buffers:
+ rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED);
+ mutex_unlock(&cap->rkisp1->stream_lock);
+
+ return ret;
+}
+
+static struct vb2_ops rkisp1_vb2_ops = {
+ .queue_setup = rkisp1_vb2_queue_setup,
+ .buf_queue = rkisp1_vb2_buf_queue,
+ .buf_prepare = rkisp1_vb2_buf_prepare,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .stop_streaming = rkisp1_vb2_stop_streaming,
+ .start_streaming = rkisp1_vb2_start_streaming,
+};
+
+/* ----------------------------------------------------------------------------
+ * IOCTLs operations
+ */
+
+static const struct v4l2_format_info *
+rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
+ enum rkisp1_stream_id id)
+{
+ struct v4l2_plane_pix_format *plane_y = &pixm->plane_fmt[0];
+ const struct v4l2_format_info *info;
+ unsigned int i;
+ u32 stride;
+
+ memset(pixm->plane_fmt, 0, sizeof(pixm->plane_fmt));
+ info = v4l2_format_info(pixm->pixelformat);
+ pixm->num_planes = info->mem_planes;
+ stride = info->bpp[0] * pixm->width;
+ /* Self path supports custom stride but Main path doesn't */
+ if (id == RKISP1_MAINPATH || plane_y->bytesperline < stride)
+ plane_y->bytesperline = stride;
+ plane_y->sizeimage = plane_y->bytesperline * pixm->height;
+
+ /* normalize stride to pixels per line */
+ stride = DIV_ROUND_UP(plane_y->bytesperline, info->bpp[0]);
+
+ for (i = 1; i < info->comp_planes; i++) {
+ struct v4l2_plane_pix_format *plane = &pixm->plane_fmt[i];
+
+ /* bytesperline for other components derive from Y component */
+ plane->bytesperline = DIV_ROUND_UP(stride, info->hdiv) *
+ info->bpp[i];
+ plane->sizeimage = plane->bytesperline *
+ DIV_ROUND_UP(pixm->height, info->vdiv);
+ }
+
+ /*
+ * If pixfmt is packed, then plane_fmt[0] should contain the total size
+ * considering all components. plane_fmt[i] for i > 0 should be ignored
+ * by userspace as mem_planes == 1, but we are keeping information there
+ * for convenience.
+ */
+ if (info->mem_planes == 1)
+ for (i = 1; i < info->comp_planes; i++)
+ plane_y->sizeimage += pixm->plane_fmt[i].sizeimage;
+
+ return info;
+}
+
+static const struct rkisp1_capture_fmt_cfg *
+rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
+{
+ unsigned int i;
+
+ for (i = 0; i < cap->config->fmt_size; i++) {
+ if (cap->config->fmts[i].fourcc == pixelfmt)
+ return &cap->config->fmts[i];
+ }
+ return NULL;
+}
+
+static void rkisp1_try_fmt(const struct rkisp1_capture *cap,
+ struct v4l2_pix_format_mplane *pixm,
+ const struct rkisp1_capture_fmt_cfg **fmt_cfg,
+ const struct v4l2_format_info **fmt_info)
+{
+ const struct rkisp1_capture_config *config = cap->config;
+ const struct rkisp1_capture_fmt_cfg *fmt;
+ const struct v4l2_format_info *info;
+ const unsigned int max_widths[] = { RKISP1_RSZ_MP_SRC_MAX_WIDTH,
+ RKISP1_RSZ_SP_SRC_MAX_WIDTH };
+ const unsigned int max_heights[] = { RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
+ RKISP1_RSZ_SP_SRC_MAX_HEIGHT};
+
+ fmt = rkisp1_find_fmt_cfg(cap, pixm->pixelformat);
+ if (!fmt) {
+ fmt = config->fmts;
+ pixm->pixelformat = fmt->fourcc;
+ }
+
+ pixm->width = clamp_t(u32, pixm->width,
+ RKISP1_RSZ_SRC_MIN_WIDTH, max_widths[cap->id]);
+ pixm->height = clamp_t(u32, pixm->height,
+ RKISP1_RSZ_SRC_MIN_HEIGHT, max_heights[cap->id]);
+
+ pixm->field = V4L2_FIELD_NONE;
+ pixm->colorspace = V4L2_COLORSPACE_DEFAULT;
+ pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ pixm->quantization = V4L2_QUANTIZATION_DEFAULT;
+
+ info = rkisp1_fill_pixfmt(pixm, cap->id);
+
+ if (fmt_cfg)
+ *fmt_cfg = fmt;
+ if (fmt_info)
+ *fmt_info = info;
+}
+
+static void rkisp1_set_fmt(struct rkisp1_capture *cap,
+ struct v4l2_pix_format_mplane *pixm)
+{
+ rkisp1_try_fmt(cap, pixm, &cap->pix.cfg, &cap->pix.info);
+ cap->pix.fmt = *pixm;
+
+ /* SP supports custom stride in number of pixels of the Y plane */
+ if (cap->id == RKISP1_SELFPATH)
+ cap->sp_y_stride = pixm->plane_fmt[0].bytesperline /
+ cap->pix.info->bpp[0];
+}
+
+static int rkisp1_try_fmt_vid_cap_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct rkisp1_capture *cap = video_drvdata(file);
+
+ rkisp1_try_fmt(cap, &f->fmt.pix_mp, NULL, NULL);
+
+ return 0;
+}
+
+static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct rkisp1_capture *cap = video_drvdata(file);
+ const struct rkisp1_capture_fmt_cfg *fmt = NULL;
+ unsigned int i, n = 0;
+
+ if (!f->mbus_code) {
+ if (f->index >= cap->config->fmt_size)
+ return -EINVAL;
+
+ fmt = &cap->config->fmts[f->index];
+ f->pixelformat = fmt->fourcc;
+ return 0;
+ }
+
+ for (i = 0; i < cap->config->fmt_size; i++) {
+ if (cap->config->fmts[i].mbus != f->mbus_code)
+ continue;
+
+ if (n++ == f->index) {
+ f->pixelformat = cap->config->fmts[i].fourcc;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static int rkisp1_s_fmt_vid_cap_mplane(struct file *file,
+ void *priv, struct v4l2_format *f)
+{
+ struct rkisp1_capture *cap = video_drvdata(file);
+ struct rkisp1_vdev_node *node =
+ rkisp1_vdev_to_node(&cap->vnode.vdev);
+
+ if (vb2_is_busy(&node->buf_queue))
+ return -EBUSY;
+
+ rkisp1_set_fmt(cap, &f->fmt.pix_mp);
+
+ return 0;
+}
+
+static int rkisp1_g_fmt_vid_cap_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct rkisp1_capture *cap = video_drvdata(file);
+
+ f->fmt.pix_mp = cap->pix.fmt;
+
+ return 0;
+}
+
+static int
+rkisp1_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+ struct rkisp1_capture *cap_dev = video_drvdata(file);
+ struct rkisp1_device *rkisp1 = cap_dev->rkisp1;
+
+ strscpy(cap->driver, rkisp1->dev->driver->name, sizeof(cap->driver));
+ strscpy(cap->card, rkisp1->dev->driver->name, sizeof(cap->card));
+ strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
+
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops rkisp1_v4l2_ioctl_ops = {
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_try_fmt_vid_cap_mplane = rkisp1_try_fmt_vid_cap_mplane,
+ .vidioc_s_fmt_vid_cap_mplane = rkisp1_s_fmt_vid_cap_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = rkisp1_g_fmt_vid_cap_mplane,
+ .vidioc_enum_fmt_vid_cap = rkisp1_enum_fmt_vid_cap_mplane,
+ .vidioc_querycap = rkisp1_querycap,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int rkisp1_capture_link_validate(struct media_link *link)
+{
+ struct video_device *vdev =
+ media_entity_to_video_device(link->sink->entity);
+ struct v4l2_subdev *sd =
+ media_entity_to_v4l2_subdev(link->source->entity);
+ struct rkisp1_capture *cap = video_get_drvdata(vdev);
+ const struct rkisp1_capture_fmt_cfg *fmt =
+ rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
+ struct v4l2_subdev_format sd_fmt;
+ int ret;
+
+ sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sd_fmt.pad = link->source->index;
+ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
+ if (ret)
+ return ret;
+
+ if (sd_fmt.format.height != cap->pix.fmt.height ||
+ sd_fmt.format.width != cap->pix.fmt.width ||
+ sd_fmt.format.code != fmt->mbus)
+ return -EPIPE;
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------------
+ * core functions
+ */
+
+static const struct media_entity_operations rkisp1_media_ops = {
+ .link_validate = rkisp1_capture_link_validate,
+};
+
+static const struct v4l2_file_operations rkisp1_fops = {
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .unlocked_ioctl = video_ioctl2,
+ .poll = vb2_fop_poll,
+ .mmap = vb2_fop_mmap,
+};
+
+static void rkisp1_unregister_capture(struct rkisp1_capture *cap)
+{
+ media_entity_cleanup(&cap->vnode.vdev.entity);
+ vb2_video_unregister_device(&cap->vnode.vdev);
+}
+
+void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_capture *mp = &rkisp1->capture_devs[RKISP1_MAINPATH];
+ struct rkisp1_capture *sp = &rkisp1->capture_devs[RKISP1_SELFPATH];
+
+ rkisp1_unregister_capture(mp);
+ rkisp1_unregister_capture(sp);
+}
+
+static int rkisp1_register_capture(struct rkisp1_capture *cap)
+{
+ const char * const dev_names[] = {RKISP1_MP_DEV_NAME,
+ RKISP1_SP_DEV_NAME};
+ struct v4l2_device *v4l2_dev = &cap->rkisp1->v4l2_dev;
+ struct video_device *vdev = &cap->vnode.vdev;
+ struct rkisp1_vdev_node *node;
+ struct vb2_queue *q;
+ int ret;
+
+ strscpy(vdev->name, dev_names[cap->id], sizeof(vdev->name));
+ node = rkisp1_vdev_to_node(vdev);
+ mutex_init(&node->vlock);
+
+ vdev->ioctl_ops = &rkisp1_v4l2_ioctl_ops;
+ vdev->release = video_device_release_empty;
+ vdev->fops = &rkisp1_fops;
+ vdev->minor = -1;
+ vdev->v4l2_dev = v4l2_dev;
+ vdev->lock = &node->vlock;
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+ V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
+ vdev->entity.ops = &rkisp1_media_ops;
+ video_set_drvdata(vdev, cap);
+ vdev->vfl_dir = VFL_DIR_RX;
+ node->pad.flags = MEDIA_PAD_FL_SINK;
+
+ q = &node->buf_queue;
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+ q->drv_priv = cap;
+ q->ops = &rkisp1_vb2_ops;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->buf_struct_size = sizeof(struct rkisp1_buffer);
+ q->min_buffers_needed = RKISP1_MIN_BUFFERS_NEEDED;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &node->vlock;
+ q->dev = cap->rkisp1->dev;
+ ret = vb2_queue_init(q);
+ if (ret) {
+ dev_err(cap->rkisp1->dev,
+ "vb2 queue init failed (err=%d)\n", ret);
+ return ret;
+ }
+
+ vdev->queue = q;
+
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(cap->rkisp1->dev,
+ "failed to register %s, ret=%d\n", vdev->name, ret);
+ return ret;
+ }
+ v4l2_info(v4l2_dev, "registered %s as /dev/video%d\n", vdev->name,
+ vdev->num);
+
+ ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
+ if (ret) {
+ video_unregister_device(vdev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+rkisp1_capture_init(struct rkisp1_device *rkisp1, enum rkisp1_stream_id id)
+{
+ struct rkisp1_capture *cap = &rkisp1->capture_devs[id];
+ struct v4l2_pix_format_mplane pixm;
+
+ memset(cap, 0, sizeof(*cap));
+ cap->id = id;
+ cap->rkisp1 = rkisp1;
+
+ INIT_LIST_HEAD(&cap->buf.queue);
+ init_waitqueue_head(&cap->done);
+ spin_lock_init(&cap->buf.lock);
+ if (cap->id == RKISP1_SELFPATH) {
+ cap->ops = &rkisp1_capture_ops_sp;
+ cap->config = &rkisp1_capture_config_sp;
+ } else {
+ cap->ops = &rkisp1_capture_ops_mp;
+ cap->config = &rkisp1_capture_config_mp;
+ }
+
+ cap->is_streaming = false;
+
+ memset(&pixm, 0, sizeof(pixm));
+ pixm.pixelformat = V4L2_PIX_FMT_YUYV;
+ pixm.width = RKISP1_DEFAULT_WIDTH;
+ pixm.height = RKISP1_DEFAULT_HEIGHT;
+ rkisp1_set_fmt(cap, &pixm);
+}
+
+int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_capture *cap;
+ unsigned int i, j;
+ int ret;
+
+ for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); i++) {
+ rkisp1_capture_init(rkisp1, i);
+ cap = &rkisp1->capture_devs[i];
+ cap->rkisp1 = rkisp1;
+ ret = rkisp1_register_capture(cap);
+ if (ret)
+ goto err_unreg_capture_devs;
+ }
+
+ return 0;
+
+err_unreg_capture_devs:
+ for (j = 0; j < i; j++) {
+ cap = &rkisp1->capture_devs[j];
+ rkisp1_unregister_capture(cap);
+ }
+
+ return ret;
+}
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Common definitions
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ */
+
+#include <media/v4l2-rect.h>
+
+#include "rkisp1-common.h"
+
+static const struct v4l2_rect rkisp1_sd_min_crop = {
+ .width = RKISP1_ISP_MIN_WIDTH,
+ .height = RKISP1_ISP_MIN_HEIGHT,
+ .top = 0,
+ .left = 0,
+};
+
+void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
+ const struct v4l2_rect *bounds)
+{
+ v4l2_rect_set_min_size(crop, &rkisp1_sd_min_crop);
+ v4l2_rect_map_inside(crop, bounds);
+}
+
+void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
+ const struct v4l2_mbus_framefmt *bounds)
+{
+ struct v4l2_rect crop_bounds = {
+ .left = 0,
+ .top = 0,
+ .width = bounds->width,
+ .height = bounds->height,
+ };
+
+ rkisp1_sd_adjust_crop_rect(crop, &crop_bounds);
+}
--- /dev/null
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Rockchip ISP1 Driver - Common definitions
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _RKISP1_COMMON_H
+#define _RKISP1_COMMON_H
+
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/rkisp1-config.h>
+#include <media/media-device.h>
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "rkisp1-regs.h"
+
+/*
+ * flags on the 'direction' field in struct 'rkisp1_isp_mbus_info' that indicate
+ * on which pad the media bus format is supported
+ */
+#define RKISP1_ISP_SD_SRC BIT(0)
+#define RKISP1_ISP_SD_SINK BIT(1)
+
+/* min and max values for the widths and heights of the entities */
+#define RKISP1_ISP_MAX_WIDTH 4032
+#define RKISP1_ISP_MAX_HEIGHT 3024
+#define RKISP1_ISP_MIN_WIDTH 32
+#define RKISP1_ISP_MIN_HEIGHT 32
+
+#define RKISP1_RSZ_MP_SRC_MAX_WIDTH 4416
+#define RKISP1_RSZ_MP_SRC_MAX_HEIGHT 3312
+#define RKISP1_RSZ_SP_SRC_MAX_WIDTH 1920
+#define RKISP1_RSZ_SP_SRC_MAX_HEIGHT 1920
+#define RKISP1_RSZ_SRC_MIN_WIDTH 32
+#define RKISP1_RSZ_SRC_MIN_HEIGHT 16
+
+/* the default width and height of all the entities */
+#define RKISP1_DEFAULT_WIDTH 800
+#define RKISP1_DEFAULT_HEIGHT 600
+
+#define RKISP1_DRIVER_NAME "rkisp1"
+#define RKISP1_BUS_INFO "platform:" RKISP1_DRIVER_NAME
+
+/* maximum number of clocks */
+#define RKISP1_MAX_BUS_CLK 8
+
+/* a bitmask of the ready stats */
+#define RKISP1_STATS_MEAS_MASK (RKISP1_CIF_ISP_AWB_DONE | \
+ RKISP1_CIF_ISP_AFM_FIN | \
+ RKISP1_CIF_ISP_EXP_END | \
+ RKISP1_CIF_ISP_HIST_MEASURE_RDY)
+
+/* enum for the resizer pads */
+enum rkisp1_rsz_pad {
+ RKISP1_RSZ_PAD_SINK,
+ RKISP1_RSZ_PAD_SRC,
+ RKISP1_RSZ_PAD_MAX
+};
+
+/* enum for the capture id */
+enum rkisp1_stream_id {
+ RKISP1_MAINPATH,
+ RKISP1_SELFPATH,
+};
+
+/* bayer patterns */
+enum rkisp1_fmt_raw_pat_type {
+ RKISP1_RAW_RGGB = 0,
+ RKISP1_RAW_GRBG,
+ RKISP1_RAW_GBRG,
+ RKISP1_RAW_BGGR,
+};
+
+/* enum for the isp pads */
+enum rkisp1_isp_pad {
+ RKISP1_ISP_PAD_SINK_VIDEO,
+ RKISP1_ISP_PAD_SINK_PARAMS,
+ RKISP1_ISP_PAD_SOURCE_VIDEO,
+ RKISP1_ISP_PAD_SOURCE_STATS,
+ RKISP1_ISP_PAD_MAX
+};
+
+/*
+ * struct rkisp1_sensor_async - A container for the v4l2_async_subdev to add to the notifier
+ * of the v4l2-async API
+ *
+ * @asd: async_subdev variable for the sensor
+ * @lanes: number of lanes
+ * @mbus_type: type of bus (currently only CSI2 is supported)
+ * @mbus_flags: media bus (V4L2_MBUS_*) flags
+ * @sd: a pointer to v4l2_subdev struct of the sensor
+ * @pixel_rate_ctrl: pixel rate of the sensor, used to initialize the phy
+ * @dphy: a pointer to the phy
+ */
+struct rkisp1_sensor_async {
+ struct v4l2_async_subdev asd;
+ unsigned int lanes;
+ enum v4l2_mbus_type mbus_type;
+ unsigned int mbus_flags;
+ struct v4l2_subdev *sd;
+ struct v4l2_ctrl *pixel_rate_ctrl;
+ struct phy *dphy;
+};
+
+/*
+ * struct rkisp1_isp - ISP subdev entity
+ *
+ * @sd: v4l2_subdev variable
+ * @rkisp1: pointer to rkisp1_device
+ * @pads: media pads
+ * @pad_cfg: pads configurations
+ * @sink_fmt: input format
+ * @src_fmt: output format
+ * @ops_lock: ops serialization
+ * @is_dphy_errctrl_disabled: if dphy errctrl is disabled (avoid endless interrupt)
+ * @frame_sequence: used to synchronize frame_id between video devices.
+ */
+struct rkisp1_isp {
+ struct v4l2_subdev sd;
+ struct media_pad pads[RKISP1_ISP_PAD_MAX];
+ struct v4l2_subdev_pad_config pad_cfg[RKISP1_ISP_PAD_MAX];
+ const struct rkisp1_isp_mbus_info *sink_fmt;
+ const struct rkisp1_isp_mbus_info *src_fmt;
+ struct mutex ops_lock; /* serialize the subdevice ops */
+ bool is_dphy_errctrl_disabled;
+ __u32 frame_sequence;
+};
+
+/*
+ * struct rkisp1_vdev_node - Container for the video nodes: params, stats, mainpath, selfpath
+ *
+ * @buf_queue: queue of buffers
+ * @vlock: lock of the video node
+ * @vdev: video node
+ * @pad: media pad
+ */
+struct rkisp1_vdev_node {
+ struct vb2_queue buf_queue;
+ struct mutex vlock; /* ioctl serialization mutex */
+ struct video_device vdev;
+ struct media_pad pad;
+};
+
+/*
+ * struct rkisp1_buffer - A container for the vb2 buffers used by the video devices:
+ * params, stats, mainpath, selfpath
+ *
+ * @vb: vb2 buffer
+ * @queue: entry of the buffer in the queue
+ * @buff_addr: dma addresses of each plane, used only by the capture devices: selfpath, mainpath
+ * @vaddr: virtual address for buffers used by params and stats devices
+ */
+struct rkisp1_buffer {
+ struct vb2_v4l2_buffer vb;
+ struct list_head queue;
+ union {
+ u32 buff_addr[VIDEO_MAX_PLANES];
+ void *vaddr;
+ };
+};
+
+/*
+ * struct rkisp1_dummy_buffer - A buffer to write the next frame to in case
+ * there are no vb2 buffers available.
+ *
+ * @vaddr: return value of call to dma_alloc_attrs.
+ * @dma_addr: dma address of the buffer.
+ * @size: size of the buffer.
+ */
+struct rkisp1_dummy_buffer {
+ void *vaddr;
+ dma_addr_t dma_addr;
+ u32 size;
+};
+
+struct rkisp1_device;
+
+/*
+ * struct rkisp1_capture - ISP capture video device
+ *
+ * @vnode: video node
+ * @rkisp1: pointer to rkisp1_device
+ * @id: id of the capture, one of RKISP1_SELFPATH, RKISP1_MAINPATH
+ * @ops: list of callbacks to configure the capture device.
+ * @config: a pointer to the list of registers to configure the capture format.
+ * @is_streaming: device is streaming
+ * @is_stopping: stop_streaming callback was called and the device is in the process of
+ * stopping the streaming.
+ * @done: when stop_streaming callback is called, the device waits for the next irq
+ * handler to stop the streaming by waiting on the 'done' wait queue.
+ * If the irq handler is not called, the stream is stopped by the callback
+ * after timeout.
+ * @sp_y_stride: the selfpath allows to configure a y stride that is longer than the image width.
+ * @buf.lock: lock to protect buf.queue
+ * @buf.queue: queued buffer list
+ * @buf.dummy: dummy space to store dropped data
+ *
+ * rkisp1 uses shadow registers, so it needs two buffers at a time
+ * @buf.curr: the buffer used for current frame
+ * @buf.next: the buffer used for next frame
+ * @pix.cfg: pixel configuration
+ * @pix.info: a pointer to the v4l2_format_info of the pixel format
+ * @pix.fmt: buffer format
+ */
+struct rkisp1_capture {
+ struct rkisp1_vdev_node vnode;
+ struct rkisp1_device *rkisp1;
+ enum rkisp1_stream_id id;
+ struct rkisp1_capture_ops *ops;
+ const struct rkisp1_capture_config *config;
+ bool is_streaming;
+ bool is_stopping;
+ wait_queue_head_t done;
+ unsigned int sp_y_stride;
+ struct {
+ /* protects queue, curr and next */
+ spinlock_t lock;
+ struct list_head queue;
+ struct rkisp1_dummy_buffer dummy;
+ struct rkisp1_buffer *curr;
+ struct rkisp1_buffer *next;
+ } buf;
+ struct {
+ const struct rkisp1_capture_fmt_cfg *cfg;
+ const struct v4l2_format_info *info;
+ struct v4l2_pix_format_mplane fmt;
+ } pix;
+};
+
+/*
+ * struct rkisp1_stats - ISP Statistics device
+ *
+ * @vnode: video node
+ * @rkisp1: pointer to the rkisp1 device
+ * @lock: locks the buffer list 'stat'
+ * @stat: queue of rkisp1_buffer
+ * @vdev_fmt: v4l2_format of the metadata format
+ */
+struct rkisp1_stats {
+ struct rkisp1_vdev_node vnode;
+ struct rkisp1_device *rkisp1;
+
+ spinlock_t lock; /* locks the buffers list 'stats' */
+ struct list_head stat;
+ struct v4l2_format vdev_fmt;
+};
+
+/*
+ * struct rkisp1_params - ISP input parameters device
+ *
+ * @vnode: video node
+ * @rkisp1: pointer to the rkisp1 device
+ * @config_lock: locks the buffer list 'params'
+ * @params: queue of rkisp1_buffer
+ * @vdev_fmt: v4l2_format of the metadata format
+ * @quantization: the quantization configured on the isp's src pad
+ * @raw_type: the bayer pattern on the isp video sink pad
+ */
+struct rkisp1_params {
+ struct rkisp1_vdev_node vnode;
+ struct rkisp1_device *rkisp1;
+
+ spinlock_t config_lock; /* locks the buffers list 'params' */
+ struct list_head params;
+ struct v4l2_format vdev_fmt;
+
+ enum v4l2_quantization quantization;
+ enum rkisp1_fmt_raw_pat_type raw_type;
+};
+
+/*
+ * struct rkisp1_resizer - Resizer subdev
+ *
+ * @sd: v4l2_subdev variable
+ * @id: id of the resizer, one of RKISP1_SELFPATH, RKISP1_MAINPATH
+ * @rkisp1: pointer to the rkisp1 device
+ * @pads: media pads
+ * @pad_cfg: configurations for the pads
+ * @config: the set of registers to configure the resizer
+ * @pixel_enc: pixel encoding of the resizer
+ * @ops_lock: a lock for the subdev ops
+ */
+struct rkisp1_resizer {
+ struct v4l2_subdev sd;
+ enum rkisp1_stream_id id;
+ struct rkisp1_device *rkisp1;
+ struct media_pad pads[RKISP1_RSZ_PAD_MAX];
+ struct v4l2_subdev_pad_config pad_cfg[RKISP1_RSZ_PAD_MAX];
+ const struct rkisp1_rsz_config *config;
+ enum v4l2_pixel_encoding pixel_enc;
+ struct mutex ops_lock; /* serialize the subdevice ops */
+};
+
+/*
+ * struct rkisp1_debug - Values to be exposed on debugfs.
+ * The parameters are counters of the number of times the
+ * event occurred since the driver was loaded.
+ *
+ * @data_loss: loss of data occurred within a line, processing failure
+ * @outform_size_error: size error is generated in outmux submodule
+ * @img_stabilization_size_error: size error is generated in image stabilization submodule
+ * @inform_size_err: size error is generated in inform submodule
+ * @mipi_error: mipi error occurred
+ * @stats_error: writing to the 'Interrupt clear register' did not clear
+ * it in the register 'Masked interrupt status'
+ * @stop_timeout: upon stream stop, the capture waits 1 second for the isr to stop
+ * the stream. This param is incremented in case of timeout.
+ * @frame_drop: a frame was ready but the buffer queue was empty so the frame
+ * was not sent to userspace
+ */
+struct rkisp1_debug {
+ struct dentry *debugfs_dir;
+ unsigned long data_loss;
+ unsigned long outform_size_error;
+ unsigned long img_stabilization_size_error;
+ unsigned long inform_size_error;
+ unsigned long irq_delay;
+ unsigned long mipi_error;
+ unsigned long stats_error;
+ unsigned long stop_timeout[2];
+ unsigned long frame_drop[2];
+};
+
+/*
+ * struct rkisp1_device - ISP platform device
+ *
+ * @base_addr: base register address
+ * @irq: the irq number
+ * @dev: a pointer to the struct device
+ * @clk_size: number of clocks
+ * @clks: array of clocks
+ * @v4l2_dev: v4l2_device variable
+ * @media_dev: media_device variable
+ * @notifier: a notifier to register on the v4l2-async API to be notified on the sensor
+ * @active_sensor: sensor in-use, set when streaming on
+ * @isp: ISP sub-device
+ * @resizer_devs: resizer sub-devices
+ * @capture_devs: capture devices
+ * @stats: ISP statistics metadata capture device
+ * @params: ISP parameters metadata output device
+ * @pipe: media pipeline
+ * @stream_lock: serializes {start/stop}_streaming callbacks between the capture devices.
+ * @debug: debug params to be exposed on debugfs
+ */
+struct rkisp1_device {
+ void __iomem *base_addr;
+ int irq;
+ struct device *dev;
+ unsigned int clk_size;
+ struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
+ struct v4l2_device v4l2_dev;
+ struct media_device media_dev;
+ struct v4l2_async_notifier notifier;
+ struct rkisp1_sensor_async *active_sensor;
+ struct rkisp1_isp isp;
+ struct rkisp1_resizer resizer_devs[2];
+ struct rkisp1_capture capture_devs[2];
+ struct rkisp1_stats stats;
+ struct rkisp1_params params;
+ struct media_pipeline pipe;
+ struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */
+ struct rkisp1_debug debug;
+};
+
+/*
+ * struct rkisp1_isp_mbus_info - ISP media bus info, Translates media bus code to hardware
+ * format values
+ *
+ * @mbus_code: media bus code
+ * @pixel_enc: pixel encoding
+ * @mipi_dt: mipi data type
+ * @yuv_seq: the order of the Y, Cb, Cr values
+ * @bus_width: bus width
+ * @bayer_pat: bayer pattern
+ * @direction: a bitmask of the flags indicating on which pad the format is supported on
+ */
+struct rkisp1_isp_mbus_info {
+ u32 mbus_code;
+ enum v4l2_pixel_encoding pixel_enc;
+ u32 mipi_dt;
+ u32 yuv_seq;
+ u8 bus_width;
+ enum rkisp1_fmt_raw_pat_type bayer_pat;
+ unsigned int direction;
+};
+
+static inline void
+rkisp1_write(struct rkisp1_device *rkisp1, u32 val, unsigned int addr)
+{
+ writel(val, rkisp1->base_addr + addr);
+}
+
+static inline u32 rkisp1_read(struct rkisp1_device *rkisp1, unsigned int addr)
+{
+ return readl(rkisp1->base_addr + addr);
+}
+
+/*
+ * rkisp1_cap_enum_mbus_codes - A helper function that return the i'th supported mbus code
+ * of the capture entity. This is used to enumerate the supported
+ * mbus codes on the source pad of the resizer.
+ *
+ * @cap: the capture entity
+ * @code: the mbus code, the function reads the code->index and fills the code->code
+ */
+int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
+ struct v4l2_subdev_mbus_code_enum *code);
+
+/*
+ * rkisp1_sd_adjust_crop_rect - adjust a rectangle to fit into another rectangle.
+ *
+ * @crop: rectangle to adjust.
+ * @bounds: rectangle used as bounds.
+ */
+void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
+ const struct v4l2_rect *bounds);
+
+/*
+ * rkisp1_sd_adjust_crop - adjust a rectangle to fit into media bus format
+ *
+ * @crop: rectangle to adjust.
+ * @bounds: media bus format used as bounds.
+ */
+void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
+ const struct v4l2_mbus_framefmt *bounds);
+
+/*
+ * rkisp1_isp_mbus_info - get the isp info of the media bus code
+ *
+ * @mbus_code: the media bus code
+ */
+const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code);
+
+/* rkisp1_params_configure - configure the params when stream starts.
+ * This function is called by the isp entity upon stream starts.
+ * The function applies the initial configuration of the parameters.
+ *
+ * @params: pointer to rkisp1_params.
+ * @bayer_pat: the bayer pattern on the isp video sink pad
+ * @quantization: the quantization configured on the isp's src pad
+ */
+void rkisp1_params_configure(struct rkisp1_params *params,
+ enum rkisp1_fmt_raw_pat_type bayer_pat,
+ enum v4l2_quantization quantization);
+
+/* rkisp1_params_disable - disable all parameters.
+ * This function is called by the isp entity upon stream start
+ * when capturing bayer format.
+ *
+ * @params: pointer to rkisp1_params.
+ */
+void rkisp1_params_disable(struct rkisp1_params *params);
+
+/* irq handlers */
+void rkisp1_isp_isr(struct rkisp1_device *rkisp1);
+void rkisp1_mipi_isr(struct rkisp1_device *rkisp1);
+void rkisp1_capture_isr(struct rkisp1_device *rkisp1);
+void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
+void rkisp1_params_isr(struct rkisp1_device *rkisp1);
+
+/* register/unregisters functions of the entities */
+int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1);
+void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_isp_register(struct rkisp1_device *rkisp1);
+void rkisp1_isp_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1);
+void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_stats_register(struct rkisp1_device *rkisp1);
+void rkisp1_stats_unregister(struct rkisp1_device *rkisp1);
+
+int rkisp1_params_register(struct rkisp1_device *rkisp1);
+void rkisp1_params_unregister(struct rkisp1_device *rkisp1);
+
+#endif /* _RKISP1_COMMON_H */
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Base driver
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mipi-dphy.h>
+#include <media/v4l2-fwnode.h>
+
+#include "rkisp1-common.h"
+
+/*
+ * ISP Details
+ * -----------
+ *
+ * ISP Comprises with:
+ * MIPI serial camera interface
+ * Image Signal Processing
+ * Many Image Enhancement Blocks
+ * Crop
+ * Resizer
+ * RBG display ready image
+ * Image Rotation
+ *
+ * ISP Block Diagram
+ * -----------------
+ * rkisp1-resizer.c rkisp1-capture.c
+ * |====================| |=======================|
+ * rkisp1-isp.c Main Picture Path
+ * |==========================| |===============================================|
+ * +-----------+ +--+--+--+--+ +--------+ +--------+ +-----------+
+ * | | | | | | | | | | | | |
+ * +--------+ |\ | | | | | | | -->| Crop |->| RSZ |------------->| |
+ * | MIPI |--->| \ | | | | | | | | | | | | | |
+ * +--------+ | | | | |IE|IE|IE|IE| | +--------+ +--------+ | Memory |
+ * |MUX|--->| ISP |->|0 |1 |2 |3 |---+ | Interface |
+ * +--------+ | | | | | | | | | | +--------+ +--------+ +--------+ | |
+ * |Parallel|--->| / | | | | | | | | | | | | | | | |
+ * +--------+ |/ | | | | | | | -->| Crop |->| RSZ |->| RGB |->| |
+ * | | | | | | | | | | | | Rotate | | |
+ * +-----------+ +--+--+--+--+ +--------+ +--------+ +--------+ +-----------+
+ * ^
+ * +--------+ | |===============================================|
+ * | DMA |------------------------------------+ Self Picture Path
+ * +--------+
+ *
+ * rkisp1-stats.c rkisp1-params.c
+ * |===============| |===============|
+ * +---------------+ +---------------+
+ * | | | |
+ * | ISP | | ISP |
+ * | | | |
+ * +---------------+ +---------------+
+ *
+ *
+ * Media Topology
+ * --------------
+ * +----------+ +----------+
+ * | Sensor 2 | | Sensor X |
+ * ------------ ... ------------
+ * | 0 | | 0 |
+ * +----------+ +----------+ +-----------+
+ * \ | | params |
+ * \ | | (output) |
+ * +----------+ \ | +-----------+
+ * | Sensor 1 | v v |
+ * ------------ +------+------+ |
+ * | 0 |----->| 0 | 1 |<---------+
+ * +----------+ |------+------|
+ * | ISP |
+ * |------+------|
+ * +-------------| 2 | 3 |----------+
+ * | +------+------+ |
+ * | | |
+ * v v v
+ * +- ---------+ +-----------+ +-----------+
+ * | 0 | | 0 | | stats |
+ * ------------- ------------- | (capture) |
+ * | Resizer | | Resizer | +-----------+
+ * ------------| ------------|
+ * | 1 | | 1 |
+ * +-----------+ +-----------+
+ * | |
+ * v v
+ * +-----------+ +-----------+
+ * | selfpath | | mainpath |
+ * | (capture) | | (capture) |
+ * +-----------+ +-----------+
+ */
+
+struct rkisp1_match_data {
+ const char * const *clks;
+ unsigned int size;
+};
+
+/* ----------------------------------------------------------------------------
+ * Sensor DT bindings
+ */
+
+static int rkisp1_create_links(struct rkisp1_device *rkisp1)
+{
+ struct media_entity *source, *sink;
+ unsigned int flags, source_pad;
+ struct v4l2_subdev *sd;
+ unsigned int i;
+ int ret;
+
+ /* sensor links */
+ flags = MEDIA_LNK_FL_ENABLED;
+ list_for_each_entry(sd, &rkisp1->v4l2_dev.subdevs, list) {
+ if (sd == &rkisp1->isp.sd ||
+ sd == &rkisp1->resizer_devs[RKISP1_MAINPATH].sd ||
+ sd == &rkisp1->resizer_devs[RKISP1_SELFPATH].sd)
+ continue;
+
+ ret = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
+ MEDIA_PAD_FL_SOURCE);
+ if (ret < 0) {
+ dev_err(rkisp1->dev, "failed to find src pad for %s\n",
+ sd->name);
+ return ret;
+ }
+ source_pad = ret;
+
+ ret = media_create_pad_link(&sd->entity, source_pad,
+ &rkisp1->isp.sd.entity,
+ RKISP1_ISP_PAD_SINK_VIDEO,
+ flags);
+ if (ret)
+ return ret;
+
+ flags = 0;
+ }
+
+ flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
+
+ /* create ISP->RSZ->CAP links */
+ for (i = 0; i < 2; i++) {
+ source = &rkisp1->isp.sd.entity;
+ sink = &rkisp1->resizer_devs[i].sd.entity;
+ ret = media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_VIDEO,
+ sink, RKISP1_RSZ_PAD_SINK,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
+
+ source = sink;
+ sink = &rkisp1->capture_devs[i].vnode.vdev.entity;
+ ret = media_create_pad_link(source, RKISP1_RSZ_PAD_SRC,
+ sink, 0, flags);
+ if (ret)
+ return ret;
+ }
+
+ /* params links */
+ source = &rkisp1->params.vnode.vdev.entity;
+ sink = &rkisp1->isp.sd.entity;
+ ret = media_create_pad_link(source, 0, sink,
+ RKISP1_ISP_PAD_SINK_PARAMS, flags);
+ if (ret)
+ return ret;
+
+ /* 3A stats links */
+ source = &rkisp1->isp.sd.entity;
+ sink = &rkisp1->stats.vnode.vdev.entity;
+ return media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_STATS,
+ sink, 0, flags);
+}
+
+static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct rkisp1_device *rkisp1 =
+ container_of(notifier, struct rkisp1_device, notifier);
+ struct rkisp1_sensor_async *s_asd =
+ container_of(asd, struct rkisp1_sensor_async, asd);
+
+ s_asd->pixel_rate_ctrl = v4l2_ctrl_find(sd->ctrl_handler,
+ V4L2_CID_PIXEL_RATE);
+ s_asd->sd = sd;
+ s_asd->dphy = devm_phy_get(rkisp1->dev, "dphy");
+ if (IS_ERR(s_asd->dphy)) {
+ if (PTR_ERR(s_asd->dphy) != -EPROBE_DEFER)
+ dev_err(rkisp1->dev, "Couldn't get the MIPI D-PHY\n");
+ return PTR_ERR(s_asd->dphy);
+ }
+
+ phy_init(s_asd->dphy);
+
+ return 0;
+}
+
+static void rkisp1_subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct rkisp1_sensor_async *s_asd =
+ container_of(asd, struct rkisp1_sensor_async, asd);
+
+ phy_exit(s_asd->dphy);
+}
+
+static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+ struct rkisp1_device *rkisp1 =
+ container_of(notifier, struct rkisp1_device, notifier);
+ int ret;
+
+ ret = rkisp1_create_links(rkisp1);
+ if (ret)
+ return ret;
+
+ ret = v4l2_device_register_subdev_nodes(&rkisp1->v4l2_dev);
+ if (ret)
+ return ret;
+
+ dev_dbg(rkisp1->dev, "Async subdev notifier completed\n");
+
+ return 0;
+}
+
+static const struct v4l2_async_notifier_operations rkisp1_subdev_notifier_ops = {
+ .bound = rkisp1_subdev_notifier_bound,
+ .unbind = rkisp1_subdev_notifier_unbind,
+ .complete = rkisp1_subdev_notifier_complete,
+};
+
+static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
+{
+ struct v4l2_async_notifier *ntf = &rkisp1->notifier;
+ unsigned int next_id = 0;
+ int ret;
+
+ v4l2_async_notifier_init(ntf);
+
+ while (1) {
+ struct v4l2_fwnode_endpoint vep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ struct rkisp1_sensor_async *rk_asd = NULL;
+ struct fwnode_handle *ep;
+
+ ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(rkisp1->dev),
+ 0, next_id,
+ FWNODE_GRAPH_ENDPOINT_NEXT);
+ if (!ep)
+ break;
+
+ ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+ if (ret)
+ goto err_parse;
+
+ rk_asd = kzalloc(sizeof(*rk_asd), GFP_KERNEL);
+ if (!rk_asd) {
+ ret = -ENOMEM;
+ goto err_parse;
+ }
+
+ rk_asd->mbus_type = vep.bus_type;
+ rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
+ rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
+
+ ret = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
+ &rk_asd->asd);
+ if (ret)
+ goto err_parse;
+
+ dev_dbg(rkisp1->dev, "registered ep id %d with %d lanes\n",
+ vep.base.id, rk_asd->lanes);
+
+ next_id = vep.base.id + 1;
+
+ fwnode_handle_put(ep);
+
+ continue;
+err_parse:
+ fwnode_handle_put(ep);
+ kfree(rk_asd);
+ v4l2_async_notifier_cleanup(ntf);
+ return ret;
+ }
+
+ if (next_id == 0)
+ dev_dbg(rkisp1->dev, "no remote subdevice found\n");
+ ntf->ops = &rkisp1_subdev_notifier_ops;
+ ret = v4l2_async_notifier_register(&rkisp1->v4l2_dev, ntf);
+ if (ret) {
+ v4l2_async_notifier_cleanup(ntf);
+ return ret;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------------------
+ * Power
+ */
+
+static int __maybe_unused rkisp1_runtime_suspend(struct device *dev)
+{
+ struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+
+ clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks);
+ return pinctrl_pm_select_sleep_state(dev);
+}
+
+static int __maybe_unused rkisp1_runtime_resume(struct device *dev)
+{
+ struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = pinctrl_pm_select_default_state(dev);
+ if (ret)
+ return ret;
+ ret = clk_bulk_prepare_enable(rkisp1->clk_size, rkisp1->clks);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct dev_pm_ops rkisp1_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(rkisp1_runtime_suspend, rkisp1_runtime_resume, NULL)
+};
+
+/* ----------------------------------------------------------------------------
+ * Core
+ */
+
+static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
+{
+ int ret;
+
+ ret = rkisp1_isp_register(rkisp1);
+ if (ret)
+ return ret;
+
+ ret = rkisp1_resizer_devs_register(rkisp1);
+ if (ret)
+ goto err_unreg_isp_subdev;
+
+ ret = rkisp1_capture_devs_register(rkisp1);
+ if (ret)
+ goto err_unreg_resizer_devs;
+
+ ret = rkisp1_stats_register(rkisp1);
+ if (ret)
+ goto err_unreg_capture_devs;
+
+ ret = rkisp1_params_register(rkisp1);
+ if (ret)
+ goto err_unreg_stats;
+
+ ret = rkisp1_subdev_notifier(rkisp1);
+ if (ret) {
+ dev_err(rkisp1->dev,
+ "Failed to register subdev notifier(%d)\n", ret);
+ goto err_unreg_params;
+ }
+
+ return 0;
+err_unreg_params:
+ rkisp1_params_unregister(rkisp1);
+err_unreg_stats:
+ rkisp1_stats_unregister(rkisp1);
+err_unreg_capture_devs:
+ rkisp1_capture_devs_unregister(rkisp1);
+err_unreg_resizer_devs:
+ rkisp1_resizer_devs_unregister(rkisp1);
+err_unreg_isp_subdev:
+ rkisp1_isp_unregister(rkisp1);
+ return ret;
+}
+
+static irqreturn_t rkisp1_isr(int irq, void *ctx)
+{
+ struct device *dev = ctx;
+ struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+
+ /*
+ * Call rkisp1_capture_isr() first to handle the frame that
+ * potentially completed using the current frame_sequence number before
+ * it is potentially incremented by rkisp1_isp_isr() in the vertical
+ * sync.
+ */
+ rkisp1_capture_isr(rkisp1);
+ rkisp1_isp_isr(rkisp1);
+ rkisp1_mipi_isr(rkisp1);
+
+ return IRQ_HANDLED;
+}
+
+static const char * const rk3399_isp_clks[] = {
+ "isp",
+ "aclk",
+ "hclk",
+};
+
+static const struct rkisp1_match_data rk3399_isp_clk_data = {
+ .clks = rk3399_isp_clks,
+ .size = ARRAY_SIZE(rk3399_isp_clks),
+};
+
+static const struct of_device_id rkisp1_of_match[] = {
+ {
+ .compatible = "rockchip,rk3399-cif-isp",
+ .data = &rk3399_isp_clk_data,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rkisp1_of_match);
+
+static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_debug *debug = &rkisp1->debug;
+
+ debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL);
+ if (!debug->debugfs_dir) {
+ dev_dbg(rkisp1->dev, "failed to create debugfs directory\n");
+ return;
+ }
+ debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
+ &debug->data_loss);
+ debugfs_create_ulong("outform_size_err", 0444, debug->debugfs_dir,
+ &debug->outform_size_error);
+ debugfs_create_ulong("img_stabilization_size_error", 0444,
+ debug->debugfs_dir,
+ &debug->img_stabilization_size_error);
+ debugfs_create_ulong("inform_size_error", 0444, debug->debugfs_dir,
+ &debug->inform_size_error);
+ debugfs_create_ulong("irq_delay", 0444, debug->debugfs_dir,
+ &debug->irq_delay);
+ debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir,
+ &debug->mipi_error);
+ debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir,
+ &debug->stats_error);
+ debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir,
+ &debug->stop_timeout[RKISP1_MAINPATH]);
+ debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir,
+ &debug->stop_timeout[RKISP1_SELFPATH]);
+ debugfs_create_ulong("mp_frame_drop", 0444, debug->debugfs_dir,
+ &debug->frame_drop[RKISP1_MAINPATH]);
+ debugfs_create_ulong("sp_frame_drop", 0444, debug->debugfs_dir,
+ &debug->frame_drop[RKISP1_SELFPATH]);
+}
+
+static int rkisp1_probe(struct platform_device *pdev)
+{
+ const struct rkisp1_match_data *clk_data;
+ struct device *dev = &pdev->dev;
+ struct rkisp1_device *rkisp1;
+ struct v4l2_device *v4l2_dev;
+ unsigned int i;
+ int ret, irq;
+
+ clk_data = of_device_get_match_data(&pdev->dev);
+ if (!clk_data)
+ return -ENODEV;
+
+ rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL);
+ if (!rkisp1)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, rkisp1);
+ rkisp1->dev = dev;
+
+ mutex_init(&rkisp1->stream_lock);
+
+ rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rkisp1->base_addr))
+ return PTR_ERR(rkisp1->base_addr);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ ret = devm_request_irq(dev, irq, rkisp1_isr, IRQF_SHARED,
+ dev_driver_string(dev), dev);
+ if (ret) {
+ dev_err(dev, "request irq failed: %d\n", ret);
+ return ret;
+ }
+
+ rkisp1->irq = irq;
+
+ for (i = 0; i < clk_data->size; i++)
+ rkisp1->clks[i].id = clk_data->clks[i];
+ ret = devm_clk_bulk_get(dev, clk_data->size, rkisp1->clks);
+ if (ret)
+ return ret;
+ rkisp1->clk_size = clk_data->size;
+
+ pm_runtime_enable(&pdev->dev);
+
+ strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME,
+ sizeof(rkisp1->media_dev.model));
+ rkisp1->media_dev.dev = &pdev->dev;
+ strscpy(rkisp1->media_dev.bus_info, RKISP1_BUS_INFO,
+ sizeof(rkisp1->media_dev.bus_info));
+ media_device_init(&rkisp1->media_dev);
+
+ v4l2_dev = &rkisp1->v4l2_dev;
+ v4l2_dev->mdev = &rkisp1->media_dev;
+ strscpy(v4l2_dev->name, RKISP1_DRIVER_NAME, sizeof(v4l2_dev->name));
+
+ ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev);
+ if (ret)
+ return ret;
+
+ ret = media_device_register(&rkisp1->media_dev);
+ if (ret) {
+ dev_err(dev, "Failed to register media device: %d\n", ret);
+ goto err_unreg_v4l2_dev;
+ }
+
+ ret = rkisp1_entities_register(rkisp1);
+ if (ret)
+ goto err_unreg_media_dev;
+
+ rkisp1_debug_init(rkisp1);
+
+ return 0;
+
+err_unreg_media_dev:
+ media_device_unregister(&rkisp1->media_dev);
+err_unreg_v4l2_dev:
+ v4l2_device_unregister(&rkisp1->v4l2_dev);
+ pm_runtime_disable(&pdev->dev);
+ return ret;
+}
+
+static int rkisp1_remove(struct platform_device *pdev)
+{
+ struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev);
+
+ v4l2_async_notifier_unregister(&rkisp1->notifier);
+ v4l2_async_notifier_cleanup(&rkisp1->notifier);
+
+ rkisp1_params_unregister(rkisp1);
+ rkisp1_stats_unregister(rkisp1);
+ rkisp1_capture_devs_unregister(rkisp1);
+ rkisp1_resizer_devs_unregister(rkisp1);
+ rkisp1_isp_unregister(rkisp1);
+
+ media_device_unregister(&rkisp1->media_dev);
+ v4l2_device_unregister(&rkisp1->v4l2_dev);
+
+ pm_runtime_disable(&pdev->dev);
+
+ debugfs_remove_recursive(rkisp1->debug.debugfs_dir);
+ return 0;
+}
+
+static struct platform_driver rkisp1_drv = {
+ .driver = {
+ .name = RKISP1_DRIVER_NAME,
+ .of_match_table = of_match_ptr(rkisp1_of_match),
+ .pm = &rkisp1_pm_ops,
+ },
+ .probe = rkisp1_probe,
+ .remove = rkisp1_remove,
+};
+
+module_platform_driver(rkisp1_drv);
+MODULE_DESCRIPTION("Rockchip ISP1 platform driver");
+MODULE_LICENSE("Dual MIT/GPL");
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - ISP Subdevice
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <linux/iopoll.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mipi-dphy.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-event.h>
+
+#include "rkisp1-common.h"
+
+#define RKISP1_DEF_SINK_PAD_FMT MEDIA_BUS_FMT_SRGGB10_1X10
+#define RKISP1_DEF_SRC_PAD_FMT MEDIA_BUS_FMT_YUYV8_2X8
+
+#define RKISP1_ISP_DEV_NAME RKISP1_DRIVER_NAME "_isp"
+
+/*
+ * NOTE: MIPI controller and input MUX are also configured in this file.
+ * This is because ISP Subdev describes not only ISP submodule (input size,
+ * format, output size, format), but also a virtual route device.
+ */
+
+/*
+ * There are many variables named with format/frame in below code,
+ * please see here for their meaning.
+ * Cropping in the sink pad defines the image region from the sensor.
+ * Cropping in the source pad defines the region for the Image Stabilizer (IS)
+ *
+ * Cropping regions of ISP
+ *
+ * +---------------------------------------------------------+
+ * | Sensor image |
+ * | +---------------------------------------------------+ |
+ * | | CIF_ISP_ACQ (for black level) | |
+ * | | sink pad format | |
+ * | | +--------------------------------------------+ | |
+ * | | | CIF_ISP_OUT | | |
+ * | | | sink pad crop | | |
+ * | | | +---------------------------------+ | | |
+ * | | | | CIF_ISP_IS | | | |
+ * | | | | source pad crop and format | | | |
+ * | | | +---------------------------------+ | | |
+ * | | +--------------------------------------------+ | |
+ * | +---------------------------------------------------+ |
+ * +---------------------------------------------------------+
+ */
+
+static const struct rkisp1_isp_mbus_info rkisp1_isp_formats[] = {
+ {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .pixel_enc = V4L2_PIXEL_ENC_YUV,
+ .direction = RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
+ .bayer_pat = RKISP1_RAW_RGGB,
+ .bus_width = 10,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
+ .bayer_pat = RKISP1_RAW_BGGR,
+ .bus_width = 10,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
+ .bayer_pat = RKISP1_RAW_GBRG,
+ .bus_width = 10,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
+ .bayer_pat = RKISP1_RAW_GRBG,
+ .bus_width = 10,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
+ .bayer_pat = RKISP1_RAW_RGGB,
+ .bus_width = 12,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
+ .bayer_pat = RKISP1_RAW_BGGR,
+ .bus_width = 12,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
+ .bayer_pat = RKISP1_RAW_GBRG,
+ .bus_width = 12,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
+ .bayer_pat = RKISP1_RAW_GRBG,
+ .bus_width = 12,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
+ .bayer_pat = RKISP1_RAW_RGGB,
+ .bus_width = 8,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
+ .bayer_pat = RKISP1_RAW_BGGR,
+ .bus_width = 8,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
+ .bayer_pat = RKISP1_RAW_GBRG,
+ .bus_width = 8,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+ .pixel_enc = V4L2_PIXEL_ENC_BAYER,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
+ .bayer_pat = RKISP1_RAW_GRBG,
+ .bus_width = 8,
+ .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+ .pixel_enc = V4L2_PIXEL_ENC_YUV,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
+ .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_YCBYCR,
+ .bus_width = 16,
+ .direction = RKISP1_ISP_SD_SINK,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
+ .pixel_enc = V4L2_PIXEL_ENC_YUV,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
+ .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_YCRYCB,
+ .bus_width = 16,
+ .direction = RKISP1_ISP_SD_SINK,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .pixel_enc = V4L2_PIXEL_ENC_YUV,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
+ .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_CBYCRY,
+ .bus_width = 16,
+ .direction = RKISP1_ISP_SD_SINK,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
+ .pixel_enc = V4L2_PIXEL_ENC_YUV,
+ .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
+ .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_CRYCBY,
+ .bus_width = 16,
+ .direction = RKISP1_ISP_SD_SINK,
+ },
+};
+
+/* ----------------------------------------------------------------------------
+ * Helpers
+ */
+
+const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
+ const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
+
+ if (fmt->mbus_code == mbus_code)
+ return fmt;
+ }
+
+ return NULL;
+}
+
+static struct v4l2_subdev *rkisp1_get_remote_sensor(struct v4l2_subdev *sd)
+{
+ struct media_pad *local, *remote;
+ struct media_entity *sensor_me;
+
+ local = &sd->entity.pads[RKISP1_ISP_PAD_SINK_VIDEO];
+ remote = media_entity_remote_pad(local);
+ if (!remote)
+ return NULL;
+
+ sensor_me = remote->entity;
+ return media_entity_to_v4l2_subdev(sensor_me);
+}
+
+static struct v4l2_mbus_framefmt *
+rkisp1_isp_get_pad_fmt(struct rkisp1_isp *isp,
+ struct v4l2_subdev_pad_config *cfg,
+ unsigned int pad, u32 which)
+{
+ if (which == V4L2_SUBDEV_FORMAT_TRY)
+ return v4l2_subdev_get_try_format(&isp->sd, cfg, pad);
+ else
+ return v4l2_subdev_get_try_format(&isp->sd, isp->pad_cfg, pad);
+}
+
+static struct v4l2_rect *
+rkisp1_isp_get_pad_crop(struct rkisp1_isp *isp,
+ struct v4l2_subdev_pad_config *cfg,
+ unsigned int pad, u32 which)
+{
+ if (which == V4L2_SUBDEV_FORMAT_TRY)
+ return v4l2_subdev_get_try_crop(&isp->sd, cfg, pad);
+ else
+ return v4l2_subdev_get_try_crop(&isp->sd, isp->pad_cfg, pad);
+}
+
+/* ----------------------------------------------------------------------------
+ * Camera Interface registers configurations
+ */
+
+/*
+ * Image Stabilization.
+ * This should only be called when configuring CIF
+ * or at the frame end interrupt
+ */
+static void rkisp1_config_ism(struct rkisp1_device *rkisp1)
+{
+ struct v4l2_rect *src_crop =
+ rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
+ RKISP1_ISP_PAD_SOURCE_VIDEO,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ u32 val;
+
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_RECENTER);
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DX);
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DY);
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_DISPLACE);
+ rkisp1_write(rkisp1, src_crop->left, RKISP1_CIF_ISP_IS_H_OFFS);
+ rkisp1_write(rkisp1, src_crop->top, RKISP1_CIF_ISP_IS_V_OFFS);
+ rkisp1_write(rkisp1, src_crop->width, RKISP1_CIF_ISP_IS_H_SIZE);
+ rkisp1_write(rkisp1, src_crop->height, RKISP1_CIF_ISP_IS_V_SIZE);
+
+ /* IS(Image Stabilization) is always on, working as output crop */
+ rkisp1_write(rkisp1, 1, RKISP1_CIF_ISP_IS_CTRL);
+ val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
+ val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD;
+ rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
+}
+
+/*
+ * configure ISP blocks with input format, size......
+ */
+static int rkisp1_config_isp(struct rkisp1_device *rkisp1)
+{
+ u32 isp_ctrl = 0, irq_mask = 0, acq_mult = 0, signal = 0;
+ const struct rkisp1_isp_mbus_info *src_fmt, *sink_fmt;
+ struct rkisp1_sensor_async *sensor;
+ struct v4l2_mbus_framefmt *sink_frm;
+ struct v4l2_rect *sink_crop;
+
+ sensor = rkisp1->active_sensor;
+ sink_fmt = rkisp1->isp.sink_fmt;
+ src_fmt = rkisp1->isp.src_fmt;
+ sink_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
+ RKISP1_ISP_PAD_SINK_VIDEO,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ sink_crop = rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
+ RKISP1_ISP_PAD_SINK_VIDEO,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+
+ if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+ acq_mult = 1;
+ if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+ if (sensor->mbus_type == V4L2_MBUS_BT656)
+ isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656;
+ else
+ isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT;
+ } else {
+ rkisp1_write(rkisp1, RKISP1_CIF_ISP_DEMOSAIC_TH(0xc),
+ RKISP1_CIF_ISP_DEMOSAIC);
+
+ if (sensor->mbus_type == V4L2_MBUS_BT656)
+ isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656;
+ else
+ isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601;
+ }
+ } else if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_YUV) {
+ acq_mult = 2;
+ if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
+ isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
+ } else {
+ if (sensor->mbus_type == V4L2_MBUS_BT656)
+ isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656;
+ else
+ isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
+ }
+
+ irq_mask |= RKISP1_CIF_ISP_DATA_LOSS;
+ }
+
+ /* Set up input acquisition properties */
+ if (sensor->mbus_type == V4L2_MBUS_BT656 ||
+ sensor->mbus_type == V4L2_MBUS_PARALLEL) {
+ if (sensor->mbus_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+ signal = RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE;
+ }
+
+ if (sensor->mbus_type == V4L2_MBUS_PARALLEL) {
+ if (sensor->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+ signal |= RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW;
+
+ if (sensor->mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+ signal |= RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW;
+ }
+
+ rkisp1_write(rkisp1, isp_ctrl, RKISP1_CIF_ISP_CTRL);
+ rkisp1_write(rkisp1, signal | sink_fmt->yuv_seq |
+ RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(sink_fmt->bayer_pat) |
+ RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL,
+ RKISP1_CIF_ISP_ACQ_PROP);
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_NR_FRAMES);
+
+ /* Acquisition Size */
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_H_OFFS);
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_V_OFFS);
+ rkisp1_write(rkisp1,
+ acq_mult * sink_frm->width, RKISP1_CIF_ISP_ACQ_H_SIZE);
+ rkisp1_write(rkisp1, sink_frm->height, RKISP1_CIF_ISP_ACQ_V_SIZE);
+
+ /* ISP Out Area */
+ rkisp1_write(rkisp1, sink_crop->left, RKISP1_CIF_ISP_OUT_H_OFFS);
+ rkisp1_write(rkisp1, sink_crop->top, RKISP1_CIF_ISP_OUT_V_OFFS);
+ rkisp1_write(rkisp1, sink_crop->width, RKISP1_CIF_ISP_OUT_H_SIZE);
+ rkisp1_write(rkisp1, sink_crop->height, RKISP1_CIF_ISP_OUT_V_SIZE);
+
+ irq_mask |= RKISP1_CIF_ISP_FRAME | RKISP1_CIF_ISP_V_START |
+ RKISP1_CIF_ISP_PIC_SIZE_ERROR;
+ rkisp1_write(rkisp1, irq_mask, RKISP1_CIF_ISP_IMSC);
+
+ if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+ rkisp1_params_disable(&rkisp1->params);
+ } else {
+ struct v4l2_mbus_framefmt *src_frm;
+
+ src_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
+ RKISP1_ISP_PAD_SINK_VIDEO,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ rkisp1_params_configure(&rkisp1->params, sink_fmt->bayer_pat,
+ src_frm->quantization);
+ }
+
+ return 0;
+}
+
+static int rkisp1_config_dvp(struct rkisp1_device *rkisp1)
+{
+ const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
+ u32 val, input_sel;
+
+ switch (sink_fmt->bus_width) {
+ case 8:
+ input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;
+ break;
+ case 10:
+ input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;
+ break;
+ case 12:
+ input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B;
+ break;
+ default:
+ dev_err(rkisp1->dev, "Invalid bus width\n");
+ return -EINVAL;
+ }
+
+ val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ACQ_PROP);
+ rkisp1_write(rkisp1, val | input_sel, RKISP1_CIF_ISP_ACQ_PROP);
+
+ return 0;
+}
+
+static int rkisp1_config_mipi(struct rkisp1_device *rkisp1)
+{
+ const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
+ unsigned int lanes = rkisp1->active_sensor->lanes;
+ u32 mipi_ctrl;
+
+ if (lanes < 1 || lanes > 4)
+ return -EINVAL;
+
+ mipi_ctrl = RKISP1_CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
+ RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
+ RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
+ RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA;
+
+ rkisp1_write(rkisp1, mipi_ctrl, RKISP1_CIF_MIPI_CTRL);
+
+ /* Configure Data Type and Virtual Channel */
+ rkisp1_write(rkisp1,
+ RKISP1_CIF_MIPI_DATA_SEL_DT(sink_fmt->mipi_dt) |
+ RKISP1_CIF_MIPI_DATA_SEL_VC(0),
+ RKISP1_CIF_MIPI_IMG_DATA_SEL);
+
+ /* Clear MIPI interrupts */
+ rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
+ /*
+ * Disable RKISP1_CIF_MIPI_ERR_DPHY interrupt here temporary for
+ * isp bus may be dead when switch isp.
+ */
+ rkisp1_write(rkisp1,
+ RKISP1_CIF_MIPI_FRAME_END | RKISP1_CIF_MIPI_ERR_CSI |
+ RKISP1_CIF_MIPI_ERR_DPHY |
+ RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(0x03) |
+ RKISP1_CIF_MIPI_ADD_DATA_OVFLW,
+ RKISP1_CIF_MIPI_IMSC);
+
+ dev_dbg(rkisp1->dev, "\n MIPI_CTRL 0x%08x\n"
+ " MIPI_IMG_DATA_SEL 0x%08x\n"
+ " MIPI_STATUS 0x%08x\n"
+ " MIPI_IMSC 0x%08x\n",
+ rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL),
+ rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMG_DATA_SEL),
+ rkisp1_read(rkisp1, RKISP1_CIF_MIPI_STATUS),
+ rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC));
+
+ return 0;
+}
+
+/* Configure MUX */
+static int rkisp1_config_path(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
+ u32 dpcl = rkisp1_read(rkisp1, RKISP1_CIF_VI_DPCL);
+ int ret = 0;
+
+ if (sensor->mbus_type == V4L2_MBUS_BT656 ||
+ sensor->mbus_type == V4L2_MBUS_PARALLEL) {
+ ret = rkisp1_config_dvp(rkisp1);
+ dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL;
+ } else if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
+ ret = rkisp1_config_mipi(rkisp1);
+ dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_MIPI;
+ }
+
+ rkisp1_write(rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
+
+ return ret;
+}
+
+/* Hardware configure Entry */
+static int rkisp1_config_cif(struct rkisp1_device *rkisp1)
+{
+ u32 cif_id;
+ int ret;
+
+ cif_id = rkisp1_read(rkisp1, RKISP1_CIF_VI_ID);
+ dev_dbg(rkisp1->dev, "CIF_ID 0x%08x\n", cif_id);
+
+ ret = rkisp1_config_isp(rkisp1);
+ if (ret)
+ return ret;
+ ret = rkisp1_config_path(rkisp1);
+ if (ret)
+ return ret;
+ rkisp1_config_ism(rkisp1);
+
+ return 0;
+}
+
+static void rkisp1_isp_stop(struct rkisp1_device *rkisp1)
+{
+ u32 val;
+
+ /*
+ * ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
+ * Stop ISP(isp) ->wait for ISP isp off
+ */
+ /* stop and clear MI, MIPI, and ISP interrupts */
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_MIPI_IMSC);
+ rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
+
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IMSC);
+ rkisp1_write(rkisp1, ~0, RKISP1_CIF_ISP_ICR);
+
+ rkisp1_write(rkisp1, 0, RKISP1_CIF_MI_IMSC);
+ rkisp1_write(rkisp1, ~0, RKISP1_CIF_MI_ICR);
+ val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
+ rkisp1_write(rkisp1, val & (~RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA),
+ RKISP1_CIF_MIPI_CTRL);
+ /* stop ISP */
+ val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
+ val &= ~(RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE |
+ RKISP1_CIF_ISP_CTRL_ISP_ENABLE);
+ rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
+
+ val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
+ rkisp1_write(rkisp1, val | RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD,
+ RKISP1_CIF_ISP_CTRL);
+
+ readx_poll_timeout(readl, rkisp1->base_addr + RKISP1_CIF_ISP_RIS,
+ val, val & RKISP1_CIF_ISP_OFF, 20, 100);
+ rkisp1_write(rkisp1,
+ RKISP1_CIF_IRCL_MIPI_SW_RST | RKISP1_CIF_IRCL_ISP_SW_RST,
+ RKISP1_CIF_IRCL);
+ rkisp1_write(rkisp1, 0x0, RKISP1_CIF_IRCL);
+}
+
+static void rkisp1_config_clk(struct rkisp1_device *rkisp1)
+{
+ u32 val = RKISP1_CIF_ICCL_ISP_CLK | RKISP1_CIF_ICCL_CP_CLK |
+ RKISP1_CIF_ICCL_MRSZ_CLK | RKISP1_CIF_ICCL_SRSZ_CLK |
+ RKISP1_CIF_ICCL_JPEG_CLK | RKISP1_CIF_ICCL_MI_CLK |
+ RKISP1_CIF_ICCL_IE_CLK | RKISP1_CIF_ICCL_MIPI_CLK |
+ RKISP1_CIF_ICCL_DCROP_CLK;
+
+ rkisp1_write(rkisp1, val, RKISP1_CIF_ICCL);
+}
+
+static void rkisp1_isp_start(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
+ u32 val;
+
+ rkisp1_config_clk(rkisp1);
+
+ /* Activate MIPI */
+ if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
+ val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
+ rkisp1_write(rkisp1, val | RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA,
+ RKISP1_CIF_MIPI_CTRL);
+ }
+ /* Activate ISP */
+ val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
+ val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
+ RKISP1_CIF_ISP_CTRL_ISP_ENABLE |
+ RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE;
+ rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
+
+ /*
+ * CIF spec says to wait for sufficient time after enabling
+ * the MIPI interface and before starting the sensor output.
+ */
+ usleep_range(1000, 1200);
+}
+
+/* ----------------------------------------------------------------------------
+ * Subdev pad operations
+ */
+
+static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ unsigned int i, dir;
+ int pos = 0;
+
+ if (code->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
+ dir = RKISP1_ISP_SD_SINK;
+ } else if (code->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) {
+ dir = RKISP1_ISP_SD_SRC;
+ } else {
+ if (code->index > 0)
+ return -EINVAL;
+ code->code = MEDIA_BUS_FMT_METADATA_FIXED;
+ return 0;
+ }
+
+ if (code->index >= ARRAY_SIZE(rkisp1_isp_formats))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
+ const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
+
+ if (fmt->direction & dir)
+ pos++;
+
+ if (code->index == pos - 1) {
+ code->code = fmt->mbus_code;
+ if (fmt->pixel_enc == V4L2_PIXEL_ENC_YUV &&
+ dir == RKISP1_ISP_SD_SRC)
+ code->flags =
+ V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg)
+{
+ struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
+ struct v4l2_rect *sink_crop, *src_crop;
+
+ sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
+ RKISP1_ISP_PAD_SINK_VIDEO);
+ sink_fmt->width = RKISP1_DEFAULT_WIDTH;
+ sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
+ sink_fmt->field = V4L2_FIELD_NONE;
+ sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
+
+ sink_crop = v4l2_subdev_get_try_crop(sd, cfg,
+ RKISP1_ISP_PAD_SINK_VIDEO);
+ sink_crop->width = RKISP1_DEFAULT_WIDTH;
+ sink_crop->height = RKISP1_DEFAULT_HEIGHT;
+ sink_crop->left = 0;
+ sink_crop->top = 0;
+
+ src_fmt = v4l2_subdev_get_try_format(sd, cfg,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+ *src_fmt = *sink_fmt;
+ src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
+
+ src_crop = v4l2_subdev_get_try_crop(sd, cfg,
+ RKISP1_ISP_PAD_SOURCE_VIDEO);
+ *src_crop = *sink_crop;
+
+ sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
+ RKISP1_ISP_PAD_SINK_PARAMS);
+ src_fmt = v4l2_subdev_get_try_format(sd, cfg,
+ RKISP1_ISP_PAD_SOURCE_STATS);
+ sink_fmt->width = 0;
+ sink_fmt->height = 0;
+ sink_fmt->field = V4L2_FIELD_NONE;
+ sink_fmt->code = MEDIA_BUS_FMT_METADATA_FIXED;
+ *src_fmt = *sink_fmt;
+
+ return 0;
+}
+
+static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_mbus_framefmt *format,
+ unsigned int which)
+{
+ const struct rkisp1_isp_mbus_info *mbus_info;
+ struct v4l2_mbus_framefmt *src_fmt;
+ const struct v4l2_rect *src_crop;
+
+ src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
+ RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+ src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+ RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+
+ src_fmt->code = format->code;
+ mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
+ if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
+ src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
+ mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
+ }
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ isp->src_fmt = mbus_info;
+ src_fmt->width = src_crop->width;
+ src_fmt->height = src_crop->height;
+
+ /*
+ * The CSC API is used to allow userspace to force full
+ * quantization on YUV formats.
+ */
+ if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC &&
+ format->quantization == V4L2_QUANTIZATION_FULL_RANGE &&
+ mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+ src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+ src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+ else
+ src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+
+ *format = *src_fmt;
+}
+
+static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_rect *r, unsigned int which)
+{
+ struct v4l2_mbus_framefmt *src_fmt;
+ const struct v4l2_rect *sink_crop;
+ struct v4l2_rect *src_crop;
+
+ src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+ RKISP1_ISP_PAD_SOURCE_VIDEO,
+ which);
+ sink_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+ RKISP1_ISP_PAD_SINK_VIDEO,
+ which);
+
+ src_crop->left = ALIGN(r->left, 2);
+ src_crop->width = ALIGN(r->width, 2);
+ src_crop->top = r->top;
+ src_crop->height = r->height;
+ rkisp1_sd_adjust_crop_rect(src_crop, sink_crop);
+
+ *r = *src_crop;
+
+ /* Propagate to out format */
+ src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
+ RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+ rkisp1_isp_set_src_fmt(isp, cfg, src_fmt, which);
+}
+
+static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_rect *r, unsigned int which)
+{
+ struct v4l2_rect *sink_crop, *src_crop;
+ struct v4l2_mbus_framefmt *sink_fmt;
+
+ sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+ which);
+ sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+ which);
+
+ sink_crop->left = ALIGN(r->left, 2);
+ sink_crop->width = ALIGN(r->width, 2);
+ sink_crop->top = r->top;
+ sink_crop->height = r->height;
+ rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
+
+ *r = *sink_crop;
+
+ /* Propagate to out crop */
+ src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
+ RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+ rkisp1_isp_set_src_crop(isp, cfg, src_crop, which);
+}
+
+static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_mbus_framefmt *format,
+ unsigned int which)
+{
+ const struct rkisp1_isp_mbus_info *mbus_info;
+ struct v4l2_mbus_framefmt *sink_fmt;
+ struct v4l2_rect *sink_crop;
+
+ sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+ which);
+ sink_fmt->code = format->code;
+ mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+ if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SINK)) {
+ sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
+ mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+ }
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ isp->sink_fmt = mbus_info;
+
+ sink_fmt->width = clamp_t(u32, format->width,
+ RKISP1_ISP_MIN_WIDTH,
+ RKISP1_ISP_MAX_WIDTH);
+ sink_fmt->height = clamp_t(u32, format->height,
+ RKISP1_ISP_MIN_HEIGHT,
+ RKISP1_ISP_MAX_HEIGHT);
+
+ *format = *sink_fmt;
+
+ /* Propagate to in crop */
+ sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
+ which);
+ rkisp1_isp_set_sink_crop(isp, cfg, sink_crop, which);
+}
+
+static int rkisp1_isp_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+
+ mutex_lock(&isp->ops_lock);
+ fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad, fmt->which);
+ mutex_unlock(&isp->ops_lock);
+ return 0;
+}
+
+static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+
+ mutex_lock(&isp->ops_lock);
+ if (fmt->pad == RKISP1_ISP_PAD_SINK_VIDEO)
+ rkisp1_isp_set_sink_fmt(isp, cfg, &fmt->format, fmt->which);
+ else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
+ rkisp1_isp_set_src_fmt(isp, cfg, &fmt->format, fmt->which);
+ else
+ fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad,
+ fmt->which);
+
+ mutex_unlock(&isp->ops_lock);
+ return 0;
+}
+
+static int rkisp1_isp_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
+{
+ struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+ int ret = 0;
+
+ if (sel->pad != RKISP1_ISP_PAD_SOURCE_VIDEO &&
+ sel->pad != RKISP1_ISP_PAD_SINK_VIDEO)
+ return -EINVAL;
+
+ mutex_lock(&isp->ops_lock);
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
+ struct v4l2_mbus_framefmt *fmt;
+
+ fmt = rkisp1_isp_get_pad_fmt(isp, cfg, sel->pad,
+ sel->which);
+ sel->r.height = fmt->height;
+ sel->r.width = fmt->width;
+ sel->r.left = 0;
+ sel->r.top = 0;
+ } else {
+ sel->r = *rkisp1_isp_get_pad_crop(isp, cfg,
+ RKISP1_ISP_PAD_SINK_VIDEO,
+ sel->which);
+ }
+ break;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = *rkisp1_isp_get_pad_crop(isp, cfg, sel->pad,
+ sel->which);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ mutex_unlock(&isp->ops_lock);
+ return ret;
+}
+
+static int rkisp1_isp_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
+{
+ struct rkisp1_device *rkisp1 =
+ container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
+ struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
+ int ret = 0;
+
+ if (sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
+
+ dev_dbg(rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
+ sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
+ mutex_lock(&isp->ops_lock);
+ if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO)
+ rkisp1_isp_set_sink_crop(isp, cfg, &sel->r, sel->which);
+ else if (sel->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
+ rkisp1_isp_set_src_crop(isp, cfg, &sel->r, sel->which);
+ else
+ ret = -EINVAL;
+
+ mutex_unlock(&isp->ops_lock);
+ return ret;
+}
+
+static int rkisp1_subdev_link_validate(struct media_link *link)
+{
+ if (link->sink->index == RKISP1_ISP_PAD_SINK_PARAMS)
+ return 0;
+
+ return v4l2_subdev_link_validate(link);
+}
+
+static const struct v4l2_subdev_pad_ops rkisp1_isp_pad_ops = {
+ .enum_mbus_code = rkisp1_isp_enum_mbus_code,
+ .get_selection = rkisp1_isp_get_selection,
+ .set_selection = rkisp1_isp_set_selection,
+ .init_cfg = rkisp1_isp_init_config,
+ .get_fmt = rkisp1_isp_get_fmt,
+ .set_fmt = rkisp1_isp_set_fmt,
+ .link_validate = v4l2_subdev_link_validate_default,
+};
+
+/* ----------------------------------------------------------------------------
+ * Stream operations
+ */
+
+static int rkisp1_mipi_csi2_start(struct rkisp1_isp *isp,
+ struct rkisp1_sensor_async *sensor)
+{
+ struct rkisp1_device *rkisp1 =
+ container_of(isp->sd.v4l2_dev, struct rkisp1_device, v4l2_dev);
+ union phy_configure_opts opts;
+ struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
+ s64 pixel_clock;
+
+ if (!sensor->pixel_rate_ctrl) {
+ dev_warn(rkisp1->dev, "No pixel rate control in sensor subdev\n");
+ return -EPIPE;
+ }
+
+ pixel_clock = v4l2_ctrl_g_ctrl_int64(sensor->pixel_rate_ctrl);
+ if (!pixel_clock) {
+ dev_err(rkisp1->dev, "Invalid pixel rate value\n");
+ return -EINVAL;
+ }
+
+ phy_mipi_dphy_get_default_config(pixel_clock, isp->sink_fmt->bus_width,
+ sensor->lanes, cfg);
+ phy_set_mode(sensor->dphy, PHY_MODE_MIPI_DPHY);
+ phy_configure(sensor->dphy, &opts);
+ phy_power_on(sensor->dphy);
+
+ return 0;
+}
+
+static void rkisp1_mipi_csi2_stop(struct rkisp1_sensor_async *sensor)
+{
+ phy_power_off(sensor->dphy);
+}
+
+static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct rkisp1_device *rkisp1 =
+ container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
+ struct rkisp1_isp *isp = &rkisp1->isp;
+ struct v4l2_subdev *sensor_sd;
+ int ret = 0;
+
+ if (!enable) {
+ rkisp1_isp_stop(rkisp1);
+ rkisp1_mipi_csi2_stop(rkisp1->active_sensor);
+ return 0;
+ }
+
+ sensor_sd = rkisp1_get_remote_sensor(sd);
+ if (!sensor_sd) {
+ dev_warn(rkisp1->dev, "No link between isp and sensor\n");
+ return -ENODEV;
+ }
+
+ rkisp1->active_sensor = container_of(sensor_sd->asd,
+ struct rkisp1_sensor_async, asd);
+
+ if (rkisp1->active_sensor->mbus_type != V4L2_MBUS_CSI2_DPHY)
+ return -EINVAL;
+
+ rkisp1->isp.frame_sequence = -1;
+ mutex_lock(&isp->ops_lock);
+ ret = rkisp1_config_cif(rkisp1);
+ if (ret)
+ goto mutex_unlock;
+
+ ret = rkisp1_mipi_csi2_start(&rkisp1->isp, rkisp1->active_sensor);
+ if (ret)
+ goto mutex_unlock;
+
+ rkisp1_isp_start(rkisp1);
+
+mutex_unlock:
+ mutex_unlock(&isp->ops_lock);
+ return ret;
+}
+
+static int rkisp1_isp_subs_evt(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ if (sub->type != V4L2_EVENT_FRAME_SYNC)
+ return -EINVAL;
+
+ /* V4L2_EVENT_FRAME_SYNC doesn't require an id, so zero should be set */
+ if (sub->id != 0)
+ return -EINVAL;
+
+ return v4l2_event_subscribe(fh, sub, 0, NULL);
+}
+
+static const struct media_entity_operations rkisp1_isp_media_ops = {
+ .link_validate = rkisp1_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_video_ops rkisp1_isp_video_ops = {
+ .s_stream = rkisp1_isp_s_stream,
+};
+
+static const struct v4l2_subdev_core_ops rkisp1_isp_core_ops = {
+ .subscribe_event = rkisp1_isp_subs_evt,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_ops rkisp1_isp_ops = {
+ .core = &rkisp1_isp_core_ops,
+ .video = &rkisp1_isp_video_ops,
+ .pad = &rkisp1_isp_pad_ops,
+};
+
+int rkisp1_isp_register(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_isp *isp = &rkisp1->isp;
+ struct media_pad *pads = isp->pads;
+ struct v4l2_subdev *sd = &isp->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &rkisp1_isp_ops);
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+ sd->entity.ops = &rkisp1_isp_media_ops;
+ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
+ sd->owner = THIS_MODULE;
+ strscpy(sd->name, RKISP1_ISP_DEV_NAME, sizeof(sd->name));
+
+ pads[RKISP1_ISP_PAD_SINK_VIDEO].flags = MEDIA_PAD_FL_SINK |
+ MEDIA_PAD_FL_MUST_CONNECT;
+ pads[RKISP1_ISP_PAD_SINK_PARAMS].flags = MEDIA_PAD_FL_SINK;
+ pads[RKISP1_ISP_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
+ pads[RKISP1_ISP_PAD_SOURCE_STATS].flags = MEDIA_PAD_FL_SOURCE;
+
+ isp->sink_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SINK_PAD_FMT);
+ isp->src_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SRC_PAD_FMT);
+
+ mutex_init(&isp->ops_lock);
+ ret = media_entity_pads_init(&sd->entity, RKISP1_ISP_PAD_MAX, pads);
+ if (ret)
+ return ret;
+
+ ret = v4l2_device_register_subdev(&rkisp1->v4l2_dev, sd);
+ if (ret) {
+ dev_err(rkisp1->dev, "Failed to register isp subdev\n");
+ goto err_cleanup_media_entity;
+ }
+
+ rkisp1_isp_init_config(sd, rkisp1->isp.pad_cfg);
+ return 0;
+
+err_cleanup_media_entity:
+ media_entity_cleanup(&sd->entity);
+
+ return ret;
+}
+
+void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
+{
+ struct v4l2_subdev *sd = &rkisp1->isp.sd;
+
+ v4l2_device_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+}
+
+/* ----------------------------------------------------------------------------
+ * Interrupt handlers
+ */
+
+void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
+{
+ u32 val, status;
+
+ status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS);
+ if (!status)
+ return;
+
+ rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR);
+
+ /*
+ * Disable DPHY errctrl interrupt, because this dphy
+ * erctrl signal is asserted until the next changes
+ * of line state. This time is may be too long and cpu
+ * is hold in this interrupt.
+ */
+ if (status & RKISP1_CIF_MIPI_ERR_CTRL(0x0f)) {
+ val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
+ rkisp1_write(rkisp1, val & ~RKISP1_CIF_MIPI_ERR_CTRL(0x0f),
+ RKISP1_CIF_MIPI_IMSC);
+ rkisp1->isp.is_dphy_errctrl_disabled = true;
+ }
+
+ /*
+ * Enable DPHY errctrl interrupt again, if mipi have receive
+ * the whole frame without any error.
+ */
+ if (status == RKISP1_CIF_MIPI_FRAME_END) {
+ /*
+ * Enable DPHY errctrl interrupt again, if mipi have receive
+ * the whole frame without any error.
+ */
+ if (rkisp1->isp.is_dphy_errctrl_disabled) {
+ val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
+ val |= RKISP1_CIF_MIPI_ERR_CTRL(0x0f);
+ rkisp1_write(rkisp1, val, RKISP1_CIF_MIPI_IMSC);
+ rkisp1->isp.is_dphy_errctrl_disabled = false;
+ }
+ } else {
+ rkisp1->debug.mipi_error++;
+ }
+}
+
+static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
+{
+ struct v4l2_event event = {
+ .type = V4L2_EVENT_FRAME_SYNC,
+ };
+ event.u.frame_sync.frame_sequence = isp->frame_sequence;
+
+ v4l2_event_queue(isp->sd.devnode, &event);
+}
+
+void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
+{
+ u32 status, isp_err;
+
+ status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
+ if (!status)
+ return;
+
+ rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR);
+
+ /* Vertical sync signal, starting generating new frame */
+ if (status & RKISP1_CIF_ISP_V_START) {
+ rkisp1->isp.frame_sequence++;
+ rkisp1_isp_queue_event_sof(&rkisp1->isp);
+ if (status & RKISP1_CIF_ISP_FRAME) {
+ WARN_ONCE(1, "irq delay is too long, buffers might not be in sync\n");
+ rkisp1->debug.irq_delay++;
+ }
+ }
+ if (status & RKISP1_CIF_ISP_PIC_SIZE_ERROR) {
+ /* Clear pic_size_error */
+ isp_err = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ERR);
+ if (isp_err & RKISP1_CIF_ISP_ERR_INFORM_SIZE)
+ rkisp1->debug.inform_size_error++;
+ if (isp_err & RKISP1_CIF_ISP_ERR_IS_SIZE)
+ rkisp1->debug.img_stabilization_size_error++;
+ if (isp_err & RKISP1_CIF_ISP_ERR_OUTFORM_SIZE)
+ rkisp1->debug.outform_size_error++;
+ rkisp1_write(rkisp1, isp_err, RKISP1_CIF_ISP_ERR_CLR);
+ } else if (status & RKISP1_CIF_ISP_DATA_LOSS) {
+ /* keep track of data_loss in debugfs */
+ rkisp1->debug.data_loss++;
+ }
+
+ if (status & RKISP1_CIF_ISP_FRAME) {
+ u32 isp_ris;
+
+ /* New frame from the sensor received */
+ isp_ris = rkisp1_read(rkisp1, RKISP1_CIF_ISP_RIS);
+ if (isp_ris & RKISP1_STATS_MEAS_MASK)
+ rkisp1_stats_isr(&rkisp1->stats, isp_ris);
+ /*
+ * Then update changed configs. Some of them involve
+ * lot of register writes. Do those only one per frame.
+ * Do the updates in the order of the processing flow.
+ */
+ rkisp1_params_isr(rkisp1);
+ }
+}
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Params subdevice
+ *
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h> /* for ISP params */
+
+#include "rkisp1-common.h"
+
+#define RKISP1_PARAMS_DEV_NAME RKISP1_DRIVER_NAME "_params"
+
+#define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2
+#define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8
+
+#define RKISP1_ISP_DPCC_LINE_THRESH(n) \
+ (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \
+ (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_PG_FAC(n) \
+ (RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_RND_THRESH(n) \
+ (RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n))
+#define RKISP1_ISP_DPCC_RG_FAC(n) \
+ (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n))
+#define RKISP1_ISP_CC_COEFF(n) \
+ (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
+
+static inline void
+rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
+{
+ u32 val;
+
+ val = rkisp1_read(params->rkisp1, reg);
+ rkisp1_write(params->rkisp1, val | bit_mask, reg);
+}
+
+static inline void
+rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
+{
+ u32 val;
+
+ val = rkisp1_read(params->rkisp1, reg);
+ rkisp1_write(params->rkisp1, val & ~bit_mask, reg);
+}
+
+/* ISP BP interface function */
+static void rkisp1_dpcc_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_dpcc_config *arg)
+{
+ unsigned int i;
+ u32 mode;
+
+ /* avoid to override the old enable value */
+ mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE);
+ mode &= RKISP1_CIF_ISP_DPCC_ENA;
+ mode |= arg->mode & ~RKISP1_CIF_ISP_DPCC_ENA;
+ rkisp1_write(params->rkisp1, mode, RKISP1_CIF_ISP_DPCC_MODE);
+ rkisp1_write(params->rkisp1, arg->output_mode,
+ RKISP1_CIF_ISP_DPCC_OUTPUT_MODE);
+ rkisp1_write(params->rkisp1, arg->set_use,
+ RKISP1_CIF_ISP_DPCC_SET_USE);
+
+ rkisp1_write(params->rkisp1, arg->methods[0].method,
+ RKISP1_CIF_ISP_DPCC_METHODS_SET_1);
+ rkisp1_write(params->rkisp1, arg->methods[1].method,
+ RKISP1_CIF_ISP_DPCC_METHODS_SET_2);
+ rkisp1_write(params->rkisp1, arg->methods[2].method,
+ RKISP1_CIF_ISP_DPCC_METHODS_SET_3);
+ for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) {
+ rkisp1_write(params->rkisp1, arg->methods[i].line_thresh,
+ RKISP1_ISP_DPCC_LINE_THRESH(i));
+ rkisp1_write(params->rkisp1, arg->methods[i].line_mad_fac,
+ RKISP1_ISP_DPCC_LINE_MAD_FAC(i));
+ rkisp1_write(params->rkisp1, arg->methods[i].pg_fac,
+ RKISP1_ISP_DPCC_PG_FAC(i));
+ rkisp1_write(params->rkisp1, arg->methods[i].rnd_thresh,
+ RKISP1_ISP_DPCC_RND_THRESH(i));
+ rkisp1_write(params->rkisp1, arg->methods[i].rg_fac,
+ RKISP1_ISP_DPCC_RG_FAC(i));
+ }
+
+ rkisp1_write(params->rkisp1, arg->rnd_offs,
+ RKISP1_CIF_ISP_DPCC_RND_OFFS);
+ rkisp1_write(params->rkisp1, arg->ro_limits,
+ RKISP1_CIF_ISP_DPCC_RO_LIMITS);
+}
+
+/* ISP black level subtraction interface function */
+static void rkisp1_bls_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_bls_config *arg)
+{
+ /* avoid to override the old enable value */
+ u32 new_control;
+
+ new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL);
+ new_control &= RKISP1_CIF_ISP_BLS_ENA;
+ /* fixed subtraction values */
+ if (!arg->enable_auto) {
+ const struct rkisp1_cif_isp_bls_fixed_val *pval =
+ &arg->fixed_val;
+
+ switch (params->raw_type) {
+ case RKISP1_RAW_BGGR:
+ rkisp1_write(params->rkisp1,
+ pval->r, RKISP1_CIF_ISP_BLS_D_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gr, RKISP1_CIF_ISP_BLS_C_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gb, RKISP1_CIF_ISP_BLS_B_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->b, RKISP1_CIF_ISP_BLS_A_FIXED);
+ break;
+ case RKISP1_RAW_GBRG:
+ rkisp1_write(params->rkisp1,
+ pval->r, RKISP1_CIF_ISP_BLS_C_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gr, RKISP1_CIF_ISP_BLS_D_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gb, RKISP1_CIF_ISP_BLS_A_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->b, RKISP1_CIF_ISP_BLS_B_FIXED);
+ break;
+ case RKISP1_RAW_GRBG:
+ rkisp1_write(params->rkisp1,
+ pval->r, RKISP1_CIF_ISP_BLS_B_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gr, RKISP1_CIF_ISP_BLS_A_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gb, RKISP1_CIF_ISP_BLS_D_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->b, RKISP1_CIF_ISP_BLS_C_FIXED);
+ break;
+ case RKISP1_RAW_RGGB:
+ rkisp1_write(params->rkisp1,
+ pval->r, RKISP1_CIF_ISP_BLS_A_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gr, RKISP1_CIF_ISP_BLS_B_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->gb, RKISP1_CIF_ISP_BLS_C_FIXED);
+ rkisp1_write(params->rkisp1,
+ pval->b, RKISP1_CIF_ISP_BLS_D_FIXED);
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ if (arg->en_windows & BIT(1)) {
+ rkisp1_write(params->rkisp1, arg->bls_window2.h_offs,
+ RKISP1_CIF_ISP_BLS_H2_START);
+ rkisp1_write(params->rkisp1, arg->bls_window2.h_size,
+ RKISP1_CIF_ISP_BLS_H2_STOP);
+ rkisp1_write(params->rkisp1, arg->bls_window2.v_offs,
+ RKISP1_CIF_ISP_BLS_V2_START);
+ rkisp1_write(params->rkisp1, arg->bls_window2.v_size,
+ RKISP1_CIF_ISP_BLS_V2_STOP);
+ new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2;
+ }
+
+ if (arg->en_windows & BIT(0)) {
+ rkisp1_write(params->rkisp1, arg->bls_window1.h_offs,
+ RKISP1_CIF_ISP_BLS_H1_START);
+ rkisp1_write(params->rkisp1, arg->bls_window1.h_size,
+ RKISP1_CIF_ISP_BLS_H1_STOP);
+ rkisp1_write(params->rkisp1, arg->bls_window1.v_offs,
+ RKISP1_CIF_ISP_BLS_V1_START);
+ rkisp1_write(params->rkisp1, arg->bls_window1.v_size,
+ RKISP1_CIF_ISP_BLS_V1_STOP);
+ new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1;
+ }
+
+ rkisp1_write(params->rkisp1, arg->bls_samples,
+ RKISP1_CIF_ISP_BLS_SAMPLES);
+
+ new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED;
+ }
+ rkisp1_write(params->rkisp1, new_control, RKISP1_CIF_ISP_BLS_CTRL);
+}
+
+/* ISP LS correction interface function */
+static void
+rkisp1_lsc_correct_matrix_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_lsc_config *pconfig)
+{
+ unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data;
+
+ isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
+
+ /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
+ sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
+ RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
+ RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
+ rkisp1_write(params->rkisp1, sram_addr,
+ RKISP1_CIF_ISP_LSC_R_TABLE_ADDR);
+ rkisp1_write(params->rkisp1, sram_addr,
+ RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR);
+ rkisp1_write(params->rkisp1, sram_addr,
+ RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR);
+ rkisp1_write(params->rkisp1, sram_addr,
+ RKISP1_CIF_ISP_LSC_B_TABLE_ADDR);
+
+ /* program data tables (table size is 9 * 17 = 153) */
+ for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
+ /*
+ * 17 sectors with 2 values in one DWORD = 9
+ * DWORDs (2nd value of last DWORD unused)
+ */
+ for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j],
+ pconfig->r_data_tbl[i][j + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
+
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j],
+ pconfig->gr_data_tbl[i][j + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
+
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j],
+ pconfig->gb_data_tbl[i][j + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
+
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j],
+ pconfig->b_data_tbl[i][j + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
+ }
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j], 0);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
+
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j], 0);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
+
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j], 0);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
+
+ data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j], 0);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
+ }
+ isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
+ RKISP1_CIF_ISP_LSC_TABLE_0 :
+ RKISP1_CIF_ISP_LSC_TABLE_1;
+ rkisp1_write(params->rkisp1, isp_lsc_table_sel,
+ RKISP1_CIF_ISP_LSC_TABLE_SEL);
+}
+
+static void rkisp1_lsc_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_lsc_config *arg)
+{
+ unsigned int i, data;
+ u32 lsc_ctrl;
+
+ /* To config must be off , store the current status firstly */
+ lsc_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_CTRL);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
+ RKISP1_CIF_ISP_LSC_CTRL_ENA);
+ rkisp1_lsc_correct_matrix_config(params, arg);
+
+ for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) {
+ /* program x size tables */
+ data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2],
+ arg->x_size_tbl[i * 2 + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4);
+
+ /* program x grad tables */
+ data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2],
+ arg->x_grad_tbl[i * 2 + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4);
+
+ /* program y size tables */
+ data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2],
+ arg->y_size_tbl[i * 2 + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4);
+
+ /* program y grad tables */
+ data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2],
+ arg->y_grad_tbl[i * 2 + 1]);
+ rkisp1_write(params->rkisp1, data,
+ RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4);
+ }
+
+ /* restore the lsc ctrl status */
+ if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) {
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_LSC_CTRL,
+ RKISP1_CIF_ISP_LSC_CTRL_ENA);
+ } else {
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_LSC_CTRL,
+ RKISP1_CIF_ISP_LSC_CTRL_ENA);
+ }
+}
+
+/* ISP Filtering function */
+static void rkisp1_flt_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_flt_config *arg)
+{
+ u32 filt_mode;
+
+ rkisp1_write(params->rkisp1,
+ arg->thresh_bl0, RKISP1_CIF_ISP_FILT_THRESH_BL0);
+ rkisp1_write(params->rkisp1,
+ arg->thresh_bl1, RKISP1_CIF_ISP_FILT_THRESH_BL1);
+ rkisp1_write(params->rkisp1,
+ arg->thresh_sh0, RKISP1_CIF_ISP_FILT_THRESH_SH0);
+ rkisp1_write(params->rkisp1,
+ arg->thresh_sh1, RKISP1_CIF_ISP_FILT_THRESH_SH1);
+ rkisp1_write(params->rkisp1, arg->fac_bl0, RKISP1_CIF_ISP_FILT_FAC_BL0);
+ rkisp1_write(params->rkisp1, arg->fac_bl1, RKISP1_CIF_ISP_FILT_FAC_BL1);
+ rkisp1_write(params->rkisp1, arg->fac_mid, RKISP1_CIF_ISP_FILT_FAC_MID);
+ rkisp1_write(params->rkisp1, arg->fac_sh0, RKISP1_CIF_ISP_FILT_FAC_SH0);
+ rkisp1_write(params->rkisp1, arg->fac_sh1, RKISP1_CIF_ISP_FILT_FAC_SH1);
+ rkisp1_write(params->rkisp1,
+ arg->lum_weight, RKISP1_CIF_ISP_FILT_LUM_WEIGHT);
+
+ rkisp1_write(params->rkisp1,
+ (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) |
+ RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
+ RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
+ RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1),
+ RKISP1_CIF_ISP_FILT_MODE);
+
+ /* avoid to override the old enable value */
+ filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE);
+ filt_mode &= RKISP1_CIF_ISP_FLT_ENA;
+ if (arg->mode)
+ filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR;
+ filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
+ RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
+ RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1);
+ rkisp1_write(params->rkisp1, filt_mode, RKISP1_CIF_ISP_FILT_MODE);
+}
+
+/* ISP demosaic interface function */
+static int rkisp1_bdm_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_bdm_config *arg)
+{
+ u32 bdm_th;
+
+ /* avoid to override the old enable value */
+ bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC);
+ bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
+ bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
+ /* set demosaic threshold */
+ rkisp1_write(params->rkisp1, bdm_th, RKISP1_CIF_ISP_DEMOSAIC);
+ return 0;
+}
+
+/* ISP GAMMA correction interface function */
+static void rkisp1_sdg_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_sdg_config *arg)
+{
+ unsigned int i;
+
+ rkisp1_write(params->rkisp1,
+ arg->xa_pnts.gamma_dx0, RKISP1_CIF_ISP_GAMMA_DX_LO);
+ rkisp1_write(params->rkisp1,
+ arg->xa_pnts.gamma_dx1, RKISP1_CIF_ISP_GAMMA_DX_HI);
+
+ for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) {
+ rkisp1_write(params->rkisp1, arg->curve_r.gamma_y[i],
+ RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4);
+ rkisp1_write(params->rkisp1, arg->curve_g.gamma_y[i],
+ RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4);
+ rkisp1_write(params->rkisp1, arg->curve_b.gamma_y[i],
+ RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4);
+ }
+}
+
+/* ISP GAMMA correction interface function */
+static void rkisp1_goc_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_goc_config *arg)
+{
+ unsigned int i;
+
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+ rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE);
+
+ for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES; i++)
+ rkisp1_write(params->rkisp1, arg->gamma_y[i],
+ RKISP1_CIF_ISP_GAMMA_OUT_Y_0 + i * 4);
+}
+
+/* ISP Cross Talk */
+static void rkisp1_ctk_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_ctk_config *arg)
+{
+ unsigned int i, j, k = 0;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ rkisp1_write(params->rkisp1, arg->coeff[i][j],
+ RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++);
+ for (i = 0; i < 3; i++)
+ rkisp1_write(params->rkisp1, arg->ct_offset[i],
+ RKISP1_CIF_ISP_CT_OFFSET_R + i * 4);
+}
+
+static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en)
+{
+ if (en)
+ return;
+
+ /* Write back the default values. */
+ rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_0);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_1);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_2);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_3);
+ rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_4);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_5);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_6);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_7);
+ rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_8);
+
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_R);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_G);
+ rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_B);
+}
+
+/* ISP White Balance Mode */
+static void rkisp1_awb_meas_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_awb_meas_config *arg)
+{
+ u32 reg_val = 0;
+ /* based on the mode,configure the awb module */
+ if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
+ /* Reference Cb and Cr */
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
+ arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF);
+ /* Yc Threshold */
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
+ RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
+ RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
+ arg->min_c, RKISP1_CIF_ISP_AWB_THRESH);
+ }
+
+ reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
+ if (arg->enable_ymax_cmp)
+ reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
+ else
+ reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
+ rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
+
+ /* window offset */
+ rkisp1_write(params->rkisp1,
+ arg->awb_wnd.v_offs, RKISP1_CIF_ISP_AWB_WND_V_OFFS);
+ rkisp1_write(params->rkisp1,
+ arg->awb_wnd.h_offs, RKISP1_CIF_ISP_AWB_WND_H_OFFS);
+ /* AWB window size */
+ rkisp1_write(params->rkisp1,
+ arg->awb_wnd.v_size, RKISP1_CIF_ISP_AWB_WND_V_SIZE);
+ rkisp1_write(params->rkisp1,
+ arg->awb_wnd.h_size, RKISP1_CIF_ISP_AWB_WND_H_SIZE);
+ /* Number of frames */
+ rkisp1_write(params->rkisp1,
+ arg->frames, RKISP1_CIF_ISP_AWB_FRAMES);
+}
+
+static void
+rkisp1_awb_meas_enable(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_awb_meas_config *arg,
+ bool en)
+{
+ u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
+
+ /* switch off */
+ reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
+
+ if (en) {
+ if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
+ reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
+ else
+ reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
+
+ rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
+
+ /* Measurements require AWB block be active. */
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+ } else {
+ rkisp1_write(params->rkisp1,
+ reg_val, RKISP1_CIF_ISP_AWB_PROP);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+ }
+}
+
+static void
+rkisp1_awb_gain_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_awb_gain_config *arg)
+{
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
+ arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G);
+
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
+ arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB);
+}
+
+static void rkisp1_aec_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_aec_config *arg)
+{
+ unsigned int block_hsize, block_vsize;
+ u32 exp_ctrl;
+
+ /* avoid to override the old enable value */
+ exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
+ exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
+ if (arg->autostop)
+ exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
+ if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
+ exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
+ rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL);
+
+ rkisp1_write(params->rkisp1,
+ arg->meas_window.h_offs, RKISP1_CIF_ISP_EXP_H_OFFSET);
+ rkisp1_write(params->rkisp1,
+ arg->meas_window.v_offs, RKISP1_CIF_ISP_EXP_V_OFFSET);
+
+ block_hsize = arg->meas_window.h_size /
+ RKISP1_CIF_ISP_EXP_COLUMN_NUM - 1;
+ block_vsize = arg->meas_window.v_size /
+ RKISP1_CIF_ISP_EXP_ROW_NUM - 1;
+
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_EXP_H_SIZE_SET(block_hsize),
+ RKISP1_CIF_ISP_EXP_H_SIZE);
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_EXP_V_SIZE_SET(block_vsize),
+ RKISP1_CIF_ISP_EXP_V_SIZE);
+}
+
+static void rkisp1_cproc_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_cproc_config *arg)
+{
+ struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg =
+ container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config);
+ struct rkisp1_cif_isp_ie_config *cur_ie_config =
+ &cur_other_cfg->ie_config;
+ u32 effect = cur_ie_config->effect;
+ u32 quantization = params->quantization;
+
+ rkisp1_write(params->rkisp1, arg->contrast, RKISP1_CIF_C_PROC_CONTRAST);
+ rkisp1_write(params->rkisp1, arg->hue, RKISP1_CIF_C_PROC_HUE);
+ rkisp1_write(params->rkisp1, arg->sat, RKISP1_CIF_C_PROC_SATURATION);
+ rkisp1_write(params->rkisp1, arg->brightness,
+ RKISP1_CIF_C_PROC_BRIGHTNESS);
+
+ if (quantization != V4L2_QUANTIZATION_FULL_RANGE ||
+ effect != V4L2_COLORFX_NONE) {
+ rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
+ RKISP1_CIF_C_PROC_YOUT_FULL |
+ RKISP1_CIF_C_PROC_YIN_FULL |
+ RKISP1_CIF_C_PROC_COUT_FULL);
+ } else {
+ rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,
+ RKISP1_CIF_C_PROC_YOUT_FULL |
+ RKISP1_CIF_C_PROC_YIN_FULL |
+ RKISP1_CIF_C_PROC_COUT_FULL);
+ }
+}
+
+static void rkisp1_hst_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_hst_config *arg)
+{
+ unsigned int block_hsize, block_vsize;
+ static const u32 hist_weight_regs[] = {
+ RKISP1_CIF_ISP_HIST_WEIGHT_00TO30,
+ RKISP1_CIF_ISP_HIST_WEIGHT_40TO21,
+ RKISP1_CIF_ISP_HIST_WEIGHT_31TO12,
+ RKISP1_CIF_ISP_HIST_WEIGHT_22TO03,
+ RKISP1_CIF_ISP_HIST_WEIGHT_13TO43,
+ RKISP1_CIF_ISP_HIST_WEIGHT_04TO34,
+ RKISP1_CIF_ISP_HIST_WEIGHT_44,
+ };
+ const u8 *weight;
+ unsigned int i;
+ u32 hist_prop;
+
+ /* avoid to override the old enable value */
+ hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP);
+ hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
+ hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET(arg->histogram_predivider);
+ rkisp1_write(params->rkisp1, hist_prop, RKISP1_CIF_ISP_HIST_PROP);
+ rkisp1_write(params->rkisp1,
+ arg->meas_window.h_offs,
+ RKISP1_CIF_ISP_HIST_H_OFFS);
+ rkisp1_write(params->rkisp1,
+ arg->meas_window.v_offs,
+ RKISP1_CIF_ISP_HIST_V_OFFS);
+
+ block_hsize = arg->meas_window.h_size /
+ RKISP1_CIF_ISP_HIST_COLUMN_NUM - 1;
+ block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM - 1;
+
+ rkisp1_write(params->rkisp1, block_hsize, RKISP1_CIF_ISP_HIST_H_SIZE);
+ rkisp1_write(params->rkisp1, block_vsize, RKISP1_CIF_ISP_HIST_V_SIZE);
+
+ weight = arg->hist_weight;
+ for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4)
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_HIST_WEIGHT_SET(weight[0],
+ weight[1],
+ weight[2],
+ weight[3]),
+ hist_weight_regs[i]);
+}
+
+static void
+rkisp1_hst_enable(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_hst_config *arg, bool en)
+{
+ if (en) {
+ u32 hist_prop = rkisp1_read(params->rkisp1,
+ RKISP1_CIF_ISP_HIST_PROP);
+
+ hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
+ hist_prop |= arg->mode;
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
+ hist_prop);
+ } else {
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP,
+ RKISP1_CIF_ISP_HIST_PROP_MODE_MASK);
+ }
+}
+
+static void rkisp1_afm_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_afc_config *arg)
+{
+ size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
+ arg->num_afm_win);
+ u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
+ unsigned int i;
+
+ /* Switch off to configure. */
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
+ RKISP1_CIF_ISP_AFM_ENA);
+
+ for (i = 0; i < num_of_win; i++) {
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
+ RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs),
+ RKISP1_CIF_ISP_AFM_LT_A + i * 8);
+ rkisp1_write(params->rkisp1,
+ RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
+ arg->afm_win[i].h_offs) |
+ RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
+ arg->afm_win[i].v_offs),
+ RKISP1_CIF_ISP_AFM_RB_A + i * 8);
+ }
+ rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES);
+ rkisp1_write(params->rkisp1, arg->var_shift,
+ RKISP1_CIF_ISP_AFM_VAR_SHIFT);
+ /* restore afm status */
+ rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
+}
+
+static void rkisp1_ie_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_ie_config *arg)
+{
+ u32 eff_ctrl;
+
+ eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL);
+ eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK;
+
+ if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL;
+
+ switch (arg->effect) {
+ case V4L2_COLORFX_SEPIA:
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
+ break;
+ case V4L2_COLORFX_SET_CBCR:
+ rkisp1_write(params->rkisp1, arg->eff_tint,
+ RKISP1_CIF_IMG_EFF_TINT);
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
+ break;
+ /*
+ * Color selection is similar to water color(AQUA):
+ * grayscale + selected color w threshold
+ */
+ case V4L2_COLORFX_AQUA:
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL;
+ rkisp1_write(params->rkisp1, arg->color_sel,
+ RKISP1_CIF_IMG_EFF_COLOR_SEL);
+ break;
+ case V4L2_COLORFX_EMBOSS:
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS;
+ rkisp1_write(params->rkisp1, arg->eff_mat_1,
+ RKISP1_CIF_IMG_EFF_MAT_1);
+ rkisp1_write(params->rkisp1, arg->eff_mat_2,
+ RKISP1_CIF_IMG_EFF_MAT_2);
+ rkisp1_write(params->rkisp1, arg->eff_mat_3,
+ RKISP1_CIF_IMG_EFF_MAT_3);
+ break;
+ case V4L2_COLORFX_SKETCH:
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH;
+ rkisp1_write(params->rkisp1, arg->eff_mat_3,
+ RKISP1_CIF_IMG_EFF_MAT_3);
+ rkisp1_write(params->rkisp1, arg->eff_mat_4,
+ RKISP1_CIF_IMG_EFF_MAT_4);
+ rkisp1_write(params->rkisp1, arg->eff_mat_5,
+ RKISP1_CIF_IMG_EFF_MAT_5);
+ break;
+ case V4L2_COLORFX_BW:
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE;
+ break;
+ case V4L2_COLORFX_NEGATIVE:
+ eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE;
+ break;
+ default:
+ break;
+ }
+
+ rkisp1_write(params->rkisp1, eff_ctrl, RKISP1_CIF_IMG_EFF_CTRL);
+}
+
+static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
+{
+ if (en) {
+ rkisp1_param_set_bits(params, RKISP1_CIF_ICCL,
+ RKISP1_CIF_ICCL_IE_CLK);
+ rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL_ENABLE,
+ RKISP1_CIF_IMG_EFF_CTRL);
+ rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
+ RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD);
+ } else {
+ rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
+ RKISP1_CIF_IMG_EFF_CTRL_ENABLE);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ICCL,
+ RKISP1_CIF_ICCL_IE_CLK);
+ }
+}
+
+static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
+{
+ static const u16 full_range_coeff[] = {
+ 0x0026, 0x004b, 0x000f,
+ 0x01ea, 0x01d6, 0x0040,
+ 0x0040, 0x01ca, 0x01f6
+ };
+ static const u16 limited_range_coeff[] = {
+ 0x0021, 0x0040, 0x000d,
+ 0x01ed, 0x01db, 0x0038,
+ 0x0038, 0x01d1, 0x01f7,
+ };
+ unsigned int i;
+
+ if (full_range) {
+ for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++)
+ rkisp1_write(params->rkisp1, full_range_coeff[i],
+ RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
+
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
+ RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
+ } else {
+ for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++)
+ rkisp1_write(params->rkisp1, limited_range_coeff[i],
+ RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
+
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
+ RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
+ }
+}
+
+/* ISP De-noise Pre-Filter(DPF) function */
+static void rkisp1_dpf_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_dpf_config *arg)
+{
+ unsigned int isp_dpf_mode, spatial_coeff, i;
+
+ switch (arg->gain.mode) {
+ case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS:
+ isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
+ RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
+ break;
+ case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:
+ isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
+ break;
+ case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS:
+ isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
+ RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP |
+ RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
+ break;
+ case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS:
+ isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
+ break;
+ case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS:
+ isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP |
+ RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
+ break;
+ case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED:
+ default:
+ isp_dpf_mode = 0;
+ break;
+ }
+
+ if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)
+ isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION;
+ if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9)
+ isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9;
+ if (!arg->rb_flt.r_enable)
+ isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS;
+ if (!arg->rb_flt.b_enable)
+ isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS;
+ if (!arg->g_flt.gb_enable)
+ isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS;
+ if (!arg->g_flt.gr_enable)
+ isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS;
+
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,
+ isp_dpf_mode);
+ rkisp1_write(params->rkisp1, arg->gain.nf_b_gain,
+ RKISP1_CIF_ISP_DPF_NF_GAIN_B);
+ rkisp1_write(params->rkisp1, arg->gain.nf_r_gain,
+ RKISP1_CIF_ISP_DPF_NF_GAIN_R);
+ rkisp1_write(params->rkisp1, arg->gain.nf_gb_gain,
+ RKISP1_CIF_ISP_DPF_NF_GAIN_GB);
+ rkisp1_write(params->rkisp1, arg->gain.nf_gr_gain,
+ RKISP1_CIF_ISP_DPF_NF_GAIN_GR);
+
+ for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) {
+ rkisp1_write(params->rkisp1, arg->nll.coeff[i],
+ RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4);
+ }
+
+ spatial_coeff = arg->g_flt.spatial_coeff[0] |
+ (arg->g_flt.spatial_coeff[1] << 8) |
+ (arg->g_flt.spatial_coeff[2] << 16) |
+ (arg->g_flt.spatial_coeff[3] << 24);
+ rkisp1_write(params->rkisp1, spatial_coeff,
+ RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4);
+
+ spatial_coeff = arg->g_flt.spatial_coeff[4] |
+ (arg->g_flt.spatial_coeff[5] << 8);
+ rkisp1_write(params->rkisp1, spatial_coeff,
+ RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6);
+
+ spatial_coeff = arg->rb_flt.spatial_coeff[0] |
+ (arg->rb_flt.spatial_coeff[1] << 8) |
+ (arg->rb_flt.spatial_coeff[2] << 16) |
+ (arg->rb_flt.spatial_coeff[3] << 24);
+ rkisp1_write(params->rkisp1, spatial_coeff,
+ RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4);
+
+ spatial_coeff = arg->rb_flt.spatial_coeff[4] |
+ (arg->rb_flt.spatial_coeff[5] << 8);
+ rkisp1_write(params->rkisp1, spatial_coeff,
+ RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6);
+}
+
+static void
+rkisp1_dpf_strength_config(struct rkisp1_params *params,
+ const struct rkisp1_cif_isp_dpf_strength_config *arg)
+{
+ rkisp1_write(params->rkisp1, arg->b, RKISP1_CIF_ISP_DPF_STRENGTH_B);
+ rkisp1_write(params->rkisp1, arg->g, RKISP1_CIF_ISP_DPF_STRENGTH_G);
+ rkisp1_write(params->rkisp1, arg->r, RKISP1_CIF_ISP_DPF_STRENGTH_R);
+}
+
+static void
+rkisp1_isp_isr_other_config(struct rkisp1_params *params,
+ const struct rkisp1_params_cfg *new_params)
+{
+ unsigned int module_en_update, module_cfg_update, module_ens;
+
+ module_en_update = new_params->module_en_update;
+ module_cfg_update = new_params->module_cfg_update;
+ module_ens = new_params->module_ens;
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)) {
+ /*update dpc config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)
+ rkisp1_dpcc_config(params,
+ &new_params->others.dpcc_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_DPCC_MODE,
+ RKISP1_CIF_ISP_DPCC_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_DPCC_MODE,
+ RKISP1_CIF_ISP_DPCC_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_BLS) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)) {
+ /* update bls config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)
+ rkisp1_bls_config(params,
+ &new_params->others.bls_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_BLS)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_BLS_CTRL,
+ RKISP1_CIF_ISP_BLS_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_BLS_CTRL,
+ RKISP1_CIF_ISP_BLS_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_SDG) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)) {
+ /* update sdg config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)
+ rkisp1_sdg_config(params,
+ &new_params->others.sdg_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_SDG)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_LSC) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)) {
+ /* update lsc config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)
+ rkisp1_lsc_config(params,
+ &new_params->others.lsc_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_LSC)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_LSC_CTRL,
+ RKISP1_CIF_ISP_LSC_CTRL_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_LSC_CTRL,
+ RKISP1_CIF_ISP_LSC_CTRL_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)) {
+ /* update awb gains */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
+ rkisp1_awb_gain_config(params,
+ &new_params->others.awb_gain_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_BDM) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)) {
+ /* update bdm config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)
+ rkisp1_bdm_config(params,
+ &new_params->others.bdm_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_BDM)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_DEMOSAIC,
+ RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_DEMOSAIC,
+ RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_FLT) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)) {
+ /* update filter config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)
+ rkisp1_flt_config(params,
+ &new_params->others.flt_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_FLT)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_FILT_MODE,
+ RKISP1_CIF_ISP_FLT_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_FILT_MODE,
+ RKISP1_CIF_ISP_FLT_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_CTK) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)) {
+ /* update ctk config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)
+ rkisp1_ctk_config(params,
+ &new_params->others.ctk_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK)
+ rkisp1_ctk_enable(params,
+ !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK));
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_GOC) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)) {
+ /* update goc config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)
+ rkisp1_goc_config(params,
+ &new_params->others.goc_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_GOC)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)) {
+ /* update cproc config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC) {
+ rkisp1_cproc_config(params,
+ &new_params->others.cproc_config);
+ }
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_CPROC)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_C_PROC_CTRL,
+ RKISP1_CIF_C_PROC_CTR_ENABLE);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_C_PROC_CTRL,
+ RKISP1_CIF_C_PROC_CTR_ENABLE);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_IE) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)) {
+ /* update ie config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)
+ rkisp1_ie_config(params,
+ &new_params->others.ie_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_IE)
+ rkisp1_ie_enable(params,
+ !!(module_ens & RKISP1_CIF_ISP_MODULE_IE));
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)) {
+ /* update dpf config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)
+ rkisp1_dpf_config(params,
+ &new_params->others.dpf_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_DPF)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_DPF_MODE,
+ RKISP1_CIF_ISP_DPF_MODE_EN);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_DPF_MODE,
+ RKISP1_CIF_ISP_DPF_MODE_EN);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) {
+ /* update dpf strength config */
+ rkisp1_dpf_strength_config(params,
+ &new_params->others.dpf_strength_config);
+ }
+}
+
+static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params,
+ struct rkisp1_params_cfg *new_params)
+{
+ unsigned int module_en_update, module_cfg_update, module_ens;
+
+ module_en_update = new_params->module_en_update;
+ module_cfg_update = new_params->module_cfg_update;
+ module_ens = new_params->module_ens;
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)) {
+ /* update awb config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)
+ rkisp1_awb_meas_config(params,
+ &new_params->meas.awb_meas_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB)
+ rkisp1_awb_meas_enable(params,
+ &new_params->meas.awb_meas_config,
+ !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB));
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_AFC) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)) {
+ /* update afc config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)
+ rkisp1_afm_config(params,
+ &new_params->meas.afc_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_AFC)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_AFM_CTRL,
+ RKISP1_CIF_ISP_AFM_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_AFM_CTRL,
+ RKISP1_CIF_ISP_AFM_ENA);
+ }
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_HST) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)) {
+ /* update hst config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)
+ rkisp1_hst_config(params,
+ &new_params->meas.hst_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_HST)
+ rkisp1_hst_enable(params,
+ &new_params->meas.hst_config,
+ !!(module_ens & RKISP1_CIF_ISP_MODULE_HST));
+ }
+
+ if ((module_en_update & RKISP1_CIF_ISP_MODULE_AEC) ||
+ (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)) {
+ /* update aec config */
+ if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)
+ rkisp1_aec_config(params,
+ &new_params->meas.aec_config);
+
+ if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) {
+ if (module_ens & RKISP1_CIF_ISP_MODULE_AEC)
+ rkisp1_param_set_bits(params,
+ RKISP1_CIF_ISP_EXP_CTRL,
+ RKISP1_CIF_ISP_EXP_ENA);
+ else
+ rkisp1_param_clear_bits(params,
+ RKISP1_CIF_ISP_EXP_CTRL,
+ RKISP1_CIF_ISP_EXP_ENA);
+ }
+ }
+}
+
+static void rkisp1_params_apply_params_cfg(struct rkisp1_params *params,
+ unsigned int frame_sequence)
+{
+ struct rkisp1_params_cfg *new_params;
+ struct rkisp1_buffer *cur_buf = NULL;
+
+ if (list_empty(¶ms->params))
+ return;
+
+ cur_buf = list_first_entry(¶ms->params,
+ struct rkisp1_buffer, queue);
+
+ new_params = (struct rkisp1_params_cfg *)(cur_buf->vaddr);
+
+ rkisp1_isp_isr_other_config(params, new_params);
+ rkisp1_isp_isr_meas_config(params, new_params);
+
+ /* update shadow register immediately */
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
+
+ list_del(&cur_buf->queue);
+
+ cur_buf->vb.sequence = frame_sequence;
+ vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+}
+
+void rkisp1_params_isr(struct rkisp1_device *rkisp1)
+{
+ /*
+ * This isr is called when the ISR finishes processing a frame (RKISP1_CIF_ISP_FRAME).
+ * Configurations performed here will be applied on the next frame.
+ * Since frame_sequence is updated on the vertical sync signal, we should use
+ * frame_sequence + 1 here to indicate to userspace on which frame these parameters
+ * are being applied.
+ */
+ unsigned int frame_sequence = rkisp1->isp.frame_sequence + 1;
+ struct rkisp1_params *params = &rkisp1->params;
+
+ spin_lock(¶ms->config_lock);
+ rkisp1_params_apply_params_cfg(params, frame_sequence);
+
+ spin_unlock(¶ms->config_lock);
+}
+
+static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = {
+ {
+ 0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT
+ },
+ RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128
+};
+
+static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = {
+ RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
+ RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0,
+ {
+ RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
+ RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
+ }
+};
+
+static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = {
+ RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
+ 3,
+ {
+ RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
+ RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
+ },
+ {
+ 0, /* To be filled in with 0x01 at runtime. */
+ }
+};
+
+static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = {
+ 1,
+ {
+ {
+ 300, 225, 200, 150
+ }
+ },
+ 4,
+ 14
+};
+
+static void rkisp1_params_config_parameter(struct rkisp1_params *params)
+{
+ struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config;
+
+ rkisp1_awb_meas_config(params, &rkisp1_awb_params_default_config);
+ rkisp1_awb_meas_enable(params, &rkisp1_awb_params_default_config,
+ true);
+
+ rkisp1_aec_config(params, &rkisp1_aec_params_default_config);
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
+ RKISP1_CIF_ISP_EXP_ENA);
+
+ rkisp1_afm_config(params, &rkisp1_afc_params_default_config);
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
+ RKISP1_CIF_ISP_AFM_ENA);
+
+ memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
+ rkisp1_hst_config(params, &hst);
+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
+ ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK |
+ rkisp1_hst_params_default_config.mode);
+
+ /* set the range */
+ if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ rkisp1_csm_config(params, true);
+ else
+ rkisp1_csm_config(params, false);
+
+ spin_lock_irq(¶ms->config_lock);
+
+ /* apply the first buffer if there is one already */
+ rkisp1_params_apply_params_cfg(params, 0);
+
+ spin_unlock_irq(¶ms->config_lock);
+}
+
+void rkisp1_params_configure(struct rkisp1_params *params,
+ enum rkisp1_fmt_raw_pat_type bayer_pat,
+ enum v4l2_quantization quantization)
+{
+ params->quantization = quantization;
+ params->raw_type = bayer_pat;
+ rkisp1_params_config_parameter(params);
+}
+
+/* Not called when the camera active, thus not isr protection. */
+void rkisp1_params_disable(struct rkisp1_params *params)
+{
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,
+ RKISP1_CIF_ISP_DPCC_ENA);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
+ RKISP1_CIF_ISP_LSC_CTRL_ENA);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,
+ RKISP1_CIF_ISP_BLS_ENA);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,
+ RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,
+ RKISP1_CIF_ISP_FLT_ENA);
+ rkisp1_awb_meas_enable(params, NULL, false);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
+ RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
+ RKISP1_CIF_ISP_EXP_ENA);
+ rkisp1_ctk_enable(params, false);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
+ RKISP1_CIF_C_PROC_CTR_ENABLE);
+ rkisp1_hst_enable(params, NULL, false);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
+ RKISP1_CIF_ISP_AFM_ENA);
+ rkisp1_ie_enable(params, false);
+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
+ RKISP1_CIF_ISP_DPF_MODE_EN);
+}
+
+static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct video_device *video = video_devdata(file);
+ struct rkisp1_params *params = video_get_drvdata(video);
+
+ if (f->index > 0 || f->type != video->queue->type)
+ return -EINVAL;
+
+ f->pixelformat = params->vdev_fmt.fmt.meta.dataformat;
+
+ return 0;
+}
+
+static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct video_device *video = video_devdata(file);
+ struct rkisp1_params *params = video_get_drvdata(video);
+ struct v4l2_meta_format *meta = &f->fmt.meta;
+
+ if (f->type != video->queue->type)
+ return -EINVAL;
+
+ memset(meta, 0, sizeof(*meta));
+ meta->dataformat = params->vdev_fmt.fmt.meta.dataformat;
+ meta->buffersize = params->vdev_fmt.fmt.meta.buffersize;
+
+ return 0;
+}
+
+static int rkisp1_params_querycap(struct file *file,
+ void *priv, struct v4l2_capability *cap)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
+ strscpy(cap->card, vdev->name, sizeof(cap->card));
+ strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
+
+ return 0;
+}
+
+/* ISP params video device IOCTLs */
+static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
+ .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
+ .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
+ .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
+ .vidioc_querycap = rkisp1_params_querycap,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
+ unsigned int *num_buffers,
+ unsigned int *num_planes,
+ unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ *num_buffers = clamp_t(u32, *num_buffers,
+ RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
+ RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
+
+ *num_planes = 1;
+
+ sizes[0] = sizeof(struct rkisp1_params_cfg);
+
+ return 0;
+}
+
+static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct rkisp1_buffer *params_buf =
+ container_of(vbuf, struct rkisp1_buffer, vb);
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct rkisp1_params *params = vq->drv_priv;
+
+ params_buf->vaddr = vb2_plane_vaddr(vb, 0);
+ spin_lock_irq(¶ms->config_lock);
+ list_add_tail(¶ms_buf->queue, ¶ms->params);
+ spin_unlock_irq(¶ms->config_lock);
+}
+
+static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+ if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
+ return -EINVAL;
+
+ vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
+
+ return 0;
+}
+
+static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)
+{
+ struct rkisp1_params *params = vq->drv_priv;
+ struct rkisp1_buffer *buf;
+ LIST_HEAD(tmp_list);
+
+ /*
+ * we first move the buffers into a local list 'tmp_list'
+ * and then we can iterate it and call vb2_buffer_done
+ * without holding the lock
+ */
+ spin_lock_irq(¶ms->config_lock);
+ list_splice_init(¶ms->params, &tmp_list);
+ spin_unlock_irq(¶ms->config_lock);
+
+ list_for_each_entry(buf, &tmp_list, queue)
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+}
+
+static struct vb2_ops rkisp1_params_vb2_ops = {
+ .queue_setup = rkisp1_params_vb2_queue_setup,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .buf_queue = rkisp1_params_vb2_buf_queue,
+ .buf_prepare = rkisp1_params_vb2_buf_prepare,
+ .stop_streaming = rkisp1_params_vb2_stop_streaming,
+
+};
+
+static struct v4l2_file_operations rkisp1_params_fops = {
+ .mmap = vb2_fop_mmap,
+ .unlocked_ioctl = video_ioctl2,
+ .poll = vb2_fop_poll,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release
+};
+
+static int rkisp1_params_init_vb2_queue(struct vb2_queue *q,
+ struct rkisp1_params *params)
+{
+ struct rkisp1_vdev_node *node;
+
+ node = container_of(q, struct rkisp1_vdev_node, buf_queue);
+
+ q->type = V4L2_BUF_TYPE_META_OUTPUT;
+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+ q->drv_priv = params;
+ q->ops = &rkisp1_params_vb2_ops;
+ q->mem_ops = &vb2_vmalloc_memops;
+ q->buf_struct_size = sizeof(struct rkisp1_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &node->vlock;
+
+ return vb2_queue_init(q);
+}
+
+static void rkisp1_init_params(struct rkisp1_params *params)
+{
+ params->vdev_fmt.fmt.meta.dataformat =
+ V4L2_META_FMT_RK_ISP1_PARAMS;
+ params->vdev_fmt.fmt.meta.buffersize =
+ sizeof(struct rkisp1_params_cfg);
+}
+
+int rkisp1_params_register(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_params *params = &rkisp1->params;
+ struct rkisp1_vdev_node *node = ¶ms->vnode;
+ struct video_device *vdev = &node->vdev;
+ int ret;
+
+ params->rkisp1 = rkisp1;
+ mutex_init(&node->vlock);
+ INIT_LIST_HEAD(¶ms->params);
+ spin_lock_init(¶ms->config_lock);
+
+ strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name));
+
+ video_set_drvdata(vdev, params);
+ vdev->ioctl_ops = &rkisp1_params_ioctl;
+ vdev->fops = &rkisp1_params_fops;
+ vdev->release = video_device_release_empty;
+ /*
+ * Provide a mutex to v4l2 core. It will be used
+ * to protect all fops and v4l2 ioctls.
+ */
+ vdev->lock = &node->vlock;
+ vdev->v4l2_dev = &rkisp1->v4l2_dev;
+ vdev->queue = &node->buf_queue;
+ vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
+ vdev->vfl_dir = VFL_DIR_TX;
+ rkisp1_params_init_vb2_queue(vdev->queue, params);
+ rkisp1_init_params(params);
+ video_set_drvdata(vdev, params);
+
+ node->pad.flags = MEDIA_PAD_FL_SOURCE;
+ ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
+ if (ret)
+ return ret;
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(rkisp1->dev,
+ "failed to register %s, ret=%d\n", vdev->name, ret);
+ goto err_cleanup_media_entity;
+ }
+ return 0;
+err_cleanup_media_entity:
+ media_entity_cleanup(&vdev->entity);
+ return ret;
+}
+
+void rkisp1_params_unregister(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_params *params = &rkisp1->params;
+ struct rkisp1_vdev_node *node = ¶ms->vnode;
+ struct video_device *vdev = &node->vdev;
+
+ vb2_video_unregister_device(vdev);
+ media_entity_cleanup(&vdev->entity);
+}
--- /dev/null
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Rockchip ISP1 Driver - Registers header
+ *
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _RKISP1_REGS_H
+#define _RKISP1_REGS_H
+
+/* ISP_CTRL */
+#define RKISP1_CIF_ISP_CTRL_ISP_ENABLE BIT(0)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT (0 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656 BIT(1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601 (2 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601 (3 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_DATA_MODE (4 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656 (5 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656 (6 << 1)
+#define RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE BIT(4)
+#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA BIT(6)
+#define RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA BIT(7)
+#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT BIT(8)
+#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD BIT(9)
+#define RKISP1_CIF_ISP_CTRL_ISP_GEN_CFG_UPD BIT(10)
+#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA BIT(11)
+#define RKISP1_CIF_ISP_CTRL_ISP_FLASH_MODE_ENA BIT(12)
+#define RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA BIT(13)
+#define RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA BIT(14)
+
+/* ISP_ACQ_PROP */
+#define RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE BIT(0)
+#define RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW BIT(1)
+#define RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW BIT(2)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_RGGB (0 << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GRBG BIT(3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GBRG (2 << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_BGGR (3 << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(pat) ((pat) << 3)
+#define RKISP1_CIF_ISP_ACQ_PROP_YCBYCR (0 << 7)
+#define RKISP1_CIF_ISP_ACQ_PROP_YCRYCB BIT(7)
+#define RKISP1_CIF_ISP_ACQ_PROP_CBYCRY (2 << 7)
+#define RKISP1_CIF_ISP_ACQ_PROP_CRYCBY (3 << 7)
+#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL (0 << 9)
+#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_EVEN BIT(9)
+#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ODD (2 << 9)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B (0 << 12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO BIT(12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_MSB (2 << 12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO (3 << 12)
+#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_MSB (4 << 12)
+
+/* VI_DPCL */
+#define RKISP1_CIF_VI_DPCL_DMA_JPEG (0 << 0)
+#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI BIT(0)
+#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_JPEG (2 << 0)
+#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MP BIT(2)
+#define RKISP1_CIF_VI_DPCL_CHAN_MODE_SP (2 << 2)
+#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MPSP (3 << 2)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_SPMUX (0 << 4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_SI BIT(4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_IE (2 << 4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_JPEG (3 << 4)
+#define RKISP1_CIF_VI_DPCL_DMA_SW_ISP (4 << 4)
+#define RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL (0 << 8)
+#define RKISP1_CIF_VI_DPCL_IF_SEL_SMIA BIT(8)
+#define RKISP1_CIF_VI_DPCL_IF_SEL_MIPI (2 << 8)
+#define RKISP1_CIF_VI_DPCL_DMA_IE_MUX_DMA BIT(10)
+#define RKISP1_CIF_VI_DPCL_DMA_SP_MUX_DMA BIT(11)
+
+/* ISP_IMSC - ISP_MIS - ISP_RIS - ISP_ICR - ISP_ISR */
+#define RKISP1_CIF_ISP_OFF BIT(0)
+#define RKISP1_CIF_ISP_FRAME BIT(1)
+#define RKISP1_CIF_ISP_DATA_LOSS BIT(2)
+#define RKISP1_CIF_ISP_PIC_SIZE_ERROR BIT(3)
+#define RKISP1_CIF_ISP_AWB_DONE BIT(4)
+#define RKISP1_CIF_ISP_FRAME_IN BIT(5)
+#define RKISP1_CIF_ISP_V_START BIT(6)
+#define RKISP1_CIF_ISP_H_START BIT(7)
+#define RKISP1_CIF_ISP_FLASH_ON BIT(8)
+#define RKISP1_CIF_ISP_FLASH_OFF BIT(9)
+#define RKISP1_CIF_ISP_SHUTTER_ON BIT(10)
+#define RKISP1_CIF_ISP_SHUTTER_OFF BIT(11)
+#define RKISP1_CIF_ISP_AFM_SUM_OF BIT(12)
+#define RKISP1_CIF_ISP_AFM_LUM_OF BIT(13)
+#define RKISP1_CIF_ISP_AFM_FIN BIT(14)
+#define RKISP1_CIF_ISP_HIST_MEASURE_RDY BIT(15)
+#define RKISP1_CIF_ISP_FLASH_CAP BIT(17)
+#define RKISP1_CIF_ISP_EXP_END BIT(18)
+#define RKISP1_CIF_ISP_VSM_END BIT(19)
+
+/* ISP_ERR */
+#define RKISP1_CIF_ISP_ERR_INFORM_SIZE BIT(0)
+#define RKISP1_CIF_ISP_ERR_IS_SIZE BIT(1)
+#define RKISP1_CIF_ISP_ERR_OUTFORM_SIZE BIT(2)
+
+/* MI_CTRL */
+#define RKISP1_CIF_MI_CTRL_MP_ENABLE BIT(0)
+#define RKISP1_CIF_MI_CTRL_SP_ENABLE (2 << 0)
+#define RKISP1_CIF_MI_CTRL_JPEG_ENABLE (4 << 0)
+#define RKISP1_CIF_MI_CTRL_RAW_ENABLE (8 << 0)
+#define RKISP1_CIF_MI_CTRL_HFLIP BIT(4)
+#define RKISP1_CIF_MI_CTRL_VFLIP BIT(5)
+#define RKISP1_CIF_MI_CTRL_ROT BIT(6)
+#define RKISP1_CIF_MI_BYTE_SWAP BIT(7)
+#define RKISP1_CIF_MI_SP_Y_FULL_YUV2RGB BIT(8)
+#define RKISP1_CIF_MI_SP_CBCR_FULL_YUV2RGB BIT(9)
+#define RKISP1_CIF_MI_SP_422NONCOSITEED BIT(10)
+#define RKISP1_CIF_MI_MP_PINGPONG_ENABEL BIT(11)
+#define RKISP1_CIF_MI_SP_PINGPONG_ENABEL BIT(12)
+#define RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE BIT(13)
+#define RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE BIT(14)
+#define RKISP1_CIF_MI_LAST_PIXEL_SIG_ENABLE BIT(15)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_16 (0 << 16)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_32 BIT(16)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64 (2 << 16)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_16 (0 << 18)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_32 BIT(18)
+#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64 (2 << 18)
+#define RKISP1_CIF_MI_CTRL_INIT_BASE_EN BIT(20)
+#define RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN BIT(21)
+#define RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8 (0 << 22)
+#define RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA BIT(22)
+#define RKISP1_MI_CTRL_MP_WRITE_YUVINT (2 << 22)
+#define RKISP1_MI_CTRL_MP_WRITE_RAW12 (2 << 22)
+#define RKISP1_MI_CTRL_SP_WRITE_PLA (0 << 24)
+#define RKISP1_MI_CTRL_SP_WRITE_SPLA BIT(24)
+#define RKISP1_MI_CTRL_SP_WRITE_INT (2 << 24)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV400 (0 << 26)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV420 BIT(26)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV422 (2 << 26)
+#define RKISP1_MI_CTRL_SP_INPUT_YUV444 (3 << 26)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV400 (0 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV420 BIT(28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV422 (2 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_YUV444 (3 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_RGB565 (4 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_RGB666 (5 << 28)
+#define RKISP1_MI_CTRL_SP_OUTPUT_RGB888 (6 << 28)
+
+#define RKISP1_MI_CTRL_MP_FMT_MASK GENMASK(23, 22)
+#define RKISP1_MI_CTRL_SP_FMT_MASK GENMASK(30, 24)
+
+/* MI_INIT */
+#define RKISP1_CIF_MI_INIT_SKIP BIT(2)
+#define RKISP1_CIF_MI_INIT_SOFT_UPD BIT(4)
+
+/* MI_CTRL_SHD */
+#define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED BIT(0)
+#define RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED BIT(1)
+#define RKISP1_CIF_MI_CTRL_SHD_JPEG_IN_ENABLED BIT(2)
+#define RKISP1_CIF_MI_CTRL_SHD_RAW_IN_ENABLED BIT(3)
+#define RKISP1_CIF_MI_CTRL_SHD_MP_OUT_ENABLED BIT(16)
+#define RKISP1_CIF_MI_CTRL_SHD_SP_OUT_ENABLED BIT(17)
+#define RKISP1_CIF_MI_CTRL_SHD_JPEG_OUT_ENABLED BIT(18)
+#define RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED BIT(19)
+
+/* RSZ_CTRL */
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE BIT(0)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE BIT(1)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE BIT(2)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE BIT(3)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP BIT(4)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP BIT(5)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP BIT(6)
+#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP BIT(7)
+#define RKISP1_CIF_RSZ_CTRL_CFG_UPD BIT(8)
+#define RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO BIT(9)
+#define RKISP1_CIF_RSZ_SCALER_FACTOR BIT(16)
+
+/* MI_IMSC - MI_MIS - MI_RIS - MI_ICR - MI_ISR */
+#define RKISP1_CIF_MI_FRAME(stream) BIT((stream)->id)
+#define RKISP1_CIF_MI_MBLK_LINE BIT(2)
+#define RKISP1_CIF_MI_FILL_MP_Y BIT(3)
+#define RKISP1_CIF_MI_WRAP_MP_Y BIT(4)
+#define RKISP1_CIF_MI_WRAP_MP_CB BIT(5)
+#define RKISP1_CIF_MI_WRAP_MP_CR BIT(6)
+#define RKISP1_CIF_MI_WRAP_SP_Y BIT(7)
+#define RKISP1_CIF_MI_WRAP_SP_CB BIT(8)
+#define RKISP1_CIF_MI_WRAP_SP_CR BIT(9)
+#define RKISP1_CIF_MI_DMA_READY BIT(11)
+
+/* MI_STATUS */
+#define RKISP1_CIF_MI_STATUS_MP_Y_FIFO_FULL BIT(0)
+#define RKISP1_CIF_MI_STATUS_SP_Y_FIFO_FULL BIT(4)
+
+/* MI_DMA_CTRL */
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_16 (0 << 0)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_32 BIT(0)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_64 (2 << 0)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_16 (0 << 2)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_32 BIT(2)
+#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_64 (2 << 2)
+#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PLANAR (0 << 4)
+#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_SPLANAR BIT(4)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV400 (0 << 6)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV420 BIT(6)
+#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PACKED (2 << 4)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV422 (2 << 6)
+#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV444 (3 << 6)
+#define RKISP1_CIF_MI_DMA_CTRL_BYTE_SWAP BIT(8)
+#define RKISP1_CIF_MI_DMA_CTRL_CONTINUOUS_ENA BIT(9)
+#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_NO (0 << 12)
+#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_8BIT BIT(12)
+#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_16BIT (2 << 12)
+/* MI_DMA_START */
+#define RKISP1_CIF_MI_DMA_START_ENABLE BIT(0)
+/* MI_XTD_FORMAT_CTRL */
+#define RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP BIT(0)
+#define RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP BIT(1)
+#define RKISP1_CIF_MI_XTD_FMT_CTRL_DMA_CB_CR_SWAP BIT(2)
+
+/* CCL */
+#define RKISP1_CIF_CCL_CIF_CLK_DIS BIT(2)
+/* ICCL */
+#define RKISP1_CIF_ICCL_ISP_CLK BIT(0)
+#define RKISP1_CIF_ICCL_CP_CLK BIT(1)
+#define RKISP1_CIF_ICCL_RES_2 BIT(2)
+#define RKISP1_CIF_ICCL_MRSZ_CLK BIT(3)
+#define RKISP1_CIF_ICCL_SRSZ_CLK BIT(4)
+#define RKISP1_CIF_ICCL_JPEG_CLK BIT(5)
+#define RKISP1_CIF_ICCL_MI_CLK BIT(6)
+#define RKISP1_CIF_ICCL_RES_7 BIT(7)
+#define RKISP1_CIF_ICCL_IE_CLK BIT(8)
+#define RKISP1_CIF_ICCL_SIMP_CLK BIT(9)
+#define RKISP1_CIF_ICCL_SMIA_CLK BIT(10)
+#define RKISP1_CIF_ICCL_MIPI_CLK BIT(11)
+#define RKISP1_CIF_ICCL_DCROP_CLK BIT(12)
+/* IRCL */
+#define RKISP1_CIF_IRCL_ISP_SW_RST BIT(0)
+#define RKISP1_CIF_IRCL_CP_SW_RST BIT(1)
+#define RKISP1_CIF_IRCL_YCS_SW_RST BIT(2)
+#define RKISP1_CIF_IRCL_MRSZ_SW_RST BIT(3)
+#define RKISP1_CIF_IRCL_SRSZ_SW_RST BIT(4)
+#define RKISP1_CIF_IRCL_JPEG_SW_RST BIT(5)
+#define RKISP1_CIF_IRCL_MI_SW_RST BIT(6)
+#define RKISP1_CIF_IRCL_CIF_SW_RST BIT(7)
+#define RKISP1_CIF_IRCL_IE_SW_RST BIT(8)
+#define RKISP1_CIF_IRCL_SI_SW_RST BIT(9)
+#define RKISP1_CIF_IRCL_MIPI_SW_RST BIT(11)
+
+/* C_PROC_CTR */
+#define RKISP1_CIF_C_PROC_CTR_ENABLE BIT(0)
+#define RKISP1_CIF_C_PROC_YOUT_FULL BIT(1)
+#define RKISP1_CIF_C_PROC_YIN_FULL BIT(2)
+#define RKISP1_CIF_C_PROC_COUT_FULL BIT(3)
+#define RKISP1_CIF_C_PROC_CTRL_RESERVED 0xFFFFFFFE
+#define RKISP1_CIF_C_PROC_CONTRAST_RESERVED 0xFFFFFF00
+#define RKISP1_CIF_C_PROC_BRIGHTNESS_RESERVED 0xFFFFFF00
+#define RKISP1_CIF_C_PROC_HUE_RESERVED 0xFFFFFF00
+#define RKISP1_CIF_C_PROC_SATURATION_RESERVED 0xFFFFFF00
+#define RKISP1_CIF_C_PROC_MACC_RESERVED 0xE000E000
+#define RKISP1_CIF_C_PROC_TONE_RESERVED 0xF000
+/* DUAL_CROP_CTRL */
+#define RKISP1_CIF_DUAL_CROP_MP_MODE_BYPASS (0 << 0)
+#define RKISP1_CIF_DUAL_CROP_MP_MODE_YUV BIT(0)
+#define RKISP1_CIF_DUAL_CROP_MP_MODE_RAW (2 << 0)
+#define RKISP1_CIF_DUAL_CROP_SP_MODE_BYPASS (0 << 2)
+#define RKISP1_CIF_DUAL_CROP_SP_MODE_YUV BIT(2)
+#define RKISP1_CIF_DUAL_CROP_SP_MODE_RAW (2 << 2)
+#define RKISP1_CIF_DUAL_CROP_CFG_UPD_PERMANENT BIT(4)
+#define RKISP1_CIF_DUAL_CROP_CFG_UPD BIT(5)
+#define RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD BIT(6)
+
+/* IMG_EFF_CTRL */
+#define RKISP1_CIF_IMG_EFF_CTRL_ENABLE BIT(0)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE (0 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE BIT(1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA (2 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL (3 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS (4 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH (5 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN (6 << 1)
+#define RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD BIT(4)
+#define RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL BIT(5)
+
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE_SHIFT 0
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE_SHIFT 1
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA_SHIFT 2
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL_SHIFT 3
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS_SHIFT 4
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH_SHIFT 5
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN_SHIFT 6
+#define RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK 0xE
+
+/* IMG_EFF_COLOR_SEL */
+#define RKISP1_CIF_IMG_EFF_COLOR_RGB 0
+#define RKISP1_CIF_IMG_EFF_COLOR_B BIT(0)
+#define RKISP1_CIF_IMG_EFF_COLOR_G (2 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_GB (3 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_R (4 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_RB (5 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_RG (6 << 0)
+#define RKISP1_CIF_IMG_EFF_COLOR_RGB2 (7 << 0)
+
+/* MIPI_CTRL */
+#define RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA BIT(0)
+#define RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(a) (((a) & 0xF) << 8)
+#define RKISP1_CIF_MIPI_CTRL_NUM_LANES(a) (((a) & 0x3) << 12)
+#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_HS_SKIP BIT(16)
+#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP BIT(17)
+#define RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA BIT(18)
+
+/* MIPI_DATA_SEL */
+#define RKISP1_CIF_MIPI_DATA_SEL_VC(a) (((a) & 0x3) << 6)
+#define RKISP1_CIF_MIPI_DATA_SEL_DT(a) (((a) & 0x3F) << 0)
+/* MIPI DATA_TYPE */
+#define RKISP1_CIF_CSI2_DT_YUV420_8b 0x18
+#define RKISP1_CIF_CSI2_DT_YUV420_10b 0x19
+#define RKISP1_CIF_CSI2_DT_YUV422_8b 0x1E
+#define RKISP1_CIF_CSI2_DT_YUV422_10b 0x1F
+#define RKISP1_CIF_CSI2_DT_RGB565 0x22
+#define RKISP1_CIF_CSI2_DT_RGB666 0x23
+#define RKISP1_CIF_CSI2_DT_RGB888 0x24
+#define RKISP1_CIF_CSI2_DT_RAW8 0x2A
+#define RKISP1_CIF_CSI2_DT_RAW10 0x2B
+#define RKISP1_CIF_CSI2_DT_RAW12 0x2C
+
+/* MIPI_IMSC, MIPI_RIS, MIPI_MIS, MIPI_ICR, MIPI_ISR */
+#define RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(a) (((a) & 0xF) << 0)
+#define RKISP1_CIF_MIPI_ERR_SOT(a) (((a) & 0xF) << 4)
+#define RKISP1_CIF_MIPI_ERR_SOT_SYNC(a) (((a) & 0xF) << 8)
+#define RKISP1_CIF_MIPI_ERR_EOT_SYNC(a) (((a) & 0xF) << 12)
+#define RKISP1_CIF_MIPI_ERR_CTRL(a) (((a) & 0xF) << 16)
+#define RKISP1_CIF_MIPI_ERR_PROTOCOL BIT(20)
+#define RKISP1_CIF_MIPI_ERR_ECC1 BIT(21)
+#define RKISP1_CIF_MIPI_ERR_ECC2 BIT(22)
+#define RKISP1_CIF_MIPI_ERR_CS BIT(23)
+#define RKISP1_CIF_MIPI_FRAME_END BIT(24)
+#define RKISP1_CIF_MIPI_ADD_DATA_OVFLW BIT(25)
+#define RKISP1_CIF_MIPI_ADD_DATA_WATER_MARK BIT(26)
+
+#define RKISP1_CIF_MIPI_ERR_CSI (RKISP1_CIF_MIPI_ERR_PROTOCOL | \
+ RKISP1_CIF_MIPI_ERR_ECC1 | \
+ RKISP1_CIF_MIPI_ERR_ECC2 | \
+ RKISP1_CIF_MIPI_ERR_CS)
+
+#define RKISP1_CIF_MIPI_ERR_DPHY (RKISP1_CIF_MIPI_ERR_SOT(3) | \
+ RKISP1_CIF_MIPI_ERR_SOT_SYNC(3) | \
+ RKISP1_CIF_MIPI_ERR_EOT_SYNC(3) | \
+ RKISP1_CIF_MIPI_ERR_CTRL(3))
+
+/* SUPER_IMPOSE */
+#define RKISP1_CIF_SUPER_IMP_CTRL_NORMAL_MODE BIT(0)
+#define RKISP1_CIF_SUPER_IMP_CTRL_REF_IMG_MEM BIT(1)
+#define RKISP1_CIF_SUPER_IMP_CTRL_TRANSP_DIS BIT(2)
+
+/* ISP HISTOGRAM CALCULATION : ISP_HIST_PROP */
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_DIS (0 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_RGB BIT(0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_RED (2 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_GREEN (3 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_BLUE (4 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_LUM (5 << 0)
+#define RKISP1_CIF_ISP_HIST_PROP_MODE_MASK 0x7
+#define RKISP1_CIF_ISP_HIST_PREDIV_SET(x) (((x) & 0x7F) << 3)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_SET(v0, v1, v2, v3) \
+ (((v0) & 0x1F) | (((v1) & 0x1F) << 8) |\
+ (((v2) & 0x1F) << 16) | \
+ (((v3) & 0x1F) << 24))
+
+#define RKISP1_CIF_ISP_HIST_WINDOW_OFFSET_RESERVED 0xFFFFF000
+#define RKISP1_CIF_ISP_HIST_WINDOW_SIZE_RESERVED 0xFFFFF800
+#define RKISP1_CIF_ISP_HIST_WEIGHT_RESERVED 0xE0E0E0E0
+#define RKISP1_CIF_ISP_MAX_HIST_PREDIVIDER 0x0000007F
+#define RKISP1_CIF_ISP_HIST_ROW_NUM 5
+#define RKISP1_CIF_ISP_HIST_COLUMN_NUM 5
+
+/* AUTO FOCUS MEASUREMENT: ISP_AFM_CTRL */
+#define RKISP1_ISP_AFM_CTRL_ENABLE BIT(0)
+
+/* SHUTTER CONTROL */
+#define RKISP1_CIF_ISP_SH_CTRL_SH_ENA BIT(0)
+#define RKISP1_CIF_ISP_SH_CTRL_REP_EN BIT(1)
+#define RKISP1_CIF_ISP_SH_CTRL_SRC_SH_TRIG BIT(2)
+#define RKISP1_CIF_ISP_SH_CTRL_EDGE_POS BIT(3)
+#define RKISP1_CIF_ISP_SH_CTRL_POL_LOW BIT(4)
+
+/* FLASH MODULE */
+/* ISP_FLASH_CMD */
+#define RKISP1_CIFFLASH_CMD_PRELIGHT_ON BIT(0)
+#define RKISP1_CIFFLASH_CMD_FLASH_ON BIT(1)
+#define RKISP1_CIFFLASH_CMD_PRE_FLASH_ON BIT(2)
+/* ISP_FLASH_CONFIG */
+#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_END BIT(0)
+#define RKISP1_CIFFLASH_CONFIG_VSYNC_POS BIT(1)
+#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_LOW BIT(2)
+#define RKISP1_CIFFLASH_CONFIG_SRC_FL_TRIG BIT(3)
+#define RKISP1_CIFFLASH_CONFIG_DELAY(a) (((a) & 0xF) << 4)
+
+/* Demosaic: ISP_DEMOSAIC */
+#define RKISP1_CIF_ISP_DEMOSAIC_BYPASS BIT(10)
+#define RKISP1_CIF_ISP_DEMOSAIC_TH(x) ((x) & 0xFF)
+
+/* AWB */
+/* ISP_AWB_PROP */
+#define RKISP1_CIF_ISP_AWB_YMAX_CMP_EN BIT(2)
+#define RKISP1_CIF_ISP_AWB_YMAX_READ(x) (((x) >> 2) & 1)
+#define RKISP1_CIF_ISP_AWB_MODE_RGB_EN ((1 << 31) | (0x2 << 0))
+#define RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN ((0 << 31) | (0x2 << 0))
+#define RKISP1_CIF_ISP_AWB_MODE_MASK_NONE 0xFFFFFFFC
+#define RKISP1_CIF_ISP_AWB_MODE_READ(x) ((x) & 3)
+/* ISP_AWB_GAIN_RB, ISP_AWB_GAIN_G */
+#define RKISP1_CIF_ISP_AWB_GAIN_R_SET(x) (((x) & 0x3FF) << 16)
+#define RKISP1_CIF_ISP_AWB_GAIN_R_READ(x) (((x) >> 16) & 0x3FF)
+#define RKISP1_CIF_ISP_AWB_GAIN_B_SET(x) ((x) & 0x3FFF)
+#define RKISP1_CIF_ISP_AWB_GAIN_B_READ(x) ((x) & 0x3FFF)
+/* ISP_AWB_REF */
+#define RKISP1_CIF_ISP_AWB_REF_CR_SET(x) (((x) & 0xFF) << 8)
+#define RKISP1_CIF_ISP_AWB_REF_CR_READ(x) (((x) >> 8) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_REF_CB_READ(x) ((x) & 0xFF)
+/* ISP_AWB_THRESH */
+#define RKISP1_CIF_ISP_AWB_MAX_CS_SET(x) (((x) & 0xFF) << 8)
+#define RKISP1_CIF_ISP_AWB_MAX_CS_READ(x) (((x) >> 8) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_MIN_C_READ(x) ((x) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_MIN_Y_SET(x) (((x) & 0xFF) << 16)
+#define RKISP1_CIF_ISP_AWB_MIN_Y_READ(x) (((x) >> 16) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_MAX_Y_SET(x) (((x) & 0xFF) << 24)
+#define RKISP1_CIF_ISP_AWB_MAX_Y_READ(x) (((x) >> 24) & 0xFF)
+/* ISP_AWB_MEAN */
+#define RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(x) ((x) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(x) (((x) >> 8) & 0xFF)
+#define RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(x) (((x) >> 16) & 0xFF)
+/* ISP_AWB_WHITE_CNT */
+#define RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(x) ((x) & 0x3FFFFFF)
+
+#define RKISP1_CIF_ISP_AWB_GAINS_MAX_VAL 0x000003FF
+#define RKISP1_CIF_ISP_AWB_WINDOW_OFFSET_MAX 0x00000FFF
+#define RKISP1_CIF_ISP_AWB_WINDOW_MAX_SIZE 0x00001FFF
+#define RKISP1_CIF_ISP_AWB_CBCR_MAX_REF 0x000000FF
+#define RKISP1_CIF_ISP_AWB_THRES_MAX_YC 0x000000FF
+
+/* AE */
+/* ISP_EXP_CTRL */
+#define RKISP1_CIF_ISP_EXP_ENA BIT(0)
+#define RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP BIT(1)
+/*
+ *'1' luminance calculation according to Y=(R+G+B) x 0.332 (85/256)
+ *'0' luminance calculation according to Y=16+0.25R+0.5G+0.1094B
+ */
+#define RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1 BIT(31)
+
+/* ISP_EXP_H_SIZE */
+#define RKISP1_CIF_ISP_EXP_H_SIZE_SET(x) ((x) & 0x7FF)
+#define RKISP1_CIF_ISP_EXP_HEIGHT_MASK 0x000007FF
+/* ISP_EXP_V_SIZE : vertical size must be a multiple of 2). */
+#define RKISP1_CIF_ISP_EXP_V_SIZE_SET(x) ((x) & 0x7FE)
+
+/* ISP_EXP_H_OFFSET */
+#define RKISP1_CIF_ISP_EXP_H_OFFSET_SET(x) ((x) & 0x1FFF)
+#define RKISP1_CIF_ISP_EXP_MAX_HOFFS 2424
+/* ISP_EXP_V_OFFSET */
+#define RKISP1_CIF_ISP_EXP_V_OFFSET_SET(x) ((x) & 0x1FFF)
+#define RKISP1_CIF_ISP_EXP_MAX_VOFFS 1806
+
+#define RKISP1_CIF_ISP_EXP_ROW_NUM 5
+#define RKISP1_CIF_ISP_EXP_COLUMN_NUM 5
+#define RKISP1_CIF_ISP_EXP_NUM_LUMA_REGS \
+ (RKISP1_CIF_ISP_EXP_ROW_NUM * RKISP1_CIF_ISP_EXP_COLUMN_NUM)
+#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE 516
+#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE 35
+#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE 390
+#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE 28
+#define RKISP1_CIF_ISP_EXP_MAX_HSIZE \
+ (RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
+#define RKISP1_CIF_ISP_EXP_MIN_HSIZE \
+ (RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
+#define RKISP1_CIF_ISP_EXP_MAX_VSIZE \
+ (RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
+#define RKISP1_CIF_ISP_EXP_MIN_VSIZE \
+ (RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
+
+/* LSC: ISP_LSC_CTRL */
+#define RKISP1_CIF_ISP_LSC_CTRL_ENA BIT(0)
+#define RKISP1_CIF_ISP_LSC_SECT_SIZE_RESERVED 0xFC00FC00
+#define RKISP1_CIF_ISP_LSC_GRAD_RESERVED 0xF000F000
+#define RKISP1_CIF_ISP_LSC_SAMPLE_RESERVED 0xF000F000
+#define RKISP1_CIF_ISP_LSC_TABLE_DATA(v0, v1) \
+ (((v0) & 0xFFF) | (((v1) & 0xFFF) << 12))
+#define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1) \
+ (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+#define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1) \
+ (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+
+/* LSC: ISP_LSC_TABLE_SEL */
+#define RKISP1_CIF_ISP_LSC_TABLE_0 0
+#define RKISP1_CIF_ISP_LSC_TABLE_1 1
+
+/* LSC: ISP_LSC_STATUS */
+#define RKISP1_CIF_ISP_LSC_ACTIVE_TABLE BIT(1)
+#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 0
+#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 153
+
+/* FLT */
+/* ISP_FILT_MODE */
+#define RKISP1_CIF_ISP_FLT_ENA BIT(0)
+
+/*
+ * 0: green filter static mode (active filter factor = FILT_FAC_MID)
+ * 1: dynamic noise reduction/sharpen Default
+ */
+#define RKISP1_CIF_ISP_FLT_MODE_DNR BIT(1)
+#define RKISP1_CIF_ISP_FLT_MODE_MAX 1
+#define RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(x) (((x) & 0x3) << 4)
+#define RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(x) (((x) & 0x3) << 6)
+#define RKISP1_CIF_ISP_FLT_CHROMA_MODE_MAX 3
+#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1(x) (((x) & 0xF) << 8)
+#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1_MAX 8
+#define RKISP1_CIF_ISP_FLT_THREAD_RESERVED 0xFFFFFC00
+#define RKISP1_CIF_ISP_FLT_FAC_RESERVED 0xFFFFFFC0
+#define RKISP1_CIF_ISP_FLT_LUM_WEIGHT_RESERVED 0xFFF80000
+
+#define RKISP1_CIF_ISP_CTK_COEFF_RESERVED 0xFFFFF800
+#define RKISP1_CIF_ISP_XTALK_OFFSET_RESERVED 0xFFFFF000
+
+/* GOC */
+#define RKISP1_CIF_ISP_GAMMA_OUT_MODE_EQU BIT(0)
+#define RKISP1_CIF_ISP_GOC_MODE_MAX 1
+#define RKISP1_CIF_ISP_GOC_RESERVED 0xFFFFF800
+/* ISP_CTRL BIT 11*/
+#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA_READ(x) (((x) >> 11) & 1)
+
+/* DPCC */
+/* ISP_DPCC_MODE */
+#define RKISP1_CIF_ISP_DPCC_ENA BIT(0)
+#define RKISP1_CIF_ISP_DPCC_MODE_MAX 0x07
+#define RKISP1_CIF_ISP_DPCC_OUTPUTMODE_MAX 0x0F
+#define RKISP1_CIF_ISP_DPCC_SETUSE_MAX 0x0F
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_RESERVED 0xFFFFE000
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_RESERVED 0xFFFF0000
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RESERVED 0xFFFFC0C0
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_RESERVED 0xFFFFC0C0
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_RESERVED 0xFFFF0000
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_RESERVED 0xFFFFC0C0
+#define RKISP1_CIF_ISP_DPCC_RO_LIMIT_RESERVED 0xFFFFF000
+#define RKISP1_CIF_ISP_DPCC_RND_OFFS_RESERVED 0xFFFFF000
+
+/* BLS */
+/* ISP_BLS_CTRL */
+#define RKISP1_CIF_ISP_BLS_ENA BIT(0)
+#define RKISP1_CIF_ISP_BLS_MODE_MEASURED BIT(1)
+#define RKISP1_CIF_ISP_BLS_MODE_FIXED 0
+#define RKISP1_CIF_ISP_BLS_WINDOW_1 BIT(2)
+#define RKISP1_CIF_ISP_BLS_WINDOW_2 (2 << 2)
+
+/* GAMMA-IN */
+#define RKISP1_CIFISP_DEGAMMA_X_RESERVED \
+ ((1 << 31) | (1 << 27) | (1 << 23) | (1 << 19) |\
+ (1 << 15) | (1 << 11) | (1 << 7) | (1 << 3))
+#define RKISP1_CIFISP_DEGAMMA_Y_RESERVED 0xFFFFF000
+
+/* AFM */
+#define RKISP1_CIF_ISP_AFM_ENA BIT(0)
+#define RKISP1_CIF_ISP_AFM_THRES_RESERVED 0xFFFF0000
+#define RKISP1_CIF_ISP_AFM_VAR_SHIFT_RESERVED 0xFFF8FFF8
+#define RKISP1_CIF_ISP_AFM_WINDOW_X_RESERVED 0xE000
+#define RKISP1_CIF_ISP_AFM_WINDOW_Y_RESERVED 0xF000
+#define RKISP1_CIF_ISP_AFM_WINDOW_X_MIN 0x5
+#define RKISP1_CIF_ISP_AFM_WINDOW_Y_MIN 0x2
+#define RKISP1_CIF_ISP_AFM_WINDOW_X(x) (((x) & 0x1FFF) << 16)
+#define RKISP1_CIF_ISP_AFM_WINDOW_Y(x) ((x) & 0x1FFF)
+
+/* DPF */
+#define RKISP1_CIF_ISP_DPF_MODE_EN BIT(0)
+#define RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS BIT(1)
+#define RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS BIT(2)
+#define RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS BIT(3)
+#define RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS BIT(4)
+#define RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9 BIT(5)
+#define RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION BIT(6)
+#define RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP BIT(7)
+#define RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP BIT(8)
+#define RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN BIT(9)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_RESERVED 0xFFFFF000
+#define RKISP1_CIF_ISP_DPF_SPATIAL_COEFF_MAX 0x1F
+#define RKISP1_CIF_ISP_DPF_NLL_COEFF_N_MAX 0x3FF
+
+/* =================================================================== */
+/* CIF Registers */
+/* =================================================================== */
+#define RKISP1_CIF_CTRL_BASE 0x00000000
+#define RKISP1_CIF_CCL (RKISP1_CIF_CTRL_BASE + 0x00000000)
+#define RKISP1_CIF_VI_ID (RKISP1_CIF_CTRL_BASE + 0x00000008)
+#define RKISP1_CIF_ICCL (RKISP1_CIF_CTRL_BASE + 0x00000010)
+#define RKISP1_CIF_IRCL (RKISP1_CIF_CTRL_BASE + 0x00000014)
+#define RKISP1_CIF_VI_DPCL (RKISP1_CIF_CTRL_BASE + 0x00000018)
+
+#define RKISP1_CIF_IMG_EFF_BASE 0x00000200
+#define RKISP1_CIF_IMG_EFF_CTRL (RKISP1_CIF_IMG_EFF_BASE + 0x00000000)
+#define RKISP1_CIF_IMG_EFF_COLOR_SEL (RKISP1_CIF_IMG_EFF_BASE + 0x00000004)
+#define RKISP1_CIF_IMG_EFF_MAT_1 (RKISP1_CIF_IMG_EFF_BASE + 0x00000008)
+#define RKISP1_CIF_IMG_EFF_MAT_2 (RKISP1_CIF_IMG_EFF_BASE + 0x0000000C)
+#define RKISP1_CIF_IMG_EFF_MAT_3 (RKISP1_CIF_IMG_EFF_BASE + 0x00000010)
+#define RKISP1_CIF_IMG_EFF_MAT_4 (RKISP1_CIF_IMG_EFF_BASE + 0x00000014)
+#define RKISP1_CIF_IMG_EFF_MAT_5 (RKISP1_CIF_IMG_EFF_BASE + 0x00000018)
+#define RKISP1_CIF_IMG_EFF_TINT (RKISP1_CIF_IMG_EFF_BASE + 0x0000001C)
+#define RKISP1_CIF_IMG_EFF_CTRL_SHD (RKISP1_CIF_IMG_EFF_BASE + 0x00000020)
+#define RKISP1_CIF_IMG_EFF_SHARPEN (RKISP1_CIF_IMG_EFF_BASE + 0x00000024)
+
+#define RKISP1_CIF_SUPER_IMP_BASE 0x00000300
+#define RKISP1_CIF_SUPER_IMP_CTRL (RKISP1_CIF_SUPER_IMP_BASE + 0x00000000)
+#define RKISP1_CIF_SUPER_IMP_OFFSET_X (RKISP1_CIF_SUPER_IMP_BASE + 0x00000004)
+#define RKISP1_CIF_SUPER_IMP_OFFSET_Y (RKISP1_CIF_SUPER_IMP_BASE + 0x00000008)
+#define RKISP1_CIF_SUPER_IMP_COLOR_Y (RKISP1_CIF_SUPER_IMP_BASE + 0x0000000C)
+#define RKISP1_CIF_SUPER_IMP_COLOR_CB (RKISP1_CIF_SUPER_IMP_BASE + 0x00000010)
+#define RKISP1_CIF_SUPER_IMP_COLOR_CR (RKISP1_CIF_SUPER_IMP_BASE + 0x00000014)
+
+#define RKISP1_CIF_ISP_BASE 0x00000400
+#define RKISP1_CIF_ISP_CTRL (RKISP1_CIF_ISP_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_ACQ_PROP (RKISP1_CIF_ISP_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_ACQ_H_OFFS (RKISP1_CIF_ISP_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_ACQ_V_OFFS (RKISP1_CIF_ISP_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_ACQ_H_SIZE (RKISP1_CIF_ISP_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_ACQ_V_SIZE (RKISP1_CIF_ISP_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_ACQ_NR_FRAMES (RKISP1_CIF_ISP_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_GAMMA_DX_LO (RKISP1_CIF_ISP_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_GAMMA_DX_HI (RKISP1_CIF_ISP_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_GAMMA_R_Y0 (RKISP1_CIF_ISP_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_GAMMA_R_Y1 (RKISP1_CIF_ISP_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_GAMMA_R_Y2 (RKISP1_CIF_ISP_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y3 (RKISP1_CIF_ISP_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_GAMMA_R_Y4 (RKISP1_CIF_ISP_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_GAMMA_R_Y5 (RKISP1_CIF_ISP_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_GAMMA_R_Y6 (RKISP1_CIF_ISP_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y7 (RKISP1_CIF_ISP_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_GAMMA_R_Y8 (RKISP1_CIF_ISP_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_GAMMA_R_Y9 (RKISP1_CIF_ISP_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_GAMMA_R_Y10 (RKISP1_CIF_ISP_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y11 (RKISP1_CIF_ISP_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_GAMMA_R_Y12 (RKISP1_CIF_ISP_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_GAMMA_R_Y13 (RKISP1_CIF_ISP_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_GAMMA_R_Y14 (RKISP1_CIF_ISP_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_GAMMA_R_Y15 (RKISP1_CIF_ISP_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_GAMMA_R_Y16 (RKISP1_CIF_ISP_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_GAMMA_G_Y0 (RKISP1_CIF_ISP_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_GAMMA_G_Y1 (RKISP1_CIF_ISP_BASE + 0x0000006C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y2 (RKISP1_CIF_ISP_BASE + 0x00000070)
+#define RKISP1_CIF_ISP_GAMMA_G_Y3 (RKISP1_CIF_ISP_BASE + 0x00000074)
+#define RKISP1_CIF_ISP_GAMMA_G_Y4 (RKISP1_CIF_ISP_BASE + 0x00000078)
+#define RKISP1_CIF_ISP_GAMMA_G_Y5 (RKISP1_CIF_ISP_BASE + 0x0000007C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y6 (RKISP1_CIF_ISP_BASE + 0x00000080)
+#define RKISP1_CIF_ISP_GAMMA_G_Y7 (RKISP1_CIF_ISP_BASE + 0x00000084)
+#define RKISP1_CIF_ISP_GAMMA_G_Y8 (RKISP1_CIF_ISP_BASE + 0x00000088)
+#define RKISP1_CIF_ISP_GAMMA_G_Y9 (RKISP1_CIF_ISP_BASE + 0x0000008C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y10 (RKISP1_CIF_ISP_BASE + 0x00000090)
+#define RKISP1_CIF_ISP_GAMMA_G_Y11 (RKISP1_CIF_ISP_BASE + 0x00000094)
+#define RKISP1_CIF_ISP_GAMMA_G_Y12 (RKISP1_CIF_ISP_BASE + 0x00000098)
+#define RKISP1_CIF_ISP_GAMMA_G_Y13 (RKISP1_CIF_ISP_BASE + 0x0000009C)
+#define RKISP1_CIF_ISP_GAMMA_G_Y14 (RKISP1_CIF_ISP_BASE + 0x000000A0)
+#define RKISP1_CIF_ISP_GAMMA_G_Y15 (RKISP1_CIF_ISP_BASE + 0x000000A4)
+#define RKISP1_CIF_ISP_GAMMA_G_Y16 (RKISP1_CIF_ISP_BASE + 0x000000A8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y0 (RKISP1_CIF_ISP_BASE + 0x000000AC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y1 (RKISP1_CIF_ISP_BASE + 0x000000B0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y2 (RKISP1_CIF_ISP_BASE + 0x000000B4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y3 (RKISP1_CIF_ISP_BASE + 0x000000B8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y4 (RKISP1_CIF_ISP_BASE + 0x000000BC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y5 (RKISP1_CIF_ISP_BASE + 0x000000C0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y6 (RKISP1_CIF_ISP_BASE + 0x000000C4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y7 (RKISP1_CIF_ISP_BASE + 0x000000C8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y8 (RKISP1_CIF_ISP_BASE + 0x000000CC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y9 (RKISP1_CIF_ISP_BASE + 0x000000D0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y10 (RKISP1_CIF_ISP_BASE + 0x000000D4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y11 (RKISP1_CIF_ISP_BASE + 0x000000D8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y12 (RKISP1_CIF_ISP_BASE + 0x000000DC)
+#define RKISP1_CIF_ISP_GAMMA_B_Y13 (RKISP1_CIF_ISP_BASE + 0x000000E0)
+#define RKISP1_CIF_ISP_GAMMA_B_Y14 (RKISP1_CIF_ISP_BASE + 0x000000E4)
+#define RKISP1_CIF_ISP_GAMMA_B_Y15 (RKISP1_CIF_ISP_BASE + 0x000000E8)
+#define RKISP1_CIF_ISP_GAMMA_B_Y16 (RKISP1_CIF_ISP_BASE + 0x000000EC)
+#define RKISP1_CIF_ISP_AWB_PROP (RKISP1_CIF_ISP_BASE + 0x00000110)
+#define RKISP1_CIF_ISP_AWB_WND_H_OFFS (RKISP1_CIF_ISP_BASE + 0x00000114)
+#define RKISP1_CIF_ISP_AWB_WND_V_OFFS (RKISP1_CIF_ISP_BASE + 0x00000118)
+#define RKISP1_CIF_ISP_AWB_WND_H_SIZE (RKISP1_CIF_ISP_BASE + 0x0000011C)
+#define RKISP1_CIF_ISP_AWB_WND_V_SIZE (RKISP1_CIF_ISP_BASE + 0x00000120)
+#define RKISP1_CIF_ISP_AWB_FRAMES (RKISP1_CIF_ISP_BASE + 0x00000124)
+#define RKISP1_CIF_ISP_AWB_REF (RKISP1_CIF_ISP_BASE + 0x00000128)
+#define RKISP1_CIF_ISP_AWB_THRESH (RKISP1_CIF_ISP_BASE + 0x0000012C)
+#define RKISP1_CIF_ISP_AWB_GAIN_G (RKISP1_CIF_ISP_BASE + 0x00000138)
+#define RKISP1_CIF_ISP_AWB_GAIN_RB (RKISP1_CIF_ISP_BASE + 0x0000013C)
+#define RKISP1_CIF_ISP_AWB_WHITE_CNT (RKISP1_CIF_ISP_BASE + 0x00000140)
+#define RKISP1_CIF_ISP_AWB_MEAN (RKISP1_CIF_ISP_BASE + 0x00000144)
+#define RKISP1_CIF_ISP_CC_COEFF_0 (RKISP1_CIF_ISP_BASE + 0x00000170)
+#define RKISP1_CIF_ISP_CC_COEFF_1 (RKISP1_CIF_ISP_BASE + 0x00000174)
+#define RKISP1_CIF_ISP_CC_COEFF_2 (RKISP1_CIF_ISP_BASE + 0x00000178)
+#define RKISP1_CIF_ISP_CC_COEFF_3 (RKISP1_CIF_ISP_BASE + 0x0000017C)
+#define RKISP1_CIF_ISP_CC_COEFF_4 (RKISP1_CIF_ISP_BASE + 0x00000180)
+#define RKISP1_CIF_ISP_CC_COEFF_5 (RKISP1_CIF_ISP_BASE + 0x00000184)
+#define RKISP1_CIF_ISP_CC_COEFF_6 (RKISP1_CIF_ISP_BASE + 0x00000188)
+#define RKISP1_CIF_ISP_CC_COEFF_7 (RKISP1_CIF_ISP_BASE + 0x0000018C)
+#define RKISP1_CIF_ISP_CC_COEFF_8 (RKISP1_CIF_ISP_BASE + 0x00000190)
+#define RKISP1_CIF_ISP_OUT_H_OFFS (RKISP1_CIF_ISP_BASE + 0x00000194)
+#define RKISP1_CIF_ISP_OUT_V_OFFS (RKISP1_CIF_ISP_BASE + 0x00000198)
+#define RKISP1_CIF_ISP_OUT_H_SIZE (RKISP1_CIF_ISP_BASE + 0x0000019C)
+#define RKISP1_CIF_ISP_OUT_V_SIZE (RKISP1_CIF_ISP_BASE + 0x000001A0)
+#define RKISP1_CIF_ISP_DEMOSAIC (RKISP1_CIF_ISP_BASE + 0x000001A4)
+#define RKISP1_CIF_ISP_FLAGS_SHD (RKISP1_CIF_ISP_BASE + 0x000001A8)
+#define RKISP1_CIF_ISP_OUT_H_OFFS_SHD (RKISP1_CIF_ISP_BASE + 0x000001AC)
+#define RKISP1_CIF_ISP_OUT_V_OFFS_SHD (RKISP1_CIF_ISP_BASE + 0x000001B0)
+#define RKISP1_CIF_ISP_OUT_H_SIZE_SHD (RKISP1_CIF_ISP_BASE + 0x000001B4)
+#define RKISP1_CIF_ISP_OUT_V_SIZE_SHD (RKISP1_CIF_ISP_BASE + 0x000001B8)
+#define RKISP1_CIF_ISP_IMSC (RKISP1_CIF_ISP_BASE + 0x000001BC)
+#define RKISP1_CIF_ISP_RIS (RKISP1_CIF_ISP_BASE + 0x000001C0)
+#define RKISP1_CIF_ISP_MIS (RKISP1_CIF_ISP_BASE + 0x000001C4)
+#define RKISP1_CIF_ISP_ICR (RKISP1_CIF_ISP_BASE + 0x000001C8)
+#define RKISP1_CIF_ISP_ISR (RKISP1_CIF_ISP_BASE + 0x000001CC)
+#define RKISP1_CIF_ISP_CT_COEFF_0 (RKISP1_CIF_ISP_BASE + 0x000001D0)
+#define RKISP1_CIF_ISP_CT_COEFF_1 (RKISP1_CIF_ISP_BASE + 0x000001D4)
+#define RKISP1_CIF_ISP_CT_COEFF_2 (RKISP1_CIF_ISP_BASE + 0x000001D8)
+#define RKISP1_CIF_ISP_CT_COEFF_3 (RKISP1_CIF_ISP_BASE + 0x000001DC)
+#define RKISP1_CIF_ISP_CT_COEFF_4 (RKISP1_CIF_ISP_BASE + 0x000001E0)
+#define RKISP1_CIF_ISP_CT_COEFF_5 (RKISP1_CIF_ISP_BASE + 0x000001E4)
+#define RKISP1_CIF_ISP_CT_COEFF_6 (RKISP1_CIF_ISP_BASE + 0x000001E8)
+#define RKISP1_CIF_ISP_CT_COEFF_7 (RKISP1_CIF_ISP_BASE + 0x000001EC)
+#define RKISP1_CIF_ISP_CT_COEFF_8 (RKISP1_CIF_ISP_BASE + 0x000001F0)
+#define RKISP1_CIF_ISP_GAMMA_OUT_MODE (RKISP1_CIF_ISP_BASE + 0x000001F4)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_0 (RKISP1_CIF_ISP_BASE + 0x000001F8)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_1 (RKISP1_CIF_ISP_BASE + 0x000001FC)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_2 (RKISP1_CIF_ISP_BASE + 0x00000200)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_3 (RKISP1_CIF_ISP_BASE + 0x00000204)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_4 (RKISP1_CIF_ISP_BASE + 0x00000208)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_5 (RKISP1_CIF_ISP_BASE + 0x0000020C)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_6 (RKISP1_CIF_ISP_BASE + 0x00000210)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_7 (RKISP1_CIF_ISP_BASE + 0x00000214)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_8 (RKISP1_CIF_ISP_BASE + 0x00000218)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_9 (RKISP1_CIF_ISP_BASE + 0x0000021C)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_10 (RKISP1_CIF_ISP_BASE + 0x00000220)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_11 (RKISP1_CIF_ISP_BASE + 0x00000224)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_12 (RKISP1_CIF_ISP_BASE + 0x00000228)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_13 (RKISP1_CIF_ISP_BASE + 0x0000022C)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_14 (RKISP1_CIF_ISP_BASE + 0x00000230)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_15 (RKISP1_CIF_ISP_BASE + 0x00000234)
+#define RKISP1_CIF_ISP_GAMMA_OUT_Y_16 (RKISP1_CIF_ISP_BASE + 0x00000238)
+#define RKISP1_CIF_ISP_ERR (RKISP1_CIF_ISP_BASE + 0x0000023C)
+#define RKISP1_CIF_ISP_ERR_CLR (RKISP1_CIF_ISP_BASE + 0x00000240)
+#define RKISP1_CIF_ISP_FRAME_COUNT (RKISP1_CIF_ISP_BASE + 0x00000244)
+#define RKISP1_CIF_ISP_CT_OFFSET_R (RKISP1_CIF_ISP_BASE + 0x00000248)
+#define RKISP1_CIF_ISP_CT_OFFSET_G (RKISP1_CIF_ISP_BASE + 0x0000024C)
+#define RKISP1_CIF_ISP_CT_OFFSET_B (RKISP1_CIF_ISP_BASE + 0x00000250)
+
+#define RKISP1_CIF_ISP_FLASH_BASE 0x00000660
+#define RKISP1_CIF_ISP_FLASH_CMD (RKISP1_CIF_ISP_FLASH_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_FLASH_CONFIG (RKISP1_CIF_ISP_FLASH_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_FLASH_PREDIV (RKISP1_CIF_ISP_FLASH_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_FLASH_DELAY (RKISP1_CIF_ISP_FLASH_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_FLASH_TIME (RKISP1_CIF_ISP_FLASH_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_FLASH_MAXP (RKISP1_CIF_ISP_FLASH_BASE + 0x00000014)
+
+#define RKISP1_CIF_ISP_SH_BASE 0x00000680
+#define RKISP1_CIF_ISP_SH_CTRL (RKISP1_CIF_ISP_SH_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_SH_PREDIV (RKISP1_CIF_ISP_SH_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_SH_DELAY (RKISP1_CIF_ISP_SH_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_SH_TIME (RKISP1_CIF_ISP_SH_BASE + 0x0000000C)
+
+#define RKISP1_CIF_C_PROC_BASE 0x00000800
+#define RKISP1_CIF_C_PROC_CTRL (RKISP1_CIF_C_PROC_BASE + 0x00000000)
+#define RKISP1_CIF_C_PROC_CONTRAST (RKISP1_CIF_C_PROC_BASE + 0x00000004)
+#define RKISP1_CIF_C_PROC_BRIGHTNESS (RKISP1_CIF_C_PROC_BASE + 0x00000008)
+#define RKISP1_CIF_C_PROC_SATURATION (RKISP1_CIF_C_PROC_BASE + 0x0000000C)
+#define RKISP1_CIF_C_PROC_HUE (RKISP1_CIF_C_PROC_BASE + 0x00000010)
+
+#define RKISP1_CIF_DUAL_CROP_BASE 0x00000880
+#define RKISP1_CIF_DUAL_CROP_CTRL (RKISP1_CIF_DUAL_CROP_BASE + 0x00000000)
+#define RKISP1_CIF_DUAL_CROP_M_H_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000004)
+#define RKISP1_CIF_DUAL_CROP_M_V_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000008)
+#define RKISP1_CIF_DUAL_CROP_M_H_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x0000000C)
+#define RKISP1_CIF_DUAL_CROP_M_V_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x00000010)
+#define RKISP1_CIF_DUAL_CROP_S_H_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000014)
+#define RKISP1_CIF_DUAL_CROP_S_V_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000018)
+#define RKISP1_CIF_DUAL_CROP_S_H_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x0000001C)
+#define RKISP1_CIF_DUAL_CROP_S_V_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x00000020)
+#define RKISP1_CIF_DUAL_CROP_M_H_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000024)
+#define RKISP1_CIF_DUAL_CROP_M_V_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000028)
+#define RKISP1_CIF_DUAL_CROP_M_H_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x0000002C)
+#define RKISP1_CIF_DUAL_CROP_M_V_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000030)
+#define RKISP1_CIF_DUAL_CROP_S_H_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000034)
+#define RKISP1_CIF_DUAL_CROP_S_V_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000038)
+#define RKISP1_CIF_DUAL_CROP_S_H_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x0000003C)
+#define RKISP1_CIF_DUAL_CROP_S_V_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000040)
+
+#define RKISP1_CIF_MRSZ_BASE 0x00000C00
+#define RKISP1_CIF_MRSZ_CTRL (RKISP1_CIF_MRSZ_BASE + 0x00000000)
+#define RKISP1_CIF_MRSZ_SCALE_HY (RKISP1_CIF_MRSZ_BASE + 0x00000004)
+#define RKISP1_CIF_MRSZ_SCALE_HCB (RKISP1_CIF_MRSZ_BASE + 0x00000008)
+#define RKISP1_CIF_MRSZ_SCALE_HCR (RKISP1_CIF_MRSZ_BASE + 0x0000000C)
+#define RKISP1_CIF_MRSZ_SCALE_VY (RKISP1_CIF_MRSZ_BASE + 0x00000010)
+#define RKISP1_CIF_MRSZ_SCALE_VC (RKISP1_CIF_MRSZ_BASE + 0x00000014)
+#define RKISP1_CIF_MRSZ_PHASE_HY (RKISP1_CIF_MRSZ_BASE + 0x00000018)
+#define RKISP1_CIF_MRSZ_PHASE_HC (RKISP1_CIF_MRSZ_BASE + 0x0000001C)
+#define RKISP1_CIF_MRSZ_PHASE_VY (RKISP1_CIF_MRSZ_BASE + 0x00000020)
+#define RKISP1_CIF_MRSZ_PHASE_VC (RKISP1_CIF_MRSZ_BASE + 0x00000024)
+#define RKISP1_CIF_MRSZ_SCALE_LUT_ADDR (RKISP1_CIF_MRSZ_BASE + 0x00000028)
+#define RKISP1_CIF_MRSZ_SCALE_LUT (RKISP1_CIF_MRSZ_BASE + 0x0000002C)
+#define RKISP1_CIF_MRSZ_CTRL_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000030)
+#define RKISP1_CIF_MRSZ_SCALE_HY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000034)
+#define RKISP1_CIF_MRSZ_SCALE_HCB_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000038)
+#define RKISP1_CIF_MRSZ_SCALE_HCR_SHD (RKISP1_CIF_MRSZ_BASE + 0x0000003C)
+#define RKISP1_CIF_MRSZ_SCALE_VY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000040)
+#define RKISP1_CIF_MRSZ_SCALE_VC_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000044)
+#define RKISP1_CIF_MRSZ_PHASE_HY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000048)
+#define RKISP1_CIF_MRSZ_PHASE_HC_SHD (RKISP1_CIF_MRSZ_BASE + 0x0000004C)
+#define RKISP1_CIF_MRSZ_PHASE_VY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000050)
+#define RKISP1_CIF_MRSZ_PHASE_VC_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000054)
+
+#define RKISP1_CIF_SRSZ_BASE 0x00001000
+#define RKISP1_CIF_SRSZ_CTRL (RKISP1_CIF_SRSZ_BASE + 0x00000000)
+#define RKISP1_CIF_SRSZ_SCALE_HY (RKISP1_CIF_SRSZ_BASE + 0x00000004)
+#define RKISP1_CIF_SRSZ_SCALE_HCB (RKISP1_CIF_SRSZ_BASE + 0x00000008)
+#define RKISP1_CIF_SRSZ_SCALE_HCR (RKISP1_CIF_SRSZ_BASE + 0x0000000C)
+#define RKISP1_CIF_SRSZ_SCALE_VY (RKISP1_CIF_SRSZ_BASE + 0x00000010)
+#define RKISP1_CIF_SRSZ_SCALE_VC (RKISP1_CIF_SRSZ_BASE + 0x00000014)
+#define RKISP1_CIF_SRSZ_PHASE_HY (RKISP1_CIF_SRSZ_BASE + 0x00000018)
+#define RKISP1_CIF_SRSZ_PHASE_HC (RKISP1_CIF_SRSZ_BASE + 0x0000001C)
+#define RKISP1_CIF_SRSZ_PHASE_VY (RKISP1_CIF_SRSZ_BASE + 0x00000020)
+#define RKISP1_CIF_SRSZ_PHASE_VC (RKISP1_CIF_SRSZ_BASE + 0x00000024)
+#define RKISP1_CIF_SRSZ_SCALE_LUT_ADDR (RKISP1_CIF_SRSZ_BASE + 0x00000028)
+#define RKISP1_CIF_SRSZ_SCALE_LUT (RKISP1_CIF_SRSZ_BASE + 0x0000002C)
+#define RKISP1_CIF_SRSZ_CTRL_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000030)
+#define RKISP1_CIF_SRSZ_SCALE_HY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000034)
+#define RKISP1_CIF_SRSZ_SCALE_HCB_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000038)
+#define RKISP1_CIF_SRSZ_SCALE_HCR_SHD (RKISP1_CIF_SRSZ_BASE + 0x0000003C)
+#define RKISP1_CIF_SRSZ_SCALE_VY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000040)
+#define RKISP1_CIF_SRSZ_SCALE_VC_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000044)
+#define RKISP1_CIF_SRSZ_PHASE_HY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000048)
+#define RKISP1_CIF_SRSZ_PHASE_HC_SHD (RKISP1_CIF_SRSZ_BASE + 0x0000004C)
+#define RKISP1_CIF_SRSZ_PHASE_VY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000050)
+#define RKISP1_CIF_SRSZ_PHASE_VC_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000054)
+
+#define RKISP1_CIF_MI_BASE 0x00001400
+#define RKISP1_CIF_MI_CTRL (RKISP1_CIF_MI_BASE + 0x00000000)
+#define RKISP1_CIF_MI_INIT (RKISP1_CIF_MI_BASE + 0x00000004)
+#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x00000008)
+#define RKISP1_CIF_MI_MP_Y_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x0000000C)
+#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000010)
+#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000014)
+#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_INIT (RKISP1_CIF_MI_BASE + 0x00000018)
+#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x0000001C)
+#define RKISP1_CIF_MI_MP_CB_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000020)
+#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000024)
+#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000028)
+#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x0000002C)
+#define RKISP1_CIF_MI_MP_CR_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000030)
+#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000034)
+#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000038)
+#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x0000003C)
+#define RKISP1_CIF_MI_SP_Y_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000040)
+#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000044)
+#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000048)
+#define RKISP1_CIF_MI_SP_Y_LLENGTH (RKISP1_CIF_MI_BASE + 0x0000004C)
+#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x00000050)
+#define RKISP1_CIF_MI_SP_CB_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000054)
+#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000058)
+#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x0000005C)
+#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x00000060)
+#define RKISP1_CIF_MI_SP_CR_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000064)
+#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000068)
+#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x0000006C)
+#define RKISP1_CIF_MI_BYTE_CNT (RKISP1_CIF_MI_BASE + 0x00000070)
+#define RKISP1_CIF_MI_CTRL_SHD (RKISP1_CIF_MI_BASE + 0x00000074)
+#define RKISP1_CIF_MI_MP_Y_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x00000078)
+#define RKISP1_CIF_MI_MP_Y_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x0000007C)
+#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x00000080)
+#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_SHD (RKISP1_CIF_MI_BASE + 0x00000084)
+#define RKISP1_CIF_MI_MP_CB_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x00000088)
+#define RKISP1_CIF_MI_MP_CB_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x0000008C)
+#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x00000090)
+#define RKISP1_CIF_MI_MP_CR_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x00000094)
+#define RKISP1_CIF_MI_MP_CR_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x00000098)
+#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x0000009C)
+#define RKISP1_CIF_MI_SP_Y_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x000000A0)
+#define RKISP1_CIF_MI_SP_Y_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x000000A4)
+#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x000000A8)
+#define RKISP1_CIF_MI_SP_CB_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x000000B0)
+#define RKISP1_CIF_MI_SP_CB_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x000000B4)
+#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x000000B8)
+#define RKISP1_CIF_MI_SP_CR_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x000000BC)
+#define RKISP1_CIF_MI_SP_CR_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x000000C0)
+#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x000000C4)
+#define RKISP1_CIF_MI_DMA_Y_PIC_START_AD (RKISP1_CIF_MI_BASE + 0x000000C8)
+#define RKISP1_CIF_MI_DMA_Y_PIC_WIDTH (RKISP1_CIF_MI_BASE + 0x000000CC)
+#define RKISP1_CIF_MI_DMA_Y_LLENGTH (RKISP1_CIF_MI_BASE + 0x000000D0)
+#define RKISP1_CIF_MI_DMA_Y_PIC_SIZE (RKISP1_CIF_MI_BASE + 0x000000D4)
+#define RKISP1_CIF_MI_DMA_CB_PIC_START_AD (RKISP1_CIF_MI_BASE + 0x000000D8)
+#define RKISP1_CIF_MI_DMA_CR_PIC_START_AD (RKISP1_CIF_MI_BASE + 0x000000E8)
+#define RKISP1_CIF_MI_IMSC (RKISP1_CIF_MI_BASE + 0x000000F8)
+#define RKISP1_CIF_MI_RIS (RKISP1_CIF_MI_BASE + 0x000000FC)
+#define RKISP1_CIF_MI_MIS (RKISP1_CIF_MI_BASE + 0x00000100)
+#define RKISP1_CIF_MI_ICR (RKISP1_CIF_MI_BASE + 0x00000104)
+#define RKISP1_CIF_MI_ISR (RKISP1_CIF_MI_BASE + 0x00000108)
+#define RKISP1_CIF_MI_STATUS (RKISP1_CIF_MI_BASE + 0x0000010C)
+#define RKISP1_CIF_MI_STATUS_CLR (RKISP1_CIF_MI_BASE + 0x00000110)
+#define RKISP1_CIF_MI_SP_Y_PIC_WIDTH (RKISP1_CIF_MI_BASE + 0x00000114)
+#define RKISP1_CIF_MI_SP_Y_PIC_HEIGHT (RKISP1_CIF_MI_BASE + 0x00000118)
+#define RKISP1_CIF_MI_SP_Y_PIC_SIZE (RKISP1_CIF_MI_BASE + 0x0000011C)
+#define RKISP1_CIF_MI_DMA_CTRL (RKISP1_CIF_MI_BASE + 0x00000120)
+#define RKISP1_CIF_MI_DMA_START (RKISP1_CIF_MI_BASE + 0x00000124)
+#define RKISP1_CIF_MI_DMA_STATUS (RKISP1_CIF_MI_BASE + 0x00000128)
+#define RKISP1_CIF_MI_PIXEL_COUNT (RKISP1_CIF_MI_BASE + 0x0000012C)
+#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000130)
+#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000134)
+#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000138)
+#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x0000013C)
+#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000140)
+#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000144)
+#define RKISP1_CIF_MI_XTD_FORMAT_CTRL (RKISP1_CIF_MI_BASE + 0x00000148)
+
+#define RKISP1_CIF_SMIA_BASE 0x00001A00
+#define RKISP1_CIF_SMIA_CTRL (RKISP1_CIF_SMIA_BASE + 0x00000000)
+#define RKISP1_CIF_SMIA_STATUS (RKISP1_CIF_SMIA_BASE + 0x00000004)
+#define RKISP1_CIF_SMIA_IMSC (RKISP1_CIF_SMIA_BASE + 0x00000008)
+#define RKISP1_CIF_SMIA_RIS (RKISP1_CIF_SMIA_BASE + 0x0000000C)
+#define RKISP1_CIF_SMIA_MIS (RKISP1_CIF_SMIA_BASE + 0x00000010)
+#define RKISP1_CIF_SMIA_ICR (RKISP1_CIF_SMIA_BASE + 0x00000014)
+#define RKISP1_CIF_SMIA_ISR (RKISP1_CIF_SMIA_BASE + 0x00000018)
+#define RKISP1_CIF_SMIA_DATA_FORMAT_SEL (RKISP1_CIF_SMIA_BASE + 0x0000001C)
+#define RKISP1_CIF_SMIA_SOF_EMB_DATA_LINES (RKISP1_CIF_SMIA_BASE + 0x00000020)
+#define RKISP1_CIF_SMIA_EMB_HSTART (RKISP1_CIF_SMIA_BASE + 0x00000024)
+#define RKISP1_CIF_SMIA_EMB_HSIZE (RKISP1_CIF_SMIA_BASE + 0x00000028)
+#define RKISP1_CIF_SMIA_EMB_VSTART (RKISP1_CIF_SMIA_BASE + 0x0000002c)
+#define RKISP1_CIF_SMIA_NUM_LINES (RKISP1_CIF_SMIA_BASE + 0x00000030)
+#define RKISP1_CIF_SMIA_EMB_DATA_FIFO (RKISP1_CIF_SMIA_BASE + 0x00000034)
+#define RKISP1_CIF_SMIA_EMB_DATA_WATERMARK (RKISP1_CIF_SMIA_BASE + 0x00000038)
+
+#define RKISP1_CIF_MIPI_BASE 0x00001C00
+#define RKISP1_CIF_MIPI_CTRL (RKISP1_CIF_MIPI_BASE + 0x00000000)
+#define RKISP1_CIF_MIPI_STATUS (RKISP1_CIF_MIPI_BASE + 0x00000004)
+#define RKISP1_CIF_MIPI_IMSC (RKISP1_CIF_MIPI_BASE + 0x00000008)
+#define RKISP1_CIF_MIPI_RIS (RKISP1_CIF_MIPI_BASE + 0x0000000C)
+#define RKISP1_CIF_MIPI_MIS (RKISP1_CIF_MIPI_BASE + 0x00000010)
+#define RKISP1_CIF_MIPI_ICR (RKISP1_CIF_MIPI_BASE + 0x00000014)
+#define RKISP1_CIF_MIPI_ISR (RKISP1_CIF_MIPI_BASE + 0x00000018)
+#define RKISP1_CIF_MIPI_CUR_DATA_ID (RKISP1_CIF_MIPI_BASE + 0x0000001C)
+#define RKISP1_CIF_MIPI_IMG_DATA_SEL (RKISP1_CIF_MIPI_BASE + 0x00000020)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_1 (RKISP1_CIF_MIPI_BASE + 0x00000024)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_2 (RKISP1_CIF_MIPI_BASE + 0x00000028)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_3 (RKISP1_CIF_MIPI_BASE + 0x0000002C)
+#define RKISP1_CIF_MIPI_ADD_DATA_SEL_4 (RKISP1_CIF_MIPI_BASE + 0x00000030)
+#define RKISP1_CIF_MIPI_ADD_DATA_FIFO (RKISP1_CIF_MIPI_BASE + 0x00000034)
+#define RKISP1_CIF_MIPI_FIFO_FILL_LEVEL (RKISP1_CIF_MIPI_BASE + 0x00000038)
+#define RKISP1_CIF_MIPI_COMPRESSED_MODE (RKISP1_CIF_MIPI_BASE + 0x0000003C)
+#define RKISP1_CIF_MIPI_FRAME (RKISP1_CIF_MIPI_BASE + 0x00000040)
+#define RKISP1_CIF_MIPI_GEN_SHORT_DT (RKISP1_CIF_MIPI_BASE + 0x00000044)
+#define RKISP1_CIF_MIPI_GEN_SHORT_8_9 (RKISP1_CIF_MIPI_BASE + 0x00000048)
+#define RKISP1_CIF_MIPI_GEN_SHORT_A_B (RKISP1_CIF_MIPI_BASE + 0x0000004C)
+#define RKISP1_CIF_MIPI_GEN_SHORT_C_D (RKISP1_CIF_MIPI_BASE + 0x00000050)
+#define RKISP1_CIF_MIPI_GEN_SHORT_E_F (RKISP1_CIF_MIPI_BASE + 0x00000054)
+
+#define RKISP1_CIF_ISP_AFM_BASE 0x00002000
+#define RKISP1_CIF_ISP_AFM_CTRL (RKISP1_CIF_ISP_AFM_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_AFM_LT_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_AFM_RB_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_AFM_LT_B (RKISP1_CIF_ISP_AFM_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_AFM_RB_B (RKISP1_CIF_ISP_AFM_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_AFM_LT_C (RKISP1_CIF_ISP_AFM_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_AFM_RB_C (RKISP1_CIF_ISP_AFM_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_AFM_THRES (RKISP1_CIF_ISP_AFM_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_AFM_VAR_SHIFT (RKISP1_CIF_ISP_AFM_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_AFM_SUM_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_AFM_SUM_B (RKISP1_CIF_ISP_AFM_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_AFM_SUM_C (RKISP1_CIF_ISP_AFM_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_AFM_LUM_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_AFM_LUM_B (RKISP1_CIF_ISP_AFM_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_AFM_LUM_C (RKISP1_CIF_ISP_AFM_BASE + 0x00000038)
+
+#define RKISP1_CIF_ISP_LSC_BASE 0x00002200
+#define RKISP1_CIF_ISP_LSC_CTRL (RKISP1_CIF_ISP_LSC_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_LSC_R_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_LSC_B_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_LSC_R_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_LSC_GR_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_LSC_B_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_LSC_GB_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_LSC_XGRAD_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_LSC_XGRAD_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_LSC_XGRAD_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_LSC_XGRAD_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_LSC_YGRAD_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_LSC_YGRAD_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_LSC_YGRAD_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_LSC_YGRAD_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_LSC_XSIZE_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_LSC_XSIZE_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_LSC_XSIZE_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_LSC_XSIZE_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_LSC_YSIZE_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_LSC_YSIZE_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_LSC_YSIZE_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_LSC_YSIZE_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_LSC_TABLE_SEL (RKISP1_CIF_ISP_LSC_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_LSC_STATUS (RKISP1_CIF_ISP_LSC_BASE + 0x00000068)
+
+#define RKISP1_CIF_ISP_IS_BASE 0x00002300
+#define RKISP1_CIF_ISP_IS_CTRL (RKISP1_CIF_ISP_IS_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_IS_RECENTER (RKISP1_CIF_ISP_IS_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_IS_H_OFFS (RKISP1_CIF_ISP_IS_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_IS_V_OFFS (RKISP1_CIF_ISP_IS_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_IS_H_SIZE (RKISP1_CIF_ISP_IS_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_IS_V_SIZE (RKISP1_CIF_ISP_IS_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_IS_MAX_DX (RKISP1_CIF_ISP_IS_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_IS_MAX_DY (RKISP1_CIF_ISP_IS_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_IS_DISPLACE (RKISP1_CIF_ISP_IS_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_IS_H_OFFS_SHD (RKISP1_CIF_ISP_IS_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_IS_V_OFFS_SHD (RKISP1_CIF_ISP_IS_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_IS_H_SIZE_SHD (RKISP1_CIF_ISP_IS_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_IS_V_SIZE_SHD (RKISP1_CIF_ISP_IS_BASE + 0x00000030)
+
+#define RKISP1_CIF_ISP_HIST_BASE 0x00002400
+
+#define RKISP1_CIF_ISP_HIST_PROP (RKISP1_CIF_ISP_HIST_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_HIST_H_OFFS (RKISP1_CIF_ISP_HIST_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_HIST_V_OFFS (RKISP1_CIF_ISP_HIST_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_HIST_H_SIZE (RKISP1_CIF_ISP_HIST_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_HIST_V_SIZE (RKISP1_CIF_ISP_HIST_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_HIST_BIN_0 (RKISP1_CIF_ISP_HIST_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_HIST_BIN_1 (RKISP1_CIF_ISP_HIST_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_HIST_BIN_2 (RKISP1_CIF_ISP_HIST_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_HIST_BIN_3 (RKISP1_CIF_ISP_HIST_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_HIST_BIN_4 (RKISP1_CIF_ISP_HIST_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_HIST_BIN_5 (RKISP1_CIF_ISP_HIST_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_HIST_BIN_6 (RKISP1_CIF_ISP_HIST_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_HIST_BIN_7 (RKISP1_CIF_ISP_HIST_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_HIST_BIN_8 (RKISP1_CIF_ISP_HIST_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_HIST_BIN_9 (RKISP1_CIF_ISP_HIST_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_HIST_BIN_10 (RKISP1_CIF_ISP_HIST_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_HIST_BIN_11 (RKISP1_CIF_ISP_HIST_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_HIST_BIN_12 (RKISP1_CIF_ISP_HIST_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_HIST_BIN_13 (RKISP1_CIF_ISP_HIST_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_HIST_BIN_14 (RKISP1_CIF_ISP_HIST_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_HIST_BIN_15 (RKISP1_CIF_ISP_HIST_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_00TO30 (RKISP1_CIF_ISP_HIST_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_40TO21 (RKISP1_CIF_ISP_HIST_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_31TO12 (RKISP1_CIF_ISP_HIST_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_22TO03 (RKISP1_CIF_ISP_HIST_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_13TO43 (RKISP1_CIF_ISP_HIST_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_04TO34 (RKISP1_CIF_ISP_HIST_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_HIST_WEIGHT_44 (RKISP1_CIF_ISP_HIST_BASE + 0x0000006C)
+
+#define RKISP1_CIF_ISP_FILT_BASE 0x00002500
+#define RKISP1_CIF_ISP_FILT_MODE (RKISP1_CIF_ISP_FILT_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_FILT_THRESH_BL0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_FILT_THRESH_BL1 (RKISP1_CIF_ISP_FILT_BASE + 0x0000002c)
+#define RKISP1_CIF_ISP_FILT_THRESH_SH0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_FILT_THRESH_SH1 (RKISP1_CIF_ISP_FILT_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_FILT_LUM_WEIGHT (RKISP1_CIF_ISP_FILT_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_FILT_FAC_SH1 (RKISP1_CIF_ISP_FILT_BASE + 0x0000003c)
+#define RKISP1_CIF_ISP_FILT_FAC_SH0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_FILT_FAC_MID (RKISP1_CIF_ISP_FILT_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_FILT_FAC_BL0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_FILT_FAC_BL1 (RKISP1_CIF_ISP_FILT_BASE + 0x0000004C)
+
+#define RKISP1_CIF_ISP_CAC_BASE 0x00002580
+#define RKISP1_CIF_ISP_CAC_CTRL (RKISP1_CIF_ISP_CAC_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_CAC_COUNT_START (RKISP1_CIF_ISP_CAC_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_CAC_A (RKISP1_CIF_ISP_CAC_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_CAC_B (RKISP1_CIF_ISP_CAC_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_CAC_C (RKISP1_CIF_ISP_CAC_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_X_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_Y_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
+
+#define RKISP1_CIF_ISP_EXP_BASE 0x00002600
+#define RKISP1_CIF_ISP_EXP_CTRL (RKISP1_CIF_ISP_EXP_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_EXP_H_OFFSET (RKISP1_CIF_ISP_EXP_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_EXP_V_OFFSET (RKISP1_CIF_ISP_EXP_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_EXP_H_SIZE (RKISP1_CIF_ISP_EXP_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_EXP_V_SIZE (RKISP1_CIF_ISP_EXP_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_EXP_MEAN_00 (RKISP1_CIF_ISP_EXP_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_EXP_MEAN_10 (RKISP1_CIF_ISP_EXP_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_EXP_MEAN_20 (RKISP1_CIF_ISP_EXP_BASE + 0x0000001c)
+#define RKISP1_CIF_ISP_EXP_MEAN_30 (RKISP1_CIF_ISP_EXP_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_EXP_MEAN_40 (RKISP1_CIF_ISP_EXP_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_EXP_MEAN_01 (RKISP1_CIF_ISP_EXP_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_EXP_MEAN_11 (RKISP1_CIF_ISP_EXP_BASE + 0x0000002c)
+#define RKISP1_CIF_ISP_EXP_MEAN_21 (RKISP1_CIF_ISP_EXP_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_EXP_MEAN_31 (RKISP1_CIF_ISP_EXP_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_EXP_MEAN_41 (RKISP1_CIF_ISP_EXP_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_EXP_MEAN_02 (RKISP1_CIF_ISP_EXP_BASE + 0x0000003c)
+#define RKISP1_CIF_ISP_EXP_MEAN_12 (RKISP1_CIF_ISP_EXP_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_EXP_MEAN_22 (RKISP1_CIF_ISP_EXP_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_EXP_MEAN_32 (RKISP1_CIF_ISP_EXP_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_EXP_MEAN_42 (RKISP1_CIF_ISP_EXP_BASE + 0x0000004c)
+#define RKISP1_CIF_ISP_EXP_MEAN_03 (RKISP1_CIF_ISP_EXP_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_EXP_MEAN_13 (RKISP1_CIF_ISP_EXP_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_EXP_MEAN_23 (RKISP1_CIF_ISP_EXP_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_EXP_MEAN_33 (RKISP1_CIF_ISP_EXP_BASE + 0x0000005c)
+#define RKISP1_CIF_ISP_EXP_MEAN_43 (RKISP1_CIF_ISP_EXP_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_EXP_MEAN_04 (RKISP1_CIF_ISP_EXP_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_EXP_MEAN_14 (RKISP1_CIF_ISP_EXP_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_EXP_MEAN_24 (RKISP1_CIF_ISP_EXP_BASE + 0x0000006c)
+#define RKISP1_CIF_ISP_EXP_MEAN_34 (RKISP1_CIF_ISP_EXP_BASE + 0x00000070)
+#define RKISP1_CIF_ISP_EXP_MEAN_44 (RKISP1_CIF_ISP_EXP_BASE + 0x00000074)
+
+#define RKISP1_CIF_ISP_BLS_BASE 0x00002700
+#define RKISP1_CIF_ISP_BLS_CTRL (RKISP1_CIF_ISP_BLS_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_BLS_SAMPLES (RKISP1_CIF_ISP_BLS_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_BLS_H1_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_BLS_H1_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x0000000c)
+#define RKISP1_CIF_ISP_BLS_V1_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_BLS_V1_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_BLS_H2_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_BLS_H2_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x0000001c)
+#define RKISP1_CIF_ISP_BLS_V2_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_BLS_V2_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_BLS_A_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_BLS_B_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x0000002c)
+#define RKISP1_CIF_ISP_BLS_C_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_BLS_D_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_BLS_A_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_BLS_B_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x0000003c)
+#define RKISP1_CIF_ISP_BLS_C_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_BLS_D_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x00000044)
+
+#define RKISP1_CIF_ISP_DPF_BASE 0x00002800
+#define RKISP1_CIF_ISP_DPF_MODE (RKISP1_CIF_ISP_DPF_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_DPF_STRENGTH_R (RKISP1_CIF_ISP_DPF_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_DPF_STRENGTH_G (RKISP1_CIF_ISP_DPF_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_DPF_STRENGTH_B (RKISP1_CIF_ISP_DPF_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4 (RKISP1_CIF_ISP_DPF_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6 (RKISP1_CIF_ISP_DPF_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4 (RKISP1_CIF_ISP_DPF_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6 (RKISP1_CIF_ISP_DPF_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_0 (RKISP1_CIF_ISP_DPF_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_1 (RKISP1_CIF_ISP_DPF_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_2 (RKISP1_CIF_ISP_DPF_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_3 (RKISP1_CIF_ISP_DPF_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_4 (RKISP1_CIF_ISP_DPF_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_5 (RKISP1_CIF_ISP_DPF_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_6 (RKISP1_CIF_ISP_DPF_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_7 (RKISP1_CIF_ISP_DPF_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_8 (RKISP1_CIF_ISP_DPF_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_9 (RKISP1_CIF_ISP_DPF_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_10 (RKISP1_CIF_ISP_DPF_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_11 (RKISP1_CIF_ISP_DPF_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_12 (RKISP1_CIF_ISP_DPF_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_13 (RKISP1_CIF_ISP_DPF_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_14 (RKISP1_CIF_ISP_DPF_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_15 (RKISP1_CIF_ISP_DPF_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_DPF_NULL_COEFF_16 (RKISP1_CIF_ISP_DPF_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_R (RKISP1_CIF_ISP_DPF_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_GR (RKISP1_CIF_ISP_DPF_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_GB (RKISP1_CIF_ISP_DPF_BASE + 0x0000006C)
+#define RKISP1_CIF_ISP_DPF_NF_GAIN_B (RKISP1_CIF_ISP_DPF_BASE + 0x00000070)
+
+#define RKISP1_CIF_ISP_DPCC_BASE 0x00002900
+#define RKISP1_CIF_ISP_DPCC_MODE (RKISP1_CIF_ISP_DPCC_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE (RKISP1_CIF_ISP_DPCC_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_DPCC_SET_USE (RKISP1_CIF_ISP_DPCC_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_DPCC_METHODS_SET_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_DPCC_PG_FAC_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_DPCC_RND_THRESH_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_DPCC_RG_FAC_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_DPCC_RO_LIMITS (RKISP1_CIF_ISP_DPCC_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_DPCC_RND_OFFS (RKISP1_CIF_ISP_DPCC_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_DPCC_BPT_CTRL (RKISP1_CIF_ISP_DPCC_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_DPCC_BPT_NUMBER (RKISP1_CIF_ISP_DPCC_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_DPCC_BPT_ADDR (RKISP1_CIF_ISP_DPCC_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_DPCC_BPT_DATA (RKISP1_CIF_ISP_DPCC_BASE + 0x00000068)
+
+#define RKISP1_CIF_ISP_WDR_BASE 0x00002A00
+#define RKISP1_CIF_ISP_WDR_CTRL (RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_1 (RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_2 (RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_3 (RKISP1_CIF_ISP_WDR_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_4 (RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0 (RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1 (RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2 (RKISP1_CIF_ISP_WDR_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3 (RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4 (RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5 (RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6 (RKISP1_CIF_ISP_WDR_BASE + 0x0000002C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7 (RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8 (RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9 (RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10 (RKISP1_CIF_ISP_WDR_BASE + 0x0000003C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11 (RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12 (RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13 (RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14 (RKISP1_CIF_ISP_WDR_BASE + 0x0000004C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15 (RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16 (RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17 (RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18 (RKISP1_CIF_ISP_WDR_BASE + 0x0000005C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19 (RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20 (RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21 (RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22 (RKISP1_CIF_ISP_WDR_BASE + 0x0000006C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23 (RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24 (RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25 (RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26 (RKISP1_CIF_ISP_WDR_BASE + 0x0000007C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27 (RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28 (RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29 (RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30 (RKISP1_CIF_ISP_WDR_BASE + 0x0000008C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31 (RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32 (RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
+#define RKISP1_CIF_ISP_WDR_OFFSET (RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
+#define RKISP1_CIF_ISP_WDR_DELTAMIN (RKISP1_CIF_ISP_WDR_BASE + 0x0000009C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000A0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000A4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000A8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000AC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000B0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000B4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000B8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000BC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000C0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000C4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000C8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000CC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000DC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000EC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F0)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F4)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F8)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000FC)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000010C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000011C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000012C)
+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
+
+#define RKISP1_CIF_ISP_VSM_BASE 0x00002F00
+#define RKISP1_CIF_ISP_VSM_MODE (RKISP1_CIF_ISP_VSM_BASE + 0x00000000)
+#define RKISP1_CIF_ISP_VSM_H_OFFS (RKISP1_CIF_ISP_VSM_BASE + 0x00000004)
+#define RKISP1_CIF_ISP_VSM_V_OFFS (RKISP1_CIF_ISP_VSM_BASE + 0x00000008)
+#define RKISP1_CIF_ISP_VSM_H_SIZE (RKISP1_CIF_ISP_VSM_BASE + 0x0000000C)
+#define RKISP1_CIF_ISP_VSM_V_SIZE (RKISP1_CIF_ISP_VSM_BASE + 0x00000010)
+#define RKISP1_CIF_ISP_VSM_H_SEGMENTS (RKISP1_CIF_ISP_VSM_BASE + 0x00000014)
+#define RKISP1_CIF_ISP_VSM_V_SEGMENTS (RKISP1_CIF_ISP_VSM_BASE + 0x00000018)
+#define RKISP1_CIF_ISP_VSM_DELTA_H (RKISP1_CIF_ISP_VSM_BASE + 0x0000001C)
+#define RKISP1_CIF_ISP_VSM_DELTA_V (RKISP1_CIF_ISP_VSM_BASE + 0x00000020)
+
+#endif /* _RKISP1_REGS_H */
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - V4l resizer device
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *
+ * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include "rkisp1-common.h"
+
+#define RKISP1_RSZ_SP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_selfpath"
+#define RKISP1_RSZ_MP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_mainpath"
+
+#define RKISP1_DEF_FMT MEDIA_BUS_FMT_YUYV8_2X8
+#define RKISP1_DEF_PIXEL_ENC V4L2_PIXEL_ENC_YUV
+
+struct rkisp1_rsz_yuv_mbus_info {
+ u32 mbus_code;
+ u32 hdiv;
+ u32 vdiv;
+};
+
+static const struct rkisp1_rsz_yuv_mbus_info rkisp1_rsz_yuv_src_formats[] = {
+ {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, /* YUV422 */
+ .hdiv = 2,
+ .vdiv = 1,
+ },
+ {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_1_5X8, /* YUV420 */
+ .hdiv = 2,
+ .vdiv = 2,
+ },
+};
+
+static const struct rkisp1_rsz_yuv_mbus_info *rkisp1_rsz_get_yuv_mbus_info(u32 mbus_code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(rkisp1_rsz_yuv_src_formats); i++) {
+ if (rkisp1_rsz_yuv_src_formats[i].mbus_code == mbus_code)
+ return &rkisp1_rsz_yuv_src_formats[i];
+ }
+
+ return NULL;
+}
+
+enum rkisp1_shadow_regs_when {
+ RKISP1_SHADOW_REGS_SYNC,
+ RKISP1_SHADOW_REGS_ASYNC,
+};
+
+struct rkisp1_rsz_config {
+ /* constrains */
+ const int max_rsz_width;
+ const int max_rsz_height;
+ const int min_rsz_width;
+ const int min_rsz_height;
+ /* registers */
+ struct {
+ u32 ctrl;
+ u32 ctrl_shd;
+ u32 scale_hy;
+ u32 scale_hcr;
+ u32 scale_hcb;
+ u32 scale_vy;
+ u32 scale_vc;
+ u32 scale_lut;
+ u32 scale_lut_addr;
+ u32 scale_hy_shd;
+ u32 scale_hcr_shd;
+ u32 scale_hcb_shd;
+ u32 scale_vy_shd;
+ u32 scale_vc_shd;
+ u32 phase_hy;
+ u32 phase_hc;
+ u32 phase_vy;
+ u32 phase_vc;
+ u32 phase_hy_shd;
+ u32 phase_hc_shd;
+ u32 phase_vy_shd;
+ u32 phase_vc_shd;
+ } rsz;
+ struct {
+ u32 ctrl;
+ u32 yuvmode_mask;
+ u32 rawmode_mask;
+ u32 h_offset;
+ u32 v_offset;
+ u32 h_size;
+ u32 v_size;
+ } dual_crop;
+};
+
+static const struct rkisp1_rsz_config rkisp1_rsz_config_mp = {
+ /* constraints */
+ .max_rsz_width = RKISP1_RSZ_MP_SRC_MAX_WIDTH,
+ .max_rsz_height = RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
+ .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
+ .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
+ /* registers */
+ .rsz = {
+ .ctrl = RKISP1_CIF_MRSZ_CTRL,
+ .scale_hy = RKISP1_CIF_MRSZ_SCALE_HY,
+ .scale_hcr = RKISP1_CIF_MRSZ_SCALE_HCR,
+ .scale_hcb = RKISP1_CIF_MRSZ_SCALE_HCB,
+ .scale_vy = RKISP1_CIF_MRSZ_SCALE_VY,
+ .scale_vc = RKISP1_CIF_MRSZ_SCALE_VC,
+ .scale_lut = RKISP1_CIF_MRSZ_SCALE_LUT,
+ .scale_lut_addr = RKISP1_CIF_MRSZ_SCALE_LUT_ADDR,
+ .scale_hy_shd = RKISP1_CIF_MRSZ_SCALE_HY_SHD,
+ .scale_hcr_shd = RKISP1_CIF_MRSZ_SCALE_HCR_SHD,
+ .scale_hcb_shd = RKISP1_CIF_MRSZ_SCALE_HCB_SHD,
+ .scale_vy_shd = RKISP1_CIF_MRSZ_SCALE_VY_SHD,
+ .scale_vc_shd = RKISP1_CIF_MRSZ_SCALE_VC_SHD,
+ .phase_hy = RKISP1_CIF_MRSZ_PHASE_HY,
+ .phase_hc = RKISP1_CIF_MRSZ_PHASE_HC,
+ .phase_vy = RKISP1_CIF_MRSZ_PHASE_VY,
+ .phase_vc = RKISP1_CIF_MRSZ_PHASE_VC,
+ .ctrl_shd = RKISP1_CIF_MRSZ_CTRL_SHD,
+ .phase_hy_shd = RKISP1_CIF_MRSZ_PHASE_HY_SHD,
+ .phase_hc_shd = RKISP1_CIF_MRSZ_PHASE_HC_SHD,
+ .phase_vy_shd = RKISP1_CIF_MRSZ_PHASE_VY_SHD,
+ .phase_vc_shd = RKISP1_CIF_MRSZ_PHASE_VC_SHD,
+ },
+ .dual_crop = {
+ .ctrl = RKISP1_CIF_DUAL_CROP_CTRL,
+ .yuvmode_mask = RKISP1_CIF_DUAL_CROP_MP_MODE_YUV,
+ .rawmode_mask = RKISP1_CIF_DUAL_CROP_MP_MODE_RAW,
+ .h_offset = RKISP1_CIF_DUAL_CROP_M_H_OFFS,
+ .v_offset = RKISP1_CIF_DUAL_CROP_M_V_OFFS,
+ .h_size = RKISP1_CIF_DUAL_CROP_M_H_SIZE,
+ .v_size = RKISP1_CIF_DUAL_CROP_M_V_SIZE,
+ },
+};
+
+static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = {
+ /* constraints */
+ .max_rsz_width = RKISP1_RSZ_SP_SRC_MAX_WIDTH,
+ .max_rsz_height = RKISP1_RSZ_SP_SRC_MAX_HEIGHT,
+ .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
+ .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
+ /* registers */
+ .rsz = {
+ .ctrl = RKISP1_CIF_SRSZ_CTRL,
+ .scale_hy = RKISP1_CIF_SRSZ_SCALE_HY,
+ .scale_hcr = RKISP1_CIF_SRSZ_SCALE_HCR,
+ .scale_hcb = RKISP1_CIF_SRSZ_SCALE_HCB,
+ .scale_vy = RKISP1_CIF_SRSZ_SCALE_VY,
+ .scale_vc = RKISP1_CIF_SRSZ_SCALE_VC,
+ .scale_lut = RKISP1_CIF_SRSZ_SCALE_LUT,
+ .scale_lut_addr = RKISP1_CIF_SRSZ_SCALE_LUT_ADDR,
+ .scale_hy_shd = RKISP1_CIF_SRSZ_SCALE_HY_SHD,
+ .scale_hcr_shd = RKISP1_CIF_SRSZ_SCALE_HCR_SHD,
+ .scale_hcb_shd = RKISP1_CIF_SRSZ_SCALE_HCB_SHD,
+ .scale_vy_shd = RKISP1_CIF_SRSZ_SCALE_VY_SHD,
+ .scale_vc_shd = RKISP1_CIF_SRSZ_SCALE_VC_SHD,
+ .phase_hy = RKISP1_CIF_SRSZ_PHASE_HY,
+ .phase_hc = RKISP1_CIF_SRSZ_PHASE_HC,
+ .phase_vy = RKISP1_CIF_SRSZ_PHASE_VY,
+ .phase_vc = RKISP1_CIF_SRSZ_PHASE_VC,
+ .ctrl_shd = RKISP1_CIF_SRSZ_CTRL_SHD,
+ .phase_hy_shd = RKISP1_CIF_SRSZ_PHASE_HY_SHD,
+ .phase_hc_shd = RKISP1_CIF_SRSZ_PHASE_HC_SHD,
+ .phase_vy_shd = RKISP1_CIF_SRSZ_PHASE_VY_SHD,
+ .phase_vc_shd = RKISP1_CIF_SRSZ_PHASE_VC_SHD,
+ },
+ .dual_crop = {
+ .ctrl = RKISP1_CIF_DUAL_CROP_CTRL,
+ .yuvmode_mask = RKISP1_CIF_DUAL_CROP_SP_MODE_YUV,
+ .rawmode_mask = RKISP1_CIF_DUAL_CROP_SP_MODE_RAW,
+ .h_offset = RKISP1_CIF_DUAL_CROP_S_H_OFFS,
+ .v_offset = RKISP1_CIF_DUAL_CROP_S_V_OFFS,
+ .h_size = RKISP1_CIF_DUAL_CROP_S_H_SIZE,
+ .v_size = RKISP1_CIF_DUAL_CROP_S_V_SIZE,
+ },
+};
+
+static struct v4l2_mbus_framefmt *
+rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz,
+ struct v4l2_subdev_pad_config *cfg,
+ unsigned int pad, u32 which)
+{
+ if (which == V4L2_SUBDEV_FORMAT_TRY)
+ return v4l2_subdev_get_try_format(&rsz->sd, cfg, pad);
+ else
+ return v4l2_subdev_get_try_format(&rsz->sd, rsz->pad_cfg, pad);
+}
+
+static struct v4l2_rect *
+rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz,
+ struct v4l2_subdev_pad_config *cfg,
+ unsigned int pad, u32 which)
+{
+ if (which == V4L2_SUBDEV_FORMAT_TRY)
+ return v4l2_subdev_get_try_crop(&rsz->sd, cfg, pad);
+ else
+ return v4l2_subdev_get_try_crop(&rsz->sd, rsz->pad_cfg, pad);
+}
+
+/* ----------------------------------------------------------------------------
+ * Dual crop hw configs
+ */
+
+static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
+ enum rkisp1_shadow_regs_when when)
+{
+ u32 dc_ctrl = rkisp1_read(rsz->rkisp1, rsz->config->dual_crop.ctrl);
+ u32 mask = ~(rsz->config->dual_crop.yuvmode_mask |
+ rsz->config->dual_crop.rawmode_mask);
+
+ dc_ctrl &= mask;
+ if (when == RKISP1_SHADOW_REGS_ASYNC)
+ dc_ctrl |= RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD;
+ else
+ dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
+ rkisp1_write(rsz->rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
+}
+
+/* configure dual-crop unit */
+static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz)
+{
+ struct rkisp1_device *rkisp1 = rsz->rkisp1;
+ struct v4l2_mbus_framefmt *sink_fmt;
+ struct v4l2_rect *sink_crop;
+ u32 dc_ctrl;
+
+ sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+
+ if (sink_crop->width == sink_fmt->width &&
+ sink_crop->height == sink_fmt->height &&
+ sink_crop->left == 0 && sink_crop->top == 0) {
+ rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_SYNC);
+ dev_dbg(rkisp1->dev, "capture %d crop disabled\n", rsz->id);
+ return;
+ }
+
+ dc_ctrl = rkisp1_read(rkisp1, rsz->config->dual_crop.ctrl);
+ rkisp1_write(rkisp1, sink_crop->left, rsz->config->dual_crop.h_offset);
+ rkisp1_write(rkisp1, sink_crop->top, rsz->config->dual_crop.v_offset);
+ rkisp1_write(rkisp1, sink_crop->width, rsz->config->dual_crop.h_size);
+ rkisp1_write(rkisp1, sink_crop->height, rsz->config->dual_crop.v_size);
+ dc_ctrl |= rsz->config->dual_crop.yuvmode_mask;
+ dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
+ rkisp1_write(rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
+
+ dev_dbg(rkisp1->dev, "stream %d crop: %dx%d -> %dx%d\n", rsz->id,
+ sink_fmt->width, sink_fmt->height,
+ sink_crop->width, sink_crop->height);
+}
+
+/* ----------------------------------------------------------------------------
+ * Resizer hw configs
+ */
+
+static void rkisp1_rsz_dump_regs(struct rkisp1_resizer *rsz)
+{
+ dev_dbg(rsz->rkisp1->dev,
+ "RSZ_CTRL 0x%08x/0x%08x\n"
+ "RSZ_SCALE_HY %d/%d\n"
+ "RSZ_SCALE_HCB %d/%d\n"
+ "RSZ_SCALE_HCR %d/%d\n"
+ "RSZ_SCALE_VY %d/%d\n"
+ "RSZ_SCALE_VC %d/%d\n"
+ "RSZ_PHASE_HY %d/%d\n"
+ "RSZ_PHASE_HC %d/%d\n"
+ "RSZ_PHASE_VY %d/%d\n"
+ "RSZ_PHASE_VC %d/%d\n",
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy_shd),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc),
+ rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc_shd));
+}
+
+static void rkisp1_rsz_update_shadow(struct rkisp1_resizer *rsz,
+ enum rkisp1_shadow_regs_when when)
+{
+ u32 ctrl_cfg = rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl);
+
+ if (when == RKISP1_SHADOW_REGS_ASYNC)
+ ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO;
+ else
+ ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD;
+
+ rkisp1_write(rsz->rkisp1, ctrl_cfg, rsz->config->rsz.ctrl);
+}
+
+static u32 rkisp1_rsz_calc_ratio(u32 len_sink, u32 len_src)
+{
+ if (len_sink < len_src)
+ return ((len_sink - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
+ (len_src - 1);
+
+ return ((len_src - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
+ (len_sink - 1) + 1;
+}
+
+static void rkisp1_rsz_disable(struct rkisp1_resizer *rsz,
+ enum rkisp1_shadow_regs_when when)
+{
+ rkisp1_write(rsz->rkisp1, 0, rsz->config->rsz.ctrl);
+
+ if (when == RKISP1_SHADOW_REGS_SYNC)
+ rkisp1_rsz_update_shadow(rsz, when);
+}
+
+static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
+ struct v4l2_rect *sink_y,
+ struct v4l2_rect *sink_c,
+ struct v4l2_rect *src_y,
+ struct v4l2_rect *src_c,
+ enum rkisp1_shadow_regs_when when)
+{
+ struct rkisp1_device *rkisp1 = rsz->rkisp1;
+ u32 ratio, rsz_ctrl = 0;
+ unsigned int i;
+
+ /* No phase offset */
+ rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hy);
+ rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hc);
+ rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vy);
+ rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vc);
+
+ /* Linear interpolation */
+ for (i = 0; i < 64; i++) {
+ rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut_addr);
+ rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut);
+ }
+
+ if (sink_y->width != src_y->width) {
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE;
+ if (sink_y->width < src_y->width)
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP;
+ ratio = rkisp1_rsz_calc_ratio(sink_y->width, src_y->width);
+ rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hy);
+ }
+
+ if (sink_c->width != src_c->width) {
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE;
+ if (sink_c->width < src_c->width)
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP;
+ ratio = rkisp1_rsz_calc_ratio(sink_c->width, src_c->width);
+ rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcb);
+ rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcr);
+ }
+
+ if (sink_y->height != src_y->height) {
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE;
+ if (sink_y->height < src_y->height)
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP;
+ ratio = rkisp1_rsz_calc_ratio(sink_y->height, src_y->height);
+ rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vy);
+ }
+
+ if (sink_c->height != src_c->height) {
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE;
+ if (sink_c->height < src_c->height)
+ rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP;
+ ratio = rkisp1_rsz_calc_ratio(sink_c->height, src_c->height);
+ rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vc);
+ }
+
+ rkisp1_write(rkisp1, rsz_ctrl, rsz->config->rsz.ctrl);
+
+ rkisp1_rsz_update_shadow(rsz, when);
+}
+
+static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
+ enum rkisp1_shadow_regs_when when)
+{
+ const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info;
+ struct v4l2_rect sink_y, sink_c, src_y, src_c;
+ struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
+ struct v4l2_rect *sink_crop;
+
+ sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code);
+ sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ sink_yuv_info = rkisp1_rsz_get_yuv_mbus_info(sink_fmt->code);
+
+ /*
+ * The resizer only works on yuv formats,
+ * so return if it is bayer format.
+ */
+ if (rsz->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+ rkisp1_rsz_disable(rsz, when);
+ return;
+ }
+
+ sink_y.width = sink_crop->width;
+ sink_y.height = sink_crop->height;
+ src_y.width = src_fmt->width;
+ src_y.height = src_fmt->height;
+
+ sink_c.width = sink_y.width / sink_yuv_info->hdiv;
+ sink_c.height = sink_y.height / sink_yuv_info->vdiv;
+
+ /*
+ * The resizer is used not only to change the dimensions of the frame
+ * but also to change the scale for YUV formats,
+ * (4:2:2 -> 4:2:0 for example). So the width/height of the CbCr
+ * streams should be set according to the media bus format in the src pad.
+ */
+ src_c.width = src_y.width / src_yuv_info->hdiv;
+ src_c.height = src_y.height / src_yuv_info->vdiv;
+
+ if (sink_c.width == src_c.width && sink_c.height == src_c.height) {
+ rkisp1_rsz_disable(rsz, when);
+ return;
+ }
+
+ dev_dbg(rsz->rkisp1->dev, "stream %d rsz/scale: %dx%d -> %dx%d\n",
+ rsz->id, sink_crop->width, sink_crop->height,
+ src_fmt->width, src_fmt->height);
+ dev_dbg(rsz->rkisp1->dev, "chroma scaling %dx%d -> %dx%d\n",
+ sink_c.width, sink_c.height, src_c.width, src_c.height);
+
+ /* set values in the hw */
+ rkisp1_rsz_config_regs(rsz, &sink_y, &sink_c, &src_y, &src_c, when);
+
+ rkisp1_rsz_dump_regs(rsz);
+}
+
+/* ----------------------------------------------------------------------------
+ * Subdev pad operations
+ */
+
+static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct rkisp1_resizer *rsz =
+ container_of(sd, struct rkisp1_resizer, sd);
+ struct v4l2_subdev_pad_config dummy_cfg;
+ u32 pad = code->pad;
+ int ret;
+
+ if (code->pad == RKISP1_RSZ_PAD_SRC) {
+ /* supported mbus codes on the src are the same as in the capture */
+ struct rkisp1_capture *cap = &rsz->rkisp1->capture_devs[rsz->id];
+
+ return rkisp1_cap_enum_mbus_codes(cap, code);
+ }
+
+ /*
+ * The selfpath capture doesn't support bayer formats. Therefore the selfpath resizer
+ * should support only YUV422 on the sink pad
+ */
+ if (rsz->id == RKISP1_SELFPATH) {
+ if (code->index > 0)
+ return -EINVAL;
+ code->code = MEDIA_BUS_FMT_YUYV8_2X8;
+ return 0;
+ }
+
+ /* supported mbus codes on the sink pad are the same as isp src pad */
+ code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO;
+ ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code,
+ &dummy_cfg, code);
+
+ /* restore pad */
+ code->pad = pad;
+ code->flags = 0;
+ return ret;
+}
+
+static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg)
+{
+ struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
+ struct v4l2_rect *sink_crop;
+
+ sink_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SRC);
+ sink_fmt->width = RKISP1_DEFAULT_WIDTH;
+ sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
+ sink_fmt->field = V4L2_FIELD_NONE;
+ sink_fmt->code = RKISP1_DEF_FMT;
+
+ sink_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_RSZ_PAD_SINK);
+ sink_crop->width = RKISP1_DEFAULT_WIDTH;
+ sink_crop->height = RKISP1_DEFAULT_HEIGHT;
+ sink_crop->left = 0;
+ sink_crop->top = 0;
+
+ src_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SINK);
+ *src_fmt = *sink_fmt;
+
+ /* NOTE: there is no crop in the source pad, only in the sink */
+
+ return 0;
+}
+
+static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_mbus_framefmt *format,
+ unsigned int which)
+{
+ const struct rkisp1_isp_mbus_info *mbus_info;
+ struct v4l2_mbus_framefmt *src_fmt;
+
+ src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
+ mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
+
+ /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */
+ if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
+ rkisp1_rsz_get_yuv_mbus_info(format->code))
+ src_fmt->code = format->code;
+
+ src_fmt->width = clamp_t(u32, format->width,
+ rsz->config->min_rsz_width,
+ rsz->config->max_rsz_width);
+ src_fmt->height = clamp_t(u32, format->height,
+ rsz->config->min_rsz_height,
+ rsz->config->max_rsz_height);
+
+ *format = *src_fmt;
+}
+
+static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_rect *r,
+ unsigned int which)
+{
+ const struct rkisp1_isp_mbus_info *mbus_info;
+ struct v4l2_mbus_framefmt *sink_fmt;
+ struct v4l2_rect *sink_crop;
+
+ sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
+ sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+ which);
+
+ /* Not crop for MP bayer raw data */
+ mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+
+ if (rsz->id == RKISP1_MAINPATH &&
+ mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+ sink_crop->left = 0;
+ sink_crop->top = 0;
+ sink_crop->width = sink_fmt->width;
+ sink_crop->height = sink_fmt->height;
+
+ *r = *sink_crop;
+ return;
+ }
+
+ sink_crop->left = ALIGN(r->left, 2);
+ sink_crop->width = ALIGN(r->width, 2);
+ sink_crop->top = r->top;
+ sink_crop->height = r->height;
+ rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
+
+ *r = *sink_crop;
+}
+
+static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_mbus_framefmt *format,
+ unsigned int which)
+{
+ const struct rkisp1_isp_mbus_info *mbus_info;
+ struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
+ struct v4l2_rect *sink_crop;
+
+ sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
+ src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
+ sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+ which);
+ if (rsz->id == RKISP1_SELFPATH)
+ sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
+ else
+ sink_fmt->code = format->code;
+
+ mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+ if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
+ sink_fmt->code = RKISP1_DEF_FMT;
+ mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
+ }
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ rsz->pixel_enc = mbus_info->pixel_enc;
+
+ /* Propagete to source pad */
+ src_fmt->code = sink_fmt->code;
+
+ sink_fmt->width = clamp_t(u32, format->width,
+ RKISP1_ISP_MIN_WIDTH,
+ RKISP1_ISP_MAX_WIDTH);
+ sink_fmt->height = clamp_t(u32, format->height,
+ RKISP1_ISP_MIN_HEIGHT,
+ RKISP1_ISP_MAX_HEIGHT);
+
+ *format = *sink_fmt;
+
+ /* Update sink crop */
+ rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which);
+}
+
+static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct rkisp1_resizer *rsz =
+ container_of(sd, struct rkisp1_resizer, sd);
+
+ mutex_lock(&rsz->ops_lock);
+ fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which);
+ mutex_unlock(&rsz->ops_lock);
+ return 0;
+}
+
+static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct rkisp1_resizer *rsz =
+ container_of(sd, struct rkisp1_resizer, sd);
+
+ mutex_lock(&rsz->ops_lock);
+ if (fmt->pad == RKISP1_RSZ_PAD_SINK)
+ rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which);
+ else
+ rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which);
+
+ mutex_unlock(&rsz->ops_lock);
+ return 0;
+}
+
+static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
+{
+ struct rkisp1_resizer *rsz =
+ container_of(sd, struct rkisp1_resizer, sd);
+ struct v4l2_mbus_framefmt *mf_sink;
+ int ret = 0;
+
+ if (sel->pad == RKISP1_RSZ_PAD_SRC)
+ return -EINVAL;
+
+ mutex_lock(&rsz->ops_lock);
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+ sel->which);
+ sel->r.height = mf_sink->height;
+ sel->r.width = mf_sink->width;
+ sel->r.left = 0;
+ sel->r.top = 0;
+ break;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
+ sel->which);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ mutex_unlock(&rsz->ops_lock);
+ return ret;
+}
+
+static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_selection *sel)
+{
+ struct rkisp1_resizer *rsz =
+ container_of(sd, struct rkisp1_resizer, sd);
+
+ if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC)
+ return -EINVAL;
+
+ dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
+ sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
+
+ mutex_lock(&rsz->ops_lock);
+ rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which);
+ mutex_unlock(&rsz->ops_lock);
+
+ return 0;
+}
+
+static const struct media_entity_operations rkisp1_rsz_media_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
+ .enum_mbus_code = rkisp1_rsz_enum_mbus_code,
+ .get_selection = rkisp1_rsz_get_selection,
+ .set_selection = rkisp1_rsz_set_selection,
+ .init_cfg = rkisp1_rsz_init_config,
+ .get_fmt = rkisp1_rsz_get_fmt,
+ .set_fmt = rkisp1_rsz_set_fmt,
+ .link_validate = v4l2_subdev_link_validate_default,
+};
+
+/* ----------------------------------------------------------------------------
+ * Stream operations
+ */
+
+static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct rkisp1_resizer *rsz =
+ container_of(sd, struct rkisp1_resizer, sd);
+ struct rkisp1_device *rkisp1 = rsz->rkisp1;
+ struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
+ enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
+
+ if (!enable) {
+ rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
+ rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
+ return 0;
+ }
+
+ if (other->is_streaming)
+ when = RKISP1_SHADOW_REGS_ASYNC;
+
+ mutex_lock(&rsz->ops_lock);
+ rkisp1_rsz_config(rsz, when);
+ rkisp1_dcrop_config(rsz);
+
+ mutex_unlock(&rsz->ops_lock);
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = {
+ .s_stream = rkisp1_rsz_s_stream,
+};
+
+static const struct v4l2_subdev_ops rkisp1_rsz_ops = {
+ .video = &rkisp1_rsz_video_ops,
+ .pad = &rkisp1_rsz_pad_ops,
+};
+
+static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
+{
+ v4l2_device_unregister_subdev(&rsz->sd);
+ media_entity_cleanup(&rsz->sd.entity);
+}
+
+static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
+{
+ static const char * const dev_names[] = {
+ RKISP1_RSZ_MP_DEV_NAME,
+ RKISP1_RSZ_SP_DEV_NAME
+ };
+ struct media_pad *pads = rsz->pads;
+ struct v4l2_subdev *sd = &rsz->sd;
+ int ret;
+
+ if (rsz->id == RKISP1_SELFPATH)
+ rsz->config = &rkisp1_rsz_config_sp;
+ else
+ rsz->config = &rkisp1_rsz_config_mp;
+
+ v4l2_subdev_init(sd, &rkisp1_rsz_ops);
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sd->entity.ops = &rkisp1_rsz_media_ops;
+ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
+ sd->owner = THIS_MODULE;
+ strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name));
+
+ pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
+ MEDIA_PAD_FL_MUST_CONNECT;
+ pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
+ MEDIA_PAD_FL_MUST_CONNECT;
+
+ rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC;
+
+ mutex_init(&rsz->ops_lock);
+ ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
+ if (ret)
+ return ret;
+
+ ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
+ if (ret) {
+ dev_err(sd->dev, "Failed to register resizer subdev\n");
+ goto err_cleanup_media_entity;
+ }
+
+ rkisp1_rsz_init_config(sd, rsz->pad_cfg);
+ return 0;
+
+err_cleanup_media_entity:
+ media_entity_cleanup(&sd->entity);
+
+ return ret;
+}
+
+int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_resizer *rsz;
+ unsigned int i, j;
+ int ret;
+
+ for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
+ rsz = &rkisp1->resizer_devs[i];
+ rsz->rkisp1 = rkisp1;
+ rsz->id = i;
+ ret = rkisp1_rsz_register(rsz);
+ if (ret)
+ goto err_unreg_resizer_devs;
+ }
+
+ return 0;
+
+err_unreg_resizer_devs:
+ for (j = 0; j < i; j++) {
+ rsz = &rkisp1->resizer_devs[j];
+ rkisp1_rsz_unregister(rsz);
+ }
+
+ return ret;
+}
+
+void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH];
+ struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH];
+
+ rkisp1_rsz_unregister(mp);
+ rkisp1_rsz_unregister(sp);
+}
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Rockchip ISP1 Driver - Stats subdevice
+ *
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h> /* for ISP statistics */
+
+#include "rkisp1-common.h"
+
+#define RKISP1_STATS_DEV_NAME RKISP1_DRIVER_NAME "_stats"
+
+#define RKISP1_ISP_STATS_REQ_BUFS_MIN 2
+#define RKISP1_ISP_STATS_REQ_BUFS_MAX 8
+
+static int rkisp1_stats_enum_fmt_meta_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct video_device *video = video_devdata(file);
+ struct rkisp1_stats *stats = video_get_drvdata(video);
+
+ if (f->index > 0 || f->type != video->queue->type)
+ return -EINVAL;
+
+ f->pixelformat = stats->vdev_fmt.fmt.meta.dataformat;
+ return 0;
+}
+
+static int rkisp1_stats_g_fmt_meta_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct video_device *video = video_devdata(file);
+ struct rkisp1_stats *stats = video_get_drvdata(video);
+ struct v4l2_meta_format *meta = &f->fmt.meta;
+
+ if (f->type != video->queue->type)
+ return -EINVAL;
+
+ memset(meta, 0, sizeof(*meta));
+ meta->dataformat = stats->vdev_fmt.fmt.meta.dataformat;
+ meta->buffersize = stats->vdev_fmt.fmt.meta.buffersize;
+
+ return 0;
+}
+
+static int rkisp1_stats_querycap(struct file *file,
+ void *priv, struct v4l2_capability *cap)
+{
+ struct video_device *vdev = video_devdata(file);
+
+ strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
+ strscpy(cap->card, vdev->name, sizeof(cap->card));
+ strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
+
+ return 0;
+}
+
+/* ISP video device IOCTLs */
+static const struct v4l2_ioctl_ops rkisp1_stats_ioctl = {
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_enum_fmt_meta_cap = rkisp1_stats_enum_fmt_meta_cap,
+ .vidioc_g_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
+ .vidioc_s_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
+ .vidioc_try_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
+ .vidioc_querycap = rkisp1_stats_querycap,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static const struct v4l2_file_operations rkisp1_stats_fops = {
+ .mmap = vb2_fop_mmap,
+ .unlocked_ioctl = video_ioctl2,
+ .poll = vb2_fop_poll,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release
+};
+
+static int rkisp1_stats_vb2_queue_setup(struct vb2_queue *vq,
+ unsigned int *num_buffers,
+ unsigned int *num_planes,
+ unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ *num_planes = 1;
+
+ *num_buffers = clamp_t(u32, *num_buffers, RKISP1_ISP_STATS_REQ_BUFS_MIN,
+ RKISP1_ISP_STATS_REQ_BUFS_MAX);
+
+ sizes[0] = sizeof(struct rkisp1_stat_buffer);
+
+ return 0;
+}
+
+static void rkisp1_stats_vb2_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct rkisp1_buffer *stats_buf =
+ container_of(vbuf, struct rkisp1_buffer, vb);
+ struct vb2_queue *vq = vb->vb2_queue;
+ struct rkisp1_stats *stats_dev = vq->drv_priv;
+
+ stats_buf->vaddr = vb2_plane_vaddr(vb, 0);
+
+ spin_lock_irq(&stats_dev->lock);
+ list_add_tail(&stats_buf->queue, &stats_dev->stat);
+ spin_unlock_irq(&stats_dev->lock);
+}
+
+static int rkisp1_stats_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+ if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_stat_buffer))
+ return -EINVAL;
+
+ vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_stat_buffer));
+
+ return 0;
+}
+
+static void rkisp1_stats_vb2_stop_streaming(struct vb2_queue *vq)
+{
+ struct rkisp1_stats *stats = vq->drv_priv;
+ struct rkisp1_buffer *buf;
+ unsigned int i;
+
+ spin_lock_irq(&stats->lock);
+ for (i = 0; i < RKISP1_ISP_STATS_REQ_BUFS_MAX; i++) {
+ if (list_empty(&stats->stat))
+ break;
+ buf = list_first_entry(&stats->stat,
+ struct rkisp1_buffer, queue);
+ list_del(&buf->queue);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+ }
+ spin_unlock_irq(&stats->lock);
+}
+
+static const struct vb2_ops rkisp1_stats_vb2_ops = {
+ .queue_setup = rkisp1_stats_vb2_queue_setup,
+ .buf_queue = rkisp1_stats_vb2_buf_queue,
+ .buf_prepare = rkisp1_stats_vb2_buf_prepare,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .stop_streaming = rkisp1_stats_vb2_stop_streaming,
+};
+
+static int
+rkisp1_stats_init_vb2_queue(struct vb2_queue *q, struct rkisp1_stats *stats)
+{
+ struct rkisp1_vdev_node *node;
+
+ node = container_of(q, struct rkisp1_vdev_node, buf_queue);
+
+ q->type = V4L2_BUF_TYPE_META_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+ q->drv_priv = stats;
+ q->ops = &rkisp1_stats_vb2_ops;
+ q->mem_ops = &vb2_vmalloc_memops;
+ q->buf_struct_size = sizeof(struct rkisp1_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &node->vlock;
+
+ return vb2_queue_init(q);
+}
+
+static void rkisp1_stats_get_awb_meas(struct rkisp1_stats *stats,
+ struct rkisp1_stat_buffer *pbuf)
+{
+ /* Protect against concurrent access from ISR? */
+ struct rkisp1_device *rkisp1 = stats->rkisp1;
+ u32 reg_val;
+
+ pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AWB;
+ reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_WHITE_CNT);
+ pbuf->params.awb.awb_mean[0].cnt =
+ RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(reg_val);
+ reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_MEAN);
+
+ pbuf->params.awb.awb_mean[0].mean_cr_or_r =
+ RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(reg_val);
+ pbuf->params.awb.awb_mean[0].mean_cb_or_b =
+ RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(reg_val);
+ pbuf->params.awb.awb_mean[0].mean_y_or_g =
+ RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(reg_val);
+}
+
+static void rkisp1_stats_get_aec_meas(struct rkisp1_stats *stats,
+ struct rkisp1_stat_buffer *pbuf)
+{
+ struct rkisp1_device *rkisp1 = stats->rkisp1;
+ unsigned int i;
+
+ pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP;
+ for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX; i++)
+ pbuf->params.ae.exp_mean[i] =
+ (u8)rkisp1_read(rkisp1,
+ RKISP1_CIF_ISP_EXP_MEAN_00 + i * 4);
+}
+
+static void rkisp1_stats_get_afc_meas(struct rkisp1_stats *stats,
+ struct rkisp1_stat_buffer *pbuf)
+{
+ struct rkisp1_device *rkisp1 = stats->rkisp1;
+ struct rkisp1_cif_isp_af_stat *af;
+
+ pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AFM;
+
+ af = &pbuf->params.af;
+ af->window[0].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_A);
+ af->window[0].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_A);
+ af->window[1].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_B);
+ af->window[1].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_B);
+ af->window[2].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_C);
+ af->window[2].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_C);
+}
+
+static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats,
+ struct rkisp1_stat_buffer *pbuf)
+{
+ struct rkisp1_device *rkisp1 = stats->rkisp1;
+ unsigned int i;
+
+ pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST;
+ for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++)
+ pbuf->params.hist.hist_bins[i] =
+ (u8)rkisp1_read(rkisp1,
+ RKISP1_CIF_ISP_HIST_BIN_0 + i * 4);
+}
+
+static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats,
+ struct rkisp1_stat_buffer *pbuf)
+{
+ struct rkisp1_device *rkisp1 = stats->rkisp1;
+ const struct rkisp1_isp_mbus_info *in_fmt = rkisp1->isp.sink_fmt;
+ struct rkisp1_cif_isp_bls_meas_val *bls_val;
+
+ bls_val = &pbuf->params.ae.bls_val;
+ if (in_fmt->bayer_pat == RKISP1_RAW_BGGR) {
+ bls_val->meas_b =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+ bls_val->meas_gb =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+ bls_val->meas_gr =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+ bls_val->meas_r =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+ } else if (in_fmt->bayer_pat == RKISP1_RAW_GBRG) {
+ bls_val->meas_gb =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+ bls_val->meas_b =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+ bls_val->meas_r =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+ bls_val->meas_gr =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+ } else if (in_fmt->bayer_pat == RKISP1_RAW_GRBG) {
+ bls_val->meas_gr =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+ bls_val->meas_r =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+ bls_val->meas_b =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+ bls_val->meas_gb =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+ } else if (in_fmt->bayer_pat == RKISP1_RAW_RGGB) {
+ bls_val->meas_r =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
+ bls_val->meas_gr =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
+ bls_val->meas_gb =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
+ bls_val->meas_b =
+ rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
+ }
+}
+
+static void
+rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris)
+{
+ struct rkisp1_stat_buffer *cur_stat_buf;
+ struct rkisp1_buffer *cur_buf = NULL;
+ unsigned int frame_sequence = stats->rkisp1->isp.frame_sequence;
+ u64 timestamp = ktime_get_ns();
+
+ /* get one empty buffer */
+ if (!list_empty(&stats->stat)) {
+ cur_buf = list_first_entry(&stats->stat,
+ struct rkisp1_buffer, queue);
+ list_del(&cur_buf->queue);
+ }
+
+ if (!cur_buf)
+ return;
+
+ cur_stat_buf =
+ (struct rkisp1_stat_buffer *)(cur_buf->vaddr);
+
+ if (isp_ris & RKISP1_CIF_ISP_AWB_DONE)
+ rkisp1_stats_get_awb_meas(stats, cur_stat_buf);
+
+ if (isp_ris & RKISP1_CIF_ISP_AFM_FIN)
+ rkisp1_stats_get_afc_meas(stats, cur_stat_buf);
+
+ if (isp_ris & RKISP1_CIF_ISP_EXP_END) {
+ rkisp1_stats_get_aec_meas(stats, cur_stat_buf);
+ rkisp1_stats_get_bls_meas(stats, cur_stat_buf);
+ }
+
+ if (isp_ris & RKISP1_CIF_ISP_HIST_MEASURE_RDY)
+ rkisp1_stats_get_hst_meas(stats, cur_stat_buf);
+
+ vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0,
+ sizeof(struct rkisp1_stat_buffer));
+ cur_buf->vb.sequence = frame_sequence;
+ cur_buf->vb.vb2_buf.timestamp = timestamp;
+ vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+}
+
+void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris)
+{
+ struct rkisp1_device *rkisp1 = stats->rkisp1;
+ unsigned int isp_mis_tmp = 0;
+
+ spin_lock(&stats->lock);
+
+ rkisp1_write(rkisp1, RKISP1_STATS_MEAS_MASK, RKISP1_CIF_ISP_ICR);
+
+ isp_mis_tmp = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
+ if (isp_mis_tmp & RKISP1_STATS_MEAS_MASK)
+ rkisp1->debug.stats_error++;
+
+ if (isp_ris & RKISP1_STATS_MEAS_MASK)
+ rkisp1_stats_send_measurement(stats, isp_ris);
+
+ spin_unlock(&stats->lock);
+}
+
+static void rkisp1_init_stats(struct rkisp1_stats *stats)
+{
+ stats->vdev_fmt.fmt.meta.dataformat =
+ V4L2_META_FMT_RK_ISP1_STAT_3A;
+ stats->vdev_fmt.fmt.meta.buffersize =
+ sizeof(struct rkisp1_stat_buffer);
+}
+
+int rkisp1_stats_register(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_stats *stats = &rkisp1->stats;
+ struct rkisp1_vdev_node *node = &stats->vnode;
+ struct video_device *vdev = &node->vdev;
+ int ret;
+
+ stats->rkisp1 = rkisp1;
+ mutex_init(&node->vlock);
+ INIT_LIST_HEAD(&stats->stat);
+ spin_lock_init(&stats->lock);
+
+ strscpy(vdev->name, RKISP1_STATS_DEV_NAME, sizeof(vdev->name));
+
+ video_set_drvdata(vdev, stats);
+ vdev->ioctl_ops = &rkisp1_stats_ioctl;
+ vdev->fops = &rkisp1_stats_fops;
+ vdev->release = video_device_release_empty;
+ vdev->lock = &node->vlock;
+ vdev->v4l2_dev = &rkisp1->v4l2_dev;
+ vdev->queue = &node->buf_queue;
+ vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
+ vdev->vfl_dir = VFL_DIR_RX;
+ rkisp1_stats_init_vb2_queue(vdev->queue, stats);
+ rkisp1_init_stats(stats);
+ video_set_drvdata(vdev, stats);
+
+ node->pad.flags = MEDIA_PAD_FL_SINK;
+ ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
+ if (ret)
+ goto err_mutex_destroy;
+
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(&vdev->dev,
+ "failed to register %s, ret=%d\n", vdev->name, ret);
+ goto err_cleanup_media_entity;
+ }
+
+ return 0;
+
+err_cleanup_media_entity:
+ media_entity_cleanup(&vdev->entity);
+err_mutex_destroy:
+ mutex_destroy(&node->vlock);
+ return ret;
+}
+
+void rkisp1_stats_unregister(struct rkisp1_device *rkisp1)
+{
+ struct rkisp1_stats *stats = &rkisp1->stats;
+ struct rkisp1_vdev_node *node = &stats->vnode;
+ struct video_device *vdev = &node->vdev;
+
+ vb2_video_unregister_device(vdev);
+ media_entity_cleanup(&vdev->entity);
+ mutex_destroy(&node->vlock);
+}
source "drivers/staging/media/ipu3/Kconfig"
-source "drivers/staging/media/rkisp1/Kconfig"
-
endif
obj-$(CONFIG_TEGRA_VDE) += tegra-vde/
obj-$(CONFIG_VIDEO_HANTRO) += hantro/
obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
-obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rkisp1/
obj-$(CONFIG_VIDEO_ZORAN) += zoran/
+++ /dev/null
-# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/media/rockchip-isp1.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Rockchip SoC Image Signal Processing unit v1
-
-maintainers:
- - Helen Koike <helen.koike@collabora.com>
-
-description: |
- Rockchip ISP1 is the Camera interface for the Rockchip series of SoCs
- which contains image processing, scaling, and compression functions.
-
-properties:
- compatible:
- const: rockchip,rk3399-cif-isp
-
- reg:
- maxItems: 1
-
- interrupts:
- maxItems: 1
-
- clocks:
- minItems: 3
- items:
- # isp0 and isp1
- - description: ISP clock
- - description: ISP AXI clock
- - description: ISP AHB clock
- # only for isp1
- - description: ISP Pixel clock
-
- clock-names:
- minItems: 3
- items:
- # isp0 and isp1
- - const: isp
- - const: aclk
- - const: hclk
- # only for isp1
- - const: pclk_isp
-
- iommus:
- maxItems: 1
-
- phys:
- maxItems: 1
- description: phandle for the PHY port
-
- phy-names:
- const: dphy
-
- power-domains:
- maxItems: 1
-
- # See ./video-interfaces.txt for details
- ports:
- type: object
- additionalProperties: false
-
- properties:
- "#address-cells":
- const: 1
-
- "#size-cells":
- const: 0
-
- port@0:
- type: object
- description: connection point for sensors at MIPI-DPHY RX0
- additionalProperties: false
-
- properties:
- "#address-cells":
- const: 1
-
- "#size-cells":
- const: 0
-
- reg:
- const: 0
-
- patternProperties:
- endpoint:
- type: object
- additionalProperties: false
-
- properties:
- reg:
- maxItems: 1
-
- data-lanes:
- minItems: 1
- maxItems: 4
-
- remote-endpoint: true
-
- required:
- - reg
- - "#address-cells"
- - "#size-cells"
-
- required:
- - "#address-cells"
- - "#size-cells"
- - port@0
-
-required:
- - compatible
- - reg
- - interrupts
- - clocks
- - clock-names
- - iommus
- - phys
- - phy-names
- - power-domains
- - ports
-
-if:
- properties:
- compatible:
- contains:
- const: rockchip,rk3399-cif-isp
-then:
- properties:
- clocks:
- minItems: 3
- maxItems: 4
- clock-names:
- minItems: 3
- maxItems: 4
-
-additionalProperties: false
-
-examples:
- - |
-
- #include <dt-bindings/clock/rk3399-cru.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/power/rk3399-power.h>
-
- parent0: parent {
- #address-cells = <2>;
- #size-cells = <2>;
-
- isp0: isp0@ff910000 {
- compatible = "rockchip,rk3399-cif-isp";
- reg = <0x0 0xff910000 0x0 0x4000>;
- interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_ISP0>,
- <&cru ACLK_ISP0_WRAPPER>,
- <&cru HCLK_ISP0_WRAPPER>;
- clock-names = "isp", "aclk", "hclk";
- iommus = <&isp0_mmu>;
- phys = <&dphy>;
- phy-names = "dphy";
- power-domains = <&power RK3399_PD_ISP0>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- mipi_in_wcam: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&wcam_out>;
- data-lanes = <1 2>;
- };
-
- mipi_in_ucam: endpoint@1 {
- reg = <1>;
- remote-endpoint = <&ucam_out>;
- data-lanes = <1>;
- };
- };
- };
- };
-
- i2c7: i2c {
- #address-cells = <1>;
- #size-cells = <0>;
-
- wcam: camera@36 {
- compatible = "ovti,ov5695";
- reg = <0x36>;
-
- port {
- wcam_out: endpoint {
- remote-endpoint = <&mipi_in_wcam>;
- data-lanes = <1 2>;
- };
- };
- };
-
- ucam: camera@3c {
- compatible = "ovti,ov2685";
- reg = <0x3c>;
-
- port {
- ucam_out: endpoint {
- remote-endpoint = <&mipi_in_ucam>;
- data-lanes = <1>;
- };
- };
- };
- };
- };
+++ /dev/null
-# SPDX-License-Identifier: GPL-2.0-only
-
-config VIDEO_ROCKCHIP_ISP1
- tristate "Rockchip Image Signal Processing v1 Unit driver"
- depends on VIDEO_V4L2 && OF
- depends on ARCH_ROCKCHIP || COMPILE_TEST
- select MEDIA_CONTROLLER
- select VIDEO_V4L2_SUBDEV_API
- select VIDEOBUF2_DMA_CONTIG
- select VIDEOBUF2_VMALLOC
- select V4L2_FWNODE
- select GENERIC_PHY_MIPI_DPHY
- default n
- help
- Enable this to support the Image Signal Processing (ISP) module
- present in RK3399 SoCs.
-
- To compile this driver as a module, choose M here: the module
- will be called rockchip-isp1.
+++ /dev/null
-# SPDX-License-Identifier: GPL-2.0
-
-obj-$(CONFIG_VIDEO_ROCKCHIP_ISP1) += rockchip-isp1.o
-rockchip-isp1-objs += rkisp1-capture.o \
- rkisp1-common.o \
- rkisp1-dev.o \
- rkisp1-isp.o \
- rkisp1-resizer.o \
- rkisp1-stats.o \
- rkisp1-params.o
+++ /dev/null
-* Fix checkpatch errors.
-
-NOTES:
-* All v4l2-compliance test must pass.
-* Stats and params can be tested with libcamera and ChromiumOS stack.
-
-Please CC patches to Linux Media <linux-media@vger.kernel.org> and
-Helen Koike <helen.koike@collabora.com>.
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - V4l capture device
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <linux/delay.h>
-#include <linux/pm_runtime.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-fh.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mc.h>
-#include <media/v4l2-subdev.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "rkisp1-common.h"
-
-/*
- * NOTE: There are two capture video devices in rkisp1, selfpath and mainpath.
- *
- * differences between selfpath and mainpath
- * available mp sink input: isp
- * available sp sink input : isp, dma(TODO)
- * available mp sink pad fmts: yuv422, raw
- * available sp sink pad fmts: yuv422, yuv420......
- * available mp source fmts: yuv, raw, jpeg(TODO)
- * available sp source fmts: yuv, rgb
- */
-
-#define RKISP1_SP_DEV_NAME RKISP1_DRIVER_NAME "_selfpath"
-#define RKISP1_MP_DEV_NAME RKISP1_DRIVER_NAME "_mainpath"
-
-#define RKISP1_MIN_BUFFERS_NEEDED 3
-
-enum rkisp1_plane {
- RKISP1_PLANE_Y = 0,
- RKISP1_PLANE_CB = 1,
- RKISP1_PLANE_CR = 2
-};
-
-/*
- * @fourcc: pixel format
- * @fmt_type: helper filed for pixel format
- * @uv_swap: if cb cr swaped, for yuv
- * @write_format: defines how YCbCr self picture data is written to memory
- * @output_format: defines sp output format
- * @mbus: the mbus code on the src resizer pad that matches the pixel format
- */
-struct rkisp1_capture_fmt_cfg {
- u32 fourcc;
- u8 uv_swap;
- u32 write_format;
- u32 output_format;
- u32 mbus;
-};
-
-struct rkisp1_capture_ops {
- void (*config)(struct rkisp1_capture *cap);
- void (*stop)(struct rkisp1_capture *cap);
- void (*enable)(struct rkisp1_capture *cap);
- void (*disable)(struct rkisp1_capture *cap);
- void (*set_data_path)(struct rkisp1_capture *cap);
- bool (*is_stopped)(struct rkisp1_capture *cap);
-};
-
-struct rkisp1_capture_config {
- const struct rkisp1_capture_fmt_cfg *fmts;
- int fmt_size;
- struct {
- u32 y_size_init;
- u32 cb_size_init;
- u32 cr_size_init;
- u32 y_base_ad_init;
- u32 cb_base_ad_init;
- u32 cr_base_ad_init;
- u32 y_offs_cnt_init;
- u32 cb_offs_cnt_init;
- u32 cr_offs_cnt_init;
- } mi;
-};
-
-/*
- * The supported pixel formats for mainpath. NOTE, pixel formats with identical 'mbus'
- * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
- */
-static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
- /* yuv422 */
- {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV16,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV61,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YVU422M,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- },
- /* yuv400 */
- {
- .fourcc = V4L2_PIX_FMT_GREY,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- },
- /* yuv420 */
- {
- .fourcc = V4L2_PIX_FMT_NV21,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV21M,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12M,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YUV420,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YVU420,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- },
- /* raw */
- {
- .fourcc = V4L2_PIX_FMT_SRGGB8,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG8,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
- }, {
- .fourcc = V4L2_PIX_FMT_SGBRG8,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
- }, {
- .fourcc = V4L2_PIX_FMT_SBGGR8,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
- .mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
- }, {
- .fourcc = V4L2_PIX_FMT_SRGGB10,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG10,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
- }, {
- .fourcc = V4L2_PIX_FMT_SGBRG10,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
- }, {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
- }, {
- .fourcc = V4L2_PIX_FMT_SRGGB12,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG12,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
- }, {
- .fourcc = V4L2_PIX_FMT_SGBRG12,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
- }, {
- .fourcc = V4L2_PIX_FMT_SBGGR12,
- .write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
- .mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
- },
-};
-
-/*
- * The supported pixel formats for selfpath. NOTE, pixel formats with identical 'mbus'
- * are grouped together. This is assumed and used by the function rkisp1_cap_enum_mbus_codes
- */
-static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
- /* yuv422 */
- {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_INT,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV16,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV61,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YVU422M,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- },
- /* yuv400 */
- {
- .fourcc = V4L2_PIX_FMT_GREY,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV400,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- },
- /* rgb */
- {
- .fourcc = V4L2_PIX_FMT_XBGR32,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB888,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB565,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_RGB565,
- .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
- },
- /* yuv420 */
- {
- .fourcc = V4L2_PIX_FMT_NV21,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV21M,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12M,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_SPLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YUV420,
- .uv_swap = 0,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- }, {
- .fourcc = V4L2_PIX_FMT_YVU420,
- .uv_swap = 1,
- .write_format = RKISP1_MI_CTRL_SP_WRITE_PLA,
- .output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV420,
- .mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
- },
-};
-
-static const struct rkisp1_capture_config rkisp1_capture_config_mp = {
- .fmts = rkisp1_mp_fmts,
- .fmt_size = ARRAY_SIZE(rkisp1_mp_fmts),
- .mi = {
- .y_size_init = RKISP1_CIF_MI_MP_Y_SIZE_INIT,
- .cb_size_init = RKISP1_CIF_MI_MP_CB_SIZE_INIT,
- .cr_size_init = RKISP1_CIF_MI_MP_CR_SIZE_INIT,
- .y_base_ad_init = RKISP1_CIF_MI_MP_Y_BASE_AD_INIT,
- .cb_base_ad_init = RKISP1_CIF_MI_MP_CB_BASE_AD_INIT,
- .cr_base_ad_init = RKISP1_CIF_MI_MP_CR_BASE_AD_INIT,
- .y_offs_cnt_init = RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT,
- .cb_offs_cnt_init = RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT,
- .cr_offs_cnt_init = RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT,
- },
-};
-
-static const struct rkisp1_capture_config rkisp1_capture_config_sp = {
- .fmts = rkisp1_sp_fmts,
- .fmt_size = ARRAY_SIZE(rkisp1_sp_fmts),
- .mi = {
- .y_size_init = RKISP1_CIF_MI_SP_Y_SIZE_INIT,
- .cb_size_init = RKISP1_CIF_MI_SP_CB_SIZE_INIT,
- .cr_size_init = RKISP1_CIF_MI_SP_CR_SIZE_INIT,
- .y_base_ad_init = RKISP1_CIF_MI_SP_Y_BASE_AD_INIT,
- .cb_base_ad_init = RKISP1_CIF_MI_SP_CB_BASE_AD_INIT,
- .cr_base_ad_init = RKISP1_CIF_MI_SP_CR_BASE_AD_INIT,
- .y_offs_cnt_init = RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT,
- .cb_offs_cnt_init = RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT,
- .cr_offs_cnt_init = RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT,
- },
-};
-
-static inline struct rkisp1_vdev_node *
-rkisp1_vdev_to_node(struct video_device *vdev)
-{
- return container_of(vdev, struct rkisp1_vdev_node, vdev);
-}
-
-int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- const struct rkisp1_capture_fmt_cfg *fmts = cap->config->fmts;
- /*
- * initialize curr_mbus to non existing mbus code 0 to ensure it is
- * different from fmts[0].mbus
- */
- u32 curr_mbus = 0;
- int i, n = 0;
-
- for (i = 0; i < cap->config->fmt_size; i++) {
- if (fmts[i].mbus == curr_mbus)
- continue;
-
- curr_mbus = fmts[i].mbus;
- if (n++ == code->index) {
- code->code = curr_mbus;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-/* ----------------------------------------------------------------------------
- * Stream operations for self-picture path (sp) and main-picture path (mp)
- */
-
-static void rkisp1_mi_config_ctrl(struct rkisp1_capture *cap)
-{
- u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
- mi_ctrl &= ~GENMASK(17, 16);
- mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64;
-
- mi_ctrl &= ~GENMASK(19, 18);
- mi_ctrl |= RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64;
-
- mi_ctrl |= RKISP1_CIF_MI_CTRL_INIT_BASE_EN |
- RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN;
-
- rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static u32 rkisp1_pixfmt_comp_size(const struct v4l2_pix_format_mplane *pixm,
- unsigned int component)
-{
- /*
- * If packed format, then plane_fmt[0].sizeimage is the sum of all
- * components, so we need to calculate just the size of Y component.
- * See rkisp1_fill_pixfmt().
- */
- if (!component && pixm->num_planes == 1)
- return pixm->plane_fmt[0].bytesperline * pixm->height;
- return pixm->plane_fmt[component].sizeimage;
-}
-
-static void rkisp1_irq_frame_end_enable(struct rkisp1_capture *cap)
-{
- u32 mi_imsc = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_IMSC);
-
- mi_imsc |= RKISP1_CIF_MI_FRAME(cap);
- rkisp1_write(cap->rkisp1, mi_imsc, RKISP1_CIF_MI_IMSC);
-}
-
-static void rkisp1_mp_config(struct rkisp1_capture *cap)
-{
- const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
- struct rkisp1_device *rkisp1 = cap->rkisp1;
- u32 reg;
-
- rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
- cap->config->mi.y_size_init);
- rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
- cap->config->mi.cb_size_init);
- rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
- cap->config->mi.cr_size_init);
-
- rkisp1_irq_frame_end_enable(cap);
-
- /* set uv swapping for semiplanar formats */
- if (cap->pix.info->comp_planes == 2) {
- reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
- if (cap->pix.cfg->uv_swap)
- reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
- else
- reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP;
- rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
- }
-
- rkisp1_mi_config_ctrl(cap);
-
- reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
- reg &= ~RKISP1_MI_CTRL_MP_FMT_MASK;
- reg |= cap->pix.cfg->write_format;
- rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
-
- reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
- reg |= RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE;
- rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_sp_config(struct rkisp1_capture *cap)
-{
- const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
- struct rkisp1_device *rkisp1 = cap->rkisp1;
- u32 mi_ctrl, reg;
-
- rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
- cap->config->mi.y_size_init);
- rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
- cap->config->mi.cb_size_init);
- rkisp1_write(rkisp1, rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR),
- cap->config->mi.cr_size_init);
-
- rkisp1_write(rkisp1, pixm->width, RKISP1_CIF_MI_SP_Y_PIC_WIDTH);
- rkisp1_write(rkisp1, pixm->height, RKISP1_CIF_MI_SP_Y_PIC_HEIGHT);
- rkisp1_write(rkisp1, cap->sp_y_stride, RKISP1_CIF_MI_SP_Y_LLENGTH);
-
- rkisp1_irq_frame_end_enable(cap);
-
- /* set uv swapping for semiplanar formats */
- if (cap->pix.info->comp_planes == 2) {
- reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
- if (cap->pix.cfg->uv_swap)
- reg |= RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
- else
- reg &= ~RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP;
- rkisp1_write(rkisp1, reg, RKISP1_CIF_MI_XTD_FORMAT_CTRL);
- }
-
- rkisp1_mi_config_ctrl(cap);
-
- mi_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
- mi_ctrl &= ~RKISP1_MI_CTRL_SP_FMT_MASK;
- mi_ctrl |= cap->pix.cfg->write_format |
- RKISP1_MI_CTRL_SP_INPUT_YUV422 |
- cap->pix.cfg->output_format |
- RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE;
- rkisp1_write(rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_mp_disable(struct rkisp1_capture *cap)
-{
- u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
- mi_ctrl &= ~(RKISP1_CIF_MI_CTRL_MP_ENABLE |
- RKISP1_CIF_MI_CTRL_RAW_ENABLE);
- rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_sp_disable(struct rkisp1_capture *cap)
-{
- u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
- mi_ctrl &= ~RKISP1_CIF_MI_CTRL_SP_ENABLE;
- rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_mp_enable(struct rkisp1_capture *cap)
-{
- u32 mi_ctrl;
-
- rkisp1_mp_disable(cap);
-
- mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
- if (v4l2_is_format_bayer(cap->pix.info))
- mi_ctrl |= RKISP1_CIF_MI_CTRL_RAW_ENABLE;
- /* YUV */
- else
- mi_ctrl |= RKISP1_CIF_MI_CTRL_MP_ENABLE;
-
- rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_sp_enable(struct rkisp1_capture *cap)
-{
- u32 mi_ctrl = rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL);
-
- mi_ctrl |= RKISP1_CIF_MI_CTRL_SP_ENABLE;
- rkisp1_write(cap->rkisp1, mi_ctrl, RKISP1_CIF_MI_CTRL);
-}
-
-static void rkisp1_mp_sp_stop(struct rkisp1_capture *cap)
-{
- if (!cap->is_streaming)
- return;
- rkisp1_write(cap->rkisp1,
- RKISP1_CIF_MI_FRAME(cap), RKISP1_CIF_MI_ICR);
- cap->ops->disable(cap);
-}
-
-static bool rkisp1_mp_is_stopped(struct rkisp1_capture *cap)
-{
- u32 en = RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED |
- RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED;
-
- return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) & en);
-}
-
-static bool rkisp1_sp_is_stopped(struct rkisp1_capture *cap)
-{
- return !(rkisp1_read(cap->rkisp1, RKISP1_CIF_MI_CTRL_SHD) &
- RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED);
-}
-
-static void rkisp1_mp_set_data_path(struct rkisp1_capture *cap)
-{
- u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
-
- dpcl = dpcl | RKISP1_CIF_VI_DPCL_CHAN_MODE_MP |
- RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI;
- rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
-}
-
-static void rkisp1_sp_set_data_path(struct rkisp1_capture *cap)
-{
- u32 dpcl = rkisp1_read(cap->rkisp1, RKISP1_CIF_VI_DPCL);
-
- dpcl |= RKISP1_CIF_VI_DPCL_CHAN_MODE_SP;
- rkisp1_write(cap->rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
-}
-
-static struct rkisp1_capture_ops rkisp1_capture_ops_mp = {
- .config = rkisp1_mp_config,
- .enable = rkisp1_mp_enable,
- .disable = rkisp1_mp_disable,
- .stop = rkisp1_mp_sp_stop,
- .set_data_path = rkisp1_mp_set_data_path,
- .is_stopped = rkisp1_mp_is_stopped,
-};
-
-static struct rkisp1_capture_ops rkisp1_capture_ops_sp = {
- .config = rkisp1_sp_config,
- .enable = rkisp1_sp_enable,
- .disable = rkisp1_sp_disable,
- .stop = rkisp1_mp_sp_stop,
- .set_data_path = rkisp1_sp_set_data_path,
- .is_stopped = rkisp1_sp_is_stopped,
-};
-
-/* ----------------------------------------------------------------------------
- * Frame buffer operations
- */
-
-static int rkisp1_dummy_buf_create(struct rkisp1_capture *cap)
-{
- const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
- struct rkisp1_dummy_buffer *dummy_buf = &cap->buf.dummy;
-
- dummy_buf->size = max3(rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y),
- rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB),
- rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
-
- /* The driver never access vaddr, no mapping is required */
- dummy_buf->vaddr = dma_alloc_attrs(cap->rkisp1->dev,
- dummy_buf->size,
- &dummy_buf->dma_addr,
- GFP_KERNEL,
- DMA_ATTR_NO_KERNEL_MAPPING);
- if (!dummy_buf->vaddr)
- return -ENOMEM;
-
- return 0;
-}
-
-static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap)
-{
- dma_free_attrs(cap->rkisp1->dev,
- cap->buf.dummy.size, cap->buf.dummy.vaddr,
- cap->buf.dummy.dma_addr, DMA_ATTR_NO_KERNEL_MAPPING);
-}
-
-static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
-{
- cap->buf.curr = cap->buf.next;
- cap->buf.next = NULL;
-
- if (!list_empty(&cap->buf.queue)) {
- u32 *buff_addr;
-
- cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue);
- list_del(&cap->buf.next->queue);
-
- buff_addr = cap->buf.next->buff_addr;
-
- rkisp1_write(cap->rkisp1,
- buff_addr[RKISP1_PLANE_Y],
- cap->config->mi.y_base_ad_init);
- rkisp1_write(cap->rkisp1,
- buff_addr[RKISP1_PLANE_CB],
- cap->config->mi.cb_base_ad_init);
- rkisp1_write(cap->rkisp1,
- buff_addr[RKISP1_PLANE_CR],
- cap->config->mi.cr_base_ad_init);
- } else {
- /*
- * Use the dummy space allocated by dma_alloc_coherent to
- * throw data if there is no available buffer.
- */
- rkisp1_write(cap->rkisp1,
- cap->buf.dummy.dma_addr,
- cap->config->mi.y_base_ad_init);
- rkisp1_write(cap->rkisp1,
- cap->buf.dummy.dma_addr,
- cap->config->mi.cb_base_ad_init);
- rkisp1_write(cap->rkisp1,
- cap->buf.dummy.dma_addr,
- cap->config->mi.cr_base_ad_init);
- }
-
- /* Set plane offsets */
- rkisp1_write(cap->rkisp1, 0, cap->config->mi.y_offs_cnt_init);
- rkisp1_write(cap->rkisp1, 0, cap->config->mi.cb_offs_cnt_init);
- rkisp1_write(cap->rkisp1, 0, cap->config->mi.cr_offs_cnt_init);
-}
-
-/*
- * This function is called when a frame end comes. The next frame
- * is processing and we should set up buffer for next-next frame,
- * otherwise it will overflow.
- */
-static void rkisp1_handle_buffer(struct rkisp1_capture *cap)
-{
- struct rkisp1_isp *isp = &cap->rkisp1->isp;
- struct rkisp1_buffer *curr_buf;
-
- spin_lock(&cap->buf.lock);
- curr_buf = cap->buf.curr;
-
- if (curr_buf) {
- curr_buf->vb.sequence = isp->frame_sequence;
- curr_buf->vb.vb2_buf.timestamp = ktime_get_boottime_ns();
- curr_buf->vb.field = V4L2_FIELD_NONE;
- vb2_buffer_done(&curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
- } else {
- cap->rkisp1->debug.frame_drop[cap->id]++;
- }
-
- rkisp1_set_next_buf(cap);
- spin_unlock(&cap->buf.lock);
-}
-
-void rkisp1_capture_isr(struct rkisp1_device *rkisp1)
-{
- unsigned int i;
- u32 status;
-
- status = rkisp1_read(rkisp1, RKISP1_CIF_MI_MIS);
- rkisp1_write(rkisp1, status, RKISP1_CIF_MI_ICR);
-
- for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
- struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
-
- if (!(status & RKISP1_CIF_MI_FRAME(cap)))
- continue;
- if (!cap->is_stopping) {
- rkisp1_handle_buffer(cap);
- continue;
- }
- /*
- * Make sure stream is actually stopped, whose state
- * can be read from the shadow register, before
- * wake_up() thread which would immediately free all
- * frame buffers. stop() takes effect at the next
- * frame end that sync the configurations to shadow
- * regs.
- */
- if (!cap->ops->is_stopped(cap)) {
- cap->ops->stop(cap);
- continue;
- }
- cap->is_stopping = false;
- cap->is_streaming = false;
- wake_up(&cap->done);
- }
-}
-
-/* ----------------------------------------------------------------------------
- * Vb2 operations
- */
-
-static int rkisp1_vb2_queue_setup(struct vb2_queue *queue,
- unsigned int *num_buffers,
- unsigned int *num_planes,
- unsigned int sizes[],
- struct device *alloc_devs[])
-{
- struct rkisp1_capture *cap = queue->drv_priv;
- const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
- unsigned int i;
-
- if (*num_planes) {
- if (*num_planes != pixm->num_planes)
- return -EINVAL;
-
- for (i = 0; i < pixm->num_planes; i++)
- if (sizes[i] < pixm->plane_fmt[i].sizeimage)
- return -EINVAL;
- } else {
- *num_planes = pixm->num_planes;
- for (i = 0; i < pixm->num_planes; i++)
- sizes[i] = pixm->plane_fmt[i].sizeimage;
- }
-
- return 0;
-}
-
-static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct rkisp1_buffer *ispbuf =
- container_of(vbuf, struct rkisp1_buffer, vb);
- struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
- const struct v4l2_pix_format_mplane *pixm = &cap->pix.fmt;
- unsigned int i;
-
- memset(ispbuf->buff_addr, 0, sizeof(ispbuf->buff_addr));
- for (i = 0; i < pixm->num_planes; i++)
- ispbuf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
-
- /* Convert to non-MPLANE */
- if (pixm->num_planes == 1) {
- ispbuf->buff_addr[RKISP1_PLANE_CB] =
- ispbuf->buff_addr[RKISP1_PLANE_Y] +
- rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_Y);
- ispbuf->buff_addr[RKISP1_PLANE_CR] =
- ispbuf->buff_addr[RKISP1_PLANE_CB] +
- rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CB);
- }
-
- /*
- * uv swap can be supported for planar formats by switching
- * the address of cb and cr
- */
- if (cap->pix.info->comp_planes == 3 && cap->pix.cfg->uv_swap)
- swap(ispbuf->buff_addr[RKISP1_PLANE_CR],
- ispbuf->buff_addr[RKISP1_PLANE_CB]);
-
- spin_lock_irq(&cap->buf.lock);
- list_add_tail(&ispbuf->queue, &cap->buf.queue);
- spin_unlock_irq(&cap->buf.lock);
-}
-
-static int rkisp1_vb2_buf_prepare(struct vb2_buffer *vb)
-{
- struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
- unsigned int i;
-
- for (i = 0; i < cap->pix.fmt.num_planes; i++) {
- unsigned long size = cap->pix.fmt.plane_fmt[i].sizeimage;
-
- if (vb2_plane_size(vb, i) < size) {
- dev_err(cap->rkisp1->dev,
- "User buffer too small (%ld < %ld)\n",
- vb2_plane_size(vb, i), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(vb, i, size);
- }
-
- return 0;
-}
-
-static void rkisp1_return_all_buffers(struct rkisp1_capture *cap,
- enum vb2_buffer_state state)
-{
- struct rkisp1_buffer *buf;
-
- spin_lock_irq(&cap->buf.lock);
- if (cap->buf.curr) {
- vb2_buffer_done(&cap->buf.curr->vb.vb2_buf, state);
- cap->buf.curr = NULL;
- }
- if (cap->buf.next) {
- vb2_buffer_done(&cap->buf.next->vb.vb2_buf, state);
- cap->buf.next = NULL;
- }
- while (!list_empty(&cap->buf.queue)) {
- buf = list_first_entry(&cap->buf.queue,
- struct rkisp1_buffer, queue);
- list_del(&buf->queue);
- vb2_buffer_done(&buf->vb.vb2_buf, state);
- }
- spin_unlock_irq(&cap->buf.lock);
-}
-
-/*
- * Most of registers inside rockchip ISP1 have shadow register since
- * they must be not be changed during processing a frame.
- * Usually, each sub-module updates its shadow register after
- * processing the last pixel of a frame.
- */
-static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
-{
- struct rkisp1_device *rkisp1 = cap->rkisp1;
- struct rkisp1_capture *other = &rkisp1->capture_devs[cap->id ^ 1];
-
- cap->ops->set_data_path(cap);
- cap->ops->config(cap);
-
- /* Setup a buffer for the next frame */
- spin_lock_irq(&cap->buf.lock);
- rkisp1_set_next_buf(cap);
- cap->ops->enable(cap);
- /* It's safe to config ACTIVE and SHADOW regs for the
- * first stream. While when the second is starting, do NOT
- * force update because it also update the first one.
- *
- * The latter case would drop one more buf(that is 2) since
- * there's not buf in shadow when the second FE received. This's
- * also required because the second FE maybe corrupt especially
- * when run at 120fps.
- */
- if (!other->is_streaming) {
- /* force cfg update */
- rkisp1_write(rkisp1,
- RKISP1_CIF_MI_INIT_SOFT_UPD, RKISP1_CIF_MI_INIT);
- rkisp1_set_next_buf(cap);
- }
- spin_unlock_irq(&cap->buf.lock);
- cap->is_streaming = true;
-}
-
-static void rkisp1_cap_stream_disable(struct rkisp1_capture *cap)
-{
- int ret;
-
- /* Stream should stop in interrupt. If it dosn't, stop it by force. */
- cap->is_stopping = true;
- ret = wait_event_timeout(cap->done,
- !cap->is_streaming,
- msecs_to_jiffies(1000));
- if (!ret) {
- cap->rkisp1->debug.stop_timeout[cap->id]++;
- cap->ops->stop(cap);
- cap->is_stopping = false;
- cap->is_streaming = false;
- }
-}
-
-/*
- * rkisp1_pipeline_stream_disable - disable nodes in the pipeline
- *
- * Call s_stream(false) in the reverse order from
- * rkisp1_pipeline_stream_enable() and disable the DMA engine.
- * Should be called before media_pipeline_stop()
- */
-static void rkisp1_pipeline_stream_disable(struct rkisp1_capture *cap)
- __must_hold(&cap->rkisp1->stream_lock)
-{
- struct rkisp1_device *rkisp1 = cap->rkisp1;
-
- rkisp1_cap_stream_disable(cap);
-
- /*
- * If the other capture is streaming, isp and sensor nodes shouldn't
- * be disabled, skip them.
- */
- if (rkisp1->pipe.streaming_count < 2) {
- v4l2_subdev_call(rkisp1->active_sensor->sd, video, s_stream,
- false);
- v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, false);
- }
-
- v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video, s_stream,
- false);
-}
-
-/*
- * rkisp1_pipeline_stream_enable - enable nodes in the pipeline
- *
- * Enable the DMA Engine and call s_stream(true) through the pipeline.
- * Should be called after media_pipeline_start()
- */
-static int rkisp1_pipeline_stream_enable(struct rkisp1_capture *cap)
- __must_hold(&cap->rkisp1->stream_lock)
-{
- struct rkisp1_device *rkisp1 = cap->rkisp1;
- int ret;
-
- rkisp1_cap_stream_enable(cap);
-
- ret = v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video,
- s_stream, true);
- if (ret)
- goto err_disable_cap;
-
- /*
- * If the other capture is streaming, isp and sensor nodes are already
- * enabled, skip them.
- */
- if (rkisp1->pipe.streaming_count > 1)
- return 0;
-
- ret = v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, true);
- if (ret)
- goto err_disable_rsz;
-
- ret = v4l2_subdev_call(rkisp1->active_sensor->sd, video, s_stream,
- true);
- if (ret)
- goto err_disable_isp;
-
- return 0;
-
-err_disable_isp:
- v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, false);
-err_disable_rsz:
- v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video, s_stream,
- false);
-err_disable_cap:
- rkisp1_cap_stream_disable(cap);
-
- return ret;
-}
-
-static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue)
-{
- struct rkisp1_capture *cap = queue->drv_priv;
- struct rkisp1_vdev_node *node = &cap->vnode;
- struct rkisp1_device *rkisp1 = cap->rkisp1;
- int ret;
-
- mutex_lock(&cap->rkisp1->stream_lock);
-
- rkisp1_pipeline_stream_disable(cap);
-
- rkisp1_return_all_buffers(cap, VB2_BUF_STATE_ERROR);
-
- v4l2_pipeline_pm_put(&node->vdev.entity);
- ret = pm_runtime_put(rkisp1->dev);
- if (ret < 0)
- dev_err(rkisp1->dev, "power down failed error:%d\n", ret);
-
- rkisp1_dummy_buf_destroy(cap);
-
- media_pipeline_stop(&node->vdev.entity);
-
- mutex_unlock(&cap->rkisp1->stream_lock);
-}
-
-static int
-rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
-{
- struct rkisp1_capture *cap = queue->drv_priv;
- struct media_entity *entity = &cap->vnode.vdev.entity;
- int ret;
-
- mutex_lock(&cap->rkisp1->stream_lock);
-
- ret = media_pipeline_start(entity, &cap->rkisp1->pipe);
- if (ret) {
- dev_err(cap->rkisp1->dev, "start pipeline failed %d\n", ret);
- goto err_ret_buffers;
- }
-
- ret = rkisp1_dummy_buf_create(cap);
- if (ret)
- goto err_pipeline_stop;
-
- ret = pm_runtime_get_sync(cap->rkisp1->dev);
- if (ret < 0) {
- pm_runtime_put_noidle(cap->rkisp1->dev);
- dev_err(cap->rkisp1->dev, "power up failed %d\n", ret);
- goto err_destroy_dummy;
- }
- ret = v4l2_pipeline_pm_get(entity);
- if (ret) {
- dev_err(cap->rkisp1->dev, "open cif pipeline failed %d\n", ret);
- goto err_pipe_pm_put;
- }
-
- ret = rkisp1_pipeline_stream_enable(cap);
- if (ret)
- goto err_v4l2_pm_put;
-
- mutex_unlock(&cap->rkisp1->stream_lock);
-
- return 0;
-
-err_v4l2_pm_put:
- v4l2_pipeline_pm_put(entity);
-err_pipe_pm_put:
- pm_runtime_put(cap->rkisp1->dev);
-err_destroy_dummy:
- rkisp1_dummy_buf_destroy(cap);
-err_pipeline_stop:
- media_pipeline_stop(entity);
-err_ret_buffers:
- rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED);
- mutex_unlock(&cap->rkisp1->stream_lock);
-
- return ret;
-}
-
-static struct vb2_ops rkisp1_vb2_ops = {
- .queue_setup = rkisp1_vb2_queue_setup,
- .buf_queue = rkisp1_vb2_buf_queue,
- .buf_prepare = rkisp1_vb2_buf_prepare,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .stop_streaming = rkisp1_vb2_stop_streaming,
- .start_streaming = rkisp1_vb2_start_streaming,
-};
-
-/* ----------------------------------------------------------------------------
- * IOCTLs operations
- */
-
-static const struct v4l2_format_info *
-rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
- enum rkisp1_stream_id id)
-{
- struct v4l2_plane_pix_format *plane_y = &pixm->plane_fmt[0];
- const struct v4l2_format_info *info;
- unsigned int i;
- u32 stride;
-
- memset(pixm->plane_fmt, 0, sizeof(pixm->plane_fmt));
- info = v4l2_format_info(pixm->pixelformat);
- pixm->num_planes = info->mem_planes;
- stride = info->bpp[0] * pixm->width;
- /* Self path supports custom stride but Main path doesn't */
- if (id == RKISP1_MAINPATH || plane_y->bytesperline < stride)
- plane_y->bytesperline = stride;
- plane_y->sizeimage = plane_y->bytesperline * pixm->height;
-
- /* normalize stride to pixels per line */
- stride = DIV_ROUND_UP(plane_y->bytesperline, info->bpp[0]);
-
- for (i = 1; i < info->comp_planes; i++) {
- struct v4l2_plane_pix_format *plane = &pixm->plane_fmt[i];
-
- /* bytesperline for other components derive from Y component */
- plane->bytesperline = DIV_ROUND_UP(stride, info->hdiv) *
- info->bpp[i];
- plane->sizeimage = plane->bytesperline *
- DIV_ROUND_UP(pixm->height, info->vdiv);
- }
-
- /*
- * If pixfmt is packed, then plane_fmt[0] should contain the total size
- * considering all components. plane_fmt[i] for i > 0 should be ignored
- * by userspace as mem_planes == 1, but we are keeping information there
- * for convenience.
- */
- if (info->mem_planes == 1)
- for (i = 1; i < info->comp_planes; i++)
- plane_y->sizeimage += pixm->plane_fmt[i].sizeimage;
-
- return info;
-}
-
-static const struct rkisp1_capture_fmt_cfg *
-rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
-{
- unsigned int i;
-
- for (i = 0; i < cap->config->fmt_size; i++) {
- if (cap->config->fmts[i].fourcc == pixelfmt)
- return &cap->config->fmts[i];
- }
- return NULL;
-}
-
-static void rkisp1_try_fmt(const struct rkisp1_capture *cap,
- struct v4l2_pix_format_mplane *pixm,
- const struct rkisp1_capture_fmt_cfg **fmt_cfg,
- const struct v4l2_format_info **fmt_info)
-{
- const struct rkisp1_capture_config *config = cap->config;
- const struct rkisp1_capture_fmt_cfg *fmt;
- const struct v4l2_format_info *info;
- const unsigned int max_widths[] = { RKISP1_RSZ_MP_SRC_MAX_WIDTH,
- RKISP1_RSZ_SP_SRC_MAX_WIDTH };
- const unsigned int max_heights[] = { RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
- RKISP1_RSZ_SP_SRC_MAX_HEIGHT};
-
- fmt = rkisp1_find_fmt_cfg(cap, pixm->pixelformat);
- if (!fmt) {
- fmt = config->fmts;
- pixm->pixelformat = fmt->fourcc;
- }
-
- pixm->width = clamp_t(u32, pixm->width,
- RKISP1_RSZ_SRC_MIN_WIDTH, max_widths[cap->id]);
- pixm->height = clamp_t(u32, pixm->height,
- RKISP1_RSZ_SRC_MIN_HEIGHT, max_heights[cap->id]);
-
- pixm->field = V4L2_FIELD_NONE;
- pixm->colorspace = V4L2_COLORSPACE_DEFAULT;
- pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
- pixm->quantization = V4L2_QUANTIZATION_DEFAULT;
-
- info = rkisp1_fill_pixfmt(pixm, cap->id);
-
- if (fmt_cfg)
- *fmt_cfg = fmt;
- if (fmt_info)
- *fmt_info = info;
-}
-
-static void rkisp1_set_fmt(struct rkisp1_capture *cap,
- struct v4l2_pix_format_mplane *pixm)
-{
- rkisp1_try_fmt(cap, pixm, &cap->pix.cfg, &cap->pix.info);
- cap->pix.fmt = *pixm;
-
- /* SP supports custom stride in number of pixels of the Y plane */
- if (cap->id == RKISP1_SELFPATH)
- cap->sp_y_stride = pixm->plane_fmt[0].bytesperline /
- cap->pix.info->bpp[0];
-}
-
-static int rkisp1_try_fmt_vid_cap_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct rkisp1_capture *cap = video_drvdata(file);
-
- rkisp1_try_fmt(cap, &f->fmt.pix_mp, NULL, NULL);
-
- return 0;
-}
-
-static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct rkisp1_capture *cap = video_drvdata(file);
- const struct rkisp1_capture_fmt_cfg *fmt = NULL;
- unsigned int i, n = 0;
-
- if (!f->mbus_code) {
- if (f->index >= cap->config->fmt_size)
- return -EINVAL;
-
- fmt = &cap->config->fmts[f->index];
- f->pixelformat = fmt->fourcc;
- return 0;
- }
-
- for (i = 0; i < cap->config->fmt_size; i++) {
- if (cap->config->fmts[i].mbus != f->mbus_code)
- continue;
-
- if (n++ == f->index) {
- f->pixelformat = cap->config->fmts[i].fourcc;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int rkisp1_s_fmt_vid_cap_mplane(struct file *file,
- void *priv, struct v4l2_format *f)
-{
- struct rkisp1_capture *cap = video_drvdata(file);
- struct rkisp1_vdev_node *node =
- rkisp1_vdev_to_node(&cap->vnode.vdev);
-
- if (vb2_is_busy(&node->buf_queue))
- return -EBUSY;
-
- rkisp1_set_fmt(cap, &f->fmt.pix_mp);
-
- return 0;
-}
-
-static int rkisp1_g_fmt_vid_cap_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct rkisp1_capture *cap = video_drvdata(file);
-
- f->fmt.pix_mp = cap->pix.fmt;
-
- return 0;
-}
-
-static int
-rkisp1_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
-{
- struct rkisp1_capture *cap_dev = video_drvdata(file);
- struct rkisp1_device *rkisp1 = cap_dev->rkisp1;
-
- strscpy(cap->driver, rkisp1->dev->driver->name, sizeof(cap->driver));
- strscpy(cap->card, rkisp1->dev->driver->name, sizeof(cap->card));
- strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops rkisp1_v4l2_ioctl_ops = {
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_expbuf = vb2_ioctl_expbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_try_fmt_vid_cap_mplane = rkisp1_try_fmt_vid_cap_mplane,
- .vidioc_s_fmt_vid_cap_mplane = rkisp1_s_fmt_vid_cap_mplane,
- .vidioc_g_fmt_vid_cap_mplane = rkisp1_g_fmt_vid_cap_mplane,
- .vidioc_enum_fmt_vid_cap = rkisp1_enum_fmt_vid_cap_mplane,
- .vidioc_querycap = rkisp1_querycap,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static int rkisp1_capture_link_validate(struct media_link *link)
-{
- struct video_device *vdev =
- media_entity_to_video_device(link->sink->entity);
- struct v4l2_subdev *sd =
- media_entity_to_v4l2_subdev(link->source->entity);
- struct rkisp1_capture *cap = video_get_drvdata(vdev);
- const struct rkisp1_capture_fmt_cfg *fmt =
- rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
- struct v4l2_subdev_format sd_fmt;
- int ret;
-
- sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- sd_fmt.pad = link->source->index;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
- if (ret)
- return ret;
-
- if (sd_fmt.format.height != cap->pix.fmt.height ||
- sd_fmt.format.width != cap->pix.fmt.width ||
- sd_fmt.format.code != fmt->mbus)
- return -EPIPE;
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------------
- * core functions
- */
-
-static const struct media_entity_operations rkisp1_media_ops = {
- .link_validate = rkisp1_capture_link_validate,
-};
-
-static const struct v4l2_file_operations rkisp1_fops = {
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .unlocked_ioctl = video_ioctl2,
- .poll = vb2_fop_poll,
- .mmap = vb2_fop_mmap,
-};
-
-static void rkisp1_unregister_capture(struct rkisp1_capture *cap)
-{
- media_entity_cleanup(&cap->vnode.vdev.entity);
- vb2_video_unregister_device(&cap->vnode.vdev);
-}
-
-void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_capture *mp = &rkisp1->capture_devs[RKISP1_MAINPATH];
- struct rkisp1_capture *sp = &rkisp1->capture_devs[RKISP1_SELFPATH];
-
- rkisp1_unregister_capture(mp);
- rkisp1_unregister_capture(sp);
-}
-
-static int rkisp1_register_capture(struct rkisp1_capture *cap)
-{
- const char * const dev_names[] = {RKISP1_MP_DEV_NAME,
- RKISP1_SP_DEV_NAME};
- struct v4l2_device *v4l2_dev = &cap->rkisp1->v4l2_dev;
- struct video_device *vdev = &cap->vnode.vdev;
- struct rkisp1_vdev_node *node;
- struct vb2_queue *q;
- int ret;
-
- strscpy(vdev->name, dev_names[cap->id], sizeof(vdev->name));
- node = rkisp1_vdev_to_node(vdev);
- mutex_init(&node->vlock);
-
- vdev->ioctl_ops = &rkisp1_v4l2_ioctl_ops;
- vdev->release = video_device_release_empty;
- vdev->fops = &rkisp1_fops;
- vdev->minor = -1;
- vdev->v4l2_dev = v4l2_dev;
- vdev->lock = &node->vlock;
- vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
- V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
- vdev->entity.ops = &rkisp1_media_ops;
- video_set_drvdata(vdev, cap);
- vdev->vfl_dir = VFL_DIR_RX;
- node->pad.flags = MEDIA_PAD_FL_SINK;
-
- q = &node->buf_queue;
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->io_modes = VB2_MMAP | VB2_DMABUF;
- q->drv_priv = cap;
- q->ops = &rkisp1_vb2_ops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct rkisp1_buffer);
- q->min_buffers_needed = RKISP1_MIN_BUFFERS_NEEDED;
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &node->vlock;
- q->dev = cap->rkisp1->dev;
- ret = vb2_queue_init(q);
- if (ret) {
- dev_err(cap->rkisp1->dev,
- "vb2 queue init failed (err=%d)\n", ret);
- return ret;
- }
-
- vdev->queue = q;
-
- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
- if (ret) {
- dev_err(cap->rkisp1->dev,
- "failed to register %s, ret=%d\n", vdev->name, ret);
- return ret;
- }
- v4l2_info(v4l2_dev, "registered %s as /dev/video%d\n", vdev->name,
- vdev->num);
-
- ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
- if (ret) {
- video_unregister_device(vdev);
- return ret;
- }
-
- return 0;
-}
-
-static void
-rkisp1_capture_init(struct rkisp1_device *rkisp1, enum rkisp1_stream_id id)
-{
- struct rkisp1_capture *cap = &rkisp1->capture_devs[id];
- struct v4l2_pix_format_mplane pixm;
-
- memset(cap, 0, sizeof(*cap));
- cap->id = id;
- cap->rkisp1 = rkisp1;
-
- INIT_LIST_HEAD(&cap->buf.queue);
- init_waitqueue_head(&cap->done);
- spin_lock_init(&cap->buf.lock);
- if (cap->id == RKISP1_SELFPATH) {
- cap->ops = &rkisp1_capture_ops_sp;
- cap->config = &rkisp1_capture_config_sp;
- } else {
- cap->ops = &rkisp1_capture_ops_mp;
- cap->config = &rkisp1_capture_config_mp;
- }
-
- cap->is_streaming = false;
-
- memset(&pixm, 0, sizeof(pixm));
- pixm.pixelformat = V4L2_PIX_FMT_YUYV;
- pixm.width = RKISP1_DEFAULT_WIDTH;
- pixm.height = RKISP1_DEFAULT_HEIGHT;
- rkisp1_set_fmt(cap, &pixm);
-}
-
-int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_capture *cap;
- unsigned int i, j;
- int ret;
-
- for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); i++) {
- rkisp1_capture_init(rkisp1, i);
- cap = &rkisp1->capture_devs[i];
- cap->rkisp1 = rkisp1;
- ret = rkisp1_register_capture(cap);
- if (ret)
- goto err_unreg_capture_devs;
- }
-
- return 0;
-
-err_unreg_capture_devs:
- for (j = 0; j < i; j++) {
- cap = &rkisp1->capture_devs[j];
- rkisp1_unregister_capture(cap);
- }
-
- return ret;
-}
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Common definitions
- *
- * Copyright (C) 2019 Collabora, Ltd.
- */
-
-#include <media/v4l2-rect.h>
-
-#include "rkisp1-common.h"
-
-static const struct v4l2_rect rkisp1_sd_min_crop = {
- .width = RKISP1_ISP_MIN_WIDTH,
- .height = RKISP1_ISP_MIN_HEIGHT,
- .top = 0,
- .left = 0,
-};
-
-void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
- const struct v4l2_rect *bounds)
-{
- v4l2_rect_set_min_size(crop, &rkisp1_sd_min_crop);
- v4l2_rect_map_inside(crop, bounds);
-}
-
-void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
- const struct v4l2_mbus_framefmt *bounds)
-{
- struct v4l2_rect crop_bounds = {
- .left = 0,
- .top = 0,
- .width = bounds->width,
- .height = bounds->height,
- };
-
- rkisp1_sd_adjust_crop_rect(crop, &crop_bounds);
-}
+++ /dev/null
-/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
-/*
- * Rockchip ISP1 Driver - Common definitions
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _RKISP1_COMMON_H
-#define _RKISP1_COMMON_H
-
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <media/media-device.h>
-#include <media/media-entity.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/videobuf2-v4l2.h>
-
-#include "rkisp1-regs.h"
-#include "uapi/rkisp1-config.h"
-
-/*
- * flags on the 'direction' field in struct 'rkisp1_isp_mbus_info' that indicate
- * on which pad the media bus format is supported
- */
-#define RKISP1_ISP_SD_SRC BIT(0)
-#define RKISP1_ISP_SD_SINK BIT(1)
-
-/* min and max values for the widths and heights of the entities */
-#define RKISP1_ISP_MAX_WIDTH 4032
-#define RKISP1_ISP_MAX_HEIGHT 3024
-#define RKISP1_ISP_MIN_WIDTH 32
-#define RKISP1_ISP_MIN_HEIGHT 32
-
-#define RKISP1_RSZ_MP_SRC_MAX_WIDTH 4416
-#define RKISP1_RSZ_MP_SRC_MAX_HEIGHT 3312
-#define RKISP1_RSZ_SP_SRC_MAX_WIDTH 1920
-#define RKISP1_RSZ_SP_SRC_MAX_HEIGHT 1920
-#define RKISP1_RSZ_SRC_MIN_WIDTH 32
-#define RKISP1_RSZ_SRC_MIN_HEIGHT 16
-
-/* the default width and height of all the entities */
-#define RKISP1_DEFAULT_WIDTH 800
-#define RKISP1_DEFAULT_HEIGHT 600
-
-#define RKISP1_DRIVER_NAME "rkisp1"
-#define RKISP1_BUS_INFO "platform:" RKISP1_DRIVER_NAME
-
-/* maximum number of clocks */
-#define RKISP1_MAX_BUS_CLK 8
-
-/* a bitmask of the ready stats */
-#define RKISP1_STATS_MEAS_MASK (RKISP1_CIF_ISP_AWB_DONE | \
- RKISP1_CIF_ISP_AFM_FIN | \
- RKISP1_CIF_ISP_EXP_END | \
- RKISP1_CIF_ISP_HIST_MEASURE_RDY)
-
-/* enum for the resizer pads */
-enum rkisp1_rsz_pad {
- RKISP1_RSZ_PAD_SINK,
- RKISP1_RSZ_PAD_SRC,
- RKISP1_RSZ_PAD_MAX
-};
-
-/* enum for the capture id */
-enum rkisp1_stream_id {
- RKISP1_MAINPATH,
- RKISP1_SELFPATH,
-};
-
-/* bayer patterns */
-enum rkisp1_fmt_raw_pat_type {
- RKISP1_RAW_RGGB = 0,
- RKISP1_RAW_GRBG,
- RKISP1_RAW_GBRG,
- RKISP1_RAW_BGGR,
-};
-
-/* enum for the isp pads */
-enum rkisp1_isp_pad {
- RKISP1_ISP_PAD_SINK_VIDEO,
- RKISP1_ISP_PAD_SINK_PARAMS,
- RKISP1_ISP_PAD_SOURCE_VIDEO,
- RKISP1_ISP_PAD_SOURCE_STATS,
- RKISP1_ISP_PAD_MAX
-};
-
-/*
- * struct rkisp1_sensor_async - A container for the v4l2_async_subdev to add to the notifier
- * of the v4l2-async API
- *
- * @asd: async_subdev variable for the sensor
- * @lanes: number of lanes
- * @mbus_type: type of bus (currently only CSI2 is supported)
- * @mbus_flags: media bus (V4L2_MBUS_*) flags
- * @sd: a pointer to v4l2_subdev struct of the sensor
- * @pixel_rate_ctrl: pixel rate of the sensor, used to initialize the phy
- * @dphy: a pointer to the phy
- */
-struct rkisp1_sensor_async {
- struct v4l2_async_subdev asd;
- unsigned int lanes;
- enum v4l2_mbus_type mbus_type;
- unsigned int mbus_flags;
- struct v4l2_subdev *sd;
- struct v4l2_ctrl *pixel_rate_ctrl;
- struct phy *dphy;
-};
-
-/*
- * struct rkisp1_isp - ISP subdev entity
- *
- * @sd: v4l2_subdev variable
- * @rkisp1: pointer to rkisp1_device
- * @pads: media pads
- * @pad_cfg: pads configurations
- * @sink_fmt: input format
- * @src_fmt: output format
- * @ops_lock: ops serialization
- * @is_dphy_errctrl_disabled: if dphy errctrl is disabled (avoid endless interrupt)
- * @frame_sequence: used to synchronize frame_id between video devices.
- */
-struct rkisp1_isp {
- struct v4l2_subdev sd;
- struct media_pad pads[RKISP1_ISP_PAD_MAX];
- struct v4l2_subdev_pad_config pad_cfg[RKISP1_ISP_PAD_MAX];
- const struct rkisp1_isp_mbus_info *sink_fmt;
- const struct rkisp1_isp_mbus_info *src_fmt;
- struct mutex ops_lock; /* serialize the subdevice ops */
- bool is_dphy_errctrl_disabled;
- __u32 frame_sequence;
-};
-
-/*
- * struct rkisp1_vdev_node - Container for the video nodes: params, stats, mainpath, selfpath
- *
- * @buf_queue: queue of buffers
- * @vlock: lock of the video node
- * @vdev: video node
- * @pad: media pad
- */
-struct rkisp1_vdev_node {
- struct vb2_queue buf_queue;
- struct mutex vlock; /* ioctl serialization mutex */
- struct video_device vdev;
- struct media_pad pad;
-};
-
-/*
- * struct rkisp1_buffer - A container for the vb2 buffers used by the video devices:
- * params, stats, mainpath, selfpath
- *
- * @vb: vb2 buffer
- * @queue: entry of the buffer in the queue
- * @buff_addr: dma addresses of each plane, used only by the capture devices: selfpath, mainpath
- * @vaddr: virtual address for buffers used by params and stats devices
- */
-struct rkisp1_buffer {
- struct vb2_v4l2_buffer vb;
- struct list_head queue;
- union {
- u32 buff_addr[VIDEO_MAX_PLANES];
- void *vaddr;
- };
-};
-
-/*
- * struct rkisp1_dummy_buffer - A buffer to write the next frame to in case
- * there are no vb2 buffers available.
- *
- * @vaddr: return value of call to dma_alloc_attrs.
- * @dma_addr: dma address of the buffer.
- * @size: size of the buffer.
- */
-struct rkisp1_dummy_buffer {
- void *vaddr;
- dma_addr_t dma_addr;
- u32 size;
-};
-
-struct rkisp1_device;
-
-/*
- * struct rkisp1_capture - ISP capture video device
- *
- * @vnode: video node
- * @rkisp1: pointer to rkisp1_device
- * @id: id of the capture, one of RKISP1_SELFPATH, RKISP1_MAINPATH
- * @ops: list of callbacks to configure the capture device.
- * @config: a pointer to the list of registers to configure the capture format.
- * @is_streaming: device is streaming
- * @is_stopping: stop_streaming callback was called and the device is in the process of
- * stopping the streaming.
- * @done: when stop_streaming callback is called, the device waits for the next irq
- * handler to stop the streaming by waiting on the 'done' wait queue.
- * If the irq handler is not called, the stream is stopped by the callback
- * after timeout.
- * @sp_y_stride: the selfpath allows to configure a y stride that is longer than the image width.
- * @buf.lock: lock to protect buf.queue
- * @buf.queue: queued buffer list
- * @buf.dummy: dummy space to store dropped data
- *
- * rkisp1 uses shadow registers, so it needs two buffers at a time
- * @buf.curr: the buffer used for current frame
- * @buf.next: the buffer used for next frame
- * @pix.cfg: pixel configuration
- * @pix.info: a pointer to the v4l2_format_info of the pixel format
- * @pix.fmt: buffer format
- */
-struct rkisp1_capture {
- struct rkisp1_vdev_node vnode;
- struct rkisp1_device *rkisp1;
- enum rkisp1_stream_id id;
- struct rkisp1_capture_ops *ops;
- const struct rkisp1_capture_config *config;
- bool is_streaming;
- bool is_stopping;
- wait_queue_head_t done;
- unsigned int sp_y_stride;
- struct {
- /* protects queue, curr and next */
- spinlock_t lock;
- struct list_head queue;
- struct rkisp1_dummy_buffer dummy;
- struct rkisp1_buffer *curr;
- struct rkisp1_buffer *next;
- } buf;
- struct {
- const struct rkisp1_capture_fmt_cfg *cfg;
- const struct v4l2_format_info *info;
- struct v4l2_pix_format_mplane fmt;
- } pix;
-};
-
-/*
- * struct rkisp1_stats - ISP Statistics device
- *
- * @vnode: video node
- * @rkisp1: pointer to the rkisp1 device
- * @lock: locks the buffer list 'stat'
- * @stat: queue of rkisp1_buffer
- * @vdev_fmt: v4l2_format of the metadata format
- */
-struct rkisp1_stats {
- struct rkisp1_vdev_node vnode;
- struct rkisp1_device *rkisp1;
-
- spinlock_t lock; /* locks the buffers list 'stats' */
- struct list_head stat;
- struct v4l2_format vdev_fmt;
-};
-
-/*
- * struct rkisp1_params - ISP input parameters device
- *
- * @vnode: video node
- * @rkisp1: pointer to the rkisp1 device
- * @config_lock: locks the buffer list 'params'
- * @params: queue of rkisp1_buffer
- * @vdev_fmt: v4l2_format of the metadata format
- * @quantization: the quantization configured on the isp's src pad
- * @raw_type: the bayer pattern on the isp video sink pad
- */
-struct rkisp1_params {
- struct rkisp1_vdev_node vnode;
- struct rkisp1_device *rkisp1;
-
- spinlock_t config_lock; /* locks the buffers list 'params' */
- struct list_head params;
- struct v4l2_format vdev_fmt;
-
- enum v4l2_quantization quantization;
- enum rkisp1_fmt_raw_pat_type raw_type;
-};
-
-/*
- * struct rkisp1_resizer - Resizer subdev
- *
- * @sd: v4l2_subdev variable
- * @id: id of the resizer, one of RKISP1_SELFPATH, RKISP1_MAINPATH
- * @rkisp1: pointer to the rkisp1 device
- * @pads: media pads
- * @pad_cfg: configurations for the pads
- * @config: the set of registers to configure the resizer
- * @pixel_enc: pixel encoding of the resizer
- * @ops_lock: a lock for the subdev ops
- */
-struct rkisp1_resizer {
- struct v4l2_subdev sd;
- enum rkisp1_stream_id id;
- struct rkisp1_device *rkisp1;
- struct media_pad pads[RKISP1_RSZ_PAD_MAX];
- struct v4l2_subdev_pad_config pad_cfg[RKISP1_RSZ_PAD_MAX];
- const struct rkisp1_rsz_config *config;
- enum v4l2_pixel_encoding pixel_enc;
- struct mutex ops_lock; /* serialize the subdevice ops */
-};
-
-/*
- * struct rkisp1_debug - Values to be exposed on debugfs.
- * The parameters are counters of the number of times the
- * event occurred since the driver was loaded.
- *
- * @data_loss: loss of data occurred within a line, processing failure
- * @outform_size_error: size error is generated in outmux submodule
- * @img_stabilization_size_error: size error is generated in image stabilization submodule
- * @inform_size_err: size error is generated in inform submodule
- * @mipi_error: mipi error occurred
- * @stats_error: writing to the 'Interrupt clear register' did not clear
- * it in the register 'Masked interrupt status'
- * @stop_timeout: upon stream stop, the capture waits 1 second for the isr to stop
- * the stream. This param is incremented in case of timeout.
- * @frame_drop: a frame was ready but the buffer queue was empty so the frame
- * was not sent to userspace
- */
-struct rkisp1_debug {
- struct dentry *debugfs_dir;
- unsigned long data_loss;
- unsigned long outform_size_error;
- unsigned long img_stabilization_size_error;
- unsigned long inform_size_error;
- unsigned long irq_delay;
- unsigned long mipi_error;
- unsigned long stats_error;
- unsigned long stop_timeout[2];
- unsigned long frame_drop[2];
-};
-
-/*
- * struct rkisp1_device - ISP platform device
- *
- * @base_addr: base register address
- * @irq: the irq number
- * @dev: a pointer to the struct device
- * @clk_size: number of clocks
- * @clks: array of clocks
- * @v4l2_dev: v4l2_device variable
- * @media_dev: media_device variable
- * @notifier: a notifier to register on the v4l2-async API to be notified on the sensor
- * @active_sensor: sensor in-use, set when streaming on
- * @isp: ISP sub-device
- * @resizer_devs: resizer sub-devices
- * @capture_devs: capture devices
- * @stats: ISP statistics metadata capture device
- * @params: ISP parameters metadata output device
- * @pipe: media pipeline
- * @stream_lock: serializes {start/stop}_streaming callbacks between the capture devices.
- * @debug: debug params to be exposed on debugfs
- */
-struct rkisp1_device {
- void __iomem *base_addr;
- int irq;
- struct device *dev;
- unsigned int clk_size;
- struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
- struct v4l2_device v4l2_dev;
- struct media_device media_dev;
- struct v4l2_async_notifier notifier;
- struct rkisp1_sensor_async *active_sensor;
- struct rkisp1_isp isp;
- struct rkisp1_resizer resizer_devs[2];
- struct rkisp1_capture capture_devs[2];
- struct rkisp1_stats stats;
- struct rkisp1_params params;
- struct media_pipeline pipe;
- struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */
- struct rkisp1_debug debug;
-};
-
-/*
- * struct rkisp1_isp_mbus_info - ISP media bus info, Translates media bus code to hardware
- * format values
- *
- * @mbus_code: media bus code
- * @pixel_enc: pixel encoding
- * @mipi_dt: mipi data type
- * @yuv_seq: the order of the Y, Cb, Cr values
- * @bus_width: bus width
- * @bayer_pat: bayer pattern
- * @direction: a bitmask of the flags indicating on which pad the format is supported on
- */
-struct rkisp1_isp_mbus_info {
- u32 mbus_code;
- enum v4l2_pixel_encoding pixel_enc;
- u32 mipi_dt;
- u32 yuv_seq;
- u8 bus_width;
- enum rkisp1_fmt_raw_pat_type bayer_pat;
- unsigned int direction;
-};
-
-static inline void
-rkisp1_write(struct rkisp1_device *rkisp1, u32 val, unsigned int addr)
-{
- writel(val, rkisp1->base_addr + addr);
-}
-
-static inline u32 rkisp1_read(struct rkisp1_device *rkisp1, unsigned int addr)
-{
- return readl(rkisp1->base_addr + addr);
-}
-
-/*
- * rkisp1_cap_enum_mbus_codes - A helper function that return the i'th supported mbus code
- * of the capture entity. This is used to enumerate the supported
- * mbus codes on the source pad of the resizer.
- *
- * @cap: the capture entity
- * @code: the mbus code, the function reads the code->index and fills the code->code
- */
-int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
- struct v4l2_subdev_mbus_code_enum *code);
-
-/*
- * rkisp1_sd_adjust_crop_rect - adjust a rectangle to fit into another rectangle.
- *
- * @crop: rectangle to adjust.
- * @bounds: rectangle used as bounds.
- */
-void rkisp1_sd_adjust_crop_rect(struct v4l2_rect *crop,
- const struct v4l2_rect *bounds);
-
-/*
- * rkisp1_sd_adjust_crop - adjust a rectangle to fit into media bus format
- *
- * @crop: rectangle to adjust.
- * @bounds: media bus format used as bounds.
- */
-void rkisp1_sd_adjust_crop(struct v4l2_rect *crop,
- const struct v4l2_mbus_framefmt *bounds);
-
-/*
- * rkisp1_isp_mbus_info - get the isp info of the media bus code
- *
- * @mbus_code: the media bus code
- */
-const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code);
-
-/* rkisp1_params_configure - configure the params when stream starts.
- * This function is called by the isp entity upon stream starts.
- * The function applies the initial configuration of the parameters.
- *
- * @params: pointer to rkisp1_params.
- * @bayer_pat: the bayer pattern on the isp video sink pad
- * @quantization: the quantization configured on the isp's src pad
- */
-void rkisp1_params_configure(struct rkisp1_params *params,
- enum rkisp1_fmt_raw_pat_type bayer_pat,
- enum v4l2_quantization quantization);
-
-/* rkisp1_params_disable - disable all parameters.
- * This function is called by the isp entity upon stream start
- * when capturing bayer format.
- *
- * @params: pointer to rkisp1_params.
- */
-void rkisp1_params_disable(struct rkisp1_params *params);
-
-/* irq handlers */
-void rkisp1_isp_isr(struct rkisp1_device *rkisp1);
-void rkisp1_mipi_isr(struct rkisp1_device *rkisp1);
-void rkisp1_capture_isr(struct rkisp1_device *rkisp1);
-void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris);
-void rkisp1_params_isr(struct rkisp1_device *rkisp1);
-
-/* register/unregisters functions of the entities */
-int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1);
-void rkisp1_capture_devs_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_isp_register(struct rkisp1_device *rkisp1);
-void rkisp1_isp_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1);
-void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_stats_register(struct rkisp1_device *rkisp1);
-void rkisp1_stats_unregister(struct rkisp1_device *rkisp1);
-
-int rkisp1_params_register(struct rkisp1_device *rkisp1);
-void rkisp1_params_unregister(struct rkisp1_device *rkisp1);
-
-#endif /* _RKISP1_COMMON_H */
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Base driver
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <linux/clk.h>
-#include <linux/debugfs.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_graph.h>
-#include <linux/of_platform.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
-#include <media/v4l2-fwnode.h>
-
-#include "rkisp1-common.h"
-
-/*
- * ISP Details
- * -----------
- *
- * ISP Comprises with:
- * MIPI serial camera interface
- * Image Signal Processing
- * Many Image Enhancement Blocks
- * Crop
- * Resizer
- * RBG display ready image
- * Image Rotation
- *
- * ISP Block Diagram
- * -----------------
- * rkisp1-resizer.c rkisp1-capture.c
- * |====================| |=======================|
- * rkisp1-isp.c Main Picture Path
- * |==========================| |===============================================|
- * +-----------+ +--+--+--+--+ +--------+ +--------+ +-----------+
- * | | | | | | | | | | | | |
- * +--------+ |\ | | | | | | | -->| Crop |->| RSZ |------------->| |
- * | MIPI |--->| \ | | | | | | | | | | | | | |
- * +--------+ | | | | |IE|IE|IE|IE| | +--------+ +--------+ | Memory |
- * |MUX|--->| ISP |->|0 |1 |2 |3 |---+ | Interface |
- * +--------+ | | | | | | | | | | +--------+ +--------+ +--------+ | |
- * |Parallel|--->| / | | | | | | | | | | | | | | | |
- * +--------+ |/ | | | | | | | -->| Crop |->| RSZ |->| RGB |->| |
- * | | | | | | | | | | | | Rotate | | |
- * +-----------+ +--+--+--+--+ +--------+ +--------+ +--------+ +-----------+
- * ^
- * +--------+ | |===============================================|
- * | DMA |------------------------------------+ Self Picture Path
- * +--------+
- *
- * rkisp1-stats.c rkisp1-params.c
- * |===============| |===============|
- * +---------------+ +---------------+
- * | | | |
- * | ISP | | ISP |
- * | | | |
- * +---------------+ +---------------+
- *
- *
- * Media Topology
- * --------------
- * +----------+ +----------+
- * | Sensor 2 | | Sensor X |
- * ------------ ... ------------
- * | 0 | | 0 |
- * +----------+ +----------+ +-----------+
- * \ | | params |
- * \ | | (output) |
- * +----------+ \ | +-----------+
- * | Sensor 1 | v v |
- * ------------ +------+------+ |
- * | 0 |----->| 0 | 1 |<---------+
- * +----------+ |------+------|
- * | ISP |
- * |------+------|
- * +-------------| 2 | 3 |----------+
- * | +------+------+ |
- * | | |
- * v v v
- * +- ---------+ +-----------+ +-----------+
- * | 0 | | 0 | | stats |
- * ------------- ------------- | (capture) |
- * | Resizer | | Resizer | +-----------+
- * ------------| ------------|
- * | 1 | | 1 |
- * +-----------+ +-----------+
- * | |
- * v v
- * +-----------+ +-----------+
- * | selfpath | | mainpath |
- * | (capture) | | (capture) |
- * +-----------+ +-----------+
- */
-
-struct rkisp1_match_data {
- const char * const *clks;
- unsigned int size;
-};
-
-/* ----------------------------------------------------------------------------
- * Sensor DT bindings
- */
-
-static int rkisp1_create_links(struct rkisp1_device *rkisp1)
-{
- struct media_entity *source, *sink;
- unsigned int flags, source_pad;
- struct v4l2_subdev *sd;
- unsigned int i;
- int ret;
-
- /* sensor links */
- flags = MEDIA_LNK_FL_ENABLED;
- list_for_each_entry(sd, &rkisp1->v4l2_dev.subdevs, list) {
- if (sd == &rkisp1->isp.sd ||
- sd == &rkisp1->resizer_devs[RKISP1_MAINPATH].sd ||
- sd == &rkisp1->resizer_devs[RKISP1_SELFPATH].sd)
- continue;
-
- ret = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
- MEDIA_PAD_FL_SOURCE);
- if (ret < 0) {
- dev_err(rkisp1->dev, "failed to find src pad for %s\n",
- sd->name);
- return ret;
- }
- source_pad = ret;
-
- ret = media_create_pad_link(&sd->entity, source_pad,
- &rkisp1->isp.sd.entity,
- RKISP1_ISP_PAD_SINK_VIDEO,
- flags);
- if (ret)
- return ret;
-
- flags = 0;
- }
-
- flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
-
- /* create ISP->RSZ->CAP links */
- for (i = 0; i < 2; i++) {
- source = &rkisp1->isp.sd.entity;
- sink = &rkisp1->resizer_devs[i].sd.entity;
- ret = media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_VIDEO,
- sink, RKISP1_RSZ_PAD_SINK,
- MEDIA_LNK_FL_ENABLED);
- if (ret)
- return ret;
-
- source = sink;
- sink = &rkisp1->capture_devs[i].vnode.vdev.entity;
- ret = media_create_pad_link(source, RKISP1_RSZ_PAD_SRC,
- sink, 0, flags);
- if (ret)
- return ret;
- }
-
- /* params links */
- source = &rkisp1->params.vnode.vdev.entity;
- sink = &rkisp1->isp.sd.entity;
- ret = media_create_pad_link(source, 0, sink,
- RKISP1_ISP_PAD_SINK_PARAMS, flags);
- if (ret)
- return ret;
-
- /* 3A stats links */
- source = &rkisp1->isp.sd.entity;
- sink = &rkisp1->stats.vnode.vdev.entity;
- return media_create_pad_link(source, RKISP1_ISP_PAD_SOURCE_STATS,
- sink, 0, flags);
-}
-
-static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *sd,
- struct v4l2_async_subdev *asd)
-{
- struct rkisp1_device *rkisp1 =
- container_of(notifier, struct rkisp1_device, notifier);
- struct rkisp1_sensor_async *s_asd =
- container_of(asd, struct rkisp1_sensor_async, asd);
-
- s_asd->pixel_rate_ctrl = v4l2_ctrl_find(sd->ctrl_handler,
- V4L2_CID_PIXEL_RATE);
- s_asd->sd = sd;
- s_asd->dphy = devm_phy_get(rkisp1->dev, "dphy");
- if (IS_ERR(s_asd->dphy)) {
- if (PTR_ERR(s_asd->dphy) != -EPROBE_DEFER)
- dev_err(rkisp1->dev, "Couldn't get the MIPI D-PHY\n");
- return PTR_ERR(s_asd->dphy);
- }
-
- phy_init(s_asd->dphy);
-
- return 0;
-}
-
-static void rkisp1_subdev_notifier_unbind(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *sd,
- struct v4l2_async_subdev *asd)
-{
- struct rkisp1_sensor_async *s_asd =
- container_of(asd, struct rkisp1_sensor_async, asd);
-
- phy_exit(s_asd->dphy);
-}
-
-static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
-{
- struct rkisp1_device *rkisp1 =
- container_of(notifier, struct rkisp1_device, notifier);
- int ret;
-
- ret = rkisp1_create_links(rkisp1);
- if (ret)
- return ret;
-
- ret = v4l2_device_register_subdev_nodes(&rkisp1->v4l2_dev);
- if (ret)
- return ret;
-
- dev_dbg(rkisp1->dev, "Async subdev notifier completed\n");
-
- return 0;
-}
-
-static const struct v4l2_async_notifier_operations rkisp1_subdev_notifier_ops = {
- .bound = rkisp1_subdev_notifier_bound,
- .unbind = rkisp1_subdev_notifier_unbind,
- .complete = rkisp1_subdev_notifier_complete,
-};
-
-static int rkisp1_subdev_notifier(struct rkisp1_device *rkisp1)
-{
- struct v4l2_async_notifier *ntf = &rkisp1->notifier;
- unsigned int next_id = 0;
- int ret;
-
- v4l2_async_notifier_init(ntf);
-
- while (1) {
- struct v4l2_fwnode_endpoint vep = {
- .bus_type = V4L2_MBUS_CSI2_DPHY
- };
- struct rkisp1_sensor_async *rk_asd = NULL;
- struct fwnode_handle *ep;
-
- ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(rkisp1->dev),
- 0, next_id, FWNODE_GRAPH_ENDPOINT_NEXT);
- if (!ep)
- break;
-
- ret = v4l2_fwnode_endpoint_parse(ep, &vep);
- if (ret)
- goto err_parse;
-
- rk_asd = kzalloc(sizeof(*rk_asd), GFP_KERNEL);
- if (!rk_asd) {
- ret = -ENOMEM;
- goto err_parse;
- }
-
- rk_asd->mbus_type = vep.bus_type;
- rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
- rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
-
- ret = v4l2_async_notifier_add_fwnode_remote_subdev(ntf, ep,
- &rk_asd->asd);
- if (ret)
- goto err_parse;
-
- dev_dbg(rkisp1->dev, "registered ep id %d with %d lanes\n",
- vep.base.id, rk_asd->lanes);
-
- next_id = vep.base.id + 1;
-
- fwnode_handle_put(ep);
-
- continue;
-err_parse:
- fwnode_handle_put(ep);
- kfree(rk_asd);
- v4l2_async_notifier_cleanup(ntf);
- return ret;
- }
-
- if (next_id == 0)
- dev_dbg(rkisp1->dev, "no remote subdevice found\n");
- ntf->ops = &rkisp1_subdev_notifier_ops;
- ret = v4l2_async_notifier_register(&rkisp1->v4l2_dev, ntf);
- if (ret) {
- v4l2_async_notifier_cleanup(ntf);
- return ret;
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------------
- * Power
- */
-
-static int __maybe_unused rkisp1_runtime_suspend(struct device *dev)
-{
- struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
-
- clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks);
- return pinctrl_pm_select_sleep_state(dev);
-}
-
-static int __maybe_unused rkisp1_runtime_resume(struct device *dev)
-{
- struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
- int ret;
-
- ret = pinctrl_pm_select_default_state(dev);
- if (ret)
- return ret;
- ret = clk_bulk_prepare_enable(rkisp1->clk_size, rkisp1->clks);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static const struct dev_pm_ops rkisp1_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
- pm_runtime_force_resume)
- SET_RUNTIME_PM_OPS(rkisp1_runtime_suspend, rkisp1_runtime_resume, NULL)
-};
-
-/* ----------------------------------------------------------------------------
- * Core
- */
-
-static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
-{
- int ret;
-
- ret = rkisp1_isp_register(rkisp1);
- if (ret)
- return ret;
-
- ret = rkisp1_resizer_devs_register(rkisp1);
- if (ret)
- goto err_unreg_isp_subdev;
-
- ret = rkisp1_capture_devs_register(rkisp1);
- if (ret)
- goto err_unreg_resizer_devs;
-
- ret = rkisp1_stats_register(rkisp1);
- if (ret)
- goto err_unreg_capture_devs;
-
- ret = rkisp1_params_register(rkisp1);
- if (ret)
- goto err_unreg_stats;
-
- ret = rkisp1_subdev_notifier(rkisp1);
- if (ret) {
- dev_err(rkisp1->dev,
- "Failed to register subdev notifier(%d)\n", ret);
- goto err_unreg_params;
- }
-
- return 0;
-err_unreg_params:
- rkisp1_params_unregister(rkisp1);
-err_unreg_stats:
- rkisp1_stats_unregister(rkisp1);
-err_unreg_capture_devs:
- rkisp1_capture_devs_unregister(rkisp1);
-err_unreg_resizer_devs:
- rkisp1_resizer_devs_unregister(rkisp1);
-err_unreg_isp_subdev:
- rkisp1_isp_unregister(rkisp1);
- return ret;
-}
-
-static irqreturn_t rkisp1_isr(int irq, void *ctx)
-{
- struct device *dev = ctx;
- struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
-
- /*
- * Call rkisp1_capture_isr() first to handle the frame that
- * potentially completed using the current frame_sequence number before
- * it is potentially incremented by rkisp1_isp_isr() in the vertical
- * sync.
- */
- rkisp1_capture_isr(rkisp1);
- rkisp1_isp_isr(rkisp1);
- rkisp1_mipi_isr(rkisp1);
-
- return IRQ_HANDLED;
-}
-
-static const char * const rk3399_isp_clks[] = {
- "isp",
- "aclk",
- "hclk",
-};
-
-static const struct rkisp1_match_data rk3399_isp_clk_data = {
- .clks = rk3399_isp_clks,
- .size = ARRAY_SIZE(rk3399_isp_clks),
-};
-
-static const struct of_device_id rkisp1_of_match[] = {
- {
- .compatible = "rockchip,rk3399-cif-isp",
- .data = &rk3399_isp_clk_data,
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, rkisp1_of_match);
-
-static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_debug *debug = &rkisp1->debug;
-
- debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL);
- if (!debug->debugfs_dir) {
- dev_dbg(rkisp1->dev, "failed to create debugfs directory\n");
- return;
- }
- debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
- &debug->data_loss);
- debugfs_create_ulong("outform_size_err", 0444, debug->debugfs_dir,
- &debug->outform_size_error);
- debugfs_create_ulong("img_stabilization_size_error", 0444,
- debug->debugfs_dir,
- &debug->img_stabilization_size_error);
- debugfs_create_ulong("inform_size_error", 0444, debug->debugfs_dir,
- &debug->inform_size_error);
- debugfs_create_ulong("irq_delay", 0444, debug->debugfs_dir,
- &debug->irq_delay);
- debugfs_create_ulong("mipi_error", 0444, debug->debugfs_dir,
- &debug->mipi_error);
- debugfs_create_ulong("stats_error", 0444, debug->debugfs_dir,
- &debug->stats_error);
- debugfs_create_ulong("mp_stop_timeout", 0444, debug->debugfs_dir,
- &debug->stop_timeout[RKISP1_MAINPATH]);
- debugfs_create_ulong("sp_stop_timeout", 0444, debug->debugfs_dir,
- &debug->stop_timeout[RKISP1_SELFPATH]);
- debugfs_create_ulong("mp_frame_drop", 0444, debug->debugfs_dir,
- &debug->frame_drop[RKISP1_MAINPATH]);
- debugfs_create_ulong("sp_frame_drop", 0444, debug->debugfs_dir,
- &debug->frame_drop[RKISP1_SELFPATH]);
-}
-
-static int rkisp1_probe(struct platform_device *pdev)
-{
- const struct rkisp1_match_data *clk_data;
- struct device *dev = &pdev->dev;
- struct rkisp1_device *rkisp1;
- struct v4l2_device *v4l2_dev;
- unsigned int i;
- int ret, irq;
-
- clk_data = of_device_get_match_data(&pdev->dev);
- if (!clk_data)
- return -ENODEV;
-
- rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL);
- if (!rkisp1)
- return -ENOMEM;
-
- dev_set_drvdata(dev, rkisp1);
- rkisp1->dev = dev;
-
- mutex_init(&rkisp1->stream_lock);
-
- rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(rkisp1->base_addr))
- return PTR_ERR(rkisp1->base_addr);
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- ret = devm_request_irq(dev, irq, rkisp1_isr, IRQF_SHARED,
- dev_driver_string(dev), dev);
- if (ret) {
- dev_err(dev, "request irq failed: %d\n", ret);
- return ret;
- }
-
- rkisp1->irq = irq;
-
- for (i = 0; i < clk_data->size; i++)
- rkisp1->clks[i].id = clk_data->clks[i];
- ret = devm_clk_bulk_get(dev, clk_data->size, rkisp1->clks);
- if (ret)
- return ret;
- rkisp1->clk_size = clk_data->size;
-
- pm_runtime_enable(&pdev->dev);
-
- strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME,
- sizeof(rkisp1->media_dev.model));
- rkisp1->media_dev.dev = &pdev->dev;
- strscpy(rkisp1->media_dev.bus_info, RKISP1_BUS_INFO,
- sizeof(rkisp1->media_dev.bus_info));
- media_device_init(&rkisp1->media_dev);
-
- v4l2_dev = &rkisp1->v4l2_dev;
- v4l2_dev->mdev = &rkisp1->media_dev;
- strscpy(v4l2_dev->name, RKISP1_DRIVER_NAME, sizeof(v4l2_dev->name));
-
- ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev);
- if (ret)
- return ret;
-
- ret = media_device_register(&rkisp1->media_dev);
- if (ret) {
- dev_err(dev, "Failed to register media device: %d\n", ret);
- goto err_unreg_v4l2_dev;
- }
-
- ret = rkisp1_entities_register(rkisp1);
- if (ret)
- goto err_unreg_media_dev;
-
- rkisp1_debug_init(rkisp1);
-
- return 0;
-
-err_unreg_media_dev:
- media_device_unregister(&rkisp1->media_dev);
-err_unreg_v4l2_dev:
- v4l2_device_unregister(&rkisp1->v4l2_dev);
- pm_runtime_disable(&pdev->dev);
- return ret;
-}
-
-static int rkisp1_remove(struct platform_device *pdev)
-{
- struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev);
-
- v4l2_async_notifier_unregister(&rkisp1->notifier);
- v4l2_async_notifier_cleanup(&rkisp1->notifier);
-
- rkisp1_params_unregister(rkisp1);
- rkisp1_stats_unregister(rkisp1);
- rkisp1_capture_devs_unregister(rkisp1);
- rkisp1_resizer_devs_unregister(rkisp1);
- rkisp1_isp_unregister(rkisp1);
-
- media_device_unregister(&rkisp1->media_dev);
- v4l2_device_unregister(&rkisp1->v4l2_dev);
-
- pm_runtime_disable(&pdev->dev);
-
- debugfs_remove_recursive(rkisp1->debug.debugfs_dir);
- return 0;
-}
-
-static struct platform_driver rkisp1_drv = {
- .driver = {
- .name = RKISP1_DRIVER_NAME,
- .of_match_table = of_match_ptr(rkisp1_of_match),
- .pm = &rkisp1_pm_ops,
- },
- .probe = rkisp1_probe,
- .remove = rkisp1_remove,
-};
-
-module_platform_driver(rkisp1_drv);
-MODULE_DESCRIPTION("Rockchip ISP1 platform driver");
-MODULE_LICENSE("Dual MIT/GPL");
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - ISP Subdevice
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <linux/iopoll.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-mipi-dphy.h>
-#include <linux/pm_runtime.h>
-#include <linux/videodev2.h>
-#include <linux/vmalloc.h>
-#include <media/v4l2-event.h>
-
-#include "rkisp1-common.h"
-
-#define RKISP1_DEF_SINK_PAD_FMT MEDIA_BUS_FMT_SRGGB10_1X10
-#define RKISP1_DEF_SRC_PAD_FMT MEDIA_BUS_FMT_YUYV8_2X8
-
-#define RKISP1_ISP_DEV_NAME RKISP1_DRIVER_NAME "_isp"
-
-/*
- * NOTE: MIPI controller and input MUX are also configured in this file.
- * This is because ISP Subdev describes not only ISP submodule (input size,
- * format, output size, format), but also a virtual route device.
- */
-
-/*
- * There are many variables named with format/frame in below code,
- * please see here for their meaning.
- * Cropping in the sink pad defines the image region from the sensor.
- * Cropping in the source pad defines the region for the Image Stabilizer (IS)
- *
- * Cropping regions of ISP
- *
- * +---------------------------------------------------------+
- * | Sensor image |
- * | +---------------------------------------------------+ |
- * | | CIF_ISP_ACQ (for black level) | |
- * | | sink pad format | |
- * | | +--------------------------------------------+ | |
- * | | | CIF_ISP_OUT | | |
- * | | | sink pad crop | | |
- * | | | +---------------------------------+ | | |
- * | | | | CIF_ISP_IS | | | |
- * | | | | source pad crop and format | | | |
- * | | | +---------------------------------+ | | |
- * | | +--------------------------------------------+ | |
- * | +---------------------------------------------------+ |
- * +---------------------------------------------------------+
- */
-
-static const struct rkisp1_isp_mbus_info rkisp1_isp_formats[] = {
- {
- .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
- .pixel_enc = V4L2_PIXEL_ENC_YUV,
- .direction = RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
- .bayer_pat = RKISP1_RAW_RGGB,
- .bus_width = 10,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
- .bayer_pat = RKISP1_RAW_BGGR,
- .bus_width = 10,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
- .bayer_pat = RKISP1_RAW_GBRG,
- .bus_width = 10,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW10,
- .bayer_pat = RKISP1_RAW_GRBG,
- .bus_width = 10,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
- .bayer_pat = RKISP1_RAW_RGGB,
- .bus_width = 12,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
- .bayer_pat = RKISP1_RAW_BGGR,
- .bus_width = 12,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
- .bayer_pat = RKISP1_RAW_GBRG,
- .bus_width = 12,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW12,
- .bayer_pat = RKISP1_RAW_GRBG,
- .bus_width = 12,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
- .bayer_pat = RKISP1_RAW_RGGB,
- .bus_width = 8,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
- .bayer_pat = RKISP1_RAW_BGGR,
- .bus_width = 8,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
- .bayer_pat = RKISP1_RAW_GBRG,
- .bus_width = 8,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
- .pixel_enc = V4L2_PIXEL_ENC_BAYER,
- .mipi_dt = RKISP1_CIF_CSI2_DT_RAW8,
- .bayer_pat = RKISP1_RAW_GRBG,
- .bus_width = 8,
- .direction = RKISP1_ISP_SD_SINK | RKISP1_ISP_SD_SRC,
- }, {
- .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
- .pixel_enc = V4L2_PIXEL_ENC_YUV,
- .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
- .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_YCBYCR,
- .bus_width = 16,
- .direction = RKISP1_ISP_SD_SINK,
- }, {
- .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
- .pixel_enc = V4L2_PIXEL_ENC_YUV,
- .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
- .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_YCRYCB,
- .bus_width = 16,
- .direction = RKISP1_ISP_SD_SINK,
- }, {
- .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
- .pixel_enc = V4L2_PIXEL_ENC_YUV,
- .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
- .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_CBYCRY,
- .bus_width = 16,
- .direction = RKISP1_ISP_SD_SINK,
- }, {
- .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
- .pixel_enc = V4L2_PIXEL_ENC_YUV,
- .mipi_dt = RKISP1_CIF_CSI2_DT_YUV422_8b,
- .yuv_seq = RKISP1_CIF_ISP_ACQ_PROP_CRYCBY,
- .bus_width = 16,
- .direction = RKISP1_ISP_SD_SINK,
- },
-};
-
-/* ----------------------------------------------------------------------------
- * Helpers
- */
-
-const struct rkisp1_isp_mbus_info *rkisp1_isp_mbus_info_get(u32 mbus_code)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
- const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
-
- if (fmt->mbus_code == mbus_code)
- return fmt;
- }
-
- return NULL;
-}
-
-static struct v4l2_subdev *rkisp1_get_remote_sensor(struct v4l2_subdev *sd)
-{
- struct media_pad *local, *remote;
- struct media_entity *sensor_me;
-
- local = &sd->entity.pads[RKISP1_ISP_PAD_SINK_VIDEO];
- remote = media_entity_remote_pad(local);
- if (!remote)
- return NULL;
-
- sensor_me = remote->entity;
- return media_entity_to_v4l2_subdev(sensor_me);
-}
-
-static struct v4l2_mbus_framefmt *
-rkisp1_isp_get_pad_fmt(struct rkisp1_isp *isp,
- struct v4l2_subdev_pad_config *cfg,
- unsigned int pad, u32 which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(&isp->sd, cfg, pad);
- else
- return v4l2_subdev_get_try_format(&isp->sd, isp->pad_cfg, pad);
-}
-
-static struct v4l2_rect *
-rkisp1_isp_get_pad_crop(struct rkisp1_isp *isp,
- struct v4l2_subdev_pad_config *cfg,
- unsigned int pad, u32 which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(&isp->sd, cfg, pad);
- else
- return v4l2_subdev_get_try_crop(&isp->sd, isp->pad_cfg, pad);
-}
-
-/* ----------------------------------------------------------------------------
- * Camera Interface registers configurations
- */
-
-/*
- * Image Stabilization.
- * This should only be called when configuring CIF
- * or at the frame end interrupt
- */
-static void rkisp1_config_ism(struct rkisp1_device *rkisp1)
-{
- struct v4l2_rect *src_crop =
- rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
- RKISP1_ISP_PAD_SOURCE_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- u32 val;
-
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_RECENTER);
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DX);
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_MAX_DY);
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IS_DISPLACE);
- rkisp1_write(rkisp1, src_crop->left, RKISP1_CIF_ISP_IS_H_OFFS);
- rkisp1_write(rkisp1, src_crop->top, RKISP1_CIF_ISP_IS_V_OFFS);
- rkisp1_write(rkisp1, src_crop->width, RKISP1_CIF_ISP_IS_H_SIZE);
- rkisp1_write(rkisp1, src_crop->height, RKISP1_CIF_ISP_IS_V_SIZE);
-
- /* IS(Image Stabilization) is always on, working as output crop */
- rkisp1_write(rkisp1, 1, RKISP1_CIF_ISP_IS_CTRL);
- val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
- val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD;
- rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
-}
-
-/*
- * configure ISP blocks with input format, size......
- */
-static int rkisp1_config_isp(struct rkisp1_device *rkisp1)
-{
- u32 isp_ctrl = 0, irq_mask = 0, acq_mult = 0, signal = 0;
- const struct rkisp1_isp_mbus_info *src_fmt, *sink_fmt;
- struct rkisp1_sensor_async *sensor;
- struct v4l2_mbus_framefmt *sink_frm;
- struct v4l2_rect *sink_crop;
-
- sensor = rkisp1->active_sensor;
- sink_fmt = rkisp1->isp.sink_fmt;
- src_fmt = rkisp1->isp.src_fmt;
- sink_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
- RKISP1_ISP_PAD_SINK_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- sink_crop = rkisp1_isp_get_pad_crop(&rkisp1->isp, NULL,
- RKISP1_ISP_PAD_SINK_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
-
- if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
- acq_mult = 1;
- if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
- if (sensor->mbus_type == V4L2_MBUS_BT656)
- isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656;
- else
- isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT;
- } else {
- rkisp1_write(rkisp1, RKISP1_CIF_ISP_DEMOSAIC_TH(0xc),
- RKISP1_CIF_ISP_DEMOSAIC);
-
- if (sensor->mbus_type == V4L2_MBUS_BT656)
- isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656;
- else
- isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601;
- }
- } else if (sink_fmt->pixel_enc == V4L2_PIXEL_ENC_YUV) {
- acq_mult = 2;
- if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
- isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
- } else {
- if (sensor->mbus_type == V4L2_MBUS_BT656)
- isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656;
- else
- isp_ctrl = RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601;
- }
-
- irq_mask |= RKISP1_CIF_ISP_DATA_LOSS;
- }
-
- /* Set up input acquisition properties */
- if (sensor->mbus_type == V4L2_MBUS_BT656 ||
- sensor->mbus_type == V4L2_MBUS_PARALLEL) {
- if (sensor->mbus_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
- signal = RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE;
- }
-
- if (sensor->mbus_type == V4L2_MBUS_PARALLEL) {
- if (sensor->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- signal |= RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW;
-
- if (sensor->mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- signal |= RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW;
- }
-
- rkisp1_write(rkisp1, isp_ctrl, RKISP1_CIF_ISP_CTRL);
- rkisp1_write(rkisp1, signal | sink_fmt->yuv_seq |
- RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(sink_fmt->bayer_pat) |
- RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL,
- RKISP1_CIF_ISP_ACQ_PROP);
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_NR_FRAMES);
-
- /* Acquisition Size */
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_H_OFFS);
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_ACQ_V_OFFS);
- rkisp1_write(rkisp1,
- acq_mult * sink_frm->width, RKISP1_CIF_ISP_ACQ_H_SIZE);
- rkisp1_write(rkisp1, sink_frm->height, RKISP1_CIF_ISP_ACQ_V_SIZE);
-
- /* ISP Out Area */
- rkisp1_write(rkisp1, sink_crop->left, RKISP1_CIF_ISP_OUT_H_OFFS);
- rkisp1_write(rkisp1, sink_crop->top, RKISP1_CIF_ISP_OUT_V_OFFS);
- rkisp1_write(rkisp1, sink_crop->width, RKISP1_CIF_ISP_OUT_H_SIZE);
- rkisp1_write(rkisp1, sink_crop->height, RKISP1_CIF_ISP_OUT_V_SIZE);
-
- irq_mask |= RKISP1_CIF_ISP_FRAME | RKISP1_CIF_ISP_V_START |
- RKISP1_CIF_ISP_PIC_SIZE_ERROR;
- rkisp1_write(rkisp1, irq_mask, RKISP1_CIF_ISP_IMSC);
-
- if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
- rkisp1_params_disable(&rkisp1->params);
- } else {
- struct v4l2_mbus_framefmt *src_frm;
-
- src_frm = rkisp1_isp_get_pad_fmt(&rkisp1->isp, NULL,
- RKISP1_ISP_PAD_SINK_VIDEO,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- rkisp1_params_configure(&rkisp1->params, sink_fmt->bayer_pat,
- src_frm->quantization);
- }
-
- return 0;
-}
-
-static int rkisp1_config_dvp(struct rkisp1_device *rkisp1)
-{
- const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
- u32 val, input_sel;
-
- switch (sink_fmt->bus_width) {
- case 8:
- input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;
- break;
- case 10:
- input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;
- break;
- case 12:
- input_sel = RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B;
- break;
- default:
- dev_err(rkisp1->dev, "Invalid bus width\n");
- return -EINVAL;
- }
-
- val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ACQ_PROP);
- rkisp1_write(rkisp1, val | input_sel, RKISP1_CIF_ISP_ACQ_PROP);
-
- return 0;
-}
-
-static int rkisp1_config_mipi(struct rkisp1_device *rkisp1)
-{
- const struct rkisp1_isp_mbus_info *sink_fmt = rkisp1->isp.sink_fmt;
- unsigned int lanes = rkisp1->active_sensor->lanes;
- u32 mipi_ctrl;
-
- if (lanes < 1 || lanes > 4)
- return -EINVAL;
-
- mipi_ctrl = RKISP1_CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
- RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
- RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
- RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA;
-
- rkisp1_write(rkisp1, mipi_ctrl, RKISP1_CIF_MIPI_CTRL);
-
- /* Configure Data Type and Virtual Channel */
- rkisp1_write(rkisp1,
- RKISP1_CIF_MIPI_DATA_SEL_DT(sink_fmt->mipi_dt) |
- RKISP1_CIF_MIPI_DATA_SEL_VC(0),
- RKISP1_CIF_MIPI_IMG_DATA_SEL);
-
- /* Clear MIPI interrupts */
- rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
- /*
- * Disable RKISP1_CIF_MIPI_ERR_DPHY interrupt here temporary for
- * isp bus may be dead when switch isp.
- */
- rkisp1_write(rkisp1,
- RKISP1_CIF_MIPI_FRAME_END | RKISP1_CIF_MIPI_ERR_CSI |
- RKISP1_CIF_MIPI_ERR_DPHY |
- RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(0x03) |
- RKISP1_CIF_MIPI_ADD_DATA_OVFLW,
- RKISP1_CIF_MIPI_IMSC);
-
- dev_dbg(rkisp1->dev, "\n MIPI_CTRL 0x%08x\n"
- " MIPI_IMG_DATA_SEL 0x%08x\n"
- " MIPI_STATUS 0x%08x\n"
- " MIPI_IMSC 0x%08x\n",
- rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL),
- rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMG_DATA_SEL),
- rkisp1_read(rkisp1, RKISP1_CIF_MIPI_STATUS),
- rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC));
-
- return 0;
-}
-
-/* Configure MUX */
-static int rkisp1_config_path(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
- u32 dpcl = rkisp1_read(rkisp1, RKISP1_CIF_VI_DPCL);
- int ret = 0;
-
- if (sensor->mbus_type == V4L2_MBUS_BT656 ||
- sensor->mbus_type == V4L2_MBUS_PARALLEL) {
- ret = rkisp1_config_dvp(rkisp1);
- dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL;
- } else if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
- ret = rkisp1_config_mipi(rkisp1);
- dpcl |= RKISP1_CIF_VI_DPCL_IF_SEL_MIPI;
- }
-
- rkisp1_write(rkisp1, dpcl, RKISP1_CIF_VI_DPCL);
-
- return ret;
-}
-
-/* Hardware configure Entry */
-static int rkisp1_config_cif(struct rkisp1_device *rkisp1)
-{
- u32 cif_id;
- int ret;
-
- cif_id = rkisp1_read(rkisp1, RKISP1_CIF_VI_ID);
- dev_dbg(rkisp1->dev, "CIF_ID 0x%08x\n", cif_id);
-
- ret = rkisp1_config_isp(rkisp1);
- if (ret)
- return ret;
- ret = rkisp1_config_path(rkisp1);
- if (ret)
- return ret;
- rkisp1_config_ism(rkisp1);
-
- return 0;
-}
-
-static void rkisp1_isp_stop(struct rkisp1_device *rkisp1)
-{
- u32 val;
-
- /*
- * ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
- * Stop ISP(isp) ->wait for ISP isp off
- */
- /* stop and clear MI, MIPI, and ISP interrupts */
- rkisp1_write(rkisp1, 0, RKISP1_CIF_MIPI_IMSC);
- rkisp1_write(rkisp1, ~0, RKISP1_CIF_MIPI_ICR);
-
- rkisp1_write(rkisp1, 0, RKISP1_CIF_ISP_IMSC);
- rkisp1_write(rkisp1, ~0, RKISP1_CIF_ISP_ICR);
-
- rkisp1_write(rkisp1, 0, RKISP1_CIF_MI_IMSC);
- rkisp1_write(rkisp1, ~0, RKISP1_CIF_MI_ICR);
- val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
- rkisp1_write(rkisp1, val & (~RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA),
- RKISP1_CIF_MIPI_CTRL);
- /* stop ISP */
- val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
- val &= ~(RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE |
- RKISP1_CIF_ISP_CTRL_ISP_ENABLE);
- rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
-
- val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
- rkisp1_write(rkisp1, val | RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD,
- RKISP1_CIF_ISP_CTRL);
-
- readx_poll_timeout(readl, rkisp1->base_addr + RKISP1_CIF_ISP_RIS,
- val, val & RKISP1_CIF_ISP_OFF, 20, 100);
- rkisp1_write(rkisp1,
- RKISP1_CIF_IRCL_MIPI_SW_RST | RKISP1_CIF_IRCL_ISP_SW_RST,
- RKISP1_CIF_IRCL);
- rkisp1_write(rkisp1, 0x0, RKISP1_CIF_IRCL);
-}
-
-static void rkisp1_config_clk(struct rkisp1_device *rkisp1)
-{
- u32 val = RKISP1_CIF_ICCL_ISP_CLK | RKISP1_CIF_ICCL_CP_CLK |
- RKISP1_CIF_ICCL_MRSZ_CLK | RKISP1_CIF_ICCL_SRSZ_CLK |
- RKISP1_CIF_ICCL_JPEG_CLK | RKISP1_CIF_ICCL_MI_CLK |
- RKISP1_CIF_ICCL_IE_CLK | RKISP1_CIF_ICCL_MIPI_CLK |
- RKISP1_CIF_ICCL_DCROP_CLK;
-
- rkisp1_write(rkisp1, val, RKISP1_CIF_ICCL);
-}
-
-static void rkisp1_isp_start(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_sensor_async *sensor = rkisp1->active_sensor;
- u32 val;
-
- rkisp1_config_clk(rkisp1);
-
- /* Activate MIPI */
- if (sensor->mbus_type == V4L2_MBUS_CSI2_DPHY) {
- val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL);
- rkisp1_write(rkisp1, val | RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA,
- RKISP1_CIF_MIPI_CTRL);
- }
- /* Activate ISP */
- val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
- val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
- RKISP1_CIF_ISP_CTRL_ISP_ENABLE |
- RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE;
- rkisp1_write(rkisp1, val, RKISP1_CIF_ISP_CTRL);
-
- /*
- * CIF spec says to wait for sufficient time after enabling
- * the MIPI interface and before starting the sensor output.
- */
- usleep_range(1000, 1200);
-}
-
-/* ----------------------------------------------------------------------------
- * Subdev pad operations
- */
-
-static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- unsigned int i, dir;
- int pos = 0;
-
- if (code->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
- dir = RKISP1_ISP_SD_SINK;
- } else if (code->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) {
- dir = RKISP1_ISP_SD_SRC;
- } else {
- if (code->index > 0)
- return -EINVAL;
- code->code = MEDIA_BUS_FMT_METADATA_FIXED;
- return 0;
- }
-
- if (code->index >= ARRAY_SIZE(rkisp1_isp_formats))
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(rkisp1_isp_formats); i++) {
- const struct rkisp1_isp_mbus_info *fmt = &rkisp1_isp_formats[i];
-
- if (fmt->direction & dir)
- pos++;
-
- if (code->index == pos - 1) {
- code->code = fmt->mbus_code;
- if (fmt->pixel_enc == V4L2_PIXEL_ENC_YUV &&
- dir == RKISP1_ISP_SD_SRC)
- code->flags =
- V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-static int rkisp1_isp_init_config(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg)
-{
- struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
- struct v4l2_rect *sink_crop, *src_crop;
-
- sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
- RKISP1_ISP_PAD_SINK_VIDEO);
- sink_fmt->width = RKISP1_DEFAULT_WIDTH;
- sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
- sink_fmt->field = V4L2_FIELD_NONE;
- sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
-
- sink_crop = v4l2_subdev_get_try_crop(sd, cfg,
- RKISP1_ISP_PAD_SINK_VIDEO);
- sink_crop->width = RKISP1_DEFAULT_WIDTH;
- sink_crop->height = RKISP1_DEFAULT_HEIGHT;
- sink_crop->left = 0;
- sink_crop->top = 0;
-
- src_fmt = v4l2_subdev_get_try_format(sd, cfg,
- RKISP1_ISP_PAD_SOURCE_VIDEO);
- *src_fmt = *sink_fmt;
- src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
-
- src_crop = v4l2_subdev_get_try_crop(sd, cfg,
- RKISP1_ISP_PAD_SOURCE_VIDEO);
- *src_crop = *sink_crop;
-
- sink_fmt = v4l2_subdev_get_try_format(sd, cfg,
- RKISP1_ISP_PAD_SINK_PARAMS);
- src_fmt = v4l2_subdev_get_try_format(sd, cfg,
- RKISP1_ISP_PAD_SOURCE_STATS);
- sink_fmt->width = 0;
- sink_fmt->height = 0;
- sink_fmt->field = V4L2_FIELD_NONE;
- sink_fmt->code = MEDIA_BUS_FMT_METADATA_FIXED;
- *src_fmt = *sink_fmt;
-
- return 0;
-}
-
-static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_mbus_framefmt *format,
- unsigned int which)
-{
- const struct rkisp1_isp_mbus_info *mbus_info;
- struct v4l2_mbus_framefmt *src_fmt;
- const struct v4l2_rect *src_crop;
-
- src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
- src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
-
- src_fmt->code = format->code;
- mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
- if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
- src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
- mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
- }
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
- isp->src_fmt = mbus_info;
- src_fmt->width = src_crop->width;
- src_fmt->height = src_crop->height;
-
- /*
- * The CSC API is used to allow userspace to force full
- * quantization on YUV formats.
- */
- if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC &&
- format->quantization == V4L2_QUANTIZATION_FULL_RANGE &&
- mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
- src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
- else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
- src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
- else
- src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
-
- *format = *src_fmt;
-}
-
-static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_rect *r, unsigned int which)
-{
- struct v4l2_mbus_framefmt *src_fmt;
- const struct v4l2_rect *sink_crop;
- struct v4l2_rect *src_crop;
-
- src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
- RKISP1_ISP_PAD_SOURCE_VIDEO,
- which);
- sink_crop = rkisp1_isp_get_pad_crop(isp, cfg,
- RKISP1_ISP_PAD_SINK_VIDEO,
- which);
-
- src_crop->left = ALIGN(r->left, 2);
- src_crop->width = ALIGN(r->width, 2);
- src_crop->top = r->top;
- src_crop->height = r->height;
- rkisp1_sd_adjust_crop_rect(src_crop, sink_crop);
-
- *r = *src_crop;
-
- /* Propagate to out format */
- src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
- rkisp1_isp_set_src_fmt(isp, cfg, src_fmt, which);
-}
-
-static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_rect *r, unsigned int which)
-{
- struct v4l2_rect *sink_crop, *src_crop;
- struct v4l2_mbus_framefmt *sink_fmt;
-
- sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
- which);
- sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
- which);
-
- sink_crop->left = ALIGN(r->left, 2);
- sink_crop->width = ALIGN(r->width, 2);
- sink_crop->top = r->top;
- sink_crop->height = r->height;
- rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
-
- *r = *sink_crop;
-
- /* Propagate to out crop */
- src_crop = rkisp1_isp_get_pad_crop(isp, cfg,
- RKISP1_ISP_PAD_SOURCE_VIDEO, which);
- rkisp1_isp_set_src_crop(isp, cfg, src_crop, which);
-}
-
-static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_mbus_framefmt *format,
- unsigned int which)
-{
- const struct rkisp1_isp_mbus_info *mbus_info;
- struct v4l2_mbus_framefmt *sink_fmt;
- struct v4l2_rect *sink_crop;
-
- sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
- which);
- sink_fmt->code = format->code;
- mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
- if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SINK)) {
- sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT;
- mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
- }
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
- isp->sink_fmt = mbus_info;
-
- sink_fmt->width = clamp_t(u32, format->width,
- RKISP1_ISP_MIN_WIDTH,
- RKISP1_ISP_MAX_WIDTH);
- sink_fmt->height = clamp_t(u32, format->height,
- RKISP1_ISP_MIN_HEIGHT,
- RKISP1_ISP_MAX_HEIGHT);
-
- *format = *sink_fmt;
-
- /* Propagate to in crop */
- sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO,
- which);
- rkisp1_isp_set_sink_crop(isp, cfg, sink_crop, which);
-}
-
-static int rkisp1_isp_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
-
- mutex_lock(&isp->ops_lock);
- fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad, fmt->which);
- mutex_unlock(&isp->ops_lock);
- return 0;
-}
-
-static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
-
- mutex_lock(&isp->ops_lock);
- if (fmt->pad == RKISP1_ISP_PAD_SINK_VIDEO)
- rkisp1_isp_set_sink_fmt(isp, cfg, &fmt->format, fmt->which);
- else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
- rkisp1_isp_set_src_fmt(isp, cfg, &fmt->format, fmt->which);
- else
- fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad,
- fmt->which);
-
- mutex_unlock(&isp->ops_lock);
- return 0;
-}
-
-static int rkisp1_isp_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_selection *sel)
-{
- struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
- int ret = 0;
-
- if (sel->pad != RKISP1_ISP_PAD_SOURCE_VIDEO &&
- sel->pad != RKISP1_ISP_PAD_SINK_VIDEO)
- return -EINVAL;
-
- mutex_lock(&isp->ops_lock);
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) {
- struct v4l2_mbus_framefmt *fmt;
-
- fmt = rkisp1_isp_get_pad_fmt(isp, cfg, sel->pad,
- sel->which);
- sel->r.height = fmt->height;
- sel->r.width = fmt->width;
- sel->r.left = 0;
- sel->r.top = 0;
- } else {
- sel->r = *rkisp1_isp_get_pad_crop(isp, cfg,
- RKISP1_ISP_PAD_SINK_VIDEO,
- sel->which);
- }
- break;
- case V4L2_SEL_TGT_CROP:
- sel->r = *rkisp1_isp_get_pad_crop(isp, cfg, sel->pad,
- sel->which);
- break;
- default:
- ret = -EINVAL;
- }
- mutex_unlock(&isp->ops_lock);
- return ret;
-}
-
-static int rkisp1_isp_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_selection *sel)
-{
- struct rkisp1_device *rkisp1 =
- container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
- struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd);
- int ret = 0;
-
- if (sel->target != V4L2_SEL_TGT_CROP)
- return -EINVAL;
-
- dev_dbg(rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
- sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
- mutex_lock(&isp->ops_lock);
- if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO)
- rkisp1_isp_set_sink_crop(isp, cfg, &sel->r, sel->which);
- else if (sel->pad == RKISP1_ISP_PAD_SOURCE_VIDEO)
- rkisp1_isp_set_src_crop(isp, cfg, &sel->r, sel->which);
- else
- ret = -EINVAL;
-
- mutex_unlock(&isp->ops_lock);
- return ret;
-}
-
-static int rkisp1_subdev_link_validate(struct media_link *link)
-{
- if (link->sink->index == RKISP1_ISP_PAD_SINK_PARAMS)
- return 0;
-
- return v4l2_subdev_link_validate(link);
-}
-
-static const struct v4l2_subdev_pad_ops rkisp1_isp_pad_ops = {
- .enum_mbus_code = rkisp1_isp_enum_mbus_code,
- .get_selection = rkisp1_isp_get_selection,
- .set_selection = rkisp1_isp_set_selection,
- .init_cfg = rkisp1_isp_init_config,
- .get_fmt = rkisp1_isp_get_fmt,
- .set_fmt = rkisp1_isp_set_fmt,
- .link_validate = v4l2_subdev_link_validate_default,
-};
-
-/* ----------------------------------------------------------------------------
- * Stream operations
- */
-
-static int rkisp1_mipi_csi2_start(struct rkisp1_isp *isp,
- struct rkisp1_sensor_async *sensor)
-{
- struct rkisp1_device *rkisp1 =
- container_of(isp->sd.v4l2_dev, struct rkisp1_device, v4l2_dev);
- union phy_configure_opts opts;
- struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
- s64 pixel_clock;
-
- if (!sensor->pixel_rate_ctrl) {
- dev_warn(rkisp1->dev, "No pixel rate control in sensor subdev\n");
- return -EPIPE;
- }
-
- pixel_clock = v4l2_ctrl_g_ctrl_int64(sensor->pixel_rate_ctrl);
- if (!pixel_clock) {
- dev_err(rkisp1->dev, "Invalid pixel rate value\n");
- return -EINVAL;
- }
-
- phy_mipi_dphy_get_default_config(pixel_clock, isp->sink_fmt->bus_width,
- sensor->lanes, cfg);
- phy_set_mode(sensor->dphy, PHY_MODE_MIPI_DPHY);
- phy_configure(sensor->dphy, &opts);
- phy_power_on(sensor->dphy);
-
- return 0;
-}
-
-static void rkisp1_mipi_csi2_stop(struct rkisp1_sensor_async *sensor)
-{
- phy_power_off(sensor->dphy);
-}
-
-static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct rkisp1_device *rkisp1 =
- container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
- struct rkisp1_isp *isp = &rkisp1->isp;
- struct v4l2_subdev *sensor_sd;
- int ret = 0;
-
- if (!enable) {
- rkisp1_isp_stop(rkisp1);
- rkisp1_mipi_csi2_stop(rkisp1->active_sensor);
- return 0;
- }
-
- sensor_sd = rkisp1_get_remote_sensor(sd);
- if (!sensor_sd) {
- dev_warn(rkisp1->dev, "No link between isp and sensor\n");
- return -ENODEV;
- }
-
- rkisp1->active_sensor = container_of(sensor_sd->asd,
- struct rkisp1_sensor_async, asd);
-
- if (rkisp1->active_sensor->mbus_type != V4L2_MBUS_CSI2_DPHY)
- return -EINVAL;
-
- rkisp1->isp.frame_sequence = -1;
- mutex_lock(&isp->ops_lock);
- ret = rkisp1_config_cif(rkisp1);
- if (ret)
- goto mutex_unlock;
-
- ret = rkisp1_mipi_csi2_start(&rkisp1->isp, rkisp1->active_sensor);
- if (ret)
- goto mutex_unlock;
-
- rkisp1_isp_start(rkisp1);
-
-mutex_unlock:
- mutex_unlock(&isp->ops_lock);
- return ret;
-}
-
-static int rkisp1_isp_subs_evt(struct v4l2_subdev *sd, struct v4l2_fh *fh,
- struct v4l2_event_subscription *sub)
-{
- if (sub->type != V4L2_EVENT_FRAME_SYNC)
- return -EINVAL;
-
- /* V4L2_EVENT_FRAME_SYNC doesn't require an id, so zero should be set */
- if (sub->id != 0)
- return -EINVAL;
-
- return v4l2_event_subscribe(fh, sub, 0, NULL);
-}
-
-static const struct media_entity_operations rkisp1_isp_media_ops = {
- .link_validate = rkisp1_subdev_link_validate,
-};
-
-static const struct v4l2_subdev_video_ops rkisp1_isp_video_ops = {
- .s_stream = rkisp1_isp_s_stream,
-};
-
-static const struct v4l2_subdev_core_ops rkisp1_isp_core_ops = {
- .subscribe_event = rkisp1_isp_subs_evt,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
-static const struct v4l2_subdev_ops rkisp1_isp_ops = {
- .core = &rkisp1_isp_core_ops,
- .video = &rkisp1_isp_video_ops,
- .pad = &rkisp1_isp_pad_ops,
-};
-
-int rkisp1_isp_register(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_isp *isp = &rkisp1->isp;
- struct media_pad *pads = isp->pads;
- struct v4l2_subdev *sd = &isp->sd;
- int ret;
-
- v4l2_subdev_init(sd, &rkisp1_isp_ops);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
- sd->entity.ops = &rkisp1_isp_media_ops;
- sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
- sd->owner = THIS_MODULE;
- strscpy(sd->name, RKISP1_ISP_DEV_NAME, sizeof(sd->name));
-
- pads[RKISP1_ISP_PAD_SINK_VIDEO].flags = MEDIA_PAD_FL_SINK |
- MEDIA_PAD_FL_MUST_CONNECT;
- pads[RKISP1_ISP_PAD_SINK_PARAMS].flags = MEDIA_PAD_FL_SINK;
- pads[RKISP1_ISP_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
- pads[RKISP1_ISP_PAD_SOURCE_STATS].flags = MEDIA_PAD_FL_SOURCE;
-
- isp->sink_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SINK_PAD_FMT);
- isp->src_fmt = rkisp1_isp_mbus_info_get(RKISP1_DEF_SRC_PAD_FMT);
-
- mutex_init(&isp->ops_lock);
- ret = media_entity_pads_init(&sd->entity, RKISP1_ISP_PAD_MAX, pads);
- if (ret)
- return ret;
-
- ret = v4l2_device_register_subdev(&rkisp1->v4l2_dev, sd);
- if (ret) {
- dev_err(rkisp1->dev, "Failed to register isp subdev\n");
- goto err_cleanup_media_entity;
- }
-
- rkisp1_isp_init_config(sd, rkisp1->isp.pad_cfg);
- return 0;
-
-err_cleanup_media_entity:
- media_entity_cleanup(&sd->entity);
-
- return ret;
-}
-
-void rkisp1_isp_unregister(struct rkisp1_device *rkisp1)
-{
- struct v4l2_subdev *sd = &rkisp1->isp.sd;
-
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(&sd->entity);
-}
-
-/* ----------------------------------------------------------------------------
- * Interrupt handlers
- */
-
-void rkisp1_mipi_isr(struct rkisp1_device *rkisp1)
-{
- u32 val, status;
-
- status = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_MIS);
- if (!status)
- return;
-
- rkisp1_write(rkisp1, status, RKISP1_CIF_MIPI_ICR);
-
- /*
- * Disable DPHY errctrl interrupt, because this dphy
- * erctrl signal is asserted until the next changes
- * of line state. This time is may be too long and cpu
- * is hold in this interrupt.
- */
- if (status & RKISP1_CIF_MIPI_ERR_CTRL(0x0f)) {
- val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
- rkisp1_write(rkisp1, val & ~RKISP1_CIF_MIPI_ERR_CTRL(0x0f),
- RKISP1_CIF_MIPI_IMSC);
- rkisp1->isp.is_dphy_errctrl_disabled = true;
- }
-
- /*
- * Enable DPHY errctrl interrupt again, if mipi have receive
- * the whole frame without any error.
- */
- if (status == RKISP1_CIF_MIPI_FRAME_END) {
- /*
- * Enable DPHY errctrl interrupt again, if mipi have receive
- * the whole frame without any error.
- */
- if (rkisp1->isp.is_dphy_errctrl_disabled) {
- val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC);
- val |= RKISP1_CIF_MIPI_ERR_CTRL(0x0f);
- rkisp1_write(rkisp1, val, RKISP1_CIF_MIPI_IMSC);
- rkisp1->isp.is_dphy_errctrl_disabled = false;
- }
- } else {
- rkisp1->debug.mipi_error++;
- }
-}
-
-static void rkisp1_isp_queue_event_sof(struct rkisp1_isp *isp)
-{
- struct v4l2_event event = {
- .type = V4L2_EVENT_FRAME_SYNC,
- };
- event.u.frame_sync.frame_sequence = isp->frame_sequence;
-
- v4l2_event_queue(isp->sd.devnode, &event);
-}
-
-void rkisp1_isp_isr(struct rkisp1_device *rkisp1)
-{
- u32 status, isp_err;
-
- status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
- if (!status)
- return;
-
- rkisp1_write(rkisp1, status, RKISP1_CIF_ISP_ICR);
-
- /* Vertical sync signal, starting generating new frame */
- if (status & RKISP1_CIF_ISP_V_START) {
- rkisp1->isp.frame_sequence++;
- rkisp1_isp_queue_event_sof(&rkisp1->isp);
- if (status & RKISP1_CIF_ISP_FRAME) {
- WARN_ONCE(1, "irq delay is too long, buffers might not be in sync\n");
- rkisp1->debug.irq_delay++;
- }
- }
- if (status & RKISP1_CIF_ISP_PIC_SIZE_ERROR) {
- /* Clear pic_size_error */
- isp_err = rkisp1_read(rkisp1, RKISP1_CIF_ISP_ERR);
- if (isp_err & RKISP1_CIF_ISP_ERR_INFORM_SIZE)
- rkisp1->debug.inform_size_error++;
- if (isp_err & RKISP1_CIF_ISP_ERR_IS_SIZE)
- rkisp1->debug.img_stabilization_size_error++;
- if (isp_err & RKISP1_CIF_ISP_ERR_OUTFORM_SIZE)
- rkisp1->debug.outform_size_error++;
- rkisp1_write(rkisp1, isp_err, RKISP1_CIF_ISP_ERR_CLR);
- } else if (status & RKISP1_CIF_ISP_DATA_LOSS) {
- /* keep track of data_loss in debugfs */
- rkisp1->debug.data_loss++;
- }
-
- if (status & RKISP1_CIF_ISP_FRAME) {
- u32 isp_ris;
-
- /* New frame from the sensor received */
- isp_ris = rkisp1_read(rkisp1, RKISP1_CIF_ISP_RIS);
- if (isp_ris & RKISP1_STATS_MEAS_MASK)
- rkisp1_stats_isr(&rkisp1->stats, isp_ris);
- /*
- * Then update changed configs. Some of them involve
- * lot of register writes. Do those only one per frame.
- * Do the updates in the order of the processing flow.
- */
- rkisp1_params_isr(rkisp1);
- }
-
-}
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Params subdevice
- *
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-vmalloc.h> /* for ISP params */
-
-#include "rkisp1-common.h"
-
-#define RKISP1_PARAMS_DEV_NAME RKISP1_DRIVER_NAME "_params"
-
-#define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2
-#define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8
-
-#define RKISP1_ISP_DPCC_LINE_THRESH(n) \
- (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \
- (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_PG_FAC(n) \
- (RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_RND_THRESH(n) \
- (RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n))
-#define RKISP1_ISP_DPCC_RG_FAC(n) \
- (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n))
-#define RKISP1_ISP_CC_COEFF(n) \
- (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4)
-
-static inline void
-rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
-{
- u32 val;
-
- val = rkisp1_read(params->rkisp1, reg);
- rkisp1_write(params->rkisp1, val | bit_mask, reg);
-}
-
-static inline void
-rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask)
-{
- u32 val;
-
- val = rkisp1_read(params->rkisp1, reg);
- rkisp1_write(params->rkisp1, val & ~bit_mask, reg);
-}
-
-/* ISP BP interface function */
-static void rkisp1_dpcc_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_dpcc_config *arg)
-{
- unsigned int i;
- u32 mode;
-
- /* avoid to override the old enable value */
- mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE);
- mode &= RKISP1_CIF_ISP_DPCC_ENA;
- mode |= arg->mode & ~RKISP1_CIF_ISP_DPCC_ENA;
- rkisp1_write(params->rkisp1, mode, RKISP1_CIF_ISP_DPCC_MODE);
- rkisp1_write(params->rkisp1, arg->output_mode,
- RKISP1_CIF_ISP_DPCC_OUTPUT_MODE);
- rkisp1_write(params->rkisp1, arg->set_use,
- RKISP1_CIF_ISP_DPCC_SET_USE);
-
- rkisp1_write(params->rkisp1, arg->methods[0].method,
- RKISP1_CIF_ISP_DPCC_METHODS_SET_1);
- rkisp1_write(params->rkisp1, arg->methods[1].method,
- RKISP1_CIF_ISP_DPCC_METHODS_SET_2);
- rkisp1_write(params->rkisp1, arg->methods[2].method,
- RKISP1_CIF_ISP_DPCC_METHODS_SET_3);
- for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) {
- rkisp1_write(params->rkisp1, arg->methods[i].line_thresh,
- RKISP1_ISP_DPCC_LINE_THRESH(i));
- rkisp1_write(params->rkisp1, arg->methods[i].line_mad_fac,
- RKISP1_ISP_DPCC_LINE_MAD_FAC(i));
- rkisp1_write(params->rkisp1, arg->methods[i].pg_fac,
- RKISP1_ISP_DPCC_PG_FAC(i));
- rkisp1_write(params->rkisp1, arg->methods[i].rnd_thresh,
- RKISP1_ISP_DPCC_RND_THRESH(i));
- rkisp1_write(params->rkisp1, arg->methods[i].rg_fac,
- RKISP1_ISP_DPCC_RG_FAC(i));
- }
-
- rkisp1_write(params->rkisp1, arg->rnd_offs,
- RKISP1_CIF_ISP_DPCC_RND_OFFS);
- rkisp1_write(params->rkisp1, arg->ro_limits,
- RKISP1_CIF_ISP_DPCC_RO_LIMITS);
-}
-
-/* ISP black level subtraction interface function */
-static void rkisp1_bls_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_bls_config *arg)
-{
- /* avoid to override the old enable value */
- u32 new_control;
-
- new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL);
- new_control &= RKISP1_CIF_ISP_BLS_ENA;
- /* fixed subtraction values */
- if (!arg->enable_auto) {
- const struct rkisp1_cif_isp_bls_fixed_val *pval =
- &arg->fixed_val;
-
- switch (params->raw_type) {
- case RKISP1_RAW_BGGR:
- rkisp1_write(params->rkisp1,
- pval->r, RKISP1_CIF_ISP_BLS_D_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gr, RKISP1_CIF_ISP_BLS_C_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gb, RKISP1_CIF_ISP_BLS_B_FIXED);
- rkisp1_write(params->rkisp1,
- pval->b, RKISP1_CIF_ISP_BLS_A_FIXED);
- break;
- case RKISP1_RAW_GBRG:
- rkisp1_write(params->rkisp1,
- pval->r, RKISP1_CIF_ISP_BLS_C_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gr, RKISP1_CIF_ISP_BLS_D_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gb, RKISP1_CIF_ISP_BLS_A_FIXED);
- rkisp1_write(params->rkisp1,
- pval->b, RKISP1_CIF_ISP_BLS_B_FIXED);
- break;
- case RKISP1_RAW_GRBG:
- rkisp1_write(params->rkisp1,
- pval->r, RKISP1_CIF_ISP_BLS_B_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gr, RKISP1_CIF_ISP_BLS_A_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gb, RKISP1_CIF_ISP_BLS_D_FIXED);
- rkisp1_write(params->rkisp1,
- pval->b, RKISP1_CIF_ISP_BLS_C_FIXED);
- break;
- case RKISP1_RAW_RGGB:
- rkisp1_write(params->rkisp1,
- pval->r, RKISP1_CIF_ISP_BLS_A_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gr, RKISP1_CIF_ISP_BLS_B_FIXED);
- rkisp1_write(params->rkisp1,
- pval->gb, RKISP1_CIF_ISP_BLS_C_FIXED);
- rkisp1_write(params->rkisp1,
- pval->b, RKISP1_CIF_ISP_BLS_D_FIXED);
- break;
- default:
- break;
- }
-
- } else {
- if (arg->en_windows & BIT(1)) {
- rkisp1_write(params->rkisp1, arg->bls_window2.h_offs,
- RKISP1_CIF_ISP_BLS_H2_START);
- rkisp1_write(params->rkisp1, arg->bls_window2.h_size,
- RKISP1_CIF_ISP_BLS_H2_STOP);
- rkisp1_write(params->rkisp1, arg->bls_window2.v_offs,
- RKISP1_CIF_ISP_BLS_V2_START);
- rkisp1_write(params->rkisp1, arg->bls_window2.v_size,
- RKISP1_CIF_ISP_BLS_V2_STOP);
- new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2;
- }
-
- if (arg->en_windows & BIT(0)) {
- rkisp1_write(params->rkisp1, arg->bls_window1.h_offs,
- RKISP1_CIF_ISP_BLS_H1_START);
- rkisp1_write(params->rkisp1, arg->bls_window1.h_size,
- RKISP1_CIF_ISP_BLS_H1_STOP);
- rkisp1_write(params->rkisp1, arg->bls_window1.v_offs,
- RKISP1_CIF_ISP_BLS_V1_START);
- rkisp1_write(params->rkisp1, arg->bls_window1.v_size,
- RKISP1_CIF_ISP_BLS_V1_STOP);
- new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1;
- }
-
- rkisp1_write(params->rkisp1, arg->bls_samples,
- RKISP1_CIF_ISP_BLS_SAMPLES);
-
- new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED;
- }
- rkisp1_write(params->rkisp1, new_control, RKISP1_CIF_ISP_BLS_CTRL);
-}
-
-/* ISP LS correction interface function */
-static void
-rkisp1_lsc_correct_matrix_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_lsc_config *pconfig)
-{
- unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data;
-
- isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS);
-
- /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */
- sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
- RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 :
- RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153;
- rkisp1_write(params->rkisp1, sram_addr,
- RKISP1_CIF_ISP_LSC_R_TABLE_ADDR);
- rkisp1_write(params->rkisp1, sram_addr,
- RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR);
- rkisp1_write(params->rkisp1, sram_addr,
- RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR);
- rkisp1_write(params->rkisp1, sram_addr,
- RKISP1_CIF_ISP_LSC_B_TABLE_ADDR);
-
- /* program data tables (table size is 9 * 17 = 153) */
- for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) {
- /*
- * 17 sectors with 2 values in one DWORD = 9
- * DWORDs (2nd value of last DWORD unused)
- */
- for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) {
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j],
- pconfig->r_data_tbl[i][j + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
-
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j],
- pconfig->gr_data_tbl[i][j + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
-
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j],
- pconfig->gb_data_tbl[i][j + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
-
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j],
- pconfig->b_data_tbl[i][j + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
- }
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i][j], 0);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_R_TABLE_DATA);
-
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i][j], 0);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_GR_TABLE_DATA);
-
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i][j], 0);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_GB_TABLE_DATA);
-
- data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i][j], 0);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_B_TABLE_DATA);
- }
- isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ?
- RKISP1_CIF_ISP_LSC_TABLE_0 :
- RKISP1_CIF_ISP_LSC_TABLE_1;
- rkisp1_write(params->rkisp1, isp_lsc_table_sel,
- RKISP1_CIF_ISP_LSC_TABLE_SEL);
-}
-
-static void rkisp1_lsc_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_lsc_config *arg)
-{
- unsigned int i, data;
- u32 lsc_ctrl;
-
- /* To config must be off , store the current status firstly */
- lsc_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_CTRL);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
- RKISP1_CIF_ISP_LSC_CTRL_ENA);
- rkisp1_lsc_correct_matrix_config(params, arg);
-
- for (i = 0; i < RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE / 2; i++) {
- /* program x size tables */
- data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2],
- arg->x_size_tbl[i * 2 + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4);
-
- /* program x grad tables */
- data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2],
- arg->x_grad_tbl[i * 2 + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4);
-
- /* program y size tables */
- data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2],
- arg->y_size_tbl[i * 2 + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4);
-
- /* program y grad tables */
- data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2],
- arg->y_grad_tbl[i * 2 + 1]);
- rkisp1_write(params->rkisp1, data,
- RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4);
- }
-
- /* restore the lsc ctrl status */
- if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) {
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_LSC_CTRL,
- RKISP1_CIF_ISP_LSC_CTRL_ENA);
- } else {
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_LSC_CTRL,
- RKISP1_CIF_ISP_LSC_CTRL_ENA);
- }
-}
-
-/* ISP Filtering function */
-static void rkisp1_flt_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_flt_config *arg)
-{
- u32 filt_mode;
-
- rkisp1_write(params->rkisp1,
- arg->thresh_bl0, RKISP1_CIF_ISP_FILT_THRESH_BL0);
- rkisp1_write(params->rkisp1,
- arg->thresh_bl1, RKISP1_CIF_ISP_FILT_THRESH_BL1);
- rkisp1_write(params->rkisp1,
- arg->thresh_sh0, RKISP1_CIF_ISP_FILT_THRESH_SH0);
- rkisp1_write(params->rkisp1,
- arg->thresh_sh1, RKISP1_CIF_ISP_FILT_THRESH_SH1);
- rkisp1_write(params->rkisp1, arg->fac_bl0, RKISP1_CIF_ISP_FILT_FAC_BL0);
- rkisp1_write(params->rkisp1, arg->fac_bl1, RKISP1_CIF_ISP_FILT_FAC_BL1);
- rkisp1_write(params->rkisp1, arg->fac_mid, RKISP1_CIF_ISP_FILT_FAC_MID);
- rkisp1_write(params->rkisp1, arg->fac_sh0, RKISP1_CIF_ISP_FILT_FAC_SH0);
- rkisp1_write(params->rkisp1, arg->fac_sh1, RKISP1_CIF_ISP_FILT_FAC_SH1);
- rkisp1_write(params->rkisp1,
- arg->lum_weight, RKISP1_CIF_ISP_FILT_LUM_WEIGHT);
-
- rkisp1_write(params->rkisp1,
- (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) |
- RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
- RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
- RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1),
- RKISP1_CIF_ISP_FILT_MODE);
-
- /* avoid to override the old enable value */
- filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE);
- filt_mode &= RKISP1_CIF_ISP_FLT_ENA;
- if (arg->mode)
- filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR;
- filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) |
- RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) |
- RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1);
- rkisp1_write(params->rkisp1, filt_mode, RKISP1_CIF_ISP_FILT_MODE);
-}
-
-/* ISP demosaic interface function */
-static int rkisp1_bdm_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_bdm_config *arg)
-{
- u32 bdm_th;
-
- /* avoid to override the old enable value */
- bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC);
- bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
- bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS;
- /* set demosaic threshold */
- rkisp1_write(params->rkisp1, bdm_th, RKISP1_CIF_ISP_DEMOSAIC);
- return 0;
-}
-
-/* ISP GAMMA correction interface function */
-static void rkisp1_sdg_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_sdg_config *arg)
-{
- unsigned int i;
-
- rkisp1_write(params->rkisp1,
- arg->xa_pnts.gamma_dx0, RKISP1_CIF_ISP_GAMMA_DX_LO);
- rkisp1_write(params->rkisp1,
- arg->xa_pnts.gamma_dx1, RKISP1_CIF_ISP_GAMMA_DX_HI);
-
- for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) {
- rkisp1_write(params->rkisp1, arg->curve_r.gamma_y[i],
- RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4);
- rkisp1_write(params->rkisp1, arg->curve_g.gamma_y[i],
- RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4);
- rkisp1_write(params->rkisp1, arg->curve_b.gamma_y[i],
- RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4);
- }
-}
-
-/* ISP GAMMA correction interface function */
-static void rkisp1_goc_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_goc_config *arg)
-{
- unsigned int i;
-
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
- rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE);
-
- for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES; i++)
- rkisp1_write(params->rkisp1, arg->gamma_y[i],
- RKISP1_CIF_ISP_GAMMA_OUT_Y_0 + i * 4);
-}
-
-/* ISP Cross Talk */
-static void rkisp1_ctk_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_ctk_config *arg)
-{
- unsigned int i, j, k = 0;
-
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- rkisp1_write(params->rkisp1, arg->coeff[i][j],
- RKISP1_CIF_ISP_CT_COEFF_0 + 4 * k++);
- for (i = 0; i < 3; i++)
- rkisp1_write(params->rkisp1, arg->ct_offset[i],
- RKISP1_CIF_ISP_CT_OFFSET_R + i * 4);
-}
-
-static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en)
-{
- if (en)
- return;
-
- /* Write back the default values. */
- rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_0);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_1);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_2);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_3);
- rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_4);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_5);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_6);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_7);
- rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_8);
-
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_R);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_G);
- rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_B);
-}
-
-/* ISP White Balance Mode */
-static void rkisp1_awb_meas_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_awb_meas_config *arg)
-{
- u32 reg_val = 0;
- /* based on the mode,configure the awb module */
- if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) {
- /* Reference Cb and Cr */
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) |
- arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF);
- /* Yc Threshold */
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) |
- RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) |
- RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) |
- arg->min_c, RKISP1_CIF_ISP_AWB_THRESH);
- }
-
- reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
- if (arg->enable_ymax_cmp)
- reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
- else
- reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN;
- rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
-
- /* window offset */
- rkisp1_write(params->rkisp1,
- arg->awb_wnd.v_offs, RKISP1_CIF_ISP_AWB_WND_V_OFFS);
- rkisp1_write(params->rkisp1,
- arg->awb_wnd.h_offs, RKISP1_CIF_ISP_AWB_WND_H_OFFS);
- /* AWB window size */
- rkisp1_write(params->rkisp1,
- arg->awb_wnd.v_size, RKISP1_CIF_ISP_AWB_WND_V_SIZE);
- rkisp1_write(params->rkisp1,
- arg->awb_wnd.h_size, RKISP1_CIF_ISP_AWB_WND_H_SIZE);
- /* Number of frames */
- rkisp1_write(params->rkisp1,
- arg->frames, RKISP1_CIF_ISP_AWB_FRAMES);
-}
-
-static void
-rkisp1_awb_meas_enable(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_awb_meas_config *arg,
- bool en)
-{
- u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP);
-
- /* switch off */
- reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE;
-
- if (en) {
- if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB)
- reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN;
- else
- reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN;
-
- rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP);
-
- /* Measurements require AWB block be active. */
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
- } else {
- rkisp1_write(params->rkisp1,
- reg_val, RKISP1_CIF_ISP_AWB_PROP);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
- }
-}
-
-static void
-rkisp1_awb_gain_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_awb_gain_config *arg)
-{
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) |
- arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G);
-
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) |
- arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB);
-}
-
-static void rkisp1_aec_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_aec_config *arg)
-{
- unsigned int block_hsize, block_vsize;
- u32 exp_ctrl;
-
- /* avoid to override the old enable value */
- exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
- exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA;
- if (arg->autostop)
- exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP;
- if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1)
- exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1;
- rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL);
-
- rkisp1_write(params->rkisp1,
- arg->meas_window.h_offs, RKISP1_CIF_ISP_EXP_H_OFFSET);
- rkisp1_write(params->rkisp1,
- arg->meas_window.v_offs, RKISP1_CIF_ISP_EXP_V_OFFSET);
-
- block_hsize = arg->meas_window.h_size /
- RKISP1_CIF_ISP_EXP_COLUMN_NUM - 1;
- block_vsize = arg->meas_window.v_size /
- RKISP1_CIF_ISP_EXP_ROW_NUM - 1;
-
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_EXP_H_SIZE_SET(block_hsize),
- RKISP1_CIF_ISP_EXP_H_SIZE);
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_EXP_V_SIZE_SET(block_vsize),
- RKISP1_CIF_ISP_EXP_V_SIZE);
-}
-
-static void rkisp1_cproc_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_cproc_config *arg)
-{
- struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg =
- container_of(arg, struct rkisp1_cif_isp_isp_other_cfg, cproc_config);
- struct rkisp1_cif_isp_ie_config *cur_ie_config =
- &cur_other_cfg->ie_config;
- u32 effect = cur_ie_config->effect;
- u32 quantization = params->quantization;
-
- rkisp1_write(params->rkisp1, arg->contrast, RKISP1_CIF_C_PROC_CONTRAST);
- rkisp1_write(params->rkisp1, arg->hue, RKISP1_CIF_C_PROC_HUE);
- rkisp1_write(params->rkisp1, arg->sat, RKISP1_CIF_C_PROC_SATURATION);
- rkisp1_write(params->rkisp1, arg->brightness,
- RKISP1_CIF_C_PROC_BRIGHTNESS);
-
- if (quantization != V4L2_QUANTIZATION_FULL_RANGE ||
- effect != V4L2_COLORFX_NONE) {
- rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
- RKISP1_CIF_C_PROC_YOUT_FULL |
- RKISP1_CIF_C_PROC_YIN_FULL |
- RKISP1_CIF_C_PROC_COUT_FULL);
- } else {
- rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL,
- RKISP1_CIF_C_PROC_YOUT_FULL |
- RKISP1_CIF_C_PROC_YIN_FULL |
- RKISP1_CIF_C_PROC_COUT_FULL);
- }
-}
-
-static void rkisp1_hst_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_hst_config *arg)
-{
- unsigned int block_hsize, block_vsize;
- static const u32 hist_weight_regs[] = {
- RKISP1_CIF_ISP_HIST_WEIGHT_00TO30,
- RKISP1_CIF_ISP_HIST_WEIGHT_40TO21,
- RKISP1_CIF_ISP_HIST_WEIGHT_31TO12,
- RKISP1_CIF_ISP_HIST_WEIGHT_22TO03,
- RKISP1_CIF_ISP_HIST_WEIGHT_13TO43,
- RKISP1_CIF_ISP_HIST_WEIGHT_04TO34,
- RKISP1_CIF_ISP_HIST_WEIGHT_44,
- };
- const u8 *weight;
- unsigned int i;
- u32 hist_prop;
-
- /* avoid to override the old enable value */
- hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP);
- hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
- hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET(arg->histogram_predivider);
- rkisp1_write(params->rkisp1, hist_prop, RKISP1_CIF_ISP_HIST_PROP);
- rkisp1_write(params->rkisp1,
- arg->meas_window.h_offs,
- RKISP1_CIF_ISP_HIST_H_OFFS);
- rkisp1_write(params->rkisp1,
- arg->meas_window.v_offs,
- RKISP1_CIF_ISP_HIST_V_OFFS);
-
- block_hsize = arg->meas_window.h_size /
- RKISP1_CIF_ISP_HIST_COLUMN_NUM - 1;
- block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM - 1;
-
- rkisp1_write(params->rkisp1, block_hsize, RKISP1_CIF_ISP_HIST_H_SIZE);
- rkisp1_write(params->rkisp1, block_vsize, RKISP1_CIF_ISP_HIST_V_SIZE);
-
- weight = arg->hist_weight;
- for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4)
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_HIST_WEIGHT_SET(weight[0],
- weight[1],
- weight[2],
- weight[3]),
- hist_weight_regs[i]);
-}
-
-static void
-rkisp1_hst_enable(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_hst_config *arg, bool en)
-{
- if (en) {
- u32 hist_prop = rkisp1_read(params->rkisp1,
- RKISP1_CIF_ISP_HIST_PROP);
-
- hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK;
- hist_prop |= arg->mode;
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
- hist_prop);
- } else {
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP,
- RKISP1_CIF_ISP_HIST_PROP_MODE_MASK);
- }
-}
-
-static void rkisp1_afm_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_afc_config *arg)
-{
- size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win),
- arg->num_afm_win);
- u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL);
- unsigned int i;
-
- /* Switch off to configure. */
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
- RKISP1_CIF_ISP_AFM_ENA);
-
- for (i = 0; i < num_of_win; i++) {
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) |
- RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs),
- RKISP1_CIF_ISP_AFM_LT_A + i * 8);
- rkisp1_write(params->rkisp1,
- RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size +
- arg->afm_win[i].h_offs) |
- RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size +
- arg->afm_win[i].v_offs),
- RKISP1_CIF_ISP_AFM_RB_A + i * 8);
- }
- rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES);
- rkisp1_write(params->rkisp1, arg->var_shift,
- RKISP1_CIF_ISP_AFM_VAR_SHIFT);
- /* restore afm status */
- rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL);
-}
-
-static void rkisp1_ie_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_ie_config *arg)
-{
- u32 eff_ctrl;
-
- eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL);
- eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK;
-
- if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL;
-
- switch (arg->effect) {
- case V4L2_COLORFX_SEPIA:
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
- break;
- case V4L2_COLORFX_SET_CBCR:
- rkisp1_write(params->rkisp1, arg->eff_tint,
- RKISP1_CIF_IMG_EFF_TINT);
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA;
- break;
- /*
- * Color selection is similar to water color(AQUA):
- * grayscale + selected color w threshold
- */
- case V4L2_COLORFX_AQUA:
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL;
- rkisp1_write(params->rkisp1, arg->color_sel,
- RKISP1_CIF_IMG_EFF_COLOR_SEL);
- break;
- case V4L2_COLORFX_EMBOSS:
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS;
- rkisp1_write(params->rkisp1, arg->eff_mat_1,
- RKISP1_CIF_IMG_EFF_MAT_1);
- rkisp1_write(params->rkisp1, arg->eff_mat_2,
- RKISP1_CIF_IMG_EFF_MAT_2);
- rkisp1_write(params->rkisp1, arg->eff_mat_3,
- RKISP1_CIF_IMG_EFF_MAT_3);
- break;
- case V4L2_COLORFX_SKETCH:
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH;
- rkisp1_write(params->rkisp1, arg->eff_mat_3,
- RKISP1_CIF_IMG_EFF_MAT_3);
- rkisp1_write(params->rkisp1, arg->eff_mat_4,
- RKISP1_CIF_IMG_EFF_MAT_4);
- rkisp1_write(params->rkisp1, arg->eff_mat_5,
- RKISP1_CIF_IMG_EFF_MAT_5);
- break;
- case V4L2_COLORFX_BW:
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE;
- break;
- case V4L2_COLORFX_NEGATIVE:
- eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE;
- break;
- default:
- break;
- }
-
- rkisp1_write(params->rkisp1, eff_ctrl, RKISP1_CIF_IMG_EFF_CTRL);
-}
-
-static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
-{
- if (en) {
- rkisp1_param_set_bits(params, RKISP1_CIF_ICCL,
- RKISP1_CIF_ICCL_IE_CLK);
- rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL_ENABLE,
- RKISP1_CIF_IMG_EFF_CTRL);
- rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
- RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD);
- } else {
- rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL,
- RKISP1_CIF_IMG_EFF_CTRL_ENABLE);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ICCL,
- RKISP1_CIF_ICCL_IE_CLK);
- }
-}
-
-static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
-{
- static const u16 full_range_coeff[] = {
- 0x0026, 0x004b, 0x000f,
- 0x01ea, 0x01d6, 0x0040,
- 0x0040, 0x01ca, 0x01f6
- };
- static const u16 limited_range_coeff[] = {
- 0x0021, 0x0040, 0x000d,
- 0x01ed, 0x01db, 0x0038,
- 0x0038, 0x01d1, 0x01f7,
- };
- unsigned int i;
-
- if (full_range) {
- for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++)
- rkisp1_write(params->rkisp1, full_range_coeff[i],
- RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
-
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
- RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
- } else {
- for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++)
- rkisp1_write(params->rkisp1, limited_range_coeff[i],
- RKISP1_CIF_ISP_CC_COEFF_0 + i * 4);
-
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA |
- RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA);
- }
-}
-
-/* ISP De-noise Pre-Filter(DPF) function */
-static void rkisp1_dpf_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_dpf_config *arg)
-{
- unsigned int isp_dpf_mode, spatial_coeff, i;
-
- switch (arg->gain.mode) {
- case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS:
- isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
- RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
- break;
- case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS:
- isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
- break;
- case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS:
- isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN |
- RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP |
- RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP;
- break;
- case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS:
- isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
- break;
- case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS:
- isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP |
- RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP;
- break;
- case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED:
- default:
- isp_dpf_mode = 0;
- break;
- }
-
- if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)
- isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION;
- if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9)
- isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9;
- if (!arg->rb_flt.r_enable)
- isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS;
- if (!arg->rb_flt.b_enable)
- isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS;
- if (!arg->g_flt.gb_enable)
- isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS;
- if (!arg->g_flt.gr_enable)
- isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS;
-
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE,
- isp_dpf_mode);
- rkisp1_write(params->rkisp1, arg->gain.nf_b_gain,
- RKISP1_CIF_ISP_DPF_NF_GAIN_B);
- rkisp1_write(params->rkisp1, arg->gain.nf_r_gain,
- RKISP1_CIF_ISP_DPF_NF_GAIN_R);
- rkisp1_write(params->rkisp1, arg->gain.nf_gb_gain,
- RKISP1_CIF_ISP_DPF_NF_GAIN_GB);
- rkisp1_write(params->rkisp1, arg->gain.nf_gr_gain,
- RKISP1_CIF_ISP_DPF_NF_GAIN_GR);
-
- for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) {
- rkisp1_write(params->rkisp1, arg->nll.coeff[i],
- RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4);
- }
-
- spatial_coeff = arg->g_flt.spatial_coeff[0] |
- (arg->g_flt.spatial_coeff[1] << 8) |
- (arg->g_flt.spatial_coeff[2] << 16) |
- (arg->g_flt.spatial_coeff[3] << 24);
- rkisp1_write(params->rkisp1, spatial_coeff,
- RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4);
-
- spatial_coeff = arg->g_flt.spatial_coeff[4] |
- (arg->g_flt.spatial_coeff[5] << 8);
- rkisp1_write(params->rkisp1, spatial_coeff,
- RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6);
-
- spatial_coeff = arg->rb_flt.spatial_coeff[0] |
- (arg->rb_flt.spatial_coeff[1] << 8) |
- (arg->rb_flt.spatial_coeff[2] << 16) |
- (arg->rb_flt.spatial_coeff[3] << 24);
- rkisp1_write(params->rkisp1, spatial_coeff,
- RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4);
-
- spatial_coeff = arg->rb_flt.spatial_coeff[4] |
- (arg->rb_flt.spatial_coeff[5] << 8);
- rkisp1_write(params->rkisp1, spatial_coeff,
- RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6);
-}
-
-static void
-rkisp1_dpf_strength_config(struct rkisp1_params *params,
- const struct rkisp1_cif_isp_dpf_strength_config *arg)
-{
- rkisp1_write(params->rkisp1, arg->b, RKISP1_CIF_ISP_DPF_STRENGTH_B);
- rkisp1_write(params->rkisp1, arg->g, RKISP1_CIF_ISP_DPF_STRENGTH_G);
- rkisp1_write(params->rkisp1, arg->r, RKISP1_CIF_ISP_DPF_STRENGTH_R);
-}
-
-static void
-rkisp1_isp_isr_other_config(struct rkisp1_params *params,
- const struct rkisp1_params_cfg *new_params)
-{
- unsigned int module_en_update, module_cfg_update, module_ens;
-
- module_en_update = new_params->module_en_update;
- module_cfg_update = new_params->module_cfg_update;
- module_ens = new_params->module_ens;
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)) {
- /*update dpc config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)
- rkisp1_dpcc_config(params,
- &new_params->others.dpcc_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_DPCC_MODE,
- RKISP1_CIF_ISP_DPCC_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_DPCC_MODE,
- RKISP1_CIF_ISP_DPCC_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_BLS) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)) {
- /* update bls config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)
- rkisp1_bls_config(params,
- &new_params->others.bls_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_BLS)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_BLS_CTRL,
- RKISP1_CIF_ISP_BLS_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_BLS_CTRL,
- RKISP1_CIF_ISP_BLS_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_SDG) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)) {
- /* update sdg config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)
- rkisp1_sdg_config(params,
- &new_params->others.sdg_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_SDG)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_LSC) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)) {
- /* update lsc config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)
- rkisp1_lsc_config(params,
- &new_params->others.lsc_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_LSC)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_LSC_CTRL,
- RKISP1_CIF_ISP_LSC_CTRL_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_LSC_CTRL,
- RKISP1_CIF_ISP_LSC_CTRL_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)) {
- /* update awb gains */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
- rkisp1_awb_gain_config(params,
- &new_params->others.awb_gain_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_BDM) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)) {
- /* update bdm config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)
- rkisp1_bdm_config(params,
- &new_params->others.bdm_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_BDM)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_DEMOSAIC,
- RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_DEMOSAIC,
- RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_FLT) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)) {
- /* update filter config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)
- rkisp1_flt_config(params,
- &new_params->others.flt_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_FLT)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_FILT_MODE,
- RKISP1_CIF_ISP_FLT_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_FILT_MODE,
- RKISP1_CIF_ISP_FLT_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_CTK) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)) {
- /* update ctk config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)
- rkisp1_ctk_config(params,
- &new_params->others.ctk_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK)
- rkisp1_ctk_enable(params,
- !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK));
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_GOC) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)) {
- /* update goc config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)
- rkisp1_goc_config(params,
- &new_params->others.goc_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_GOC)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)) {
- /* update cproc config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC) {
- rkisp1_cproc_config(params,
- &new_params->others.cproc_config);
- }
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_CPROC)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_C_PROC_CTRL,
- RKISP1_CIF_C_PROC_CTR_ENABLE);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_C_PROC_CTRL,
- RKISP1_CIF_C_PROC_CTR_ENABLE);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_IE) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)) {
- /* update ie config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)
- rkisp1_ie_config(params,
- &new_params->others.ie_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_IE)
- rkisp1_ie_enable(params,
- !!(module_ens & RKISP1_CIF_ISP_MODULE_IE));
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)) {
- /* update dpf config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)
- rkisp1_dpf_config(params,
- &new_params->others.dpf_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_DPF)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_DPF_MODE,
- RKISP1_CIF_ISP_DPF_MODE_EN);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_DPF_MODE,
- RKISP1_CIF_ISP_DPF_MODE_EN);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) {
- /* update dpf strength config */
- rkisp1_dpf_strength_config(params,
- &new_params->others.dpf_strength_config);
- }
-}
-
-static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params,
- struct rkisp1_params_cfg *new_params)
-{
- unsigned int module_en_update, module_cfg_update, module_ens;
-
- module_en_update = new_params->module_en_update;
- module_cfg_update = new_params->module_cfg_update;
- module_ens = new_params->module_ens;
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)) {
- /* update awb config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)
- rkisp1_awb_meas_config(params,
- &new_params->meas.awb_meas_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB)
- rkisp1_awb_meas_enable(params,
- &new_params->meas.awb_meas_config,
- !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB));
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_AFC) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)) {
- /* update afc config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)
- rkisp1_afm_config(params,
- &new_params->meas.afc_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_AFC)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_AFM_CTRL,
- RKISP1_CIF_ISP_AFM_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_AFM_CTRL,
- RKISP1_CIF_ISP_AFM_ENA);
- }
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_HST) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)) {
- /* update hst config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)
- rkisp1_hst_config(params,
- &new_params->meas.hst_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_HST)
- rkisp1_hst_enable(params,
- &new_params->meas.hst_config,
- !!(module_ens & RKISP1_CIF_ISP_MODULE_HST));
- }
-
- if ((module_en_update & RKISP1_CIF_ISP_MODULE_AEC) ||
- (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)) {
- /* update aec config */
- if (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)
- rkisp1_aec_config(params,
- &new_params->meas.aec_config);
-
- if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) {
- if (module_ens & RKISP1_CIF_ISP_MODULE_AEC)
- rkisp1_param_set_bits(params,
- RKISP1_CIF_ISP_EXP_CTRL,
- RKISP1_CIF_ISP_EXP_ENA);
- else
- rkisp1_param_clear_bits(params,
- RKISP1_CIF_ISP_EXP_CTRL,
- RKISP1_CIF_ISP_EXP_ENA);
- }
- }
-}
-
-static void rkisp1_params_apply_params_cfg(struct rkisp1_params *params,
- unsigned int frame_sequence)
-{
- struct rkisp1_params_cfg *new_params;
- struct rkisp1_buffer *cur_buf = NULL;
-
- if (list_empty(¶ms->params))
- return;
-
- cur_buf = list_first_entry(¶ms->params,
- struct rkisp1_buffer, queue);
-
- new_params = (struct rkisp1_params_cfg *)(cur_buf->vaddr);
-
- rkisp1_isp_isr_other_config(params, new_params);
- rkisp1_isp_isr_meas_config(params, new_params);
-
- /* update shadow register immediately */
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD);
-
- list_del(&cur_buf->queue);
-
- cur_buf->vb.sequence = frame_sequence;
- vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-}
-
-void rkisp1_params_isr(struct rkisp1_device *rkisp1)
-{
- /*
- * This isr is called when the ISR finishes processing a frame (RKISP1_CIF_ISP_FRAME).
- * Configurations performed here will be applied on the next frame.
- * Since frame_sequence is updated on the vertical sync signal, we should use
- * frame_sequence + 1 here to indicate to userspace on which frame these parameters
- * are being applied.
- */
- unsigned int frame_sequence = rkisp1->isp.frame_sequence + 1;
- struct rkisp1_params *params = &rkisp1->params;
-
- spin_lock(¶ms->config_lock);
- rkisp1_params_apply_params_cfg(params, frame_sequence);
-
- spin_unlock(¶ms->config_lock);
-}
-
-static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = {
- {
- 0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT
- },
- RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128
-};
-
-static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = {
- RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
- RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0,
- {
- RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
- RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
- }
-};
-
-static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = {
- RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
- 3,
- {
- RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2,
- RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1
- },
- {
- 0, /* To be filled in with 0x01 at runtime. */
- }
-};
-
-static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = {
- 1,
- {
- {
- 300, 225, 200, 150
- }
- },
- 4,
- 14
-};
-
-static void rkisp1_params_config_parameter(struct rkisp1_params *params)
-{
- struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config;
-
- rkisp1_awb_meas_config(params, &rkisp1_awb_params_default_config);
- rkisp1_awb_meas_enable(params, &rkisp1_awb_params_default_config,
- true);
-
- rkisp1_aec_config(params, &rkisp1_aec_params_default_config);
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
- RKISP1_CIF_ISP_EXP_ENA);
-
- rkisp1_afm_config(params, &rkisp1_afc_params_default_config);
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
- RKISP1_CIF_ISP_AFM_ENA);
-
- memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight));
- rkisp1_hst_config(params, &hst);
- rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP,
- ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK |
- rkisp1_hst_params_default_config.mode);
-
- /* set the range */
- if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
- rkisp1_csm_config(params, true);
- else
- rkisp1_csm_config(params, false);
-
- spin_lock_irq(¶ms->config_lock);
-
- /* apply the first buffer if there is one already */
- rkisp1_params_apply_params_cfg(params, 0);
-
- spin_unlock_irq(¶ms->config_lock);
-}
-
-void rkisp1_params_configure(struct rkisp1_params *params,
- enum rkisp1_fmt_raw_pat_type bayer_pat,
- enum v4l2_quantization quantization)
-{
- params->quantization = quantization;
- params->raw_type = bayer_pat;
- rkisp1_params_config_parameter(params);
-}
-
-/* Not called when the camera active, thus not isr protection. */
-void rkisp1_params_disable(struct rkisp1_params *params)
-{
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE,
- RKISP1_CIF_ISP_DPCC_ENA);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL,
- RKISP1_CIF_ISP_LSC_CTRL_ENA);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,
- RKISP1_CIF_ISP_BLS_ENA);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC,
- RKISP1_CIF_ISP_DEMOSAIC_BYPASS);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE,
- RKISP1_CIF_ISP_FLT_ENA);
- rkisp1_awb_meas_enable(params, NULL, false);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL,
- RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL,
- RKISP1_CIF_ISP_EXP_ENA);
- rkisp1_ctk_enable(params, false);
- rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL,
- RKISP1_CIF_C_PROC_CTR_ENABLE);
- rkisp1_hst_enable(params, NULL, false);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL,
- RKISP1_CIF_ISP_AFM_ENA);
- rkisp1_ie_enable(params, false);
- rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE,
- RKISP1_CIF_ISP_DPF_MODE_EN);
-}
-
-static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct video_device *video = video_devdata(file);
- struct rkisp1_params *params = video_get_drvdata(video);
-
- if (f->index > 0 || f->type != video->queue->type)
- return -EINVAL;
-
- f->pixelformat = params->vdev_fmt.fmt.meta.dataformat;
-
- return 0;
-}
-
-static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct video_device *video = video_devdata(file);
- struct rkisp1_params *params = video_get_drvdata(video);
- struct v4l2_meta_format *meta = &f->fmt.meta;
-
- if (f->type != video->queue->type)
- return -EINVAL;
-
- memset(meta, 0, sizeof(*meta));
- meta->dataformat = params->vdev_fmt.fmt.meta.dataformat;
- meta->buffersize = params->vdev_fmt.fmt.meta.buffersize;
-
- return 0;
-}
-
-static int rkisp1_params_querycap(struct file *file,
- void *priv, struct v4l2_capability *cap)
-{
- struct video_device *vdev = video_devdata(file);
-
- strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
- strscpy(cap->card, vdev->name, sizeof(cap->card));
- strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
-
- return 0;
-}
-
-/* ISP params video device IOCTLs */
-static const struct v4l2_ioctl_ops rkisp1_params_ioctl = {
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_expbuf = vb2_ioctl_expbuf,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out,
- .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
- .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
- .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out,
- .vidioc_querycap = rkisp1_params_querycap,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq,
- unsigned int *num_buffers,
- unsigned int *num_planes,
- unsigned int sizes[],
- struct device *alloc_devs[])
-{
- *num_buffers = clamp_t(u32, *num_buffers,
- RKISP1_ISP_PARAMS_REQ_BUFS_MIN,
- RKISP1_ISP_PARAMS_REQ_BUFS_MAX);
-
- *num_planes = 1;
-
- sizes[0] = sizeof(struct rkisp1_params_cfg);
-
- return 0;
-}
-
-static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct rkisp1_buffer *params_buf =
- container_of(vbuf, struct rkisp1_buffer, vb);
- struct vb2_queue *vq = vb->vb2_queue;
- struct rkisp1_params *params = vq->drv_priv;
-
- params_buf->vaddr = vb2_plane_vaddr(vb, 0);
- spin_lock_irq(¶ms->config_lock);
- list_add_tail(¶ms_buf->queue, ¶ms->params);
- spin_unlock_irq(¶ms->config_lock);
-}
-
-static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
-{
- if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg))
- return -EINVAL;
-
- vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg));
-
- return 0;
-}
-
-static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq)
-{
- struct rkisp1_params *params = vq->drv_priv;
- struct rkisp1_buffer *buf;
- LIST_HEAD(tmp_list);
-
- /*
- * we first move the buffers into a local list 'tmp_list'
- * and then we can iterate it and call vb2_buffer_done
- * without holding the lock
- */
- spin_lock_irq(¶ms->config_lock);
- list_splice_init(¶ms->params, &tmp_list);
- spin_unlock_irq(¶ms->config_lock);
-
- list_for_each_entry(buf, &tmp_list, queue)
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-}
-
-static struct vb2_ops rkisp1_params_vb2_ops = {
- .queue_setup = rkisp1_params_vb2_queue_setup,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .buf_queue = rkisp1_params_vb2_buf_queue,
- .buf_prepare = rkisp1_params_vb2_buf_prepare,
- .stop_streaming = rkisp1_params_vb2_stop_streaming,
-
-};
-
-static struct v4l2_file_operations rkisp1_params_fops = {
- .mmap = vb2_fop_mmap,
- .unlocked_ioctl = video_ioctl2,
- .poll = vb2_fop_poll,
- .open = v4l2_fh_open,
- .release = vb2_fop_release
-};
-
-static int rkisp1_params_init_vb2_queue(struct vb2_queue *q,
- struct rkisp1_params *params)
-{
- struct rkisp1_vdev_node *node;
-
- node = container_of(q, struct rkisp1_vdev_node, buf_queue);
-
- q->type = V4L2_BUF_TYPE_META_OUTPUT;
- q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
- q->drv_priv = params;
- q->ops = &rkisp1_params_vb2_ops;
- q->mem_ops = &vb2_vmalloc_memops;
- q->buf_struct_size = sizeof(struct rkisp1_buffer);
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &node->vlock;
-
- return vb2_queue_init(q);
-}
-
-static void rkisp1_init_params(struct rkisp1_params *params)
-{
- params->vdev_fmt.fmt.meta.dataformat =
- V4L2_META_FMT_RK_ISP1_PARAMS;
- params->vdev_fmt.fmt.meta.buffersize =
- sizeof(struct rkisp1_params_cfg);
-}
-
-int rkisp1_params_register(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_params *params = &rkisp1->params;
- struct rkisp1_vdev_node *node = ¶ms->vnode;
- struct video_device *vdev = &node->vdev;
- int ret;
-
- params->rkisp1 = rkisp1;
- mutex_init(&node->vlock);
- INIT_LIST_HEAD(¶ms->params);
- spin_lock_init(¶ms->config_lock);
-
- strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name));
-
- video_set_drvdata(vdev, params);
- vdev->ioctl_ops = &rkisp1_params_ioctl;
- vdev->fops = &rkisp1_params_fops;
- vdev->release = video_device_release_empty;
- /*
- * Provide a mutex to v4l2 core. It will be used
- * to protect all fops and v4l2 ioctls.
- */
- vdev->lock = &node->vlock;
- vdev->v4l2_dev = &rkisp1->v4l2_dev;
- vdev->queue = &node->buf_queue;
- vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
- vdev->vfl_dir = VFL_DIR_TX;
- rkisp1_params_init_vb2_queue(vdev->queue, params);
- rkisp1_init_params(params);
- video_set_drvdata(vdev, params);
-
- node->pad.flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
- if (ret)
- return ret;
- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
- if (ret) {
- dev_err(rkisp1->dev,
- "failed to register %s, ret=%d\n", vdev->name, ret);
- goto err_cleanup_media_entity;
- }
- return 0;
-err_cleanup_media_entity:
- media_entity_cleanup(&vdev->entity);
- return ret;
-}
-
-void rkisp1_params_unregister(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_params *params = &rkisp1->params;
- struct rkisp1_vdev_node *node = ¶ms->vnode;
- struct video_device *vdev = &node->vdev;
-
- vb2_video_unregister_device(vdev);
- media_entity_cleanup(&vdev->entity);
-}
+++ /dev/null
-/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
-/*
- * Rockchip ISP1 Driver - Registers header
- *
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _RKISP1_REGS_H
-#define _RKISP1_REGS_H
-
-/* ISP_CTRL */
-#define RKISP1_CIF_ISP_CTRL_ISP_ENABLE BIT(0)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT (0 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU656 BIT(1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_ITU601 (2 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601 (3 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_DATA_MODE (4 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656 (5 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656 (6 << 1)
-#define RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE BIT(4)
-#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA BIT(6)
-#define RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA BIT(7)
-#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT BIT(8)
-#define RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD BIT(9)
-#define RKISP1_CIF_ISP_CTRL_ISP_GEN_CFG_UPD BIT(10)
-#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA BIT(11)
-#define RKISP1_CIF_ISP_CTRL_ISP_FLASH_MODE_ENA BIT(12)
-#define RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA BIT(13)
-#define RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA BIT(14)
-
-/* ISP_ACQ_PROP */
-#define RKISP1_CIF_ISP_ACQ_PROP_POS_EDGE BIT(0)
-#define RKISP1_CIF_ISP_ACQ_PROP_HSYNC_LOW BIT(1)
-#define RKISP1_CIF_ISP_ACQ_PROP_VSYNC_LOW BIT(2)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_RGGB (0 << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GRBG BIT(3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_GBRG (2 << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT_BGGR (3 << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_BAYER_PAT(pat) ((pat) << 3)
-#define RKISP1_CIF_ISP_ACQ_PROP_YCBYCR (0 << 7)
-#define RKISP1_CIF_ISP_ACQ_PROP_YCRYCB BIT(7)
-#define RKISP1_CIF_ISP_ACQ_PROP_CBYCRY (2 << 7)
-#define RKISP1_CIF_ISP_ACQ_PROP_CRYCBY (3 << 7)
-#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ALL (0 << 9)
-#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_EVEN BIT(9)
-#define RKISP1_CIF_ISP_ACQ_PROP_FIELD_SEL_ODD (2 << 9)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_12B (0 << 12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO BIT(12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_10B_MSB (2 << 12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO (3 << 12)
-#define RKISP1_CIF_ISP_ACQ_PROP_IN_SEL_8B_MSB (4 << 12)
-
-/* VI_DPCL */
-#define RKISP1_CIF_VI_DPCL_DMA_JPEG (0 << 0)
-#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_MI BIT(0)
-#define RKISP1_CIF_VI_DPCL_MP_MUX_MRSZ_JPEG (2 << 0)
-#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MP BIT(2)
-#define RKISP1_CIF_VI_DPCL_CHAN_MODE_SP (2 << 2)
-#define RKISP1_CIF_VI_DPCL_CHAN_MODE_MPSP (3 << 2)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_SPMUX (0 << 4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_SI BIT(4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_IE (2 << 4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_JPEG (3 << 4)
-#define RKISP1_CIF_VI_DPCL_DMA_SW_ISP (4 << 4)
-#define RKISP1_CIF_VI_DPCL_IF_SEL_PARALLEL (0 << 8)
-#define RKISP1_CIF_VI_DPCL_IF_SEL_SMIA BIT(8)
-#define RKISP1_CIF_VI_DPCL_IF_SEL_MIPI (2 << 8)
-#define RKISP1_CIF_VI_DPCL_DMA_IE_MUX_DMA BIT(10)
-#define RKISP1_CIF_VI_DPCL_DMA_SP_MUX_DMA BIT(11)
-
-/* ISP_IMSC - ISP_MIS - ISP_RIS - ISP_ICR - ISP_ISR */
-#define RKISP1_CIF_ISP_OFF BIT(0)
-#define RKISP1_CIF_ISP_FRAME BIT(1)
-#define RKISP1_CIF_ISP_DATA_LOSS BIT(2)
-#define RKISP1_CIF_ISP_PIC_SIZE_ERROR BIT(3)
-#define RKISP1_CIF_ISP_AWB_DONE BIT(4)
-#define RKISP1_CIF_ISP_FRAME_IN BIT(5)
-#define RKISP1_CIF_ISP_V_START BIT(6)
-#define RKISP1_CIF_ISP_H_START BIT(7)
-#define RKISP1_CIF_ISP_FLASH_ON BIT(8)
-#define RKISP1_CIF_ISP_FLASH_OFF BIT(9)
-#define RKISP1_CIF_ISP_SHUTTER_ON BIT(10)
-#define RKISP1_CIF_ISP_SHUTTER_OFF BIT(11)
-#define RKISP1_CIF_ISP_AFM_SUM_OF BIT(12)
-#define RKISP1_CIF_ISP_AFM_LUM_OF BIT(13)
-#define RKISP1_CIF_ISP_AFM_FIN BIT(14)
-#define RKISP1_CIF_ISP_HIST_MEASURE_RDY BIT(15)
-#define RKISP1_CIF_ISP_FLASH_CAP BIT(17)
-#define RKISP1_CIF_ISP_EXP_END BIT(18)
-#define RKISP1_CIF_ISP_VSM_END BIT(19)
-
-/* ISP_ERR */
-#define RKISP1_CIF_ISP_ERR_INFORM_SIZE BIT(0)
-#define RKISP1_CIF_ISP_ERR_IS_SIZE BIT(1)
-#define RKISP1_CIF_ISP_ERR_OUTFORM_SIZE BIT(2)
-
-/* MI_CTRL */
-#define RKISP1_CIF_MI_CTRL_MP_ENABLE BIT(0)
-#define RKISP1_CIF_MI_CTRL_SP_ENABLE (2 << 0)
-#define RKISP1_CIF_MI_CTRL_JPEG_ENABLE (4 << 0)
-#define RKISP1_CIF_MI_CTRL_RAW_ENABLE (8 << 0)
-#define RKISP1_CIF_MI_CTRL_HFLIP BIT(4)
-#define RKISP1_CIF_MI_CTRL_VFLIP BIT(5)
-#define RKISP1_CIF_MI_CTRL_ROT BIT(6)
-#define RKISP1_CIF_MI_BYTE_SWAP BIT(7)
-#define RKISP1_CIF_MI_SP_Y_FULL_YUV2RGB BIT(8)
-#define RKISP1_CIF_MI_SP_CBCR_FULL_YUV2RGB BIT(9)
-#define RKISP1_CIF_MI_SP_422NONCOSITEED BIT(10)
-#define RKISP1_CIF_MI_MP_PINGPONG_ENABEL BIT(11)
-#define RKISP1_CIF_MI_SP_PINGPONG_ENABEL BIT(12)
-#define RKISP1_CIF_MI_MP_AUTOUPDATE_ENABLE BIT(13)
-#define RKISP1_CIF_MI_SP_AUTOUPDATE_ENABLE BIT(14)
-#define RKISP1_CIF_MI_LAST_PIXEL_SIG_ENABLE BIT(15)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_16 (0 << 16)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_32 BIT(16)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_LUM_64 (2 << 16)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_16 (0 << 18)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_32 BIT(18)
-#define RKISP1_CIF_MI_CTRL_BURST_LEN_CHROM_64 (2 << 18)
-#define RKISP1_CIF_MI_CTRL_INIT_BASE_EN BIT(20)
-#define RKISP1_CIF_MI_CTRL_INIT_OFFSET_EN BIT(21)
-#define RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8 (0 << 22)
-#define RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA BIT(22)
-#define RKISP1_MI_CTRL_MP_WRITE_YUVINT (2 << 22)
-#define RKISP1_MI_CTRL_MP_WRITE_RAW12 (2 << 22)
-#define RKISP1_MI_CTRL_SP_WRITE_PLA (0 << 24)
-#define RKISP1_MI_CTRL_SP_WRITE_SPLA BIT(24)
-#define RKISP1_MI_CTRL_SP_WRITE_INT (2 << 24)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV400 (0 << 26)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV420 BIT(26)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV422 (2 << 26)
-#define RKISP1_MI_CTRL_SP_INPUT_YUV444 (3 << 26)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV400 (0 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV420 BIT(28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV422 (2 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_YUV444 (3 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_RGB565 (4 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_RGB666 (5 << 28)
-#define RKISP1_MI_CTRL_SP_OUTPUT_RGB888 (6 << 28)
-
-#define RKISP1_MI_CTRL_MP_FMT_MASK GENMASK(23, 22)
-#define RKISP1_MI_CTRL_SP_FMT_MASK GENMASK(30, 24)
-
-/* MI_INIT */
-#define RKISP1_CIF_MI_INIT_SKIP BIT(2)
-#define RKISP1_CIF_MI_INIT_SOFT_UPD BIT(4)
-
-/* MI_CTRL_SHD */
-#define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED BIT(0)
-#define RKISP1_CIF_MI_CTRL_SHD_SP_IN_ENABLED BIT(1)
-#define RKISP1_CIF_MI_CTRL_SHD_JPEG_IN_ENABLED BIT(2)
-#define RKISP1_CIF_MI_CTRL_SHD_RAW_IN_ENABLED BIT(3)
-#define RKISP1_CIF_MI_CTRL_SHD_MP_OUT_ENABLED BIT(16)
-#define RKISP1_CIF_MI_CTRL_SHD_SP_OUT_ENABLED BIT(17)
-#define RKISP1_CIF_MI_CTRL_SHD_JPEG_OUT_ENABLED BIT(18)
-#define RKISP1_CIF_MI_CTRL_SHD_RAW_OUT_ENABLED BIT(19)
-
-/* RSZ_CTRL */
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE BIT(0)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE BIT(1)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE BIT(2)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE BIT(3)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP BIT(4)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP BIT(5)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP BIT(6)
-#define RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP BIT(7)
-#define RKISP1_CIF_RSZ_CTRL_CFG_UPD BIT(8)
-#define RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO BIT(9)
-#define RKISP1_CIF_RSZ_SCALER_FACTOR BIT(16)
-
-/* MI_IMSC - MI_MIS - MI_RIS - MI_ICR - MI_ISR */
-#define RKISP1_CIF_MI_FRAME(stream) BIT((stream)->id)
-#define RKISP1_CIF_MI_MBLK_LINE BIT(2)
-#define RKISP1_CIF_MI_FILL_MP_Y BIT(3)
-#define RKISP1_CIF_MI_WRAP_MP_Y BIT(4)
-#define RKISP1_CIF_MI_WRAP_MP_CB BIT(5)
-#define RKISP1_CIF_MI_WRAP_MP_CR BIT(6)
-#define RKISP1_CIF_MI_WRAP_SP_Y BIT(7)
-#define RKISP1_CIF_MI_WRAP_SP_CB BIT(8)
-#define RKISP1_CIF_MI_WRAP_SP_CR BIT(9)
-#define RKISP1_CIF_MI_DMA_READY BIT(11)
-
-/* MI_STATUS */
-#define RKISP1_CIF_MI_STATUS_MP_Y_FIFO_FULL BIT(0)
-#define RKISP1_CIF_MI_STATUS_SP_Y_FIFO_FULL BIT(4)
-
-/* MI_DMA_CTRL */
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_16 (0 << 0)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_32 BIT(0)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_LUM_64 (2 << 0)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_16 (0 << 2)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_32 BIT(2)
-#define RKISP1_CIF_MI_DMA_CTRL_BURST_LEN_CHROM_64 (2 << 2)
-#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PLANAR (0 << 4)
-#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_SPLANAR BIT(4)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV400 (0 << 6)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV420 BIT(6)
-#define RKISP1_CIF_MI_DMA_CTRL_READ_FMT_PACKED (2 << 4)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV422 (2 << 6)
-#define RKISP1_CIF_MI_DMA_CTRL_FMT_YUV444 (3 << 6)
-#define RKISP1_CIF_MI_DMA_CTRL_BYTE_SWAP BIT(8)
-#define RKISP1_CIF_MI_DMA_CTRL_CONTINUOUS_ENA BIT(9)
-#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_NO (0 << 12)
-#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_8BIT BIT(12)
-#define RKISP1_CIF_MI_DMA_CTRL_RGB_BAYER_16BIT (2 << 12)
-/* MI_DMA_START */
-#define RKISP1_CIF_MI_DMA_START_ENABLE BIT(0)
-/* MI_XTD_FORMAT_CTRL */
-#define RKISP1_CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP BIT(0)
-#define RKISP1_CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP BIT(1)
-#define RKISP1_CIF_MI_XTD_FMT_CTRL_DMA_CB_CR_SWAP BIT(2)
-
-/* CCL */
-#define RKISP1_CIF_CCL_CIF_CLK_DIS BIT(2)
-/* ICCL */
-#define RKISP1_CIF_ICCL_ISP_CLK BIT(0)
-#define RKISP1_CIF_ICCL_CP_CLK BIT(1)
-#define RKISP1_CIF_ICCL_RES_2 BIT(2)
-#define RKISP1_CIF_ICCL_MRSZ_CLK BIT(3)
-#define RKISP1_CIF_ICCL_SRSZ_CLK BIT(4)
-#define RKISP1_CIF_ICCL_JPEG_CLK BIT(5)
-#define RKISP1_CIF_ICCL_MI_CLK BIT(6)
-#define RKISP1_CIF_ICCL_RES_7 BIT(7)
-#define RKISP1_CIF_ICCL_IE_CLK BIT(8)
-#define RKISP1_CIF_ICCL_SIMP_CLK BIT(9)
-#define RKISP1_CIF_ICCL_SMIA_CLK BIT(10)
-#define RKISP1_CIF_ICCL_MIPI_CLK BIT(11)
-#define RKISP1_CIF_ICCL_DCROP_CLK BIT(12)
-/* IRCL */
-#define RKISP1_CIF_IRCL_ISP_SW_RST BIT(0)
-#define RKISP1_CIF_IRCL_CP_SW_RST BIT(1)
-#define RKISP1_CIF_IRCL_YCS_SW_RST BIT(2)
-#define RKISP1_CIF_IRCL_MRSZ_SW_RST BIT(3)
-#define RKISP1_CIF_IRCL_SRSZ_SW_RST BIT(4)
-#define RKISP1_CIF_IRCL_JPEG_SW_RST BIT(5)
-#define RKISP1_CIF_IRCL_MI_SW_RST BIT(6)
-#define RKISP1_CIF_IRCL_CIF_SW_RST BIT(7)
-#define RKISP1_CIF_IRCL_IE_SW_RST BIT(8)
-#define RKISP1_CIF_IRCL_SI_SW_RST BIT(9)
-#define RKISP1_CIF_IRCL_MIPI_SW_RST BIT(11)
-
-/* C_PROC_CTR */
-#define RKISP1_CIF_C_PROC_CTR_ENABLE BIT(0)
-#define RKISP1_CIF_C_PROC_YOUT_FULL BIT(1)
-#define RKISP1_CIF_C_PROC_YIN_FULL BIT(2)
-#define RKISP1_CIF_C_PROC_COUT_FULL BIT(3)
-#define RKISP1_CIF_C_PROC_CTRL_RESERVED 0xFFFFFFFE
-#define RKISP1_CIF_C_PROC_CONTRAST_RESERVED 0xFFFFFF00
-#define RKISP1_CIF_C_PROC_BRIGHTNESS_RESERVED 0xFFFFFF00
-#define RKISP1_CIF_C_PROC_HUE_RESERVED 0xFFFFFF00
-#define RKISP1_CIF_C_PROC_SATURATION_RESERVED 0xFFFFFF00
-#define RKISP1_CIF_C_PROC_MACC_RESERVED 0xE000E000
-#define RKISP1_CIF_C_PROC_TONE_RESERVED 0xF000
-/* DUAL_CROP_CTRL */
-#define RKISP1_CIF_DUAL_CROP_MP_MODE_BYPASS (0 << 0)
-#define RKISP1_CIF_DUAL_CROP_MP_MODE_YUV BIT(0)
-#define RKISP1_CIF_DUAL_CROP_MP_MODE_RAW (2 << 0)
-#define RKISP1_CIF_DUAL_CROP_SP_MODE_BYPASS (0 << 2)
-#define RKISP1_CIF_DUAL_CROP_SP_MODE_YUV BIT(2)
-#define RKISP1_CIF_DUAL_CROP_SP_MODE_RAW (2 << 2)
-#define RKISP1_CIF_DUAL_CROP_CFG_UPD_PERMANENT BIT(4)
-#define RKISP1_CIF_DUAL_CROP_CFG_UPD BIT(5)
-#define RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD BIT(6)
-
-/* IMG_EFF_CTRL */
-#define RKISP1_CIF_IMG_EFF_CTRL_ENABLE BIT(0)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE (0 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE BIT(1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA (2 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL (3 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS (4 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH (5 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN (6 << 1)
-#define RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD BIT(4)
-#define RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL BIT(5)
-
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE_SHIFT 0
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE_SHIFT 1
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA_SHIFT 2
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL_SHIFT 3
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS_SHIFT 4
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH_SHIFT 5
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_SHARPEN_SHIFT 6
-#define RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK 0xE
-
-/* IMG_EFF_COLOR_SEL */
-#define RKISP1_CIF_IMG_EFF_COLOR_RGB 0
-#define RKISP1_CIF_IMG_EFF_COLOR_B BIT(0)
-#define RKISP1_CIF_IMG_EFF_COLOR_G (2 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_GB (3 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_R (4 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_RB (5 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_RG (6 << 0)
-#define RKISP1_CIF_IMG_EFF_COLOR_RGB2 (7 << 0)
-
-/* MIPI_CTRL */
-#define RKISP1_CIF_MIPI_CTRL_OUTPUT_ENA BIT(0)
-#define RKISP1_CIF_MIPI_CTRL_SHUTDOWNLANES(a) (((a) & 0xF) << 8)
-#define RKISP1_CIF_MIPI_CTRL_NUM_LANES(a) (((a) & 0x3) << 12)
-#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_HS_SKIP BIT(16)
-#define RKISP1_CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP BIT(17)
-#define RKISP1_CIF_MIPI_CTRL_CLOCKLANE_ENA BIT(18)
-
-/* MIPI_DATA_SEL */
-#define RKISP1_CIF_MIPI_DATA_SEL_VC(a) (((a) & 0x3) << 6)
-#define RKISP1_CIF_MIPI_DATA_SEL_DT(a) (((a) & 0x3F) << 0)
-/* MIPI DATA_TYPE */
-#define RKISP1_CIF_CSI2_DT_YUV420_8b 0x18
-#define RKISP1_CIF_CSI2_DT_YUV420_10b 0x19
-#define RKISP1_CIF_CSI2_DT_YUV422_8b 0x1E
-#define RKISP1_CIF_CSI2_DT_YUV422_10b 0x1F
-#define RKISP1_CIF_CSI2_DT_RGB565 0x22
-#define RKISP1_CIF_CSI2_DT_RGB666 0x23
-#define RKISP1_CIF_CSI2_DT_RGB888 0x24
-#define RKISP1_CIF_CSI2_DT_RAW8 0x2A
-#define RKISP1_CIF_CSI2_DT_RAW10 0x2B
-#define RKISP1_CIF_CSI2_DT_RAW12 0x2C
-
-/* MIPI_IMSC, MIPI_RIS, MIPI_MIS, MIPI_ICR, MIPI_ISR */
-#define RKISP1_CIF_MIPI_SYNC_FIFO_OVFLW(a) (((a) & 0xF) << 0)
-#define RKISP1_CIF_MIPI_ERR_SOT(a) (((a) & 0xF) << 4)
-#define RKISP1_CIF_MIPI_ERR_SOT_SYNC(a) (((a) & 0xF) << 8)
-#define RKISP1_CIF_MIPI_ERR_EOT_SYNC(a) (((a) & 0xF) << 12)
-#define RKISP1_CIF_MIPI_ERR_CTRL(a) (((a) & 0xF) << 16)
-#define RKISP1_CIF_MIPI_ERR_PROTOCOL BIT(20)
-#define RKISP1_CIF_MIPI_ERR_ECC1 BIT(21)
-#define RKISP1_CIF_MIPI_ERR_ECC2 BIT(22)
-#define RKISP1_CIF_MIPI_ERR_CS BIT(23)
-#define RKISP1_CIF_MIPI_FRAME_END BIT(24)
-#define RKISP1_CIF_MIPI_ADD_DATA_OVFLW BIT(25)
-#define RKISP1_CIF_MIPI_ADD_DATA_WATER_MARK BIT(26)
-
-#define RKISP1_CIF_MIPI_ERR_CSI (RKISP1_CIF_MIPI_ERR_PROTOCOL | \
- RKISP1_CIF_MIPI_ERR_ECC1 | \
- RKISP1_CIF_MIPI_ERR_ECC2 | \
- RKISP1_CIF_MIPI_ERR_CS)
-
-#define RKISP1_CIF_MIPI_ERR_DPHY (RKISP1_CIF_MIPI_ERR_SOT(3) | \
- RKISP1_CIF_MIPI_ERR_SOT_SYNC(3) | \
- RKISP1_CIF_MIPI_ERR_EOT_SYNC(3) | \
- RKISP1_CIF_MIPI_ERR_CTRL(3))
-
-/* SUPER_IMPOSE */
-#define RKISP1_CIF_SUPER_IMP_CTRL_NORMAL_MODE BIT(0)
-#define RKISP1_CIF_SUPER_IMP_CTRL_REF_IMG_MEM BIT(1)
-#define RKISP1_CIF_SUPER_IMP_CTRL_TRANSP_DIS BIT(2)
-
-/* ISP HISTOGRAM CALCULATION : ISP_HIST_PROP */
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_DIS (0 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_RGB BIT(0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_RED (2 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_GREEN (3 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_BLUE (4 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_LUM (5 << 0)
-#define RKISP1_CIF_ISP_HIST_PROP_MODE_MASK 0x7
-#define RKISP1_CIF_ISP_HIST_PREDIV_SET(x) (((x) & 0x7F) << 3)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_SET(v0, v1, v2, v3) \
- (((v0) & 0x1F) | (((v1) & 0x1F) << 8) |\
- (((v2) & 0x1F) << 16) | \
- (((v3) & 0x1F) << 24))
-
-#define RKISP1_CIF_ISP_HIST_WINDOW_OFFSET_RESERVED 0xFFFFF000
-#define RKISP1_CIF_ISP_HIST_WINDOW_SIZE_RESERVED 0xFFFFF800
-#define RKISP1_CIF_ISP_HIST_WEIGHT_RESERVED 0xE0E0E0E0
-#define RKISP1_CIF_ISP_MAX_HIST_PREDIVIDER 0x0000007F
-#define RKISP1_CIF_ISP_HIST_ROW_NUM 5
-#define RKISP1_CIF_ISP_HIST_COLUMN_NUM 5
-
-/* AUTO FOCUS MEASUREMENT: ISP_AFM_CTRL */
-#define RKISP1_ISP_AFM_CTRL_ENABLE BIT(0)
-
-/* SHUTTER CONTROL */
-#define RKISP1_CIF_ISP_SH_CTRL_SH_ENA BIT(0)
-#define RKISP1_CIF_ISP_SH_CTRL_REP_EN BIT(1)
-#define RKISP1_CIF_ISP_SH_CTRL_SRC_SH_TRIG BIT(2)
-#define RKISP1_CIF_ISP_SH_CTRL_EDGE_POS BIT(3)
-#define RKISP1_CIF_ISP_SH_CTRL_POL_LOW BIT(4)
-
-/* FLASH MODULE */
-/* ISP_FLASH_CMD */
-#define RKISP1_CIFFLASH_CMD_PRELIGHT_ON BIT(0)
-#define RKISP1_CIFFLASH_CMD_FLASH_ON BIT(1)
-#define RKISP1_CIFFLASH_CMD_PRE_FLASH_ON BIT(2)
-/* ISP_FLASH_CONFIG */
-#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_END BIT(0)
-#define RKISP1_CIFFLASH_CONFIG_VSYNC_POS BIT(1)
-#define RKISP1_CIFFLASH_CONFIG_PRELIGHT_LOW BIT(2)
-#define RKISP1_CIFFLASH_CONFIG_SRC_FL_TRIG BIT(3)
-#define RKISP1_CIFFLASH_CONFIG_DELAY(a) (((a) & 0xF) << 4)
-
-/* Demosaic: ISP_DEMOSAIC */
-#define RKISP1_CIF_ISP_DEMOSAIC_BYPASS BIT(10)
-#define RKISP1_CIF_ISP_DEMOSAIC_TH(x) ((x) & 0xFF)
-
-/* AWB */
-/* ISP_AWB_PROP */
-#define RKISP1_CIF_ISP_AWB_YMAX_CMP_EN BIT(2)
-#define RKISP1_CIF_ISP_AWB_YMAX_READ(x) (((x) >> 2) & 1)
-#define RKISP1_CIF_ISP_AWB_MODE_RGB_EN ((1 << 31) | (0x2 << 0))
-#define RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN ((0 << 31) | (0x2 << 0))
-#define RKISP1_CIF_ISP_AWB_MODE_MASK_NONE 0xFFFFFFFC
-#define RKISP1_CIF_ISP_AWB_MODE_READ(x) ((x) & 3)
-/* ISP_AWB_GAIN_RB, ISP_AWB_GAIN_G */
-#define RKISP1_CIF_ISP_AWB_GAIN_R_SET(x) (((x) & 0x3FF) << 16)
-#define RKISP1_CIF_ISP_AWB_GAIN_R_READ(x) (((x) >> 16) & 0x3FF)
-#define RKISP1_CIF_ISP_AWB_GAIN_B_SET(x) ((x) & 0x3FFF)
-#define RKISP1_CIF_ISP_AWB_GAIN_B_READ(x) ((x) & 0x3FFF)
-/* ISP_AWB_REF */
-#define RKISP1_CIF_ISP_AWB_REF_CR_SET(x) (((x) & 0xFF) << 8)
-#define RKISP1_CIF_ISP_AWB_REF_CR_READ(x) (((x) >> 8) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_REF_CB_READ(x) ((x) & 0xFF)
-/* ISP_AWB_THRESH */
-#define RKISP1_CIF_ISP_AWB_MAX_CS_SET(x) (((x) & 0xFF) << 8)
-#define RKISP1_CIF_ISP_AWB_MAX_CS_READ(x) (((x) >> 8) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_MIN_C_READ(x) ((x) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_MIN_Y_SET(x) (((x) & 0xFF) << 16)
-#define RKISP1_CIF_ISP_AWB_MIN_Y_READ(x) (((x) >> 16) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_MAX_Y_SET(x) (((x) & 0xFF) << 24)
-#define RKISP1_CIF_ISP_AWB_MAX_Y_READ(x) (((x) >> 24) & 0xFF)
-/* ISP_AWB_MEAN */
-#define RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(x) ((x) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(x) (((x) >> 8) & 0xFF)
-#define RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(x) (((x) >> 16) & 0xFF)
-/* ISP_AWB_WHITE_CNT */
-#define RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(x) ((x) & 0x3FFFFFF)
-
-#define RKISP1_CIF_ISP_AWB_GAINS_MAX_VAL 0x000003FF
-#define RKISP1_CIF_ISP_AWB_WINDOW_OFFSET_MAX 0x00000FFF
-#define RKISP1_CIF_ISP_AWB_WINDOW_MAX_SIZE 0x00001FFF
-#define RKISP1_CIF_ISP_AWB_CBCR_MAX_REF 0x000000FF
-#define RKISP1_CIF_ISP_AWB_THRES_MAX_YC 0x000000FF
-
-/* AE */
-/* ISP_EXP_CTRL */
-#define RKISP1_CIF_ISP_EXP_ENA BIT(0)
-#define RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP BIT(1)
-/*
- *'1' luminance calculation according to Y=(R+G+B) x 0.332 (85/256)
- *'0' luminance calculation according to Y=16+0.25R+0.5G+0.1094B
- */
-#define RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1 BIT(31)
-
-/* ISP_EXP_H_SIZE */
-#define RKISP1_CIF_ISP_EXP_H_SIZE_SET(x) ((x) & 0x7FF)
-#define RKISP1_CIF_ISP_EXP_HEIGHT_MASK 0x000007FF
-/* ISP_EXP_V_SIZE : vertical size must be a multiple of 2). */
-#define RKISP1_CIF_ISP_EXP_V_SIZE_SET(x) ((x) & 0x7FE)
-
-/* ISP_EXP_H_OFFSET */
-#define RKISP1_CIF_ISP_EXP_H_OFFSET_SET(x) ((x) & 0x1FFF)
-#define RKISP1_CIF_ISP_EXP_MAX_HOFFS 2424
-/* ISP_EXP_V_OFFSET */
-#define RKISP1_CIF_ISP_EXP_V_OFFSET_SET(x) ((x) & 0x1FFF)
-#define RKISP1_CIF_ISP_EXP_MAX_VOFFS 1806
-
-#define RKISP1_CIF_ISP_EXP_ROW_NUM 5
-#define RKISP1_CIF_ISP_EXP_COLUMN_NUM 5
-#define RKISP1_CIF_ISP_EXP_NUM_LUMA_REGS \
- (RKISP1_CIF_ISP_EXP_ROW_NUM * RKISP1_CIF_ISP_EXP_COLUMN_NUM)
-#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE 516
-#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE 35
-#define RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE 390
-#define RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE 28
-#define RKISP1_CIF_ISP_EXP_MAX_HSIZE \
- (RKISP1_CIF_ISP_EXP_BLOCK_MAX_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
-#define RKISP1_CIF_ISP_EXP_MIN_HSIZE \
- (RKISP1_CIF_ISP_EXP_BLOCK_MIN_HSIZE * RKISP1_CIF_ISP_EXP_COLUMN_NUM + 1)
-#define RKISP1_CIF_ISP_EXP_MAX_VSIZE \
- (RKISP1_CIF_ISP_EXP_BLOCK_MAX_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
-#define RKISP1_CIF_ISP_EXP_MIN_VSIZE \
- (RKISP1_CIF_ISP_EXP_BLOCK_MIN_VSIZE * RKISP1_CIF_ISP_EXP_ROW_NUM + 1)
-
-/* LSC: ISP_LSC_CTRL */
-#define RKISP1_CIF_ISP_LSC_CTRL_ENA BIT(0)
-#define RKISP1_CIF_ISP_LSC_SECT_SIZE_RESERVED 0xFC00FC00
-#define RKISP1_CIF_ISP_LSC_GRAD_RESERVED 0xF000F000
-#define RKISP1_CIF_ISP_LSC_SAMPLE_RESERVED 0xF000F000
-#define RKISP1_CIF_ISP_LSC_TABLE_DATA(v0, v1) \
- (((v0) & 0xFFF) | (((v1) & 0xFFF) << 12))
-#define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1) \
- (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
-#define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1) \
- (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
-
-/* LSC: ISP_LSC_TABLE_SEL */
-#define RKISP1_CIF_ISP_LSC_TABLE_0 0
-#define RKISP1_CIF_ISP_LSC_TABLE_1 1
-
-/* LSC: ISP_LSC_STATUS */
-#define RKISP1_CIF_ISP_LSC_ACTIVE_TABLE BIT(1)
-#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 0
-#define RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 153
-
-/* FLT */
-/* ISP_FILT_MODE */
-#define RKISP1_CIF_ISP_FLT_ENA BIT(0)
-
-/*
- * 0: green filter static mode (active filter factor = FILT_FAC_MID)
- * 1: dynamic noise reduction/sharpen Default
- */
-#define RKISP1_CIF_ISP_FLT_MODE_DNR BIT(1)
-#define RKISP1_CIF_ISP_FLT_MODE_MAX 1
-#define RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(x) (((x) & 0x3) << 4)
-#define RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(x) (((x) & 0x3) << 6)
-#define RKISP1_CIF_ISP_FLT_CHROMA_MODE_MAX 3
-#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1(x) (((x) & 0xF) << 8)
-#define RKISP1_CIF_ISP_FLT_GREEN_STAGE1_MAX 8
-#define RKISP1_CIF_ISP_FLT_THREAD_RESERVED 0xFFFFFC00
-#define RKISP1_CIF_ISP_FLT_FAC_RESERVED 0xFFFFFFC0
-#define RKISP1_CIF_ISP_FLT_LUM_WEIGHT_RESERVED 0xFFF80000
-
-#define RKISP1_CIF_ISP_CTK_COEFF_RESERVED 0xFFFFF800
-#define RKISP1_CIF_ISP_XTALK_OFFSET_RESERVED 0xFFFFF000
-
-/* GOC */
-#define RKISP1_CIF_ISP_GAMMA_OUT_MODE_EQU BIT(0)
-#define RKISP1_CIF_ISP_GOC_MODE_MAX 1
-#define RKISP1_CIF_ISP_GOC_RESERVED 0xFFFFF800
-/* ISP_CTRL BIT 11*/
-#define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA_READ(x) (((x) >> 11) & 1)
-
-/* DPCC */
-/* ISP_DPCC_MODE */
-#define RKISP1_CIF_ISP_DPCC_ENA BIT(0)
-#define RKISP1_CIF_ISP_DPCC_MODE_MAX 0x07
-#define RKISP1_CIF_ISP_DPCC_OUTPUTMODE_MAX 0x0F
-#define RKISP1_CIF_ISP_DPCC_SETUSE_MAX 0x0F
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_RESERVED 0xFFFFE000
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_RESERVED 0xFFFF0000
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RESERVED 0xFFFFC0C0
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_RESERVED 0xFFFFC0C0
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_RESERVED 0xFFFF0000
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_RESERVED 0xFFFFC0C0
-#define RKISP1_CIF_ISP_DPCC_RO_LIMIT_RESERVED 0xFFFFF000
-#define RKISP1_CIF_ISP_DPCC_RND_OFFS_RESERVED 0xFFFFF000
-
-/* BLS */
-/* ISP_BLS_CTRL */
-#define RKISP1_CIF_ISP_BLS_ENA BIT(0)
-#define RKISP1_CIF_ISP_BLS_MODE_MEASURED BIT(1)
-#define RKISP1_CIF_ISP_BLS_MODE_FIXED 0
-#define RKISP1_CIF_ISP_BLS_WINDOW_1 BIT(2)
-#define RKISP1_CIF_ISP_BLS_WINDOW_2 (2 << 2)
-
-/* GAMMA-IN */
-#define RKISP1_CIFISP_DEGAMMA_X_RESERVED \
- ((1 << 31) | (1 << 27) | (1 << 23) | (1 << 19) |\
- (1 << 15) | (1 << 11) | (1 << 7) | (1 << 3))
-#define RKISP1_CIFISP_DEGAMMA_Y_RESERVED 0xFFFFF000
-
-/* AFM */
-#define RKISP1_CIF_ISP_AFM_ENA BIT(0)
-#define RKISP1_CIF_ISP_AFM_THRES_RESERVED 0xFFFF0000
-#define RKISP1_CIF_ISP_AFM_VAR_SHIFT_RESERVED 0xFFF8FFF8
-#define RKISP1_CIF_ISP_AFM_WINDOW_X_RESERVED 0xE000
-#define RKISP1_CIF_ISP_AFM_WINDOW_Y_RESERVED 0xF000
-#define RKISP1_CIF_ISP_AFM_WINDOW_X_MIN 0x5
-#define RKISP1_CIF_ISP_AFM_WINDOW_Y_MIN 0x2
-#define RKISP1_CIF_ISP_AFM_WINDOW_X(x) (((x) & 0x1FFF) << 16)
-#define RKISP1_CIF_ISP_AFM_WINDOW_Y(x) ((x) & 0x1FFF)
-
-/* DPF */
-#define RKISP1_CIF_ISP_DPF_MODE_EN BIT(0)
-#define RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS BIT(1)
-#define RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS BIT(2)
-#define RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS BIT(3)
-#define RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS BIT(4)
-#define RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9 BIT(5)
-#define RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION BIT(6)
-#define RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP BIT(7)
-#define RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP BIT(8)
-#define RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN BIT(9)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_RESERVED 0xFFFFF000
-#define RKISP1_CIF_ISP_DPF_SPATIAL_COEFF_MAX 0x1F
-#define RKISP1_CIF_ISP_DPF_NLL_COEFF_N_MAX 0x3FF
-
-/* =================================================================== */
-/* CIF Registers */
-/* =================================================================== */
-#define RKISP1_CIF_CTRL_BASE 0x00000000
-#define RKISP1_CIF_CCL (RKISP1_CIF_CTRL_BASE + 0x00000000)
-#define RKISP1_CIF_VI_ID (RKISP1_CIF_CTRL_BASE + 0x00000008)
-#define RKISP1_CIF_ICCL (RKISP1_CIF_CTRL_BASE + 0x00000010)
-#define RKISP1_CIF_IRCL (RKISP1_CIF_CTRL_BASE + 0x00000014)
-#define RKISP1_CIF_VI_DPCL (RKISP1_CIF_CTRL_BASE + 0x00000018)
-
-#define RKISP1_CIF_IMG_EFF_BASE 0x00000200
-#define RKISP1_CIF_IMG_EFF_CTRL (RKISP1_CIF_IMG_EFF_BASE + 0x00000000)
-#define RKISP1_CIF_IMG_EFF_COLOR_SEL (RKISP1_CIF_IMG_EFF_BASE + 0x00000004)
-#define RKISP1_CIF_IMG_EFF_MAT_1 (RKISP1_CIF_IMG_EFF_BASE + 0x00000008)
-#define RKISP1_CIF_IMG_EFF_MAT_2 (RKISP1_CIF_IMG_EFF_BASE + 0x0000000C)
-#define RKISP1_CIF_IMG_EFF_MAT_3 (RKISP1_CIF_IMG_EFF_BASE + 0x00000010)
-#define RKISP1_CIF_IMG_EFF_MAT_4 (RKISP1_CIF_IMG_EFF_BASE + 0x00000014)
-#define RKISP1_CIF_IMG_EFF_MAT_5 (RKISP1_CIF_IMG_EFF_BASE + 0x00000018)
-#define RKISP1_CIF_IMG_EFF_TINT (RKISP1_CIF_IMG_EFF_BASE + 0x0000001C)
-#define RKISP1_CIF_IMG_EFF_CTRL_SHD (RKISP1_CIF_IMG_EFF_BASE + 0x00000020)
-#define RKISP1_CIF_IMG_EFF_SHARPEN (RKISP1_CIF_IMG_EFF_BASE + 0x00000024)
-
-#define RKISP1_CIF_SUPER_IMP_BASE 0x00000300
-#define RKISP1_CIF_SUPER_IMP_CTRL (RKISP1_CIF_SUPER_IMP_BASE + 0x00000000)
-#define RKISP1_CIF_SUPER_IMP_OFFSET_X (RKISP1_CIF_SUPER_IMP_BASE + 0x00000004)
-#define RKISP1_CIF_SUPER_IMP_OFFSET_Y (RKISP1_CIF_SUPER_IMP_BASE + 0x00000008)
-#define RKISP1_CIF_SUPER_IMP_COLOR_Y (RKISP1_CIF_SUPER_IMP_BASE + 0x0000000C)
-#define RKISP1_CIF_SUPER_IMP_COLOR_CB (RKISP1_CIF_SUPER_IMP_BASE + 0x00000010)
-#define RKISP1_CIF_SUPER_IMP_COLOR_CR (RKISP1_CIF_SUPER_IMP_BASE + 0x00000014)
-
-#define RKISP1_CIF_ISP_BASE 0x00000400
-#define RKISP1_CIF_ISP_CTRL (RKISP1_CIF_ISP_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_ACQ_PROP (RKISP1_CIF_ISP_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_ACQ_H_OFFS (RKISP1_CIF_ISP_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_ACQ_V_OFFS (RKISP1_CIF_ISP_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_ACQ_H_SIZE (RKISP1_CIF_ISP_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_ACQ_V_SIZE (RKISP1_CIF_ISP_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_ACQ_NR_FRAMES (RKISP1_CIF_ISP_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_GAMMA_DX_LO (RKISP1_CIF_ISP_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_GAMMA_DX_HI (RKISP1_CIF_ISP_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_GAMMA_R_Y0 (RKISP1_CIF_ISP_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_GAMMA_R_Y1 (RKISP1_CIF_ISP_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_GAMMA_R_Y2 (RKISP1_CIF_ISP_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y3 (RKISP1_CIF_ISP_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_GAMMA_R_Y4 (RKISP1_CIF_ISP_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_GAMMA_R_Y5 (RKISP1_CIF_ISP_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_GAMMA_R_Y6 (RKISP1_CIF_ISP_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y7 (RKISP1_CIF_ISP_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_GAMMA_R_Y8 (RKISP1_CIF_ISP_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_GAMMA_R_Y9 (RKISP1_CIF_ISP_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_GAMMA_R_Y10 (RKISP1_CIF_ISP_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y11 (RKISP1_CIF_ISP_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_GAMMA_R_Y12 (RKISP1_CIF_ISP_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_GAMMA_R_Y13 (RKISP1_CIF_ISP_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_GAMMA_R_Y14 (RKISP1_CIF_ISP_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_GAMMA_R_Y15 (RKISP1_CIF_ISP_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_GAMMA_R_Y16 (RKISP1_CIF_ISP_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_GAMMA_G_Y0 (RKISP1_CIF_ISP_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_GAMMA_G_Y1 (RKISP1_CIF_ISP_BASE + 0x0000006C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y2 (RKISP1_CIF_ISP_BASE + 0x00000070)
-#define RKISP1_CIF_ISP_GAMMA_G_Y3 (RKISP1_CIF_ISP_BASE + 0x00000074)
-#define RKISP1_CIF_ISP_GAMMA_G_Y4 (RKISP1_CIF_ISP_BASE + 0x00000078)
-#define RKISP1_CIF_ISP_GAMMA_G_Y5 (RKISP1_CIF_ISP_BASE + 0x0000007C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y6 (RKISP1_CIF_ISP_BASE + 0x00000080)
-#define RKISP1_CIF_ISP_GAMMA_G_Y7 (RKISP1_CIF_ISP_BASE + 0x00000084)
-#define RKISP1_CIF_ISP_GAMMA_G_Y8 (RKISP1_CIF_ISP_BASE + 0x00000088)
-#define RKISP1_CIF_ISP_GAMMA_G_Y9 (RKISP1_CIF_ISP_BASE + 0x0000008C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y10 (RKISP1_CIF_ISP_BASE + 0x00000090)
-#define RKISP1_CIF_ISP_GAMMA_G_Y11 (RKISP1_CIF_ISP_BASE + 0x00000094)
-#define RKISP1_CIF_ISP_GAMMA_G_Y12 (RKISP1_CIF_ISP_BASE + 0x00000098)
-#define RKISP1_CIF_ISP_GAMMA_G_Y13 (RKISP1_CIF_ISP_BASE + 0x0000009C)
-#define RKISP1_CIF_ISP_GAMMA_G_Y14 (RKISP1_CIF_ISP_BASE + 0x000000A0)
-#define RKISP1_CIF_ISP_GAMMA_G_Y15 (RKISP1_CIF_ISP_BASE + 0x000000A4)
-#define RKISP1_CIF_ISP_GAMMA_G_Y16 (RKISP1_CIF_ISP_BASE + 0x000000A8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y0 (RKISP1_CIF_ISP_BASE + 0x000000AC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y1 (RKISP1_CIF_ISP_BASE + 0x000000B0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y2 (RKISP1_CIF_ISP_BASE + 0x000000B4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y3 (RKISP1_CIF_ISP_BASE + 0x000000B8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y4 (RKISP1_CIF_ISP_BASE + 0x000000BC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y5 (RKISP1_CIF_ISP_BASE + 0x000000C0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y6 (RKISP1_CIF_ISP_BASE + 0x000000C4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y7 (RKISP1_CIF_ISP_BASE + 0x000000C8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y8 (RKISP1_CIF_ISP_BASE + 0x000000CC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y9 (RKISP1_CIF_ISP_BASE + 0x000000D0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y10 (RKISP1_CIF_ISP_BASE + 0x000000D4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y11 (RKISP1_CIF_ISP_BASE + 0x000000D8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y12 (RKISP1_CIF_ISP_BASE + 0x000000DC)
-#define RKISP1_CIF_ISP_GAMMA_B_Y13 (RKISP1_CIF_ISP_BASE + 0x000000E0)
-#define RKISP1_CIF_ISP_GAMMA_B_Y14 (RKISP1_CIF_ISP_BASE + 0x000000E4)
-#define RKISP1_CIF_ISP_GAMMA_B_Y15 (RKISP1_CIF_ISP_BASE + 0x000000E8)
-#define RKISP1_CIF_ISP_GAMMA_B_Y16 (RKISP1_CIF_ISP_BASE + 0x000000EC)
-#define RKISP1_CIF_ISP_AWB_PROP (RKISP1_CIF_ISP_BASE + 0x00000110)
-#define RKISP1_CIF_ISP_AWB_WND_H_OFFS (RKISP1_CIF_ISP_BASE + 0x00000114)
-#define RKISP1_CIF_ISP_AWB_WND_V_OFFS (RKISP1_CIF_ISP_BASE + 0x00000118)
-#define RKISP1_CIF_ISP_AWB_WND_H_SIZE (RKISP1_CIF_ISP_BASE + 0x0000011C)
-#define RKISP1_CIF_ISP_AWB_WND_V_SIZE (RKISP1_CIF_ISP_BASE + 0x00000120)
-#define RKISP1_CIF_ISP_AWB_FRAMES (RKISP1_CIF_ISP_BASE + 0x00000124)
-#define RKISP1_CIF_ISP_AWB_REF (RKISP1_CIF_ISP_BASE + 0x00000128)
-#define RKISP1_CIF_ISP_AWB_THRESH (RKISP1_CIF_ISP_BASE + 0x0000012C)
-#define RKISP1_CIF_ISP_AWB_GAIN_G (RKISP1_CIF_ISP_BASE + 0x00000138)
-#define RKISP1_CIF_ISP_AWB_GAIN_RB (RKISP1_CIF_ISP_BASE + 0x0000013C)
-#define RKISP1_CIF_ISP_AWB_WHITE_CNT (RKISP1_CIF_ISP_BASE + 0x00000140)
-#define RKISP1_CIF_ISP_AWB_MEAN (RKISP1_CIF_ISP_BASE + 0x00000144)
-#define RKISP1_CIF_ISP_CC_COEFF_0 (RKISP1_CIF_ISP_BASE + 0x00000170)
-#define RKISP1_CIF_ISP_CC_COEFF_1 (RKISP1_CIF_ISP_BASE + 0x00000174)
-#define RKISP1_CIF_ISP_CC_COEFF_2 (RKISP1_CIF_ISP_BASE + 0x00000178)
-#define RKISP1_CIF_ISP_CC_COEFF_3 (RKISP1_CIF_ISP_BASE + 0x0000017C)
-#define RKISP1_CIF_ISP_CC_COEFF_4 (RKISP1_CIF_ISP_BASE + 0x00000180)
-#define RKISP1_CIF_ISP_CC_COEFF_5 (RKISP1_CIF_ISP_BASE + 0x00000184)
-#define RKISP1_CIF_ISP_CC_COEFF_6 (RKISP1_CIF_ISP_BASE + 0x00000188)
-#define RKISP1_CIF_ISP_CC_COEFF_7 (RKISP1_CIF_ISP_BASE + 0x0000018C)
-#define RKISP1_CIF_ISP_CC_COEFF_8 (RKISP1_CIF_ISP_BASE + 0x00000190)
-#define RKISP1_CIF_ISP_OUT_H_OFFS (RKISP1_CIF_ISP_BASE + 0x00000194)
-#define RKISP1_CIF_ISP_OUT_V_OFFS (RKISP1_CIF_ISP_BASE + 0x00000198)
-#define RKISP1_CIF_ISP_OUT_H_SIZE (RKISP1_CIF_ISP_BASE + 0x0000019C)
-#define RKISP1_CIF_ISP_OUT_V_SIZE (RKISP1_CIF_ISP_BASE + 0x000001A0)
-#define RKISP1_CIF_ISP_DEMOSAIC (RKISP1_CIF_ISP_BASE + 0x000001A4)
-#define RKISP1_CIF_ISP_FLAGS_SHD (RKISP1_CIF_ISP_BASE + 0x000001A8)
-#define RKISP1_CIF_ISP_OUT_H_OFFS_SHD (RKISP1_CIF_ISP_BASE + 0x000001AC)
-#define RKISP1_CIF_ISP_OUT_V_OFFS_SHD (RKISP1_CIF_ISP_BASE + 0x000001B0)
-#define RKISP1_CIF_ISP_OUT_H_SIZE_SHD (RKISP1_CIF_ISP_BASE + 0x000001B4)
-#define RKISP1_CIF_ISP_OUT_V_SIZE_SHD (RKISP1_CIF_ISP_BASE + 0x000001B8)
-#define RKISP1_CIF_ISP_IMSC (RKISP1_CIF_ISP_BASE + 0x000001BC)
-#define RKISP1_CIF_ISP_RIS (RKISP1_CIF_ISP_BASE + 0x000001C0)
-#define RKISP1_CIF_ISP_MIS (RKISP1_CIF_ISP_BASE + 0x000001C4)
-#define RKISP1_CIF_ISP_ICR (RKISP1_CIF_ISP_BASE + 0x000001C8)
-#define RKISP1_CIF_ISP_ISR (RKISP1_CIF_ISP_BASE + 0x000001CC)
-#define RKISP1_CIF_ISP_CT_COEFF_0 (RKISP1_CIF_ISP_BASE + 0x000001D0)
-#define RKISP1_CIF_ISP_CT_COEFF_1 (RKISP1_CIF_ISP_BASE + 0x000001D4)
-#define RKISP1_CIF_ISP_CT_COEFF_2 (RKISP1_CIF_ISP_BASE + 0x000001D8)
-#define RKISP1_CIF_ISP_CT_COEFF_3 (RKISP1_CIF_ISP_BASE + 0x000001DC)
-#define RKISP1_CIF_ISP_CT_COEFF_4 (RKISP1_CIF_ISP_BASE + 0x000001E0)
-#define RKISP1_CIF_ISP_CT_COEFF_5 (RKISP1_CIF_ISP_BASE + 0x000001E4)
-#define RKISP1_CIF_ISP_CT_COEFF_6 (RKISP1_CIF_ISP_BASE + 0x000001E8)
-#define RKISP1_CIF_ISP_CT_COEFF_7 (RKISP1_CIF_ISP_BASE + 0x000001EC)
-#define RKISP1_CIF_ISP_CT_COEFF_8 (RKISP1_CIF_ISP_BASE + 0x000001F0)
-#define RKISP1_CIF_ISP_GAMMA_OUT_MODE (RKISP1_CIF_ISP_BASE + 0x000001F4)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_0 (RKISP1_CIF_ISP_BASE + 0x000001F8)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_1 (RKISP1_CIF_ISP_BASE + 0x000001FC)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_2 (RKISP1_CIF_ISP_BASE + 0x00000200)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_3 (RKISP1_CIF_ISP_BASE + 0x00000204)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_4 (RKISP1_CIF_ISP_BASE + 0x00000208)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_5 (RKISP1_CIF_ISP_BASE + 0x0000020C)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_6 (RKISP1_CIF_ISP_BASE + 0x00000210)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_7 (RKISP1_CIF_ISP_BASE + 0x00000214)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_8 (RKISP1_CIF_ISP_BASE + 0x00000218)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_9 (RKISP1_CIF_ISP_BASE + 0x0000021C)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_10 (RKISP1_CIF_ISP_BASE + 0x00000220)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_11 (RKISP1_CIF_ISP_BASE + 0x00000224)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_12 (RKISP1_CIF_ISP_BASE + 0x00000228)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_13 (RKISP1_CIF_ISP_BASE + 0x0000022C)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_14 (RKISP1_CIF_ISP_BASE + 0x00000230)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_15 (RKISP1_CIF_ISP_BASE + 0x00000234)
-#define RKISP1_CIF_ISP_GAMMA_OUT_Y_16 (RKISP1_CIF_ISP_BASE + 0x00000238)
-#define RKISP1_CIF_ISP_ERR (RKISP1_CIF_ISP_BASE + 0x0000023C)
-#define RKISP1_CIF_ISP_ERR_CLR (RKISP1_CIF_ISP_BASE + 0x00000240)
-#define RKISP1_CIF_ISP_FRAME_COUNT (RKISP1_CIF_ISP_BASE + 0x00000244)
-#define RKISP1_CIF_ISP_CT_OFFSET_R (RKISP1_CIF_ISP_BASE + 0x00000248)
-#define RKISP1_CIF_ISP_CT_OFFSET_G (RKISP1_CIF_ISP_BASE + 0x0000024C)
-#define RKISP1_CIF_ISP_CT_OFFSET_B (RKISP1_CIF_ISP_BASE + 0x00000250)
-
-#define RKISP1_CIF_ISP_FLASH_BASE 0x00000660
-#define RKISP1_CIF_ISP_FLASH_CMD (RKISP1_CIF_ISP_FLASH_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_FLASH_CONFIG (RKISP1_CIF_ISP_FLASH_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_FLASH_PREDIV (RKISP1_CIF_ISP_FLASH_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_FLASH_DELAY (RKISP1_CIF_ISP_FLASH_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_FLASH_TIME (RKISP1_CIF_ISP_FLASH_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_FLASH_MAXP (RKISP1_CIF_ISP_FLASH_BASE + 0x00000014)
-
-#define RKISP1_CIF_ISP_SH_BASE 0x00000680
-#define RKISP1_CIF_ISP_SH_CTRL (RKISP1_CIF_ISP_SH_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_SH_PREDIV (RKISP1_CIF_ISP_SH_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_SH_DELAY (RKISP1_CIF_ISP_SH_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_SH_TIME (RKISP1_CIF_ISP_SH_BASE + 0x0000000C)
-
-#define RKISP1_CIF_C_PROC_BASE 0x00000800
-#define RKISP1_CIF_C_PROC_CTRL (RKISP1_CIF_C_PROC_BASE + 0x00000000)
-#define RKISP1_CIF_C_PROC_CONTRAST (RKISP1_CIF_C_PROC_BASE + 0x00000004)
-#define RKISP1_CIF_C_PROC_BRIGHTNESS (RKISP1_CIF_C_PROC_BASE + 0x00000008)
-#define RKISP1_CIF_C_PROC_SATURATION (RKISP1_CIF_C_PROC_BASE + 0x0000000C)
-#define RKISP1_CIF_C_PROC_HUE (RKISP1_CIF_C_PROC_BASE + 0x00000010)
-
-#define RKISP1_CIF_DUAL_CROP_BASE 0x00000880
-#define RKISP1_CIF_DUAL_CROP_CTRL (RKISP1_CIF_DUAL_CROP_BASE + 0x00000000)
-#define RKISP1_CIF_DUAL_CROP_M_H_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000004)
-#define RKISP1_CIF_DUAL_CROP_M_V_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000008)
-#define RKISP1_CIF_DUAL_CROP_M_H_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x0000000C)
-#define RKISP1_CIF_DUAL_CROP_M_V_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x00000010)
-#define RKISP1_CIF_DUAL_CROP_S_H_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000014)
-#define RKISP1_CIF_DUAL_CROP_S_V_OFFS (RKISP1_CIF_DUAL_CROP_BASE + 0x00000018)
-#define RKISP1_CIF_DUAL_CROP_S_H_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x0000001C)
-#define RKISP1_CIF_DUAL_CROP_S_V_SIZE (RKISP1_CIF_DUAL_CROP_BASE + 0x00000020)
-#define RKISP1_CIF_DUAL_CROP_M_H_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000024)
-#define RKISP1_CIF_DUAL_CROP_M_V_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000028)
-#define RKISP1_CIF_DUAL_CROP_M_H_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x0000002C)
-#define RKISP1_CIF_DUAL_CROP_M_V_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000030)
-#define RKISP1_CIF_DUAL_CROP_S_H_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000034)
-#define RKISP1_CIF_DUAL_CROP_S_V_OFFS_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000038)
-#define RKISP1_CIF_DUAL_CROP_S_H_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x0000003C)
-#define RKISP1_CIF_DUAL_CROP_S_V_SIZE_SHD (RKISP1_CIF_DUAL_CROP_BASE + 0x00000040)
-
-#define RKISP1_CIF_MRSZ_BASE 0x00000C00
-#define RKISP1_CIF_MRSZ_CTRL (RKISP1_CIF_MRSZ_BASE + 0x00000000)
-#define RKISP1_CIF_MRSZ_SCALE_HY (RKISP1_CIF_MRSZ_BASE + 0x00000004)
-#define RKISP1_CIF_MRSZ_SCALE_HCB (RKISP1_CIF_MRSZ_BASE + 0x00000008)
-#define RKISP1_CIF_MRSZ_SCALE_HCR (RKISP1_CIF_MRSZ_BASE + 0x0000000C)
-#define RKISP1_CIF_MRSZ_SCALE_VY (RKISP1_CIF_MRSZ_BASE + 0x00000010)
-#define RKISP1_CIF_MRSZ_SCALE_VC (RKISP1_CIF_MRSZ_BASE + 0x00000014)
-#define RKISP1_CIF_MRSZ_PHASE_HY (RKISP1_CIF_MRSZ_BASE + 0x00000018)
-#define RKISP1_CIF_MRSZ_PHASE_HC (RKISP1_CIF_MRSZ_BASE + 0x0000001C)
-#define RKISP1_CIF_MRSZ_PHASE_VY (RKISP1_CIF_MRSZ_BASE + 0x00000020)
-#define RKISP1_CIF_MRSZ_PHASE_VC (RKISP1_CIF_MRSZ_BASE + 0x00000024)
-#define RKISP1_CIF_MRSZ_SCALE_LUT_ADDR (RKISP1_CIF_MRSZ_BASE + 0x00000028)
-#define RKISP1_CIF_MRSZ_SCALE_LUT (RKISP1_CIF_MRSZ_BASE + 0x0000002C)
-#define RKISP1_CIF_MRSZ_CTRL_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000030)
-#define RKISP1_CIF_MRSZ_SCALE_HY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000034)
-#define RKISP1_CIF_MRSZ_SCALE_HCB_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000038)
-#define RKISP1_CIF_MRSZ_SCALE_HCR_SHD (RKISP1_CIF_MRSZ_BASE + 0x0000003C)
-#define RKISP1_CIF_MRSZ_SCALE_VY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000040)
-#define RKISP1_CIF_MRSZ_SCALE_VC_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000044)
-#define RKISP1_CIF_MRSZ_PHASE_HY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000048)
-#define RKISP1_CIF_MRSZ_PHASE_HC_SHD (RKISP1_CIF_MRSZ_BASE + 0x0000004C)
-#define RKISP1_CIF_MRSZ_PHASE_VY_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000050)
-#define RKISP1_CIF_MRSZ_PHASE_VC_SHD (RKISP1_CIF_MRSZ_BASE + 0x00000054)
-
-#define RKISP1_CIF_SRSZ_BASE 0x00001000
-#define RKISP1_CIF_SRSZ_CTRL (RKISP1_CIF_SRSZ_BASE + 0x00000000)
-#define RKISP1_CIF_SRSZ_SCALE_HY (RKISP1_CIF_SRSZ_BASE + 0x00000004)
-#define RKISP1_CIF_SRSZ_SCALE_HCB (RKISP1_CIF_SRSZ_BASE + 0x00000008)
-#define RKISP1_CIF_SRSZ_SCALE_HCR (RKISP1_CIF_SRSZ_BASE + 0x0000000C)
-#define RKISP1_CIF_SRSZ_SCALE_VY (RKISP1_CIF_SRSZ_BASE + 0x00000010)
-#define RKISP1_CIF_SRSZ_SCALE_VC (RKISP1_CIF_SRSZ_BASE + 0x00000014)
-#define RKISP1_CIF_SRSZ_PHASE_HY (RKISP1_CIF_SRSZ_BASE + 0x00000018)
-#define RKISP1_CIF_SRSZ_PHASE_HC (RKISP1_CIF_SRSZ_BASE + 0x0000001C)
-#define RKISP1_CIF_SRSZ_PHASE_VY (RKISP1_CIF_SRSZ_BASE + 0x00000020)
-#define RKISP1_CIF_SRSZ_PHASE_VC (RKISP1_CIF_SRSZ_BASE + 0x00000024)
-#define RKISP1_CIF_SRSZ_SCALE_LUT_ADDR (RKISP1_CIF_SRSZ_BASE + 0x00000028)
-#define RKISP1_CIF_SRSZ_SCALE_LUT (RKISP1_CIF_SRSZ_BASE + 0x0000002C)
-#define RKISP1_CIF_SRSZ_CTRL_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000030)
-#define RKISP1_CIF_SRSZ_SCALE_HY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000034)
-#define RKISP1_CIF_SRSZ_SCALE_HCB_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000038)
-#define RKISP1_CIF_SRSZ_SCALE_HCR_SHD (RKISP1_CIF_SRSZ_BASE + 0x0000003C)
-#define RKISP1_CIF_SRSZ_SCALE_VY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000040)
-#define RKISP1_CIF_SRSZ_SCALE_VC_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000044)
-#define RKISP1_CIF_SRSZ_PHASE_HY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000048)
-#define RKISP1_CIF_SRSZ_PHASE_HC_SHD (RKISP1_CIF_SRSZ_BASE + 0x0000004C)
-#define RKISP1_CIF_SRSZ_PHASE_VY_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000050)
-#define RKISP1_CIF_SRSZ_PHASE_VC_SHD (RKISP1_CIF_SRSZ_BASE + 0x00000054)
-
-#define RKISP1_CIF_MI_BASE 0x00001400
-#define RKISP1_CIF_MI_CTRL (RKISP1_CIF_MI_BASE + 0x00000000)
-#define RKISP1_CIF_MI_INIT (RKISP1_CIF_MI_BASE + 0x00000004)
-#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x00000008)
-#define RKISP1_CIF_MI_MP_Y_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x0000000C)
-#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000010)
-#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000014)
-#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_INIT (RKISP1_CIF_MI_BASE + 0x00000018)
-#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x0000001C)
-#define RKISP1_CIF_MI_MP_CB_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000020)
-#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000024)
-#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000028)
-#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x0000002C)
-#define RKISP1_CIF_MI_MP_CR_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000030)
-#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000034)
-#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000038)
-#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x0000003C)
-#define RKISP1_CIF_MI_SP_Y_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000040)
-#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000044)
-#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x00000048)
-#define RKISP1_CIF_MI_SP_Y_LLENGTH (RKISP1_CIF_MI_BASE + 0x0000004C)
-#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x00000050)
-#define RKISP1_CIF_MI_SP_CB_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000054)
-#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000058)
-#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x0000005C)
-#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT (RKISP1_CIF_MI_BASE + 0x00000060)
-#define RKISP1_CIF_MI_SP_CR_SIZE_INIT (RKISP1_CIF_MI_BASE + 0x00000064)
-#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_INIT (RKISP1_CIF_MI_BASE + 0x00000068)
-#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_START (RKISP1_CIF_MI_BASE + 0x0000006C)
-#define RKISP1_CIF_MI_BYTE_CNT (RKISP1_CIF_MI_BASE + 0x00000070)
-#define RKISP1_CIF_MI_CTRL_SHD (RKISP1_CIF_MI_BASE + 0x00000074)
-#define RKISP1_CIF_MI_MP_Y_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x00000078)
-#define RKISP1_CIF_MI_MP_Y_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x0000007C)
-#define RKISP1_CIF_MI_MP_Y_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x00000080)
-#define RKISP1_CIF_MI_MP_Y_IRQ_OFFS_SHD (RKISP1_CIF_MI_BASE + 0x00000084)
-#define RKISP1_CIF_MI_MP_CB_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x00000088)
-#define RKISP1_CIF_MI_MP_CB_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x0000008C)
-#define RKISP1_CIF_MI_MP_CB_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x00000090)
-#define RKISP1_CIF_MI_MP_CR_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x00000094)
-#define RKISP1_CIF_MI_MP_CR_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x00000098)
-#define RKISP1_CIF_MI_MP_CR_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x0000009C)
-#define RKISP1_CIF_MI_SP_Y_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x000000A0)
-#define RKISP1_CIF_MI_SP_Y_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x000000A4)
-#define RKISP1_CIF_MI_SP_Y_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x000000A8)
-#define RKISP1_CIF_MI_SP_CB_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x000000B0)
-#define RKISP1_CIF_MI_SP_CB_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x000000B4)
-#define RKISP1_CIF_MI_SP_CB_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x000000B8)
-#define RKISP1_CIF_MI_SP_CR_BASE_AD_SHD (RKISP1_CIF_MI_BASE + 0x000000BC)
-#define RKISP1_CIF_MI_SP_CR_SIZE_SHD (RKISP1_CIF_MI_BASE + 0x000000C0)
-#define RKISP1_CIF_MI_SP_CR_OFFS_CNT_SHD (RKISP1_CIF_MI_BASE + 0x000000C4)
-#define RKISP1_CIF_MI_DMA_Y_PIC_START_AD (RKISP1_CIF_MI_BASE + 0x000000C8)
-#define RKISP1_CIF_MI_DMA_Y_PIC_WIDTH (RKISP1_CIF_MI_BASE + 0x000000CC)
-#define RKISP1_CIF_MI_DMA_Y_LLENGTH (RKISP1_CIF_MI_BASE + 0x000000D0)
-#define RKISP1_CIF_MI_DMA_Y_PIC_SIZE (RKISP1_CIF_MI_BASE + 0x000000D4)
-#define RKISP1_CIF_MI_DMA_CB_PIC_START_AD (RKISP1_CIF_MI_BASE + 0x000000D8)
-#define RKISP1_CIF_MI_DMA_CR_PIC_START_AD (RKISP1_CIF_MI_BASE + 0x000000E8)
-#define RKISP1_CIF_MI_IMSC (RKISP1_CIF_MI_BASE + 0x000000F8)
-#define RKISP1_CIF_MI_RIS (RKISP1_CIF_MI_BASE + 0x000000FC)
-#define RKISP1_CIF_MI_MIS (RKISP1_CIF_MI_BASE + 0x00000100)
-#define RKISP1_CIF_MI_ICR (RKISP1_CIF_MI_BASE + 0x00000104)
-#define RKISP1_CIF_MI_ISR (RKISP1_CIF_MI_BASE + 0x00000108)
-#define RKISP1_CIF_MI_STATUS (RKISP1_CIF_MI_BASE + 0x0000010C)
-#define RKISP1_CIF_MI_STATUS_CLR (RKISP1_CIF_MI_BASE + 0x00000110)
-#define RKISP1_CIF_MI_SP_Y_PIC_WIDTH (RKISP1_CIF_MI_BASE + 0x00000114)
-#define RKISP1_CIF_MI_SP_Y_PIC_HEIGHT (RKISP1_CIF_MI_BASE + 0x00000118)
-#define RKISP1_CIF_MI_SP_Y_PIC_SIZE (RKISP1_CIF_MI_BASE + 0x0000011C)
-#define RKISP1_CIF_MI_DMA_CTRL (RKISP1_CIF_MI_BASE + 0x00000120)
-#define RKISP1_CIF_MI_DMA_START (RKISP1_CIF_MI_BASE + 0x00000124)
-#define RKISP1_CIF_MI_DMA_STATUS (RKISP1_CIF_MI_BASE + 0x00000128)
-#define RKISP1_CIF_MI_PIXEL_COUNT (RKISP1_CIF_MI_BASE + 0x0000012C)
-#define RKISP1_CIF_MI_MP_Y_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000130)
-#define RKISP1_CIF_MI_MP_CB_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000134)
-#define RKISP1_CIF_MI_MP_CR_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000138)
-#define RKISP1_CIF_MI_SP_Y_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x0000013C)
-#define RKISP1_CIF_MI_SP_CB_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000140)
-#define RKISP1_CIF_MI_SP_CR_BASE_AD_INIT2 (RKISP1_CIF_MI_BASE + 0x00000144)
-#define RKISP1_CIF_MI_XTD_FORMAT_CTRL (RKISP1_CIF_MI_BASE + 0x00000148)
-
-#define RKISP1_CIF_SMIA_BASE 0x00001A00
-#define RKISP1_CIF_SMIA_CTRL (RKISP1_CIF_SMIA_BASE + 0x00000000)
-#define RKISP1_CIF_SMIA_STATUS (RKISP1_CIF_SMIA_BASE + 0x00000004)
-#define RKISP1_CIF_SMIA_IMSC (RKISP1_CIF_SMIA_BASE + 0x00000008)
-#define RKISP1_CIF_SMIA_RIS (RKISP1_CIF_SMIA_BASE + 0x0000000C)
-#define RKISP1_CIF_SMIA_MIS (RKISP1_CIF_SMIA_BASE + 0x00000010)
-#define RKISP1_CIF_SMIA_ICR (RKISP1_CIF_SMIA_BASE + 0x00000014)
-#define RKISP1_CIF_SMIA_ISR (RKISP1_CIF_SMIA_BASE + 0x00000018)
-#define RKISP1_CIF_SMIA_DATA_FORMAT_SEL (RKISP1_CIF_SMIA_BASE + 0x0000001C)
-#define RKISP1_CIF_SMIA_SOF_EMB_DATA_LINES (RKISP1_CIF_SMIA_BASE + 0x00000020)
-#define RKISP1_CIF_SMIA_EMB_HSTART (RKISP1_CIF_SMIA_BASE + 0x00000024)
-#define RKISP1_CIF_SMIA_EMB_HSIZE (RKISP1_CIF_SMIA_BASE + 0x00000028)
-#define RKISP1_CIF_SMIA_EMB_VSTART (RKISP1_CIF_SMIA_BASE + 0x0000002c)
-#define RKISP1_CIF_SMIA_NUM_LINES (RKISP1_CIF_SMIA_BASE + 0x00000030)
-#define RKISP1_CIF_SMIA_EMB_DATA_FIFO (RKISP1_CIF_SMIA_BASE + 0x00000034)
-#define RKISP1_CIF_SMIA_EMB_DATA_WATERMARK (RKISP1_CIF_SMIA_BASE + 0x00000038)
-
-#define RKISP1_CIF_MIPI_BASE 0x00001C00
-#define RKISP1_CIF_MIPI_CTRL (RKISP1_CIF_MIPI_BASE + 0x00000000)
-#define RKISP1_CIF_MIPI_STATUS (RKISP1_CIF_MIPI_BASE + 0x00000004)
-#define RKISP1_CIF_MIPI_IMSC (RKISP1_CIF_MIPI_BASE + 0x00000008)
-#define RKISP1_CIF_MIPI_RIS (RKISP1_CIF_MIPI_BASE + 0x0000000C)
-#define RKISP1_CIF_MIPI_MIS (RKISP1_CIF_MIPI_BASE + 0x00000010)
-#define RKISP1_CIF_MIPI_ICR (RKISP1_CIF_MIPI_BASE + 0x00000014)
-#define RKISP1_CIF_MIPI_ISR (RKISP1_CIF_MIPI_BASE + 0x00000018)
-#define RKISP1_CIF_MIPI_CUR_DATA_ID (RKISP1_CIF_MIPI_BASE + 0x0000001C)
-#define RKISP1_CIF_MIPI_IMG_DATA_SEL (RKISP1_CIF_MIPI_BASE + 0x00000020)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_1 (RKISP1_CIF_MIPI_BASE + 0x00000024)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_2 (RKISP1_CIF_MIPI_BASE + 0x00000028)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_3 (RKISP1_CIF_MIPI_BASE + 0x0000002C)
-#define RKISP1_CIF_MIPI_ADD_DATA_SEL_4 (RKISP1_CIF_MIPI_BASE + 0x00000030)
-#define RKISP1_CIF_MIPI_ADD_DATA_FIFO (RKISP1_CIF_MIPI_BASE + 0x00000034)
-#define RKISP1_CIF_MIPI_FIFO_FILL_LEVEL (RKISP1_CIF_MIPI_BASE + 0x00000038)
-#define RKISP1_CIF_MIPI_COMPRESSED_MODE (RKISP1_CIF_MIPI_BASE + 0x0000003C)
-#define RKISP1_CIF_MIPI_FRAME (RKISP1_CIF_MIPI_BASE + 0x00000040)
-#define RKISP1_CIF_MIPI_GEN_SHORT_DT (RKISP1_CIF_MIPI_BASE + 0x00000044)
-#define RKISP1_CIF_MIPI_GEN_SHORT_8_9 (RKISP1_CIF_MIPI_BASE + 0x00000048)
-#define RKISP1_CIF_MIPI_GEN_SHORT_A_B (RKISP1_CIF_MIPI_BASE + 0x0000004C)
-#define RKISP1_CIF_MIPI_GEN_SHORT_C_D (RKISP1_CIF_MIPI_BASE + 0x00000050)
-#define RKISP1_CIF_MIPI_GEN_SHORT_E_F (RKISP1_CIF_MIPI_BASE + 0x00000054)
-
-#define RKISP1_CIF_ISP_AFM_BASE 0x00002000
-#define RKISP1_CIF_ISP_AFM_CTRL (RKISP1_CIF_ISP_AFM_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_AFM_LT_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_AFM_RB_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_AFM_LT_B (RKISP1_CIF_ISP_AFM_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_AFM_RB_B (RKISP1_CIF_ISP_AFM_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_AFM_LT_C (RKISP1_CIF_ISP_AFM_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_AFM_RB_C (RKISP1_CIF_ISP_AFM_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_AFM_THRES (RKISP1_CIF_ISP_AFM_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_AFM_VAR_SHIFT (RKISP1_CIF_ISP_AFM_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_AFM_SUM_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_AFM_SUM_B (RKISP1_CIF_ISP_AFM_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_AFM_SUM_C (RKISP1_CIF_ISP_AFM_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_AFM_LUM_A (RKISP1_CIF_ISP_AFM_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_AFM_LUM_B (RKISP1_CIF_ISP_AFM_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_AFM_LUM_C (RKISP1_CIF_ISP_AFM_BASE + 0x00000038)
-
-#define RKISP1_CIF_ISP_LSC_BASE 0x00002200
-#define RKISP1_CIF_ISP_LSC_CTRL (RKISP1_CIF_ISP_LSC_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_LSC_R_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_LSC_B_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR (RKISP1_CIF_ISP_LSC_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_LSC_R_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_LSC_GR_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_LSC_B_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_LSC_GB_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_LSC_XGRAD_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_LSC_XGRAD_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_LSC_XGRAD_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_LSC_XGRAD_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_LSC_YGRAD_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_LSC_YGRAD_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_LSC_YGRAD_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_LSC_YGRAD_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_LSC_XSIZE_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_LSC_XSIZE_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_LSC_XSIZE_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_LSC_XSIZE_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_LSC_YSIZE_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_LSC_YSIZE_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_LSC_YSIZE_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_LSC_YSIZE_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_LSC_TABLE_SEL (RKISP1_CIF_ISP_LSC_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_LSC_STATUS (RKISP1_CIF_ISP_LSC_BASE + 0x00000068)
-
-#define RKISP1_CIF_ISP_IS_BASE 0x00002300
-#define RKISP1_CIF_ISP_IS_CTRL (RKISP1_CIF_ISP_IS_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_IS_RECENTER (RKISP1_CIF_ISP_IS_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_IS_H_OFFS (RKISP1_CIF_ISP_IS_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_IS_V_OFFS (RKISP1_CIF_ISP_IS_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_IS_H_SIZE (RKISP1_CIF_ISP_IS_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_IS_V_SIZE (RKISP1_CIF_ISP_IS_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_IS_MAX_DX (RKISP1_CIF_ISP_IS_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_IS_MAX_DY (RKISP1_CIF_ISP_IS_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_IS_DISPLACE (RKISP1_CIF_ISP_IS_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_IS_H_OFFS_SHD (RKISP1_CIF_ISP_IS_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_IS_V_OFFS_SHD (RKISP1_CIF_ISP_IS_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_IS_H_SIZE_SHD (RKISP1_CIF_ISP_IS_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_IS_V_SIZE_SHD (RKISP1_CIF_ISP_IS_BASE + 0x00000030)
-
-#define RKISP1_CIF_ISP_HIST_BASE 0x00002400
-
-#define RKISP1_CIF_ISP_HIST_PROP (RKISP1_CIF_ISP_HIST_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_HIST_H_OFFS (RKISP1_CIF_ISP_HIST_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_HIST_V_OFFS (RKISP1_CIF_ISP_HIST_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_HIST_H_SIZE (RKISP1_CIF_ISP_HIST_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_HIST_V_SIZE (RKISP1_CIF_ISP_HIST_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_HIST_BIN_0 (RKISP1_CIF_ISP_HIST_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_HIST_BIN_1 (RKISP1_CIF_ISP_HIST_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_HIST_BIN_2 (RKISP1_CIF_ISP_HIST_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_HIST_BIN_3 (RKISP1_CIF_ISP_HIST_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_HIST_BIN_4 (RKISP1_CIF_ISP_HIST_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_HIST_BIN_5 (RKISP1_CIF_ISP_HIST_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_HIST_BIN_6 (RKISP1_CIF_ISP_HIST_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_HIST_BIN_7 (RKISP1_CIF_ISP_HIST_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_HIST_BIN_8 (RKISP1_CIF_ISP_HIST_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_HIST_BIN_9 (RKISP1_CIF_ISP_HIST_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_HIST_BIN_10 (RKISP1_CIF_ISP_HIST_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_HIST_BIN_11 (RKISP1_CIF_ISP_HIST_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_HIST_BIN_12 (RKISP1_CIF_ISP_HIST_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_HIST_BIN_13 (RKISP1_CIF_ISP_HIST_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_HIST_BIN_14 (RKISP1_CIF_ISP_HIST_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_HIST_BIN_15 (RKISP1_CIF_ISP_HIST_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_00TO30 (RKISP1_CIF_ISP_HIST_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_40TO21 (RKISP1_CIF_ISP_HIST_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_31TO12 (RKISP1_CIF_ISP_HIST_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_22TO03 (RKISP1_CIF_ISP_HIST_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_13TO43 (RKISP1_CIF_ISP_HIST_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_04TO34 (RKISP1_CIF_ISP_HIST_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_HIST_WEIGHT_44 (RKISP1_CIF_ISP_HIST_BASE + 0x0000006C)
-
-#define RKISP1_CIF_ISP_FILT_BASE 0x00002500
-#define RKISP1_CIF_ISP_FILT_MODE (RKISP1_CIF_ISP_FILT_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_FILT_THRESH_BL0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_FILT_THRESH_BL1 (RKISP1_CIF_ISP_FILT_BASE + 0x0000002c)
-#define RKISP1_CIF_ISP_FILT_THRESH_SH0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_FILT_THRESH_SH1 (RKISP1_CIF_ISP_FILT_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_FILT_LUM_WEIGHT (RKISP1_CIF_ISP_FILT_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_FILT_FAC_SH1 (RKISP1_CIF_ISP_FILT_BASE + 0x0000003c)
-#define RKISP1_CIF_ISP_FILT_FAC_SH0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_FILT_FAC_MID (RKISP1_CIF_ISP_FILT_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_FILT_FAC_BL0 (RKISP1_CIF_ISP_FILT_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_FILT_FAC_BL1 (RKISP1_CIF_ISP_FILT_BASE + 0x0000004C)
-
-#define RKISP1_CIF_ISP_CAC_BASE 0x00002580
-#define RKISP1_CIF_ISP_CAC_CTRL (RKISP1_CIF_ISP_CAC_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_CAC_COUNT_START (RKISP1_CIF_ISP_CAC_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_CAC_A (RKISP1_CIF_ISP_CAC_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_CAC_B (RKISP1_CIF_ISP_CAC_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_CAC_C (RKISP1_CIF_ISP_CAC_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_X_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_Y_NORM (RKISP1_CIF_ISP_CAC_BASE + 0x00000018)
-
-#define RKISP1_CIF_ISP_EXP_BASE 0x00002600
-#define RKISP1_CIF_ISP_EXP_CTRL (RKISP1_CIF_ISP_EXP_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_EXP_H_OFFSET (RKISP1_CIF_ISP_EXP_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_EXP_V_OFFSET (RKISP1_CIF_ISP_EXP_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_EXP_H_SIZE (RKISP1_CIF_ISP_EXP_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_EXP_V_SIZE (RKISP1_CIF_ISP_EXP_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_EXP_MEAN_00 (RKISP1_CIF_ISP_EXP_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_EXP_MEAN_10 (RKISP1_CIF_ISP_EXP_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_EXP_MEAN_20 (RKISP1_CIF_ISP_EXP_BASE + 0x0000001c)
-#define RKISP1_CIF_ISP_EXP_MEAN_30 (RKISP1_CIF_ISP_EXP_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_EXP_MEAN_40 (RKISP1_CIF_ISP_EXP_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_EXP_MEAN_01 (RKISP1_CIF_ISP_EXP_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_EXP_MEAN_11 (RKISP1_CIF_ISP_EXP_BASE + 0x0000002c)
-#define RKISP1_CIF_ISP_EXP_MEAN_21 (RKISP1_CIF_ISP_EXP_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_EXP_MEAN_31 (RKISP1_CIF_ISP_EXP_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_EXP_MEAN_41 (RKISP1_CIF_ISP_EXP_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_EXP_MEAN_02 (RKISP1_CIF_ISP_EXP_BASE + 0x0000003c)
-#define RKISP1_CIF_ISP_EXP_MEAN_12 (RKISP1_CIF_ISP_EXP_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_EXP_MEAN_22 (RKISP1_CIF_ISP_EXP_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_EXP_MEAN_32 (RKISP1_CIF_ISP_EXP_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_EXP_MEAN_42 (RKISP1_CIF_ISP_EXP_BASE + 0x0000004c)
-#define RKISP1_CIF_ISP_EXP_MEAN_03 (RKISP1_CIF_ISP_EXP_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_EXP_MEAN_13 (RKISP1_CIF_ISP_EXP_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_EXP_MEAN_23 (RKISP1_CIF_ISP_EXP_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_EXP_MEAN_33 (RKISP1_CIF_ISP_EXP_BASE + 0x0000005c)
-#define RKISP1_CIF_ISP_EXP_MEAN_43 (RKISP1_CIF_ISP_EXP_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_EXP_MEAN_04 (RKISP1_CIF_ISP_EXP_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_EXP_MEAN_14 (RKISP1_CIF_ISP_EXP_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_EXP_MEAN_24 (RKISP1_CIF_ISP_EXP_BASE + 0x0000006c)
-#define RKISP1_CIF_ISP_EXP_MEAN_34 (RKISP1_CIF_ISP_EXP_BASE + 0x00000070)
-#define RKISP1_CIF_ISP_EXP_MEAN_44 (RKISP1_CIF_ISP_EXP_BASE + 0x00000074)
-
-#define RKISP1_CIF_ISP_BLS_BASE 0x00002700
-#define RKISP1_CIF_ISP_BLS_CTRL (RKISP1_CIF_ISP_BLS_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_BLS_SAMPLES (RKISP1_CIF_ISP_BLS_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_BLS_H1_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_BLS_H1_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x0000000c)
-#define RKISP1_CIF_ISP_BLS_V1_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_BLS_V1_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_BLS_H2_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_BLS_H2_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x0000001c)
-#define RKISP1_CIF_ISP_BLS_V2_START (RKISP1_CIF_ISP_BLS_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_BLS_V2_STOP (RKISP1_CIF_ISP_BLS_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_BLS_A_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_BLS_B_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x0000002c)
-#define RKISP1_CIF_ISP_BLS_C_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_BLS_D_FIXED (RKISP1_CIF_ISP_BLS_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_BLS_A_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_BLS_B_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x0000003c)
-#define RKISP1_CIF_ISP_BLS_C_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_BLS_D_MEASURED (RKISP1_CIF_ISP_BLS_BASE + 0x00000044)
-
-#define RKISP1_CIF_ISP_DPF_BASE 0x00002800
-#define RKISP1_CIF_ISP_DPF_MODE (RKISP1_CIF_ISP_DPF_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_DPF_STRENGTH_R (RKISP1_CIF_ISP_DPF_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_DPF_STRENGTH_G (RKISP1_CIF_ISP_DPF_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_DPF_STRENGTH_B (RKISP1_CIF_ISP_DPF_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4 (RKISP1_CIF_ISP_DPF_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6 (RKISP1_CIF_ISP_DPF_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4 (RKISP1_CIF_ISP_DPF_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6 (RKISP1_CIF_ISP_DPF_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_0 (RKISP1_CIF_ISP_DPF_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_1 (RKISP1_CIF_ISP_DPF_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_2 (RKISP1_CIF_ISP_DPF_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_3 (RKISP1_CIF_ISP_DPF_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_4 (RKISP1_CIF_ISP_DPF_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_5 (RKISP1_CIF_ISP_DPF_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_6 (RKISP1_CIF_ISP_DPF_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_7 (RKISP1_CIF_ISP_DPF_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_8 (RKISP1_CIF_ISP_DPF_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_9 (RKISP1_CIF_ISP_DPF_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_10 (RKISP1_CIF_ISP_DPF_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_11 (RKISP1_CIF_ISP_DPF_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_12 (RKISP1_CIF_ISP_DPF_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_13 (RKISP1_CIF_ISP_DPF_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_14 (RKISP1_CIF_ISP_DPF_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_15 (RKISP1_CIF_ISP_DPF_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_DPF_NULL_COEFF_16 (RKISP1_CIF_ISP_DPF_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_R (RKISP1_CIF_ISP_DPF_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_GR (RKISP1_CIF_ISP_DPF_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_GB (RKISP1_CIF_ISP_DPF_BASE + 0x0000006C)
-#define RKISP1_CIF_ISP_DPF_NF_GAIN_B (RKISP1_CIF_ISP_DPF_BASE + 0x00000070)
-
-#define RKISP1_CIF_ISP_DPCC_BASE 0x00002900
-#define RKISP1_CIF_ISP_DPCC_MODE (RKISP1_CIF_ISP_DPCC_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE (RKISP1_CIF_ISP_DPCC_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_DPCC_SET_USE (RKISP1_CIF_ISP_DPCC_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_DPCC_METHODS_SET_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_1 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_2 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_DPCC_LINE_THRESH_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_DPCC_PG_FAC_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_DPCC_RND_THRESH_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_DPCC_RG_FAC_3 (RKISP1_CIF_ISP_DPCC_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_DPCC_RO_LIMITS (RKISP1_CIF_ISP_DPCC_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_DPCC_RND_OFFS (RKISP1_CIF_ISP_DPCC_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_DPCC_BPT_CTRL (RKISP1_CIF_ISP_DPCC_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_DPCC_BPT_NUMBER (RKISP1_CIF_ISP_DPCC_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_DPCC_BPT_ADDR (RKISP1_CIF_ISP_DPCC_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_DPCC_BPT_DATA (RKISP1_CIF_ISP_DPCC_BASE + 0x00000068)
-
-#define RKISP1_CIF_ISP_WDR_BASE 0x00002A00
-#define RKISP1_CIF_ISP_WDR_CTRL (RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_1 (RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_2 (RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_3 (RKISP1_CIF_ISP_WDR_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_4 (RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0 (RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1 (RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2 (RKISP1_CIF_ISP_WDR_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3 (RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4 (RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5 (RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6 (RKISP1_CIF_ISP_WDR_BASE + 0x0000002C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7 (RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8 (RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9 (RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10 (RKISP1_CIF_ISP_WDR_BASE + 0x0000003C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11 (RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12 (RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13 (RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14 (RKISP1_CIF_ISP_WDR_BASE + 0x0000004C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15 (RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16 (RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17 (RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18 (RKISP1_CIF_ISP_WDR_BASE + 0x0000005C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19 (RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20 (RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21 (RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22 (RKISP1_CIF_ISP_WDR_BASE + 0x0000006C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23 (RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24 (RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25 (RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26 (RKISP1_CIF_ISP_WDR_BASE + 0x0000007C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27 (RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28 (RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29 (RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30 (RKISP1_CIF_ISP_WDR_BASE + 0x0000008C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31 (RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32 (RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
-#define RKISP1_CIF_ISP_WDR_OFFSET (RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
-#define RKISP1_CIF_ISP_WDR_DELTAMIN (RKISP1_CIF_ISP_WDR_BASE + 0x0000009C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000A0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000A4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000A8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000AC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000B0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000B4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000B8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000BC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000C0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000C4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000C8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000CC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000D8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000DC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000E8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000EC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F0)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F4)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000F8)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000FC)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000010C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000011C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000012C)
-#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
-
-#define RKISP1_CIF_ISP_VSM_BASE 0x00002F00
-#define RKISP1_CIF_ISP_VSM_MODE (RKISP1_CIF_ISP_VSM_BASE + 0x00000000)
-#define RKISP1_CIF_ISP_VSM_H_OFFS (RKISP1_CIF_ISP_VSM_BASE + 0x00000004)
-#define RKISP1_CIF_ISP_VSM_V_OFFS (RKISP1_CIF_ISP_VSM_BASE + 0x00000008)
-#define RKISP1_CIF_ISP_VSM_H_SIZE (RKISP1_CIF_ISP_VSM_BASE + 0x0000000C)
-#define RKISP1_CIF_ISP_VSM_V_SIZE (RKISP1_CIF_ISP_VSM_BASE + 0x00000010)
-#define RKISP1_CIF_ISP_VSM_H_SEGMENTS (RKISP1_CIF_ISP_VSM_BASE + 0x00000014)
-#define RKISP1_CIF_ISP_VSM_V_SEGMENTS (RKISP1_CIF_ISP_VSM_BASE + 0x00000018)
-#define RKISP1_CIF_ISP_VSM_DELTA_H (RKISP1_CIF_ISP_VSM_BASE + 0x0000001C)
-#define RKISP1_CIF_ISP_VSM_DELTA_V (RKISP1_CIF_ISP_VSM_BASE + 0x00000020)
-
-#endif /* _RKISP1_REGS_H */
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - V4l resizer device
- *
- * Copyright (C) 2019 Collabora, Ltd.
- *
- * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include "rkisp1-common.h"
-
-#define RKISP1_RSZ_SP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_selfpath"
-#define RKISP1_RSZ_MP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_mainpath"
-
-#define RKISP1_DEF_FMT MEDIA_BUS_FMT_YUYV8_2X8
-#define RKISP1_DEF_PIXEL_ENC V4L2_PIXEL_ENC_YUV
-
-struct rkisp1_rsz_yuv_mbus_info {
- u32 mbus_code;
- u32 hdiv;
- u32 vdiv;
-};
-
-static const struct rkisp1_rsz_yuv_mbus_info rkisp1_rsz_yuv_src_formats[] = {
- {
- .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, /* YUV422 */
- .hdiv = 2,
- .vdiv = 1,
- },
- {
- .mbus_code = MEDIA_BUS_FMT_YUYV8_1_5X8, /* YUV420 */
- .hdiv = 2,
- .vdiv = 2,
- },
-};
-
-static const struct rkisp1_rsz_yuv_mbus_info *rkisp1_rsz_get_yuv_mbus_info(u32 mbus_code)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(rkisp1_rsz_yuv_src_formats); i++) {
- if (rkisp1_rsz_yuv_src_formats[i].mbus_code == mbus_code)
- return &rkisp1_rsz_yuv_src_formats[i];
- }
-
- return NULL;
-}
-
-enum rkisp1_shadow_regs_when {
- RKISP1_SHADOW_REGS_SYNC,
- RKISP1_SHADOW_REGS_ASYNC,
-};
-
-struct rkisp1_rsz_config {
- /* constrains */
- const int max_rsz_width;
- const int max_rsz_height;
- const int min_rsz_width;
- const int min_rsz_height;
- /* registers */
- struct {
- u32 ctrl;
- u32 ctrl_shd;
- u32 scale_hy;
- u32 scale_hcr;
- u32 scale_hcb;
- u32 scale_vy;
- u32 scale_vc;
- u32 scale_lut;
- u32 scale_lut_addr;
- u32 scale_hy_shd;
- u32 scale_hcr_shd;
- u32 scale_hcb_shd;
- u32 scale_vy_shd;
- u32 scale_vc_shd;
- u32 phase_hy;
- u32 phase_hc;
- u32 phase_vy;
- u32 phase_vc;
- u32 phase_hy_shd;
- u32 phase_hc_shd;
- u32 phase_vy_shd;
- u32 phase_vc_shd;
- } rsz;
- struct {
- u32 ctrl;
- u32 yuvmode_mask;
- u32 rawmode_mask;
- u32 h_offset;
- u32 v_offset;
- u32 h_size;
- u32 v_size;
- } dual_crop;
-};
-
-static const struct rkisp1_rsz_config rkisp1_rsz_config_mp = {
- /* constraints */
- .max_rsz_width = RKISP1_RSZ_MP_SRC_MAX_WIDTH,
- .max_rsz_height = RKISP1_RSZ_MP_SRC_MAX_HEIGHT,
- .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
- .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
- /* registers */
- .rsz = {
- .ctrl = RKISP1_CIF_MRSZ_CTRL,
- .scale_hy = RKISP1_CIF_MRSZ_SCALE_HY,
- .scale_hcr = RKISP1_CIF_MRSZ_SCALE_HCR,
- .scale_hcb = RKISP1_CIF_MRSZ_SCALE_HCB,
- .scale_vy = RKISP1_CIF_MRSZ_SCALE_VY,
- .scale_vc = RKISP1_CIF_MRSZ_SCALE_VC,
- .scale_lut = RKISP1_CIF_MRSZ_SCALE_LUT,
- .scale_lut_addr = RKISP1_CIF_MRSZ_SCALE_LUT_ADDR,
- .scale_hy_shd = RKISP1_CIF_MRSZ_SCALE_HY_SHD,
- .scale_hcr_shd = RKISP1_CIF_MRSZ_SCALE_HCR_SHD,
- .scale_hcb_shd = RKISP1_CIF_MRSZ_SCALE_HCB_SHD,
- .scale_vy_shd = RKISP1_CIF_MRSZ_SCALE_VY_SHD,
- .scale_vc_shd = RKISP1_CIF_MRSZ_SCALE_VC_SHD,
- .phase_hy = RKISP1_CIF_MRSZ_PHASE_HY,
- .phase_hc = RKISP1_CIF_MRSZ_PHASE_HC,
- .phase_vy = RKISP1_CIF_MRSZ_PHASE_VY,
- .phase_vc = RKISP1_CIF_MRSZ_PHASE_VC,
- .ctrl_shd = RKISP1_CIF_MRSZ_CTRL_SHD,
- .phase_hy_shd = RKISP1_CIF_MRSZ_PHASE_HY_SHD,
- .phase_hc_shd = RKISP1_CIF_MRSZ_PHASE_HC_SHD,
- .phase_vy_shd = RKISP1_CIF_MRSZ_PHASE_VY_SHD,
- .phase_vc_shd = RKISP1_CIF_MRSZ_PHASE_VC_SHD,
- },
- .dual_crop = {
- .ctrl = RKISP1_CIF_DUAL_CROP_CTRL,
- .yuvmode_mask = RKISP1_CIF_DUAL_CROP_MP_MODE_YUV,
- .rawmode_mask = RKISP1_CIF_DUAL_CROP_MP_MODE_RAW,
- .h_offset = RKISP1_CIF_DUAL_CROP_M_H_OFFS,
- .v_offset = RKISP1_CIF_DUAL_CROP_M_V_OFFS,
- .h_size = RKISP1_CIF_DUAL_CROP_M_H_SIZE,
- .v_size = RKISP1_CIF_DUAL_CROP_M_V_SIZE,
- },
-};
-
-static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = {
- /* constraints */
- .max_rsz_width = RKISP1_RSZ_SP_SRC_MAX_WIDTH,
- .max_rsz_height = RKISP1_RSZ_SP_SRC_MAX_HEIGHT,
- .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH,
- .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT,
- /* registers */
- .rsz = {
- .ctrl = RKISP1_CIF_SRSZ_CTRL,
- .scale_hy = RKISP1_CIF_SRSZ_SCALE_HY,
- .scale_hcr = RKISP1_CIF_SRSZ_SCALE_HCR,
- .scale_hcb = RKISP1_CIF_SRSZ_SCALE_HCB,
- .scale_vy = RKISP1_CIF_SRSZ_SCALE_VY,
- .scale_vc = RKISP1_CIF_SRSZ_SCALE_VC,
- .scale_lut = RKISP1_CIF_SRSZ_SCALE_LUT,
- .scale_lut_addr = RKISP1_CIF_SRSZ_SCALE_LUT_ADDR,
- .scale_hy_shd = RKISP1_CIF_SRSZ_SCALE_HY_SHD,
- .scale_hcr_shd = RKISP1_CIF_SRSZ_SCALE_HCR_SHD,
- .scale_hcb_shd = RKISP1_CIF_SRSZ_SCALE_HCB_SHD,
- .scale_vy_shd = RKISP1_CIF_SRSZ_SCALE_VY_SHD,
- .scale_vc_shd = RKISP1_CIF_SRSZ_SCALE_VC_SHD,
- .phase_hy = RKISP1_CIF_SRSZ_PHASE_HY,
- .phase_hc = RKISP1_CIF_SRSZ_PHASE_HC,
- .phase_vy = RKISP1_CIF_SRSZ_PHASE_VY,
- .phase_vc = RKISP1_CIF_SRSZ_PHASE_VC,
- .ctrl_shd = RKISP1_CIF_SRSZ_CTRL_SHD,
- .phase_hy_shd = RKISP1_CIF_SRSZ_PHASE_HY_SHD,
- .phase_hc_shd = RKISP1_CIF_SRSZ_PHASE_HC_SHD,
- .phase_vy_shd = RKISP1_CIF_SRSZ_PHASE_VY_SHD,
- .phase_vc_shd = RKISP1_CIF_SRSZ_PHASE_VC_SHD,
- },
- .dual_crop = {
- .ctrl = RKISP1_CIF_DUAL_CROP_CTRL,
- .yuvmode_mask = RKISP1_CIF_DUAL_CROP_SP_MODE_YUV,
- .rawmode_mask = RKISP1_CIF_DUAL_CROP_SP_MODE_RAW,
- .h_offset = RKISP1_CIF_DUAL_CROP_S_H_OFFS,
- .v_offset = RKISP1_CIF_DUAL_CROP_S_V_OFFS,
- .h_size = RKISP1_CIF_DUAL_CROP_S_H_SIZE,
- .v_size = RKISP1_CIF_DUAL_CROP_S_V_SIZE,
- },
-};
-
-static struct v4l2_mbus_framefmt *
-rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz,
- struct v4l2_subdev_pad_config *cfg,
- unsigned int pad, u32 which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_format(&rsz->sd, cfg, pad);
- else
- return v4l2_subdev_get_try_format(&rsz->sd, rsz->pad_cfg, pad);
-}
-
-static struct v4l2_rect *
-rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz,
- struct v4l2_subdev_pad_config *cfg,
- unsigned int pad, u32 which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return v4l2_subdev_get_try_crop(&rsz->sd, cfg, pad);
- else
- return v4l2_subdev_get_try_crop(&rsz->sd, rsz->pad_cfg, pad);
-}
-
-/* ----------------------------------------------------------------------------
- * Dual crop hw configs
- */
-
-static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
- enum rkisp1_shadow_regs_when when)
-{
- u32 dc_ctrl = rkisp1_read(rsz->rkisp1, rsz->config->dual_crop.ctrl);
- u32 mask = ~(rsz->config->dual_crop.yuvmode_mask |
- rsz->config->dual_crop.rawmode_mask);
-
- dc_ctrl &= mask;
- if (when == RKISP1_SHADOW_REGS_ASYNC)
- dc_ctrl |= RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD;
- else
- dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
- rkisp1_write(rsz->rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
-}
-
-/* configure dual-crop unit */
-static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz)
-{
- struct rkisp1_device *rkisp1 = rsz->rkisp1;
- struct v4l2_mbus_framefmt *sink_fmt;
- struct v4l2_rect *sink_crop;
- u32 dc_ctrl;
-
- sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
- V4L2_SUBDEV_FORMAT_ACTIVE);
-
- if (sink_crop->width == sink_fmt->width &&
- sink_crop->height == sink_fmt->height &&
- sink_crop->left == 0 && sink_crop->top == 0) {
- rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_SYNC);
- dev_dbg(rkisp1->dev, "capture %d crop disabled\n", rsz->id);
- return;
- }
-
- dc_ctrl = rkisp1_read(rkisp1, rsz->config->dual_crop.ctrl);
- rkisp1_write(rkisp1, sink_crop->left, rsz->config->dual_crop.h_offset);
- rkisp1_write(rkisp1, sink_crop->top, rsz->config->dual_crop.v_offset);
- rkisp1_write(rkisp1, sink_crop->width, rsz->config->dual_crop.h_size);
- rkisp1_write(rkisp1, sink_crop->height, rsz->config->dual_crop.v_size);
- dc_ctrl |= rsz->config->dual_crop.yuvmode_mask;
- dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD;
- rkisp1_write(rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl);
-
- dev_dbg(rkisp1->dev, "stream %d crop: %dx%d -> %dx%d\n", rsz->id,
- sink_fmt->width, sink_fmt->height,
- sink_crop->width, sink_crop->height);
-}
-
-/* ----------------------------------------------------------------------------
- * Resizer hw configs
- */
-
-static void rkisp1_rsz_dump_regs(struct rkisp1_resizer *rsz)
-{
- dev_dbg(rsz->rkisp1->dev,
- "RSZ_CTRL 0x%08x/0x%08x\n"
- "RSZ_SCALE_HY %d/%d\n"
- "RSZ_SCALE_HCB %d/%d\n"
- "RSZ_SCALE_HCR %d/%d\n"
- "RSZ_SCALE_VY %d/%d\n"
- "RSZ_SCALE_VC %d/%d\n"
- "RSZ_PHASE_HY %d/%d\n"
- "RSZ_PHASE_HC %d/%d\n"
- "RSZ_PHASE_VY %d/%d\n"
- "RSZ_PHASE_VC %d/%d\n",
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy_shd),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc),
- rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc_shd));
-}
-
-static void rkisp1_rsz_update_shadow(struct rkisp1_resizer *rsz,
- enum rkisp1_shadow_regs_when when)
-{
- u32 ctrl_cfg = rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl);
-
- if (when == RKISP1_SHADOW_REGS_ASYNC)
- ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO;
- else
- ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD;
-
- rkisp1_write(rsz->rkisp1, ctrl_cfg, rsz->config->rsz.ctrl);
-}
-
-static u32 rkisp1_rsz_calc_ratio(u32 len_sink, u32 len_src)
-{
- if (len_sink < len_src)
- return ((len_sink - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
- (len_src - 1);
-
- return ((len_src - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) /
- (len_sink - 1) + 1;
-}
-
-static void rkisp1_rsz_disable(struct rkisp1_resizer *rsz,
- enum rkisp1_shadow_regs_when when)
-{
- rkisp1_write(rsz->rkisp1, 0, rsz->config->rsz.ctrl);
-
- if (when == RKISP1_SHADOW_REGS_SYNC)
- rkisp1_rsz_update_shadow(rsz, when);
-}
-
-static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
- struct v4l2_rect *sink_y,
- struct v4l2_rect *sink_c,
- struct v4l2_rect *src_y,
- struct v4l2_rect *src_c,
- enum rkisp1_shadow_regs_when when)
-{
- struct rkisp1_device *rkisp1 = rsz->rkisp1;
- u32 ratio, rsz_ctrl = 0;
- unsigned int i;
-
- /* No phase offset */
- rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hy);
- rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hc);
- rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vy);
- rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vc);
-
- /* Linear interpolation */
- for (i = 0; i < 64; i++) {
- rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut_addr);
- rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut);
- }
-
- if (sink_y->width != src_y->width) {
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE;
- if (sink_y->width < src_y->width)
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP;
- ratio = rkisp1_rsz_calc_ratio(sink_y->width, src_y->width);
- rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hy);
- }
-
- if (sink_c->width != src_c->width) {
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE;
- if (sink_c->width < src_c->width)
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP;
- ratio = rkisp1_rsz_calc_ratio(sink_c->width, src_c->width);
- rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcb);
- rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcr);
- }
-
- if (sink_y->height != src_y->height) {
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE;
- if (sink_y->height < src_y->height)
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP;
- ratio = rkisp1_rsz_calc_ratio(sink_y->height, src_y->height);
- rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vy);
- }
-
- if (sink_c->height != src_c->height) {
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE;
- if (sink_c->height < src_c->height)
- rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP;
- ratio = rkisp1_rsz_calc_ratio(sink_c->height, src_c->height);
- rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vc);
- }
-
- rkisp1_write(rkisp1, rsz_ctrl, rsz->config->rsz.ctrl);
-
- rkisp1_rsz_update_shadow(rsz, when);
-}
-
-static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
- enum rkisp1_shadow_regs_when when)
-{
- const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info;
- struct v4l2_rect sink_y, sink_c, src_y, src_c;
- struct v4l2_mbus_framefmt *src_fmt, *sink_fmt;
- struct v4l2_rect *sink_crop;
-
- sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code);
- sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- sink_yuv_info = rkisp1_rsz_get_yuv_mbus_info(sink_fmt->code);
-
- /*
- * The resizer only works on yuv formats,
- * so return if it is bayer format.
- */
- if (rsz->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
- rkisp1_rsz_disable(rsz, when);
- return;
- }
-
- sink_y.width = sink_crop->width;
- sink_y.height = sink_crop->height;
- src_y.width = src_fmt->width;
- src_y.height = src_fmt->height;
-
- sink_c.width = sink_y.width / sink_yuv_info->hdiv;
- sink_c.height = sink_y.height / sink_yuv_info->vdiv;
-
- /*
- * The resizer is used not only to change the dimensions of the frame
- * but also to change the scale for YUV formats,
- * (4:2:2 -> 4:2:0 for example). So the width/height of the CbCr
- * streams should be set according to the media bus format in the src pad.
- */
- src_c.width = src_y.width / src_yuv_info->hdiv;
- src_c.height = src_y.height / src_yuv_info->vdiv;
-
- if (sink_c.width == src_c.width && sink_c.height == src_c.height) {
- rkisp1_rsz_disable(rsz, when);
- return;
- }
-
- dev_dbg(rsz->rkisp1->dev, "stream %d rsz/scale: %dx%d -> %dx%d\n",
- rsz->id, sink_crop->width, sink_crop->height,
- src_fmt->width, src_fmt->height);
- dev_dbg(rsz->rkisp1->dev, "chroma scaling %dx%d -> %dx%d\n",
- sink_c.width, sink_c.height, src_c.width, src_c.height);
-
- /* set values in the hw */
- rkisp1_rsz_config_regs(rsz, &sink_y, &sink_c, &src_y, &src_c, when);
-
- rkisp1_rsz_dump_regs(rsz);
-}
-
-/* ----------------------------------------------------------------------------
- * Subdev pad operations
- */
-
-static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct rkisp1_resizer *rsz =
- container_of(sd, struct rkisp1_resizer, sd);
- struct v4l2_subdev_pad_config dummy_cfg;
- u32 pad = code->pad;
- int ret;
-
- if (code->pad == RKISP1_RSZ_PAD_SRC) {
- /* supported mbus codes on the src are the same as in the capture */
- struct rkisp1_capture *cap = &rsz->rkisp1->capture_devs[rsz->id];
-
- return rkisp1_cap_enum_mbus_codes(cap, code);
- }
-
- /*
- * The selfpath capture doesn't support bayer formats. Therefore the selfpath resizer
- * should support only YUV422 on the sink pad
- */
- if (rsz->id == RKISP1_SELFPATH) {
- if (code->index > 0)
- return -EINVAL;
- code->code = MEDIA_BUS_FMT_YUYV8_2X8;
- return 0;
- }
-
- /* supported mbus codes on the sink pad are the same as isp src pad */
- code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO;
- ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code,
- &dummy_cfg, code);
-
- /* restore pad */
- code->pad = pad;
- code->flags = 0;
- return ret;
-}
-
-static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg)
-{
- struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
- struct v4l2_rect *sink_crop;
-
- sink_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SRC);
- sink_fmt->width = RKISP1_DEFAULT_WIDTH;
- sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
- sink_fmt->field = V4L2_FIELD_NONE;
- sink_fmt->code = RKISP1_DEF_FMT;
-
- sink_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_RSZ_PAD_SINK);
- sink_crop->width = RKISP1_DEFAULT_WIDTH;
- sink_crop->height = RKISP1_DEFAULT_HEIGHT;
- sink_crop->left = 0;
- sink_crop->top = 0;
-
- src_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SINK);
- *src_fmt = *sink_fmt;
-
- /* NOTE: there is no crop in the source pad, only in the sink */
-
- return 0;
-}
-
-static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_mbus_framefmt *format,
- unsigned int which)
-{
- const struct rkisp1_isp_mbus_info *mbus_info;
- struct v4l2_mbus_framefmt *src_fmt;
-
- src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
- mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code);
-
- /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */
- if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
- rkisp1_rsz_get_yuv_mbus_info(format->code))
- src_fmt->code = format->code;
-
- src_fmt->width = clamp_t(u32, format->width,
- rsz->config->min_rsz_width,
- rsz->config->max_rsz_width);
- src_fmt->height = clamp_t(u32, format->height,
- rsz->config->min_rsz_height,
- rsz->config->max_rsz_height);
-
- *format = *src_fmt;
-}
-
-static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_rect *r,
- unsigned int which)
-{
- const struct rkisp1_isp_mbus_info *mbus_info;
- struct v4l2_mbus_framefmt *sink_fmt;
- struct v4l2_rect *sink_crop;
-
- sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
- sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
- which);
-
- /* Not crop for MP bayer raw data */
- mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
-
- if (rsz->id == RKISP1_MAINPATH &&
- mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
- sink_crop->left = 0;
- sink_crop->top = 0;
- sink_crop->width = sink_fmt->width;
- sink_crop->height = sink_fmt->height;
-
- *r = *sink_crop;
- return;
- }
-
- sink_crop->left = ALIGN(r->left, 2);
- sink_crop->width = ALIGN(r->width, 2);
- sink_crop->top = r->top;
- sink_crop->height = r->height;
- rkisp1_sd_adjust_crop(sink_crop, sink_fmt);
-
- *r = *sink_crop;
-}
-
-static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_mbus_framefmt *format,
- unsigned int which)
-{
- const struct rkisp1_isp_mbus_info *mbus_info;
- struct v4l2_mbus_framefmt *sink_fmt, *src_fmt;
- struct v4l2_rect *sink_crop;
-
- sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which);
- src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which);
- sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
- which);
- if (rsz->id == RKISP1_SELFPATH)
- sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
- else
- sink_fmt->code = format->code;
-
- mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
- if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
- sink_fmt->code = RKISP1_DEF_FMT;
- mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code);
- }
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
- rsz->pixel_enc = mbus_info->pixel_enc;
-
- /* Propagete to source pad */
- src_fmt->code = sink_fmt->code;
-
- sink_fmt->width = clamp_t(u32, format->width,
- RKISP1_ISP_MIN_WIDTH,
- RKISP1_ISP_MAX_WIDTH);
- sink_fmt->height = clamp_t(u32, format->height,
- RKISP1_ISP_MIN_HEIGHT,
- RKISP1_ISP_MAX_HEIGHT);
-
- *format = *sink_fmt;
-
- /* Update sink crop */
- rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which);
-}
-
-static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct rkisp1_resizer *rsz =
- container_of(sd, struct rkisp1_resizer, sd);
-
- mutex_lock(&rsz->ops_lock);
- fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which);
- mutex_unlock(&rsz->ops_lock);
- return 0;
-}
-
-static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct rkisp1_resizer *rsz =
- container_of(sd, struct rkisp1_resizer, sd);
-
- mutex_lock(&rsz->ops_lock);
- if (fmt->pad == RKISP1_RSZ_PAD_SINK)
- rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which);
- else
- rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which);
-
- mutex_unlock(&rsz->ops_lock);
- return 0;
-}
-
-static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_selection *sel)
-{
- struct rkisp1_resizer *rsz =
- container_of(sd, struct rkisp1_resizer, sd);
- struct v4l2_mbus_framefmt *mf_sink;
- int ret = 0;
-
- if (sel->pad == RKISP1_RSZ_PAD_SRC)
- return -EINVAL;
-
- mutex_lock(&rsz->ops_lock);
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP_BOUNDS:
- mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK,
- sel->which);
- sel->r.height = mf_sink->height;
- sel->r.width = mf_sink->width;
- sel->r.left = 0;
- sel->r.top = 0;
- break;
- case V4L2_SEL_TGT_CROP:
- sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK,
- sel->which);
- break;
- default:
- ret = -EINVAL;
- }
-
- mutex_unlock(&rsz->ops_lock);
- return ret;
-}
-
-static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_selection *sel)
-{
- struct rkisp1_resizer *rsz =
- container_of(sd, struct rkisp1_resizer, sd);
-
- if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC)
- return -EINVAL;
-
- dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__,
- sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
-
- mutex_lock(&rsz->ops_lock);
- rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which);
- mutex_unlock(&rsz->ops_lock);
-
- return 0;
-}
-
-static const struct media_entity_operations rkisp1_rsz_media_ops = {
- .link_validate = v4l2_subdev_link_validate,
-};
-
-static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = {
- .enum_mbus_code = rkisp1_rsz_enum_mbus_code,
- .get_selection = rkisp1_rsz_get_selection,
- .set_selection = rkisp1_rsz_set_selection,
- .init_cfg = rkisp1_rsz_init_config,
- .get_fmt = rkisp1_rsz_get_fmt,
- .set_fmt = rkisp1_rsz_set_fmt,
- .link_validate = v4l2_subdev_link_validate_default,
-};
-
-/* ----------------------------------------------------------------------------
- * Stream operations
- */
-
-static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct rkisp1_resizer *rsz =
- container_of(sd, struct rkisp1_resizer, sd);
- struct rkisp1_device *rkisp1 = rsz->rkisp1;
- struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1];
- enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC;
-
- if (!enable) {
- rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
- rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
- return 0;
- }
-
- if (other->is_streaming)
- when = RKISP1_SHADOW_REGS_ASYNC;
-
- mutex_lock(&rsz->ops_lock);
- rkisp1_rsz_config(rsz, when);
- rkisp1_dcrop_config(rsz);
-
- mutex_unlock(&rsz->ops_lock);
- return 0;
-}
-
-static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = {
- .s_stream = rkisp1_rsz_s_stream,
-};
-
-static const struct v4l2_subdev_ops rkisp1_rsz_ops = {
- .video = &rkisp1_rsz_video_ops,
- .pad = &rkisp1_rsz_pad_ops,
-};
-
-static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz)
-{
- v4l2_device_unregister_subdev(&rsz->sd);
- media_entity_cleanup(&rsz->sd.entity);
-}
-
-static int rkisp1_rsz_register(struct rkisp1_resizer *rsz)
-{
- static const char * const dev_names[] = {
- RKISP1_RSZ_MP_DEV_NAME,
- RKISP1_RSZ_SP_DEV_NAME
- };
- struct media_pad *pads = rsz->pads;
- struct v4l2_subdev *sd = &rsz->sd;
- int ret;
-
- if (rsz->id == RKISP1_SELFPATH)
- rsz->config = &rkisp1_rsz_config_sp;
- else
- rsz->config = &rkisp1_rsz_config_mp;
-
- v4l2_subdev_init(sd, &rkisp1_rsz_ops);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- sd->entity.ops = &rkisp1_rsz_media_ops;
- sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
- sd->owner = THIS_MODULE;
- strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name));
-
- pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
- MEDIA_PAD_FL_MUST_CONNECT;
- pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE |
- MEDIA_PAD_FL_MUST_CONNECT;
-
- rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC;
-
- mutex_init(&rsz->ops_lock);
- ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads);
- if (ret)
- return ret;
-
- ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd);
- if (ret) {
- dev_err(sd->dev, "Failed to register resizer subdev\n");
- goto err_cleanup_media_entity;
- }
-
- rkisp1_rsz_init_config(sd, rsz->pad_cfg);
- return 0;
-
-err_cleanup_media_entity:
- media_entity_cleanup(&sd->entity);
-
- return ret;
-}
-
-int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_resizer *rsz;
- unsigned int i, j;
- int ret;
-
- for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
- rsz = &rkisp1->resizer_devs[i];
- rsz->rkisp1 = rkisp1;
- rsz->id = i;
- ret = rkisp1_rsz_register(rsz);
- if (ret)
- goto err_unreg_resizer_devs;
- }
-
- return 0;
-
-err_unreg_resizer_devs:
- for (j = 0; j < i; j++) {
- rsz = &rkisp1->resizer_devs[j];
- rkisp1_rsz_unregister(rsz);
- }
-
- return ret;
-}
-
-void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH];
- struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH];
-
- rkisp1_rsz_unregister(mp);
- rkisp1_rsz_unregister(sp);
-}
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Rockchip ISP1 Driver - Stats subdevice
- *
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-vmalloc.h> /* for ISP statistics */
-
-#include "rkisp1-common.h"
-
-#define RKISP1_STATS_DEV_NAME RKISP1_DRIVER_NAME "_stats"
-
-#define RKISP1_ISP_STATS_REQ_BUFS_MIN 2
-#define RKISP1_ISP_STATS_REQ_BUFS_MAX 8
-
-static int rkisp1_stats_enum_fmt_meta_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct video_device *video = video_devdata(file);
- struct rkisp1_stats *stats = video_get_drvdata(video);
-
- if (f->index > 0 || f->type != video->queue->type)
- return -EINVAL;
-
- f->pixelformat = stats->vdev_fmt.fmt.meta.dataformat;
- return 0;
-}
-
-static int rkisp1_stats_g_fmt_meta_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct video_device *video = video_devdata(file);
- struct rkisp1_stats *stats = video_get_drvdata(video);
- struct v4l2_meta_format *meta = &f->fmt.meta;
-
- if (f->type != video->queue->type)
- return -EINVAL;
-
- memset(meta, 0, sizeof(*meta));
- meta->dataformat = stats->vdev_fmt.fmt.meta.dataformat;
- meta->buffersize = stats->vdev_fmt.fmt.meta.buffersize;
-
- return 0;
-}
-
-static int rkisp1_stats_querycap(struct file *file,
- void *priv, struct v4l2_capability *cap)
-{
- struct video_device *vdev = video_devdata(file);
-
- strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver));
- strscpy(cap->card, vdev->name, sizeof(cap->card));
- strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info));
-
- return 0;
-}
-
-/* ISP video device IOCTLs */
-static const struct v4l2_ioctl_ops rkisp1_stats_ioctl = {
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_expbuf = vb2_ioctl_expbuf,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_enum_fmt_meta_cap = rkisp1_stats_enum_fmt_meta_cap,
- .vidioc_g_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
- .vidioc_s_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
- .vidioc_try_fmt_meta_cap = rkisp1_stats_g_fmt_meta_cap,
- .vidioc_querycap = rkisp1_stats_querycap,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static const struct v4l2_file_operations rkisp1_stats_fops = {
- .mmap = vb2_fop_mmap,
- .unlocked_ioctl = video_ioctl2,
- .poll = vb2_fop_poll,
- .open = v4l2_fh_open,
- .release = vb2_fop_release
-};
-
-static int rkisp1_stats_vb2_queue_setup(struct vb2_queue *vq,
- unsigned int *num_buffers,
- unsigned int *num_planes,
- unsigned int sizes[],
- struct device *alloc_devs[])
-{
- *num_planes = 1;
-
- *num_buffers = clamp_t(u32, *num_buffers, RKISP1_ISP_STATS_REQ_BUFS_MIN,
- RKISP1_ISP_STATS_REQ_BUFS_MAX);
-
- sizes[0] = sizeof(struct rkisp1_stat_buffer);
-
- return 0;
-}
-
-static void rkisp1_stats_vb2_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct rkisp1_buffer *stats_buf =
- container_of(vbuf, struct rkisp1_buffer, vb);
- struct vb2_queue *vq = vb->vb2_queue;
- struct rkisp1_stats *stats_dev = vq->drv_priv;
-
- stats_buf->vaddr = vb2_plane_vaddr(vb, 0);
-
- spin_lock_irq(&stats_dev->lock);
- list_add_tail(&stats_buf->queue, &stats_dev->stat);
- spin_unlock_irq(&stats_dev->lock);
-}
-
-static int rkisp1_stats_vb2_buf_prepare(struct vb2_buffer *vb)
-{
- if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_stat_buffer))
- return -EINVAL;
-
- vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_stat_buffer));
-
- return 0;
-}
-
-static void rkisp1_stats_vb2_stop_streaming(struct vb2_queue *vq)
-{
- struct rkisp1_stats *stats = vq->drv_priv;
- struct rkisp1_buffer *buf;
- unsigned int i;
-
- spin_lock_irq(&stats->lock);
- for (i = 0; i < RKISP1_ISP_STATS_REQ_BUFS_MAX; i++) {
- if (list_empty(&stats->stat))
- break;
- buf = list_first_entry(&stats->stat,
- struct rkisp1_buffer, queue);
- list_del(&buf->queue);
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- }
- spin_unlock_irq(&stats->lock);
-}
-
-static const struct vb2_ops rkisp1_stats_vb2_ops = {
- .queue_setup = rkisp1_stats_vb2_queue_setup,
- .buf_queue = rkisp1_stats_vb2_buf_queue,
- .buf_prepare = rkisp1_stats_vb2_buf_prepare,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .stop_streaming = rkisp1_stats_vb2_stop_streaming,
-};
-
-static int
-rkisp1_stats_init_vb2_queue(struct vb2_queue *q, struct rkisp1_stats *stats)
-{
- struct rkisp1_vdev_node *node;
-
- node = container_of(q, struct rkisp1_vdev_node, buf_queue);
-
- q->type = V4L2_BUF_TYPE_META_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
- q->drv_priv = stats;
- q->ops = &rkisp1_stats_vb2_ops;
- q->mem_ops = &vb2_vmalloc_memops;
- q->buf_struct_size = sizeof(struct rkisp1_buffer);
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &node->vlock;
-
- return vb2_queue_init(q);
-}
-
-static void rkisp1_stats_get_awb_meas(struct rkisp1_stats *stats,
- struct rkisp1_stat_buffer *pbuf)
-{
- /* Protect against concurrent access from ISR? */
- struct rkisp1_device *rkisp1 = stats->rkisp1;
- u32 reg_val;
-
- pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AWB;
- reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_WHITE_CNT);
- pbuf->params.awb.awb_mean[0].cnt =
- RKISP1_CIF_ISP_AWB_GET_PIXEL_CNT(reg_val);
- reg_val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AWB_MEAN);
-
- pbuf->params.awb.awb_mean[0].mean_cr_or_r =
- RKISP1_CIF_ISP_AWB_GET_MEAN_CR_R(reg_val);
- pbuf->params.awb.awb_mean[0].mean_cb_or_b =
- RKISP1_CIF_ISP_AWB_GET_MEAN_CB_B(reg_val);
- pbuf->params.awb.awb_mean[0].mean_y_or_g =
- RKISP1_CIF_ISP_AWB_GET_MEAN_Y_G(reg_val);
-}
-
-static void rkisp1_stats_get_aec_meas(struct rkisp1_stats *stats,
- struct rkisp1_stat_buffer *pbuf)
-{
- struct rkisp1_device *rkisp1 = stats->rkisp1;
- unsigned int i;
-
- pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AUTOEXP;
- for (i = 0; i < RKISP1_CIF_ISP_AE_MEAN_MAX; i++)
- pbuf->params.ae.exp_mean[i] =
- (u8)rkisp1_read(rkisp1,
- RKISP1_CIF_ISP_EXP_MEAN_00 + i * 4);
-}
-
-static void rkisp1_stats_get_afc_meas(struct rkisp1_stats *stats,
- struct rkisp1_stat_buffer *pbuf)
-{
- struct rkisp1_device *rkisp1 = stats->rkisp1;
- struct rkisp1_cif_isp_af_stat *af;
-
- pbuf->meas_type |= RKISP1_CIF_ISP_STAT_AFM;
-
- af = &pbuf->params.af;
- af->window[0].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_A);
- af->window[0].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_A);
- af->window[1].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_B);
- af->window[1].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_B);
- af->window[2].sum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_SUM_C);
- af->window[2].lum = rkisp1_read(rkisp1, RKISP1_CIF_ISP_AFM_LUM_C);
-}
-
-static void rkisp1_stats_get_hst_meas(struct rkisp1_stats *stats,
- struct rkisp1_stat_buffer *pbuf)
-{
- struct rkisp1_device *rkisp1 = stats->rkisp1;
- unsigned int i;
-
- pbuf->meas_type |= RKISP1_CIF_ISP_STAT_HIST;
- for (i = 0; i < RKISP1_CIF_ISP_HIST_BIN_N_MAX; i++)
- pbuf->params.hist.hist_bins[i] =
- (u8)rkisp1_read(rkisp1,
- RKISP1_CIF_ISP_HIST_BIN_0 + i * 4);
-}
-
-static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats,
- struct rkisp1_stat_buffer *pbuf)
-{
- struct rkisp1_device *rkisp1 = stats->rkisp1;
- const struct rkisp1_isp_mbus_info *in_fmt = rkisp1->isp.sink_fmt;
- struct rkisp1_cif_isp_bls_meas_val *bls_val;
-
- bls_val = &pbuf->params.ae.bls_val;
- if (in_fmt->bayer_pat == RKISP1_RAW_BGGR) {
- bls_val->meas_b =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
- bls_val->meas_gb =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
- bls_val->meas_gr =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
- bls_val->meas_r =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
- } else if (in_fmt->bayer_pat == RKISP1_RAW_GBRG) {
- bls_val->meas_gb =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
- bls_val->meas_b =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
- bls_val->meas_r =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
- bls_val->meas_gr =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
- } else if (in_fmt->bayer_pat == RKISP1_RAW_GRBG) {
- bls_val->meas_gr =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
- bls_val->meas_r =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
- bls_val->meas_b =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
- bls_val->meas_gb =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
- } else if (in_fmt->bayer_pat == RKISP1_RAW_RGGB) {
- bls_val->meas_r =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED);
- bls_val->meas_gr =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED);
- bls_val->meas_gb =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED);
- bls_val->meas_b =
- rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED);
- }
-}
-
-static void
-rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris)
-{
- struct rkisp1_stat_buffer *cur_stat_buf;
- struct rkisp1_buffer *cur_buf = NULL;
- unsigned int frame_sequence = stats->rkisp1->isp.frame_sequence;
- u64 timestamp = ktime_get_ns();
-
- /* get one empty buffer */
- if (!list_empty(&stats->stat)) {
- cur_buf = list_first_entry(&stats->stat,
- struct rkisp1_buffer, queue);
- list_del(&cur_buf->queue);
- }
-
- if (!cur_buf)
- return;
-
- cur_stat_buf =
- (struct rkisp1_stat_buffer *)(cur_buf->vaddr);
-
- if (isp_ris & RKISP1_CIF_ISP_AWB_DONE)
- rkisp1_stats_get_awb_meas(stats, cur_stat_buf);
-
- if (isp_ris & RKISP1_CIF_ISP_AFM_FIN)
- rkisp1_stats_get_afc_meas(stats, cur_stat_buf);
-
- if (isp_ris & RKISP1_CIF_ISP_EXP_END) {
- rkisp1_stats_get_aec_meas(stats, cur_stat_buf);
- rkisp1_stats_get_bls_meas(stats, cur_stat_buf);
- }
-
- if (isp_ris & RKISP1_CIF_ISP_HIST_MEASURE_RDY)
- rkisp1_stats_get_hst_meas(stats, cur_stat_buf);
-
- vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0,
- sizeof(struct rkisp1_stat_buffer));
- cur_buf->vb.sequence = frame_sequence;
- cur_buf->vb.vb2_buf.timestamp = timestamp;
- vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-}
-
-void rkisp1_stats_isr(struct rkisp1_stats *stats, u32 isp_ris)
-{
- struct rkisp1_device *rkisp1 = stats->rkisp1;
- unsigned int isp_mis_tmp = 0;
-
- spin_lock(&stats->lock);
-
- rkisp1_write(rkisp1, RKISP1_STATS_MEAS_MASK, RKISP1_CIF_ISP_ICR);
-
- isp_mis_tmp = rkisp1_read(rkisp1, RKISP1_CIF_ISP_MIS);
- if (isp_mis_tmp & RKISP1_STATS_MEAS_MASK)
- rkisp1->debug.stats_error++;
-
- if (isp_ris & RKISP1_STATS_MEAS_MASK)
- rkisp1_stats_send_measurement(stats, isp_ris);
-
- spin_unlock(&stats->lock);
-}
-
-static void rkisp1_init_stats(struct rkisp1_stats *stats)
-{
- stats->vdev_fmt.fmt.meta.dataformat =
- V4L2_META_FMT_RK_ISP1_STAT_3A;
- stats->vdev_fmt.fmt.meta.buffersize =
- sizeof(struct rkisp1_stat_buffer);
-}
-
-int rkisp1_stats_register(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_stats *stats = &rkisp1->stats;
- struct rkisp1_vdev_node *node = &stats->vnode;
- struct video_device *vdev = &node->vdev;
- int ret;
-
- stats->rkisp1 = rkisp1;
- mutex_init(&node->vlock);
- INIT_LIST_HEAD(&stats->stat);
- spin_lock_init(&stats->lock);
-
- strscpy(vdev->name, RKISP1_STATS_DEV_NAME, sizeof(vdev->name));
-
- video_set_drvdata(vdev, stats);
- vdev->ioctl_ops = &rkisp1_stats_ioctl;
- vdev->fops = &rkisp1_stats_fops;
- vdev->release = video_device_release_empty;
- vdev->lock = &node->vlock;
- vdev->v4l2_dev = &rkisp1->v4l2_dev;
- vdev->queue = &node->buf_queue;
- vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
- vdev->vfl_dir = VFL_DIR_RX;
- rkisp1_stats_init_vb2_queue(vdev->queue, stats);
- rkisp1_init_stats(stats);
- video_set_drvdata(vdev, stats);
-
- node->pad.flags = MEDIA_PAD_FL_SINK;
- ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
- if (ret)
- goto err_mutex_destroy;
-
- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
- if (ret) {
- dev_err(&vdev->dev,
- "failed to register %s, ret=%d\n", vdev->name, ret);
- goto err_cleanup_media_entity;
- }
-
- return 0;
-
-err_cleanup_media_entity:
- media_entity_cleanup(&vdev->entity);
-err_mutex_destroy:
- mutex_destroy(&node->vlock);
- return ret;
-}
-
-void rkisp1_stats_unregister(struct rkisp1_device *rkisp1)
-{
- struct rkisp1_stats *stats = &rkisp1->stats;
- struct rkisp1_vdev_node *node = &stats->vnode;
- struct video_device *vdev = &node->vdev;
-
- vb2_video_unregister_device(vdev);
- media_entity_cleanup(&vdev->entity);
- mutex_destroy(&node->vlock);
-}
+++ /dev/null
-/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR MIT) */
-/*
- * Rockchip ISP1 userspace API
- * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
- */
-
-#ifndef _UAPI_RKISP1_CONFIG_H
-#define _UAPI_RKISP1_CONFIG_H
-
-#include <linux/types.h>
-
-/* Defect Pixel Cluster Detection */
-#define RKISP1_CIF_ISP_MODULE_DPCC (1U << 0)
-/* Black Level Subtraction */
-#define RKISP1_CIF_ISP_MODULE_BLS (1U << 1)
-/* Sensor De-gamma */
-#define RKISP1_CIF_ISP_MODULE_SDG (1U << 2)
-/* Histogram */
-#define RKISP1_CIF_ISP_MODULE_HST (1U << 3)
-/* Lens Shade Control */
-#define RKISP1_CIF_ISP_MODULE_LSC (1U << 4)
-/* Auto White Balance Gain */
-#define RKISP1_CIF_ISP_MODULE_AWB_GAIN (1U << 5)
-/* Filter */
-#define RKISP1_CIF_ISP_MODULE_FLT (1U << 6)
-/* Bayer Demosaic */
-#define RKISP1_CIF_ISP_MODULE_BDM (1U << 7)
-/* Cross Talk */
-#define RKISP1_CIF_ISP_MODULE_CTK (1U << 8)
-/* Gamma Out Curve */
-#define RKISP1_CIF_ISP_MODULE_GOC (1U << 9)
-/* Color Processing */
-#define RKISP1_CIF_ISP_MODULE_CPROC (1U << 10)
-/* Auto Focus Control */
-#define RKISP1_CIF_ISP_MODULE_AFC (1U << 11)
-/* Auto White Balancing */
-#define RKISP1_CIF_ISP_MODULE_AWB (1U << 12)
-/* Image Effect */
-#define RKISP1_CIF_ISP_MODULE_IE (1U << 13)
-/* Auto Exposure Control */
-#define RKISP1_CIF_ISP_MODULE_AEC (1U << 14)
-/* Wide Dynamic Range */
-#define RKISP1_CIF_ISP_MODULE_WDR (1U << 15)
-/* Denoise Pre-Filter */
-#define RKISP1_CIF_ISP_MODULE_DPF (1U << 16)
-/* Denoise Pre-Filter Strength */
-#define RKISP1_CIF_ISP_MODULE_DPF_STRENGTH (1U << 17)
-
-#define RKISP1_CIF_ISP_CTK_COEFF_MAX 0x100
-#define RKISP1_CIF_ISP_CTK_OFFSET_MAX 0x800
-
-#define RKISP1_CIF_ISP_AE_MEAN_MAX 25
-#define RKISP1_CIF_ISP_HIST_BIN_N_MAX 16
-#define RKISP1_CIF_ISP_AFM_MAX_WINDOWS 3
-#define RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE 17
-
-#define RKISP1_CIF_ISP_BDM_MAX_TH 0xff
-
-/*
- * Black level compensation
- */
-/* maximum value for horizontal start address */
-#define RKISP1_CIF_ISP_BLS_START_H_MAX 0x00000fff
-/* maximum value for horizontal stop address */
-#define RKISP1_CIF_ISP_BLS_STOP_H_MAX 0x00000fff
-/* maximum value for vertical start address */
-#define RKISP1_CIF_ISP_BLS_START_V_MAX 0x00000fff
-/* maximum value for vertical stop address */
-#define RKISP1_CIF_ISP_BLS_STOP_V_MAX 0x00000fff
-/* maximum is 2^18 = 262144*/
-#define RKISP1_CIF_ISP_BLS_SAMPLES_MAX 0x00000012
-/* maximum value for fixed black level */
-#define RKISP1_CIF_ISP_BLS_FIX_SUB_MAX 0x00000fff
-/* minimum value for fixed black level */
-#define RKISP1_CIF_ISP_BLS_FIX_SUB_MIN 0xfffff000
-/* 13 bit range (signed)*/
-#define RKISP1_CIF_ISP_BLS_FIX_MASK 0x00001fff
-
-/*
- * Automatic white balance measurements
- */
-#define RKISP1_CIF_ISP_AWB_MAX_GRID 1
-#define RKISP1_CIF_ISP_AWB_MAX_FRAMES 7
-
-/*
- * Gamma out
- */
-/* Maximum number of color samples supported */
-#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES 17
-
-/*
- * Lens shade correction
- */
-#define RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE 8
-
-/*
- * The following matches the tuning process,
- * not the max capabilities of the chip.
- */
-#define RKISP1_CIF_ISP_LSC_SAMPLES_MAX 17
-
-/*
- * Histogram calculation
- */
-/* Last 3 values unused. */
-#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 28
-
-/*
- * Defect Pixel Cluster Correction
- */
-#define RKISP1_CIF_ISP_DPCC_METHODS_MAX 3
-
-/*
- * Denoising pre filter
- */
-#define RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS 17
-#define RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS 6
-
-/*
- * Measurement types
- */
-#define RKISP1_CIF_ISP_STAT_AWB (1U << 0)
-#define RKISP1_CIF_ISP_STAT_AUTOEXP (1U << 1)
-#define RKISP1_CIF_ISP_STAT_AFM (1U << 2)
-#define RKISP1_CIF_ISP_STAT_HIST (1U << 3)
-
-enum rkisp1_cif_isp_histogram_mode {
- RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE,
- RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
- RKISP1_CIF_ISP_HISTOGRAM_MODE_R_HISTOGRAM,
- RKISP1_CIF_ISP_HISTOGRAM_MODE_G_HISTOGRAM,
- RKISP1_CIF_ISP_HISTOGRAM_MODE_B_HISTOGRAM,
- RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM
-};
-
-enum rkisp1_cif_isp_awb_mode_type {
- RKISP1_CIF_ISP_AWB_MODE_MANUAL,
- RKISP1_CIF_ISP_AWB_MODE_RGB,
- RKISP1_CIF_ISP_AWB_MODE_YCBCR
-};
-
-enum rkisp1_cif_isp_flt_mode {
- RKISP1_CIF_ISP_FLT_STATIC_MODE,
- RKISP1_CIF_ISP_FLT_DYNAMIC_MODE
-};
-
-/**
- * enum rkisp1_cif_isp_exp_ctrl_autostop - stop modes
- * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0: continuous measurement
- * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1: stop measuring after a complete frame
- */
-enum rkisp1_cif_isp_exp_ctrl_autostop {
- RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0 = 0,
- RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1 = 1,
-};
-
-/**
- * enum rkisp1_cif_isp_exp_meas_mode - Exposure measure mode
- * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_0: Y = 16 + 0.25R + 0.5G + 0.1094B
- * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_1: Y = (R + G + B) x (85/256)
- */
-enum rkisp1_cif_isp_exp_meas_mode {
- RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
- RKISP1_CIF_ISP_EXP_MEASURING_MODE_1,
-};
-
-/*---------- PART1: Input Parameters ------------*/
-
-/**
- * struct rkisp1_cif_isp_window - measurement window.
- *
- * Measurements are calculated per window inside the frame.
- * This struct represents a window for a measurement.
- *
- * @h_offs: the horizontal offset of the window from the left of the frame in pixels.
- * @v_offs: the vertical offset of the window from the top of the frame in pixels.
- * @h_size: the horizontal size of the window in pixels
- * @v_size: the vertical size of the window in pixels.
- */
-struct rkisp1_cif_isp_window {
- __u16 h_offs;
- __u16 v_offs;
- __u16 h_size;
- __u16 v_size;
-};
-
-/**
- * struct rkisp1_cif_isp_bls_fixed_val - BLS fixed subtraction values
- *
- * The values will be subtracted from the sensor
- * values. Therefore a negative value means addition instead of subtraction!
- *
- * @r: Fixed (signed!) subtraction value for Bayer pattern R
- * @gr: Fixed (signed!) subtraction value for Bayer pattern Gr
- * @gb: Fixed (signed!) subtraction value for Bayer pattern Gb
- * @b: Fixed (signed!) subtraction value for Bayer pattern B
- */
-struct rkisp1_cif_isp_bls_fixed_val {
- __s16 r;
- __s16 gr;
- __s16 gb;
- __s16 b;
-};
-
-/**
- * struct rkisp1_cif_isp_bls_config - Configuration used by black level subtraction
- *
- * @enable_auto: Automatic mode activated means that the measured values
- * are subtracted. Otherwise the fixed subtraction
- * values will be subtracted.
- * @en_windows: enabled window
- * @bls_window1: Measurement window 1 size
- * @bls_window2: Measurement window 2 size
- * @bls_samples: Set amount of measured pixels for each Bayer position
- * (A, B,C and D) to 2^bls_samples.
- * @fixed_val: Fixed subtraction values
- */
-struct rkisp1_cif_isp_bls_config {
- __u8 enable_auto;
- __u8 en_windows;
- struct rkisp1_cif_isp_window bls_window1;
- struct rkisp1_cif_isp_window bls_window2;
- __u8 bls_samples;
- struct rkisp1_cif_isp_bls_fixed_val fixed_val;
-};
-
-/**
- * struct rkisp1_cif_isp_dpcc_methods_config - Methods Configuration used by DPCC
- *
- * Methods Configuration used by Defect Pixel Cluster Correction
- *
- * @method: Method enable bits
- * @line_thresh: Line threshold
- * @line_mad_fac: Line MAD factor
- * @pg_fac: Peak gradient factor
- * @rnd_thresh: Rank Neighbor Difference threshold
- * @rg_fac: Rank gradient factor
- */
-struct rkisp1_cif_isp_dpcc_methods_config {
- __u32 method;
- __u32 line_thresh;
- __u32 line_mad_fac;
- __u32 pg_fac;
- __u32 rnd_thresh;
- __u32 rg_fac;
-};
-
-/**
- * struct rkisp1_cif_isp_dpcc_config - Configuration used by DPCC
- *
- * Configuration used by Defect Pixel Cluster Correction
- *
- * @mode: dpcc output mode
- * @output_mode: whether use hard coded methods
- * @set_use: stage1 methods set
- * @methods: methods config
- * @ro_limits: rank order limits
- * @rnd_offs: differential rank offsets for rank neighbor difference
- */
-struct rkisp1_cif_isp_dpcc_config {
- __u32 mode;
- __u32 output_mode;
- __u32 set_use;
- struct rkisp1_cif_isp_dpcc_methods_config methods[RKISP1_CIF_ISP_DPCC_METHODS_MAX];
- __u32 ro_limits;
- __u32 rnd_offs;
-};
-
-/**
- * struct rkisp1_cif_isp_gamma_corr_curve - gamma curve point definition y-axis (output).
- *
- * The reset values define a linear curve which has the same effect as bypass. Reset values are:
- * gamma_y[0] = 0x0000, gamma_y[1] = 0x0100, ... gamma_y[15] = 0x0f00, gamma_y[16] = 0xfff
- *
- * @gamma_y: the values for the y-axis of gamma curve points. Each value is 12 bit.
- */
-struct rkisp1_cif_isp_gamma_corr_curve {
- __u16 gamma_y[RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE];
-};
-
-/**
- * struct rkisp1_cif_isp_gamma_curve_x_axis_pnts - De-Gamma Curve definition x increments
- * (sampling points). gamma_dx0 is for the lower samples (1-8), gamma_dx1 is for the
- * higher samples (9-16). The reset values for both fields is 0x44444444. This means
- * that each sample is 4 units away from the previous one on the x-axis.
- *
- * @gamma_dx0: gamma curve sample points definitions. Bits 0:2 for sample 1. Bit 3 unused.
- * Bits 4:6 for sample 2. bit 7 unused ... Bits 28:30 for sample 8. Bit 31 unused
- * @gamma_dx1: gamma curve sample points definitions. Bits 0:2 for sample 9. Bit 3 unused.
- * Bits 4:6 for sample 10. bit 7 unused ... Bits 28:30 for sample 16. Bit 31 unused
- */
-struct rkisp1_cif_isp_gamma_curve_x_axis_pnts {
- __u32 gamma_dx0;
- __u32 gamma_dx1;
-};
-
-/**
- * struct rkisp1_cif_isp_sdg_config - Configuration used by sensor degamma
- *
- * @curve_r: gamma curve point definition axis for red
- * @curve_g: gamma curve point definition axis for green
- * @curve_b: gamma curve point definition axis for blue
- * @xa_pnts: x axis increments
- */
-struct rkisp1_cif_isp_sdg_config {
- struct rkisp1_cif_isp_gamma_corr_curve curve_r;
- struct rkisp1_cif_isp_gamma_corr_curve curve_g;
- struct rkisp1_cif_isp_gamma_corr_curve curve_b;
- struct rkisp1_cif_isp_gamma_curve_x_axis_pnts xa_pnts;
-};
-
-/**
- * struct rkisp1_cif_isp_lsc_config - Configuration used by Lens shading correction
- *
- * @r_data_tbl: sample table red
- * @gr_data_tbl: sample table green (red)
- * @gb_data_tbl: sample table green (blue)
- * @b_data_tbl: sample table blue
- * @x_grad_tbl: gradient table x
- * @y_grad_tbl: gradient table y
- * @x_size_tbl: size table x
- * @y_size_tbl: size table y
- * @config_width: not used at the moment
- * @config_height: not used at the moment
- */
-struct rkisp1_cif_isp_lsc_config {
- __u16 r_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
- __u16 gr_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
- __u16 gb_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
- __u16 b_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
-
- __u16 x_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
- __u16 y_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
-
- __u16 x_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
- __u16 y_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
- __u16 config_width;
- __u16 config_height;
-};
-
-/**
- * struct rkisp1_cif_isp_ie_config - Configuration used by image effects
- *
- * @effect: values from 'enum v4l2_colorfx'. Possible values are: V4L2_COLORFX_SEPIA,
- * V4L2_COLORFX_SET_CBCR, V4L2_COLORFX_AQUA, V4L2_COLORFX_EMBOSS,
- * V4L2_COLORFX_SKETCH, V4L2_COLORFX_BW, V4L2_COLORFX_NEGATIVE
- * @color_sel: bits 0:2 - colors bitmask (001 - blue, 010 - green, 100 - red).
- * bits 8:15 - Threshold value of the RGB colors for the color selection effect.
- * @eff_mat_1: 3x3 Matrix Coefficients for Emboss Effect 1
- * @eff_mat_2: 3x3 Matrix Coefficients for Emboss Effect 2
- * @eff_mat_3: 3x3 Matrix Coefficients for Emboss 3/Sketch 1
- * @eff_mat_4: 3x3 Matrix Coefficients for Sketch Effect 2
- * @eff_mat_5: 3x3 Matrix Coefficients for Sketch Effect 3
- * @eff_tint: Chrominance increment values of tint (used for sepia effect)
- */
-struct rkisp1_cif_isp_ie_config {
- __u16 effect;
- __u16 color_sel;
- __u16 eff_mat_1;
- __u16 eff_mat_2;
- __u16 eff_mat_3;
- __u16 eff_mat_4;
- __u16 eff_mat_5;
- __u16 eff_tint;
-};
-
-/**
- * struct rkisp1_cif_isp_cproc_config - Configuration used by Color Processing
- *
- * @c_out_range: Chrominance pixel clipping range at output.
- * (0 for limit, 1 for full)
- * @y_in_range: Luminance pixel clipping range at output.
- * @y_out_range: Luminance pixel clipping range at output.
- * @contrast: 00~ff, 0.0~1.992
- * @brightness: 80~7F, -128~+127
- * @sat: saturation, 00~FF, 0.0~1.992
- * @hue: 80~7F, -90~+87.188
- */
-struct rkisp1_cif_isp_cproc_config {
- __u8 c_out_range;
- __u8 y_in_range;
- __u8 y_out_range;
- __u8 contrast;
- __u8 brightness;
- __u8 sat;
- __u8 hue;
-};
-
-/**
- * struct rkisp1_cif_isp_awb_meas_config - Configuration used by auto white balance
- *
- * @awb_mode: the awb meas mode. From enum rkisp1_cif_isp_awb_mode_type.
- * @awb_wnd: white balance measurement window (in pixels)
- * @max_y: only pixels values < max_y contribute to awb measurement, set to 0
- * to disable this feature
- * @min_y: only pixels values > min_y contribute to awb measurement
- * @max_csum: Chrominance sum maximum value, only consider pixels with Cb+Cr,
- * smaller than threshold for awb measurements
- * @min_c: Chrominance minimum value, only consider pixels with Cb/Cr
- * each greater than threshold value for awb measurements
- * @frames: number of frames - 1 used for mean value calculation
- * (ucFrames=0 means 1 Frame)
- * @awb_ref_cr: reference Cr value for AWB regulation, target for AWB
- * @awb_ref_cb: reference Cb value for AWB regulation, target for AWB
- * @enable_ymax_cmp: enable Y_MAX compare (Not valid in RGB measurement mode.)
- */
-struct rkisp1_cif_isp_awb_meas_config {
- /*
- * Note: currently the h and v offsets are mapped to grid offsets
- */
- struct rkisp1_cif_isp_window awb_wnd;
- __u32 awb_mode;
- __u8 max_y;
- __u8 min_y;
- __u8 max_csum;
- __u8 min_c;
- __u8 frames;
- __u8 awb_ref_cr;
- __u8 awb_ref_cb;
- __u8 enable_ymax_cmp;
-};
-
-/**
- * struct rkisp1_cif_isp_awb_gain_config - Configuration used by auto white balance gain
- *
- * All fields in this struct are 10 bit, where:
- * 0x100h = 1, unsigned integer value, range 0 to 4 with 8 bit fractional part.
- *
- * out_data_x = ( AWB_GAIN_X * in_data + 128) >> 8
- *
- * @gain_red: gain value for red component.
- * @gain_green_r: gain value for green component in red line.
- * @gain_blue: gain value for blue component.
- * @gain_green_b: gain value for green component in blue line.
- */
-struct rkisp1_cif_isp_awb_gain_config {
- __u16 gain_red;
- __u16 gain_green_r;
- __u16 gain_blue;
- __u16 gain_green_b;
-};
-
-/**
- * struct rkisp1_cif_isp_flt_config - Configuration used by ISP filtering
- *
- * All 4 threshold fields (thresh_*) are 10 bits.
- * All 6 factor fields (fac_*) are 6 bits.
- *
- * @mode: ISP_FILT_MODE register fields (from enum rkisp1_cif_isp_flt_mode)
- * @grn_stage1: Green filter stage 1 select (range 0x0...0x8)
- * @chr_h_mode: Chroma filter horizontal mode
- * @chr_v_mode: Chroma filter vertical mode
- * @thresh_bl0: If thresh_bl1 < sum_grad < thresh_bl0 then fac_bl0 is selected (blurring th)
- * @thresh_bl1: If sum_grad < thresh_bl1 then fac_bl1 is selected (blurring th)
- * @thresh_sh0: If thresh_sh0 < sum_grad < thresh_sh1 then thresh_sh0 is selected (sharpening th)
- * @thresh_sh1: If thresh_sh1 < sum_grad then thresh_sh1 is selected (sharpening th)
- * @lum_weight: Parameters for luminance weight function.
- * @fac_sh1: filter factor for sharp1 level
- * @fac_sh0: filter factor for sharp0 level
- * @fac_mid: filter factor for mid level and for static filter mode
- * @fac_bl0: filter factor for blur 0 level
- * @fac_bl1: filter factor for blur 1 level (max blur)
- */
-struct rkisp1_cif_isp_flt_config {
- __u32 mode;
- __u8 grn_stage1;
- __u8 chr_h_mode;
- __u8 chr_v_mode;
- __u32 thresh_bl0;
- __u32 thresh_bl1;
- __u32 thresh_sh0;
- __u32 thresh_sh1;
- __u32 lum_weight;
- __u32 fac_sh1;
- __u32 fac_sh0;
- __u32 fac_mid;
- __u32 fac_bl0;
- __u32 fac_bl1;
-};
-
-/**
- * struct rkisp1_cif_isp_bdm_config - Configuration used by Bayer DeMosaic
- *
- * @demosaic_th: threshold for bayer demosaicing texture detection
- */
-struct rkisp1_cif_isp_bdm_config {
- __u8 demosaic_th;
-};
-
-/**
- * struct rkisp1_cif_isp_ctk_config - Configuration used by Cross Talk correction
- *
- * @coeff: color correction matrix. Values are 11-bit signed fixed-point numbers with 4 bit integer
- * and 7 bit fractional part, ranging from -8 (0x400) to +7.992 (0x3FF). 0 is
- * represented by 0x000 and a coefficient value of 1 as 0x080.
- * @ct_offset: Red, Green, Blue offsets for the crosstalk correction matrix
- */
-struct rkisp1_cif_isp_ctk_config {
- __u16 coeff[3][3];
- __u16 ct_offset[3];
-};
-
-enum rkisp1_cif_isp_goc_mode {
- RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC,
- RKISP1_CIF_ISP_GOC_MODE_EQUIDISTANT
-};
-
-/**
- * struct rkisp1_cif_isp_goc_config - Configuration used by Gamma Out correction
- *
- * @mode: goc mode (from enum rkisp1_cif_isp_goc_mode)
- * @gamma_y: gamma out curve y-axis for all color components
- */
-struct rkisp1_cif_isp_goc_config {
- __u32 mode;
- __u16 gamma_y[RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES];
-};
-
-/**
- * struct rkisp1_cif_isp_hst_config - Configuration used by Histogram
- *
- * @mode: histogram mode (from enum rkisp1_cif_isp_histogram_mode)
- * @histogram_predivider: process every stepsize pixel, all other pixels are
- * skipped
- * @meas_window: coordinates of the measure window
- * @hist_weight: weighting factor for sub-windows
- */
-struct rkisp1_cif_isp_hst_config {
- __u32 mode;
- __u8 histogram_predivider;
- struct rkisp1_cif_isp_window meas_window;
- __u8 hist_weight[RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE];
-};
-
-/**
- * struct rkisp1_cif_isp_aec_config - Configuration used by Auto Exposure Control
- *
- * @mode: Exposure measure mode (from enum rkisp1_cif_isp_exp_meas_mode)
- * @autostop: stop mode (from enum rkisp1_cif_isp_exp_ctrl_autostop)
- * @meas_window: coordinates of the measure window
- */
-struct rkisp1_cif_isp_aec_config {
- __u32 mode;
- __u32 autostop;
- struct rkisp1_cif_isp_window meas_window;
-};
-
-/**
- * struct rkisp1_cif_isp_afc_config - Configuration used by Auto Focus Control
- *
- * @num_afm_win: max RKISP1_CIF_ISP_AFM_MAX_WINDOWS
- * @afm_win: coordinates of the meas window
- * @thres: threshold used for minimizing the influence of noise
- * @var_shift: the number of bits for the shift operation at the end of the
- * calculation chain.
- */
-struct rkisp1_cif_isp_afc_config {
- __u8 num_afm_win;
- struct rkisp1_cif_isp_window afm_win[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
- __u32 thres;
- __u32 var_shift;
-};
-
-/**
- * enum rkisp1_cif_isp_dpf_gain_usage - dpf gain usage
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED: don't use any gains in preprocessing stage
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS: use only the noise function gains from
- * registers DPF_NF_GAIN_R, ...
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS: use only the gains from LSC module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS: use the noise function gains and the
- * gains from LSC module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS: use only the gains from AWB module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: use the gains from AWB and LSC module
- * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX: upper border (only for an internal evaluation)
- */
-enum rkisp1_cif_isp_dpf_gain_usage {
- RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED,
- RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS,
- RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS,
- RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS,
- RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS,
- RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS,
- RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX
-};
-
-/**
- * enum rkisp1_cif_isp_dpf_rb_filtersize - Red and blue filter sizes
- * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9: red and blue filter kernel size 13x9
- * (means 7x5 active pixel)
- * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9: red and blue filter kernel size 9x9
- * (means 5x5 active pixel)
- */
-enum rkisp1_cif_isp_dpf_rb_filtersize {
- RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9,
- RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9,
-};
-
-/**
- * enum rkisp1_cif_isp_dpf_nll_scale_mode - dpf noise level scale mode
- * @RKISP1_CIF_ISP_NLL_SCALE_LINEAR: use a linear scaling
- * @RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC: use a logarithmic scaling
- */
-enum rkisp1_cif_isp_dpf_nll_scale_mode {
- RKISP1_CIF_ISP_NLL_SCALE_LINEAR,
- RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC,
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_nll - Noise level lookup
- *
- * @coeff: Noise level Lookup coefficient
- * @scale_mode: dpf noise level scale mode (from enum rkisp1_cif_isp_dpf_nll_scale_mode)
- */
-struct rkisp1_cif_isp_dpf_nll {
- __u16 coeff[RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS];
- __u32 scale_mode;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_rb_flt - Red blue filter config
- *
- * @fltsize: The filter size for the red and blue pixels
- * (from enum rkisp1_cif_isp_dpf_rb_filtersize)
- * @spatial_coeff: Spatial weights
- * @r_enable: enable filter processing for red pixels
- * @b_enable: enable filter processing for blue pixels
- */
-struct rkisp1_cif_isp_dpf_rb_flt {
- __u32 fltsize;
- __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
- __u8 r_enable;
- __u8 b_enable;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_g_flt - Green filter Configuration
- *
- * @spatial_coeff: Spatial weights
- * @gr_enable: enable filter processing for green pixels in green/red lines
- * @gb_enable: enable filter processing for green pixels in green/blue lines
- */
-struct rkisp1_cif_isp_dpf_g_flt {
- __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
- __u8 gr_enable;
- __u8 gb_enable;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_gain - Noise function Configuration
- *
- * @mode: dpf gain usage (from enum rkisp1_cif_isp_dpf_gain_usage)
- * @nf_r_gain: Noise function Gain that replaces the AWB gain for red pixels
- * @nf_b_gain: Noise function Gain that replaces the AWB gain for blue pixels
- * @nf_gr_gain: Noise function Gain that replaces the AWB gain
- * for green pixels in a red line
- * @nf_gb_gain: Noise function Gain that replaces the AWB gain
- * for green pixels in a blue line
- */
-struct rkisp1_cif_isp_dpf_gain {
- __u32 mode;
- __u16 nf_r_gain;
- __u16 nf_b_gain;
- __u16 nf_gr_gain;
- __u16 nf_gb_gain;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_config - Configuration used by De-noising pre-filter
- *
- * @gain: noise function gain
- * @g_flt: green filter config
- * @rb_flt: red blue filter config
- * @nll: noise level lookup
- */
-struct rkisp1_cif_isp_dpf_config {
- struct rkisp1_cif_isp_dpf_gain gain;
- struct rkisp1_cif_isp_dpf_g_flt g_flt;
- struct rkisp1_cif_isp_dpf_rb_flt rb_flt;
- struct rkisp1_cif_isp_dpf_nll nll;
-};
-
-/**
- * struct rkisp1_cif_isp_dpf_strength_config - strength of the filter
- *
- * @r: filter strength of the RED filter
- * @g: filter strength of the GREEN filter
- * @b: filter strength of the BLUE filter
- */
-struct rkisp1_cif_isp_dpf_strength_config {
- __u8 r;
- __u8 g;
- __u8 b;
-};
-
-/**
- * struct rkisp1_cif_isp_isp_other_cfg - Parameters for some blocks in rockchip isp1
- *
- * @dpcc_config: Defect Pixel Cluster Correction config
- * @bls_config: Black Level Subtraction config
- * @sdg_config: sensor degamma config
- * @lsc_config: Lens Shade config
- * @awb_gain_config: Auto White balance gain config
- * @flt_config: filter config
- * @bdm_config: demosaic config
- * @ctk_config: cross talk config
- * @goc_config: gamma out config
- * @bls_config: black level subtraction config
- * @dpf_config: De-noising pre-filter config
- * @dpf_strength_config: dpf strength config
- * @cproc_config: color process config
- * @ie_config: image effects config
- */
-struct rkisp1_cif_isp_isp_other_cfg {
- struct rkisp1_cif_isp_dpcc_config dpcc_config;
- struct rkisp1_cif_isp_bls_config bls_config;
- struct rkisp1_cif_isp_sdg_config sdg_config;
- struct rkisp1_cif_isp_lsc_config lsc_config;
- struct rkisp1_cif_isp_awb_gain_config awb_gain_config;
- struct rkisp1_cif_isp_flt_config flt_config;
- struct rkisp1_cif_isp_bdm_config bdm_config;
- struct rkisp1_cif_isp_ctk_config ctk_config;
- struct rkisp1_cif_isp_goc_config goc_config;
- struct rkisp1_cif_isp_dpf_config dpf_config;
- struct rkisp1_cif_isp_dpf_strength_config dpf_strength_config;
- struct rkisp1_cif_isp_cproc_config cproc_config;
- struct rkisp1_cif_isp_ie_config ie_config;
-};
-
-/**
- * struct rkisp1_cif_isp_isp_meas_cfg - Rockchip ISP1 Measure Parameters
- *
- * @awb_meas_config: auto white balance config
- * @hst_config: histogram config
- * @aec_config: auto exposure config
- * @afc_config: auto focus config
- */
-struct rkisp1_cif_isp_isp_meas_cfg {
- struct rkisp1_cif_isp_awb_meas_config awb_meas_config;
- struct rkisp1_cif_isp_hst_config hst_config;
- struct rkisp1_cif_isp_aec_config aec_config;
- struct rkisp1_cif_isp_afc_config afc_config;
-};
-
-/**
- * struct rkisp1_params_cfg - Rockchip ISP1 Input Parameters Meta Data
- *
- * @module_en_update: mask the enable bits of which module should be updated
- * @module_ens: mask the enable value of each module, only update the module
- * which correspond bit was set in module_en_update
- * @module_cfg_update: mask the config bits of which module should be updated
- * @meas: measurement config
- * @others: other config
- */
-struct rkisp1_params_cfg {
- __u32 module_en_update;
- __u32 module_ens;
- __u32 module_cfg_update;
-
- struct rkisp1_cif_isp_isp_meas_cfg meas;
- struct rkisp1_cif_isp_isp_other_cfg others;
-};
-
-/*---------- PART2: Measurement Statistics ------------*/
-
-/**
- * struct rkisp1_cif_isp_awb_meas - AWB measured values
- *
- * @cnt: White pixel count, number of "white pixels" found during last
- * measurement
- * @mean_y_or_g: Mean value of Y within window and frames,
- * Green if RGB is selected.
- * @mean_cb_or_b: Mean value of Cb within window and frames,
- * Blue if RGB is selected.
- * @mean_cr_or_r: Mean value of Cr within window and frames,
- * Red if RGB is selected.
- */
-struct rkisp1_cif_isp_awb_meas {
- __u32 cnt;
- __u8 mean_y_or_g;
- __u8 mean_cb_or_b;
- __u8 mean_cr_or_r;
-};
-
-/**
- * struct rkisp1_cif_isp_awb_stat - statistics automatic white balance data
- *
- * @awb_mean: Mean measured data
- */
-struct rkisp1_cif_isp_awb_stat {
- struct rkisp1_cif_isp_awb_meas awb_mean[RKISP1_CIF_ISP_AWB_MAX_GRID];
-};
-
-/**
- * struct rkisp1_cif_isp_bls_meas_val - BLS measured values
- *
- * @meas_r: Mean measured value for Bayer pattern R
- * @meas_gr: Mean measured value for Bayer pattern Gr
- * @meas_gb: Mean measured value for Bayer pattern Gb
- * @meas_b: Mean measured value for Bayer pattern B
- */
-struct rkisp1_cif_isp_bls_meas_val {
- __u16 meas_r;
- __u16 meas_gr;
- __u16 meas_gb;
- __u16 meas_b;
-};
-
-/**
- * struct rkisp1_cif_isp_ae_stat - statistics auto exposure data
- *
- * @exp_mean: Mean luminance value of block xx
- * @bls_val: BLS measured values
- *
- * Image is divided into 5x5 blocks.
- */
-struct rkisp1_cif_isp_ae_stat {
- __u8 exp_mean[RKISP1_CIF_ISP_AE_MEAN_MAX];
- struct rkisp1_cif_isp_bls_meas_val bls_val;
-};
-
-/**
- * struct rkisp1_cif_isp_af_meas_val - AF measured values
- *
- * @sum: sharpness value
- * @lum: luminance value
- */
-struct rkisp1_cif_isp_af_meas_val {
- __u32 sum;
- __u32 lum;
-};
-
-/**
- * struct rkisp1_cif_isp_af_stat - statistics auto focus data
- *
- * @window: AF measured value of window x
- *
- * The module measures the sharpness in 3 windows of selectable size via
- * register settings(ISP_AFM_*_A/B/C)
- */
-struct rkisp1_cif_isp_af_stat {
- struct rkisp1_cif_isp_af_meas_val window[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
-};
-
-/**
- * struct rkisp1_cif_isp_hist_stat - statistics histogram data
- *
- * @hist_bins: measured bin counters
- *
- * Measurement window divided into 25 sub-windows, set
- * with ISP_HIST_XXX
- */
-struct rkisp1_cif_isp_hist_stat {
- __u16 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
-};
-
-/**
- * struct rkisp1_cif_isp_stat - Rockchip ISP1 Statistics Data
- *
- * @awb: statistics data for automatic white balance
- * @ae: statistics data for auto exposure
- * @af: statistics data for auto focus
- * @hist: statistics histogram data
- */
-struct rkisp1_cif_isp_stat {
- struct rkisp1_cif_isp_awb_stat awb;
- struct rkisp1_cif_isp_ae_stat ae;
- struct rkisp1_cif_isp_af_stat af;
- struct rkisp1_cif_isp_hist_stat hist;
-};
-
-/**
- * struct rkisp1_stat_buffer - Rockchip ISP1 Statistics Meta Data
- *
- * @meas_type: measurement types (RKISP1_CIF_ISP_STAT_* definitions)
- * @frame_id: frame ID for sync
- * @params: statistics data
- */
-struct rkisp1_stat_buffer {
- __u32 meas_type;
- __u32 frame_id;
- struct rkisp1_cif_isp_stat params;
-};
-
-#endif /* _UAPI_RKISP1_CONFIG_H */
--- /dev/null
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR MIT) */
+/*
+ * Rockchip ISP1 userspace API
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _UAPI_RKISP1_CONFIG_H
+#define _UAPI_RKISP1_CONFIG_H
+
+#include <linux/types.h>
+
+/* Defect Pixel Cluster Detection */
+#define RKISP1_CIF_ISP_MODULE_DPCC (1U << 0)
+/* Black Level Subtraction */
+#define RKISP1_CIF_ISP_MODULE_BLS (1U << 1)
+/* Sensor De-gamma */
+#define RKISP1_CIF_ISP_MODULE_SDG (1U << 2)
+/* Histogram */
+#define RKISP1_CIF_ISP_MODULE_HST (1U << 3)
+/* Lens Shade Control */
+#define RKISP1_CIF_ISP_MODULE_LSC (1U << 4)
+/* Auto White Balance Gain */
+#define RKISP1_CIF_ISP_MODULE_AWB_GAIN (1U << 5)
+/* Filter */
+#define RKISP1_CIF_ISP_MODULE_FLT (1U << 6)
+/* Bayer Demosaic */
+#define RKISP1_CIF_ISP_MODULE_BDM (1U << 7)
+/* Cross Talk */
+#define RKISP1_CIF_ISP_MODULE_CTK (1U << 8)
+/* Gamma Out Curve */
+#define RKISP1_CIF_ISP_MODULE_GOC (1U << 9)
+/* Color Processing */
+#define RKISP1_CIF_ISP_MODULE_CPROC (1U << 10)
+/* Auto Focus Control */
+#define RKISP1_CIF_ISP_MODULE_AFC (1U << 11)
+/* Auto White Balancing */
+#define RKISP1_CIF_ISP_MODULE_AWB (1U << 12)
+/* Image Effect */
+#define RKISP1_CIF_ISP_MODULE_IE (1U << 13)
+/* Auto Exposure Control */
+#define RKISP1_CIF_ISP_MODULE_AEC (1U << 14)
+/* Wide Dynamic Range */
+#define RKISP1_CIF_ISP_MODULE_WDR (1U << 15)
+/* Denoise Pre-Filter */
+#define RKISP1_CIF_ISP_MODULE_DPF (1U << 16)
+/* Denoise Pre-Filter Strength */
+#define RKISP1_CIF_ISP_MODULE_DPF_STRENGTH (1U << 17)
+
+#define RKISP1_CIF_ISP_CTK_COEFF_MAX 0x100
+#define RKISP1_CIF_ISP_CTK_OFFSET_MAX 0x800
+
+#define RKISP1_CIF_ISP_AE_MEAN_MAX 25
+#define RKISP1_CIF_ISP_HIST_BIN_N_MAX 16
+#define RKISP1_CIF_ISP_AFM_MAX_WINDOWS 3
+#define RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE 17
+
+#define RKISP1_CIF_ISP_BDM_MAX_TH 0xff
+
+/*
+ * Black level compensation
+ */
+/* maximum value for horizontal start address */
+#define RKISP1_CIF_ISP_BLS_START_H_MAX 0x00000fff
+/* maximum value for horizontal stop address */
+#define RKISP1_CIF_ISP_BLS_STOP_H_MAX 0x00000fff
+/* maximum value for vertical start address */
+#define RKISP1_CIF_ISP_BLS_START_V_MAX 0x00000fff
+/* maximum value for vertical stop address */
+#define RKISP1_CIF_ISP_BLS_STOP_V_MAX 0x00000fff
+/* maximum is 2^18 = 262144*/
+#define RKISP1_CIF_ISP_BLS_SAMPLES_MAX 0x00000012
+/* maximum value for fixed black level */
+#define RKISP1_CIF_ISP_BLS_FIX_SUB_MAX 0x00000fff
+/* minimum value for fixed black level */
+#define RKISP1_CIF_ISP_BLS_FIX_SUB_MIN 0xfffff000
+/* 13 bit range (signed)*/
+#define RKISP1_CIF_ISP_BLS_FIX_MASK 0x00001fff
+
+/*
+ * Automatic white balance measurements
+ */
+#define RKISP1_CIF_ISP_AWB_MAX_GRID 1
+#define RKISP1_CIF_ISP_AWB_MAX_FRAMES 7
+
+/*
+ * Gamma out
+ */
+/* Maximum number of color samples supported */
+#define RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES 17
+
+/*
+ * Lens shade correction
+ */
+#define RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE 8
+
+/*
+ * The following matches the tuning process,
+ * not the max capabilities of the chip.
+ */
+#define RKISP1_CIF_ISP_LSC_SAMPLES_MAX 17
+
+/*
+ * Histogram calculation
+ */
+/* Last 3 values unused. */
+#define RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE 28
+
+/*
+ * Defect Pixel Cluster Correction
+ */
+#define RKISP1_CIF_ISP_DPCC_METHODS_MAX 3
+
+/*
+ * Denoising pre filter
+ */
+#define RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS 17
+#define RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS 6
+
+/*
+ * Measurement types
+ */
+#define RKISP1_CIF_ISP_STAT_AWB (1U << 0)
+#define RKISP1_CIF_ISP_STAT_AUTOEXP (1U << 1)
+#define RKISP1_CIF_ISP_STAT_AFM (1U << 2)
+#define RKISP1_CIF_ISP_STAT_HIST (1U << 3)
+
+enum rkisp1_cif_isp_histogram_mode {
+ RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE,
+ RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED,
+ RKISP1_CIF_ISP_HISTOGRAM_MODE_R_HISTOGRAM,
+ RKISP1_CIF_ISP_HISTOGRAM_MODE_G_HISTOGRAM,
+ RKISP1_CIF_ISP_HISTOGRAM_MODE_B_HISTOGRAM,
+ RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM
+};
+
+enum rkisp1_cif_isp_awb_mode_type {
+ RKISP1_CIF_ISP_AWB_MODE_MANUAL,
+ RKISP1_CIF_ISP_AWB_MODE_RGB,
+ RKISP1_CIF_ISP_AWB_MODE_YCBCR
+};
+
+enum rkisp1_cif_isp_flt_mode {
+ RKISP1_CIF_ISP_FLT_STATIC_MODE,
+ RKISP1_CIF_ISP_FLT_DYNAMIC_MODE
+};
+
+/**
+ * enum rkisp1_cif_isp_exp_ctrl_autostop - stop modes
+ * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0: continuous measurement
+ * @RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1: stop measuring after a complete frame
+ */
+enum rkisp1_cif_isp_exp_ctrl_autostop {
+ RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0 = 0,
+ RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_1 = 1,
+};
+
+/**
+ * enum rkisp1_cif_isp_exp_meas_mode - Exposure measure mode
+ * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_0: Y = 16 + 0.25R + 0.5G + 0.1094B
+ * @RKISP1_CIF_ISP_EXP_MEASURING_MODE_1: Y = (R + G + B) x (85/256)
+ */
+enum rkisp1_cif_isp_exp_meas_mode {
+ RKISP1_CIF_ISP_EXP_MEASURING_MODE_0,
+ RKISP1_CIF_ISP_EXP_MEASURING_MODE_1,
+};
+
+/*---------- PART1: Input Parameters ------------*/
+
+/**
+ * struct rkisp1_cif_isp_window - measurement window.
+ *
+ * Measurements are calculated per window inside the frame.
+ * This struct represents a window for a measurement.
+ *
+ * @h_offs: the horizontal offset of the window from the left of the frame in pixels.
+ * @v_offs: the vertical offset of the window from the top of the frame in pixels.
+ * @h_size: the horizontal size of the window in pixels
+ * @v_size: the vertical size of the window in pixels.
+ */
+struct rkisp1_cif_isp_window {
+ __u16 h_offs;
+ __u16 v_offs;
+ __u16 h_size;
+ __u16 v_size;
+};
+
+/**
+ * struct rkisp1_cif_isp_bls_fixed_val - BLS fixed subtraction values
+ *
+ * The values will be subtracted from the sensor
+ * values. Therefore a negative value means addition instead of subtraction!
+ *
+ * @r: Fixed (signed!) subtraction value for Bayer pattern R
+ * @gr: Fixed (signed!) subtraction value for Bayer pattern Gr
+ * @gb: Fixed (signed!) subtraction value for Bayer pattern Gb
+ * @b: Fixed (signed!) subtraction value for Bayer pattern B
+ */
+struct rkisp1_cif_isp_bls_fixed_val {
+ __s16 r;
+ __s16 gr;
+ __s16 gb;
+ __s16 b;
+};
+
+/**
+ * struct rkisp1_cif_isp_bls_config - Configuration used by black level subtraction
+ *
+ * @enable_auto: Automatic mode activated means that the measured values
+ * are subtracted. Otherwise the fixed subtraction
+ * values will be subtracted.
+ * @en_windows: enabled window
+ * @bls_window1: Measurement window 1 size
+ * @bls_window2: Measurement window 2 size
+ * @bls_samples: Set amount of measured pixels for each Bayer position
+ * (A, B,C and D) to 2^bls_samples.
+ * @fixed_val: Fixed subtraction values
+ */
+struct rkisp1_cif_isp_bls_config {
+ __u8 enable_auto;
+ __u8 en_windows;
+ struct rkisp1_cif_isp_window bls_window1;
+ struct rkisp1_cif_isp_window bls_window2;
+ __u8 bls_samples;
+ struct rkisp1_cif_isp_bls_fixed_val fixed_val;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpcc_methods_config - Methods Configuration used by DPCC
+ *
+ * Methods Configuration used by Defect Pixel Cluster Correction
+ *
+ * @method: Method enable bits
+ * @line_thresh: Line threshold
+ * @line_mad_fac: Line MAD factor
+ * @pg_fac: Peak gradient factor
+ * @rnd_thresh: Rank Neighbor Difference threshold
+ * @rg_fac: Rank gradient factor
+ */
+struct rkisp1_cif_isp_dpcc_methods_config {
+ __u32 method;
+ __u32 line_thresh;
+ __u32 line_mad_fac;
+ __u32 pg_fac;
+ __u32 rnd_thresh;
+ __u32 rg_fac;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpcc_config - Configuration used by DPCC
+ *
+ * Configuration used by Defect Pixel Cluster Correction
+ *
+ * @mode: dpcc output mode
+ * @output_mode: whether use hard coded methods
+ * @set_use: stage1 methods set
+ * @methods: methods config
+ * @ro_limits: rank order limits
+ * @rnd_offs: differential rank offsets for rank neighbor difference
+ */
+struct rkisp1_cif_isp_dpcc_config {
+ __u32 mode;
+ __u32 output_mode;
+ __u32 set_use;
+ struct rkisp1_cif_isp_dpcc_methods_config methods[RKISP1_CIF_ISP_DPCC_METHODS_MAX];
+ __u32 ro_limits;
+ __u32 rnd_offs;
+};
+
+/**
+ * struct rkisp1_cif_isp_gamma_corr_curve - gamma curve point definition y-axis (output).
+ *
+ * The reset values define a linear curve which has the same effect as bypass. Reset values are:
+ * gamma_y[0] = 0x0000, gamma_y[1] = 0x0100, ... gamma_y[15] = 0x0f00, gamma_y[16] = 0xfff
+ *
+ * @gamma_y: the values for the y-axis of gamma curve points. Each value is 12 bit.
+ */
+struct rkisp1_cif_isp_gamma_corr_curve {
+ __u16 gamma_y[RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE];
+};
+
+/**
+ * struct rkisp1_cif_isp_gamma_curve_x_axis_pnts - De-Gamma Curve definition x increments
+ * (sampling points). gamma_dx0 is for the lower samples (1-8), gamma_dx1 is for the
+ * higher samples (9-16). The reset values for both fields is 0x44444444. This means
+ * that each sample is 4 units away from the previous one on the x-axis.
+ *
+ * @gamma_dx0: gamma curve sample points definitions. Bits 0:2 for sample 1. Bit 3 unused.
+ * Bits 4:6 for sample 2. bit 7 unused ... Bits 28:30 for sample 8. Bit 31 unused
+ * @gamma_dx1: gamma curve sample points definitions. Bits 0:2 for sample 9. Bit 3 unused.
+ * Bits 4:6 for sample 10. bit 7 unused ... Bits 28:30 for sample 16. Bit 31 unused
+ */
+struct rkisp1_cif_isp_gamma_curve_x_axis_pnts {
+ __u32 gamma_dx0;
+ __u32 gamma_dx1;
+};
+
+/**
+ * struct rkisp1_cif_isp_sdg_config - Configuration used by sensor degamma
+ *
+ * @curve_r: gamma curve point definition axis for red
+ * @curve_g: gamma curve point definition axis for green
+ * @curve_b: gamma curve point definition axis for blue
+ * @xa_pnts: x axis increments
+ */
+struct rkisp1_cif_isp_sdg_config {
+ struct rkisp1_cif_isp_gamma_corr_curve curve_r;
+ struct rkisp1_cif_isp_gamma_corr_curve curve_g;
+ struct rkisp1_cif_isp_gamma_corr_curve curve_b;
+ struct rkisp1_cif_isp_gamma_curve_x_axis_pnts xa_pnts;
+};
+
+/**
+ * struct rkisp1_cif_isp_lsc_config - Configuration used by Lens shading correction
+ *
+ * @r_data_tbl: sample table red
+ * @gr_data_tbl: sample table green (red)
+ * @gb_data_tbl: sample table green (blue)
+ * @b_data_tbl: sample table blue
+ * @x_grad_tbl: gradient table x
+ * @y_grad_tbl: gradient table y
+ * @x_size_tbl: size table x
+ * @y_size_tbl: size table y
+ * @config_width: not used at the moment
+ * @config_height: not used at the moment
+ */
+struct rkisp1_cif_isp_lsc_config {
+ __u16 r_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+ __u16 gr_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+ __u16 gb_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+ __u16 b_data_tbl[RKISP1_CIF_ISP_LSC_SAMPLES_MAX][RKISP1_CIF_ISP_LSC_SAMPLES_MAX];
+
+ __u16 x_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+ __u16 y_grad_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+
+ __u16 x_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+ __u16 y_size_tbl[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];
+ __u16 config_width;
+ __u16 config_height;
+};
+
+/**
+ * struct rkisp1_cif_isp_ie_config - Configuration used by image effects
+ *
+ * @effect: values from 'enum v4l2_colorfx'. Possible values are: V4L2_COLORFX_SEPIA,
+ * V4L2_COLORFX_SET_CBCR, V4L2_COLORFX_AQUA, V4L2_COLORFX_EMBOSS,
+ * V4L2_COLORFX_SKETCH, V4L2_COLORFX_BW, V4L2_COLORFX_NEGATIVE
+ * @color_sel: bits 0:2 - colors bitmask (001 - blue, 010 - green, 100 - red).
+ * bits 8:15 - Threshold value of the RGB colors for the color selection effect.
+ * @eff_mat_1: 3x3 Matrix Coefficients for Emboss Effect 1
+ * @eff_mat_2: 3x3 Matrix Coefficients for Emboss Effect 2
+ * @eff_mat_3: 3x3 Matrix Coefficients for Emboss 3/Sketch 1
+ * @eff_mat_4: 3x3 Matrix Coefficients for Sketch Effect 2
+ * @eff_mat_5: 3x3 Matrix Coefficients for Sketch Effect 3
+ * @eff_tint: Chrominance increment values of tint (used for sepia effect)
+ */
+struct rkisp1_cif_isp_ie_config {
+ __u16 effect;
+ __u16 color_sel;
+ __u16 eff_mat_1;
+ __u16 eff_mat_2;
+ __u16 eff_mat_3;
+ __u16 eff_mat_4;
+ __u16 eff_mat_5;
+ __u16 eff_tint;
+};
+
+/**
+ * struct rkisp1_cif_isp_cproc_config - Configuration used by Color Processing
+ *
+ * @c_out_range: Chrominance pixel clipping range at output.
+ * (0 for limit, 1 for full)
+ * @y_in_range: Luminance pixel clipping range at output.
+ * @y_out_range: Luminance pixel clipping range at output.
+ * @contrast: 00~ff, 0.0~1.992
+ * @brightness: 80~7F, -128~+127
+ * @sat: saturation, 00~FF, 0.0~1.992
+ * @hue: 80~7F, -90~+87.188
+ */
+struct rkisp1_cif_isp_cproc_config {
+ __u8 c_out_range;
+ __u8 y_in_range;
+ __u8 y_out_range;
+ __u8 contrast;
+ __u8 brightness;
+ __u8 sat;
+ __u8 hue;
+};
+
+/**
+ * struct rkisp1_cif_isp_awb_meas_config - Configuration used by auto white balance
+ *
+ * @awb_mode: the awb meas mode. From enum rkisp1_cif_isp_awb_mode_type.
+ * @awb_wnd: white balance measurement window (in pixels)
+ * @max_y: only pixels values < max_y contribute to awb measurement, set to 0
+ * to disable this feature
+ * @min_y: only pixels values > min_y contribute to awb measurement
+ * @max_csum: Chrominance sum maximum value, only consider pixels with Cb+Cr,
+ * smaller than threshold for awb measurements
+ * @min_c: Chrominance minimum value, only consider pixels with Cb/Cr
+ * each greater than threshold value for awb measurements
+ * @frames: number of frames - 1 used for mean value calculation
+ * (ucFrames=0 means 1 Frame)
+ * @awb_ref_cr: reference Cr value for AWB regulation, target for AWB
+ * @awb_ref_cb: reference Cb value for AWB regulation, target for AWB
+ * @enable_ymax_cmp: enable Y_MAX compare (Not valid in RGB measurement mode.)
+ */
+struct rkisp1_cif_isp_awb_meas_config {
+ /*
+ * Note: currently the h and v offsets are mapped to grid offsets
+ */
+ struct rkisp1_cif_isp_window awb_wnd;
+ __u32 awb_mode;
+ __u8 max_y;
+ __u8 min_y;
+ __u8 max_csum;
+ __u8 min_c;
+ __u8 frames;
+ __u8 awb_ref_cr;
+ __u8 awb_ref_cb;
+ __u8 enable_ymax_cmp;
+};
+
+/**
+ * struct rkisp1_cif_isp_awb_gain_config - Configuration used by auto white balance gain
+ *
+ * All fields in this struct are 10 bit, where:
+ * 0x100h = 1, unsigned integer value, range 0 to 4 with 8 bit fractional part.
+ *
+ * out_data_x = ( AWB_GAIN_X * in_data + 128) >> 8
+ *
+ * @gain_red: gain value for red component.
+ * @gain_green_r: gain value for green component in red line.
+ * @gain_blue: gain value for blue component.
+ * @gain_green_b: gain value for green component in blue line.
+ */
+struct rkisp1_cif_isp_awb_gain_config {
+ __u16 gain_red;
+ __u16 gain_green_r;
+ __u16 gain_blue;
+ __u16 gain_green_b;
+};
+
+/**
+ * struct rkisp1_cif_isp_flt_config - Configuration used by ISP filtering
+ *
+ * All 4 threshold fields (thresh_*) are 10 bits.
+ * All 6 factor fields (fac_*) are 6 bits.
+ *
+ * @mode: ISP_FILT_MODE register fields (from enum rkisp1_cif_isp_flt_mode)
+ * @grn_stage1: Green filter stage 1 select (range 0x0...0x8)
+ * @chr_h_mode: Chroma filter horizontal mode
+ * @chr_v_mode: Chroma filter vertical mode
+ * @thresh_bl0: If thresh_bl1 < sum_grad < thresh_bl0 then fac_bl0 is selected (blurring th)
+ * @thresh_bl1: If sum_grad < thresh_bl1 then fac_bl1 is selected (blurring th)
+ * @thresh_sh0: If thresh_sh0 < sum_grad < thresh_sh1 then thresh_sh0 is selected (sharpening th)
+ * @thresh_sh1: If thresh_sh1 < sum_grad then thresh_sh1 is selected (sharpening th)
+ * @lum_weight: Parameters for luminance weight function.
+ * @fac_sh1: filter factor for sharp1 level
+ * @fac_sh0: filter factor for sharp0 level
+ * @fac_mid: filter factor for mid level and for static filter mode
+ * @fac_bl0: filter factor for blur 0 level
+ * @fac_bl1: filter factor for blur 1 level (max blur)
+ */
+struct rkisp1_cif_isp_flt_config {
+ __u32 mode;
+ __u8 grn_stage1;
+ __u8 chr_h_mode;
+ __u8 chr_v_mode;
+ __u32 thresh_bl0;
+ __u32 thresh_bl1;
+ __u32 thresh_sh0;
+ __u32 thresh_sh1;
+ __u32 lum_weight;
+ __u32 fac_sh1;
+ __u32 fac_sh0;
+ __u32 fac_mid;
+ __u32 fac_bl0;
+ __u32 fac_bl1;
+};
+
+/**
+ * struct rkisp1_cif_isp_bdm_config - Configuration used by Bayer DeMosaic
+ *
+ * @demosaic_th: threshold for bayer demosaicing texture detection
+ */
+struct rkisp1_cif_isp_bdm_config {
+ __u8 demosaic_th;
+};
+
+/**
+ * struct rkisp1_cif_isp_ctk_config - Configuration used by Cross Talk correction
+ *
+ * @coeff: color correction matrix. Values are 11-bit signed fixed-point numbers with 4 bit integer
+ * and 7 bit fractional part, ranging from -8 (0x400) to +7.992 (0x3FF). 0 is
+ * represented by 0x000 and a coefficient value of 1 as 0x080.
+ * @ct_offset: Red, Green, Blue offsets for the crosstalk correction matrix
+ */
+struct rkisp1_cif_isp_ctk_config {
+ __u16 coeff[3][3];
+ __u16 ct_offset[3];
+};
+
+enum rkisp1_cif_isp_goc_mode {
+ RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC,
+ RKISP1_CIF_ISP_GOC_MODE_EQUIDISTANT
+};
+
+/**
+ * struct rkisp1_cif_isp_goc_config - Configuration used by Gamma Out correction
+ *
+ * @mode: goc mode (from enum rkisp1_cif_isp_goc_mode)
+ * @gamma_y: gamma out curve y-axis for all color components
+ */
+struct rkisp1_cif_isp_goc_config {
+ __u32 mode;
+ __u16 gamma_y[RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES];
+};
+
+/**
+ * struct rkisp1_cif_isp_hst_config - Configuration used by Histogram
+ *
+ * @mode: histogram mode (from enum rkisp1_cif_isp_histogram_mode)
+ * @histogram_predivider: process every stepsize pixel, all other pixels are
+ * skipped
+ * @meas_window: coordinates of the measure window
+ * @hist_weight: weighting factor for sub-windows
+ */
+struct rkisp1_cif_isp_hst_config {
+ __u32 mode;
+ __u8 histogram_predivider;
+ struct rkisp1_cif_isp_window meas_window;
+ __u8 hist_weight[RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE];
+};
+
+/**
+ * struct rkisp1_cif_isp_aec_config - Configuration used by Auto Exposure Control
+ *
+ * @mode: Exposure measure mode (from enum rkisp1_cif_isp_exp_meas_mode)
+ * @autostop: stop mode (from enum rkisp1_cif_isp_exp_ctrl_autostop)
+ * @meas_window: coordinates of the measure window
+ */
+struct rkisp1_cif_isp_aec_config {
+ __u32 mode;
+ __u32 autostop;
+ struct rkisp1_cif_isp_window meas_window;
+};
+
+/**
+ * struct rkisp1_cif_isp_afc_config - Configuration used by Auto Focus Control
+ *
+ * @num_afm_win: max RKISP1_CIF_ISP_AFM_MAX_WINDOWS
+ * @afm_win: coordinates of the meas window
+ * @thres: threshold used for minimizing the influence of noise
+ * @var_shift: the number of bits for the shift operation at the end of the
+ * calculation chain.
+ */
+struct rkisp1_cif_isp_afc_config {
+ __u8 num_afm_win;
+ struct rkisp1_cif_isp_window afm_win[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
+ __u32 thres;
+ __u32 var_shift;
+};
+
+/**
+ * enum rkisp1_cif_isp_dpf_gain_usage - dpf gain usage
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED: don't use any gains in preprocessing stage
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS: use only the noise function gains from
+ * registers DPF_NF_GAIN_R, ...
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS: use only the gains from LSC module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS: use the noise function gains and the
+ * gains from LSC module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS: use only the gains from AWB module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: use the gains from AWB and LSC module
+ * @RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX: upper border (only for an internal evaluation)
+ */
+enum rkisp1_cif_isp_dpf_gain_usage {
+ RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED,
+ RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS,
+ RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS,
+ RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS,
+ RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS,
+ RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS,
+ RKISP1_CIF_ISP_DPF_GAIN_USAGE_MAX
+};
+
+/**
+ * enum rkisp1_cif_isp_dpf_rb_filtersize - Red and blue filter sizes
+ * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9: red and blue filter kernel size 13x9
+ * (means 7x5 active pixel)
+ * @RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9: red and blue filter kernel size 9x9
+ * (means 5x5 active pixel)
+ */
+enum rkisp1_cif_isp_dpf_rb_filtersize {
+ RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9,
+ RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9,
+};
+
+/**
+ * enum rkisp1_cif_isp_dpf_nll_scale_mode - dpf noise level scale mode
+ * @RKISP1_CIF_ISP_NLL_SCALE_LINEAR: use a linear scaling
+ * @RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC: use a logarithmic scaling
+ */
+enum rkisp1_cif_isp_dpf_nll_scale_mode {
+ RKISP1_CIF_ISP_NLL_SCALE_LINEAR,
+ RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC,
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_nll - Noise level lookup
+ *
+ * @coeff: Noise level Lookup coefficient
+ * @scale_mode: dpf noise level scale mode (from enum rkisp1_cif_isp_dpf_nll_scale_mode)
+ */
+struct rkisp1_cif_isp_dpf_nll {
+ __u16 coeff[RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS];
+ __u32 scale_mode;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_rb_flt - Red blue filter config
+ *
+ * @fltsize: The filter size for the red and blue pixels
+ * (from enum rkisp1_cif_isp_dpf_rb_filtersize)
+ * @spatial_coeff: Spatial weights
+ * @r_enable: enable filter processing for red pixels
+ * @b_enable: enable filter processing for blue pixels
+ */
+struct rkisp1_cif_isp_dpf_rb_flt {
+ __u32 fltsize;
+ __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
+ __u8 r_enable;
+ __u8 b_enable;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_g_flt - Green filter Configuration
+ *
+ * @spatial_coeff: Spatial weights
+ * @gr_enable: enable filter processing for green pixels in green/red lines
+ * @gb_enable: enable filter processing for green pixels in green/blue lines
+ */
+struct rkisp1_cif_isp_dpf_g_flt {
+ __u8 spatial_coeff[RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS];
+ __u8 gr_enable;
+ __u8 gb_enable;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_gain - Noise function Configuration
+ *
+ * @mode: dpf gain usage (from enum rkisp1_cif_isp_dpf_gain_usage)
+ * @nf_r_gain: Noise function Gain that replaces the AWB gain for red pixels
+ * @nf_b_gain: Noise function Gain that replaces the AWB gain for blue pixels
+ * @nf_gr_gain: Noise function Gain that replaces the AWB gain
+ * for green pixels in a red line
+ * @nf_gb_gain: Noise function Gain that replaces the AWB gain
+ * for green pixels in a blue line
+ */
+struct rkisp1_cif_isp_dpf_gain {
+ __u32 mode;
+ __u16 nf_r_gain;
+ __u16 nf_b_gain;
+ __u16 nf_gr_gain;
+ __u16 nf_gb_gain;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_config - Configuration used by De-noising pre-filter
+ *
+ * @gain: noise function gain
+ * @g_flt: green filter config
+ * @rb_flt: red blue filter config
+ * @nll: noise level lookup
+ */
+struct rkisp1_cif_isp_dpf_config {
+ struct rkisp1_cif_isp_dpf_gain gain;
+ struct rkisp1_cif_isp_dpf_g_flt g_flt;
+ struct rkisp1_cif_isp_dpf_rb_flt rb_flt;
+ struct rkisp1_cif_isp_dpf_nll nll;
+};
+
+/**
+ * struct rkisp1_cif_isp_dpf_strength_config - strength of the filter
+ *
+ * @r: filter strength of the RED filter
+ * @g: filter strength of the GREEN filter
+ * @b: filter strength of the BLUE filter
+ */
+struct rkisp1_cif_isp_dpf_strength_config {
+ __u8 r;
+ __u8 g;
+ __u8 b;
+};
+
+/**
+ * struct rkisp1_cif_isp_isp_other_cfg - Parameters for some blocks in rockchip isp1
+ *
+ * @dpcc_config: Defect Pixel Cluster Correction config
+ * @bls_config: Black Level Subtraction config
+ * @sdg_config: sensor degamma config
+ * @lsc_config: Lens Shade config
+ * @awb_gain_config: Auto White balance gain config
+ * @flt_config: filter config
+ * @bdm_config: demosaic config
+ * @ctk_config: cross talk config
+ * @goc_config: gamma out config
+ * @bls_config: black level subtraction config
+ * @dpf_config: De-noising pre-filter config
+ * @dpf_strength_config: dpf strength config
+ * @cproc_config: color process config
+ * @ie_config: image effects config
+ */
+struct rkisp1_cif_isp_isp_other_cfg {
+ struct rkisp1_cif_isp_dpcc_config dpcc_config;
+ struct rkisp1_cif_isp_bls_config bls_config;
+ struct rkisp1_cif_isp_sdg_config sdg_config;
+ struct rkisp1_cif_isp_lsc_config lsc_config;
+ struct rkisp1_cif_isp_awb_gain_config awb_gain_config;
+ struct rkisp1_cif_isp_flt_config flt_config;
+ struct rkisp1_cif_isp_bdm_config bdm_config;
+ struct rkisp1_cif_isp_ctk_config ctk_config;
+ struct rkisp1_cif_isp_goc_config goc_config;
+ struct rkisp1_cif_isp_dpf_config dpf_config;
+ struct rkisp1_cif_isp_dpf_strength_config dpf_strength_config;
+ struct rkisp1_cif_isp_cproc_config cproc_config;
+ struct rkisp1_cif_isp_ie_config ie_config;
+};
+
+/**
+ * struct rkisp1_cif_isp_isp_meas_cfg - Rockchip ISP1 Measure Parameters
+ *
+ * @awb_meas_config: auto white balance config
+ * @hst_config: histogram config
+ * @aec_config: auto exposure config
+ * @afc_config: auto focus config
+ */
+struct rkisp1_cif_isp_isp_meas_cfg {
+ struct rkisp1_cif_isp_awb_meas_config awb_meas_config;
+ struct rkisp1_cif_isp_hst_config hst_config;
+ struct rkisp1_cif_isp_aec_config aec_config;
+ struct rkisp1_cif_isp_afc_config afc_config;
+};
+
+/**
+ * struct rkisp1_params_cfg - Rockchip ISP1 Input Parameters Meta Data
+ *
+ * @module_en_update: mask the enable bits of which module should be updated
+ * @module_ens: mask the enable value of each module, only update the module
+ * which correspond bit was set in module_en_update
+ * @module_cfg_update: mask the config bits of which module should be updated
+ * @meas: measurement config
+ * @others: other config
+ */
+struct rkisp1_params_cfg {
+ __u32 module_en_update;
+ __u32 module_ens;
+ __u32 module_cfg_update;
+
+ struct rkisp1_cif_isp_isp_meas_cfg meas;
+ struct rkisp1_cif_isp_isp_other_cfg others;
+};
+
+/*---------- PART2: Measurement Statistics ------------*/
+
+/**
+ * struct rkisp1_cif_isp_awb_meas - AWB measured values
+ *
+ * @cnt: White pixel count, number of "white pixels" found during last
+ * measurement
+ * @mean_y_or_g: Mean value of Y within window and frames,
+ * Green if RGB is selected.
+ * @mean_cb_or_b: Mean value of Cb within window and frames,
+ * Blue if RGB is selected.
+ * @mean_cr_or_r: Mean value of Cr within window and frames,
+ * Red if RGB is selected.
+ */
+struct rkisp1_cif_isp_awb_meas {
+ __u32 cnt;
+ __u8 mean_y_or_g;
+ __u8 mean_cb_or_b;
+ __u8 mean_cr_or_r;
+};
+
+/**
+ * struct rkisp1_cif_isp_awb_stat - statistics automatic white balance data
+ *
+ * @awb_mean: Mean measured data
+ */
+struct rkisp1_cif_isp_awb_stat {
+ struct rkisp1_cif_isp_awb_meas awb_mean[RKISP1_CIF_ISP_AWB_MAX_GRID];
+};
+
+/**
+ * struct rkisp1_cif_isp_bls_meas_val - BLS measured values
+ *
+ * @meas_r: Mean measured value for Bayer pattern R
+ * @meas_gr: Mean measured value for Bayer pattern Gr
+ * @meas_gb: Mean measured value for Bayer pattern Gb
+ * @meas_b: Mean measured value for Bayer pattern B
+ */
+struct rkisp1_cif_isp_bls_meas_val {
+ __u16 meas_r;
+ __u16 meas_gr;
+ __u16 meas_gb;
+ __u16 meas_b;
+};
+
+/**
+ * struct rkisp1_cif_isp_ae_stat - statistics auto exposure data
+ *
+ * @exp_mean: Mean luminance value of block xx
+ * @bls_val: BLS measured values
+ *
+ * Image is divided into 5x5 blocks.
+ */
+struct rkisp1_cif_isp_ae_stat {
+ __u8 exp_mean[RKISP1_CIF_ISP_AE_MEAN_MAX];
+ struct rkisp1_cif_isp_bls_meas_val bls_val;
+};
+
+/**
+ * struct rkisp1_cif_isp_af_meas_val - AF measured values
+ *
+ * @sum: sharpness value
+ * @lum: luminance value
+ */
+struct rkisp1_cif_isp_af_meas_val {
+ __u32 sum;
+ __u32 lum;
+};
+
+/**
+ * struct rkisp1_cif_isp_af_stat - statistics auto focus data
+ *
+ * @window: AF measured value of window x
+ *
+ * The module measures the sharpness in 3 windows of selectable size via
+ * register settings(ISP_AFM_*_A/B/C)
+ */
+struct rkisp1_cif_isp_af_stat {
+ struct rkisp1_cif_isp_af_meas_val window[RKISP1_CIF_ISP_AFM_MAX_WINDOWS];
+};
+
+/**
+ * struct rkisp1_cif_isp_hist_stat - statistics histogram data
+ *
+ * @hist_bins: measured bin counters
+ *
+ * Measurement window divided into 25 sub-windows, set
+ * with ISP_HIST_XXX
+ */
+struct rkisp1_cif_isp_hist_stat {
+ __u16 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
+};
+
+/**
+ * struct rkisp1_cif_isp_stat - Rockchip ISP1 Statistics Data
+ *
+ * @awb: statistics data for automatic white balance
+ * @ae: statistics data for auto exposure
+ * @af: statistics data for auto focus
+ * @hist: statistics histogram data
+ */
+struct rkisp1_cif_isp_stat {
+ struct rkisp1_cif_isp_awb_stat awb;
+ struct rkisp1_cif_isp_ae_stat ae;
+ struct rkisp1_cif_isp_af_stat af;
+ struct rkisp1_cif_isp_hist_stat hist;
+};
+
+/**
+ * struct rkisp1_stat_buffer - Rockchip ISP1 Statistics Meta Data
+ *
+ * @meas_type: measurement types (RKISP1_CIF_ISP_STAT_* definitions)
+ * @frame_id: frame ID for sync
+ * @params: statistics data
+ */
+struct rkisp1_stat_buffer {
+ __u32 meas_type;
+ __u32 frame_id;
+ struct rkisp1_cif_isp_stat params;
+};
+
+#endif /* _UAPI_RKISP1_CONFIG_H */