summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/media/visl.rst12
-rw-r--r--Documentation/admin-guide/media/vivid.rst2
-rw-r--r--Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml2
-rw-r--r--Documentation/devicetree/bindings/media/rockchip-isp1.yaml37
-rw-r--r--Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml49
-rw-r--r--Documentation/driver-api/media/drivers/ccs/ccs.rst53
-rw-r--r--Documentation/driver-api/media/v4l2-subdev.rst2
-rw-r--r--Documentation/userspace-api/media/drivers/ccs.rst6
-rw-r--r--Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst1
-rw-r--r--Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst1642
-rw-r--r--Documentation/userspace-api/media/dvb/legacy_dvb_decoder_api.rst61
-rw-r--r--Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst883
-rw-r--r--Documentation/userspace-api/media/dvb/legacy_dvb_video.rst2430
-rw-r--r--Documentation/userspace-api/media/mediactl/media-types.rst11
-rw-r--r--Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst15
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/media/cec/core/cec-adap.c14
-rw-r--r--drivers/media/cec/core/cec-core.c2
-rw-r--r--drivers/media/cec/platform/cros-ec/cros-ec-cec.c2
-rw-r--r--drivers/media/common/v4l2-tpg/v4l2-tpg-core.c52
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c25
-rw-r--r--drivers/media/dvb-core/dvbdev.c5
-rw-r--r--drivers/media/dvb-frontends/bcm3510.c3
-rw-r--r--drivers/media/dvb-frontends/bcm3510_priv.h6
-rw-r--r--drivers/media/dvb-frontends/cx24110.c4
-rw-r--r--drivers/media/dvb-frontends/cx24110.h8
-rw-r--r--drivers/media/dvb-frontends/dvb-pll.c6
-rw-r--r--drivers/media/dvb-frontends/stv0367.c34
-rw-r--r--drivers/media/dvb-frontends/stv6110x_priv.h8
-rw-r--r--drivers/media/dvb-frontends/tda8083.h8
-rw-r--r--drivers/media/dvb-frontends/zl10036.c2
-rw-r--r--drivers/media/dvb-frontends/zl10036.h2
-rw-r--r--drivers/media/i2c/Kconfig2
-rw-r--r--drivers/media/i2c/adv7180.c4
-rw-r--r--drivers/media/i2c/adv7343.c2
-rw-r--r--drivers/media/i2c/adv748x/adv748x.h1
-rw-r--r--drivers/media/i2c/adv7604.c4
-rw-r--r--drivers/media/i2c/alvium-csi2.c101
-rw-r--r--drivers/media/i2c/alvium-csi2.h5
-rw-r--r--drivers/media/i2c/ar0521.c6
-rw-r--r--drivers/media/i2c/ccs/ccs-quirk.h8
-rw-r--r--drivers/media/i2c/dw9714.c2
-rw-r--r--drivers/media/i2c/imx214.c2
-rw-r--r--drivers/media/i2c/imx274.c2
-rw-r--r--drivers/media/i2c/imx290.c16
-rw-r--r--drivers/media/i2c/imx319.c53
-rw-r--r--drivers/media/i2c/imx334.c41
-rw-r--r--drivers/media/i2c/imx335.c251
-rw-r--r--drivers/media/i2c/imx355.c53
-rw-r--r--drivers/media/i2c/imx415.c672
-rw-r--r--drivers/media/i2c/isl7998x.c2
-rw-r--r--drivers/media/i2c/max2175.c2
-rw-r--r--drivers/media/i2c/msp3400-driver.c22
-rw-r--r--drivers/media/i2c/msp3400-driver.h2
-rw-r--r--drivers/media/i2c/mt9p031.c2
-rw-r--r--drivers/media/i2c/mt9v032.c4
-rw-r--r--drivers/media/i2c/ov08x40.c1307
-rw-r--r--drivers/media/i2c/ov2659.c2
-rw-r--r--drivers/media/i2c/ov5645.c7
-rw-r--r--drivers/media/i2c/ov5647.c2
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c2
-rw-r--r--drivers/media/i2c/s5k5baf.c2
-rw-r--r--drivers/media/i2c/st-vgxy61.c392
-rw-r--r--drivers/media/i2c/tc358743.c2
-rw-r--r--drivers/media/i2c/tc358746.c4
-rw-r--r--drivers/media/i2c/tda1997x.c2
-rw-r--r--drivers/media/i2c/tvp514x.c2
-rw-r--r--drivers/media/i2c/tvp5150.c2
-rw-r--r--drivers/media/i2c/tvp7002.c2
-rw-r--r--drivers/media/mc/mc-devnode.c3
-rw-r--r--drivers/media/mc/mc-entity.c93
-rw-r--r--drivers/media/pci/bt8xx/bttv-gpio.c2
-rw-r--r--drivers/media/pci/bt8xx/bttvp.h2
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c8
-rw-r--r--drivers/media/pci/dt3155/dt3155.h1
-rw-r--r--drivers/media/pci/intel/ipu-bridge.c26
-rw-r--r--drivers/media/pci/intel/ipu3/ipu3-cio2.c53
-rw-r--r--drivers/media/pci/intel/ivsc/mei_csi.c87
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.c9
-rw-r--r--drivers/media/pci/ttpci/budget-av.c8
-rw-r--r--drivers/media/platform/amphion/vdec.c4
-rw-r--r--drivers/media/platform/atmel/atmel-isi.c4
-rw-r--r--drivers/media/platform/cadence/cdns-csi2rx.c19
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-hw.c2
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c2
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu.c6
-rw-r--r--drivers/media/platform/intel/pxa_camera.c2
-rw-r--r--drivers/media/platform/marvell/Kconfig2
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h1
-rw-r--r--drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c2
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c729
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h25
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_color.h31
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h23
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h31
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h25
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h25
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h21
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h24
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h2
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h34
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h8
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h283
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h4
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h2
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c440
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h1
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c895
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h93
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c142
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h50
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c15
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c18
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h1
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c3
-rw-r--r--drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c10
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h1
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c14
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c1
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c1
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h1
-rw-r--r--drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h1
-rw-r--r--drivers/media/platform/mediatek/vpu/mtk_vpu.c2
-rw-r--r--drivers/media/platform/mediatek/vpu/mtk_vpu.h2
-rw-r--r--drivers/media/platform/nuvoton/npcm-video.c6
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c16
-rw-r--r--drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h1
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c6
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c4
-rw-r--r--drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c8
-rw-r--r--drivers/media/platform/qcom/venus/core.h1
-rw-r--r--drivers/media/platform/renesas/Kconfig16
-rw-r--r--drivers/media/platform/renesas/Makefile1
-rw-r--r--drivers/media/platform/renesas/rcar-csi2.c (renamed from drivers/media/platform/renesas/rcar-vin/rcar-csi2.c)0
-rw-r--r--drivers/media/platform/renesas/rcar-isp.c1
-rw-r--r--drivers/media/platform/renesas/rcar-vin/Kconfig16
-rw-r--r--drivers/media/platform/renesas/rcar-vin/Makefile1
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h3
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c37
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c18
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c83
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c216
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-common.h35
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c71
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c131
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h36
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c19
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-capture.c52
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-core.c23
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-core.h23
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is.c2
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c2
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c13
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h12
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite.c2
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-lite.h3
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-m2m.c23
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-reg.c38
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-reg.h10
-rw-r--r--drivers/media/platform/samsung/exynos4-is/mipi-csis.c3
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c76
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c8
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c6
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c8
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h15
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c26
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c20
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h3
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c12
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h3
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c7
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c28
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c36
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h2
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c51
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h8
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmi.c4
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c6
-rw-r--r--drivers/media/platform/sunxi/sun8i-di/sun8i-di.c69
-rw-r--r--drivers/media/platform/ti/davinci/vpif.c3
-rw-r--r--drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c35
-rw-r--r--drivers/media/platform/verisilicon/Kconfig14
-rw-r--r--drivers/media/platform/verisilicon/Makefile3
-rw-r--r--drivers/media/platform/verisilicon/hantro.h1
-rw-r--r--drivers/media/platform/verisilicon/hantro_drv.c4
-rw-r--r--drivers/media/platform/verisilicon/hantro_g1_h264_dec.c2
-rw-r--r--drivers/media/platform/verisilicon/hantro_hw.h2
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c2
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu981_regs.h2
-rw-r--r--drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c186
-rw-r--r--drivers/media/platform/xilinx/Kconfig4
-rw-r--r--drivers/media/test-drivers/vidtv/vidtv_bridge.c26
-rw-r--r--drivers/media/test-drivers/visl/visl-core.c15
-rw-r--r--drivers/media/test-drivers/visl/visl-dec.c301
-rw-r--r--drivers/media/test-drivers/visl/visl.h1
-rw-r--r--drivers/media/tuners/tda18271-fe.c1
-rw-r--r--drivers/media/tuners/xc4000.c4
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-417.c2
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c4
-rw-r--r--drivers/media/usb/go7007/go7007-driver.c8
-rw-r--r--drivers/media/usb/go7007/go7007-usb.c4
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-context.c10
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-dvb.c12
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-v4l2.c11
-rw-r--r--drivers/media/usb/s2255/s2255drv.c7
-rw-r--r--drivers/media/usb/usbtv/usbtv-video.c7
-rw-r--r--drivers/media/v4l2-core/v4l2-cci.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c47
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-api.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-core.c23
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-mc.c23
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c10
-rw-r--r--drivers/staging/media/atomisp/TODO10
-rw-r--r--drivers/staging/media/atomisp/i2c/gc2235.h5
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.c141
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_css20.c2
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_drvfs.c144
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_drvfs.h5
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_internal.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_ioctl.c8
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.c260
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h2
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c6
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_acc_types.h4
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_control.h29
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_firmware.h6
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_irq.h6
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h4
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c4
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_input_system_global.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_input_system_public.h2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c22
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c6
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css.c35
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_defs.h2
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_mipi.c4
-rw-r--r--drivers/staging/media/imx/imx-media-csc-scaler.c1
-rw-r--r--drivers/staging/media/imx/imx-media-fim.c2
-rw-r--r--drivers/staging/media/ipu3/include/uapi/intel-ipu3.h3
-rw-r--r--drivers/staging/media/ipu3/ipu3-v4l2.c16
-rw-r--r--drivers/staging/media/meson/vdec/vdec.h1
-rw-r--r--drivers/staging/media/starfive/camss/stf-capture.c8
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_h265.c10
-rw-r--r--include/media/cec.h2
-rw-r--r--include/media/media-entity.h6
-rw-r--r--include/media/v4l2-common.h32
-rw-r--r--include/media/videobuf2-core.h15
-rw-r--r--include/uapi/linux/rkisp1-config.h50
-rw-r--r--include/uapi/linux/videodev2.h32
257 files changed, 10978 insertions, 3696 deletions
diff --git a/Documentation/admin-guide/media/visl.rst b/Documentation/admin-guide/media/visl.rst
index db1ef29438e1..cd45145cde68 100644
--- a/Documentation/admin-guide/media/visl.rst
+++ b/Documentation/admin-guide/media/visl.rst
@@ -49,6 +49,10 @@ Module parameters
visl_dprintk_frame_start, visl_dprintk_nframes, but controls the dumping of
buffer data through debugfs instead.
+- tpg_verbose: Write extra information on each output frame to ease debugging
+ the API. When set to true, the output frames are not stable for a given input
+ as some information like pointers or queue status will be added to them.
+
What is the default use case for this driver?
---------------------------------------------
@@ -57,8 +61,12 @@ This assumes that a working client is run against visl and that the ftrace and
OUTPUT buffer data is subsequently used to debug a work-in-progress
implementation.
-Information on reference frames, their timestamps, the status of the OUTPUT and
-CAPTURE queues and more can be read directly from the CAPTURE buffers.
+Even though no video decoding is actually done, the output frames can be used
+against a reference for a given input, except if tpg_verbose is set to true.
+
+Depending on the tpg_verbose parameter value, information on reference frames,
+their timestamps, the status of the OUTPUT and CAPTURE queues and more can be
+read directly from the CAPTURE buffers.
Supported codecs
----------------
diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst
index 58ac25b2c385..b6f658c0997e 100644
--- a/Documentation/admin-guide/media/vivid.rst
+++ b/Documentation/admin-guide/media/vivid.rst
@@ -60,7 +60,7 @@ all configurable using the following module options:
- node_types:
which devices should each driver instance create. An array of
- hexadecimal values, one for each instance. The default is 0x1d3d.
+ hexadecimal values, one for each instance. The default is 0xe1d3d.
Each value is a bitmask with the following meaning:
- bit 0: Video Capture node
diff --git a/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml b/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml
index e37317f81072..c9673391afdb 100644
--- a/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml
@@ -36,7 +36,7 @@ properties:
properties:
port@0:
- $ref: /schemas/graph.yaml#/$defs/port-base
+ $ref: /schemas/graph.yaml#/properties/port
description: Analog input port
properties:
diff --git a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
index afcaa427d48b..6be00aca4181 100644
--- a/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip-isp1.yaml
@@ -16,6 +16,7 @@ description: |
properties:
compatible:
enum:
+ - fsl,imx8mp-isp
- rockchip,px30-cif-isp
- rockchip,rk3399-cif-isp
@@ -36,9 +37,9 @@ properties:
minItems: 3
items:
# isp0 and isp1
- - description: ISP clock
- - description: ISP AXI clock
- - description: ISP AHB clock
+ - description: ISP clock (for imx8mp, clk)
+ - description: ISP AXI clock (for imx8mp, m_hclk)
+ - description: ISP AHB clock (for imx8mp, hclk)
# only for isp1
- description: ISP Pixel clock
@@ -52,6 +53,13 @@ properties:
# only for isp1
- const: pclk
+ fsl,blk-ctrl:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ maxItems: 1
+ description:
+ A phandle to the media block control for the ISP, followed by a cell
+ containing the index of the gasket.
+
iommus:
maxItems: 1
@@ -113,9 +121,6 @@ required:
- interrupts
- clocks
- clock-names
- - iommus
- - phys
- - phy-names
- power-domains
- ports
@@ -143,6 +148,26 @@ allOf:
required:
- interrupt-names
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,imx8mp-isp
+ then:
+ properties:
+ iommus: false
+ phys: false
+ phy-names: false
+ required:
+ - fsl,blk-ctrl
+ else:
+ properties:
+ fsl,blk-ctrl: false
+ required:
+ - iommus
+ - phys
+ - phy-names
+
additionalProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml b/Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml
new file mode 100644
index 000000000000..b8611bc8756c
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/st,stm32mp25-video-codec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32MP25 VDEC video decoder & VENC video encoder
+
+maintainers:
+ - Hugues Fruchet <hugues.fruchet@foss.st.com>
+
+description:
+ The STMicroelectronics STM32MP25 SOCs embeds a VDEC video hardware
+ decoder peripheral based on Verisilicon VC8000NanoD IP (former Hantro G1)
+ and a VENC video hardware encoder peripheral based on Verisilicon
+ VC8000NanoE IP (former Hantro H1).
+
+properties:
+ compatible:
+ enum:
+ - st,stm32mp25-vdec
+ - st,stm32mp25-venc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ video-codec@580d0000 {
+ compatible = "st,stm32mp25-vdec";
+ reg = <0x580d0000 0x3c8>;
+ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ck_icn_p_vdec>;
+ };
diff --git a/Documentation/driver-api/media/drivers/ccs/ccs.rst b/Documentation/driver-api/media/drivers/ccs/ccs.rst
index 776eec72bc80..5d4451339b7f 100644
--- a/Documentation/driver-api/media/drivers/ccs/ccs.rst
+++ b/Documentation/driver-api/media/drivers/ccs/ccs.rst
@@ -2,59 +2,16 @@
.. include:: <isonum.txt>
+.. _media-ccs-driver:
+
MIPI CCS camera sensor driver
=============================
The MIPI CCS camera sensor driver is a generic driver for `MIPI CCS
<https://www.mipi.org/specifications/camera-command-set>`_ compliant
-camera sensors. It exposes three sub-devices representing the pixel array,
-the binner and the scaler.
-
-As the capabilities of individual devices vary, the driver exposes
-interfaces based on the capabilities that exist in hardware.
-
-Pixel Array sub-device
-----------------------
-
-The pixel array sub-device represents the camera sensor's pixel matrix, as well
-as analogue crop functionality present in many compliant devices. The analogue
-crop is configured using the ``V4L2_SEL_TGT_CROP`` on the source pad (0) of the
-entity. The size of the pixel matrix can be obtained by getting the
-``V4L2_SEL_TGT_NATIVE_SIZE`` target.
-
-Binner
-------
-
-The binner sub-device represents the binning functionality on the sensor. For
-that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the
-sink pad (0).
-
-Additionally, if a device has no scaler or digital crop functionality, the
-source pad (1) exposes another digital crop selection rectangle that can only
-crop at the end of the lines and frames.
-
-Scaler
-------
-
-The scaler sub-device represents the digital crop and scaling functionality of
-the sensor. The V4L2 selection target ``V4L2_SEL_TGT_CROP`` is used to
-configure the digital crop on the sink pad (0) when digital crop is supported.
-Scaling is configured using selection target ``V4L2_SEL_TGT_COMPOSE`` on the
-sink pad (0) as well.
-
-Additionally, if the scaler sub-device exists, its source pad (1) exposes
-another digital crop selection rectangle that can only crop at the end of the
-lines and frames.
-
-Digital and analogue crop
--------------------------
-
-Digital crop functionality is referred to as cropping that effectively works by
-dropping some data on the floor. Analogue crop, on the other hand, means that
-the cropped information is never retrieved. In case of camera sensors, the
-analogue data is never read from the pixel matrix that are outside the
-configured selection rectangle that designates crop. The difference has an
-effect in device timing and likely also in power consumption.
+camera sensors.
+
+Also see :ref:`the CCS driver UAPI documentation <media-ccs-uapi>`.
CCS static data
---------------
diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
index 1db2ba27c54c..13aec460e802 100644
--- a/Documentation/driver-api/media/v4l2-subdev.rst
+++ b/Documentation/driver-api/media/v4l2-subdev.rst
@@ -229,7 +229,7 @@ Asynchronous sub-device notifier for sub-devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A driver that registers an asynchronous sub-device may also register an
-asynchronous notifier. This is called an asynchronous sub-device notifier andthe
+asynchronous notifier. This is called an asynchronous sub-device notifier and the
process is similar to that of a bridge driver apart from that the notifier is
initialised using :c:func:`v4l2_async_subdev_nf_init` instead. A sub-device
notifier may complete only after the V4L2 device becomes available, i.e. there's
diff --git a/Documentation/userspace-api/media/drivers/ccs.rst b/Documentation/userspace-api/media/drivers/ccs.rst
index 161cb65f4d98..03015b33d5ab 100644
--- a/Documentation/userspace-api/media/drivers/ccs.rst
+++ b/Documentation/userspace-api/media/drivers/ccs.rst
@@ -2,6 +2,8 @@
.. include:: <isonum.txt>
+.. _media-ccs-uapi:
+
MIPI CCS camera sensor driver
=============================
@@ -13,6 +15,8 @@ the binner and the scaler.
As the capabilities of individual devices vary, the driver exposes
interfaces based on the capabilities that exist in hardware.
+Also see :ref:`the CCS driver kernel documentation <media-ccs-driver>`.
+
Pixel Array sub-device
----------------------
@@ -30,7 +34,7 @@ that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the
sink pad (0).
Additionally, if a device has no scaler or digital crop functionality, the
-source pad (1) expses another digital crop selection rectangle that can only
+source pad (1) exposes another digital crop selection rectangle that can only
crop at the end of the lines and frames.
Scaler
diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst
index b97d56ee543c..ffe8325749e5 100644
--- a/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst
+++ b/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst
@@ -23,3 +23,4 @@ DVB-S2, DVB-T2, ISDB, etc.
:maxdepth: 1
frontend_legacy_dvbv3_api
+ legacy_dvb_decoder_api
diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst
new file mode 100644
index 000000000000..b46fe2becd02
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/legacy_dvb_audio.rst
@@ -0,0 +1,1642 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0
+
+.. c:namespace:: dtv.legacy.audio
+
+.. _dvb_audio:
+
+================
+DVB Audio Device
+================
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+The DVB audio device controls the MPEG2 audio decoder of the DVB
+hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data
+types and ioctl definitions can be accessed by including
+``linux/dvb/audio.h`` in your application.
+
+Please note that most DVB cards don’t have their own MPEG decoder, which
+results in the omission of the audio and video device.
+
+These ioctls were also used by V4L2 to control MPEG decoders implemented
+in V4L2. The use of these ioctls for that purpose has been made obsolete
+and proper V4L2 ioctls or controls have been created to replace that
+functionality. Use :ref:`V4L2 ioctls<audio>` for new drivers!
+
+
+Audio Data Types
+================
+
+This section describes the structures, data types and defines used when
+talking to the audio device.
+
+
+-----
+
+
+audio_stream_source_t
+---------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:enum:: audio_stream_source_t
+
+.. code-block:: c
+
+ typedef enum {
+ AUDIO_SOURCE_DEMUX,
+ AUDIO_SOURCE_MEMORY
+ } audio_stream_source_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``AUDIO_SOURCE_DEMUX``
+
+ - :cspan:`1` Selects the demultiplexer (fed either by the frontend
+ or the DVR device) as the source of the video stream.
+
+ - ..
+
+ - ``AUDIO_SOURCE_MEMORY``
+
+ - Selects the stream from the application that comes through
+ the `write()`_ system call.
+
+Description
+~~~~~~~~~~~
+
+The audio stream source is set through the `AUDIO_SELECT_SOURCE`_ call
+and can take the following values, depending on whether we are replaying
+from an internal (demux) or external (user write) source.
+
+The data fed to the decoder is also controlled by the PID-filter.
+Output selection: :c:type:`dmx_output` ``DMX_OUT_DECODER``.
+
+
+-----
+
+
+audio_play_state_t
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:enum:: audio_play_state_t
+
+.. code-block:: c
+
+ typedef enum {
+ AUDIO_STOPPED,
+ AUDIO_PLAYING,
+ AUDIO_PAUSED
+ } audio_play_state_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``AUDIO_STOPPED``
+
+ - Audio is stopped.
+
+ - ..
+
+ - ``AUDIO_PLAYING``
+
+ - Audio is currently playing.
+
+ - ..
+
+ - ``AUDIO_PAUSE``
+
+ - Audio is frozen.
+
+Description
+~~~~~~~~~~~
+
+This values can be returned by the `AUDIO_GET_STATUS`_ call
+representing the state of audio playback.
+
+
+-----
+
+
+audio_channel_select_t
+----------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:enum:: audio_channel_select_t
+
+.. code-block:: c
+
+ typedef enum {
+ AUDIO_STEREO,
+ AUDIO_MONO_LEFT,
+ AUDIO_MONO_RIGHT,
+ AUDIO_MONO,
+ AUDIO_STEREO_SWAPPED
+ } audio_channel_select_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``AUDIO_STEREO``
+
+ - Stereo.
+
+ - ..
+
+ - ``AUDIO_MONO_LEFT``
+
+ - Mono, select left stereo channel as source.
+
+ - ..
+
+ - ``AUDIO_MONO_RIGHT``
+
+ - Mono, select right stereo channel as source.
+
+ - ..
+
+ - ``AUDIO_MONO``
+
+ - Mono source only.
+
+ - ..
+
+ - ``AUDIO_STEREO_SWAPPED``
+
+ - Stereo, swap L & R.
+
+Description
+~~~~~~~~~~~
+
+The audio channel selected via `AUDIO_CHANNEL_SELECT`_ is determined by
+this values.
+
+
+-----
+
+
+audio_mixer_t
+-------------
+
+Synopsis
+~~~~~~~~
+
+.. c:struct:: audio_mixer
+
+.. code-block:: c
+
+ typedef struct audio_mixer {
+ unsigned int volume_left;
+ unsigned int volume_right;
+ } audio_mixer_t;
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``unsigned int volume_left``
+
+ - Volume left channel.
+ Valid range: 0 ... 255
+
+ - ..
+
+ - ``unsigned int volume_right``
+
+ - Volume right channel.
+ Valid range: 0 ... 255
+
+Description
+~~~~~~~~~~~
+
+This structure is used by the `AUDIO_SET_MIXER`_ call to set the
+audio volume.
+
+
+-----
+
+
+audio_status
+------------
+
+Synopsis
+~~~~~~~~
+
+.. c:struct:: audio_status
+
+.. code-block:: c
+
+ typedef struct audio_status {
+ int AV_sync_state;
+ int mute_state;
+ audio_play_state_t play_state;
+ audio_stream_source_t stream_source;
+ audio_channel_select_t channel_select;
+ int bypass_mode;
+ audio_mixer_t mixer_state;
+ } audio_status_t;
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - :rspan:`2` ``int AV_sync_state``
+
+ - :cspan:`1` Shows if A/V synchronization is ON or OFF.
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - AV-sync ON.
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - AV-sync OFF.
+
+ - ..
+
+ - :rspan:`2` ``int mute_state``
+
+ - :cspan:`1` Indicates if audio is muted or not.
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - mute audio
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - unmute audio
+
+ - ..
+
+ - `audio_play_state_t`_ ``play_state``
+
+ - Current playback state.
+
+ - ..
+
+ - `audio_stream_source_t`_ ``stream_source``
+
+ - Current source of the data.
+
+ - ..
+
+ - :rspan:`2` ``int bypass_mode``
+
+ - :cspan:`1` Is the decoding of the current Audio stream in
+ the DVB subsystem enabled or disabled.
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - Bypass disabled.
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - Bypass enabled.
+
+ - ..
+
+ - `audio_mixer_t`_ ``mixer_state``
+
+ - Current volume settings.
+
+Description
+~~~~~~~~~~~
+
+The `AUDIO_GET_STATUS`_ call returns this structure as information
+about various states of the playback operation.
+
+
+-----
+
+
+audio encodings
+---------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ #define AUDIO_CAP_DTS 1
+ #define AUDIO_CAP_LPCM 2
+ #define AUDIO_CAP_MP1 4
+ #define AUDIO_CAP_MP2 8
+ #define AUDIO_CAP_MP3 16
+ #define AUDIO_CAP_AAC 32
+ #define AUDIO_CAP_OGG 64
+ #define AUDIO_CAP_SDDS 128
+ #define AUDIO_CAP_AC3 256
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``AUDIO_CAP_DTS``
+
+ - :cspan:`1` The hardware accepts DTS audio tracks.
+
+ - ..
+
+ - ``AUDIO_CAP_LPCM``
+
+ - The hardware accepts uncompressed audio with
+ Linear Pulse-Code Modulation (LPCM)
+
+ - ..
+
+ - ``AUDIO_CAP_MP1``
+
+ - The hardware accepts MPEG-1 Audio Layer 1.
+
+ - ..
+
+ - ``AUDIO_CAP_MP2``
+
+ - The hardware accepts MPEG-1 Audio Layer 2.
+ Also known as MUSICAM.
+
+ - ..
+
+ - ``AUDIO_CAP_MP3``
+
+ - The hardware accepts MPEG-1 Audio Layer III.
+ Commomly known as .mp3.
+
+ - ..
+
+ - ``AUDIO_CAP_AAC``
+
+ - The hardware accepts AAC (Advanced Audio Coding).
+
+ - ..
+
+ - ``AUDIO_CAP_OGG``
+
+ - The hardware accepts Vorbis audio tracks.
+
+ - ..
+
+ - ``AUDIO_CAP_SDDS``
+
+ - The hardware accepts Sony Dynamic Digital Sound (SDDS).
+
+ - ..
+
+ - ``AUDIO_CAP_AC3``
+
+ - The hardware accepts Dolby Digital ATSC A/52 audio.
+ Also known as AC-3.
+
+Description
+~~~~~~~~~~~
+
+A call to `AUDIO_GET_CAPABILITIES`_ returns an unsigned integer with the
+following bits set according to the hardwares capabilities.
+
+
+-----
+
+
+Audio Function Calls
+====================
+
+
+AUDIO_STOP
+----------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_STOP
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_STOP)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - File descriptor returned by a previous call to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - :cspan:`1` Equals ``AUDIO_STOP`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Audio Device to stop playing the current
+stream.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_PLAY
+----------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_PLAY
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_PLAY)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - File descriptor returned by a previous call to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - :cspan:`1` Equals ``AUDIO_PLAY`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Audio Device to start playing an audio stream
+from the selected source.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_PAUSE
+-----------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_PAUSE
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_PAUSE)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_PAUSE`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call suspends the audio stream being played. Decoding and
+playing are paused. It is then possible to restart again decoding and
+playing process of the audio stream using `AUDIO_CONTINUE`_ command.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_CONTINUE
+--------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_CONTINUE
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_CONTINUE)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_CONTINUE`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl restarts the decoding and playing process previously paused
+with `AUDIO_PAUSE`_ command.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_SELECT_SOURCE
+-------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_SELECT_SOURCE
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_SELECT_SOURCE,
+ audio_stream_source_t source)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_SELECT_SOURCE`` for this command.
+
+ - ..
+
+ - `audio_stream_source_t`_ ``source``
+
+ - Indicates the source that shall be used for the Audio stream.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call informs the audio device which source shall be used for
+the input data. The possible sources are demux or memory. If
+``AUDIO_SOURCE_MEMORY`` is selected, the data is fed to the Audio Device
+through the write command. If ``AUDIO_SOURCE_DEMUX`` is selected, the data
+is directly transferred from the onboard demux-device to the decoder.
+Note: This only supports DVB-devices with one demux and one decoder so far.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_SET_MUTE
+--------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_SET_MUTE
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_SET_MUTE, int state)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - :cspan:`1` Equals ``AUDIO_SET_MUTE`` for this command.
+
+ - ..
+
+ - :rspan:`2` ``int state``
+
+ - :cspan:`1` Indicates if audio device shall mute or not.
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - mute audio
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - unmute audio
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for DVB devices only. To control a V4L2 decoder use the
+V4L2 :ref:`VIDIOC_DECODER_CMD` with the
+``V4L2_DEC_CMD_START_MUTE_AUDIO`` flag instead.
+
+This ioctl call asks the audio device to mute the stream that is
+currently being played.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_SET_AV_SYNC
+-----------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_SET_AV_SYNC
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_SET_AV_SYNC, int state)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - :cspan:`1` Equals ``AUDIO_AV_SYNC`` for this command.
+
+ - ..
+
+ - :rspan:`2` ``int state``
+
+ - :cspan:`1` Tells the DVB subsystem if A/V synchronization
+ shall be ON or OFF.
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - AV-sync ON.
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - AV-sync OFF.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Audio Device to turn ON or OFF A/V
+synchronization.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_SET_BYPASS_MODE
+---------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_SET_BYPASS_MODE
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_SET_BYPASS_MODE, int mode)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - :cspan:`1` Equals ``AUDIO_SET_BYPASS_MODE`` for this command.
+
+ - ..
+
+ - :rspan:`2` ``int mode``
+
+ - :cspan:`1` Enables or disables the decoding of the current
+ Audio stream in the DVB subsystem.
+ - ..
+
+ - TRUE ( != 0 )
+
+ - Disable bypass
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - Enable bypass
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Audio Device to bypass the Audio decoder and
+forward the stream without decoding. This mode shall be used if streams
+that can’t be handled by the DVB system shall be decoded. Dolby
+DigitalTM streams are automatically forwarded by the DVB subsystem if
+the hardware can handle it.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_CHANNEL_SELECT
+--------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_CHANNEL_SELECT
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_CHANNEL_SELECT,
+ audio_channel_select_t)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_CHANNEL_SELECT`` for this command.
+
+ - ..
+
+ - `audio_channel_select_t`_ ``ch``
+
+ - Select the output format of the audio (mono left/right, stereo).
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for DVB devices only. To control a V4L2 decoder use the
+V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK`` control instead.
+
+This ioctl call asks the Audio Device to select the requested channel if
+possible.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_GET_STATUS
+----------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_GET_STATUS
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_GET_STATUS,
+ struct audio_status *status)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals AUDIO_GET_STATUS for this command.
+
+ - ..
+
+ - ``struct`` `audio_status`_ ``*status``
+
+ - Returns the current state of Audio Device.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Audio Device to return the current state of the
+Audio Device.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_GET_CAPABILITIES
+----------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_GET_CAPABILITIES
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_GET_CAPABILITIES,
+ unsigned int *cap)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_GET_CAPABILITIES`` for this command.
+
+ - ..
+
+ - ``unsigned int *cap``
+
+ - Returns a bit array of supported sound formats.
+ Bits are defined in `audio encodings`_.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Audio Device to tell us about the decoding
+capabilities of the audio hardware.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_CLEAR_BUFFER
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_CLEAR_BUFFER
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_CLEAR_BUFFER)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_CLEAR_BUFFER`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Audio Device to clear all software and hardware
+buffers of the audio decoder device.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_SET_ID
+------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_SET_ID
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_SET_ID, int id)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_SET_ID`` for this command.
+
+ - ..
+
+ - ``int id``
+
+ - Audio sub-stream id.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl selects which sub-stream is to be decoded if a program or
+system stream is sent to the video device.
+
+If no audio stream type is set the id has to be in range [0xC0,0xDF]
+for MPEG sound, in [0x80,0x87] for AC3 and in [0xA0,0xA7] for LPCM.
+See ITU-T H.222.0 | ISO/IEC 13818-1 for further description.
+
+If the stream type is set with `AUDIO_SET_STREAMTYPE`_, specifies the
+id just the sub-stream id of the audio stream and only the first 5 bits
+(& 0x1F) are recognized.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_SET_MIXER
+---------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_SET_MIXER
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_SET_MIXER, audio_mixer_t *mix)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_SET_MIXER`` for this command.
+
+ - ..
+
+ - ``audio_mixer_t *mix``
+
+ - Mixer settings.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl lets you adjust the mixer settings of the audio decoder.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+AUDIO_SET_STREAMTYPE
+--------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_SET_STREAMTYPE
+
+.. code-block:: c
+
+ int ioctl(fd, int request = AUDIO_SET_STREAMTYPE, int type)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_SET_STREAMTYPE`` for this command.
+
+ - ..
+
+ - ``int type``
+
+ - Stream type.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl tells the driver which kind of audio stream to expect. This
+is useful if the stream offers several audio sub-streams like LPCM and
+AC3.
+
+Stream types defined in ITU-T H.222.0 | ISO/IEC 13818-1 are used.
+
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EINVAL``
+
+ - Type is not a valid or supported stream type.
+
+
+-----
+
+
+AUDIO_BILINGUAL_CHANNEL_SELECT
+------------------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: AUDIO_BILINGUAL_CHANNEL_SELECT
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = AUDIO_BILINGUAL_CHANNEL_SELECT,
+ audio_channel_select_t)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``AUDIO_BILINGUAL_CHANNEL_SELECT`` for this command.
+
+ - ..
+
+ - ``audio_channel_select_t ch``
+
+ - Select the output format of the audio (mono left/right, stereo).
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl has been replaced by the V4L2
+``V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK`` control
+for MPEG decoders controlled through V4L2.
+
+This ioctl call asks the Audio Device to select the requested channel
+for bilingual streams if possible.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+open()
+------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ #include <fcntl.h>
+
+.. c:function:: int open(const char *deviceName, int flags)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``const char *deviceName``
+
+ - Name of specific audio device.
+
+ - ..
+
+ - :rspan:`3` ``int flags``
+
+ - :cspan:`1` A bit-wise OR of the following flags:
+
+ - ..
+
+ - ``O_RDONLY``
+
+ - read-only access
+
+ - ..
+
+ - ``O_RDWR``
+
+ - read/write access
+
+ - ..
+
+ - ``O_NONBLOCK``
+ - | Open in non-blocking mode
+ | (blocking mode is the default)
+
+Description
+~~~~~~~~~~~
+
+This system call opens a named audio device (e.g.
+``/dev/dvb/adapter0/audio0``) for subsequent use. When an open() call has
+succeeded, the device will be ready for use. The significance of
+blocking or non-blocking mode is described in the documentation for
+functions where there is a difference. It does not affect the semantics
+of the open() call itself. A device opened in blocking mode can later be
+put into non-blocking mode (and vice versa) using the F_SETFL command
+of the fcntl system call. This is a standard system call, documented in
+the Linux manual page for fcntl. Only one user can open the Audio Device
+in O_RDWR mode. All other attempts to open the device in this mode will
+fail, and an error code will be returned. If the Audio Device is opened
+in O_RDONLY mode, the only ioctl call that can be used is
+`AUDIO_GET_STATUS`_. All other call will return with an error code.
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``ENODEV``
+
+ - Device driver not loaded/available.
+
+ - ..
+
+ - ``EBUSY``
+
+ - Device or resource busy.
+
+ - ..
+
+ - ``EINVAL``
+
+ - Invalid argument.
+
+
+-----
+
+
+close()
+-------
+
+Synopsis
+~~~~~~~~
+
+.. c:function:: int close(int fd)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+Description
+~~~~~~~~~~~
+
+This system call closes a previously opened audio device.
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EBADF``
+
+ - Fd is not a valid open file descriptor.
+
+-----
+
+
+write()
+-------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ size_t write(int fd, const void *buf, size_t count)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``void *buf``
+
+ - Pointer to the buffer containing the PES data.
+
+ - ..
+
+ - ``size_t count``
+
+ - Size of buf.
+
+Description
+~~~~~~~~~~~
+
+This system call can only be used if ``AUDIO_SOURCE_MEMORY`` is selected
+in the ioctl call `AUDIO_SELECT_SOURCE`_. The data provided shall be in
+PES format. If ``O_NONBLOCK`` is not specified the function will block
+until buffer space is available. The amount of data to be transferred is
+implied by count.
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EPERM``
+
+ - :cspan:`1` Mode ``AUDIO_SOURCE_MEMORY`` not selected.
+
+ - ..
+
+ - ``ENOMEM``
+
+ - Attempted to write more data than the internal buffer can hold.
+
+ - ..
+
+ - ``EBADF``
+
+ - Fd is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_decoder_api.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_decoder_api.rst
new file mode 100644
index 000000000000..f58985a6e63c
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/legacy_dvb_decoder_api.rst
@@ -0,0 +1,61 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0
+
+.. _legacy_dvb_decoder_api:
+
+============================
+Legacy DVB MPEG Decoder APIs
+============================
+
+.. _legacy_dvb_decoder_notes:
+
+General Notes
+=============
+
+This API has originally been designed for DVB only and is therefore limited to
+the :ref:`legacy_dvb_decoder_formats` used in such digital TV-broadcastsystems.
+
+To circumvent this limitations the more versatile :ref:`V4L2 <v4l2spec>` API has
+been designed. Which replaces this part of the DVB API.
+
+Nevertheless there have been projects build around this API.
+To ensure compatibility this API is kept as it is.
+
+.. attention:: Do **not** use this API in new drivers!
+
+ For audio and video use the :ref:`V4L2 <v4l2spec>` and ALSA APIs.
+
+ Pipelines should be set up using the :ref:`Media Controller API<media_controller>`.
+
+Practically the decoders seem to be treated differently. The application typically
+knows which decoder is in use or it is specially written for one decoder type.
+Querying capabilities are rarely used because they are already known.
+
+
+.. _legacy_dvb_decoder_formats:
+
+Data Formats
+============
+
+The API has been designed for DVB and compatible broadcastsystems.
+Because of that fact the only supported data formats are ISO/IEC 13818-1
+compatible MPEG streams. The supported payloads may vary depending on the
+used decoder.
+
+Timestamps are always MPEG PTS as defined in ITU T-REC-H.222.0 /
+ISO/IEC 13818-1, if not otherwise noted.
+
+For storing recordings typically TS streams are used, in lesser extent PES.
+Both variants are commonly accepted for playback, but it may be driver dependent.
+
+
+
+
+Table of Contents
+=================
+
+.. toctree::
+ :maxdepth: 2
+
+ legacy_dvb_video
+ legacy_dvb_audio
+ legacy_dvb_osd
diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst
new file mode 100644
index 000000000000..179b66a8016a
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/legacy_dvb_osd.rst
@@ -0,0 +1,883 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0
+
+.. c:namespace:: dtv.legacy.osd
+
+.. _dvb_osd:
+
+==============
+DVB OSD Device
+==============
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+The DVB OSD device controls the OnScreen-Display of the AV7110 based
+DVB-cards with hardware MPEG2 decoder. It can be accessed through
+``/dev/dvb/adapter?/osd0``.
+Data types and ioctl definitions can be accessed by including
+``linux/dvb/osd.h`` in your application.
+
+The OSD is not a frame-buffer like on many other cards.
+It is a kind of canvas one can draw on.
+The color-depth is limited depending on the memory size installed.
+An appropriate palette of colors has to be set up.
+The installed memory size can be identified with the `OSD_GET_CAPABILITY`_
+ioctl.
+
+OSD Data Types
+==============
+
+OSD_Command
+-----------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef enum {
+ /* All functions return -2 on "not open" */
+ OSD_Close = 1,
+ OSD_Open,
+ OSD_Show,
+ OSD_Hide,
+ OSD_Clear,
+ OSD_Fill,
+ OSD_SetColor,
+ OSD_SetPalette,
+ OSD_SetTrans,
+ OSD_SetPixel,
+ OSD_GetPixel,
+ OSD_SetRow,
+ OSD_SetBlock,
+ OSD_FillRow,
+ OSD_FillBlock,
+ OSD_Line,
+ OSD_Query,
+ OSD_Test,
+ OSD_Text,
+ OSD_SetWindow,
+ OSD_MoveWindow,
+ OSD_OpenRaw,
+ } OSD_Command;
+
+Commands
+~~~~~~~~
+
+.. note:: All functions return -2 on "not open"
+
+.. flat-table::
+ :header-rows: 1
+ :stub-columns: 0
+
+ - ..
+
+ - Command
+
+ - | Used variables of ``struct`` `osd_cmd_t`_.
+ | Usage{variable} if alternative use.
+
+ - :cspan:`2` Description
+
+
+
+ - ..
+
+ - ``OSD_Close``
+
+ - -
+
+ - | Disables OSD and releases the buffers.
+ | Returns 0 on success.
+
+ - ..
+
+ - ``OSD_Open``
+
+ - | x0,y0,x1,y1,
+ | BitPerPixel[2/4/8]{color&0x0F},
+ | mix[0..15]{color&0xF0}
+
+ - | Opens OSD with this size and bit depth
+ | Returns 0 on success,
+ | -1 on DRAM allocation error,
+ | -2 on "already open".
+
+ - ..
+
+ - ``OSD_Show``
+
+ - -
+
+ - | Enables OSD mode.
+ | Returns 0 on success.
+
+ - ..
+
+ - ``OSD_Hide``
+
+ - -
+
+ - | Disables OSD mode.
+ | Returns 0 on success.
+
+ - ..
+
+ - ``OSD_Clear``
+
+ - -
+
+ - | Sets all pixel to color 0.
+ | Returns 0 on success.
+
+ - ..
+
+ - ``OSD_Fill``
+
+ - color
+
+ - | Sets all pixel to color <color>.
+ | Returns 0 on success.
+
+ - ..
+
+ - ``OSD_SetColor``
+
+ - | color,
+ | R{x0},G{y0},B{x1},
+ | opacity{y1}
+
+ - | Set palette entry <num> to <r,g,b>, <mix> and <trans> apply
+ | R,G,B: 0..255
+ | R=Red, G=Green, B=Blue
+ | opacity=0: pixel opacity 0% (only video pixel shows)
+ | opacity=1..254: pixel opacity as specified in header
+ | opacity=255: pixel opacity 100% (only OSD pixel shows)
+ | Returns 0 on success, -1 on error.
+
+ - ..
+
+ - ``OSD_SetPalette``
+
+ - | firstcolor{color},
+ | lastcolor{x0},data
+
+ - | Set a number of entries in the palette.
+ | Sets the entries "firstcolor" through "lastcolor" from the
+ array "data".
+ | Data has 4 byte for each color:
+ | R,G,B, and a opacity value: 0->transparent, 1..254->mix,
+ 255->pixel
+
+ - ..
+
+ - ``OSD_SetTrans``
+
+ - transparency{color}
+
+ - | Sets transparency of mixed pixel (0..15).
+ | Returns 0 on success.
+
+ - ..
+
+ - ``OSD_SetPixel``
+
+ - x0,y0,color
+
+ - | Sets pixel <x>,<y> to color number <color>.
+ | Returns 0 on success, -1 on error.
+
+ - ..
+
+ - ``OSD_GetPixel``
+
+ - x0,y0
+
+ - | Returns color number of pixel <x>,<y>, or -1.
+ | Command currently not supported by the AV7110!
+
+ - ..
+
+ - ``OSD_SetRow``
+
+ - x0,y0,x1,data
+
+ - | Fills pixels x0,y through x1,y with the content of data[].
+ | Returns 0 on success, -1 on clipping all pixel (no pixel
+ drawn).
+
+ - ..
+
+ - ``OSD_SetBlock``
+
+ - | x0,y0,x1,y1,
+ | increment{color},
+ | data
+
+ - | Fills pixels x0,y0 through x1,y1 with the content of data[].
+ | Inc contains the width of one line in the data block,
+ | inc<=0 uses block width as line width.
+ | Returns 0 on success, -1 on clipping all pixel.
+
+ - ..
+
+ - ``OSD_FillRow``
+
+ - x0,y0,x1,color
+
+ - | Fills pixels x0,y through x1,y with the color <color>.
+ | Returns 0 on success, -1 on clipping all pixel.
+
+ - ..
+
+ - ``OSD_FillBlock``
+
+ - x0,y0,x1,y1,color
+
+ - | Fills pixels x0,y0 through x1,y1 with the color <color>.
+ | Returns 0 on success, -1 on clipping all pixel.
+
+ - ..
+
+ - ``OSD_Line``
+
+ - x0,y0,x1,y1,color
+
+ - | Draw a line from x0,y0 to x1,y1 with the color <color>.
+ | Returns 0 on success.
+
+ - ..
+
+ - ``OSD_Query``
+
+ - | x0,y0,x1,y1,
+ | xasp{color}; yasp=11
+
+ - | Fills parameters with the picture dimensions and the pixel
+ aspect ratio.
+ | Returns 0 on success.
+ | Command currently not supported by the AV7110!
+
+ - ..
+
+ - ``OSD_Test``
+
+ - -
+
+ - | Draws a test picture.
+ | For debugging purposes only.
+ | Returns 0 on success.
+ - ..
+
+ - ``OSD_Text``
+
+ - x0,y0,size,color,text
+
+ - Draws a text at position x0,y0 with the color <color>.
+
+ - ..
+
+ - ``OSD_SetWindow``
+
+ - x0
+
+ - Set window with number 0<x0<8 as current.
+
+ - ..
+
+ - ``OSD_MoveWindow``
+
+ - x0,y0
+
+ - Move current window to (x0, y0).
+
+ - ..
+
+ - ``OSD_OpenRaw``
+
+ - | x0,y0,x1,y1,
+ | `osd_raw_window_t`_ {color}
+
+ - Open other types of OSD windows.
+
+Description
+~~~~~~~~~~~
+
+The ``OSD_Command`` data type is used with the `OSD_SEND_CMD`_ ioctl to
+tell the driver which OSD_Command to execute.
+
+
+-----
+
+osd_cmd_t
+---------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef struct osd_cmd_s {
+ OSD_Command cmd;
+ int x0;
+ int y0;
+ int x1;
+ int y1;
+ int color;
+ void __user *data;
+ } osd_cmd_t;
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``OSD_Command cmd``
+
+ - `OSD_Command`_ to be executed.
+
+ - ..
+
+ - ``int x0``
+
+ - First horizontal position.
+
+ - ..
+
+ - ``int y0``
+
+ - First vertical position.
+
+ - ..
+
+ - ``int x1``
+
+ - Second horizontal position.
+
+ - ..
+
+ - ``int y1``
+
+ - Second vertical position.
+
+ - ..
+
+ - ``int color``
+
+ - Number of the color in the palette.
+
+ - ..
+
+ - ``void __user *data``
+
+ - Command specific Data.
+
+Description
+~~~~~~~~~~~
+
+The ``osd_cmd_t`` data type is used with the `OSD_SEND_CMD`_ ioctl.
+It contains the data for the OSD_Command and the `OSD_Command`_ itself.
+The structure has to be passed to the driver and the components may be
+modified by it.
+
+
+-----
+
+
+osd_raw_window_t
+----------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef enum {
+ OSD_BITMAP1,
+ OSD_BITMAP2,
+ OSD_BITMAP4,
+ OSD_BITMAP8,
+ OSD_BITMAP1HR,
+ OSD_BITMAP2HR,
+ OSD_BITMAP4HR,
+ OSD_BITMAP8HR,
+ OSD_YCRCB422,
+ OSD_YCRCB444,
+ OSD_YCRCB444HR,
+ OSD_VIDEOTSIZE,
+ OSD_VIDEOHSIZE,
+ OSD_VIDEOQSIZE,
+ OSD_VIDEODSIZE,
+ OSD_VIDEOTHSIZE,
+ OSD_VIDEOTQSIZE,
+ OSD_VIDEOTDSIZE,
+ OSD_VIDEONSIZE,
+ OSD_CURSOR
+ } osd_raw_window_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``OSD_BITMAP1``
+
+ - :cspan:`1` 1 bit bitmap
+
+ - ..
+
+ - ``OSD_BITMAP2``
+
+ - 2 bit bitmap
+
+ - ..
+
+ - ``OSD_BITMAP4``
+
+ - 4 bit bitmap
+
+ - ..
+
+ - ``OSD_BITMAP8``
+
+ - 8 bit bitmap
+
+ - ..
+
+ - ``OSD_BITMAP1HR``
+
+ - 1 Bit bitmap half resolution
+
+ - ..
+
+ - ``OSD_BITMAP2HR``
+
+ - 2 Bit bitmap half resolution
+
+ - ..
+
+ - ``OSD_BITMAP4HR``
+
+ - 4 Bit bitmap half resolution
+
+ - ..
+
+ - ``OSD_BITMAP8HR``
+
+ - 8 Bit bitmap half resolution
+
+ - ..
+
+ - ``OSD_YCRCB422``
+
+ - 4:2:2 YCRCB Graphic Display
+
+ - ..
+
+ - ``OSD_YCRCB444``
+
+ - 4:4:4 YCRCB Graphic Display
+
+ - ..
+
+ - ``OSD_YCRCB444HR``
+
+ - 4:4:4 YCRCB graphic half resolution
+
+ - ..
+
+ - ``OSD_VIDEOTSIZE``
+
+ - True Size Normal MPEG Video Display
+
+ - ..
+
+ - ``OSD_VIDEOHSIZE``
+
+ - MPEG Video Display Half Resolution
+
+ - ..
+
+ - ``OSD_VIDEOQSIZE``
+
+ - MPEG Video Display Quarter Resolution
+
+ - ..
+
+ - ``OSD_VIDEODSIZE``
+
+ - MPEG Video Display Double Resolution
+
+ - ..
+
+ - ``OSD_VIDEOTHSIZE``
+
+ - True Size MPEG Video Display Half Resolution
+
+ - ..
+
+ - ``OSD_VIDEOTQSIZE``
+
+ - True Size MPEG Video Display Quarter Resolution
+
+ - ..
+
+ - ``OSD_VIDEOTDSIZE``
+
+ - True Size MPEG Video Display Double Resolution
+
+ - ..
+
+ - ``OSD_VIDEONSIZE``
+
+ - Full Size MPEG Video Display
+
+ - ..
+
+ - ``OSD_CURSOR``
+
+ - Cursor
+
+Description
+~~~~~~~~~~~
+
+The ``osd_raw_window_t`` data type is used with the `OSD_Command`_
+OSD_OpenRaw to tell the driver which type of OSD to open.
+
+
+-----
+
+
+osd_cap_t
+---------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef struct osd_cap_s {
+ int cmd;
+ #define OSD_CAP_MEMSIZE 1
+ long val;
+ } osd_cap_t;
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int cmd``
+
+ - Capability to query.
+
+ - ..
+
+ - ``long val``
+
+ - Used to store the Data.
+
+Supported capabilities
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``OSD_CAP_MEMSIZE``
+
+ - Memory size installed on the card.
+
+Description
+~~~~~~~~~~~
+
+This structure of data used with the `OSD_GET_CAPABILITY`_ call.
+
+
+-----
+
+
+OSD Function Calls
+==================
+
+OSD_SEND_CMD
+------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: OSD_SEND_CMD
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = OSD_SEND_CMD, enum osd_cmd_t *cmd)
+
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Pointer to the location of the structure `osd_cmd_t`_ for this
+ command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl sends the `OSD_Command`_ to the card.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EINVAL``
+
+ - Command is out of range.
+
+
+-----
+
+
+OSD_GET_CAPABILITY
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: OSD_GET_CAPABILITY
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = OSD_GET_CAPABILITY,
+ struct osd_cap_t *cap)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``OSD_GET_CAPABILITY`` for this command.
+
+ - ..
+
+ - ``unsigned int *cap``
+
+ - Pointer to the location of the structure `osd_cap_t`_ for this
+ command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is used to get the capabilities of the OSD of the AV7110 based
+DVB-decoder-card in use.
+
+.. note::
+ The structure osd_cap_t has to be setup by the user and passed to the
+ driver.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+
+ - ..
+
+ - ``EINVAL``
+
+ - Unsupported capability.
+
+
+-----
+
+
+open()
+------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ #include <fcntl.h>
+
+.. c:function:: int open(const char *deviceName, int flags)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``const char *deviceName``
+
+ - Name of specific OSD device.
+
+ - ..
+
+ - :rspan:`3` ``int flags``
+
+ - :cspan:`1` A bit-wise OR of the following flags:
+
+ - ..
+
+ - ``O_RDONLY``
+
+ - read-only access
+
+ - ..
+
+ - ``O_RDWR``
+
+ - read/write access
+
+ - ..
+
+ - ``O_NONBLOCK``
+ - | Open in non-blocking mode
+ | (blocking mode is the default)
+
+Description
+~~~~~~~~~~~
+
+This system call opens a named OSD device (e.g.
+``/dev/dvb/adapter?/osd0``) for subsequent use.
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``ENODEV``
+
+ - Device driver not loaded/available.
+
+ - ..
+
+ - ``EINTERNAL``
+
+ - Internal error.
+
+ - ..
+
+ - ``EBUSY``
+
+ - Device or resource busy.
+
+ - ..
+
+ - ``EINVAL``
+
+ - Invalid argument.
+
+
+-----
+
+
+close()
+-------
+
+Synopsis
+~~~~~~~~
+
+.. c:function:: int close(int fd)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_ .
+
+Description
+~~~~~~~~~~~
+
+This system call closes a previously opened OSD device.
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EBADF``
+
+ - fd is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_video.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_video.rst
new file mode 100644
index 000000000000..b9fd5cadae24
--- /dev/null
+++ b/Documentation/userspace-api/media/dvb/legacy_dvb_video.rst
@@ -0,0 +1,2430 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0
+
+.. c:namespace:: dtv.legacy.video
+
+.. _dvb_video:
+
+================
+DVB Video Device
+================
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+The DVB video device controls the MPEG2 video decoder of the DVB
+hardware. It can be accessed through ``/dev/dvb/adapter0/video0``. Data
+types and ioctl definitions can be accessed by including
+``linux/dvb/video.h`` in your application.
+
+Note that the DVB video device only controls decoding of the MPEG video
+stream, not its presentation on the TV or computer screen. On PCs this
+is typically handled by an associated video4linux device, e.g.
+``/dev/video``, which allows scaling and defining output windows.
+
+Most DVB cards don’t have their own MPEG decoder, which results in the
+omission of the audio and video device as well as the video4linux
+device.
+
+These ioctls were also used by V4L2 to control MPEG decoders implemented
+in V4L2. The use of these ioctls for that purpose has been made obsolete
+and proper V4L2 ioctls or controls have been created to replace that
+functionality. Use :ref:`V4L2 ioctls<video>` for new drivers!
+
+
+Video Data Types
+================
+
+
+
+video_format_t
+--------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef enum {
+ VIDEO_FORMAT_4_3,
+ VIDEO_FORMAT_16_9,
+ VIDEO_FORMAT_221_1
+ } video_format_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``VIDEO_FORMAT_4_3``
+
+ - Select 4:3 format.
+
+ - ..
+
+ - ``VIDEO_FORMAT_16_9``
+
+ - Select 16:9 format.
+
+ - ..
+
+ - ``VIDEO_FORMAT_221_1``
+
+ - Select 2.21:1 format.
+
+Description
+~~~~~~~~~~~
+
+The ``video_format_t`` data type
+is used in the `VIDEO_SET_FORMAT`_ function to tell the driver which
+aspect ratio the output hardware (e.g. TV) has. It is also used in the
+data structures `video_status`_ returned by `VIDEO_GET_STATUS`_
+and `video_event`_ returned by `VIDEO_GET_EVENT`_ which report
+about the display format of the current video stream.
+
+
+-----
+
+
+video_displayformat_t
+---------------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef enum {
+ VIDEO_PAN_SCAN,
+ VIDEO_LETTER_BOX,
+ VIDEO_CENTER_CUT_OUT
+ } video_displayformat_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``VIDEO_PAN_SCAN``
+
+ - Use pan and scan format.
+
+ - ..
+
+ - ``VIDEO_LETTER_BOX``
+
+ - Use letterbox format.
+
+ - ..
+
+ - ``VIDEO_CENTER_CUT_OUT``
+
+ - Use center cut out format.
+
+Description
+~~~~~~~~~~~
+
+In case the display format of the video stream and of the display
+hardware differ the application has to specify how to handle the
+cropping of the picture. This can be done using the
+`VIDEO_SET_DISPLAY_FORMAT`_ call which accepts this enum as argument.
+
+
+-----
+
+
+video_size_t
+------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef struct {
+ int w;
+ int h;
+ video_format_t aspect_ratio;
+ } video_size_t;
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int w``
+
+ - Video width in pixels.
+
+ - ..
+
+ - ``int h``
+
+ - Video height in pixels.
+
+ - ..
+
+ - `video_format_t`_ ``aspect_ratio``
+
+ - Aspect ratio.
+
+Description
+~~~~~~~~~~~
+
+Used in the struct `video_event`_. It stores the resolution and
+aspect ratio of the video.
+
+
+-----
+
+
+video_stream_source_t
+---------------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef enum {
+ VIDEO_SOURCE_DEMUX,
+ VIDEO_SOURCE_MEMORY
+ } video_stream_source_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``VIDEO_SOURCE_DEMUX``
+
+ - :cspan:`1` Select the demux as the main source.
+
+ - ..
+
+ - ``VIDEO_SOURCE_MEMORY``
+
+ - If this source is selected, the stream
+ comes from the user through the write
+ system call.
+
+Description
+~~~~~~~~~~~
+
+The video stream source is set through the `VIDEO_SELECT_SOURCE`_ call
+and can take the following values, depending on whether we are replaying
+from an internal (demuxer) or external (user write) source.
+VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the
+frontend or the DVR device) as the source of the video stream. If
+VIDEO_SOURCE_MEMORY is selected the stream comes from the application
+through the `write()`_ system call.
+
+
+-----
+
+
+video_play_state_t
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ typedef enum {
+ VIDEO_STOPPED,
+ VIDEO_PLAYING,
+ VIDEO_FREEZED
+ } video_play_state_t;
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``VIDEO_STOPPED``
+
+ - Video is stopped.
+
+ - ..
+
+ - ``VIDEO_PLAYING``
+
+ - Video is currently playing.
+
+ - ..
+
+ - ``VIDEO_FREEZED``
+
+ - Video is frozen.
+
+Description
+~~~~~~~~~~~
+
+This values can be returned by the `VIDEO_GET_STATUS`_ call
+representing the state of video playback.
+
+
+-----
+
+
+struct video_command
+--------------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ struct video_command {
+ __u32 cmd;
+ __u32 flags;
+ union {
+ struct {
+ __u64 pts;
+ } stop;
+
+ struct {
+ __s32 speed;
+ __u32 format;
+ } play;
+
+ struct {
+ __u32 data[16];
+ } raw;
+ };
+ };
+
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``__u32 cmd``
+
+ - `Decoder command`_
+
+ - ..
+
+ - ``__u32 flags``
+
+ - Flags for the `Decoder command`_.
+
+ - ..
+
+ - ``struct stop``
+
+ - ``__u64 pts``
+
+ - MPEG PTS
+
+ - ..
+
+ - :rspan:`5` ``stuct play``
+
+ - :rspan:`4` ``__s32 speed``
+
+ - 0 or 1000 specifies normal speed,
+
+ - ..
+
+ - 1: specifies forward single stepping,
+
+ - ..
+
+ - -1: specifies backward single stepping,
+
+ - ..
+
+ - >1: playback at speed / 1000 of the normal speed
+
+ - ..
+
+ - <-1: reverse playback at ( -speed / 1000 ) of the normal speed.
+
+ - ..
+
+ - ``__u32 format``
+
+ - `Play input formats`_
+
+ - ..
+
+ - ``__u32 data[16]``
+
+ - Reserved
+
+Description
+~~~~~~~~~~~
+
+The structure must be zeroed before use by the application. This ensures
+it can be extended safely in the future.
+
+
+-----
+
+
+Predefined decoder commands and flags
+-------------------------------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ #define VIDEO_CMD_PLAY (0)
+ #define VIDEO_CMD_STOP (1)
+ #define VIDEO_CMD_FREEZE (2)
+ #define VIDEO_CMD_CONTINUE (3)
+
+ #define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0)
+
+ #define VIDEO_CMD_STOP_TO_BLACK (1 << 0)
+ #define VIDEO_CMD_STOP_IMMEDIATELY (1 << 1)
+
+ #define VIDEO_PLAY_FMT_NONE (0)
+ #define VIDEO_PLAY_FMT_GOP (1)
+
+ #define VIDEO_VSYNC_FIELD_UNKNOWN (0)
+ #define VIDEO_VSYNC_FIELD_ODD (1)
+ #define VIDEO_VSYNC_FIELD_EVEN (2)
+ #define VIDEO_VSYNC_FIELD_PROGRESSIVE (3)
+
+Constants
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - :rspan:`3` _`Decoder command`
+
+ - ``VIDEO_CMD_PLAY``
+
+ - Start playback.
+
+ - ..
+
+ - ``VIDEO_CMD_STOP``
+
+ - Stop playback.
+
+ - ..
+
+ - ``VIDEO_CMD_FREEZE``
+
+ - Freeze playback.
+
+ - ..
+
+ - ``VIDEO_CMD_CONTINUE``
+
+ - Continue playback after freeze.
+
+ - ..
+
+ - Flags for ``VIDEO_CMD_FREEZE``
+
+ - ``VIDEO_CMD_FREEZE_TO_BLACK``
+
+ - Show black picture on freeze.
+
+ - ..
+
+ - :rspan:`1` Flags for ``VIDEO_CMD_STOP``
+
+ - ``VIDEO_CMD_STOP_TO_BLACK``
+
+ - Show black picture on stop.
+
+ - ..
+
+ - ``VIDEO_CMD_STOP_IMMEDIATELY``
+
+ - Stop immediately, without emptying buffers.
+
+ - ..
+
+ - :rspan:`1` _`Play input formats`
+
+ - ``VIDEO_PLAY_FMT_NONE``
+
+ - The decoder has no special format requirements
+
+ - ..
+
+ - ``VIDEO_PLAY_FMT_GOP``
+
+ - The decoder requires full GOPs
+
+ - ..
+
+ - :rspan:`3` Field order
+
+ - ``VIDEO_VSYNC_FIELD_UNKNOWN``
+
+ - FIELD_UNKNOWN can be used if the hardware does not know
+ whether the Vsync is for an odd, even or progressive
+ (i.e. non-interlaced) field.
+
+ - ..
+
+ - ``VIDEO_VSYNC_FIELD_ODD``
+
+ - Vsync is for an odd field.
+
+ - ..
+
+ - ``VIDEO_VSYNC_FIELD_EVEN``
+
+ - Vsync is for an even field.
+
+ - ..
+
+ - ``VIDEO_VSYNC_FIELD_PROGRESSIVE``
+
+ - progressive (i.e. non-interlaced)
+
+
+-----
+
+
+video_event
+-----------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ struct video_event {
+ __s32 type;
+ #define VIDEO_EVENT_SIZE_CHANGED 1
+ #define VIDEO_EVENT_FRAME_RATE_CHANGED 2
+ #define VIDEO_EVENT_DECODER_STOPPED 3
+ #define VIDEO_EVENT_VSYNC 4
+ long timestamp;
+ union {
+ video_size_t size;
+ unsigned int frame_rate;
+ unsigned char vsync_field;
+ } u;
+ };
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - :rspan:`4` ``__s32 type``
+
+ - :cspan:`1` Event type.
+
+ - ..
+
+ - ``VIDEO_EVENT_SIZE_CHANGED``
+
+ - Size changed.
+
+ - ..
+
+ - ``VIDEO_EVENT_FRAME_RATE_CHANGED``
+
+ - Framerate changed.
+
+ - ..
+
+ - ``VIDEO_EVENT_DECODER_STOPPED``
+
+ - Decoder stopped.
+
+ - ..
+
+ - ``VIDEO_EVENT_VSYNC``
+
+ - Vsync occurred.
+
+ - ..
+
+ - ``long timestamp``
+
+ - :cspan:`1` MPEG PTS at occurrence.
+
+ - ..
+
+ - :rspan:`2` ``union u``
+
+ - `video_size_t`_ size
+
+ - Resolution and aspect ratio of the video.
+
+ - ..
+
+ - ``unsigned int frame_rate``
+
+ - in frames per 1000sec
+
+ - ..
+
+ - ``unsigned char vsync_field``
+
+ - | unknown / odd / even / progressive
+ | See: `Predefined decoder commands and flags`_
+
+Description
+~~~~~~~~~~~
+
+This is the structure of a video event as it is returned by the
+`VIDEO_GET_EVENT`_ call. See there for more details.
+
+
+-----
+
+
+video_status
+------------
+
+Synopsis
+~~~~~~~~
+
+The `VIDEO_GET_STATUS`_ call returns the following structure informing
+about various states of the playback operation.
+
+.. code-block:: c
+
+ struct video_status {
+ int video_blank;
+ video_play_state_t play_state;
+ video_stream_source_t stream_source;
+ video_format_t video_format;
+ video_displayformat_t display_format;
+ };
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - :rspan:`2` ``int video_blank``
+
+ - :cspan:`1` Show blank video on freeze?
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - Blank screen when freeze.
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - Show last decoded frame.
+
+ - ..
+
+ - `video_play_state_t`_ ``play_state``
+
+ - Current state of playback.
+
+ - ..
+
+ - `video_stream_source_t`_ ``stream_source``
+
+ - Current source (demux/memory).
+
+ - ..
+
+ - `video_format_t`_ ``video_format``
+
+ - Current aspect ratio of stream.
+
+ - ..
+
+ - `video_displayformat_t`_ ``display_format``
+
+ - Applied cropping mode.
+
+Description
+~~~~~~~~~~~
+
+If ``video_blank`` is set ``TRUE`` video will be blanked out if the
+channel is changed or if playback is stopped. Otherwise, the last picture
+will be displayed. ``play_state`` indicates if the video is currently
+frozen, stopped, or being played back. The ``stream_source`` corresponds
+to the selected source for the video stream. It can come either from the
+demultiplexer or from memory. The ``video_format`` indicates the aspect
+ratio (one of 4:3 or 16:9) of the currently played video stream.
+Finally, ``display_format`` corresponds to the applied cropping mode in
+case the source video format is not the same as the format of the output
+device.
+
+
+-----
+
+
+video_still_picture
+-------------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ struct video_still_picture {
+ char *iFrame;
+ int32_t size;
+ };
+
+Variables
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``char *iFrame``
+
+ - Pointer to a single iframe in memory.
+
+ - ..
+
+ - ``int32_t size``
+
+ - Size of the iframe.
+
+
+Description
+~~~~~~~~~~~
+
+An I-frame displayed via the `VIDEO_STILLPICTURE`_ call is passed on
+within this structure.
+
+
+-----
+
+
+video capabilities
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ #define VIDEO_CAP_MPEG1 1
+ #define VIDEO_CAP_MPEG2 2
+ #define VIDEO_CAP_SYS 4
+ #define VIDEO_CAP_PROG 8
+
+Constants
+~~~~~~~~~
+Bit definitions for capabilities:
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``VIDEO_CAP_MPEG1``
+
+ - :cspan:`1` The hardware can decode MPEG1.
+
+ - ..
+
+ - ``VIDEO_CAP_MPEG2``
+
+ - The hardware can decode MPEG2.
+
+ - ..
+
+ - ``VIDEO_CAP_SYS``
+
+ - The video device accepts system stream.
+
+ You still have to open the video and the audio device
+ but only send the stream to the video device.
+
+ - ..
+
+ - ``VIDEO_CAP_PROG``
+
+ - The video device accepts program stream.
+
+ You still have to open the video and the audio device
+ but only send the stream to the video device.
+
+Description
+~~~~~~~~~~~
+
+A call to `VIDEO_GET_CAPABILITIES`_ returns an unsigned integer with the
+following bits set according to the hardware's capabilities.
+
+
+-----
+
+
+Video Function Calls
+====================
+
+
+VIDEO_STOP
+----------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_STOP
+
+.. code-block:: c
+
+ int ioctl(fd, VIDEO_STOP, int mode)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - :cspan:`1` Equals ``VIDEO_STOP`` for this command.
+
+ - ..
+
+ - :rspan:`2` ``int mode``
+
+ - :cspan:`1` Indicates how the screen shall be handled.
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - Blank screen when stop.
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - Show last decoded frame.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use
+the V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call asks the Video Device to stop playing the current
+stream. Depending on the input parameter, the screen can be blanked out
+or displaying the last decoded frame.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_PLAY
+----------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_PLAY
+
+.. code-block:: c
+
+ int ioctl(fd, VIDEO_PLAY)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_PLAY`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use
+the V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call asks the Video Device to start playing a video stream
+from the selected source.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_FREEZE
+------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_FREEZE
+
+.. code-block:: c
+
+ int ioctl(fd, VIDEO_FREEZE)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_FREEZE`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use
+the V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call suspends the live video stream being played, if
+VIDEO_SOURCE_DEMUX is selected. Decoding and playing are frozen.
+It is then possible to restart the decoding and playing process of the
+video stream using the `VIDEO_CONTINUE`_ command.
+If VIDEO_SOURCE_MEMORY is selected in the ioctl call
+`VIDEO_SELECT_SOURCE`_, the Digital TV subsystem will not decode any more
+data until the ioctl call `VIDEO_CONTINUE`_ or `VIDEO_PLAY`_ is performed.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_CONTINUE
+--------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_CONTINUE
+
+.. code-block:: c
+
+ int ioctl(fd, VIDEO_CONTINUE)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_CONTINUE`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for Digital TV devices only. To control a V4L2 decoder use
+the V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
+
+This ioctl call restarts decoding and playing processes of the video
+stream which was played before a call to `VIDEO_FREEZE`_ was made.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_SELECT_SOURCE
+-------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_SELECT_SOURCE
+
+.. code-block:: c
+
+ int ioctl(fd, VIDEO_SELECT_SOURCE, video_stream_source_t source)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_SELECT_SOURCE`` for this command.
+
+ - ..
+
+ - `video_stream_source_t`_ ``source``
+
+ - Indicates which source shall be used for the Video stream.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for Digital TV devices only. This ioctl was also supported
+by the V4L2 ivtv driver, but that has been replaced by the ivtv-specific
+``IVTV_IOC_PASSTHROUGH_MODE`` ioctl.
+
+This ioctl call informs the video device which source shall be used for
+the input data. The possible sources are demux or memory. If memory is
+selected, the data is fed to the video device through the write command
+using the struct `video_stream_source_t`_. If demux is selected, the data
+is directly transferred from the onboard demux-device to the decoder.
+
+The data fed to the decoder is also controlled by the PID-filter.
+Output selection: :c:type:`dmx_output` ``DMX_OUT_DECODER``.
+
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_SET_BLANK
+---------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_SET_BLANK
+
+.. code-block:: c
+
+ int ioctl(fd, VIDEO_SET_BLANK, int mode)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - :cspan:`1` Equals ``VIDEO_SET_BLANK`` for this command.
+
+ - ..
+
+ - :rspan:`2` ``int mode``
+
+ - :cspan:`1` Indicates if the screen shall be blanked.
+
+ - ..
+
+ - TRUE ( != 0 )
+
+ - Blank screen when stop.
+
+ - ..
+
+ - FALSE ( == 0 )
+
+ - Show last decoded frame.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Video Device to blank out the picture.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_GET_STATUS
+----------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_GET_STATUS
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_GET_STATUS,
+ struct video_status *status)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_GET_STATUS`` for this command.
+
+ - ..
+
+ - ``struct`` `video_status`_ ``*status``
+
+ - Returns the current status of the Video Device.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Video Device to return the current status of
+the device.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_GET_EVENT
+---------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_GET_EVENT
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_GET_EVENT,
+ struct video_event *ev)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_GET_EVENT`` for this command.
+
+ - ..
+
+ - ``struct`` `video_event`_ ``*ev``
+
+ - Points to the location where the event, if any, is to be stored.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl is for DVB devices only. To get events from a V4L2 decoder
+use the V4L2 :ref:`VIDIOC_DQEVENT` ioctl instead.
+
+This ioctl call returns an event of type `video_event`_ if available. A
+certain number of the latest events will be cued and returned in order of
+occurrence. Older events may be discarded if not fetched in time. If
+an event is not available, the behavior depends on whether the device is
+in blocking or non-blocking mode. In the latter case, the call fails
+immediately with errno set to ``EWOULDBLOCK``. In the former case, the
+call blocks until an event becomes available. The standard Linux poll()
+and/or select() system calls can be used with the device file descriptor
+to watch for new events. For select(), the file descriptor should be
+included in the exceptfds argument, and for poll(), POLLPRI should be
+specified as the wake-up condition. Read-only permissions are sufficient
+for this ioctl call.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EWOULDBLOCK``
+
+ - :cspan:`1` There is no event pending, and the device is in
+ non-blocking mode.
+
+ - ..
+
+ - ``EOVERFLOW``
+
+ - Overflow in event queue - one or more events were lost.
+
+
+-----
+
+
+VIDEO_SET_DISPLAY_FORMAT
+------------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_SET_DISPLAY_FORMAT
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_SET_DISPLAY_FORMAT,
+ video_display_format_t format)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_SET_DISPLAY_FORMAT`` for this command.
+
+ - ..
+
+ - `video_displayformat_t`_ ``format``
+
+ - Selects the video format to be used.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Video Device to select the video format to be
+applied by the MPEG chip on the video.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_STILLPICTURE
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_STILLPICTURE
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_STILLPICTURE,
+ struct video_still_picture *sp)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_STILLPICTURE`` for this command.
+
+ - ..
+
+ - ``struct`` `video_still_picture`_ ``*sp``
+
+ - Pointer to the location where the struct with the I-frame
+ and size is stored.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Video Device to display a still picture
+(I-frame). The input data shall be the section of an elementary video
+stream containing an I-frame. Typically this section is extracted from a
+TS or PES recording. Resolution and codec (see `video capabilities`_) must
+be supported by the device. If the pointer is NULL, then the current
+displayed still picture is blanked.
+
+e.g. The AV7110 supports MPEG1 and MPEG2 with the common PAL-SD
+resolutions.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_FAST_FORWARD
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_FAST_FORWARD
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_FAST_FORWARD, int nFrames)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_FAST_FORWARD`` for this command.
+
+ - ..
+
+ - ``int nFrames``
+
+ - The number of frames to skip.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the Video Device to skip decoding of N number of
+I-frames. This call can only be used if ``VIDEO_SOURCE_MEMORY`` is
+selected.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EPERM``
+
+ - Mode ``VIDEO_SOURCE_MEMORY`` not selected.
+
+
+-----
+
+
+VIDEO_SLOWMOTION
+----------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_SLOWMOTION
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_SLOWMOTION, int nFrames)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_SLOWMOTION`` for this command.
+
+ - ..
+
+ - ``int nFrames``
+
+ - The number of times to repeat each frame.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the video device to repeat decoding frames N number
+of times. This call can only be used if ``VIDEO_SOURCE_MEMORY`` is
+selected.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EPERM``
+
+ - Mode ``VIDEO_SOURCE_MEMORY`` not selected.
+
+
+-----
+
+
+VIDEO_GET_CAPABILITIES
+----------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_GET_CAPABILITIES
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_GET_CAPABILITIES, unsigned int *cap)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_GET_CAPABILITIES`` for this command.
+
+ - ..
+
+ - ``unsigned int *cap``
+
+ - Pointer to a location where to store the capability information.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call asks the video device about its decoding capabilities.
+On success it returns an integer which has bits set according to the
+defines in `video capabilities`_.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_CLEAR_BUFFER
+------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_CLEAR_BUFFER
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_CLEAR_BUFFER)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_CLEAR_BUFFER`` for this command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl call clears all video buffers in the driver and in the
+decoder hardware.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_SET_STREAMTYPE
+--------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_SET_STREAMTYPE
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_SET_STREAMTYPE, int type)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_SET_STREAMTYPE`` for this command.
+
+ - ..
+
+ - ``int type``
+
+ - Stream type.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl tells the driver which kind of stream to expect being written
+to it.
+Intelligent decoder might also not support or ignore (like the AV7110)
+this call and determine the stream type themselves.
+
+Currently used stream types:
+
+.. flat-table::
+ :header-rows: 1
+ :stub-columns: 0
+
+ - ..
+
+ - Codec
+
+ - Stream type
+
+ - ..
+
+ - MPEG2
+
+ - 0
+
+ - ..
+
+ - MPEG4 h.264
+
+ - 1
+
+ - ..
+
+ - VC1
+
+ - 3
+
+ - ..
+
+ - MPEG4 Part2
+
+ - 4
+
+ - ..
+
+ - VC1 SM
+
+ - 5
+
+ - ..
+
+ - MPEG1
+
+ - 6
+
+ - ..
+
+ - HEVC h.265
+
+ - | 7
+ | DREAMBOX: 22
+
+ - ..
+
+ - AVS
+
+ - 16
+
+ - ..
+
+ - AVS2
+
+ - 40
+
+Not every decoder supports all stream types.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_SET_FORMAT
+----------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_SET_FORMAT
+
+.. code-block:: c
+
+ int ioctl(fd, int request = VIDEO_SET_FORMAT, video_format_t format)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_SET_FORMAT`` for this command.
+
+ - ..
+
+ - `video_format_t`_ ``format``
+
+ - Video format of TV as defined in section `video_format_t`_.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl sets the screen format (aspect ratio) of the connected output
+device (TV) so that the output of the decoder can be adjusted
+accordingly.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_GET_SIZE
+--------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_GET_SIZE
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = VIDEO_GET_SIZE, video_size_t *size)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call,
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_GET_SIZE`` for this command.
+
+ - ..
+
+ - `video_size_t`_ ``*size``
+
+ - Returns the size and aspect ratio.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+This ioctl returns the size and aspect ratio.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_GET_PTS
+-------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_GET_PTS
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = VIDEO_GET_PTS, __u64 *pts)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_GET_PTS`` for this command.
+
+ - ..
+
+ - ``__u64 *pts``
+
+ - Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 /
+ ISO/IEC 13818-1.
+
+ The PTS should belong to the currently played frame if possible,
+ but may also be a value close to it like the PTS of the last
+ decoded frame or the last PTS extracted by the PES parser.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+For V4L2 decoders this ioctl has been replaced by the
+``V4L2_CID_MPEG_VIDEO_DEC_PTS`` control.
+
+This ioctl call asks the Video Device to return the current PTS
+timestamp.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_GET_FRAME_COUNT
+---------------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_GET_FRAME_COUNT
+
+.. code-block:: c
+
+ int ioctl(int fd, VIDEO_GET_FRAME_COUNT, __u64 *pts)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_GET_FRAME_COUNT`` for this command.
+
+ - ..
+
+ - ``__u64 *pts``
+
+ - Returns the number of frames displayed since the decoder was
+ started.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+For V4L2 decoders this ioctl has been replaced by the
+``V4L2_CID_MPEG_VIDEO_DEC_FRAME`` control.
+
+This ioctl call asks the Video Device to return the number of displayed
+frames since the decoder was started.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_COMMAND
+-------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_COMMAND
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = VIDEO_COMMAND,
+ struct video_command *cmd)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_COMMAND`` for this command.
+
+ - ..
+
+ - `struct video_command`_ ``*cmd``
+
+ - Commands the decoder.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+For V4L2 decoders this ioctl has been replaced by the
+:ref:`VIDIOC_DECODER_CMD` ioctl.
+
+This ioctl commands the decoder. The `struct video_command`_ is a
+subset of the ``v4l2_decoder_cmd`` struct, so refer to the
+:ref:`VIDIOC_DECODER_CMD` documentation for
+more information.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+VIDEO_TRY_COMMAND
+-----------------
+
+Synopsis
+~~~~~~~~
+
+.. c:macro:: VIDEO_TRY_COMMAND
+
+.. code-block:: c
+
+ int ioctl(int fd, int request = VIDEO_TRY_COMMAND,
+ struct video_command *cmd)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``int request``
+
+ - Equals ``VIDEO_TRY_COMMAND`` for this command.
+
+ - ..
+
+ - `struct video_command`_ ``*cmd``
+
+ - Try a decoder command.
+
+Description
+~~~~~~~~~~~
+
+.. attention:: Do **not** use in new drivers!
+ See: :ref:`legacy_dvb_decoder_notes`
+
+For V4L2 decoders this ioctl has been replaced by the
+:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` ioctl.
+
+This ioctl tries a decoder command. The `struct video_command`_ is a
+subset of the ``v4l2_decoder_cmd`` struct, so refer to the
+:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` documentation
+for more information.
+
+Return Value
+~~~~~~~~~~~~
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+
+-----
+
+
+open()
+------
+
+Synopsis
+~~~~~~~~
+
+.. code-block:: c
+
+ #include <fcntl.h>
+
+.. c:function:: int open(const char *deviceName, int flags)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``const char *deviceName``
+
+ - Name of specific video device.
+
+ - ..
+
+ - :rspan:`3` ``int flags``
+
+ - :cspan:`1` A bit-wise OR of the following flags:
+
+ - ..
+
+ - ``O_RDONLY``
+
+ - read-only access
+
+ - ..
+
+ - ``O_RDWR``
+
+ - read/write access
+
+ - ..
+
+ - ``O_NONBLOCK``
+ - | Open in non-blocking mode
+ | (blocking mode is the default)
+
+Description
+~~~~~~~~~~~
+
+This system call opens a named video device (e.g.
+/dev/dvb/adapter?/video?) for subsequent use.
+
+When an open() call has succeeded, the device will be ready for use. The
+significance of blocking or non-blocking mode is described in the
+documentation for functions where there is a difference. It does not
+affect the semantics of the open() call itself. A device opened in
+blocking mode can later be put into non-blocking mode (and vice versa)
+using the F_SETFL command of the fcntl system call. This is a standard
+system call, documented in the Linux manual page for fcntl. Only one
+user can open the Video Device in O_RDWR mode. All other attempts to
+open the device in this mode will fail, and an error-code will be
+returned. If the Video Device is opened in O_RDONLY mode, the only
+ioctl call that can be used is `VIDEO_GET_STATUS`_. All other call will
+return an error code.
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``ENODEV``
+
+ - :cspan:`1` Device driver not loaded/available.
+
+ - ..
+
+ - ``EINTERNAL``
+
+ - Internal error.
+
+ - ..
+
+ - ``EBUSY``
+
+ - Device or resource busy.
+
+ - ..
+
+ - ``EINVAL``
+
+ - Invalid argument.
+
+
+-----
+
+
+close()
+-------
+
+Synopsis
+~~~~~~~~
+
+.. c:function:: int close(int fd)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+Description
+~~~~~~~~~~~
+
+This system call closes a previously opened video device.
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EBADF``
+
+ - fd is not a valid open file descriptor.
+
+
+-----
+
+
+write()
+-------
+
+Synopsis
+~~~~~~~~
+
+.. c:function:: size_t write(int fd, const void *buf, size_t count)
+
+Arguments
+~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``int fd``
+
+ - :cspan:`1` File descriptor returned by a previous call
+ to `open()`_.
+
+ - ..
+
+ - ``void *buf``
+
+ - Pointer to the buffer containing the PES data.
+
+ - ..
+
+ - ``size_t count``
+
+ - Size of buf.
+
+Description
+~~~~~~~~~~~
+
+This system call can only be used if VIDEO_SOURCE_MEMORY is selected
+in the ioctl call `VIDEO_SELECT_SOURCE`_. The data provided shall be in
+PES format, unless the capability allows other formats. TS is the
+most common format for storing DVB-data, it is usually supported too.
+If O_NONBLOCK is not specified the function will block until buffer space
+is available. The amount of data to be transferred is implied by count.
+
+.. note:: See: :ref:`DVB Data Formats <legacy_dvb_decoder_formats>`
+
+Return Value
+~~~~~~~~~~~~
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+ - ..
+
+ - ``EPERM``
+
+ - :cspan:`1` Mode ``VIDEO_SOURCE_MEMORY`` not selected.
+
+ - ..
+
+ - ``ENOMEM``
+
+ - Attempted to write more data than the internal buffer can hold.
+
+ - ..
+
+ - ``EBADF``
+
+ - fd is not a valid open file descriptor.
diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst b/Documentation/userspace-api/media/mediactl/media-types.rst
index 0ffeece1e0c8..6332e8395263 100644
--- a/Documentation/userspace-api/media/mediactl/media-types.rst
+++ b/Documentation/userspace-api/media/mediactl/media-types.rst
@@ -375,12 +375,11 @@ Types and flags used to represent the media graph elements
are origins of links.
* - ``MEDIA_PAD_FL_MUST_CONNECT``
- - If this flag is set and the pad is linked to any other pad, then
- at least one of those links must be enabled for the entity to be
- able to stream. There could be temporary reasons (e.g. device
- configuration dependent) for the pad to need enabled links even
- when this flag isn't set; the absence of the flag doesn't imply
- there is none.
+ - If this flag is set, then for this pad to be able to stream, it must
+ be connected by at least one enabled link. There could be temporary
+ reasons (e.g. device configuration dependent) for the pad to need
+ enabled links even when this flag isn't set; the absence of the flag
+ doesn't imply there is none.
One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE``
diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst
index 810b6a859dc8..da4a358ce762 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-client-cap.rst
@@ -61,6 +61,21 @@ been accepted. A common case for the kernel not accepting a capability is that
the kernel is older than the headers the userspace uses, and thus the capability
is unknown to the kernel.
+.. tabularcolumns:: |p{1.5cm}|p{2.9cm}|p{12.9cm}|
+
+.. c:type:: v4l2_subdev_client_capability
+
+.. flat-table:: struct v4l2_subdev_client_capability
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 3 4 20
+
+ * - __u64
+ - ``capabilities``
+ - Sub-device client capabilities of the opened device.
+
+.. tabularcolumns:: |p{6.8cm}|p{2.4cm}|p{8.1cm}|
+
.. flat-table:: Client Capabilities
:header-rows: 1
diff --git a/MAINTAINERS b/MAINTAINERS
index e58171cb32fd..fd00b0fc5b70 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2761,6 +2761,7 @@ M: Andrzej Hajda <andrzej.hajda@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
F: drivers/media/platform/samsung/s5p-mfc/
ARM/SOCFPGA ARCHITECTURE
@@ -13630,6 +13631,7 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,csi2.yaml
F: Documentation/devicetree/bindings/media/renesas,isp.yaml
F: Documentation/devicetree/bindings/media/renesas,vin.yaml
+F: drivers/media/platform/renesas/rcar-csi2.c
F: drivers/media/platform/renesas/rcar-isp.c
F: drivers/media/platform/renesas/rcar-vin/
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
index 5741adf09a2e..559a172ebc6c 100644
--- a/drivers/media/cec/core/cec-adap.c
+++ b/drivers/media/cec/core/cec-adap.c
@@ -1151,20 +1151,6 @@ void cec_received_msg_ts(struct cec_adapter *adap,
if (valid_la && min_len) {
/* These messages have special length requirements */
switch (cmd) {
- case CEC_MSG_TIMER_STATUS:
- if (msg->msg[2] & 0x10) {
- switch (msg->msg[2] & 0xf) {
- case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE:
- case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE:
- if (msg->len < 5)
- valid_la = false;
- break;
- }
- } else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) {
- if (msg->len < 5)
- valid_la = false;
- }
- break;
case CEC_MSG_RECORD_ON:
switch (msg->msg[2]) {
case CEC_OP_RECORD_SRC_OWN:
diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c
index 7e153c5cad04..5a54db839e5d 100644
--- a/drivers/media/cec/core/cec-core.c
+++ b/drivers/media/cec/core/cec-core.c
@@ -93,7 +93,7 @@ static void cec_devnode_release(struct device *cd)
cec_delete_adapter(to_cec_adapter(devnode));
}
-static struct bus_type cec_bus_type = {
+static const struct bus_type cec_bus_type = {
.name = CEC_NAME,
};
diff --git a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
index 52ec0ba4b339..48ed2993d2f0 100644
--- a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
+++ b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
@@ -326,6 +326,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = {
{ "Google", "Taranza", "0000:00:02.0", port_db_conns },
/* Google Dexi */
{ "Google", "Dexi", "0000:00:02.0", port_db_conns },
+ /* Google Dita */
+ { "Google", "Dita", "0000:00:02.0", port_db_conns },
};
static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
index a366566f22c3..642c48e8c1f5 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -113,6 +113,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
{
unsigned pat;
unsigned plane;
+ int ret = 0;
tpg->max_line_width = max_w;
for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
@@ -121,14 +122,18 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
tpg->lines[pat][plane] =
vzalloc(array3_size(max_w, 2, pixelsz));
- if (!tpg->lines[pat][plane])
- return -ENOMEM;
+ if (!tpg->lines[pat][plane]) {
+ ret = -ENOMEM;
+ goto free_lines;
+ }
if (plane == 0)
continue;
tpg->downsampled_lines[pat][plane] =
vzalloc(array3_size(max_w, 2, pixelsz));
- if (!tpg->downsampled_lines[pat][plane])
- return -ENOMEM;
+ if (!tpg->downsampled_lines[pat][plane]) {
+ ret = -ENOMEM;
+ goto free_lines;
+ }
}
}
for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
@@ -136,18 +141,45 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
tpg->contrast_line[plane] =
vzalloc(array_size(pixelsz, max_w));
- if (!tpg->contrast_line[plane])
- return -ENOMEM;
+ if (!tpg->contrast_line[plane]) {
+ ret = -ENOMEM;
+ goto free_contrast_line;
+ }
tpg->black_line[plane] =
vzalloc(array_size(pixelsz, max_w));
- if (!tpg->black_line[plane])
- return -ENOMEM;
+ if (!tpg->black_line[plane]) {
+ ret = -ENOMEM;
+ goto free_contrast_line;
+ }
tpg->random_line[plane] =
vzalloc(array3_size(max_w, 2, pixelsz));
- if (!tpg->random_line[plane])
- return -ENOMEM;
+ if (!tpg->random_line[plane]) {
+ ret = -ENOMEM;
+ goto free_contrast_line;
+ }
}
return 0;
+
+free_contrast_line:
+ for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
+ vfree(tpg->contrast_line[plane]);
+ vfree(tpg->black_line[plane]);
+ vfree(tpg->random_line[plane]);
+ tpg->contrast_line[plane] = NULL;
+ tpg->black_line[plane] = NULL;
+ tpg->random_line[plane] = NULL;
+ }
+free_lines:
+ for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
+ for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
+ vfree(tpg->lines[pat][plane]);
+ tpg->lines[pat][plane] = NULL;
+ if (plane == 0)
+ continue;
+ vfree(tpg->downsampled_lines[pat][plane]);
+ tpg->downsampled_lines[pat][plane] = NULL;
+ }
+ return ret;
}
EXPORT_SYMBOL_GPL(tpg_alloc);
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 9293b058ab99..4f78f30b3646 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -679,12 +679,10 @@ static int dvb_frontend_thread(void *data)
set_freezable();
while (1) {
up(&fepriv->sem); /* is locked when we enter the thread... */
-restart:
- wait_event_interruptible_timeout(fepriv->wait_queue,
- dvb_frontend_should_wakeup(fe) ||
- kthread_should_stop() ||
- freezing(current),
- fepriv->delay);
+ wait_event_freezable_timeout(fepriv->wait_queue,
+ dvb_frontend_should_wakeup(fe) ||
+ kthread_should_stop(),
+ fepriv->delay);
if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
/* got signal or quitting */
@@ -694,9 +692,6 @@ restart:
break;
}
- if (try_to_freeze())
- goto restart;
-
if (down_interruptible(&fepriv->sem))
break;
@@ -2168,7 +2163,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,
if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
- tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+ tvp = memdup_array_user(compat_ptr(tvps->props),
+ tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);
@@ -2199,7 +2195,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,
if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
- tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+ tvp = memdup_array_user(compat_ptr(tvps->props),
+ tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);
@@ -2379,7 +2376,8 @@ static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS)
return -EINVAL;
- tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
+ tvp = memdup_array_user((void __user *)tvps->props,
+ tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);
@@ -2457,7 +2455,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
- tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
+ tvp = memdup_array_user((void __user *)tvps->props,
+ tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 49f0eb7d0b9d..733d0bc4b4cc 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -490,6 +490,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
if (!dvbdevfops) {
kfree(dvbdev);
+ *pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return -ENOMEM;
}
@@ -498,6 +499,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
if (!new_node) {
kfree(dvbdevfops);
kfree(dvbdev);
+ *pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return -ENOMEM;
}
@@ -531,6 +533,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
}
list_del(&dvbdev->list_head);
kfree(dvbdev);
+ *pdvbdev = NULL;
up_write(&minor_rwsem);
mutex_unlock(&dvbdev_register_lock);
return -EINVAL;
@@ -553,6 +556,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvb_media_device_free(dvbdev);
list_del(&dvbdev->list_head);
kfree(dvbdev);
+ *pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return ret;
}
@@ -571,6 +575,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvb_media_device_free(dvbdev);
list_del(&dvbdev->list_head);
kfree(dvbdev);
+ *pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return PTR_ERR(clsdev);
}
diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
index b3f5c49accaf..27f1de21f571 100644
--- a/drivers/media/dvb-frontends/bcm3510.c
+++ b/drivers/media/dvb-frontends/bcm3510.c
@@ -797,7 +797,6 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
struct i2c_adapter *i2c)
{
struct bcm3510_state* state = NULL;
- int ret;
bcm3510_register_value v;
/* allocate memory for the internal state */
@@ -816,7 +815,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
mutex_init(&state->hab_mutex);
- if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
+ if (bcm3510_readB(state, 0xe0, &v) < 0)
goto error;
deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
diff --git a/drivers/media/dvb-frontends/bcm3510_priv.h b/drivers/media/dvb-frontends/bcm3510_priv.h
index 2c9f3c430a82..89c71bc42a0f 100644
--- a/drivers/media/dvb-frontends/bcm3510_priv.h
+++ b/drivers/media/dvb-frontends/bcm3510_priv.h
@@ -12,11 +12,11 @@
#define PACKED __attribute__((packed))
#undef err
-#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg)
+#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n", ## arg)
#undef info
-#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n", ## arg)
#undef warn
-#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n", ## arg)
#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500
diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c
index 9aeea089756f..65dd9b72ea55 100644
--- a/drivers/media/dvb-frontends/cx24110.c
+++ b/drivers/media/dvb-frontends/cx24110.c
@@ -224,13 +224,13 @@ static enum fe_code_rate cx24110_get_fec(struct cx24110_state *state)
}
}
-static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
+static int cx24110_set_symbolrate (struct cx24110_state *state, u32 srate)
{
/* fixme (low): add error handling */
u32 ratio;
u32 tmp, fclk, BDRI;
- static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
+ static const u32 bands[] = {5000000UL, 15000000UL, 90999000UL/2};
int i;
dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate);
diff --git a/drivers/media/dvb-frontends/cx24110.h b/drivers/media/dvb-frontends/cx24110.h
index 834b011d3462..839551841893 100644
--- a/drivers/media/dvb-frontends/cx24110.h
+++ b/drivers/media/dvb-frontends/cx24110.h
@@ -34,11 +34,11 @@ static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
}
#if IS_REACHABLE(CONFIG_DVB_CX24110)
-extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
- struct i2c_adapter* i2c);
+extern struct dvb_frontend *cx24110_attach(const struct cx24110_config *config,
+ struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
- struct i2c_adapter* i2c)
+static inline struct dvb_frontend *cx24110_attach(const struct cx24110_config *config,
+ struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c
index ef697ab6bc2e..1775a4aa0a18 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -796,7 +796,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
b1[0] = 0;
msg.buf = b1;
- nr = ida_simple_get(&pll_ida, 0, DVB_PLL_MAX, GFP_KERNEL);
+ nr = ida_alloc_max(&pll_ida, DVB_PLL_MAX - 1, GFP_KERNEL);
if (nr < 0) {
kfree(b1);
return NULL;
@@ -862,7 +862,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
return fe;
out:
kfree(b1);
- ida_simple_remove(&pll_ida, nr);
+ ida_free(&pll_ida, nr);
return NULL;
}
@@ -905,7 +905,7 @@ static void dvb_pll_remove(struct i2c_client *client)
struct dvb_frontend *fe = i2c_get_clientdata(client);
struct dvb_pll_priv *priv = fe->tuner_priv;
- ida_simple_remove(&pll_ida, priv->nr);
+ ida_free(&pll_ida, priv->nr);
dvb_pll_release(fe);
}
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index 48326434488c..72540ef4e5f8 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -118,50 +118,32 @@ static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_S
}
};
-static
-int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
+static noinline_for_stack
+int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
{
- u8 buf[MAX_XFER_SIZE];
+ u8 buf[3] = { MSB(reg), LSB(reg), data };
struct i2c_msg msg = {
.addr = state->config->demod_address,
.flags = 0,
.buf = buf,
- .len = len + 2
+ .len = 3,
};
int ret;
- if (2 + len > sizeof(buf)) {
- printk(KERN_WARNING
- "%s: i2c wr reg=%04x: len=%d is too big!\n",
- KBUILD_MODNAME, reg, len);
- return -EINVAL;
- }
-
-
- buf[0] = MSB(reg);
- buf[1] = LSB(reg);
- memcpy(buf + 2, data, len);
-
if (i2cdebug)
printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
- state->config->demod_address, reg, buf[2]);
+ state->config->demod_address, reg, data);
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n",
- __func__, state->config->demod_address, reg, buf[2]);
+ __func__, state->config->demod_address, reg, data);
return (ret != 1) ? -EREMOTEIO : 0;
}
-static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
-{
- u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
-
- return stv0367_writeregs(state, reg, &tmp, 1);
-}
-
-static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
+static noinline_for_stack
+u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
{
u8 b0[] = { 0, 0 };
u8 b1[] = { 0 };
diff --git a/drivers/media/dvb-frontends/stv6110x_priv.h b/drivers/media/dvb-frontends/stv6110x_priv.h
index b27769558f78..81410595820a 100644
--- a/drivers/media/dvb-frontends/stv6110x_priv.h
+++ b/drivers/media/dvb-frontends/stv6110x_priv.h
@@ -20,13 +20,13 @@
#define dprintk(__y, __z, format, arg...) do { \
if (__z) { \
if ((verbose > FE_ERROR) && (verbose > __y)) \
- printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
+ printk(KERN_ERR "%s: " format "\n", __func__, ##arg); \
else if ((verbose > FE_NOTICE) && (verbose > __y)) \
- printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
+ printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg); \
else if ((verbose > FE_INFO) && (verbose > __y)) \
- printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
+ printk(KERN_INFO "%s: " format "\n", __func__, ##arg); \
else if ((verbose > FE_DEBUG) && (verbose > __y)) \
- printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
+ printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg); \
} else { \
if (verbose > __y) \
printk(format, ##arg); \
diff --git a/drivers/media/dvb-frontends/tda8083.h b/drivers/media/dvb-frontends/tda8083.h
index 3a671ec3f45e..b635ac7ef688 100644
--- a/drivers/media/dvb-frontends/tda8083.h
+++ b/drivers/media/dvb-frontends/tda8083.h
@@ -24,11 +24,11 @@ struct tda8083_config
};
#if IS_REACHABLE(CONFIG_DVB_TDA8083)
-extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
- struct i2c_adapter* i2c);
+extern struct dvb_frontend *tda8083_attach(const struct tda8083_config *config,
+ struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
- struct i2c_adapter* i2c)
+static inline struct dvb_frontend *tda8083_attach(const struct tda8083_config *config,
+ struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c
index 7ba575e9c55f..3df055be66d6 100644
--- a/drivers/media/dvb-frontends/zl10036.c
+++ b/drivers/media/dvb-frontends/zl10036.c
@@ -3,7 +3,7 @@
* Driver for Zarlink zl10036 DVB-S silicon tuner
*
* Copyright (C) 2006 Tino Reichardt
- * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.org>
*
**
* The data sheet for this tuner can be found at:
diff --git a/drivers/media/dvb-frontends/zl10036.h b/drivers/media/dvb-frontends/zl10036.h
index ad83e6344e7f..23c2964a928c 100644
--- a/drivers/media/dvb-frontends/zl10036.h
+++ b/drivers/media/dvb-frontends/zl10036.h
@@ -3,7 +3,7 @@
* Driver for Zarlink ZL10036 DVB-S silicon tuner
*
* Copyright (C) 2006 Tino Reichardt
- * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.org>
*/
#ifndef DVB_ZL10036_H
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 4c3435921f19..56f276b920ab 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -224,6 +224,7 @@ config VIDEO_IMX412
config VIDEO_IMX415
tristate "Sony IMX415 sensor support"
depends on OF_GPIO
+ select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the Sony
IMX415 camera.
@@ -658,6 +659,7 @@ config VIDEO_S5K6A3
config VIDEO_ST_VGXY61
tristate "ST VGXY61 sensor support"
+ select V4L2_CCI_I2C
depends on OF && GPIOLIB
help
This is a Video4Linux2 sensor driver for the ST VGXY61
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 409b9a37f018..4829cbe32419 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1057,11 +1057,11 @@ static int adv7182_init(struct adv7180_state *state)
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
0x17);
}
- }
- else
+ } else {
adv7180_write(state,
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
0x07);
+ }
adv7180_write(state, ADV7180_REG_OUTPUT_CONTROL, 0x0c);
adv7180_write(state, ADV7180_REG_CTRL_2, 0x40);
}
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index ff21cd4744d3..4fbe4e18570e 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
- np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+ np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!np)
return NULL;
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
index 6f90f78f58cf..d2b5e722e997 100644
--- a/drivers/media/i2c/adv748x/adv748x.h
+++ b/drivers/media/i2c/adv748x/adv748x.h
@@ -173,7 +173,6 @@ struct adv748x_afe {
*
* @endpoints: parsed device node endpoints for each port
*
- * @i2c_addresses: I2C Page addresses
* @i2c_clients: I2C clients for the page accesses
* @regmap: regmap configuration pages.
*
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 810fa8826f30..319db3e847c4 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3204,8 +3204,8 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
- /* Parse the endpoint. */
- endpoint = of_graph_get_next_endpoint(np, NULL);
+ /* FIXME: Parse the endpoint. */
+ endpoint = of_graph_get_endpoint_by_regs(np, -1, -1);
if (!endpoint)
return -EINVAL;
diff --git a/drivers/media/i2c/alvium-csi2.c b/drivers/media/i2c/alvium-csi2.c
index 34ff7fad3877..e65702e3f73e 100644
--- a/drivers/media/i2c/alvium-csi2.c
+++ b/drivers/media/i2c/alvium-csi2.c
@@ -1170,40 +1170,32 @@ static int alvium_set_bayer_pattern(struct alvium_dev *alvium,
return 0;
}
-static int alvium_get_frame_interval(struct alvium_dev *alvium)
+static int alvium_get_frame_interval(struct alvium_dev *alvium,
+ u64 *min_fr, u64 *max_fr)
{
- u64 dft_fr, min_fr, max_fr;
int ret = 0;
- alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_RW,
- &dft_fr, &ret);
alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_MIN_R,
- &min_fr, &ret);
+ min_fr, &ret);
alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_MAX_R,
- &max_fr, &ret);
- if (ret)
- return ret;
-
- alvium->dft_fr = dft_fr;
- alvium->min_fr = min_fr;
- alvium->max_fr = max_fr;
+ max_fr, &ret);
- return 0;
+ return ret;
}
-static int alvium_set_frame_rate(struct alvium_dev *alvium)
+static int alvium_set_frame_rate(struct alvium_dev *alvium, u64 fr)
{
struct device *dev = &alvium->i2c_client->dev;
int ret;
ret = alvium_write_hshake(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_RW,
- alvium->fr);
+ fr);
if (ret) {
dev_err(dev, "Fail to set frame rate lanes reg\n");
return ret;
}
- dev_dbg(dev, "set frame rate: %llu us\n", alvium->fr);
+ dev_dbg(dev, "set frame rate: %llu us\n", fr);
return 0;
}
@@ -1472,7 +1464,7 @@ static int alvium_get_hw_features_params(struct alvium_dev *alvium)
ret = alvium_get_img_height_params(alvium);
if (ret) {
- dev_err(dev, "Fail to read img heigth regs\n");
+ dev_err(dev, "Fail to read img height regs\n");
return ret;
}
@@ -1647,44 +1639,28 @@ static int alvium_hw_init(struct alvium_dev *alvium)
}
/* --------------- Subdev Operations --------------- */
-
-static int alvium_g_frame_interval(struct v4l2_subdev *sd,
+static int alvium_s_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct alvium_dev *alvium = sd_to_alvium(sd);
-
- /*
- * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
- * subdev active state API.
- */
- if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- fi->interval = alvium->frame_interval;
-
- return 0;
-}
-
-static int alvium_set_frame_interval(struct alvium_dev *alvium,
- struct v4l2_subdev_frame_interval *fi)
-{
struct device *dev = &alvium->i2c_client->dev;
u64 req_fr, min_fr, max_fr;
+ struct v4l2_fract *interval;
int ret;
+ if (alvium->streaming)
+ return -EBUSY;
+
if (fi->interval.denominator == 0)
return -EINVAL;
- ret = alvium_get_frame_interval(alvium);
+ ret = alvium_get_frame_interval(alvium, &min_fr, &max_fr);
if (ret) {
dev_err(dev, "Fail to get frame interval\n");
return ret;
}
- min_fr = alvium->min_fr;
- max_fr = alvium->max_fr;
-
dev_dbg(dev, "fi->interval.numerator = %d\n",
fi->interval.numerator);
dev_dbg(dev, "fi->interval.denominator = %d\n",
@@ -1692,39 +1668,17 @@ static int alvium_set_frame_interval(struct alvium_dev *alvium,
req_fr = (u64)((fi->interval.denominator * USEC_PER_SEC) /
fi->interval.numerator);
+ req_fr = clamp(req_fr, min_fr, max_fr);
- if (req_fr >= max_fr && req_fr <= min_fr)
- req_fr = alvium->dft_fr;
+ interval = v4l2_subdev_state_get_interval(sd_state, 0);
- alvium->fr = req_fr;
- alvium->frame_interval.numerator = fi->interval.numerator;
- alvium->frame_interval.denominator = fi->interval.denominator;
+ interval->numerator = fi->interval.numerator;
+ interval->denominator = fi->interval.denominator;
- return 0;
-}
-
-static int alvium_s_frame_interval(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_frame_interval *fi)
-{
- struct alvium_dev *alvium = sd_to_alvium(sd);
- int ret;
-
- /*
- * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
- * subdev active state API.
- */
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (alvium->streaming)
- return -EBUSY;
-
- ret = alvium_set_frame_interval(alvium, fi);
- if (!ret)
- ret = alvium_set_frame_rate(alvium);
+ return 0;
- return ret;
+ return alvium_set_frame_rate(alvium, req_fr);
}
static int alvium_enum_mbus_code(struct v4l2_subdev *sd,
@@ -1872,6 +1826,7 @@ static int alvium_init_state(struct v4l2_subdev *sd,
{
struct alvium_dev *alvium = sd_to_alvium(sd);
struct alvium_mode *mode = &alvium->mode;
+ struct v4l2_fract *interval;
struct v4l2_subdev_format sd_fmt = {
.which = V4L2_SUBDEV_FORMAT_TRY,
.format = alvium_csi2_default_fmt,
@@ -1889,6 +1844,11 @@ static int alvium_init_state(struct v4l2_subdev *sd,
*v4l2_subdev_state_get_crop(state, 0) = sd_crop.rect;
*v4l2_subdev_state_get_format(state, 0) = sd_fmt.format;
+ /* Setup initial frame interval*/
+ interval = v4l2_subdev_state_get_interval(state, 0);
+ interval->numerator = 1;
+ interval->denominator = ALVIUM_DEFAULT_FR_HZ;
+
return 0;
}
@@ -2258,7 +2218,7 @@ static const struct v4l2_subdev_pad_ops alvium_pad_ops = {
.set_fmt = alvium_set_fmt,
.get_selection = alvium_get_selection,
.set_selection = alvium_set_selection,
- .get_frame_interval = alvium_g_frame_interval,
+ .get_frame_interval = v4l2_subdev_get_frame_interval,
.set_frame_interval = alvium_s_frame_interval,
};
@@ -2279,11 +2239,6 @@ static int alvium_subdev_init(struct alvium_dev *alvium)
struct v4l2_subdev *sd = &alvium->sd;
int ret;
- /* Setup initial frame interval*/
- alvium->frame_interval.numerator = 1;
- alvium->frame_interval.denominator = ALVIUM_DEFAULT_FR_HZ;
- alvium->fr = ALVIUM_DEFAULT_FR_HZ;
-
/* Setup the initial mode */
alvium->mode.fmt = alvium_csi2_default_fmt;
alvium->mode.width = alvium_csi2_default_fmt.width;
diff --git a/drivers/media/i2c/alvium-csi2.h b/drivers/media/i2c/alvium-csi2.h
index b85a25169e79..9463f8604fbc 100644
--- a/drivers/media/i2c/alvium-csi2.h
+++ b/drivers/media/i2c/alvium-csi2.h
@@ -442,11 +442,6 @@ struct alvium_dev {
s32 inc_sharp;
struct alvium_mode mode;
- struct v4l2_fract frame_interval;
- u64 dft_fr;
- u64 min_fr;
- u64 max_fr;
- u64 fr;
u8 h_sup_csi_lanes;
u64 link_freq;
diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c
index c7d5fa532ae1..09331cf95c62 100644
--- a/drivers/media/i2c/ar0521.c
+++ b/drivers/media/i2c/ar0521.c
@@ -314,7 +314,7 @@ static void ar0521_calc_pll(struct ar0521_dev *sensor)
* In the clock tree:
* MIPI_CLK = PIXEL_CLOCK * bpp / 2 / 2
*
- * Generic pixel_rate to bus clock frequencey equation:
+ * Generic pixel_rate to bus clock frequency equation:
* MIPI_CLK = V4L2_CID_PIXEL_RATE * bpp / lanes / 2
*
* From which we derive the PIXEL_CLOCK to use in the clock tree:
@@ -327,7 +327,7 @@ static void ar0521_calc_pll(struct ar0521_dev *sensor)
*
* TODO: in case we have less data lanes we have to reduce the desired
* VCO not to exceed the limits specified by the datasheet and
- * consequentially reduce the obtained pixel clock.
+ * consequently reduce the obtained pixel clock.
*/
pixel_clock = AR0521_PIXEL_CLOCK_RATE * 2 / sensor->lane_count;
bpp = ar0521_code_to_bpp(sensor);
@@ -806,7 +806,7 @@ static const struct initial_reg {
REGS(be(0x3F00),
be(0x0017), /* 3F00: BM_T0 */
be(0x02DD), /* 3F02: BM_T1 */
- /* 3F04: if Ana_gain less than 2, use noise_floor0, multipl */
+ /* 3F04: if Ana_gain less than 2, use noise_floor0, multiply */
be(0x0020),
/* 3F06: if Ana_gain between 4 and 7, use noise_floor2 and */
be(0x0040),
diff --git a/drivers/media/i2c/ccs/ccs-quirk.h b/drivers/media/i2c/ccs/ccs-quirk.h
index 0b1a64958d71..392c97109617 100644
--- a/drivers/media/i2c/ccs/ccs-quirk.h
+++ b/drivers/media/i2c/ccs/ccs-quirk.h
@@ -28,11 +28,11 @@ struct ccs_sensor;
* @reg_access: Register access quirk. The quirk may divert the access
* to another register, or no register at all.
*
- * @write: Is this read (false) or write (true) access?
- * @reg: Pointer to the register to access
- * @value: Register value, set by the caller on write, or
+ * -write: Is this read (false) or write (true) access?
+ * -reg: Pointer to the register to access
+ * -val: Register value, set by the caller on write, or
* by the quirk on read
- * @return: 0 on success, -ENOIOCTLCMD if no register
+ * -return: 0 on success, -ENOIOCTLCMD if no register
* access may be done by the caller (default read
* value is zero), else negative error code on error
* @flags: Quirk flags
diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c
index cc09b32ede60..84d29bcf0ccd 100644
--- a/drivers/media/i2c/dw9714.c
+++ b/drivers/media/i2c/dw9714.c
@@ -157,6 +157,8 @@ static int dw9714_probe(struct i2c_client *client)
return rval;
}
+ usleep_range(1000, 2000);
+
v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS;
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
index b148b1bd2bc3..10b6ad66d126 100644
--- a/drivers/media/i2c/imx214.c
+++ b/drivers/media/i2c/imx214.c
@@ -968,7 +968,7 @@ static const struct v4l2_subdev_internal_ops imx214_internal_ops = {
static const struct regmap_config sensor_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static int imx214_get_regulators(struct device *dev, struct imx214 *imx214)
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index 352da68b8b41..3800de974e8a 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -151,7 +151,7 @@ struct reg_8 {
static const struct regmap_config imx274_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
/*
diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
index 9967f3477433..4150e6e4b9a6 100644
--- a/drivers/media/i2c/imx290.c
+++ b/drivers/media/i2c/imx290.c
@@ -150,10 +150,10 @@
#define IMX290_PIXEL_ARRAY_WIDTH 1945
#define IMX290_PIXEL_ARRAY_HEIGHT 1097
-#define IMX920_PIXEL_ARRAY_MARGIN_LEFT 12
-#define IMX920_PIXEL_ARRAY_MARGIN_RIGHT 13
-#define IMX920_PIXEL_ARRAY_MARGIN_TOP 8
-#define IMX920_PIXEL_ARRAY_MARGIN_BOTTOM 9
+#define IMX290_PIXEL_ARRAY_MARGIN_LEFT 12
+#define IMX290_PIXEL_ARRAY_MARGIN_RIGHT 13
+#define IMX290_PIXEL_ARRAY_MARGIN_TOP 8
+#define IMX290_PIXEL_ARRAY_MARGIN_BOTTOM 9
#define IMX290_PIXEL_ARRAY_RECORDING_WIDTH 1920
#define IMX290_PIXEL_ARRAY_RECORDING_HEIGHT 1080
@@ -1161,10 +1161,10 @@ static int imx290_get_selection(struct v4l2_subdev *sd,
* The sensor moves the readout by 1 pixel based on flips to
* keep the Bayer order the same.
*/
- sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP
+ sel->r.top = IMX290_PIXEL_ARRAY_MARGIN_TOP
+ (IMX290_PIXEL_ARRAY_RECORDING_HEIGHT - format->height) / 2
+ imx290->vflip->val;
- sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT
+ sel->r.left = IMX290_PIXEL_ARRAY_MARGIN_LEFT
+ (IMX290_PIXEL_ARRAY_RECORDING_WIDTH - format->width) / 2
+ imx290->hflip->val;
sel->r.width = format->width;
@@ -1183,8 +1183,8 @@ static int imx290_get_selection(struct v4l2_subdev *sd,
return 0;
case V4L2_SEL_TGT_CROP_DEFAULT:
- sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP;
- sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT;
+ sel->r.top = IMX290_PIXEL_ARRAY_MARGIN_TOP;
+ sel->r.left = IMX290_PIXEL_ARRAY_MARGIN_LEFT;
sel->r.width = IMX290_PIXEL_ARRAY_RECORDING_WIDTH;
sel->r.height = IMX290_PIXEL_ARRAY_RECORDING_HEIGHT;
diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c
index e47eff672e0c..8fe3933f3146 100644
--- a/drivers/media/i2c/imx319.c
+++ b/drivers/media/i2c/imx319.c
@@ -70,7 +70,7 @@
#define IMX319_REG_ORIENTATION 0x0101
/* default link frequency and external clock */
-#define IMX319_LINK_FREQ_DEFAULT 482400000
+#define IMX319_LINK_FREQ_DEFAULT 482400000LL
#define IMX319_EXT_CLK 19200000
#define IMX319_LINK_FREQ_INDEX 0
@@ -107,8 +107,7 @@ struct imx319_mode {
struct imx319_hwcfg {
u32 ext_clk; /* sensor external clk */
- s64 *link_freqs; /* CSI-2 link frequencies */
- unsigned int nr_of_link_freqs;
+ unsigned long link_freq_bitmap;
};
struct imx319 {
@@ -129,7 +128,6 @@ struct imx319 {
const struct imx319_mode *cur_mode;
struct imx319_hwcfg *hwcfg;
- s64 link_def_freq; /* CSI-2 link default frequency */
/*
* Mutex for serialized access:
@@ -1654,7 +1652,10 @@ static const char * const imx319_test_pattern_menu[] = {
"Pseudorandom Sequence (PN9)",
};
-/* supported link frequencies */
+/*
+ * When adding more than the one below, make sure the disallowed ones will
+ * actually be disabled in the LINK_FREQ control.
+ */
static const s64 link_freq_menu_items[] = {
IMX319_LINK_FREQ_DEFAULT,
};
@@ -2058,7 +2059,7 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
*framefmt = fmt->format;
} else {
imx319->cur_mode = mode;
- pixel_rate = imx319->link_def_freq * 2 * 4;
+ pixel_rate = IMX319_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
__v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate);
/* Update limits and set FPS to default */
@@ -2255,7 +2256,7 @@ static int imx319_init_controls(struct imx319 *imx319)
imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
- pixel_rate = imx319->link_def_freq * 2 * 4;
+ pixel_rate = IMX319_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
/* By default, PIXEL_RATE is read only */
imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
@@ -2332,7 +2333,6 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
};
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
- unsigned int i;
int ret;
if (!fwnode)
@@ -2364,24 +2364,14 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
goto out_err;
}
- dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
- if (!bus_cfg.nr_of_link_frequencies) {
- dev_warn(dev, "no link frequencies defined");
- goto out_err;
- }
-
- cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
- cfg->link_freqs = devm_kcalloc(dev,
- bus_cfg.nr_of_link_frequencies + 1,
- sizeof(*cfg->link_freqs), GFP_KERNEL);
- if (!cfg->link_freqs)
+ ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_freq_menu_items,
+ ARRAY_SIZE(link_freq_menu_items),
+ &cfg->link_freq_bitmap);
+ if (ret)
goto out_err;
- for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
- cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
- dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
- }
-
v4l2_fwnode_endpoint_free(&bus_cfg);
fwnode_handle_put(ep);
return cfg;
@@ -2397,7 +2387,6 @@ static int imx319_probe(struct i2c_client *client)
struct imx319 *imx319;
bool full_power;
int ret;
- u32 i;
imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL);
if (!imx319)
@@ -2425,20 +2414,6 @@ static int imx319_probe(struct i2c_client *client)
goto error_probe;
}
- imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX];
- for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) {
- if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) {
- dev_dbg(&client->dev, "link freq index %d matched", i);
- break;
- }
- }
-
- if (i == imx319->hwcfg->nr_of_link_freqs) {
- dev_err(&client->dev, "no link frequency supported");
- ret = -EINVAL;
- goto error_probe;
- }
-
/* Set default mode to max resolution */
imx319->cur_mode = &supported_modes[0];
diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c
index 6725b3e2a73e..40863d87d341 100644
--- a/drivers/media/i2c/imx334.c
+++ b/drivers/media/i2c/imx334.c
@@ -136,7 +136,7 @@ struct imx334_mode {
* @vblank: Vertical blanking in lines
* @cur_mode: Pointer to current selected sensor mode
* @mutex: Mutex for serializing sensor controls
- * @menu_skip_mask: Menu skip mask for link_freq_ctrl
+ * @link_freq_bitmap: Menu bitmap for link_freq_ctrl
* @cur_code: current selected format code
*/
struct imx334 {
@@ -158,7 +158,7 @@ struct imx334 {
u32 vblank;
const struct imx334_mode *cur_mode;
struct mutex mutex;
- unsigned long menu_skip_mask;
+ unsigned long link_freq_bitmap;
u32 cur_code;
};
@@ -954,9 +954,9 @@ static int imx334_init_state(struct v4l2_subdev *sd,
imx334_fill_pad_format(imx334, imx334->cur_mode, &fmt);
__v4l2_ctrl_modify_range(imx334->link_freq_ctrl, 0,
- __fls(imx334->menu_skip_mask),
- ~(imx334->menu_skip_mask),
- __ffs(imx334->menu_skip_mask));
+ __fls(imx334->link_freq_bitmap),
+ ~(imx334->link_freq_bitmap),
+ __ffs(imx334->link_freq_bitmap));
mutex_unlock(&imx334->mutex);
@@ -1112,7 +1112,6 @@ static int imx334_parse_hw_config(struct imx334 *imx334)
};
struct fwnode_handle *ep;
unsigned long rate;
- unsigned int i, j;
int ret;
if (!fwnode)
@@ -1157,26 +1156,10 @@ static int imx334_parse_hw_config(struct imx334 *imx334)
goto done_endpoint_free;
}
- if (!bus_cfg.nr_of_link_frequencies) {
- dev_err(imx334->dev, "no link frequencies defined");
- ret = -EINVAL;
- goto done_endpoint_free;
- }
-
- for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
- for (j = 0; j < ARRAY_SIZE(link_freq); j++) {
- if (bus_cfg.link_frequencies[i] == link_freq[j]) {
- set_bit(j, &imx334->menu_skip_mask);
- break;
- }
- }
-
- if (j == ARRAY_SIZE(link_freq)) {
- ret = dev_err_probe(imx334->dev, -EINVAL,
- "no supported link freq found\n");
- goto done_endpoint_free;
- }
- }
+ ret = v4l2_link_freq_to_bitmap(imx334->dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_freq, ARRAY_SIZE(link_freq),
+ &imx334->link_freq_bitmap);
done_endpoint_free:
v4l2_fwnode_endpoint_free(&bus_cfg);
@@ -1310,8 +1293,8 @@ static int imx334_init_controls(struct imx334 *imx334)
imx334->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&imx334_ctrl_ops,
V4L2_CID_LINK_FREQ,
- __fls(imx334->menu_skip_mask),
- __ffs(imx334->menu_skip_mask),
+ __fls(imx334->link_freq_bitmap),
+ __ffs(imx334->link_freq_bitmap),
link_freq);
if (imx334->link_freq_ctrl)
@@ -1386,7 +1369,7 @@ static int imx334_probe(struct i2c_client *client)
}
/* Set default mode to max resolution */
- imx334->cur_mode = &supported_modes[__ffs(imx334->menu_skip_mask)];
+ imx334->cur_mode = &supported_modes[__ffs(imx334->link_freq_bitmap)];
imx334->cur_code = imx334_mbus_codes[0];
imx334->vblank = imx334->cur_mode->vblank;
diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c
index 7a37eb327ff4..dab6d080bc4c 100644
--- a/drivers/media/i2c/imx335.c
+++ b/drivers/media/i2c/imx335.c
@@ -45,11 +45,28 @@
/* Group hold register */
#define IMX335_REG_HOLD 0x3001
+/* Test pattern generator */
+#define IMX335_REG_TPG 0x329e
+#define IMX335_TPG_ALL_000 0
+#define IMX335_TPG_ALL_FFF 1
+#define IMX335_TPG_ALL_555 2
+#define IMX335_TPG_ALL_AAA 3
+#define IMX335_TPG_TOG_555_AAA 4
+#define IMX335_TPG_TOG_AAA_555 5
+#define IMX335_TPG_TOG_000_555 6
+#define IMX335_TPG_TOG_555_000 7
+#define IMX335_TPG_TOG_000_FFF 8
+#define IMX335_TPG_TOG_FFF_000 9
+#define IMX335_TPG_H_COLOR_BARS 10
+#define IMX335_TPG_V_COLOR_BARS 11
+
/* Input clock rate */
#define IMX335_INCLK_RATE 24000000
/* CSI2 HW configuration */
-#define IMX335_LINK_FREQ 594000000
+#define IMX335_LINK_FREQ_594MHz 594000000LL
+#define IMX335_LINK_FREQ_445MHz 445500000LL
+
#define IMX335_NUM_DATA_LANES 4
#define IMX335_REG_MIN 0x00
@@ -99,7 +116,6 @@ static const char * const imx335_supply_name[] = {
* @vblank_min: Minimum vertical blanking in lines
* @vblank_max: Maximum vertical blanking in lines
* @pclk: Sensor pixel clock
- * @link_freq_idx: Link frequency index
* @reg_list: Register list for sensor mode
*/
struct imx335_mode {
@@ -111,7 +127,6 @@ struct imx335_mode {
u32 vblank_min;
u32 vblank_max;
u64 pclk;
- u32 link_freq_idx;
struct imx335_reg_list reg_list;
};
@@ -134,6 +149,7 @@ struct imx335_mode {
* @vblank: Vertical blanking in lines
* @cur_mode: Pointer to current selected sensor mode
* @mutex: Mutex for serializing sensor controls
+ * @link_freq_bitmap: Menu bitmap for link_freq_ctrl
* @cur_mbus_code: Currently selected media bus format code
*/
struct imx335 {
@@ -157,19 +173,46 @@ struct imx335 {
u32 vblank;
const struct imx335_mode *cur_mode;
struct mutex mutex;
+ unsigned long link_freq_bitmap;
u32 cur_mbus_code;
};
-static const s64 link_freq[] = {
- IMX335_LINK_FREQ,
+static const char * const imx335_tpg_menu[] = {
+ "Disabled",
+ "All 000h",
+ "All FFFh",
+ "All 555h",
+ "All AAAh",
+ "Toggle 555/AAAh",
+ "Toggle AAA/555h",
+ "Toggle 000/555h",
+ "Toggle 555/000h",
+ "Toggle 000/FFFh",
+ "Toggle FFF/000h",
+ "Horizontal color bars",
+ "Vertical color bars",
+};
+
+static const int imx335_tpg_val[] = {
+ IMX335_TPG_ALL_000,
+ IMX335_TPG_ALL_000,
+ IMX335_TPG_ALL_FFF,
+ IMX335_TPG_ALL_555,
+ IMX335_TPG_ALL_AAA,
+ IMX335_TPG_TOG_555_AAA,
+ IMX335_TPG_TOG_AAA_555,
+ IMX335_TPG_TOG_000_555,
+ IMX335_TPG_TOG_555_000,
+ IMX335_TPG_TOG_000_FFF,
+ IMX335_TPG_TOG_FFF_000,
+ IMX335_TPG_H_COLOR_BARS,
+ IMX335_TPG_V_COLOR_BARS,
};
/* Sensor mode registers */
static const struct imx335_reg mode_2592x1940_regs[] = {
{0x3000, 0x01},
{0x3002, 0x00},
- {0x300c, 0x3b},
- {0x300d, 0x2a},
{0x3018, 0x04},
{0x302c, 0x3c},
{0x302e, 0x20},
@@ -177,10 +220,6 @@ static const struct imx335_reg mode_2592x1940_regs[] = {
{0x3074, 0xc8},
{0x3076, 0x28},
{0x304c, 0x00},
- {0x314c, 0xc6},
- {0x315a, 0x02},
- {0x3168, 0xa0},
- {0x316a, 0x7e},
{0x31a1, 0x00},
{0x3288, 0x21},
{0x328a, 0x02},
@@ -249,7 +288,7 @@ static const struct imx335_reg mode_2592x1940_regs[] = {
{0x3794, 0x7a},
{0x3796, 0xa1},
{0x37b0, 0x36},
- {0x3a00, 0x01},
+ {0x3a00, 0x00},
};
static const struct imx335_reg raw10_framefmt_regs[] = {
@@ -266,6 +305,65 @@ static const struct imx335_reg raw12_framefmt_regs[] = {
{0x341d, 0x00},
};
+static const struct imx335_reg mipi_data_rate_1188Mbps[] = {
+ {0x300c, 0x3b},
+ {0x300d, 0x2a},
+ {0x314c, 0xc6},
+ {0x314d, 0x00},
+ {0x315a, 0x02},
+ {0x3168, 0xa0},
+ {0x316a, 0x7e},
+ {0x319e, 0x01},
+ {0x3a18, 0x8f},
+ {0x3a1a, 0x4f},
+ {0x3a1c, 0x47},
+ {0x3a1e, 0x37},
+ {0x3a1f, 0x01},
+ {0x3a20, 0x4f},
+ {0x3a22, 0x87},
+ {0x3a24, 0x4f},
+ {0x3a26, 0x7f},
+ {0x3a28, 0x3f},
+};
+
+static const struct imx335_reg mipi_data_rate_891Mbps[] = {
+ {0x300c, 0x3b},
+ {0x300d, 0x2a},
+ {0x314c, 0x29},
+ {0x314d, 0x01},
+ {0x315a, 0x06},
+ {0x3168, 0xa0},
+ {0x316a, 0x7e},
+ {0x319e, 0x02},
+ {0x3a18, 0x7f},
+ {0x3a1a, 0x37},
+ {0x3a1c, 0x37},
+ {0x3a1e, 0xf7},
+ {0x3a20, 0x3f},
+ {0x3a22, 0x6f},
+ {0x3a24, 0x3f},
+ {0x3a26, 0x5f},
+ {0x3a28, 0x2f},
+};
+
+static const s64 link_freq[] = {
+ /* Corresponds to 1188Mbps data lane rate */
+ IMX335_LINK_FREQ_594MHz,
+ /* Corresponds to 891Mbps data lane rate */
+ IMX335_LINK_FREQ_445MHz,
+};
+
+static const struct imx335_reg_list link_freq_reglist[] = {
+ {
+ .num_of_regs = ARRAY_SIZE(mipi_data_rate_1188Mbps),
+ .regs = mipi_data_rate_1188Mbps,
+ },
+ {
+ .num_of_regs = ARRAY_SIZE(mipi_data_rate_891Mbps),
+ .regs = mipi_data_rate_891Mbps,
+ },
+};
+
static const u32 imx335_mbus_codes[] = {
MEDIA_BUS_FMT_SRGGB12_1X12,
MEDIA_BUS_FMT_SRGGB10_1X10,
@@ -280,7 +378,6 @@ static const struct imx335_mode supported_mode = {
.vblank_min = 2560,
.vblank_max = 133060,
.pclk = 396000000,
- .link_freq_idx = 0,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_2592x1940_regs),
.regs = mode_2592x1940_regs,
@@ -405,7 +502,8 @@ static int imx335_update_controls(struct imx335 *imx335,
{
int ret;
- ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl, mode->link_freq_idx);
+ ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl,
+ __ffs(imx335->link_freq_bitmap));
if (ret)
return ret;
@@ -456,6 +554,49 @@ error_release_group_hold:
return ret;
}
+static int imx335_update_test_pattern(struct imx335 *imx335, u32 pattern_index)
+{
+ int ret;
+
+ if (pattern_index >= ARRAY_SIZE(imx335_tpg_val))
+ return -EINVAL;
+
+ if (pattern_index) {
+ const struct imx335_reg tpg_enable_regs[] = {
+ { 0x3148, 0x10 },
+ { 0x3280, 0x00 },
+ { 0x329c, 0x01 },
+ { 0x32a0, 0x11 },
+ { 0x3302, 0x00 },
+ { 0x3303, 0x00 },
+ { 0x336c, 0x00 },
+ };
+
+ ret = imx335_write_reg(imx335, IMX335_REG_TPG, 1,
+ imx335_tpg_val[pattern_index]);
+ if (ret)
+ return ret;
+
+ ret = imx335_write_regs(imx335, tpg_enable_regs,
+ ARRAY_SIZE(tpg_enable_regs));
+ } else {
+ const struct imx335_reg tpg_disable_regs[] = {
+ { 0x3148, 0x00 },
+ { 0x3280, 0x01 },
+ { 0x329c, 0x00 },
+ { 0x32a0, 0x10 },
+ { 0x3302, 0x32 },
+ { 0x3303, 0x00 },
+ { 0x336c, 0x01 },
+ };
+
+ ret = imx335_write_regs(imx335, tpg_disable_regs,
+ ARRAY_SIZE(tpg_disable_regs));
+ }
+
+ return ret;
+}
+
/**
* imx335_set_ctrl() - Set subdevice control
* @ctrl: pointer to v4l2_ctrl structure
@@ -476,26 +617,31 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
u32 exposure;
int ret;
- switch (ctrl->id) {
- case V4L2_CID_VBLANK:
+ /* Propagate change of current control to all related controls */
+ if (ctrl->id == V4L2_CID_VBLANK) {
imx335->vblank = imx335->vblank_ctrl->val;
dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u\n",
imx335->vblank,
imx335->vblank + imx335->cur_mode->height);
- ret = __v4l2_ctrl_modify_range(imx335->exp_ctrl,
- IMX335_EXPOSURE_MIN,
- imx335->vblank +
- imx335->cur_mode->height -
- IMX335_EXPOSURE_OFFSET,
- 1, IMX335_EXPOSURE_DEFAULT);
- break;
- case V4L2_CID_EXPOSURE:
- /* Set controls only if sensor is in power on state */
- if (!pm_runtime_get_if_in_use(imx335->dev))
- return 0;
+ return __v4l2_ctrl_modify_range(imx335->exp_ctrl,
+ IMX335_EXPOSURE_MIN,
+ imx335->vblank +
+ imx335->cur_mode->height -
+ IMX335_EXPOSURE_OFFSET,
+ 1, IMX335_EXPOSURE_DEFAULT);
+ }
+ /*
+ * Applying V4L2 control value only happens
+ * when power is up for streaming.
+ */
+ if (pm_runtime_get_if_in_use(imx335->dev) == 0)
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
exposure = ctrl->val;
analog_gain = imx335->again_ctrl->val;
@@ -504,7 +650,9 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
ret = imx335_update_exp_gain(imx335, exposure, analog_gain);
- pm_runtime_put(imx335->dev);
+ break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = imx335_update_test_pattern(imx335, ctrl->val);
break;
default:
@@ -512,6 +660,8 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
ret = -EINVAL;
}
+ pm_runtime_put(imx335->dev);
+
return ret;
}
@@ -691,6 +841,13 @@ static int imx335_init_state(struct v4l2_subdev *sd,
fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
imx335_fill_pad_format(imx335, &supported_mode, &fmt);
+ mutex_lock(&imx335->mutex);
+ __v4l2_ctrl_modify_range(imx335->link_freq_ctrl, 0,
+ __fls(imx335->link_freq_bitmap),
+ ~(imx335->link_freq_bitmap),
+ __ffs(imx335->link_freq_bitmap));
+ mutex_unlock(&imx335->mutex);
+
return imx335_set_pad_format(sd, sd_state, &fmt);
}
@@ -755,6 +912,14 @@ static int imx335_start_streaming(struct imx335 *imx335)
const struct imx335_reg_list *reg_list;
int ret;
+ /* Setup PLL */
+ reg_list = &link_freq_reglist[__ffs(imx335->link_freq_bitmap)];
+ ret = imx335_write_regs(imx335, reg_list->regs, reg_list->num_of_regs);
+ if (ret) {
+ dev_err(imx335->dev, "%s failed to set plls\n", __func__);
+ return ret;
+ }
+
/* Write sensor mode registers */
reg_list = &imx335->cur_mode->reg_list;
ret = imx335_write_regs(imx335, reg_list->regs,
@@ -939,19 +1104,10 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
goto done_endpoint_free;
}
- if (!bus_cfg.nr_of_link_frequencies) {
- dev_err(imx335->dev, "no link frequencies defined\n");
- ret = -EINVAL;
- goto done_endpoint_free;
- }
-
- for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
- if (bus_cfg.link_frequencies[i] == IMX335_LINK_FREQ)
- goto done_endpoint_free;
-
- dev_err(imx335->dev, "no compatible link frequencies found\n");
-
- ret = -EINVAL;
+ ret = v4l2_link_freq_to_bitmap(imx335->dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_freq, ARRAY_SIZE(link_freq),
+ &imx335->link_freq_bitmap);
done_endpoint_free:
v4l2_fwnode_endpoint_free(&bus_cfg);
@@ -1055,7 +1211,7 @@ static int imx335_init_controls(struct imx335 *imx335)
u32 lpfr;
int ret;
- ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 7);
if (ret)
return ret;
@@ -1089,6 +1245,12 @@ static int imx335_init_controls(struct imx335 *imx335)
mode->vblank_max,
1, mode->vblank);
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr,
+ &imx335_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(imx335_tpg_menu) - 1,
+ 0, 0, imx335_tpg_menu);
+
/* Read only controls */
imx335->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
&imx335_ctrl_ops,
@@ -1099,9 +1261,8 @@ static int imx335_init_controls(struct imx335 *imx335)
imx335->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&imx335_ctrl_ops,
V4L2_CID_LINK_FREQ,
- ARRAY_SIZE(link_freq) -
- 1,
- mode->link_freq_idx,
+ __fls(imx335->link_freq_bitmap),
+ __ffs(imx335->link_freq_bitmap),
link_freq);
if (imx335->link_freq_ctrl)
imx335->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 8c995c58743a..7e9c2f65fa08 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -56,7 +56,7 @@
#define IMX355_REG_ORIENTATION 0x0101
/* default link frequency and external clock */
-#define IMX355_LINK_FREQ_DEFAULT 360000000
+#define IMX355_LINK_FREQ_DEFAULT 360000000LL
#define IMX355_EXT_CLK 19200000
#define IMX355_LINK_FREQ_INDEX 0
@@ -93,8 +93,7 @@ struct imx355_mode {
struct imx355_hwcfg {
u32 ext_clk; /* sensor external clk */
- s64 *link_freqs; /* CSI-2 link frequencies */
- unsigned int nr_of_link_freqs;
+ unsigned long link_freq_bitmap;
};
struct imx355 {
@@ -115,7 +114,6 @@ struct imx355 {
const struct imx355_mode *cur_mode;
struct imx355_hwcfg *hwcfg;
- s64 link_def_freq; /* CSI-2 link default frequency */
/*
* Mutex for serialized access:
@@ -879,7 +877,10 @@ static const char * const imx355_test_pattern_menu[] = {
"Pseudorandom Sequence (PN9)",
};
-/* supported link frequencies */
+/*
+ * When adding more than the one below, make sure the disallowed ones will
+ * actually be disabled in the LINK_FREQ control.
+ */
static const s64 link_freq_menu_items[] = {
IMX355_LINK_FREQ_DEFAULT,
};
@@ -1356,7 +1357,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
*framefmt = fmt->format;
} else {
imx355->cur_mode = mode;
- pixel_rate = imx355->link_def_freq * 2 * 4;
+ pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
__v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
/* Update limits and set FPS to default */
@@ -1543,7 +1544,7 @@ static int imx355_init_controls(struct imx355 *imx355)
imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
- pixel_rate = imx355->link_def_freq * 2 * 4;
+ pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
/* By default, PIXEL_RATE is read only */
imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
@@ -1620,7 +1621,6 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
};
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
- unsigned int i;
int ret;
if (!fwnode)
@@ -1652,24 +1652,14 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
goto out_err;
}
- dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
- if (!bus_cfg.nr_of_link_frequencies) {
- dev_warn(dev, "no link frequencies defined");
- goto out_err;
- }
-
- cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
- cfg->link_freqs = devm_kcalloc(dev,
- bus_cfg.nr_of_link_frequencies + 1,
- sizeof(*cfg->link_freqs), GFP_KERNEL);
- if (!cfg->link_freqs)
+ ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_freq_menu_items,
+ ARRAY_SIZE(link_freq_menu_items),
+ &cfg->link_freq_bitmap);
+ if (ret)
goto out_err;
- for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
- cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
- dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
- }
-
v4l2_fwnode_endpoint_free(&bus_cfg);
fwnode_handle_put(ep);
return cfg;
@@ -1684,7 +1674,6 @@ static int imx355_probe(struct i2c_client *client)
{
struct imx355 *imx355;
int ret;
- u32 i;
imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
if (!imx355)
@@ -1709,20 +1698,6 @@ static int imx355_probe(struct i2c_client *client)
goto error_probe;
}
- imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX];
- for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) {
- if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) {
- dev_dbg(&client->dev, "link freq index %d matched", i);
- break;
- }
- }
-
- if (i == imx355->hwcfg->nr_of_link_freqs) {
- dev_err(&client->dev, "no link frequency supported");
- ret = -EINVAL;
- goto error_probe;
- }
-
/* Set default mode to max resolution */
imx355->cur_mode = &supported_modes[0];
diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c
index 1e5f20c3ed82..a20b0db330d3 100644
--- a/drivers/media/i2c/imx415.c
+++ b/drivers/media/i2c/imx415.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/videodev2.h>
+#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -28,76 +29,65 @@
#define IMX415_NUM_CLK_PARAM_REGS 11
-#define IMX415_REG_8BIT(n) ((1 << 16) | (n))
-#define IMX415_REG_16BIT(n) ((2 << 16) | (n))
-#define IMX415_REG_24BIT(n) ((3 << 16) | (n))
-#define IMX415_REG_SIZE_SHIFT 16
-#define IMX415_REG_ADDR_MASK 0xffff
-
-#define IMX415_MODE IMX415_REG_8BIT(0x3000)
+#define IMX415_MODE CCI_REG8(0x3000)
#define IMX415_MODE_OPERATING (0)
#define IMX415_MODE_STANDBY BIT(0)
-#define IMX415_REGHOLD IMX415_REG_8BIT(0x3001)
+#define IMX415_REGHOLD CCI_REG8(0x3001)
#define IMX415_REGHOLD_INVALID (0)
#define IMX415_REGHOLD_VALID BIT(0)
-#define IMX415_XMSTA IMX415_REG_8BIT(0x3002)
+#define IMX415_XMSTA CCI_REG8(0x3002)
#define IMX415_XMSTA_START (0)
#define IMX415_XMSTA_STOP BIT(0)
-#define IMX415_BCWAIT_TIME IMX415_REG_16BIT(0x3008)
-#define IMX415_CPWAIT_TIME IMX415_REG_16BIT(0x300A)
-#define IMX415_WINMODE IMX415_REG_8BIT(0x301C)
-#define IMX415_ADDMODE IMX415_REG_8BIT(0x3022)
-#define IMX415_REVERSE IMX415_REG_8BIT(0x3030)
+#define IMX415_BCWAIT_TIME CCI_REG16_LE(0x3008)
+#define IMX415_CPWAIT_TIME CCI_REG16_LE(0x300a)
+#define IMX415_WINMODE CCI_REG8(0x301c)
+#define IMX415_ADDMODE CCI_REG8(0x3022)
+#define IMX415_REVERSE CCI_REG8(0x3030)
#define IMX415_HREVERSE_SHIFT (0)
#define IMX415_VREVERSE_SHIFT BIT(0)
-#define IMX415_ADBIT IMX415_REG_8BIT(0x3031)
-#define IMX415_MDBIT IMX415_REG_8BIT(0x3032)
-#define IMX415_SYS_MODE IMX415_REG_8BIT(0x3033)
-#define IMX415_OUTSEL IMX415_REG_8BIT(0x30C0)
-#define IMX415_DRV IMX415_REG_8BIT(0x30C1)
-#define IMX415_VMAX IMX415_REG_24BIT(0x3024)
-#define IMX415_HMAX IMX415_REG_16BIT(0x3028)
-#define IMX415_SHR0 IMX415_REG_24BIT(0x3050)
-#define IMX415_GAIN_PCG_0 IMX415_REG_16BIT(0x3090)
+#define IMX415_ADBIT CCI_REG8(0x3031)
+#define IMX415_MDBIT CCI_REG8(0x3032)
+#define IMX415_SYS_MODE CCI_REG8(0x3033)
+#define IMX415_OUTSEL CCI_REG8(0x30c0)
+#define IMX415_DRV CCI_REG8(0x30c1)
+#define IMX415_VMAX CCI_REG24_LE(0x3024)
+#define IMX415_HMAX CCI_REG16_LE(0x3028)
+#define IMX415_SHR0 CCI_REG24_LE(0x3050)
+#define IMX415_GAIN_PCG_0 CCI_REG16_LE(0x3090)
#define IMX415_AGAIN_MIN 0
#define IMX415_AGAIN_MAX 100
#define IMX415_AGAIN_STEP 1
-#define IMX415_BLKLEVEL IMX415_REG_16BIT(0x30E2)
+#define IMX415_BLKLEVEL CCI_REG16_LE(0x30e2)
#define IMX415_BLKLEVEL_DEFAULT 50
-#define IMX415_TPG_EN_DUOUT IMX415_REG_8BIT(0x30E4)
-#define IMX415_TPG_PATSEL_DUOUT IMX415_REG_8BIT(0x30E6)
-#define IMX415_TPG_COLORWIDTH IMX415_REG_8BIT(0x30E8)
-#define IMX415_TESTCLKEN_MIPI IMX415_REG_8BIT(0x3110)
-#define IMX415_INCKSEL1 IMX415_REG_8BIT(0x3115)
-#define IMX415_INCKSEL2 IMX415_REG_8BIT(0x3116)
-#define IMX415_INCKSEL3 IMX415_REG_16BIT(0x3118)
-#define IMX415_INCKSEL4 IMX415_REG_16BIT(0x311A)
-#define IMX415_INCKSEL5 IMX415_REG_8BIT(0x311E)
-#define IMX415_DIG_CLP_MODE IMX415_REG_8BIT(0x32C8)
-#define IMX415_WRJ_OPEN IMX415_REG_8BIT(0x3390)
-#define IMX415_SENSOR_INFO IMX415_REG_16BIT(0x3F12)
-#define IMX415_SENSOR_INFO_MASK 0xFFF
+#define IMX415_TPG_EN_DUOUT CCI_REG8(0x30e4)
+#define IMX415_TPG_PATSEL_DUOUT CCI_REG8(0x30e6)
+#define IMX415_TPG_COLORWIDTH CCI_REG8(0x30e8)
+#define IMX415_TESTCLKEN_MIPI CCI_REG8(0x3110)
+#define IMX415_INCKSEL1 CCI_REG8(0x3115)
+#define IMX415_INCKSEL2 CCI_REG8(0x3116)
+#define IMX415_INCKSEL3 CCI_REG16_LE(0x3118)
+#define IMX415_INCKSEL4 CCI_REG16_LE(0x311a)
+#define IMX415_INCKSEL5 CCI_REG8(0x311e)
+#define IMX415_DIG_CLP_MODE CCI_REG8(0x32c8)
+#define IMX415_WRJ_OPEN CCI_REG8(0x3390)
+#define IMX415_SENSOR_INFO CCI_REG16_LE(0x3f12)
+#define IMX415_SENSOR_INFO_MASK 0xfff
#define IMX415_CHIP_ID 0x514
-#define IMX415_LANEMODE IMX415_REG_16BIT(0x4001)
+#define IMX415_LANEMODE CCI_REG16_LE(0x4001)
#define IMX415_LANEMODE_2 1
#define IMX415_LANEMODE_4 3
-#define IMX415_TXCLKESC_FREQ IMX415_REG_16BIT(0x4004)
-#define IMX415_INCKSEL6 IMX415_REG_8BIT(0x400C)
-#define IMX415_TCLKPOST IMX415_REG_16BIT(0x4018)
-#define IMX415_TCLKPREPARE IMX415_REG_16BIT(0x401A)
-#define IMX415_TCLKTRAIL IMX415_REG_16BIT(0x401C)
-#define IMX415_TCLKZERO IMX415_REG_16BIT(0x401E)
-#define IMX415_THSPREPARE IMX415_REG_16BIT(0x4020)
-#define IMX415_THSZERO IMX415_REG_16BIT(0x4022)
-#define IMX415_THSTRAIL IMX415_REG_16BIT(0x4024)
-#define IMX415_THSEXIT IMX415_REG_16BIT(0x4026)
-#define IMX415_TLPX IMX415_REG_16BIT(0x4028)
-#define IMX415_INCKSEL7 IMX415_REG_8BIT(0x4074)
-
-struct imx415_reg {
- u32 address;
- u32 val;
-};
+#define IMX415_TXCLKESC_FREQ CCI_REG16_LE(0x4004)
+#define IMX415_INCKSEL6 CCI_REG8(0x400c)
+#define IMX415_TCLKPOST CCI_REG16_LE(0x4018)
+#define IMX415_TCLKPREPARE CCI_REG16_LE(0x401a)
+#define IMX415_TCLKTRAIL CCI_REG16_LE(0x401c)
+#define IMX415_TCLKZERO CCI_REG16_LE(0x401e)
+#define IMX415_THSPREPARE CCI_REG16_LE(0x4020)
+#define IMX415_THSZERO CCI_REG16_LE(0x4022)
+#define IMX415_THSTRAIL CCI_REG16_LE(0x4024)
+#define IMX415_THSEXIT CCI_REG16_LE(0x4026)
+#define IMX415_TLPX CCI_REG16_LE(0x4028)
+#define IMX415_INCKSEL7 CCI_REG8(0x4074)
static const char *const imx415_supply_names[] = {
"dvdd",
@@ -118,13 +108,13 @@ static const s64 link_freq_menu_items[] = {
struct imx415_clk_params {
u64 lane_rate;
u64 inck;
- struct imx415_reg regs[IMX415_NUM_CLK_PARAM_REGS];
+ struct cci_reg_sequence regs[IMX415_NUM_CLK_PARAM_REGS];
};
/* INCK Settings - includes all lane rate and INCK dependent registers */
static const struct imx415_clk_params imx415_clk_params[] = {
{
- .lane_rate = 594000000,
+ .lane_rate = 594000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
@@ -139,7 +129,37 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
- .lane_rate = 720000000,
+ .lane_rate = 594000000UL,
+ .inck = 37125000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
+ .regs[2] = { IMX415_SYS_MODE, 0x7 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x24 },
+ .regs[5] = { IMX415_INCKSEL3, 0x080 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x24 },
+ .regs[8] = { IMX415_INCKSEL6, 0x0 },
+ .regs[9] = { IMX415_INCKSEL7, 0x1 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0984 },
+ },
+ {
+ .lane_rate = 594000000UL,
+ .inck = 74250000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
+ .regs[2] = { IMX415_SYS_MODE, 0x7 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x080 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x0 },
+ .regs[9] = { IMX415_INCKSEL7, 0x1 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
+ },
+ {
+ .lane_rate = 720000000UL,
.inck = 24000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x054 },
.regs[1] = { IMX415_CPWAIT_TIME, 0x03B },
@@ -154,7 +174,22 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0600 },
},
{
- .lane_rate = 891000000,
+ .lane_rate = 720000000UL,
+ .inck = 72000000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0F8 },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B0 },
+ .regs[2] = { IMX415_SYS_MODE, 0x9 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0A0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x0 },
+ .regs[9] = { IMX415_INCKSEL7, 0x1 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1200 },
+ },
+ {
+ .lane_rate = 891000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
@@ -169,7 +204,37 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
- .lane_rate = 1440000000,
+ .lane_rate = 891000000UL,
+ .inck = 37125000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
+ .regs[2] = { IMX415_SYS_MODE, 0x5 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x24 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0C0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x24 },
+ .regs[8] = { IMX415_INCKSEL6, 0x0 },
+ .regs[9] = { IMX415_INCKSEL7, 0x1 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
+ },
+ {
+ .lane_rate = 891000000UL,
+ .inck = 74250000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
+ .regs[2] = { IMX415_SYS_MODE, 0x5 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0C0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x0 },
+ .regs[9] = { IMX415_INCKSEL7, 0x1 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
+ },
+ {
+ .lane_rate = 1440000000UL,
.inck = 24000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x054 },
.regs[1] = { IMX415_CPWAIT_TIME, 0x03B },
@@ -184,7 +249,22 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0600 },
},
{
- .lane_rate = 1485000000,
+ .lane_rate = 1440000000UL,
+ .inck = 72000000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0F8 },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B0 },
+ .regs[2] = { IMX415_SYS_MODE, 0x8 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0A0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1200 },
+ },
+ {
+ .lane_rate = 1485000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
@@ -198,10 +278,175 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
+ {
+ .lane_rate = 1485000000UL,
+ .inck = 37125000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
+ .regs[2] = { IMX415_SYS_MODE, 0x8 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x24 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0A0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x24 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
+ },
+ {
+ .lane_rate = 1485000000UL,
+ .inck = 74250000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
+ .regs[2] = { IMX415_SYS_MODE, 0x8 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0A0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
+ },
+ {
+ .lane_rate = 1782000000UL,
+ .inck = 27000000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
+ .regs[2] = { IMX415_SYS_MODE, 0x4 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x23 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0C6 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E7 },
+ .regs[7] = { IMX415_INCKSEL5, 0x23 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
+ },
+ {
+ .lane_rate = 1782000000UL,
+ .inck = 37125000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
+ .regs[2] = { IMX415_SYS_MODE, 0x4 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x24 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0C0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x24 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
+ },
+ {
+ .lane_rate = 1782000000UL,
+ .inck = 74250000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
+ .regs[2] = { IMX415_SYS_MODE, 0x4 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0C0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
+ },
+ {
+ .lane_rate = 2079000000UL,
+ .inck = 27000000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
+ .regs[2] = { IMX415_SYS_MODE, 0x2 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x23 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0E7 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E7 },
+ .regs[7] = { IMX415_INCKSEL5, 0x23 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
+ },
+ {
+ .lane_rate = 2079000000UL,
+ .inck = 37125000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
+ .regs[2] = { IMX415_SYS_MODE, 0x2 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x24 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0E0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x24 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
+ },
+ {
+ .lane_rate = 2079000000UL,
+ .inck = 74250000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
+ .regs[2] = { IMX415_SYS_MODE, 0x2 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x0E0 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
+ },
+ {
+ .lane_rate = 2376000000UL,
+ .inck = 27000000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
+ .regs[2] = { IMX415_SYS_MODE, 0x0 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x23 },
+ .regs[5] = { IMX415_INCKSEL3, 0x108 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E7 },
+ .regs[7] = { IMX415_INCKSEL5, 0x23 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
+ },
+ {
+ .lane_rate = 2376000000UL,
+ .inck = 37125000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
+ .regs[2] = { IMX415_SYS_MODE, 0x0 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x24 },
+ .regs[5] = { IMX415_INCKSEL3, 0x100 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x24 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
+ },
+ {
+ .lane_rate = 2376000000UL,
+ .inck = 74250000,
+ .regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
+ .regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
+ .regs[2] = { IMX415_SYS_MODE, 0x0 },
+ .regs[3] = { IMX415_INCKSEL1, 0x00 },
+ .regs[4] = { IMX415_INCKSEL2, 0x28 },
+ .regs[5] = { IMX415_INCKSEL3, 0x100 },
+ .regs[6] = { IMX415_INCKSEL4, 0x0E0 },
+ .regs[7] = { IMX415_INCKSEL5, 0x28 },
+ .regs[8] = { IMX415_INCKSEL6, 0x1 },
+ .regs[9] = { IMX415_INCKSEL7, 0x0 },
+ .regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
+ },
};
/* all-pixel 2-lane 720 Mbps 15.74 Hz mode */
-static const struct imx415_reg imx415_mode_2_720[] = {
+static const struct cci_reg_sequence imx415_mode_2_720[] = {
{ IMX415_VMAX, 0x08CA },
{ IMX415_HMAX, 0x07F0 },
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
@@ -217,7 +462,7 @@ static const struct imx415_reg imx415_mode_2_720[] = {
};
/* all-pixel 2-lane 1440 Mbps 30.01 Hz mode */
-static const struct imx415_reg imx415_mode_2_1440[] = {
+static const struct cci_reg_sequence imx415_mode_2_1440[] = {
{ IMX415_VMAX, 0x08CA },
{ IMX415_HMAX, 0x042A },
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
@@ -233,7 +478,7 @@ static const struct imx415_reg imx415_mode_2_1440[] = {
};
/* all-pixel 4-lane 891 Mbps 30 Hz mode */
-static const struct imx415_reg imx415_mode_4_891[] = {
+static const struct cci_reg_sequence imx415_mode_4_891[] = {
{ IMX415_VMAX, 0x08CA },
{ IMX415_HMAX, 0x044C },
{ IMX415_LANEMODE, IMX415_LANEMODE_4 },
@@ -250,7 +495,7 @@ static const struct imx415_reg imx415_mode_4_891[] = {
struct imx415_mode_reg_list {
u32 num_of_regs;
- const struct imx415_reg *regs;
+ const struct cci_reg_sequence *regs;
};
/*
@@ -323,11 +568,6 @@ static const struct imx415_mode supported_modes[] = {
},
};
-static const struct regmap_config imx415_regmap_config = {
- .reg_bits = 16,
- .val_bits = 8,
-};
-
static const char *const imx415_test_pattern_menu[] = {
"disabled",
"solid black",
@@ -369,7 +609,7 @@ struct imx415 {
* This table includes fixed register settings and a bunch of undocumented
* registers that have to be set to another value than default.
*/
-static const struct imx415_reg imx415_init_table[] = {
+static const struct cci_reg_sequence imx415_init_table[] = {
/* use all-pixel readout mode, no flip */
{ IMX415_WINMODE, 0x00 },
{ IMX415_ADDMODE, 0x00 },
@@ -382,77 +622,77 @@ static const struct imx415_reg imx415_init_table[] = {
{ IMX415_DRV, 0x00 },
/* SONY magic registers */
- { IMX415_REG_8BIT(0x32D4), 0x21 },
- { IMX415_REG_8BIT(0x32EC), 0xA1 },
- { IMX415_REG_8BIT(0x3452), 0x7F },
- { IMX415_REG_8BIT(0x3453), 0x03 },
- { IMX415_REG_8BIT(0x358A), 0x04 },
- { IMX415_REG_8BIT(0x35A1), 0x02 },
- { IMX415_REG_8BIT(0x36BC), 0x0C },
- { IMX415_REG_8BIT(0x36CC), 0x53 },
- { IMX415_REG_8BIT(0x36CD), 0x00 },
- { IMX415_REG_8BIT(0x36CE), 0x3C },
- { IMX415_REG_8BIT(0x36D0), 0x8C },
- { IMX415_REG_8BIT(0x36D1), 0x00 },
- { IMX415_REG_8BIT(0x36D2), 0x71 },
- { IMX415_REG_8BIT(0x36D4), 0x3C },
- { IMX415_REG_8BIT(0x36D6), 0x53 },
- { IMX415_REG_8BIT(0x36D7), 0x00 },
- { IMX415_REG_8BIT(0x36D8), 0x71 },
- { IMX415_REG_8BIT(0x36DA), 0x8C },
- { IMX415_REG_8BIT(0x36DB), 0x00 },
- { IMX415_REG_8BIT(0x3724), 0x02 },
- { IMX415_REG_8BIT(0x3726), 0x02 },
- { IMX415_REG_8BIT(0x3732), 0x02 },
- { IMX415_REG_8BIT(0x3734), 0x03 },
- { IMX415_REG_8BIT(0x3736), 0x03 },
- { IMX415_REG_8BIT(0x3742), 0x03 },
- { IMX415_REG_8BIT(0x3862), 0xE0 },
- { IMX415_REG_8BIT(0x38CC), 0x30 },
- { IMX415_REG_8BIT(0x38CD), 0x2F },
- { IMX415_REG_8BIT(0x395C), 0x0C },
- { IMX415_REG_8BIT(0x3A42), 0xD1 },
- { IMX415_REG_8BIT(0x3A4C), 0x77 },
- { IMX415_REG_8BIT(0x3AE0), 0x02 },
- { IMX415_REG_8BIT(0x3AEC), 0x0C },
- { IMX415_REG_8BIT(0x3B00), 0x2E },
- { IMX415_REG_8BIT(0x3B06), 0x29 },
- { IMX415_REG_8BIT(0x3B98), 0x25 },
- { IMX415_REG_8BIT(0x3B99), 0x21 },
- { IMX415_REG_8BIT(0x3B9B), 0x13 },
- { IMX415_REG_8BIT(0x3B9C), 0x13 },
- { IMX415_REG_8BIT(0x3B9D), 0x13 },
- { IMX415_REG_8BIT(0x3B9E), 0x13 },
- { IMX415_REG_8BIT(0x3BA1), 0x00 },
- { IMX415_REG_8BIT(0x3BA2), 0x06 },
- { IMX415_REG_8BIT(0x3BA3), 0x0B },
- { IMX415_REG_8BIT(0x3BA4), 0x10 },
- { IMX415_REG_8BIT(0x3BA5), 0x14 },
- { IMX415_REG_8BIT(0x3BA6), 0x18 },
- { IMX415_REG_8BIT(0x3BA7), 0x1A },
- { IMX415_REG_8BIT(0x3BA8), 0x1A },
- { IMX415_REG_8BIT(0x3BA9), 0x1A },
- { IMX415_REG_8BIT(0x3BAC), 0xED },
- { IMX415_REG_8BIT(0x3BAD), 0x01 },
- { IMX415_REG_8BIT(0x3BAE), 0xF6 },
- { IMX415_REG_8BIT(0x3BAF), 0x02 },
- { IMX415_REG_8BIT(0x3BB0), 0xA2 },
- { IMX415_REG_8BIT(0x3BB1), 0x03 },
- { IMX415_REG_8BIT(0x3BB2), 0xE0 },
- { IMX415_REG_8BIT(0x3BB3), 0x03 },
- { IMX415_REG_8BIT(0x3BB4), 0xE0 },
- { IMX415_REG_8BIT(0x3BB5), 0x03 },
- { IMX415_REG_8BIT(0x3BB6), 0xE0 },
- { IMX415_REG_8BIT(0x3BB7), 0x03 },
- { IMX415_REG_8BIT(0x3BB8), 0xE0 },
- { IMX415_REG_8BIT(0x3BBA), 0xE0 },
- { IMX415_REG_8BIT(0x3BBC), 0xDA },
- { IMX415_REG_8BIT(0x3BBE), 0x88 },
- { IMX415_REG_8BIT(0x3BC0), 0x44 },
- { IMX415_REG_8BIT(0x3BC2), 0x7B },
- { IMX415_REG_8BIT(0x3BC4), 0xA2 },
- { IMX415_REG_8BIT(0x3BC8), 0xBD },
- { IMX415_REG_8BIT(0x3BCA), 0xBD },
+ { CCI_REG8(0x32D4), 0x21 },
+ { CCI_REG8(0x32EC), 0xA1 },
+ { CCI_REG8(0x3452), 0x7F },
+ { CCI_REG8(0x3453), 0x03 },
+ { CCI_REG8(0x358A), 0x04 },
+ { CCI_REG8(0x35A1), 0x02 },
+ { CCI_REG8(0x36BC), 0x0C },
+ { CCI_REG8(0x36CC), 0x53 },
+ { CCI_REG8(0x36CD), 0x00 },
+ { CCI_REG8(0x36CE), 0x3C },
+ { CCI_REG8(0x36D0), 0x8C },
+ { CCI_REG8(0x36D1), 0x00 },
+ { CCI_REG8(0x36D2), 0x71 },
+ { CCI_REG8(0x36D4), 0x3C },
+ { CCI_REG8(0x36D6), 0x53 },
+ { CCI_REG8(0x36D7), 0x00 },
+ { CCI_REG8(0x36D8), 0x71 },
+ { CCI_REG8(0x36DA), 0x8C },
+ { CCI_REG8(0x36DB), 0x00 },
+ { CCI_REG8(0x3724), 0x02 },
+ { CCI_REG8(0x3726), 0x02 },
+ { CCI_REG8(0x3732), 0x02 },
+ { CCI_REG8(0x3734), 0x03 },
+ { CCI_REG8(0x3736), 0x03 },
+ { CCI_REG8(0x3742), 0x03 },
+ { CCI_REG8(0x3862), 0xE0 },
+ { CCI_REG8(0x38CC), 0x30 },
+ { CCI_REG8(0x38CD), 0x2F },
+ { CCI_REG8(0x395C), 0x0C },
+ { CCI_REG8(0x3A42), 0xD1 },
+ { CCI_REG8(0x3A4C), 0x77 },
+ { CCI_REG8(0x3AE0), 0x02 },
+ { CCI_REG8(0x3AEC), 0x0C },
+ { CCI_REG8(0x3B00), 0x2E },
+ { CCI_REG8(0x3B06), 0x29 },
+ { CCI_REG8(0x3B98), 0x25 },
+ { CCI_REG8(0x3B99), 0x21 },
+ { CCI_REG8(0x3B9B), 0x13 },
+ { CCI_REG8(0x3B9C), 0x13 },
+ { CCI_REG8(0x3B9D), 0x13 },
+ { CCI_REG8(0x3B9E), 0x13 },
+ { CCI_REG8(0x3BA1), 0x00 },
+ { CCI_REG8(0x3BA2), 0x06 },
+ { CCI_REG8(0x3BA3), 0x0B },
+ { CCI_REG8(0x3BA4), 0x10 },
+ { CCI_REG8(0x3BA5), 0x14 },
+ { CCI_REG8(0x3BA6), 0x18 },
+ { CCI_REG8(0x3BA7), 0x1A },
+ { CCI_REG8(0x3BA8), 0x1A },
+ { CCI_REG8(0x3BA9), 0x1A },
+ { CCI_REG8(0x3BAC), 0xED },
+ { CCI_REG8(0x3BAD), 0x01 },
+ { CCI_REG8(0x3BAE), 0xF6 },
+ { CCI_REG8(0x3BAF), 0x02 },
+ { CCI_REG8(0x3BB0), 0xA2 },
+ { CCI_REG8(0x3BB1), 0x03 },
+ { CCI_REG8(0x3BB2), 0xE0 },
+ { CCI_REG8(0x3BB3), 0x03 },
+ { CCI_REG8(0x3BB4), 0xE0 },
+ { CCI_REG8(0x3BB5), 0x03 },
+ { CCI_REG8(0x3BB6), 0xE0 },
+ { CCI_REG8(0x3BB7), 0x03 },
+ { CCI_REG8(0x3BB8), 0xE0 },
+ { CCI_REG8(0x3BBA), 0xE0 },
+ { CCI_REG8(0x3BBC), 0xDA },
+ { CCI_REG8(0x3BBE), 0x88 },
+ { CCI_REG8(0x3BC0), 0x44 },
+ { CCI_REG8(0x3BC2), 0x7B },
+ { CCI_REG8(0x3BC4), 0xA2 },
+ { CCI_REG8(0x3BC8), 0xBD },
+ { CCI_REG8(0x3BCA), 0xBD },
};
static inline struct imx415 *to_imx415(struct v4l2_subdev *sd)
@@ -460,74 +700,26 @@ static inline struct imx415 *to_imx415(struct v4l2_subdev *sd)
return container_of(sd, struct imx415, subdev);
}
-static int imx415_read(struct imx415 *sensor, u32 addr)
-{
- u8 data[3] = { 0 };
- int ret;
-
- ret = regmap_raw_read(sensor->regmap, addr & IMX415_REG_ADDR_MASK, data,
- (addr >> IMX415_REG_SIZE_SHIFT) & 3);
- if (ret < 0)
- return ret;
-
- return (data[2] << 16) | (data[1] << 8) | data[0];
-}
-
-static int imx415_write(struct imx415 *sensor, u32 addr, u32 value)
-{
- u8 data[3] = { value & 0xff, (value >> 8) & 0xff, value >> 16 };
- int ret;
-
- ret = regmap_raw_write(sensor->regmap, addr & IMX415_REG_ADDR_MASK,
- data, (addr >> IMX415_REG_SIZE_SHIFT) & 3);
- if (ret < 0)
- dev_err_ratelimited(sensor->dev,
- "%u-bit write to 0x%04x failed: %d\n",
- ((addr >> IMX415_REG_SIZE_SHIFT) & 3) * 8,
- addr & IMX415_REG_ADDR_MASK, ret);
-
- return 0;
-}
-
static int imx415_set_testpattern(struct imx415 *sensor, int val)
{
- int ret;
+ int ret = 0;
if (val) {
- ret = imx415_write(sensor, IMX415_BLKLEVEL, 0x00);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_TPG_EN_DUOUT, 0x01);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_TPG_PATSEL_DUOUT, val - 1);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_TPG_COLORWIDTH, 0x01);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_TESTCLKEN_MIPI, 0x20);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_DIG_CLP_MODE, 0x00);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_WRJ_OPEN, 0x00);
+ cci_write(sensor->regmap, IMX415_BLKLEVEL, 0x00, &ret);
+ cci_write(sensor->regmap, IMX415_TPG_EN_DUOUT, 0x01, &ret);
+ cci_write(sensor->regmap, IMX415_TPG_PATSEL_DUOUT,
+ val - 1, &ret);
+ cci_write(sensor->regmap, IMX415_TPG_COLORWIDTH, 0x01, &ret);
+ cci_write(sensor->regmap, IMX415_TESTCLKEN_MIPI, 0x20, &ret);
+ cci_write(sensor->regmap, IMX415_DIG_CLP_MODE, 0x00, &ret);
+ cci_write(sensor->regmap, IMX415_WRJ_OPEN, 0x00, &ret);
} else {
- ret = imx415_write(sensor, IMX415_BLKLEVEL,
- IMX415_BLKLEVEL_DEFAULT);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_TPG_EN_DUOUT, 0x00);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_TESTCLKEN_MIPI, 0x00);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_DIG_CLP_MODE, 0x01);
- if (ret)
- return ret;
- ret = imx415_write(sensor, IMX415_WRJ_OPEN, 0x01);
+ cci_write(sensor->regmap, IMX415_BLKLEVEL,
+ IMX415_BLKLEVEL_DEFAULT, &ret);
+ cci_write(sensor->regmap, IMX415_TPG_EN_DUOUT, 0x00, &ret);
+ cci_write(sensor->regmap, IMX415_TESTCLKEN_MIPI, 0x00, &ret);
+ cci_write(sensor->regmap, IMX415_DIG_CLP_MODE, 0x01, &ret);
+ cci_write(sensor->regmap, IMX415_WRJ_OPEN, 0x01, &ret);
}
return 0;
}
@@ -553,19 +745,21 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl)
/* clamp the exposure value to VMAX. */
vmax = format->height + sensor->vblank->cur.val;
ctrl->val = min_t(int, ctrl->val, vmax);
- ret = imx415_write(sensor, IMX415_SHR0, vmax - ctrl->val);
+ ret = cci_write(sensor->regmap, IMX415_SHR0,
+ vmax - ctrl->val, NULL);
break;
case V4L2_CID_ANALOGUE_GAIN:
/* analogue gain in 0.3 dB step size */
- ret = imx415_write(sensor, IMX415_GAIN_PCG_0, ctrl->val);
+ ret = cci_write(sensor->regmap, IMX415_GAIN_PCG_0,
+ ctrl->val, NULL);
break;
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
flip = (sensor->hflip->val << IMX415_HREVERSE_SHIFT) |
(sensor->vflip->val << IMX415_VREVERSE_SHIFT);
- ret = imx415_write(sensor, IMX415_REVERSE, flip);
+ ret = cci_write(sensor->regmap, IMX415_REVERSE, flip, NULL);
break;
case V4L2_CID_TEST_PATTERN:
@@ -679,8 +873,6 @@ static int imx415_ctrls_init(struct imx415 *sensor)
static int imx415_set_mode(struct imx415 *sensor, int mode)
{
- const struct imx415_reg *reg;
- unsigned int i;
int ret = 0;
if (mode >= ARRAY_SIZE(supported_modes)) {
@@ -688,34 +880,29 @@ static int imx415_set_mode(struct imx415 *sensor, int mode)
return -EINVAL;
}
- for (i = 0; i < supported_modes[mode].reg_list.num_of_regs; ++i) {
- reg = &supported_modes[mode].reg_list.regs[i];
- ret = imx415_write(sensor, reg->address, reg->val);
- if (ret)
- return ret;
- }
+ cci_multi_reg_write(sensor->regmap,
+ supported_modes[mode].reg_list.regs,
+ supported_modes[mode].reg_list.num_of_regs,
+ &ret);
- for (i = 0; i < IMX415_NUM_CLK_PARAM_REGS; ++i) {
- reg = &sensor->clk_params->regs[i];
- ret = imx415_write(sensor, reg->address, reg->val);
- if (ret)
- return ret;
- }
+ cci_multi_reg_write(sensor->regmap,
+ sensor->clk_params->regs,
+ IMX415_NUM_CLK_PARAM_REGS,
+ &ret);
return 0;
}
static int imx415_setup(struct imx415 *sensor, struct v4l2_subdev_state *state)
{
- unsigned int i;
int ret;
- for (i = 0; i < ARRAY_SIZE(imx415_init_table); ++i) {
- ret = imx415_write(sensor, imx415_init_table[i].address,
- imx415_init_table[i].val);
- if (ret)
- return ret;
- }
+ ret = cci_multi_reg_write(sensor->regmap,
+ imx415_init_table,
+ ARRAY_SIZE(imx415_init_table),
+ NULL);
+ if (ret)
+ return ret;
return imx415_set_mode(sensor, sensor->cur_mode);
}
@@ -724,7 +911,8 @@ static int imx415_wakeup(struct imx415 *sensor)
{
int ret;
- ret = imx415_write(sensor, IMX415_MODE, IMX415_MODE_OPERATING);
+ ret = cci_write(sensor->regmap, IMX415_MODE,
+ IMX415_MODE_OPERATING, NULL);
if (ret)
return ret;
@@ -743,21 +931,18 @@ static int imx415_stream_on(struct imx415 *sensor)
int ret;
ret = imx415_wakeup(sensor);
- if (ret)
- return ret;
-
- return imx415_write(sensor, IMX415_XMSTA, IMX415_XMSTA_START);
+ return cci_write(sensor->regmap, IMX415_XMSTA,
+ IMX415_XMSTA_START, &ret);
}
static int imx415_stream_off(struct imx415 *sensor)
{
int ret;
- ret = imx415_write(sensor, IMX415_XMSTA, IMX415_XMSTA_STOP);
- if (ret)
- return ret;
-
- return imx415_write(sensor, IMX415_MODE, IMX415_MODE_STANDBY);
+ ret = cci_write(sensor->regmap, IMX415_XMSTA,
+ IMX415_XMSTA_STOP, NULL);
+ return cci_write(sensor->regmap, IMX415_MODE,
+ IMX415_MODE_STANDBY, &ret);
}
static int imx415_s_stream(struct v4l2_subdev *sd, int enable)
@@ -992,6 +1177,7 @@ static void imx415_power_off(struct imx415 *sensor)
static int imx415_identify_model(struct imx415 *sensor)
{
int model, ret;
+ u64 chip_id;
/*
* While most registers can be read when the sensor is in standby, this
@@ -1002,14 +1188,14 @@ static int imx415_identify_model(struct imx415 *sensor)
return dev_err_probe(sensor->dev, ret,
"failed to get sensor out of standby\n");
- ret = imx415_read(sensor, IMX415_SENSOR_INFO);
+ ret = cci_read(sensor->regmap, IMX415_SENSOR_INFO, &chip_id, NULL);
if (ret < 0) {
dev_err_probe(sensor->dev, ret,
"failed to read sensor information\n");
goto done;
}
- model = ret & IMX415_SENSOR_INFO_MASK;
+ model = chip_id & IMX415_SENSOR_INFO_MASK;
switch (model) {
case IMX415_CHIP_ID:
@@ -1024,7 +1210,7 @@ static int imx415_identify_model(struct imx415 *sensor)
ret = 0;
done:
- imx415_write(sensor, IMX415_MODE, IMX415_MODE_STANDBY);
+ cci_write(sensor->regmap, IMX415_MODE, IMX415_MODE_STANDBY, &ret);
return ret;
}
@@ -1173,7 +1359,7 @@ static int imx415_probe(struct i2c_client *client)
if (ret)
return ret;
- sensor->regmap = devm_regmap_init_i2c(client, &imx415_regmap_config);
+ sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(sensor->regmap))
return PTR_ERR(sensor->regmap);
diff --git a/drivers/media/i2c/isl7998x.c b/drivers/media/i2c/isl7998x.c
index 89e13ebbce0c..c7089035bbc1 100644
--- a/drivers/media/i2c/isl7998x.c
+++ b/drivers/media/i2c/isl7998x.c
@@ -1337,7 +1337,7 @@ static const struct regmap_config isl7998x_regmap = {
.rd_table = &isl7998x_readable_table,
.wr_table = &isl7998x_writeable_table,
.volatile_table = &isl7998x_volatile_table,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static int isl7998x_mc_init(struct isl7998x *isl7998x)
diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c
index 70c2a2948fd4..cd73d2096ae4 100644
--- a/drivers/media/i2c/max2175.c
+++ b/drivers/media/i2c/max2175.c
@@ -257,7 +257,7 @@ static const struct regmap_config max2175_regmap_config = {
.reg_defaults = max2175_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(max2175_reg_defaults),
.volatile_table = &max2175_volatile_regs,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
struct max2175 {
diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c
index 0ed8561edfee..599a5bc7cbb3 100644
--- a/drivers/media/i2c/msp3400-driver.c
+++ b/drivers/media/i2c/msp3400-driver.c
@@ -309,23 +309,15 @@ static void msp_wake_thread(struct i2c_client *client)
wake_up_interruptible(&state->wq);
}
-int msp_sleep(struct msp_state *state, int timeout)
+int msp_sleep(struct msp_state *state, int msec)
{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&state->wq, &wait);
- if (!kthread_should_stop()) {
- if (timeout < 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- } else {
- schedule_timeout_interruptible
- (msecs_to_jiffies(timeout));
- }
- }
+ long timeout;
+
+ timeout = msec < 0 ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(msec);
+
+ wait_event_freezable_timeout(state->wq, kthread_should_stop() ||
+ state->restart, timeout);
- remove_wait_queue(&state->wq, &wait);
- try_to_freeze();
return state->restart;
}
diff --git a/drivers/media/i2c/msp3400-driver.h b/drivers/media/i2c/msp3400-driver.h
index 2bb9d5ff1bbd..7d391714ea52 100644
--- a/drivers/media/i2c/msp3400-driver.h
+++ b/drivers/media/i2c/msp3400-driver.h
@@ -134,7 +134,7 @@ int msp_read_dsp(struct i2c_client *client, int addr);
int msp_reset(struct i2c_client *client);
void msp_set_scart(struct i2c_client *client, int in, int out);
void msp_update_volume(struct msp_state *state);
-int msp_sleep(struct msp_state *state, int timeout);
+int msp_sleep(struct msp_state *state, int msec);
/* msp3400-kthreads.c */
const char *msp_standard_std_name(int std);
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 596200d0248c..f4b481212356 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1078,7 +1078,7 @@ mt9p031_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
- np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+ np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!np)
return NULL;
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 3ca76eeae7ff..302120ff125e 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -988,7 +988,7 @@ static const struct regmap_config mt9v032_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.max_register = 0xff,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
/* -----------------------------------------------------------------------------
@@ -1006,7 +1006,7 @@ mt9v032_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
- np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+ np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!np)
return NULL;
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index abbb0b774d43..48df077522ad 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022 Intel Corporation.
+#include <asm-generic/unaligned.h>
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/module.h>
@@ -34,7 +35,7 @@
/* V_TIMING internal */
#define OV08X40_REG_VTS 0x380e
-#define OV08X40_VTS_30FPS 0x1388
+#define OV08X40_VTS_30FPS 0x09c4 /* the VTS need to be half in normal mode */
#define OV08X40_VTS_BIN_30FPS 0x115c
#define OV08X40_VTS_MAX 0x7fff
@@ -44,8 +45,9 @@
/* Exposure control */
#define OV08X40_REG_EXPOSURE 0x3500
-#define OV08X40_EXPOSURE_MAX_MARGIN 31
-#define OV08X40_EXPOSURE_MIN 1
+#define OV08X40_EXPOSURE_MAX_MARGIN 8
+#define OV08X40_EXPOSURE_BIN_MAX_MARGIN 2
+#define OV08X40_EXPOSURE_MIN 4
#define OV08X40_EXPOSURE_STEP 1
#define OV08X40_EXPOSURE_DEFAULT 0x40
@@ -94,6 +96,12 @@
/* Vertical Window Offset */
#define OV08X40_REG_V_WIN_OFFSET 0x3813
+/* Burst Register */
+#define OV08X40_REG_XTALK_FIRST_A 0x5a80
+#define OV08X40_REG_XTALK_LAST_A 0x5b9f
+#define OV08X40_REG_XTALK_FIRST_B 0x5bc0
+#define OV08X40_REG_XTALK_LAST_B 0x5f1f
+
enum {
OV08X40_LINK_FREQ_400MHZ_INDEX,
};
@@ -126,13 +134,17 @@ struct ov08x40_mode {
u32 vts_def;
u32 vts_min;
- /* HTS */
- u32 hts;
+ /* Line Length Pixels */
+ u32 llp;
/* Index of Link frequency config to be used */
u32 link_freq_index;
/* Default register values */
struct ov08x40_reg_list reg_list;
+
+ /* Exposure calculation */
+ u16 exposure_margin;
+ u16 exposure_shift;
};
static const struct ov08x40_reg mipi_data_rate_800mbps[] = {
@@ -665,1158 +677,6 @@ static const struct ov08x40_reg mode_3856x2416_regs[] = {
{0x3502, 0x10},
{0x3508, 0x0f},
{0x3509, 0x80},
- {0x5a80, 0x75},
- {0x5a81, 0x75},
- {0x5a82, 0x75},
- {0x5a83, 0x75},
- {0x5a84, 0x75},
- {0x5a85, 0x75},
- {0x5a86, 0x75},
- {0x5a87, 0x75},
- {0x5a88, 0x75},
- {0x5a89, 0x75},
- {0x5a8a, 0x75},
- {0x5a8b, 0x75},
- {0x5a8c, 0x75},
- {0x5a8d, 0x75},
- {0x5a8e, 0x75},
- {0x5a8f, 0x75},
- {0x5a90, 0x75},
- {0x5a91, 0x75},
- {0x5a92, 0x75},
- {0x5a93, 0x75},
- {0x5a94, 0x75},
- {0x5a95, 0x75},
- {0x5a96, 0x75},
- {0x5a97, 0x75},
- {0x5a98, 0x75},
- {0x5a99, 0x75},
- {0x5a9a, 0x75},
- {0x5a9b, 0x75},
- {0x5a9c, 0x75},
- {0x5a9d, 0x75},
- {0x5a9e, 0x75},
- {0x5a9f, 0x75},
- {0x5aa0, 0x75},
- {0x5aa1, 0x75},
- {0x5aa2, 0x75},
- {0x5aa3, 0x75},
- {0x5aa4, 0x75},
- {0x5aa5, 0x75},
- {0x5aa6, 0x75},
- {0x5aa7, 0x75},
- {0x5aa8, 0x75},
- {0x5aa9, 0x75},
- {0x5aaa, 0x75},
- {0x5aab, 0x75},
- {0x5aac, 0x75},
- {0x5aad, 0x75},
- {0x5aae, 0x75},
- {0x5aaf, 0x75},
- {0x5ab0, 0x75},
- {0x5ab1, 0x75},
- {0x5ab2, 0x75},
- {0x5ab3, 0x75},
- {0x5ab4, 0x75},
- {0x5ab5, 0x75},
- {0x5ab6, 0x75},
- {0x5ab7, 0x75},
- {0x5ab8, 0x75},
- {0x5ab9, 0x75},
- {0x5aba, 0x75},
- {0x5abb, 0x75},
- {0x5abc, 0x75},
- {0x5abd, 0x75},
- {0x5abe, 0x75},
- {0x5abf, 0x75},
- {0x5ac0, 0x75},
- {0x5ac1, 0x75},
- {0x5ac2, 0x75},
- {0x5ac3, 0x75},
- {0x5ac4, 0x75},
- {0x5ac5, 0x75},
- {0x5ac6, 0x75},
- {0x5ac7, 0x75},
- {0x5ac8, 0x75},
- {0x5ac9, 0x75},
- {0x5aca, 0x75},
- {0x5acb, 0x75},
- {0x5acc, 0x75},
- {0x5acd, 0x75},
- {0x5ace, 0x75},
- {0x5acf, 0x75},
- {0x5ad0, 0x75},
- {0x5ad1, 0x75},
- {0x5ad2, 0x75},
- {0x5ad3, 0x75},
- {0x5ad4, 0x75},
- {0x5ad5, 0x75},
- {0x5ad6, 0x75},
- {0x5ad7, 0x75},
- {0x5ad8, 0x75},
- {0x5ad9, 0x75},
- {0x5ada, 0x75},
- {0x5adb, 0x75},
- {0x5adc, 0x75},
- {0x5add, 0x75},
- {0x5ade, 0x75},
- {0x5adf, 0x75},
- {0x5ae0, 0x75},
- {0x5ae1, 0x75},
- {0x5ae2, 0x75},
- {0x5ae3, 0x75},
- {0x5ae4, 0x75},
- {0x5ae5, 0x75},
- {0x5ae6, 0x75},
- {0x5ae7, 0x75},
- {0x5ae8, 0x75},
- {0x5ae9, 0x75},
- {0x5aea, 0x75},
- {0x5aeb, 0x75},
- {0x5aec, 0x75},
- {0x5aed, 0x75},
- {0x5aee, 0x75},
- {0x5aef, 0x75},
- {0x5af0, 0x75},
- {0x5af1, 0x75},
- {0x5af2, 0x75},
- {0x5af3, 0x75},
- {0x5af4, 0x75},
- {0x5af5, 0x75},
- {0x5af6, 0x75},
- {0x5af7, 0x75},
- {0x5af8, 0x75},
- {0x5af9, 0x75},
- {0x5afa, 0x75},
- {0x5afb, 0x75},
- {0x5afc, 0x75},
- {0x5afd, 0x75},
- {0x5afe, 0x75},
- {0x5aff, 0x75},
- {0x5b00, 0x75},
- {0x5b01, 0x75},
- {0x5b02, 0x75},
- {0x5b03, 0x75},
- {0x5b04, 0x75},
- {0x5b05, 0x75},
- {0x5b06, 0x75},
- {0x5b07, 0x75},
- {0x5b08, 0x75},
- {0x5b09, 0x75},
- {0x5b0a, 0x75},
- {0x5b0b, 0x75},
- {0x5b0c, 0x75},
- {0x5b0d, 0x75},
- {0x5b0e, 0x75},
- {0x5b0f, 0x75},
- {0x5b10, 0x75},
- {0x5b11, 0x75},
- {0x5b12, 0x75},
- {0x5b13, 0x75},
- {0x5b14, 0x75},
- {0x5b15, 0x75},
- {0x5b16, 0x75},
- {0x5b17, 0x75},
- {0x5b18, 0x75},
- {0x5b19, 0x75},
- {0x5b1a, 0x75},
- {0x5b1b, 0x75},
- {0x5b1c, 0x75},
- {0x5b1d, 0x75},
- {0x5b1e, 0x75},
- {0x5b1f, 0x75},
- {0x5b20, 0x75},
- {0x5b21, 0x75},
- {0x5b22, 0x75},
- {0x5b23, 0x75},
- {0x5b24, 0x75},
- {0x5b25, 0x75},
- {0x5b26, 0x75},
- {0x5b27, 0x75},
- {0x5b28, 0x75},
- {0x5b29, 0x75},
- {0x5b2a, 0x75},
- {0x5b2b, 0x75},
- {0x5b2c, 0x75},
- {0x5b2d, 0x75},
- {0x5b2e, 0x75},
- {0x5b2f, 0x75},
- {0x5b30, 0x75},
- {0x5b31, 0x75},
- {0x5b32, 0x75},
- {0x5b33, 0x75},
- {0x5b34, 0x75},
- {0x5b35, 0x75},
- {0x5b36, 0x75},
- {0x5b37, 0x75},
- {0x5b38, 0x75},
- {0x5b39, 0x75},
- {0x5b3a, 0x75},
- {0x5b3b, 0x75},
- {0x5b3c, 0x75},
- {0x5b3d, 0x75},
- {0x5b3e, 0x75},
- {0x5b3f, 0x75},
- {0x5b40, 0x75},
- {0x5b41, 0x75},
- {0x5b42, 0x75},
- {0x5b43, 0x75},
- {0x5b44, 0x75},
- {0x5b45, 0x75},
- {0x5b46, 0x75},
- {0x5b47, 0x75},
- {0x5b48, 0x75},
- {0x5b49, 0x75},
- {0x5b4a, 0x75},
- {0x5b4b, 0x75},
- {0x5b4c, 0x75},
- {0x5b4d, 0x75},
- {0x5b4e, 0x75},
- {0x5b4f, 0x75},
- {0x5b50, 0x75},
- {0x5b51, 0x75},
- {0x5b52, 0x75},
- {0x5b53, 0x75},
- {0x5b54, 0x75},
- {0x5b55, 0x75},
- {0x5b56, 0x75},
- {0x5b57, 0x75},
- {0x5b58, 0x75},
- {0x5b59, 0x75},
- {0x5b5a, 0x75},
- {0x5b5b, 0x75},
- {0x5b5c, 0x75},
- {0x5b5d, 0x75},
- {0x5b5e, 0x75},
- {0x5b5f, 0x75},
- {0x5b60, 0x75},
- {0x5b61, 0x75},
- {0x5b62, 0x75},
- {0x5b63, 0x75},
- {0x5b64, 0x75},
- {0x5b65, 0x75},
- {0x5b66, 0x75},
- {0x5b67, 0x75},
- {0x5b68, 0x75},
- {0x5b69, 0x75},
- {0x5b6a, 0x75},
- {0x5b6b, 0x75},
- {0x5b6c, 0x75},
- {0x5b6d, 0x75},
- {0x5b6e, 0x75},
- {0x5b6f, 0x75},
- {0x5b70, 0x75},
- {0x5b71, 0x75},
- {0x5b72, 0x75},
- {0x5b73, 0x75},
- {0x5b74, 0x75},
- {0x5b75, 0x75},
- {0x5b76, 0x75},
- {0x5b77, 0x75},
- {0x5b78, 0x75},
- {0x5b79, 0x75},
- {0x5b7a, 0x75},
- {0x5b7b, 0x75},
- {0x5b7c, 0x75},
- {0x5b7d, 0x75},
- {0x5b7e, 0x75},
- {0x5b7f, 0x75},
- {0x5b80, 0x75},
- {0x5b81, 0x75},
- {0x5b82, 0x75},
- {0x5b83, 0x75},
- {0x5b84, 0x75},
- {0x5b85, 0x75},
- {0x5b86, 0x75},
- {0x5b87, 0x75},
- {0x5b88, 0x75},
- {0x5b89, 0x75},
- {0x5b8a, 0x75},
- {0x5b8b, 0x75},
- {0x5b8c, 0x75},
- {0x5b8d, 0x75},
- {0x5b8e, 0x75},
- {0x5b8f, 0x75},
- {0x5b90, 0x75},
- {0x5b91, 0x75},
- {0x5b92, 0x75},
- {0x5b93, 0x75},
- {0x5b94, 0x75},
- {0x5b95, 0x75},
- {0x5b96, 0x75},
- {0x5b97, 0x75},
- {0x5b98, 0x75},
- {0x5b99, 0x75},
- {0x5b9a, 0x75},
- {0x5b9b, 0x75},
- {0x5b9c, 0x75},
- {0x5b9d, 0x75},
- {0x5b9e, 0x75},
- {0x5b9f, 0x75},
- {0x5bc0, 0x75},
- {0x5bc1, 0x75},
- {0x5bc2, 0x75},
- {0x5bc3, 0x75},
- {0x5bc4, 0x75},
- {0x5bc5, 0x75},
- {0x5bc6, 0x75},
- {0x5bc7, 0x75},
- {0x5bc8, 0x75},
- {0x5bc9, 0x75},
- {0x5bca, 0x75},
- {0x5bcb, 0x75},
- {0x5bcc, 0x75},
- {0x5bcd, 0x75},
- {0x5bce, 0x75},
- {0x5bcf, 0x75},
- {0x5bd0, 0x75},
- {0x5bd1, 0x75},
- {0x5bd2, 0x75},
- {0x5bd3, 0x75},
- {0x5bd4, 0x75},
- {0x5bd5, 0x75},
- {0x5bd6, 0x75},
- {0x5bd7, 0x75},
- {0x5bd8, 0x75},
- {0x5bd9, 0x75},
- {0x5bda, 0x75},
- {0x5bdb, 0x75},
- {0x5bdc, 0x75},
- {0x5bdd, 0x75},
- {0x5bde, 0x75},
- {0x5bdf, 0x75},
- {0x5be0, 0x75},
- {0x5be1, 0x75},
- {0x5be2, 0x75},
- {0x5be3, 0x75},
- {0x5be4, 0x75},
- {0x5be5, 0x75},
- {0x5be6, 0x75},
- {0x5be7, 0x75},
- {0x5be8, 0x75},
- {0x5be9, 0x75},
- {0x5bea, 0x75},
- {0x5beb, 0x75},
- {0x5bec, 0x75},
- {0x5bed, 0x75},
- {0x5bee, 0x75},
- {0x5bef, 0x75},
- {0x5bf0, 0x75},
- {0x5bf1, 0x75},
- {0x5bf2, 0x75},
- {0x5bf3, 0x75},
- {0x5bf4, 0x75},
- {0x5bf5, 0x75},
- {0x5bf6, 0x75},
- {0x5bf7, 0x75},
- {0x5bf8, 0x75},
- {0x5bf9, 0x75},
- {0x5bfa, 0x75},
- {0x5bfb, 0x75},
- {0x5bfc, 0x75},
- {0x5bfd, 0x75},
- {0x5bfe, 0x75},
- {0x5bff, 0x75},
- {0x5c00, 0x75},
- {0x5c01, 0x75},
- {0x5c02, 0x75},
- {0x5c03, 0x75},
- {0x5c04, 0x75},
- {0x5c05, 0x75},
- {0x5c06, 0x75},
- {0x5c07, 0x75},
- {0x5c08, 0x75},
- {0x5c09, 0x75},
- {0x5c0a, 0x75},
- {0x5c0b, 0x75},
- {0x5c0c, 0x75},
- {0x5c0d, 0x75},
- {0x5c0e, 0x75},
- {0x5c0f, 0x75},
- {0x5c10, 0x75},
- {0x5c11, 0x75},
- {0x5c12, 0x75},
- {0x5c13, 0x75},
- {0x5c14, 0x75},
- {0x5c15, 0x75},
- {0x5c16, 0x75},
- {0x5c17, 0x75},
- {0x5c18, 0x75},
- {0x5c19, 0x75},
- {0x5c1a, 0x75},
- {0x5c1b, 0x75},
- {0x5c1c, 0x75},
- {0x5c1d, 0x75},
- {0x5c1e, 0x75},
- {0x5c1f, 0x75},
- {0x5c20, 0x75},
- {0x5c21, 0x75},
- {0x5c22, 0x75},
- {0x5c23, 0x75},
- {0x5c24, 0x75},
- {0x5c25, 0x75},
- {0x5c26, 0x75},
- {0x5c27, 0x75},
- {0x5c28, 0x75},
- {0x5c29, 0x75},
- {0x5c2a, 0x75},
- {0x5c2b, 0x75},
- {0x5c2c, 0x75},
- {0x5c2d, 0x75},
- {0x5c2e, 0x75},
- {0x5c2f, 0x75},
- {0x5c30, 0x75},
- {0x5c31, 0x75},
- {0x5c32, 0x75},
- {0x5c33, 0x75},
- {0x5c34, 0x75},
- {0x5c35, 0x75},
- {0x5c36, 0x75},
- {0x5c37, 0x75},
- {0x5c38, 0x75},
- {0x5c39, 0x75},
- {0x5c3a, 0x75},
- {0x5c3b, 0x75},
- {0x5c3c, 0x75},
- {0x5c3d, 0x75},
- {0x5c3e, 0x75},
- {0x5c3f, 0x75},
- {0x5c40, 0x75},
- {0x5c41, 0x75},
- {0x5c42, 0x75},
- {0x5c43, 0x75},
- {0x5c44, 0x75},
- {0x5c45, 0x75},
- {0x5c46, 0x75},
- {0x5c47, 0x75},
- {0x5c48, 0x75},
- {0x5c49, 0x75},
- {0x5c4a, 0x75},
- {0x5c4b, 0x75},
- {0x5c4c, 0x75},
- {0x5c4d, 0x75},
- {0x5c4e, 0x75},
- {0x5c4f, 0x75},
- {0x5c50, 0x75},
- {0x5c51, 0x75},
- {0x5c52, 0x75},
- {0x5c53, 0x75},
- {0x5c54, 0x75},
- {0x5c55, 0x75},
- {0x5c56, 0x75},
- {0x5c57, 0x75},
- {0x5c58, 0x75},
- {0x5c59, 0x75},
- {0x5c5a, 0x75},
- {0x5c5b, 0x75},
- {0x5c5c, 0x75},
- {0x5c5d, 0x75},
- {0x5c5e, 0x75},
- {0x5c5f, 0x75},
- {0x5c60, 0x75},
- {0x5c61, 0x75},
- {0x5c62, 0x75},
- {0x5c63, 0x75},
- {0x5c64, 0x75},
- {0x5c65, 0x75},
- {0x5c66, 0x75},
- {0x5c67, 0x75},
- {0x5c68, 0x75},
- {0x5c69, 0x75},
- {0x5c6a, 0x75},
- {0x5c6b, 0x75},
- {0x5c6c, 0x75},
- {0x5c6d, 0x75},
- {0x5c6e, 0x75},
- {0x5c6f, 0x75},
- {0x5c70, 0x75},
- {0x5c71, 0x75},
- {0x5c72, 0x75},
- {0x5c73, 0x75},
- {0x5c74, 0x75},
- {0x5c75, 0x75},
- {0x5c76, 0x75},
- {0x5c77, 0x75},
- {0x5c78, 0x75},
- {0x5c79, 0x75},
- {0x5c7a, 0x75},
- {0x5c7b, 0x75},
- {0x5c7c, 0x75},
- {0x5c7d, 0x75},
- {0x5c7e, 0x75},
- {0x5c7f, 0x75},
- {0x5c80, 0x75},
- {0x5c81, 0x75},
- {0x5c82, 0x75},
- {0x5c83, 0x75},
- {0x5c84, 0x75},
- {0x5c85, 0x75},
- {0x5c86, 0x75},
- {0x5c87, 0x75},
- {0x5c88, 0x75},
- {0x5c89, 0x75},
- {0x5c8a, 0x75},
- {0x5c8b, 0x75},
- {0x5c8c, 0x75},
- {0x5c8d, 0x75},
- {0x5c8e, 0x75},
- {0x5c8f, 0x75},
- {0x5c90, 0x75},
- {0x5c91, 0x75},
- {0x5c92, 0x75},
- {0x5c93, 0x75},
- {0x5c94, 0x75},
- {0x5c95, 0x75},
- {0x5c96, 0x75},
- {0x5c97, 0x75},
- {0x5c98, 0x75},
- {0x5c99, 0x75},
- {0x5c9a, 0x75},
- {0x5c9b, 0x75},
- {0x5c9c, 0x75},
- {0x5c9d, 0x75},
- {0x5c9e, 0x75},
- {0x5c9f, 0x75},
- {0x5ca0, 0x75},
- {0x5ca1, 0x75},
- {0x5ca2, 0x75},
- {0x5ca3, 0x75},
- {0x5ca4, 0x75},
- {0x5ca5, 0x75},
- {0x5ca6, 0x75},
- {0x5ca7, 0x75},
- {0x5ca8, 0x75},
- {0x5ca9, 0x75},
- {0x5caa, 0x75},
- {0x5cab, 0x75},
- {0x5cac, 0x75},
- {0x5cad, 0x75},
- {0x5cae, 0x75},
- {0x5caf, 0x75},
- {0x5cb0, 0x75},
- {0x5cb1, 0x75},
- {0x5cb2, 0x75},
- {0x5cb3, 0x75},
- {0x5cb4, 0x75},
- {0x5cb5, 0x75},
- {0x5cb6, 0x75},
- {0x5cb7, 0x75},
- {0x5cb8, 0x75},
- {0x5cb9, 0x75},
- {0x5cba, 0x75},
- {0x5cbb, 0x75},
- {0x5cbc, 0x75},
- {0x5cbd, 0x75},
- {0x5cbe, 0x75},
- {0x5cbf, 0x75},
- {0x5cc0, 0x75},
- {0x5cc1, 0x75},
- {0x5cc2, 0x75},
- {0x5cc3, 0x75},
- {0x5cc4, 0x75},
- {0x5cc5, 0x75},
- {0x5cc6, 0x75},
- {0x5cc7, 0x75},
- {0x5cc8, 0x75},
- {0x5cc9, 0x75},
- {0x5cca, 0x75},
- {0x5ccb, 0x75},
- {0x5ccc, 0x75},
- {0x5ccd, 0x75},
- {0x5cce, 0x75},
- {0x5ccf, 0x75},
- {0x5cd0, 0x75},
- {0x5cd1, 0x75},
- {0x5cd2, 0x75},
- {0x5cd3, 0x75},
- {0x5cd4, 0x75},
- {0x5cd5, 0x75},
- {0x5cd6, 0x75},
- {0x5cd7, 0x75},
- {0x5cd8, 0x75},
- {0x5cd9, 0x75},
- {0x5cda, 0x75},
- {0x5cdb, 0x75},
- {0x5cdc, 0x75},
- {0x5cdd, 0x75},
- {0x5cde, 0x75},
- {0x5cdf, 0x75},
- {0x5ce0, 0x75},
- {0x5ce1, 0x75},
- {0x5ce2, 0x75},
- {0x5ce3, 0x75},
- {0x5ce4, 0x75},
- {0x5ce5, 0x75},
- {0x5ce6, 0x75},
- {0x5ce7, 0x75},
- {0x5ce8, 0x75},
- {0x5ce9, 0x75},
- {0x5cea, 0x75},
- {0x5ceb, 0x75},
- {0x5cec, 0x75},
- {0x5ced, 0x75},
- {0x5cee, 0x75},
- {0x5cef, 0x75},
- {0x5cf0, 0x75},
- {0x5cf1, 0x75},
- {0x5cf2, 0x75},
- {0x5cf3, 0x75},
- {0x5cf4, 0x75},
- {0x5cf5, 0x75},
- {0x5cf6, 0x75},
- {0x5cf7, 0x75},
- {0x5cf8, 0x75},
- {0x5cf9, 0x75},
- {0x5cfa, 0x75},
- {0x5cfb, 0x75},
- {0x5cfc, 0x75},
- {0x5cfd, 0x75},
- {0x5cfe, 0x75},
- {0x5cff, 0x75},
- {0x5d00, 0x75},
- {0x5d01, 0x75},
- {0x5d02, 0x75},
- {0x5d03, 0x75},
- {0x5d04, 0x75},
- {0x5d05, 0x75},
- {0x5d06, 0x75},
- {0x5d07, 0x75},
- {0x5d08, 0x75},
- {0x5d09, 0x75},
- {0x5d0a, 0x75},
- {0x5d0b, 0x75},
- {0x5d0c, 0x75},
- {0x5d0d, 0x75},
- {0x5d0e, 0x75},
- {0x5d0f, 0x75},
- {0x5d10, 0x75},
- {0x5d11, 0x75},
- {0x5d12, 0x75},
- {0x5d13, 0x75},
- {0x5d14, 0x75},
- {0x5d15, 0x75},
- {0x5d16, 0x75},
- {0x5d17, 0x75},
- {0x5d18, 0x75},
- {0x5d19, 0x75},
- {0x5d1a, 0x75},
- {0x5d1b, 0x75},
- {0x5d1c, 0x75},
- {0x5d1d, 0x75},
- {0x5d1e, 0x75},
- {0x5d1f, 0x75},
- {0x5d20, 0x75},
- {0x5d21, 0x75},
- {0x5d22, 0x75},
- {0x5d23, 0x75},
- {0x5d24, 0x75},
- {0x5d25, 0x75},
- {0x5d26, 0x75},
- {0x5d27, 0x75},
- {0x5d28, 0x75},
- {0x5d29, 0x75},
- {0x5d2a, 0x75},
- {0x5d2b, 0x75},
- {0x5d2c, 0x75},
- {0x5d2d, 0x75},
- {0x5d2e, 0x75},
- {0x5d2f, 0x75},
- {0x5d30, 0x75},
- {0x5d31, 0x75},
- {0x5d32, 0x75},
- {0x5d33, 0x75},
- {0x5d34, 0x75},
- {0x5d35, 0x75},
- {0x5d36, 0x75},
- {0x5d37, 0x75},
- {0x5d38, 0x75},
- {0x5d39, 0x75},
- {0x5d3a, 0x75},
- {0x5d3b, 0x75},
- {0x5d3c, 0x75},
- {0x5d3d, 0x75},
- {0x5d3e, 0x75},
- {0x5d3f, 0x75},
- {0x5d40, 0x75},
- {0x5d41, 0x75},
- {0x5d42, 0x75},
- {0x5d43, 0x75},
- {0x5d44, 0x75},
- {0x5d45, 0x75},
- {0x5d46, 0x75},
- {0x5d47, 0x75},
- {0x5d48, 0x75},
- {0x5d49, 0x75},
- {0x5d4a, 0x75},
- {0x5d4b, 0x75},
- {0x5d4c, 0x75},
- {0x5d4d, 0x75},
- {0x5d4e, 0x75},
- {0x5d4f, 0x75},
- {0x5d50, 0x75},
- {0x5d51, 0x75},
- {0x5d52, 0x75},
- {0x5d53, 0x75},
- {0x5d54, 0x75},
- {0x5d55, 0x75},
- {0x5d56, 0x75},
- {0x5d57, 0x75},
- {0x5d58, 0x75},
- {0x5d59, 0x75},
- {0x5d5a, 0x75},
- {0x5d5b, 0x75},
- {0x5d5c, 0x75},
- {0x5d5d, 0x75},
- {0x5d5e, 0x75},
- {0x5d5f, 0x75},
- {0x5d60, 0x75},
- {0x5d61, 0x75},
- {0x5d62, 0x75},
- {0x5d63, 0x75},
- {0x5d64, 0x75},
- {0x5d65, 0x75},
- {0x5d66, 0x75},
- {0x5d67, 0x75},
- {0x5d68, 0x75},
- {0x5d69, 0x75},
- {0x5d6a, 0x75},
- {0x5d6b, 0x75},
- {0x5d6c, 0x75},
- {0x5d6d, 0x75},
- {0x5d6e, 0x75},
- {0x5d6f, 0x75},
- {0x5d70, 0x75},
- {0x5d71, 0x75},
- {0x5d72, 0x75},
- {0x5d73, 0x75},
- {0x5d74, 0x75},
- {0x5d75, 0x75},
- {0x5d76, 0x75},
- {0x5d77, 0x75},
- {0x5d78, 0x75},
- {0x5d79, 0x75},
- {0x5d7a, 0x75},
- {0x5d7b, 0x75},
- {0x5d7c, 0x75},
- {0x5d7d, 0x75},
- {0x5d7e, 0x75},
- {0x5d7f, 0x75},
- {0x5d80, 0x75},
- {0x5d81, 0x75},
- {0x5d82, 0x75},
- {0x5d83, 0x75},
- {0x5d84, 0x75},
- {0x5d85, 0x75},
- {0x5d86, 0x75},
- {0x5d87, 0x75},
- {0x5d88, 0x75},
- {0x5d89, 0x75},
- {0x5d8a, 0x75},
- {0x5d8b, 0x75},
- {0x5d8c, 0x75},
- {0x5d8d, 0x75},
- {0x5d8e, 0x75},
- {0x5d8f, 0x75},
- {0x5d90, 0x75},
- {0x5d91, 0x75},
- {0x5d92, 0x75},
- {0x5d93, 0x75},
- {0x5d94, 0x75},
- {0x5d95, 0x75},
- {0x5d96, 0x75},
- {0x5d97, 0x75},
- {0x5d98, 0x75},
- {0x5d99, 0x75},
- {0x5d9a, 0x75},
- {0x5d9b, 0x75},
- {0x5d9c, 0x75},
- {0x5d9d, 0x75},
- {0x5d9e, 0x75},
- {0x5d9f, 0x75},
- {0x5da0, 0x75},
- {0x5da1, 0x75},
- {0x5da2, 0x75},
- {0x5da3, 0x75},
- {0x5da4, 0x75},
- {0x5da5, 0x75},
- {0x5da6, 0x75},
- {0x5da7, 0x75},
- {0x5da8, 0x75},
- {0x5da9, 0x75},
- {0x5daa, 0x75},
- {0x5dab, 0x75},
- {0x5dac, 0x75},
- {0x5dad, 0x75},
- {0x5dae, 0x75},
- {0x5daf, 0x75},
- {0x5db0, 0x75},
- {0x5db1, 0x75},
- {0x5db2, 0x75},
- {0x5db3, 0x75},
- {0x5db4, 0x75},
- {0x5db5, 0x75},
- {0x5db6, 0x75},
- {0x5db7, 0x75},
- {0x5db8, 0x75},
- {0x5db9, 0x75},
- {0x5dba, 0x75},
- {0x5dbb, 0x75},
- {0x5dbc, 0x75},
- {0x5dbd, 0x75},
- {0x5dbe, 0x75},
- {0x5dbf, 0x75},
- {0x5dc0, 0x75},
- {0x5dc1, 0x75},
- {0x5dc2, 0x75},
- {0x5dc3, 0x75},
- {0x5dc4, 0x75},
- {0x5dc5, 0x75},
- {0x5dc6, 0x75},
- {0x5dc7, 0x75},
- {0x5dc8, 0x75},
- {0x5dc9, 0x75},
- {0x5dca, 0x75},
- {0x5dcb, 0x75},
- {0x5dcc, 0x75},
- {0x5dcd, 0x75},
- {0x5dce, 0x75},
- {0x5dcf, 0x75},
- {0x5dd0, 0x75},
- {0x5dd1, 0x75},
- {0x5dd2, 0x75},
- {0x5dd3, 0x75},
- {0x5dd4, 0x75},
- {0x5dd5, 0x75},
- {0x5dd6, 0x75},
- {0x5dd7, 0x75},
- {0x5dd8, 0x75},
- {0x5dd9, 0x75},
- {0x5dda, 0x75},
- {0x5ddb, 0x75},
- {0x5ddc, 0x75},
- {0x5ddd, 0x75},
- {0x5dde, 0x75},
- {0x5ddf, 0x75},
- {0x5de0, 0x75},
- {0x5de1, 0x75},
- {0x5de2, 0x75},
- {0x5de3, 0x75},
- {0x5de4, 0x75},
- {0x5de5, 0x75},
- {0x5de6, 0x75},
- {0x5de7, 0x75},
- {0x5de8, 0x75},
- {0x5de9, 0x75},
- {0x5dea, 0x75},
- {0x5deb, 0x75},
- {0x5dec, 0x75},
- {0x5ded, 0x75},
- {0x5dee, 0x75},
- {0x5def, 0x75},
- {0x5df0, 0x75},
- {0x5df1, 0x75},
- {0x5df2, 0x75},
- {0x5df3, 0x75},
- {0x5df4, 0x75},
- {0x5df5, 0x75},
- {0x5df6, 0x75},
- {0x5df7, 0x75},
- {0x5df8, 0x75},
- {0x5df9, 0x75},
- {0x5dfa, 0x75},
- {0x5dfb, 0x75},
- {0x5dfc, 0x75},
- {0x5dfd, 0x75},
- {0x5dfe, 0x75},
- {0x5dff, 0x75},
- {0x5e00, 0x75},
- {0x5e01, 0x75},
- {0x5e02, 0x75},
- {0x5e03, 0x75},
- {0x5e04, 0x75},
- {0x5e05, 0x75},
- {0x5e06, 0x75},
- {0x5e07, 0x75},
- {0x5e08, 0x75},
- {0x5e09, 0x75},
- {0x5e0a, 0x75},
- {0x5e0b, 0x75},
- {0x5e0c, 0x75},
- {0x5e0d, 0x75},
- {0x5e0e, 0x75},
- {0x5e0f, 0x75},
- {0x5e10, 0x75},
- {0x5e11, 0x75},
- {0x5e12, 0x75},
- {0x5e13, 0x75},
- {0x5e14, 0x75},
- {0x5e15, 0x75},
- {0x5e16, 0x75},
- {0x5e17, 0x75},
- {0x5e18, 0x75},
- {0x5e19, 0x75},
- {0x5e1a, 0x75},
- {0x5e1b, 0x75},
- {0x5e1c, 0x75},
- {0x5e1d, 0x75},
- {0x5e1e, 0x75},
- {0x5e1f, 0x75},
- {0x5e20, 0x75},
- {0x5e21, 0x75},
- {0x5e22, 0x75},
- {0x5e23, 0x75},
- {0x5e24, 0x75},
- {0x5e25, 0x75},
- {0x5e26, 0x75},
- {0x5e27, 0x75},
- {0x5e28, 0x75},
- {0x5e29, 0x75},
- {0x5e2a, 0x75},
- {0x5e2b, 0x75},
- {0x5e2c, 0x75},
- {0x5e2d, 0x75},
- {0x5e2e, 0x75},
- {0x5e2f, 0x75},
- {0x5e30, 0x75},
- {0x5e31, 0x75},
- {0x5e32, 0x75},
- {0x5e33, 0x75},
- {0x5e34, 0x75},
- {0x5e35, 0x75},
- {0x5e36, 0x75},
- {0x5e37, 0x75},
- {0x5e38, 0x75},
- {0x5e39, 0x75},
- {0x5e3a, 0x75},
- {0x5e3b, 0x75},
- {0x5e3c, 0x75},
- {0x5e3d, 0x75},
- {0x5e3e, 0x75},
- {0x5e3f, 0x75},
- {0x5e40, 0x75},
- {0x5e41, 0x75},
- {0x5e42, 0x75},
- {0x5e43, 0x75},
- {0x5e44, 0x75},
- {0x5e45, 0x75},
- {0x5e46, 0x75},
- {0x5e47, 0x75},
- {0x5e48, 0x75},
- {0x5e49, 0x75},
- {0x5e4a, 0x75},
- {0x5e4b, 0x75},
- {0x5e4c, 0x75},
- {0x5e4d, 0x75},
- {0x5e4e, 0x75},
- {0x5e4f, 0x75},
- {0x5e50, 0x75},
- {0x5e51, 0x75},
- {0x5e52, 0x75},
- {0x5e53, 0x75},
- {0x5e54, 0x75},
- {0x5e55, 0x75},
- {0x5e56, 0x75},
- {0x5e57, 0x75},
- {0x5e58, 0x75},
- {0x5e59, 0x75},
- {0x5e5a, 0x75},
- {0x5e5b, 0x75},
- {0x5e5c, 0x75},
- {0x5e5d, 0x75},
- {0x5e5e, 0x75},
- {0x5e5f, 0x75},
- {0x5e60, 0x75},
- {0x5e61, 0x75},
- {0x5e62, 0x75},
- {0x5e63, 0x75},
- {0x5e64, 0x75},
- {0x5e65, 0x75},
- {0x5e66, 0x75},
- {0x5e67, 0x75},
- {0x5e68, 0x75},
- {0x5e69, 0x75},
- {0x5e6a, 0x75},
- {0x5e6b, 0x75},
- {0x5e6c, 0x75},
- {0x5e6d, 0x75},
- {0x5e6e, 0x75},
- {0x5e6f, 0x75},
- {0x5e70, 0x75},
- {0x5e71, 0x75},
- {0x5e72, 0x75},
- {0x5e73, 0x75},
- {0x5e74, 0x75},
- {0x5e75, 0x75},
- {0x5e76, 0x75},
- {0x5e77, 0x75},
- {0x5e78, 0x75},
- {0x5e79, 0x75},
- {0x5e7a, 0x75},
- {0x5e7b, 0x75},
- {0x5e7c, 0x75},
- {0x5e7d, 0x75},
- {0x5e7e, 0x75},
- {0x5e7f, 0x75},
- {0x5e80, 0x75},
- {0x5e81, 0x75},
- {0x5e82, 0x75},
- {0x5e83, 0x75},
- {0x5e84, 0x75},
- {0x5e85, 0x75},
- {0x5e86, 0x75},
- {0x5e87, 0x75},
- {0x5e88, 0x75},
- {0x5e89, 0x75},
- {0x5e8a, 0x75},
- {0x5e8b, 0x75},
- {0x5e8c, 0x75},
- {0x5e8d, 0x75},
- {0x5e8e, 0x75},
- {0x5e8f, 0x75},
- {0x5e90, 0x75},
- {0x5e91, 0x75},
- {0x5e92, 0x75},
- {0x5e93, 0x75},
- {0x5e94, 0x75},
- {0x5e95, 0x75},
- {0x5e96, 0x75},
- {0x5e97, 0x75},
- {0x5e98, 0x75},
- {0x5e99, 0x75},
- {0x5e9a, 0x75},
- {0x5e9b, 0x75},
- {0x5e9c, 0x75},
- {0x5e9d, 0x75},
- {0x5e9e, 0x75},
- {0x5e9f, 0x75},
- {0x5ea0, 0x75},
- {0x5ea1, 0x75},
- {0x5ea2, 0x75},
- {0x5ea3, 0x75},
- {0x5ea4, 0x75},
- {0x5ea5, 0x75},
- {0x5ea6, 0x75},
- {0x5ea7, 0x75},
- {0x5ea8, 0x75},
- {0x5ea9, 0x75},
- {0x5eaa, 0x75},
- {0x5eab, 0x75},
- {0x5eac, 0x75},
- {0x5ead, 0x75},
- {0x5eae, 0x75},
- {0x5eaf, 0x75},
- {0x5eb0, 0x75},
- {0x5eb1, 0x75},
- {0x5eb2, 0x75},
- {0x5eb3, 0x75},
- {0x5eb4, 0x75},
- {0x5eb5, 0x75},
- {0x5eb6, 0x75},
- {0x5eb7, 0x75},
- {0x5eb8, 0x75},
- {0x5eb9, 0x75},
- {0x5eba, 0x75},
- {0x5ebb, 0x75},
- {0x5ebc, 0x75},
- {0x5ebd, 0x75},
- {0x5ebe, 0x75},
- {0x5ebf, 0x75},
- {0x5ec0, 0x75},
- {0x5ec1, 0x75},
- {0x5ec2, 0x75},
- {0x5ec3, 0x75},
- {0x5ec4, 0x75},
- {0x5ec5, 0x75},
- {0x5ec6, 0x75},
- {0x5ec7, 0x75},
- {0x5ec8, 0x75},
- {0x5ec9, 0x75},
- {0x5eca, 0x75},
- {0x5ecb, 0x75},
- {0x5ecc, 0x75},
- {0x5ecd, 0x75},
- {0x5ece, 0x75},
- {0x5ecf, 0x75},
- {0x5ed0, 0x75},
- {0x5ed1, 0x75},
- {0x5ed2, 0x75},
- {0x5ed3, 0x75},
- {0x5ed4, 0x75},
- {0x5ed5, 0x75},
- {0x5ed6, 0x75},
- {0x5ed7, 0x75},
- {0x5ed8, 0x75},
- {0x5ed9, 0x75},
- {0x5eda, 0x75},
- {0x5edb, 0x75},
- {0x5edc, 0x75},
- {0x5edd, 0x75},
- {0x5ede, 0x75},
- {0x5edf, 0x75},
- {0x5ee0, 0x75},
- {0x5ee1, 0x75},
- {0x5ee2, 0x75},
- {0x5ee3, 0x75},
- {0x5ee4, 0x75},
- {0x5ee5, 0x75},
- {0x5ee6, 0x75},
- {0x5ee7, 0x75},
- {0x5ee8, 0x75},
- {0x5ee9, 0x75},
- {0x5eea, 0x75},
- {0x5eeb, 0x75},
- {0x5eec, 0x75},
- {0x5eed, 0x75},
- {0x5eee, 0x75},
- {0x5eef, 0x75},
- {0x5ef0, 0x75},
- {0x5ef1, 0x75},
- {0x5ef2, 0x75},
- {0x5ef3, 0x75},
- {0x5ef4, 0x75},
- {0x5ef5, 0x75},
- {0x5ef6, 0x75},
- {0x5ef7, 0x75},
- {0x5ef8, 0x75},
- {0x5ef9, 0x75},
- {0x5efa, 0x75},
- {0x5efb, 0x75},
- {0x5efc, 0x75},
- {0x5efd, 0x75},
- {0x5efe, 0x75},
- {0x5eff, 0x75},
- {0x5f00, 0x75},
- {0x5f01, 0x75},
- {0x5f02, 0x75},
- {0x5f03, 0x75},
- {0x5f04, 0x75},
- {0x5f05, 0x75},
- {0x5f06, 0x75},
- {0x5f07, 0x75},
- {0x5f08, 0x75},
- {0x5f09, 0x75},
- {0x5f0a, 0x75},
- {0x5f0b, 0x75},
- {0x5f0c, 0x75},
- {0x5f0d, 0x75},
- {0x5f0e, 0x75},
- {0x5f0f, 0x75},
- {0x5f10, 0x75},
- {0x5f11, 0x75},
- {0x5f12, 0x75},
- {0x5f13, 0x75},
- {0x5f14, 0x75},
- {0x5f15, 0x75},
- {0x5f16, 0x75},
- {0x5f17, 0x75},
- {0x5f18, 0x75},
- {0x5f19, 0x75},
- {0x5f1a, 0x75},
- {0x5f1b, 0x75},
- {0x5f1c, 0x75},
- {0x5f1d, 0x75},
- {0x5f1e, 0x75},
- {0x5f1f, 0x75},
};
static const struct ov08x40_reg mode_1928x1208_regs[] = {
@@ -2354,7 +1214,7 @@ static const char * const ov08x40_test_pattern_menu[] = {
/* Configurations for supported link frequencies */
#define OV08X40_LINK_FREQ_400MHZ 400000000ULL
-
+#define OV08X40_SCLK_96MHZ 96000000ULL
#define OV08X40_EXT_CLK 19200000
#define OV08X40_DATA_LANES 4
@@ -2392,26 +1252,30 @@ static const struct ov08x40_mode supported_modes[] = {
.height = 2416,
.vts_def = OV08X40_VTS_30FPS,
.vts_min = OV08X40_VTS_30FPS,
- .hts = 640,
+ .llp = 0x10aa, /* in normal mode, tline time = 2 * HTS / SCLK */
.lanes = 4,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3856x2416_regs),
.regs = mode_3856x2416_regs,
},
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
+ .exposure_shift = 1,
+ .exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
},
{
.width = 1928,
.height = 1208,
.vts_def = OV08X40_VTS_BIN_30FPS,
.vts_min = OV08X40_VTS_BIN_30FPS,
- .hts = 720,
+ .llp = 0x960,
.lanes = 4,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1928x1208_regs),
.regs = mode_1928x1208_regs,
},
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
+ .exposure_shift = 0,
+ .exposure_margin = OV08X40_EXPOSURE_BIN_MAX_MARGIN,
},
};
@@ -2432,6 +1296,9 @@ struct ov08x40 {
/* Mutex for serialized access */
struct mutex mutex;
+
+ /* True if the device has been identified */
+ bool identified;
};
#define to_ov08x40(_sd) container_of(_sd, struct ov08x40, sd)
@@ -2472,6 +1339,40 @@ static int ov08x40_read_reg(struct ov08x40 *ov08x,
return 0;
}
+static int ov08x40_burst_fill_regs(struct ov08x40 *ov08x, u16 first_reg,
+ u16 last_reg, u8 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
+ struct i2c_msg msgs;
+ size_t i, num_regs;
+ int ret;
+
+ num_regs = last_reg - first_reg + 1;
+ msgs.addr = client->addr;
+ msgs.flags = 0;
+ msgs.len = 2 + num_regs;
+ msgs.buf = kmalloc(msgs.len, GFP_KERNEL);
+
+ if (!msgs.buf)
+ return -ENOMEM;
+
+ put_unaligned_be16(first_reg, msgs.buf);
+
+ for (i = 0; i < num_regs; ++i)
+ msgs.buf[2 + i] = val;
+
+ ret = i2c_transfer(client->adapter, &msgs, 1);
+
+ kfree(msgs.buf);
+
+ if (ret != 1) {
+ dev_err(&client->dev, "Failed regs transferred: %d\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
/* Write registers up to 4 at a time */
static int ov08x40_write_reg(struct ov08x40 *ov08x,
u16 reg, u32 len, u32 __val)
@@ -2664,13 +1565,23 @@ static int ov08x40_set_ctrl(struct v4l2_ctrl *ctrl)
struct ov08x40, ctrl_handler);
struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
s64 max;
+ int exp;
+ int fll;
int ret = 0;
/* Propagate change of current control to all related controls */
switch (ctrl->id) {
case V4L2_CID_VBLANK:
/* Update max exposure while meeting expected vblanking */
- max = ov08x->cur_mode->height + ctrl->val - OV08X40_EXPOSURE_MAX_MARGIN;
+ /*
+ * because in normal mode, 1 HTS = 0.5 tline
+ * fps = sclk / hts / vts
+ * so the vts value needs to be double
+ */
+ max = ((ov08x->cur_mode->height + ctrl->val) <<
+ ov08x->cur_mode->exposure_shift) -
+ ov08x->cur_mode->exposure_margin;
+
__v4l2_ctrl_modify_range(ov08x->exposure,
ov08x->exposure->minimum,
max, ov08x->exposure->step, max);
@@ -2694,15 +1605,20 @@ static int ov08x40_set_ctrl(struct v4l2_ctrl *ctrl)
ret = ov08x40_update_digital_gain(ov08x, ctrl->val);
break;
case V4L2_CID_EXPOSURE:
+ exp = (ctrl->val << ov08x->cur_mode->exposure_shift) -
+ ov08x->cur_mode->exposure_margin;
+
ret = ov08x40_write_reg(ov08x, OV08X40_REG_EXPOSURE,
OV08X40_REG_VALUE_24BIT,
- ctrl->val);
+ exp);
break;
case V4L2_CID_VBLANK:
+ fll = ((ov08x->cur_mode->height + ctrl->val) <<
+ ov08x->cur_mode->exposure_shift);
+
ret = ov08x40_write_reg(ov08x, OV08X40_REG_VTS,
OV08X40_REG_VALUE_16BIT,
- ov08x->cur_mode->height
- + ctrl->val);
+ fll);
break;
case V4L2_CID_TEST_PATTERN:
ret = ov08x40_enable_test_pattern(ov08x, ctrl->val);
@@ -2812,6 +1728,7 @@ ov08x40_set_pad_format(struct v4l2_subdev *sd,
s64 h_blank;
s64 pixel_rate;
s64 link_freq;
+ u64 steps;
mutex_lock(&ov08x->mutex);
@@ -2839,13 +1756,22 @@ ov08x40_set_pad_format(struct v4l2_subdev *sd,
ov08x->cur_mode->height;
vblank_min = ov08x->cur_mode->vts_min -
ov08x->cur_mode->height;
+
+ /*
+ * The frame length line should be aligned to a multiple of 4,
+ * as provided by the sensor vendor, in normal mode.
+ */
+ steps = mode->exposure_shift == 1 ? 4 : 1;
+
__v4l2_ctrl_modify_range(ov08x->vblank, vblank_min,
OV08X40_VTS_MAX
- ov08x->cur_mode->height,
- 1,
+ steps,
vblank_def);
__v4l2_ctrl_s_ctrl(ov08x->vblank, vblank_def);
- h_blank = ov08x->cur_mode->hts;
+
+ h_blank = ov08x->cur_mode->llp - ov08x->cur_mode->width;
+
__v4l2_ctrl_modify_range(ov08x->hblank, h_blank,
h_blank, 1, h_blank);
}
@@ -2887,6 +1813,22 @@ static int ov08x40_start_streaming(struct ov08x40 *ov08x)
return ret;
}
+ /* Use i2c burst to write register on full size registers */
+ if (ov08x->cur_mode->exposure_shift == 1) {
+ ret = ov08x40_burst_fill_regs(ov08x, OV08X40_REG_XTALK_FIRST_A,
+ OV08X40_REG_XTALK_LAST_A, 0x75);
+ if (ret == 0)
+ ret = ov08x40_burst_fill_regs(ov08x,
+ OV08X40_REG_XTALK_FIRST_B,
+ OV08X40_REG_XTALK_LAST_B,
+ 0x75);
+ }
+
+ if (ret) {
+ dev_err(&client->dev, "%s failed to set regs\n", __func__);
+ return ret;
+ }
+
/* Apply customized values from user */
ret = __v4l2_ctrl_handler_setup(ov08x->sd.ctrl_handler);
if (ret)
@@ -2948,6 +1890,9 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x)
int ret;
u32 val;
+ if (ov08x->identified)
+ return 0;
+
ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID,
OV08X40_REG_VALUE_24BIT, &val);
if (ret)
@@ -2956,9 +1901,11 @@ static int ov08x40_identify_module(struct ov08x40 *ov08x)
if (val != OV08X40_CHIP_ID) {
dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
OV08X40_CHIP_ID, val);
- return -EIO;
+ return -ENXIO;
}
+ ov08x->identified = true;
+
return 0;
}
@@ -3035,7 +1982,8 @@ static int ov08x40_init_controls(struct ov08x40 *ov08x)
OV08X40_VTS_MAX - mode->height, 1,
vblank_def);
- hblank = ov08x->cur_mode->hts;
+ hblank = ov08x->cur_mode->llp - ov08x->cur_mode->width;
+
ov08x->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov08x40_ctrl_ops,
V4L2_CID_HBLANK,
hblank, hblank, 1, hblank);
@@ -3175,6 +2123,7 @@ static int ov08x40_probe(struct i2c_client *client)
{
struct ov08x40 *ov08x;
int ret;
+ bool full_power;
/* Check HW config */
ret = ov08x40_check_hwcfg(&client->dev);
@@ -3190,11 +2139,14 @@ static int ov08x40_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov08x->sd, client, &ov08x40_subdev_ops);
- /* Check module identity */
- ret = ov08x40_identify_module(ov08x);
- if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d\n", ret);
- return ret;
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ /* Check module identity */
+ ret = ov08x40_identify_module(ov08x);
+ if (ret) {
+ dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+ return ret;
+ }
}
/* Set default mode to max resolution */
@@ -3222,11 +2174,8 @@ static int ov08x40_probe(struct i2c_client *client)
if (ret < 0)
goto error_media_entity;
- /*
- * Device is already turned on by i2c-core with ACPI domain PM.
- * Enable runtime PM and turn off the device.
- */
- pm_runtime_set_active(&client->dev);
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -3270,11 +2219,13 @@ static struct i2c_driver ov08x40_i2c_driver = {
},
.probe = ov08x40_probe,
.remove = ov08x40_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(ov08x40_i2c_driver);
MODULE_AUTHOR("Jason Chen <jason.z.chen@intel.com>");
+MODULE_AUTHOR("Qingwu Zhang <qingwu.zhang@intel.com>");
MODULE_AUTHOR("Shawn Tu");
MODULE_DESCRIPTION("OmniVision OV08X40 sensor driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 1d0ef72a6403..d1653d7431d0 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
- endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+ endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!endpoint)
return NULL;
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index a26ac11c989d..3b22b9e12787 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -118,7 +118,6 @@ static inline struct ov5645 *to_ov5645(struct v4l2_subdev *sd)
static const struct reg_value ov5645_global_init_setting[] = {
{ 0x3103, 0x11 },
- { 0x3008, 0x82 },
{ 0x3008, 0x42 },
{ 0x3103, 0x03 },
{ 0x3503, 0x07 },
@@ -627,6 +626,10 @@ static int ov5645_set_register_array(struct ov5645 *ov5645,
ret = ov5645_write_reg(ov5645, settings->reg, settings->val);
if (ret < 0)
return ret;
+
+ if (settings->reg == OV5645_SYSTEM_CTRL0 &&
+ settings->val == OV5645_SYSTEM_CTRL0_START)
+ usleep_range(1000, 2000);
}
return 0;
@@ -1056,7 +1059,7 @@ static int ov5645_probe(struct i2c_client *client)
ov5645->i2c_client = client;
ov5645->dev = dev;
- endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
if (!endpoint) {
dev_err(dev, "endpoint node not found\n");
return -EINVAL;
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 96c0fd4ff5ab..7e1ecdf2485f 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1363,7 +1363,7 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
struct device_node *ep;
int ret;
- ep = of_graph_get_next_endpoint(np, NULL);
+ ep = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!ep)
return -EINVAL;
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index af8d01f78c32..cf6be509af33 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1568,7 +1568,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
"failed to request gpio S5C73M3_RST\n");
gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
- node_ep = of_graph_get_next_endpoint(node, NULL);
+ node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
if (!node_ep) {
dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
return 0;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index de079d2c9282..6b11039c3579 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1849,7 +1849,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
state->mclk_frequency);
}
- node_ep = of_graph_get_next_endpoint(node, NULL);
+ node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
if (!node_ep) {
dev_err(dev, "no endpoint defined at node %pOF\n", node);
return -EINVAL;
diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c
index e4d37a197724..b9e7c57027b1 100644
--- a/drivers/media/i2c/st-vgxy61.c
+++ b/drivers/media/i2c/st-vgxy61.c
@@ -12,6 +12,7 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/units.h>
@@ -19,79 +20,74 @@
#include <media/mipi-csi2.h>
#include <media/v4l2-async.h>
+#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
-#define VGXY61_REG_8BIT(n) ((1 << 16) | (n))
-#define VGXY61_REG_16BIT(n) ((2 << 16) | (n))
-#define VGXY61_REG_32BIT(n) ((4 << 16) | (n))
-#define VGXY61_REG_SIZE_SHIFT 16
-#define VGXY61_REG_ADDR_MASK 0xffff
-
-#define VGXY61_REG_MODEL_ID VGXY61_REG_16BIT(0x0000)
+#define VGXY61_REG_MODEL_ID CCI_REG16_LE(0x0000)
#define VG5661_MODEL_ID 0x5661
#define VG5761_MODEL_ID 0x5761
-#define VGXY61_REG_REVISION VGXY61_REG_16BIT(0x0002)
-#define VGXY61_REG_FWPATCH_REVISION VGXY61_REG_16BIT(0x0014)
-#define VGXY61_REG_FWPATCH_START_ADDR VGXY61_REG_8BIT(0x2000)
-#define VGXY61_REG_SYSTEM_FSM VGXY61_REG_8BIT(0x0020)
+#define VGXY61_REG_REVISION CCI_REG16_LE(0x0002)
+#define VGXY61_REG_FWPATCH_REVISION CCI_REG16_LE(0x0014)
+#define VGXY61_REG_FWPATCH_START_ADDR CCI_REG8(0x2000)
+#define VGXY61_REG_SYSTEM_FSM CCI_REG8(0x0020)
#define VGXY61_SYSTEM_FSM_SW_STBY 0x03
#define VGXY61_SYSTEM_FSM_STREAMING 0x04
-#define VGXY61_REG_NVM VGXY61_REG_8BIT(0x0023)
+#define VGXY61_REG_NVM CCI_REG8(0x0023)
#define VGXY61_NVM_OK 0x04
-#define VGXY61_REG_STBY VGXY61_REG_8BIT(0x0201)
+#define VGXY61_REG_STBY CCI_REG8(0x0201)
#define VGXY61_STBY_NO_REQ 0
#define VGXY61_STBY_REQ_TMP_READ BIT(2)
-#define VGXY61_REG_STREAMING VGXY61_REG_8BIT(0x0202)
+#define VGXY61_REG_STREAMING CCI_REG8(0x0202)
#define VGXY61_STREAMING_NO_REQ 0
#define VGXY61_STREAMING_REQ_STOP BIT(0)
#define VGXY61_STREAMING_REQ_START BIT(1)
-#define VGXY61_REG_EXT_CLOCK VGXY61_REG_32BIT(0x0220)
-#define VGXY61_REG_CLK_PLL_PREDIV VGXY61_REG_8BIT(0x0224)
-#define VGXY61_REG_CLK_SYS_PLL_MULT VGXY61_REG_8BIT(0x0225)
-#define VGXY61_REG_GPIO_0_CTRL VGXY61_REG_8BIT(0x0236)
-#define VGXY61_REG_GPIO_1_CTRL VGXY61_REG_8BIT(0x0237)
-#define VGXY61_REG_GPIO_2_CTRL VGXY61_REG_8BIT(0x0238)
-#define VGXY61_REG_GPIO_3_CTRL VGXY61_REG_8BIT(0x0239)
-#define VGXY61_REG_SIGNALS_POLARITY_CTRL VGXY61_REG_8BIT(0x023b)
-#define VGXY61_REG_LINE_LENGTH VGXY61_REG_16BIT(0x0300)
-#define VGXY61_REG_ORIENTATION VGXY61_REG_8BIT(0x0302)
-#define VGXY61_REG_VT_CTRL VGXY61_REG_8BIT(0x0304)
-#define VGXY61_REG_FORMAT_CTRL VGXY61_REG_8BIT(0x0305)
-#define VGXY61_REG_OIF_CTRL VGXY61_REG_16BIT(0x0306)
-#define VGXY61_REG_OIF_ROI0_CTRL VGXY61_REG_8BIT(0x030a)
-#define VGXY61_REG_ROI0_START_H VGXY61_REG_16BIT(0x0400)
-#define VGXY61_REG_ROI0_START_V VGXY61_REG_16BIT(0x0402)
-#define VGXY61_REG_ROI0_END_H VGXY61_REG_16BIT(0x0404)
-#define VGXY61_REG_ROI0_END_V VGXY61_REG_16BIT(0x0406)
-#define VGXY61_REG_PATGEN_CTRL VGXY61_REG_32BIT(0x0440)
+#define VGXY61_REG_EXT_CLOCK CCI_REG32_LE(0x0220)
+#define VGXY61_REG_CLK_PLL_PREDIV CCI_REG8(0x0224)
+#define VGXY61_REG_CLK_SYS_PLL_MULT CCI_REG8(0x0225)
+#define VGXY61_REG_GPIO_0_CTRL CCI_REG8(0x0236)
+#define VGXY61_REG_GPIO_1_CTRL CCI_REG8(0x0237)
+#define VGXY61_REG_GPIO_2_CTRL CCI_REG8(0x0238)
+#define VGXY61_REG_GPIO_3_CTRL CCI_REG8(0x0239)
+#define VGXY61_REG_SIGNALS_POLARITY_CTRL CCI_REG8(0x023b)
+#define VGXY61_REG_LINE_LENGTH CCI_REG16_LE(0x0300)
+#define VGXY61_REG_ORIENTATION CCI_REG8(0x0302)
+#define VGXY61_REG_VT_CTRL CCI_REG8(0x0304)
+#define VGXY61_REG_FORMAT_CTRL CCI_REG8(0x0305)
+#define VGXY61_REG_OIF_CTRL CCI_REG16_LE(0x0306)
+#define VGXY61_REG_OIF_ROI0_CTRL CCI_REG8(0x030a)
+#define VGXY61_REG_ROI0_START_H CCI_REG16_LE(0x0400)
+#define VGXY61_REG_ROI0_START_V CCI_REG16_LE(0x0402)
+#define VGXY61_REG_ROI0_END_H CCI_REG16_LE(0x0404)
+#define VGXY61_REG_ROI0_END_V CCI_REG16_LE(0x0406)
+#define VGXY61_REG_PATGEN_CTRL CCI_REG32_LE(0x0440)
#define VGXY61_PATGEN_LONG_ENABLE BIT(16)
#define VGXY61_PATGEN_SHORT_ENABLE BIT(0)
#define VGXY61_PATGEN_LONG_TYPE_SHIFT 18
#define VGXY61_PATGEN_SHORT_TYPE_SHIFT 4
-#define VGXY61_REG_FRAME_CONTENT_CTRL VGXY61_REG_8BIT(0x0478)
-#define VGXY61_REG_COARSE_EXPOSURE_LONG VGXY61_REG_16BIT(0x0500)
-#define VGXY61_REG_COARSE_EXPOSURE_SHORT VGXY61_REG_16BIT(0x0504)
-#define VGXY61_REG_ANALOG_GAIN VGXY61_REG_8BIT(0x0508)
-#define VGXY61_REG_DIGITAL_GAIN_LONG VGXY61_REG_16BIT(0x050a)
-#define VGXY61_REG_DIGITAL_GAIN_SHORT VGXY61_REG_16BIT(0x0512)
-#define VGXY61_REG_FRAME_LENGTH VGXY61_REG_16BIT(0x051a)
-#define VGXY61_REG_SIGNALS_CTRL VGXY61_REG_16BIT(0x0522)
+#define VGXY61_REG_FRAME_CONTENT_CTRL CCI_REG8(0x0478)
+#define VGXY61_REG_COARSE_EXPOSURE_LONG CCI_REG16_LE(0x0500)
+#define VGXY61_REG_COARSE_EXPOSURE_SHORT CCI_REG16_LE(0x0504)
+#define VGXY61_REG_ANALOG_GAIN CCI_REG8(0x0508)
+#define VGXY61_REG_DIGITAL_GAIN_LONG CCI_REG16_LE(0x050a)
+#define VGXY61_REG_DIGITAL_GAIN_SHORT CCI_REG16_LE(0x0512)
+#define VGXY61_REG_FRAME_LENGTH CCI_REG16_LE(0x051a)
+#define VGXY61_REG_SIGNALS_CTRL CCI_REG16_LE(0x0522)
#define VGXY61_SIGNALS_GPIO_ID_SHIFT 4
-#define VGXY61_REG_READOUT_CTRL VGXY61_REG_8BIT(0x0530)
-#define VGXY61_REG_HDR_CTRL VGXY61_REG_8BIT(0x0532)
-#define VGXY61_REG_PATGEN_LONG_DATA_GR VGXY61_REG_16BIT(0x092c)
-#define VGXY61_REG_PATGEN_LONG_DATA_R VGXY61_REG_16BIT(0x092e)
-#define VGXY61_REG_PATGEN_LONG_DATA_B VGXY61_REG_16BIT(0x0930)
-#define VGXY61_REG_PATGEN_LONG_DATA_GB VGXY61_REG_16BIT(0x0932)
-#define VGXY61_REG_PATGEN_SHORT_DATA_GR VGXY61_REG_16BIT(0x0950)
-#define VGXY61_REG_PATGEN_SHORT_DATA_R VGXY61_REG_16BIT(0x0952)
-#define VGXY61_REG_PATGEN_SHORT_DATA_B VGXY61_REG_16BIT(0x0954)
-#define VGXY61_REG_PATGEN_SHORT_DATA_GB VGXY61_REG_16BIT(0x0956)
-#define VGXY61_REG_BYPASS_CTRL VGXY61_REG_8BIT(0x0a60)
+#define VGXY61_REG_READOUT_CTRL CCI_REG8(0x0530)
+#define VGXY61_REG_HDR_CTRL CCI_REG8(0x0532)
+#define VGXY61_REG_PATGEN_LONG_DATA_GR CCI_REG16_LE(0x092c)
+#define VGXY61_REG_PATGEN_LONG_DATA_R CCI_REG16_LE(0x092e)
+#define VGXY61_REG_PATGEN_LONG_DATA_B CCI_REG16_LE(0x0930)
+#define VGXY61_REG_PATGEN_LONG_DATA_GB CCI_REG16_LE(0x0932)
+#define VGXY61_REG_PATGEN_SHORT_DATA_GR CCI_REG16_LE(0x0950)
+#define VGXY61_REG_PATGEN_SHORT_DATA_R CCI_REG16_LE(0x0952)
+#define VGXY61_REG_PATGEN_SHORT_DATA_B CCI_REG16_LE(0x0954)
+#define VGXY61_REG_PATGEN_SHORT_DATA_GB CCI_REG16_LE(0x0956)
+#define VGXY61_REG_BYPASS_CTRL CCI_REG8(0x0a60)
#define VGX661_WIDTH 1464
#define VGX661_HEIGHT 1104
@@ -384,6 +380,7 @@ static const struct vgxy61_mode_info vgx761_mode_data[] = {
struct vgxy61_dev {
struct i2c_client *i2c_client;
+ struct regmap *regmap;
struct v4l2_subdev sd;
struct media_pad pad;
struct regulator_bulk_data supplies[ARRAY_SIZE(vgxy61_supply_name)];
@@ -510,82 +507,6 @@ static unsigned int get_chunk_size(struct vgxy61_dev *sensor)
return max(max_write_len, 1);
}
-static int vgxy61_read_multiple(struct vgxy61_dev *sensor, u32 reg,
- unsigned int len)
-{
- struct i2c_client *client = sensor->i2c_client;
- struct i2c_msg msg[2];
- u8 buf[2];
- u8 val[sizeof(u32)] = {0};
- int ret;
-
- if (len > sizeof(u32))
- return -EINVAL;
- buf[0] = reg >> 8;
- buf[1] = reg & 0xff;
-
- msg[0].addr = client->addr;
- msg[0].flags = client->flags;
- msg[0].buf = buf;
- msg[0].len = sizeof(buf);
-
- msg[1].addr = client->addr;
- msg[1].flags = client->flags | I2C_M_RD;
- msg[1].buf = val;
- msg[1].len = len;
-
- ret = i2c_transfer(client->adapter, msg, 2);
- if (ret < 0) {
- dev_dbg(&client->dev, "%s: %x i2c_transfer, reg: %x => %d\n",
- __func__, client->addr, reg, ret);
- return ret;
- }
-
- return get_unaligned_le32(val);
-}
-
-static inline int vgxy61_read_reg(struct vgxy61_dev *sensor, u32 reg)
-{
- return vgxy61_read_multiple(sensor, reg & VGXY61_REG_ADDR_MASK,
- (reg >> VGXY61_REG_SIZE_SHIFT) & 7);
-}
-
-static int vgxy61_write_multiple(struct vgxy61_dev *sensor, u32 reg,
- const u8 *data, unsigned int len, int *err)
-{
- struct i2c_client *client = sensor->i2c_client;
- struct i2c_msg msg;
- u8 buf[VGXY61_WRITE_MULTIPLE_CHUNK_MAX + 2];
- unsigned int i;
- int ret;
-
- if (err && *err)
- return *err;
-
- if (len > VGXY61_WRITE_MULTIPLE_CHUNK_MAX)
- return -EINVAL;
- buf[0] = reg >> 8;
- buf[1] = reg & 0xff;
- for (i = 0; i < len; i++)
- buf[i + 2] = data[i];
-
- msg.addr = client->addr;
- msg.flags = client->flags;
- msg.buf = buf;
- msg.len = len + 2;
-
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret < 0) {
- dev_dbg(&client->dev, "%s: i2c_transfer, reg: %x => %d\n",
- __func__, reg, ret);
- if (err)
- *err = ret;
- return ret;
- }
-
- return 0;
-}
-
static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg,
unsigned int nb, const u8 *array)
{
@@ -595,7 +516,8 @@ static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg,
while (nb) {
sz = min(nb, chunk_size);
- ret = vgxy61_write_multiple(sensor, reg, array, sz, NULL);
+ ret = regmap_bulk_write(sensor->regmap, CCI_REG_ADDR(reg),
+ array, sz);
if (ret < 0)
return ret;
nb -= sz;
@@ -606,24 +528,17 @@ static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg,
return 0;
}
-static inline int vgxy61_write_reg(struct vgxy61_dev *sensor, u32 reg, u32 val,
- int *err)
-{
- return vgxy61_write_multiple(sensor, reg & VGXY61_REG_ADDR_MASK,
- (u8 *)&val,
- (reg >> VGXY61_REG_SIZE_SHIFT) & 7, err);
-}
-
static int vgxy61_poll_reg(struct vgxy61_dev *sensor, u32 reg, u8 poll_val,
unsigned int timeout_ms)
{
const unsigned int loop_delay_ms = 10;
+ u64 val;
int ret;
- return read_poll_timeout(vgxy61_read_reg, ret,
- ((ret < 0) || (ret == poll_val)),
+ return read_poll_timeout(cci_read, ret,
+ ((ret < 0) || (val == poll_val)),
loop_delay_ms * 1000, timeout_ms * 1000,
- false, sensor, reg);
+ false, sensor->regmap, reg, &val, NULL);
}
static int vgxy61_wait_state(struct vgxy61_dev *sensor, int state,
@@ -662,11 +577,11 @@ static int vgxy61_apply_exposure(struct vgxy61_dev *sensor)
int ret = 0;
/* We first set expo to zero to avoid forbidden parameters couple */
- vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_SHORT, 0, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_LONG,
- sensor->expo_long, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_SHORT,
- sensor->expo_short, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_SHORT, 0, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_LONG,
+ sensor->expo_long, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_SHORT,
+ sensor->expo_short, &ret);
return ret;
}
@@ -714,7 +629,7 @@ static int vgxy61_try_fmt_internal(struct v4l2_subdev *sd,
const struct vgxy61_mode_info **new_mode)
{
struct vgxy61_dev *sensor = to_vgxy61_dev(sd);
- const struct vgxy61_mode_info *mode = sensor->sensor_modes;
+ const struct vgxy61_mode_info *mode;
unsigned int index;
for (index = 0; index < ARRAY_SIZE(vgxy61_supported_codes); index++) {
@@ -827,8 +742,8 @@ static int vgxy61_update_analog_gain(struct vgxy61_dev *sensor, u32 target)
sensor->analog_gain = target;
if (sensor->streaming)
- return vgxy61_write_reg(sensor, VGXY61_REG_ANALOG_GAIN, target,
- NULL);
+ return cci_write(sensor->regmap, VGXY61_REG_ANALOG_GAIN, target,
+ NULL);
return 0;
}
@@ -842,10 +757,10 @@ static int vgxy61_apply_digital_gain(struct vgxy61_dev *sensor,
* DIGITAL_GAIN_SHORT_CH0 is enough to configure the gain of all
* four sub pixels.
*/
- vgxy61_write_reg(sensor, VGXY61_REG_DIGITAL_GAIN_LONG, digital_gain,
- &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_DIGITAL_GAIN_SHORT, digital_gain,
- &ret);
+ cci_write(sensor->regmap, VGXY61_REG_DIGITAL_GAIN_LONG, digital_gain,
+ &ret);
+ cci_write(sensor->regmap, VGXY61_REG_DIGITAL_GAIN_SHORT, digital_gain,
+ &ret);
return ret;
}
@@ -870,7 +785,7 @@ static int vgxy61_apply_patgen(struct vgxy61_dev *sensor, u32 index)
if (pattern)
reg |= VGXY61_PATGEN_LONG_ENABLE | VGXY61_PATGEN_SHORT_ENABLE;
- return vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_CTRL, reg, NULL);
+ return cci_write(sensor->regmap, VGXY61_REG_PATGEN_CTRL, reg, NULL);
}
static int vgxy61_update_patgen(struct vgxy61_dev *sensor, u32 pattern)
@@ -887,15 +802,13 @@ static int vgxy61_apply_gpiox_strobe_mode(struct vgxy61_dev *sensor,
unsigned int idx)
{
static const u8 index2val[] = {0x0, 0x1, 0x3};
- int reg;
+ u16 mask, val;
- reg = vgxy61_read_reg(sensor, VGXY61_REG_SIGNALS_CTRL);
- if (reg < 0)
- return reg;
- reg &= ~(0xf << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT));
- reg |= index2val[mode] << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT);
+ mask = 0xf << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT);
+ val = index2val[mode] << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT);
- return vgxy61_write_reg(sensor, VGXY61_REG_SIGNALS_CTRL, reg, NULL);
+ return cci_update_bits(sensor->regmap, VGXY61_REG_SIGNALS_CTRL,
+ mask, val, NULL);
}
static int vgxy61_update_gpios_strobe_mode(struct vgxy61_dev *sensor,
@@ -940,12 +853,12 @@ static int vgxy61_update_gpios_strobe_polarity(struct vgxy61_dev *sensor,
if (sensor->streaming)
return -EBUSY;
- vgxy61_write_reg(sensor, VGXY61_REG_GPIO_0_CTRL, polarity << 1, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_GPIO_1_CTRL, polarity << 1, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_GPIO_2_CTRL, polarity << 1, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_GPIO_3_CTRL, polarity << 1, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_SIGNALS_POLARITY_CTRL, polarity,
- &ret);
+ cci_write(sensor->regmap, VGXY61_REG_GPIO_0_CTRL, polarity << 1, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_GPIO_1_CTRL, polarity << 1, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_GPIO_2_CTRL, polarity << 1, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_GPIO_3_CTRL, polarity << 1, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_SIGNALS_POLARITY_CTRL, polarity,
+ &ret);
return ret;
}
@@ -1057,8 +970,8 @@ static int vgxy61_update_exposure(struct vgxy61_dev *sensor, u16 new_expo_long,
static int vgxy61_apply_framelength(struct vgxy61_dev *sensor)
{
- return vgxy61_write_reg(sensor, VGXY61_REG_FRAME_LENGTH,
- sensor->frame_length, NULL);
+ return cci_write(sensor->regmap, VGXY61_REG_FRAME_LENGTH,
+ sensor->frame_length, NULL);
}
static int vgxy61_update_vblank(struct vgxy61_dev *sensor, u16 vblank,
@@ -1086,8 +999,8 @@ static int vgxy61_apply_hdr(struct vgxy61_dev *sensor,
{
static const u8 index2val[] = {0x1, 0x4, 0xa};
- return vgxy61_write_reg(sensor, VGXY61_REG_HDR_CTRL, index2val[index],
- NULL);
+ return cci_write(sensor->regmap, VGXY61_REG_HDR_CTRL, index2val[index],
+ NULL);
}
static int vgxy61_update_hdr(struct vgxy61_dev *sensor,
@@ -1133,16 +1046,16 @@ static int vgxy61_apply_settings(struct vgxy61_dev *sensor)
if (ret)
return ret;
- ret = vgxy61_write_reg(sensor, VGXY61_REG_ANALOG_GAIN,
- sensor->analog_gain, NULL);
+ ret = cci_write(sensor->regmap, VGXY61_REG_ANALOG_GAIN,
+ sensor->analog_gain, NULL);
if (ret)
return ret;
ret = vgxy61_apply_digital_gain(sensor, sensor->digital_gain);
if (ret)
return ret;
- ret = vgxy61_write_reg(sensor, VGXY61_REG_ORIENTATION,
- sensor->hflip | (sensor->vflip << 1), NULL);
+ ret = cci_write(sensor->regmap, VGXY61_REG_ORIENTATION,
+ sensor->hflip | (sensor->vflip << 1), NULL);
if (ret)
return ret;
@@ -1174,19 +1087,19 @@ static int vgxy61_stream_enable(struct vgxy61_dev *sensor)
if (ret)
return ret;
- vgxy61_write_reg(sensor, VGXY61_REG_FORMAT_CTRL,
- get_bpp_by_code(sensor->fmt.code), &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_OIF_ROI0_CTRL,
- get_data_type_by_code(sensor->fmt.code), &ret);
-
- vgxy61_write_reg(sensor, VGXY61_REG_READOUT_CTRL,
- sensor->current_mode->bin_mode, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_ROI0_START_H, crop->left, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_ROI0_END_H,
- crop->left + crop->width - 1, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_ROI0_START_V, crop->top, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_ROI0_END_V,
- crop->top + crop->height - 1, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_FORMAT_CTRL,
+ get_bpp_by_code(sensor->fmt.code), &ret);
+ cci_write(sensor->regmap, VGXY61_REG_OIF_ROI0_CTRL,
+ get_data_type_by_code(sensor->fmt.code), &ret);
+
+ cci_write(sensor->regmap, VGXY61_REG_READOUT_CTRL,
+ sensor->current_mode->bin_mode, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_ROI0_START_H, crop->left, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_ROI0_END_H,
+ crop->left + crop->width - 1, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_ROI0_START_V, crop->top, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_ROI0_END_V,
+ crop->top + crop->height - 1, &ret);
if (ret)
goto err_rpm_put;
@@ -1194,8 +1107,8 @@ static int vgxy61_stream_enable(struct vgxy61_dev *sensor)
if (ret)
goto err_rpm_put;
- ret = vgxy61_write_reg(sensor, VGXY61_REG_STREAMING,
- VGXY61_STREAMING_REQ_START, NULL);
+ ret = cci_write(sensor->regmap, VGXY61_REG_STREAMING,
+ VGXY61_STREAMING_REQ_START, NULL);
if (ret)
goto err_rpm_put;
@@ -1225,8 +1138,8 @@ static int vgxy61_stream_disable(struct vgxy61_dev *sensor)
struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
int ret;
- ret = vgxy61_write_reg(sensor, VGXY61_REG_STREAMING,
- VGXY61_STREAMING_REQ_STOP, NULL);
+ ret = cci_write(sensor->regmap, VGXY61_REG_STREAMING,
+ VGXY61_STREAMING_REQ_STOP, NULL);
if (ret)
goto err_str_dis;
@@ -1582,7 +1495,7 @@ static int vgxy61_configure(struct vgxy61_dev *sensor)
{
u32 sensor_freq;
u8 prediv, mult;
- int line_length;
+ u64 line_length;
int ret = 0;
compute_pll_parameters_by_freq(sensor->clk_freq, &prediv, &mult);
@@ -1592,28 +1505,28 @@ static int vgxy61_configure(struct vgxy61_dev *sensor)
/* Video timing ISP path (pixel clock) requires 804/5 mhz = 160 mhz */
sensor->pclk = sensor_freq / 5;
- line_length = vgxy61_read_reg(sensor, VGXY61_REG_LINE_LENGTH);
- if (line_length < 0)
- return line_length;
- sensor->line_length = line_length;
- vgxy61_write_reg(sensor, VGXY61_REG_EXT_CLOCK, sensor->clk_freq, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_CLK_PLL_PREDIV, prediv, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_CLK_SYS_PLL_MULT, mult, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_OIF_CTRL, sensor->oif_ctrl, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_FRAME_CONTENT_CTRL, 0, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_BYPASS_CTRL, 4, &ret);
+ cci_read(sensor->regmap, VGXY61_REG_LINE_LENGTH, &line_length, &ret);
+ if (ret < 0)
+ return ret;
+ sensor->line_length = (u16)line_length;
+ cci_write(sensor->regmap, VGXY61_REG_EXT_CLOCK, sensor->clk_freq, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_CLK_PLL_PREDIV, prediv, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_CLK_SYS_PLL_MULT, mult, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_OIF_CTRL, sensor->oif_ctrl, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_FRAME_CONTENT_CTRL, 0, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_BYPASS_CTRL, 4, &ret);
if (ret)
return ret;
vgxy61_update_gpios_strobe_polarity(sensor, sensor->gpios_polarity);
/* Set pattern generator solid to middle value */
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_GR, 0x800, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_R, 0x800, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_B, 0x800, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_GB, 0x800, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_GR, 0x800, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_R, 0x800, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_B, 0x800, &ret);
- vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_GB, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_GR, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_R, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_B, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_GB, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_GR, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_R, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_B, 0x800, &ret);
+ cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_GB, 0x800, &ret);
if (ret)
return ret;
@@ -1623,37 +1536,33 @@ static int vgxy61_configure(struct vgxy61_dev *sensor)
static int vgxy61_patch(struct vgxy61_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
- int patch, ret;
+ u64 patch;
+ int ret;
ret = vgxy61_write_array(sensor, VGXY61_REG_FWPATCH_START_ADDR,
sizeof(patch_array), patch_array);
- if (ret)
- return ret;
-
- ret = vgxy61_write_reg(sensor, VGXY61_REG_STBY, 0x10, NULL);
+ cci_write(sensor->regmap, VGXY61_REG_STBY, 0x10, &ret);
if (ret)
return ret;
ret = vgxy61_poll_reg(sensor, VGXY61_REG_STBY, 0, VGXY61_TIMEOUT_MS);
- if (ret)
+ cci_read(sensor->regmap, VGXY61_REG_FWPATCH_REVISION, &patch, &ret);
+ if (ret < 0)
return ret;
- patch = vgxy61_read_reg(sensor, VGXY61_REG_FWPATCH_REVISION);
- if (patch < 0)
- return patch;
-
if (patch != (VGXY61_FWPATCH_REVISION_MAJOR << 12) +
(VGXY61_FWPATCH_REVISION_MINOR << 8) +
VGXY61_FWPATCH_REVISION_MICRO) {
- dev_err(&client->dev, "bad patch version expected %d.%d.%d got %d.%d.%d\n",
+ dev_err(&client->dev,
+ "bad patch version expected %d.%d.%d got %u.%u.%u\n",
VGXY61_FWPATCH_REVISION_MAJOR,
VGXY61_FWPATCH_REVISION_MINOR,
VGXY61_FWPATCH_REVISION_MICRO,
- patch >> 12, (patch >> 8) & 0x0f, patch & 0xff);
+ (u16)patch >> 12, ((u16)patch >> 8) & 0x0f, (u16)patch & 0xff);
return -ENODEV;
}
- dev_dbg(&client->dev, "patch %d.%d.%d applied\n",
- patch >> 12, (patch >> 8) & 0x0f, patch & 0xff);
+ dev_dbg(&client->dev, "patch %u.%u.%u applied\n",
+ (u16)patch >> 12, ((u16)patch >> 8) & 0x0f, (u16)patch & 0xff);
return 0;
}
@@ -1661,11 +1570,12 @@ static int vgxy61_patch(struct vgxy61_dev *sensor)
static int vgxy61_detect_cut_version(struct vgxy61_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
- int device_rev;
+ u64 device_rev;
+ int ret;
- device_rev = vgxy61_read_reg(sensor, VGXY61_REG_REVISION);
- if (device_rev < 0)
- return device_rev;
+ ret = cci_read(sensor->regmap, VGXY61_REG_REVISION, &device_rev, NULL);
+ if (ret < 0)
+ return ret;
switch (device_rev >> 8) {
case 0xA:
@@ -1687,17 +1597,17 @@ static int vgxy61_detect_cut_version(struct vgxy61_dev *sensor)
static int vgxy61_detect(struct vgxy61_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
- int id = 0;
- int ret, st;
+ u64 st, id = 0;
+ int ret;
- id = vgxy61_read_reg(sensor, VGXY61_REG_MODEL_ID);
- if (id < 0)
- return id;
+ ret = cci_read(sensor->regmap, VGXY61_REG_MODEL_ID, &id, NULL);
+ if (ret < 0)
+ return ret;
if (id != VG5661_MODEL_ID && id != VG5761_MODEL_ID) {
- dev_warn(&client->dev, "Unsupported sensor id %x\n", id);
+ dev_warn(&client->dev, "Unsupported sensor id %x\n", (u16)id);
return -ENODEV;
}
- dev_dbg(&client->dev, "detected sensor id = 0x%04x\n", id);
+ dev_dbg(&client->dev, "detected sensor id = 0x%04x\n", (u16)id);
sensor->id = id;
ret = vgxy61_wait_state(sensor, VGXY61_SYSTEM_FSM_SW_STBY,
@@ -1705,11 +1615,11 @@ static int vgxy61_detect(struct vgxy61_dev *sensor)
if (ret)
return ret;
- st = vgxy61_read_reg(sensor, VGXY61_REG_NVM);
- if (st < 0)
+ ret = cci_read(sensor->regmap, VGXY61_REG_NVM, &st, NULL);
+ if (ret < 0)
return st;
if (st != VGXY61_NVM_OK)
- dev_warn(&client->dev, "Bad nvm state got %d\n", st);
+ dev_warn(&client->dev, "Bad nvm state got %u\n", (u8)st);
ret = vgxy61_detect_cut_version(sensor);
if (ret)
@@ -1832,6 +1742,12 @@ static int vgxy61_probe(struct i2c_client *client)
sensor->analog_gain = 0;
sensor->digital_gain = 256;
+ sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(sensor->regmap)) {
+ ret = PTR_ERR(sensor->regmap);
+ return dev_err_probe(dev, ret, "Failed to init regmap\n");
+ }
+
handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
if (!handle) {
dev_err(dev, "handle node not found\n");
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 558152575d10..3192a334aaab 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1895,7 +1895,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
return dev_err_probe(dev, PTR_ERR(refclk),
"failed to get refclk\n");
- ep = of_graph_get_next_endpoint(dev->of_node, NULL);
+ ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
if (!ep) {
dev_err(dev, "missing endpoint node\n");
return -EINVAL;
diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c
index 106de4271d2e..d676adc4401b 100644
--- a/drivers/media/i2c/tc358746.c
+++ b/drivers/media/i2c/tc358746.c
@@ -843,14 +843,14 @@ static unsigned long tc358746_find_pll_settings(struct tc358746 *tc358746,
if (fin < 4 * HZ_PER_MHZ || fin > 40 * HZ_PER_MHZ)
continue;
- tmp = fout * p * postdiv;
+ tmp = fout * postdiv;
do_div(tmp, fin);
mul = tmp;
if (mul > 511)
continue;
tmp = mul * fin;
- do_div(tmp, p * postdiv);
+ do_div(tmp, postdiv);
delta = abs(fout - tmp);
if (delta < min_delta) {
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 1ea703a9909f..8e4a0718c4b6 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -2310,7 +2310,7 @@ static int tda1997x_parse_dt(struct tda1997x_state *state)
pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF;
np = state->client->dev.of_node;
- ep = of_graph_get_next_endpoint(np, NULL);
+ ep = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!ep)
return -EINVAL;
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index 5a561e5bf659..f9c9c80c33ac 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -987,7 +987,7 @@ tvp514x_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
- endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+ endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!endpoint)
return NULL;
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 9fc586cfdcd8..64b91aa3c82a 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -1817,7 +1817,7 @@ static struct regmap_config tvp5150_config = {
.val_bits = 8,
.max_register = 0xff,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.rd_table = &tvp5150_readable_table,
.volatile_reg = tvp5150_volatile_reg,
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 30831b4b56d6..6a04ffae5343 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -893,7 +893,7 @@ tvp7002_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
- endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
+ endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!endpoint)
return NULL;
diff --git a/drivers/media/mc/mc-devnode.c b/drivers/media/mc/mc-devnode.c
index 680fbb3a9340..7f67825c8757 100644
--- a/drivers/media/mc/mc-devnode.c
+++ b/drivers/media/mc/mc-devnode.c
@@ -63,7 +63,7 @@ static void media_devnode_release(struct device *cd)
pr_debug("%s: Media Devnode Deallocated\n", __func__);
}
-static struct bus_type media_bus_type = {
+static const struct bus_type media_bus_type = {
.name = MEDIA_NAME,
};
@@ -190,7 +190,6 @@ static int media_release(struct inode *inode, struct file *filp)
return value is ignored. */
put_device(&devnode->dev);
- pr_debug("%s: Media Release\n", __func__);
return 0;
}
diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c
index 543a392f8635..0e28b9a7936e 100644
--- a/drivers/media/mc/mc-entity.c
+++ b/drivers/media/mc/mc-entity.c
@@ -535,14 +535,15 @@ static int media_pipeline_walk_push(struct media_pipeline_walk *walk,
/*
* Move the top entry link cursor to the next link. If all links of the entry
- * have been visited, pop the entry itself.
+ * have been visited, pop the entry itself. Return true if the entry has been
+ * popped.
*/
-static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
+static bool media_pipeline_walk_pop(struct media_pipeline_walk *walk)
{
struct media_pipeline_walk_entry *entry;
if (WARN_ON(walk->stack.top < 0))
- return;
+ return false;
entry = media_pipeline_walk_top(walk);
@@ -552,7 +553,7 @@ static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
walk->stack.top);
walk->stack.top--;
- return;
+ return true;
}
entry->links = entry->links->next;
@@ -560,6 +561,8 @@ static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
dev_dbg(walk->mdev->dev,
"media pipeline: moved entry %u to next link\n",
walk->stack.top);
+
+ return false;
}
/* Free all memory allocated while walking the pipeline. */
@@ -605,30 +608,24 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
struct media_pipeline_walk *walk)
{
struct media_pipeline_walk_entry *entry = media_pipeline_walk_top(walk);
- struct media_pad *pad;
+ struct media_pad *origin;
struct media_link *link;
struct media_pad *local;
struct media_pad *remote;
+ bool last_link;
int ret;
- pad = entry->pad;
+ origin = entry->pad;
link = list_entry(entry->links, typeof(*link), list);
- media_pipeline_walk_pop(walk);
+ last_link = media_pipeline_walk_pop(walk);
dev_dbg(walk->mdev->dev,
"media pipeline: exploring link '%s':%u -> '%s':%u\n",
link->source->entity->name, link->source->index,
link->sink->entity->name, link->sink->index);
- /* Skip links that are not enabled. */
- if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
- dev_dbg(walk->mdev->dev,
- "media pipeline: skipping link (disabled)\n");
- return 0;
- }
-
/* Get the local pad and remote pad. */
- if (link->source->entity == pad->entity) {
+ if (link->source->entity == origin->entity) {
local = link->source;
remote = link->sink;
} else {
@@ -640,25 +637,64 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
* Skip links that originate from a different pad than the incoming pad
* that is not connected internally in the entity to the incoming pad.
*/
- if (pad != local &&
- !media_entity_has_pad_interdep(pad->entity, pad->index, local->index)) {
+ if (origin != local &&
+ !media_entity_has_pad_interdep(origin->entity, origin->index,
+ local->index)) {
dev_dbg(walk->mdev->dev,
"media pipeline: skipping link (no route)\n");
- return 0;
+ goto done;
}
/*
- * Add the local and remote pads of the link to the pipeline and push
- * them to the stack, if they're not already present.
+ * Add the local pad of the link to the pipeline and push it to the
+ * stack, if not already present.
*/
ret = media_pipeline_add_pad(pipe, walk, local);
if (ret)
return ret;
+ /* Similarly, add the remote pad, but only if the link is enabled. */
+ if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
+ dev_dbg(walk->mdev->dev,
+ "media pipeline: skipping link (disabled)\n");
+ goto done;
+ }
+
ret = media_pipeline_add_pad(pipe, walk, remote);
if (ret)
return ret;
+done:
+ /*
+ * If we're done iterating over links, iterate over pads of the entity.
+ * This is necessary to discover pads that are not connected with any
+ * link. Those are dead ends from a pipeline exploration point of view,
+ * but are still part of the pipeline and need to be added to enable
+ * proper validation.
+ */
+ if (!last_link)
+ return 0;
+
+ dev_dbg(walk->mdev->dev,
+ "media pipeline: adding unconnected pads of '%s'\n",
+ local->entity->name);
+
+ media_entity_for_each_pad(origin->entity, local) {
+ /*
+ * Skip the origin pad (already handled), pad that have links
+ * (already discovered through iterating over links) and pads
+ * not internally connected.
+ */
+ if (origin == local || !local->num_links ||
+ !media_entity_has_pad_interdep(origin->entity, origin->index,
+ local->index))
+ continue;
+
+ ret = media_pipeline_add_pad(pipe, walk, local);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
@@ -770,7 +806,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
struct media_pad *pad = ppad->pad;
struct media_entity *entity = pad->entity;
bool has_enabled_link = false;
- bool has_link = false;
struct media_link *link;
dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name,
@@ -800,7 +835,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
/* Record if the pad has links and enabled links. */
if (link->flags & MEDIA_LNK_FL_ENABLED)
has_enabled_link = true;
- has_link = true;
/*
* Validate the link if it's enabled and has the
@@ -838,7 +872,7 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
* 3. If the pad has the MEDIA_PAD_FL_MUST_CONNECT flag set,
* ensure that it has either no link or an enabled link.
*/
- if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && has_link &&
+ if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) &&
!has_enabled_link) {
dev_dbg(mdev->dev,
"Pad '%s':%u must be connected by an enabled link\n",
@@ -1038,6 +1072,9 @@ static void __media_entity_remove_link(struct media_entity *entity,
/* Remove the reverse links for a data link. */
if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) {
+ link->source->num_links--;
+ link->sink->num_links--;
+
if (link->source->entity == entity)
remote = link->sink->entity;
else
@@ -1092,6 +1129,11 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
struct media_link *link;
struct media_link *backlink;
+ if (flags & MEDIA_LNK_FL_LINK_TYPE)
+ return -EINVAL;
+
+ flags |= MEDIA_LNK_FL_DATA_LINK;
+
if (WARN_ON(!source || !sink) ||
WARN_ON(source_pad >= source->num_pads) ||
WARN_ON(sink_pad >= sink->num_pads))
@@ -1107,7 +1149,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
link->source = &source->pads[source_pad];
link->sink = &sink->pads[sink_pad];
- link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK;
+ link->flags = flags;
/* Initialize graph object embedded at the new link */
media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
@@ -1138,6 +1180,9 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
sink->num_links++;
source->num_links++;
+ link->source->num_links++;
+ link->sink->num_links++;
+
return 0;
}
EXPORT_SYMBOL_GPL(media_create_pad_link);
diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c
index a2b18e2bed1b..6b7fea50328c 100644
--- a/drivers/media/pci/bt8xx/bttv-gpio.c
+++ b/drivers/media/pci/bt8xx/bttv-gpio.c
@@ -55,7 +55,7 @@ static void bttv_sub_remove(struct device *dev)
sub->remove(sdev);
}
-struct bus_type bttv_sub_bus_type = {
+const struct bus_type bttv_sub_bus_type = {
.name = "bttv-sub",
.match = &bttv_sub_bus_match,
.probe = bttv_sub_probe,
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index 0368a583cf07..a534e63b9a37 100644
--- a/drivers/media/pci/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -234,7 +234,7 @@ int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
/* ---------------------------------------------------------- */
/* bttv-gpio.c */
-extern struct bus_type bttv_sub_bus_type;
+extern const struct bus_type bttv_sub_bus_type;
int bttv_sub_add_device(struct bttv_core *core, char *name);
int bttv_sub_del_devices(struct bttv_core *core);
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 42fdcf992e48..7d4a409c433e 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1354,6 +1354,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* register Video device */
dev->video_dev = cx23885_vdev_init(dev, dev->pci,
&cx23885_video_template, "video");
+ if (!dev->video_dev) {
+ err = -ENOMEM;
+ goto fail_unreg;
+ }
dev->video_dev->queue = &dev->vb2_vidq;
dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE;
@@ -1382,6 +1386,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* register VBI device */
dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
&cx23885_vbi_template, "vbi");
+ if (!dev->vbi_dev) {
+ err = -ENOMEM;
+ goto fail_unreg;
+ }
dev->vbi_dev->queue = &dev->vb2_vbiq;
dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE;
diff --git a/drivers/media/pci/dt3155/dt3155.h b/drivers/media/pci/dt3155/dt3155.h
index c9ce79cb5566..ce1835d9691e 100644
--- a/drivers/media/pci/dt3155/dt3155.h
+++ b/drivers/media/pci/dt3155/dt3155.h
@@ -162,7 +162,6 @@
* @height: frame height
* @input: current input
* @sequence: frame counter
- * @stats: statistics structure
* @regs: local copy of mmio base register
* @csr2: local copy of csr2 register
* @config: local copy of config register
diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
index f980e3125a7b..e994db4f4d91 100644
--- a/drivers/media/pci/intel/ipu-bridge.c
+++ b/drivers/media/pci/intel/ipu-bridge.c
@@ -2,6 +2,7 @@
/* Author: Dan Scally <djrscally@gmail.com> */
#include <linux/acpi.h>
+#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/mei_cl_bus.h>
@@ -60,6 +61,8 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = {
IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
/* GalaxyCore GC0310 */
IPU_SENSOR_CONFIG("INT0310", 0),
+ /* Omnivision ov01a10 */
+ IPU_SENSOR_CONFIG("OVTI01A0", 1, 400000000),
};
static const struct ipu_property_names prop_names = {
@@ -747,6 +750,24 @@ static int ipu_bridge_ivsc_is_ready(void)
return ready;
}
+static int ipu_bridge_check_fwnode_graph(struct fwnode_handle *fwnode)
+{
+ struct fwnode_handle *endpoint;
+
+ if (IS_ERR_OR_NULL(fwnode))
+ return -EINVAL;
+
+ endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
+ if (endpoint) {
+ fwnode_handle_put(endpoint);
+ return 0;
+ }
+
+ return ipu_bridge_check_fwnode_graph(fwnode->secondary);
+}
+
+static DEFINE_MUTEX(ipu_bridge_mutex);
+
int ipu_bridge_init(struct device *dev,
ipu_parse_sensor_fwnode_t parse_sensor_fwnode)
{
@@ -755,6 +776,11 @@ int ipu_bridge_init(struct device *dev,
unsigned int i;
int ret;
+ guard(mutex)(&ipu_bridge_mutex);
+
+ if (!ipu_bridge_check_fwnode_graph(dev_fwnode(dev)))
+ return 0;
+
if (!ipu_bridge_ivsc_is_ready())
return -EPROBE_DEFER;
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
index ed08bf4178f0..c42adc5a408d 100644
--- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -28,6 +28,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-dma-sg.h>
@@ -1407,7 +1408,6 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier,
static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
{
struct cio2_device *cio2 = to_cio2_device(notifier);
- struct device *dev = &cio2->pci_dev->dev;
struct sensor_async_subdev *s_asd;
struct v4l2_async_connection *asd;
struct cio2_queue *q;
@@ -1417,23 +1417,10 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
s_asd = to_sensor_asd(asd);
q = &cio2->queue[s_asd->csi2.port];
- ret = media_entity_get_fwnode_pad(&q->sensor->entity,
- s_asd->asd.match.fwnode,
- MEDIA_PAD_FL_SOURCE);
- if (ret < 0) {
- dev_err(dev, "no pad for endpoint %pfw (%d)\n",
- s_asd->asd.match.fwnode, ret);
- return ret;
- }
-
- ret = media_create_pad_link(&q->sensor->entity, ret,
- &q->subdev.entity, CIO2_PAD_SINK,
- 0);
- if (ret) {
- dev_err(dev, "failed to create link for %s (endpoint %pfw, error %d)\n",
- q->sensor->name, s_asd->asd.match.fwnode, ret);
+ ret = v4l2_create_fwnode_links_to_pad(asd->sd,
+ &q->subdev_pads[CIO2_PAD_SINK], 0);
+ if (ret)
return ret;
- }
}
return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev);
@@ -1572,6 +1559,7 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q)
v4l2_subdev_init(subdev, &cio2_subdev_ops);
subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
subdev->owner = THIS_MODULE;
+ subdev->dev = dev;
snprintf(subdev->name, sizeof(subdev->name),
CIO2_ENTITY_NAME " %td", q - cio2->queue);
subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
@@ -1679,29 +1667,12 @@ static void cio2_queues_exit(struct cio2_device *cio2)
cio2_queue_exit(cio2, &cio2->queue[i]);
}
-static int cio2_check_fwnode_graph(struct fwnode_handle *fwnode)
-{
- struct fwnode_handle *endpoint;
-
- if (IS_ERR_OR_NULL(fwnode))
- return -EINVAL;
-
- endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
- if (endpoint) {
- fwnode_handle_put(endpoint);
- return 0;
- }
-
- return cio2_check_fwnode_graph(fwnode->secondary);
-}
-
/**************** PCI interface ****************/
static int cio2_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
struct device *dev = &pci_dev->dev;
- struct fwnode_handle *fwnode = dev_fwnode(dev);
struct cio2_device *cio2;
int r;
@@ -1710,17 +1681,9 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
* if the device has no endpoints then we can try to build those as
* software_nodes parsed from SSDB.
*/
- r = cio2_check_fwnode_graph(fwnode);
- if (r) {
- if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) {
- dev_err(dev, "fwnode graph has no endpoints connected\n");
- return -EINVAL;
- }
-
- r = ipu_bridge_init(dev, ipu_bridge_parse_ssdb);
- if (r)
- return r;
- }
+ r = ipu_bridge_init(dev, ipu_bridge_parse_ssdb);
+ if (r)
+ return r;
cio2 = devm_kzalloc(dev, sizeof(*cio2), GFP_KERNEL);
if (!cio2)
diff --git a/drivers/media/pci/intel/ivsc/mei_csi.c b/drivers/media/pci/intel/ivsc/mei_csi.c
index 15b905f66ab7..55e0c60c420c 100644
--- a/drivers/media/pci/intel/ivsc/mei_csi.c
+++ b/drivers/media/pci/intel/ivsc/mei_csi.c
@@ -71,8 +71,8 @@ enum ivsc_privacy_status {
};
enum csi_pads {
- CSI_PAD_SOURCE,
CSI_PAD_SINK,
+ CSI_PAD_SOURCE,
CSI_NUM_PADS
};
@@ -128,7 +128,6 @@ struct mei_csi {
int streaming;
struct media_pad pads[CSI_NUM_PADS];
- struct v4l2_mbus_framefmt format_mbus[CSI_NUM_PADS];
/* number of data lanes used on the CSI-2 link */
u32 nr_of_lanes;
@@ -329,58 +328,17 @@ err:
return ret;
}
-static struct v4l2_mbus_framefmt *
-mei_csi_get_pad_format(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- unsigned int pad, u32 which)
-{
- struct mei_csi *csi = sd_to_csi(sd);
-
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_state_get_format(sd_state, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &csi->format_mbus[pad];
- default:
- return NULL;
- }
-}
-
static int mei_csi_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct v4l2_mbus_framefmt *mbusformat;
- struct mei_csi *csi = sd_to_csi(sd);
unsigned int i;
- mutex_lock(&csi->lock);
-
for (i = 0; i < sd->entity.num_pads; i++) {
mbusformat = v4l2_subdev_state_get_format(sd_state, i);
*mbusformat = mei_csi_format_mbus_default;
}
- mutex_unlock(&csi->lock);
-
- return 0;
-}
-
-static int mei_csi_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
-{
- struct v4l2_mbus_framefmt *mbusformat;
- struct mei_csi *csi = sd_to_csi(sd);
-
- mutex_lock(&csi->lock);
-
- mbusformat = mei_csi_get_pad_format(sd, sd_state, format->pad,
- format->which);
- if (mbusformat)
- format->format = *mbusformat;
-
- mutex_unlock(&csi->lock);
-
return 0;
}
@@ -388,20 +346,17 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
{
- struct v4l2_mbus_framefmt *source_mbusformat;
- struct v4l2_mbus_framefmt *mbusformat;
- struct mei_csi *csi = sd_to_csi(sd);
- struct media_pad *pad;
+ struct v4l2_mbus_framefmt *source_fmt;
+ struct v4l2_mbus_framefmt *sink_fmt;
- mbusformat = mei_csi_get_pad_format(sd, sd_state, format->pad,
- format->which);
- if (!mbusformat)
- return -EINVAL;
+ sink_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SINK);
+ source_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SOURCE);
- source_mbusformat = mei_csi_get_pad_format(sd, sd_state, CSI_PAD_SOURCE,
- format->which);
- if (!source_mbusformat)
- return -EINVAL;
+ if (format->pad) {
+ *source_fmt = *sink_fmt;
+
+ return 0;
+ }
v4l_bound_align_image(&format->format.width, 1, 65536, 0,
&format->format.height, 1, 65536, 0, 0);
@@ -504,18 +459,8 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
if (format->format.field == V4L2_FIELD_ANY)
format->format.field = V4L2_FIELD_NONE;
- mutex_lock(&csi->lock);
-
- pad = &csi->pads[format->pad];
- if (pad->flags & MEDIA_PAD_FL_SOURCE)
- format->format = csi->format_mbus[CSI_PAD_SINK];
-
- *mbusformat = format->format;
-
- if (pad->flags & MEDIA_PAD_FL_SINK)
- *source_mbusformat = format->format;
-
- mutex_unlock(&csi->lock);
+ *sink_fmt = format->format;
+ *source_fmt = *sink_fmt;
return 0;
}
@@ -554,7 +499,7 @@ static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
};
static const struct v4l2_subdev_pad_ops mei_csi_pad_ops = {
- .get_fmt = mei_csi_get_fmt,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = mei_csi_set_fmt,
};
@@ -587,7 +532,7 @@ static int mei_csi_notify_bound(struct v4l2_async_notifier *notifier,
csi->remote_pad = pad;
return media_create_pad_link(&subdev->entity, pad,
- &csi->subdev.entity, 1,
+ &csi->subdev.entity, CSI_PAD_SINK,
MEDIA_LNK_FL_ENABLED |
MEDIA_LNK_FL_IMMUTABLE);
}
@@ -749,6 +694,7 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
goto err_disable;
csi->subdev.dev = &cldev->dev;
+ csi->subdev.state_lock = &csi->lock;
v4l2_subdev_init(&csi->subdev, &mei_csi_subdev_ops);
csi->subdev.internal_ops = &mei_csi_internal_ops;
v4l2_set_subdevdata(&csi->subdev, csi);
@@ -764,9 +710,6 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
if (ret)
goto err_ctrl_handler;
- csi->format_mbus[CSI_PAD_SOURCE] = mei_csi_format_mbus_default;
- csi->format_mbus[CSI_PAD_SINK] = mei_csi_format_mbus_default;
-
csi->pads[CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
csi->pads[CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
ret = media_entity_pads_init(&csi->subdev.entity, CSI_NUM_PADS,
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index e4cf9d63e926..364ce9e57018 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -757,7 +757,7 @@ static const struct video_device video_dev_template = {
/**
* vip_irq - interrupt routine
* @irq: Number of interrupt ( not used, correct number is assumed )
- * @vip: local data structure containing all information
+ * @data: local data structure containing all information
*
* check for both frame interrupts set ( top and bottom ).
* check FIFO overflow, but limit number of log messages after open.
@@ -767,8 +767,9 @@ static const struct video_device video_dev_template = {
*
* IRQ_HANDLED, interrupt done.
*/
-static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
+static irqreturn_t vip_irq(int irq, void *data)
{
+ struct sta2x11_vip *vip = data;
unsigned int status;
status = reg_read(vip, DVP_ITS);
@@ -1053,9 +1054,7 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev,
spin_lock_init(&vip->slock);
- ret = request_irq(pdev->irq,
- (irq_handler_t) vip_irq,
- IRQF_SHARED, KBUILD_MODNAME, vip);
+ ret = request_irq(pdev->irq, vip_irq, IRQF_SHARED, KBUILD_MODNAME, vip);
if (ret) {
dev_err(&pdev->dev, "request_irq failed\n");
ret = -ENODEV;
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index 230b104a7cdf..a47c5850ef87 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
@@ -1463,7 +1463,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
budget_av->has_saa7113 = 1;
err = saa7146_vv_init(dev, &vv_data);
if (err != 0) {
- /* fixme: proper cleanup here */
+ ttpci_budget_deinit(&budget_av->budget);
+ kfree(budget_av);
ERR("cannot init vv subsystem\n");
return err;
}
@@ -1472,9 +1473,10 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) {
- /* fixme: proper cleanup here */
- ERR("cannot register capture v4l2 device\n");
saa7146_vv_release(dev);
+ ttpci_budget_deinit(&budget_av->budget);
+ kfree(budget_av);
+ ERR("cannot register capture v4l2 device\n");
return err;
}
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
index 133d77d1ea0c..a57f9f4f3b87 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -1595,9 +1595,11 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type)
if (V4L2_TYPE_IS_OUTPUT(type)) {
vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
vdec->drain = 0;
+ vdec_abort(inst);
} else {
if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) {
- vdec_abort(inst);
+ if (vb2_is_streaming(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx)))
+ vdec_abort(inst);
vdec->eos_received = 0;
}
vdec_clear_slots(inst);
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index f8450a8ccda6..c1108df72dd5 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -834,7 +834,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
isi->pdata.full_mode = 1;
isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
- np = of_graph_get_next_endpoint(np, NULL);
+ np = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!np) {
dev_err(&pdev->dev, "Could not find the endpoint\n");
return -EINVAL;
@@ -1158,7 +1158,7 @@ static int isi_graph_init(struct atmel_isi *isi)
struct device_node *ep;
int ret;
- ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
+ ep = of_graph_get_endpoint_by_regs(isi->dev->of_node, 0, -1);
if (!ep)
return -EINVAL;
diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index fead5426830e..2d7b0508cc9a 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -114,10 +114,14 @@ static const struct csi2rx_fmt formats[] = {
{ .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },
{ .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },
{ .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, },
+ { .code = MEDIA_BUS_FMT_Y8_1X8, .bpp = 8, },
{ .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, },
{ .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, },
{ .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, },
{ .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, },
+ { .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, },
+ { .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, },
+ { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, },
};
static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
@@ -389,6 +393,18 @@ out:
return ret;
}
+static int csi2rx_enum_mbus_code(struct v4l2_subdev *subdev,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_mbus_code_enum *code_enum)
+{
+ if (code_enum->index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+
+ code_enum->code = formats[code_enum->index].code;
+
+ return 0;
+}
+
static int csi2rx_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
@@ -439,6 +455,7 @@ static int csi2rx_init_state(struct v4l2_subdev *subdev,
}
static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
+ .enum_mbus_code = csi2rx_enum_mbus_code,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = csi2rx_set_fmt,
};
@@ -468,7 +485,7 @@ static int csi2rx_async_bound(struct v4l2_async_notifier *notifier,
struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
csi2rx->source_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
- s_subdev->fwnode,
+ asd->match.fwnode,
MEDIA_PAD_FL_SOURCE);
if (csi2rx->source_pad < 0) {
dev_err(csi2rx->dev, "Couldn't find output pad for subdev %s\n",
diff --git a/drivers/media/platform/chips-media/wave5/wave5-hw.c b/drivers/media/platform/chips-media/wave5/wave5-hw.c
index f1e022fb148e..2d82791f575e 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-hw.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-hw.c
@@ -2315,7 +2315,7 @@ static bool wave5_vpu_enc_check_common_param_valid(struct vpu_instance *inst,
param->intra_refresh_mode);
return false;
}
- };
+ }
return true;
invalid_refresh_argument:
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
index f29cfa3af94a..8bbf9d10b467 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
@@ -92,7 +92,7 @@ static int switch_state(struct vpu_instance *inst, enum vpu_instance_state state
break;
case VPU_INST_STATE_STOP:
break;
- };
+ }
dev_dbg(inst->dev->dev, "Switch state from %s to %s.\n",
state_to_str(inst->state), state_to_str(state));
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.c b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
index 0d90b5820bef..1b3df5b04249 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c
@@ -250,7 +250,7 @@ err_clk_dis:
return ret;
}
-static int wave5_vpu_remove(struct platform_device *pdev)
+static void wave5_vpu_remove(struct platform_device *pdev)
{
struct vpu_device *dev = dev_get_drvdata(&pdev->dev);
@@ -262,8 +262,6 @@ static int wave5_vpu_remove(struct platform_device *pdev)
v4l2_device_unregister(&dev->v4l2_dev);
wave5_vdi_release(&pdev->dev);
ida_destroy(&dev->inst_ida);
-
- return 0;
}
static const struct wave5_match_data ti_wave521c_data = {
@@ -283,7 +281,7 @@ static struct platform_driver wave5_vpu_driver = {
.of_match_table = of_match_ptr(wave5_dt_ids),
},
.probe = wave5_vpu_probe,
- .remove = wave5_vpu_remove,
+ .remove_new = wave5_vpu_remove,
};
module_platform_driver(wave5_vpu_driver);
diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c
index 59b89e421dc2..d904952bf00e 100644
--- a/drivers/media/platform/intel/pxa_camera.c
+++ b/drivers/media/platform/intel/pxa_camera.c
@@ -2207,7 +2207,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
pcdev->mclk = mclk_rate;
}
- np = of_graph_get_next_endpoint(np, NULL);
+ np = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!np) {
dev_err(dev, "could not find endpoint\n");
return -EINVAL;
diff --git a/drivers/media/platform/marvell/Kconfig b/drivers/media/platform/marvell/Kconfig
index d6499ffe30e8..d31f4730f2a3 100644
--- a/drivers/media/platform/marvell/Kconfig
+++ b/drivers/media/platform/marvell/Kconfig
@@ -7,6 +7,7 @@ config VIDEO_CAFE_CCIC
depends on V4L_PLATFORM_DRIVERS
depends on PCI && I2C && VIDEO_DEV
depends on COMMON_CLK
+ select V4L2_ASYNC
select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR
select VIDEOBUF2_VMALLOC
select VIDEOBUF2_DMA_CONTIG
@@ -24,6 +25,7 @@ config VIDEO_MMP_CAMERA
depends on COMMON_CLK
select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR
select I2C_GPIO
+ select V4L2_ASYNC
select VIDEOBUF2_VMALLOC
select VIDEOBUF2_DMA_CONTIG
select VIDEOBUF2_DMA_SG
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
index 8ba6e757e11a..8877eb39e807 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
@@ -144,7 +144,6 @@ struct mtk_jpegdec_clk {
* @jpegenc_irq: jpeg encode irq num
* @job_timeout_work: encode timeout workqueue
* @hw_param: jpeg encode hw parameters
- * @hw_rdy: record hw ready
* @hw_state: record hw state
* @hw_lock: spinlock protecting the hw device resource
*/
diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
index b065ccd06914..378a1cba0144 100644
--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
+++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
@@ -26,7 +26,7 @@ static void mtk_mdp_vpu_handle_init_ack(const struct mdp_ipi_comm_ack *msg)
vpu->inst_addr = msg->vpu_inst_addr;
}
-static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len,
+static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len,
void *priv)
{
const struct mdp_ipi_comm_ack *msg = data;
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c
index 502eeae0bfdc..ecca52b45307 100644
--- a/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c
+++ b/drivers/media/platform/mediatek/mdp3/mdp_cfg_data.c
@@ -46,18 +46,114 @@ enum mt8183_mdp_comp_id {
MT8183_MDP_COMP_WROT1, /* 25 */
};
+enum mt8195_mdp_comp_id {
+ /* MT8195 Comp id */
+ /* ISP */
+ MT8195_MDP_COMP_WPEI = 0,
+ MT8195_MDP_COMP_WPEO, /* 1 */
+ MT8195_MDP_COMP_WPEI2, /* 2 */
+ MT8195_MDP_COMP_WPEO2, /* 3 */
+
+ /* MDP */
+ MT8195_MDP_COMP_CAMIN, /* 4 */
+ MT8195_MDP_COMP_CAMIN2, /* 5 */
+ MT8195_MDP_COMP_SPLIT, /* 6 */
+ MT8195_MDP_COMP_SPLIT2, /* 7 */
+ MT8195_MDP_COMP_RDMA0, /* 8 */
+ MT8195_MDP_COMP_RDMA1, /* 9 */
+ MT8195_MDP_COMP_RDMA2, /* 10 */
+ MT8195_MDP_COMP_RDMA3, /* 11 */
+ MT8195_MDP_COMP_STITCH, /* 12 */
+ MT8195_MDP_COMP_FG0, /* 13 */
+ MT8195_MDP_COMP_FG1, /* 14 */
+ MT8195_MDP_COMP_FG2, /* 15 */
+ MT8195_MDP_COMP_FG3, /* 16 */
+ MT8195_MDP_COMP_TO_SVPP2MOUT, /* 17 */
+ MT8195_MDP_COMP_TO_SVPP3MOUT, /* 18 */
+ MT8195_MDP_COMP_TO_WARP0MOUT, /* 19 */
+ MT8195_MDP_COMP_TO_WARP1MOUT, /* 20 */
+ MT8195_MDP_COMP_VPP0_SOUT, /* 21 */
+ MT8195_MDP_COMP_VPP1_SOUT, /* 22 */
+ MT8195_MDP_COMP_PQ0_SOUT, /* 23 */
+ MT8195_MDP_COMP_PQ1_SOUT, /* 24 */
+ MT8195_MDP_COMP_HDR0, /* 25 */
+ MT8195_MDP_COMP_HDR1, /* 26 */
+ MT8195_MDP_COMP_HDR2, /* 27 */
+ MT8195_MDP_COMP_HDR3, /* 28 */
+ MT8195_MDP_COMP_AAL0, /* 29 */
+ MT8195_MDP_COMP_AAL1, /* 30 */
+ MT8195_MDP_COMP_AAL2, /* 31 */
+ MT8195_MDP_COMP_AAL3, /* 32 */
+ MT8195_MDP_COMP_RSZ0, /* 33 */
+ MT8195_MDP_COMP_RSZ1, /* 34 */
+ MT8195_MDP_COMP_RSZ2, /* 35 */
+ MT8195_MDP_COMP_RSZ3, /* 36 */
+ MT8195_MDP_COMP_TDSHP0, /* 37 */
+ MT8195_MDP_COMP_TDSHP1, /* 38 */
+ MT8195_MDP_COMP_TDSHP2, /* 39 */
+ MT8195_MDP_COMP_TDSHP3, /* 40 */
+ MT8195_MDP_COMP_COLOR0, /* 41 */
+ MT8195_MDP_COMP_COLOR1, /* 42 */
+ MT8195_MDP_COMP_COLOR2, /* 43 */
+ MT8195_MDP_COMP_COLOR3, /* 44 */
+ MT8195_MDP_COMP_OVL0, /* 45 */
+ MT8195_MDP_COMP_OVL1, /* 46 */
+ MT8195_MDP_COMP_PAD0, /* 47 */
+ MT8195_MDP_COMP_PAD1, /* 48 */
+ MT8195_MDP_COMP_PAD2, /* 49 */
+ MT8195_MDP_COMP_PAD3, /* 50 */
+ MT8195_MDP_COMP_TCC0, /* 51 */
+ MT8195_MDP_COMP_TCC1, /* 52 */
+ MT8195_MDP_COMP_WROT0, /* 53 */
+ MT8195_MDP_COMP_WROT1, /* 54 */
+ MT8195_MDP_COMP_WROT2, /* 55 */
+ MT8195_MDP_COMP_WROT3, /* 56 */
+ MT8195_MDP_COMP_MERGE2, /* 57 */
+ MT8195_MDP_COMP_MERGE3, /* 58 */
+
+ MT8195_MDP_COMP_VDO0DL0, /* 59 */
+ MT8195_MDP_COMP_VDO1DL0, /* 60 */
+ MT8195_MDP_COMP_VDO0DL1, /* 61 */
+ MT8195_MDP_COMP_VDO1DL1, /* 62 */
+};
+
static const struct of_device_id mt8183_mdp_probe_infra[MDP_INFRA_MAX] = {
[MDP_INFRA_MMSYS] = { .compatible = "mediatek,mt8183-mmsys" },
[MDP_INFRA_MUTEX] = { .compatible = "mediatek,mt8183-disp-mutex" },
[MDP_INFRA_SCP] = { .compatible = "mediatek,mt8183-scp" }
};
+static const struct of_device_id mt8195_mdp_probe_infra[MDP_INFRA_MAX] = {
+ [MDP_INFRA_MMSYS] = { .compatible = "mediatek,mt8195-vppsys0" },
+ [MDP_INFRA_MMSYS2] = { .compatible = "mediatek,mt8195-vppsys1" },
+ [MDP_INFRA_MUTEX] = { .compatible = "mediatek,mt8195-vpp-mutex" },
+ [MDP_INFRA_MUTEX2] = { .compatible = "mediatek,mt8195-vpp-mutex" },
+ [MDP_INFRA_SCP] = { .compatible = "mediatek,mt8195-scp" }
+};
+
static const struct mdp_platform_config mt8183_plat_cfg = {
.rdma_support_10bit = true,
.rdma_rsz1_sram_sharing = true,
.rdma_upsample_repeat_only = true,
+ .rdma_event_num = 1,
.rsz_disable_dcm_small_sample = false,
.wrot_filter_constraint = false,
+ .wrot_event_num = 1,
+};
+
+static const struct mdp_platform_config mt8195_plat_cfg = {
+ .rdma_support_10bit = true,
+ .rdma_rsz1_sram_sharing = false,
+ .rdma_upsample_repeat_only = false,
+ .rdma_esl_setting = true,
+ .rdma_event_num = 4,
+ .rsz_disable_dcm_small_sample = false,
+ .rsz_etc_control = true,
+ .wrot_filter_constraint = false,
+ .wrot_event_num = 4,
+ .tdshp_hist_num = 17,
+ .tdshp_constrain = true,
+ .tdshp_contour = true,
};
static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = {
@@ -71,81 +167,384 @@ static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = {
[MDP_COMP_CCORR0] = MUTEX_MOD_IDX_MDP_CCORR0,
};
+static const u32 mt8195_mutex_idx[MDP_MAX_COMP_COUNT] = {
+ [MDP_COMP_RDMA0] = MUTEX_MOD_IDX_MDP_RDMA0,
+ [MDP_COMP_RDMA1] = MUTEX_MOD_IDX_MDP_RDMA1,
+ [MDP_COMP_RDMA2] = MUTEX_MOD_IDX_MDP_RDMA2,
+ [MDP_COMP_RDMA3] = MUTEX_MOD_IDX_MDP_RDMA3,
+ [MDP_COMP_STITCH] = MUTEX_MOD_IDX_MDP_STITCH0,
+ [MDP_COMP_FG0] = MUTEX_MOD_IDX_MDP_FG0,
+ [MDP_COMP_FG1] = MUTEX_MOD_IDX_MDP_FG1,
+ [MDP_COMP_FG2] = MUTEX_MOD_IDX_MDP_FG2,
+ [MDP_COMP_FG3] = MUTEX_MOD_IDX_MDP_FG3,
+ [MDP_COMP_HDR0] = MUTEX_MOD_IDX_MDP_HDR0,
+ [MDP_COMP_HDR1] = MUTEX_MOD_IDX_MDP_HDR1,
+ [MDP_COMP_HDR2] = MUTEX_MOD_IDX_MDP_HDR2,
+ [MDP_COMP_HDR3] = MUTEX_MOD_IDX_MDP_HDR3,
+ [MDP_COMP_AAL0] = MUTEX_MOD_IDX_MDP_AAL0,
+ [MDP_COMP_AAL1] = MUTEX_MOD_IDX_MDP_AAL1,
+ [MDP_COMP_AAL2] = MUTEX_MOD_IDX_MDP_AAL2,
+ [MDP_COMP_AAL3] = MUTEX_MOD_IDX_MDP_AAL3,
+ [MDP_COMP_RSZ0] = MUTEX_MOD_IDX_MDP_RSZ0,
+ [MDP_COMP_RSZ1] = MUTEX_MOD_IDX_MDP_RSZ1,
+ [MDP_COMP_RSZ2] = MUTEX_MOD_IDX_MDP_RSZ2,
+ [MDP_COMP_RSZ3] = MUTEX_MOD_IDX_MDP_RSZ3,
+ [MDP_COMP_MERGE2] = MUTEX_MOD_IDX_MDP_MERGE2,
+ [MDP_COMP_MERGE3] = MUTEX_MOD_IDX_MDP_MERGE3,
+ [MDP_COMP_TDSHP0] = MUTEX_MOD_IDX_MDP_TDSHP0,
+ [MDP_COMP_TDSHP1] = MUTEX_MOD_IDX_MDP_TDSHP1,
+ [MDP_COMP_TDSHP2] = MUTEX_MOD_IDX_MDP_TDSHP2,
+ [MDP_COMP_TDSHP3] = MUTEX_MOD_IDX_MDP_TDSHP3,
+ [MDP_COMP_COLOR0] = MUTEX_MOD_IDX_MDP_COLOR0,
+ [MDP_COMP_COLOR1] = MUTEX_MOD_IDX_MDP_COLOR1,
+ [MDP_COMP_COLOR2] = MUTEX_MOD_IDX_MDP_COLOR2,
+ [MDP_COMP_COLOR3] = MUTEX_MOD_IDX_MDP_COLOR3,
+ [MDP_COMP_OVL0] = MUTEX_MOD_IDX_MDP_OVL0,
+ [MDP_COMP_OVL1] = MUTEX_MOD_IDX_MDP_OVL1,
+ [MDP_COMP_PAD0] = MUTEX_MOD_IDX_MDP_PAD0,
+ [MDP_COMP_PAD1] = MUTEX_MOD_IDX_MDP_PAD1,
+ [MDP_COMP_PAD2] = MUTEX_MOD_IDX_MDP_PAD2,
+ [MDP_COMP_PAD3] = MUTEX_MOD_IDX_MDP_PAD3,
+ [MDP_COMP_TCC0] = MUTEX_MOD_IDX_MDP_TCC0,
+ [MDP_COMP_TCC1] = MUTEX_MOD_IDX_MDP_TCC1,
+ [MDP_COMP_WROT0] = MUTEX_MOD_IDX_MDP_WROT0,
+ [MDP_COMP_WROT1] = MUTEX_MOD_IDX_MDP_WROT1,
+ [MDP_COMP_WROT2] = MUTEX_MOD_IDX_MDP_WROT2,
+ [MDP_COMP_WROT3] = MUTEX_MOD_IDX_MDP_WROT3,
+};
+
static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = {
[MDP_COMP_WPEI] = {
- {MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI},
+ {MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEO] = {
- {MDP_COMP_TYPE_EXTO, 2, MT8183_MDP_COMP_WPEO},
+ {MDP_COMP_TYPE_EXTO, 2, MT8183_MDP_COMP_WPEO, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEI2] = {
- {MDP_COMP_TYPE_WPEI, 1, MT8183_MDP_COMP_WPEI2},
+ {MDP_COMP_TYPE_WPEI, 1, MT8183_MDP_COMP_WPEI2, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEO2] = {
- {MDP_COMP_TYPE_EXTO, 3, MT8183_MDP_COMP_WPEO2},
+ {MDP_COMP_TYPE_EXTO, 3, MT8183_MDP_COMP_WPEO2, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_ISP_IMGI] = {
- {MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI},
+ {MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI, MDP_MM_SUBSYS_0},
{0, 0, 4}
},
[MDP_COMP_ISP_IMGO] = {
- {MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO},
+ {MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO, MDP_MM_SUBSYS_0},
{0, 0, 4}
},
[MDP_COMP_ISP_IMG2O] = {
- {MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O},
+ {MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_CAMIN] = {
- {MDP_COMP_TYPE_DL_PATH, 0, MT8183_MDP_COMP_CAMIN},
+ {MDP_COMP_TYPE_DL_PATH, 0, MT8183_MDP_COMP_CAMIN, MDP_MM_SUBSYS_0},
{2, 2, 1}
},
[MDP_COMP_CAMIN2] = {
- {MDP_COMP_TYPE_DL_PATH, 1, MT8183_MDP_COMP_CAMIN2},
+ {MDP_COMP_TYPE_DL_PATH, 1, MT8183_MDP_COMP_CAMIN2, MDP_MM_SUBSYS_0},
{2, 4, 1}
},
[MDP_COMP_RDMA0] = {
- {MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0},
+ {MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0, MDP_MM_SUBSYS_0},
{2, 0, 0}
},
[MDP_COMP_CCORR0] = {
- {MDP_COMP_TYPE_CCORR, 0, MT8183_MDP_COMP_CCORR0},
+ {MDP_COMP_TYPE_CCORR, 0, MT8183_MDP_COMP_CCORR0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_RSZ0] = {
- {MDP_COMP_TYPE_RSZ, 0, MT8183_MDP_COMP_RSZ0},
+ {MDP_COMP_TYPE_RSZ, 0, MT8183_MDP_COMP_RSZ0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_RSZ1] = {
- {MDP_COMP_TYPE_RSZ, 1, MT8183_MDP_COMP_RSZ1},
+ {MDP_COMP_TYPE_RSZ, 1, MT8183_MDP_COMP_RSZ1, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_TDSHP0] = {
- {MDP_COMP_TYPE_TDSHP, 0, MT8183_MDP_COMP_TDSHP0},
+ {MDP_COMP_TYPE_TDSHP, 0, MT8183_MDP_COMP_TDSHP0, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_PATH0_SOUT] = {
- {MDP_COMP_TYPE_PATH, 0, MT8183_MDP_COMP_PATH0_SOUT},
+ {MDP_COMP_TYPE_PATH, 0, MT8183_MDP_COMP_PATH0_SOUT, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_PATH1_SOUT] = {
- {MDP_COMP_TYPE_PATH, 1, MT8183_MDP_COMP_PATH1_SOUT},
+ {MDP_COMP_TYPE_PATH, 1, MT8183_MDP_COMP_PATH1_SOUT, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WROT0] = {
- {MDP_COMP_TYPE_WROT, 0, MT8183_MDP_COMP_WROT0},
+ {MDP_COMP_TYPE_WROT, 0, MT8183_MDP_COMP_WROT0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_WDMA] = {
- {MDP_COMP_TYPE_WDMA, 0, MT8183_MDP_COMP_WDMA},
+ {MDP_COMP_TYPE_WDMA, 0, MT8183_MDP_COMP_WDMA, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
};
+static const struct mdp_comp_data mt8195_mdp_comp_data[MDP_MAX_COMP_COUNT] = {
+ [MDP_COMP_WPEI] = {
+ {MDP_COMP_TYPE_WPEI, 0, MT8195_MDP_COMP_WPEI, MDP_MM_SUBSYS_0},
+ {0, 0, 0}
+ },
+ [MDP_COMP_WPEO] = {
+ {MDP_COMP_TYPE_EXTO, 2, MT8195_MDP_COMP_WPEO, MDP_MM_SUBSYS_0},
+ {0, 0, 0}
+ },
+ [MDP_COMP_WPEI2] = {
+ {MDP_COMP_TYPE_WPEI, 1, MT8195_MDP_COMP_WPEI2, MDP_MM_SUBSYS_0},
+ {0, 0, 0}
+ },
+ [MDP_COMP_WPEO2] = {
+ {MDP_COMP_TYPE_EXTO, 3, MT8195_MDP_COMP_WPEO2, MDP_MM_SUBSYS_0},
+ {0, 0, 0}
+ },
+ [MDP_COMP_CAMIN] = {
+ {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_CAMIN, MDP_MM_SUBSYS_0},
+ {3, 3, 0}
+ },
+ [MDP_COMP_CAMIN2] = {
+ {MDP_COMP_TYPE_DL_PATH, 1, MT8195_MDP_COMP_CAMIN2, MDP_MM_SUBSYS_0},
+ {3, 6, 0}
+ },
+ [MDP_COMP_SPLIT] = {
+ {MDP_COMP_TYPE_SPLIT, 0, MT8195_MDP_COMP_SPLIT, MDP_MM_SUBSYS_1},
+ {7, 0, 0}
+ },
+ [MDP_COMP_SPLIT2] = {
+ {MDP_COMP_TYPE_SPLIT, 1, MT8195_MDP_COMP_SPLIT2, MDP_MM_SUBSYS_1},
+ {7, 0, 0}
+ },
+ [MDP_COMP_RDMA0] = {
+ {MDP_COMP_TYPE_RDMA, 0, MT8195_MDP_COMP_RDMA0, MDP_MM_SUBSYS_0},
+ {3, 0, 0}
+ },
+ [MDP_COMP_RDMA1] = {
+ {MDP_COMP_TYPE_RDMA, 1, MT8195_MDP_COMP_RDMA1, MDP_MM_SUBSYS_1},
+ {3, 0, 0}
+ },
+ [MDP_COMP_RDMA2] = {
+ {MDP_COMP_TYPE_RDMA, 2, MT8195_MDP_COMP_RDMA2, MDP_MM_SUBSYS_1},
+ {3, 0, 0}
+ },
+ [MDP_COMP_RDMA3] = {
+ {MDP_COMP_TYPE_RDMA, 3, MT8195_MDP_COMP_RDMA3, MDP_MM_SUBSYS_1},
+ {3, 0, 0}
+ },
+ [MDP_COMP_STITCH] = {
+ {MDP_COMP_TYPE_STITCH, 0, MT8195_MDP_COMP_STITCH, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_FG0] = {
+ {MDP_COMP_TYPE_FG, 0, MT8195_MDP_COMP_FG0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_FG1] = {
+ {MDP_COMP_TYPE_FG, 1, MT8195_MDP_COMP_FG1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_FG2] = {
+ {MDP_COMP_TYPE_FG, 2, MT8195_MDP_COMP_FG2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_FG3] = {
+ {MDP_COMP_TYPE_FG, 3, MT8195_MDP_COMP_FG3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_HDR0] = {
+ {MDP_COMP_TYPE_HDR, 0, MT8195_MDP_COMP_HDR0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_HDR1] = {
+ {MDP_COMP_TYPE_HDR, 1, MT8195_MDP_COMP_HDR1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_HDR2] = {
+ {MDP_COMP_TYPE_HDR, 2, MT8195_MDP_COMP_HDR2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_HDR3] = {
+ {MDP_COMP_TYPE_HDR, 3, MT8195_MDP_COMP_HDR3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_AAL0] = {
+ {MDP_COMP_TYPE_AAL, 0, MT8195_MDP_COMP_AAL0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_AAL1] = {
+ {MDP_COMP_TYPE_AAL, 1, MT8195_MDP_COMP_AAL1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_AAL2] = {
+ {MDP_COMP_TYPE_AAL, 2, MT8195_MDP_COMP_AAL2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_AAL3] = {
+ {MDP_COMP_TYPE_AAL, 3, MT8195_MDP_COMP_AAL3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_RSZ0] = {
+ {MDP_COMP_TYPE_RSZ, 0, MT8195_MDP_COMP_RSZ0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_RSZ1] = {
+ {MDP_COMP_TYPE_RSZ, 1, MT8195_MDP_COMP_RSZ1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_RSZ2] = {
+ {MDP_COMP_TYPE_RSZ, 2, MT8195_MDP_COMP_RSZ2, MDP_MM_SUBSYS_1},
+ {2, 0, 0},
+ {MDP_COMP_MERGE2, true, true}
+ },
+ [MDP_COMP_RSZ3] = {
+ {MDP_COMP_TYPE_RSZ, 3, MT8195_MDP_COMP_RSZ3, MDP_MM_SUBSYS_1},
+ {2, 0, 0},
+ {MDP_COMP_MERGE3, true, true}
+ },
+ [MDP_COMP_TDSHP0] = {
+ {MDP_COMP_TYPE_TDSHP, 0, MT8195_MDP_COMP_TDSHP0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_TDSHP1] = {
+ {MDP_COMP_TYPE_TDSHP, 1, MT8195_MDP_COMP_TDSHP1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_TDSHP2] = {
+ {MDP_COMP_TYPE_TDSHP, 2, MT8195_MDP_COMP_TDSHP2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_TDSHP3] = {
+ {MDP_COMP_TYPE_TDSHP, 3, MT8195_MDP_COMP_TDSHP3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_COLOR0] = {
+ {MDP_COMP_TYPE_COLOR, 0, MT8195_MDP_COMP_COLOR0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_COLOR1] = {
+ {MDP_COMP_TYPE_COLOR, 1, MT8195_MDP_COMP_COLOR1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_COLOR2] = {
+ {MDP_COMP_TYPE_COLOR, 2, MT8195_MDP_COMP_COLOR2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_COLOR3] = {
+ {MDP_COMP_TYPE_COLOR, 3, MT8195_MDP_COMP_COLOR3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_OVL0] = {
+ {MDP_COMP_TYPE_OVL, 0, MT8195_MDP_COMP_OVL0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_OVL1] = {
+ {MDP_COMP_TYPE_OVL, 1, MT8195_MDP_COMP_OVL1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_PAD0] = {
+ {MDP_COMP_TYPE_PAD, 0, MT8195_MDP_COMP_PAD0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_PAD1] = {
+ {MDP_COMP_TYPE_PAD, 1, MT8195_MDP_COMP_PAD1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_PAD2] = {
+ {MDP_COMP_TYPE_PAD, 2, MT8195_MDP_COMP_PAD2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_PAD3] = {
+ {MDP_COMP_TYPE_PAD, 3, MT8195_MDP_COMP_PAD3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_TCC0] = {
+ {MDP_COMP_TYPE_TCC, 0, MT8195_MDP_COMP_TCC0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_TCC1] = {
+ {MDP_COMP_TYPE_TCC, 1, MT8195_MDP_COMP_TCC1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_WROT0] = {
+ {MDP_COMP_TYPE_WROT, 0, MT8195_MDP_COMP_WROT0, MDP_MM_SUBSYS_0},
+ {1, 0, 0}
+ },
+ [MDP_COMP_WROT1] = {
+ {MDP_COMP_TYPE_WROT, 1, MT8195_MDP_COMP_WROT1, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_WROT2] = {
+ {MDP_COMP_TYPE_WROT, 2, MT8195_MDP_COMP_WROT2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_WROT3] = {
+ {MDP_COMP_TYPE_WROT, 3, MT8195_MDP_COMP_WROT3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_MERGE2] = {
+ {MDP_COMP_TYPE_MERGE, 0, MT8195_MDP_COMP_MERGE2, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_MERGE3] = {
+ {MDP_COMP_TYPE_MERGE, 1, MT8195_MDP_COMP_MERGE3, MDP_MM_SUBSYS_1},
+ {1, 0, 0}
+ },
+ [MDP_COMP_PQ0_SOUT] = {
+ {MDP_COMP_TYPE_DUMMY, 0, MT8195_MDP_COMP_PQ0_SOUT, MDP_MM_SUBSYS_0},
+ {0, 0, 0}
+ },
+ [MDP_COMP_PQ1_SOUT] = {
+ {MDP_COMP_TYPE_DUMMY, 1, MT8195_MDP_COMP_PQ1_SOUT, MDP_MM_SUBSYS_1},
+ {0, 0, 0}
+ },
+ [MDP_COMP_TO_WARP0MOUT] = {
+ {MDP_COMP_TYPE_DUMMY, 2, MT8195_MDP_COMP_TO_WARP0MOUT, MDP_MM_SUBSYS_0},
+ {0, 0, 0}
+ },
+ [MDP_COMP_TO_WARP1MOUT] = {
+ {MDP_COMP_TYPE_DUMMY, 3, MT8195_MDP_COMP_TO_WARP1MOUT, MDP_MM_SUBSYS_0},
+ {0, 0, 0}
+ },
+ [MDP_COMP_TO_SVPP2MOUT] = {
+ {MDP_COMP_TYPE_DUMMY, 4, MT8195_MDP_COMP_TO_SVPP2MOUT, MDP_MM_SUBSYS_1},
+ {0, 0, 0}
+ },
+ [MDP_COMP_TO_SVPP3MOUT] = {
+ {MDP_COMP_TYPE_DUMMY, 5, MT8195_MDP_COMP_TO_SVPP3MOUT, MDP_MM_SUBSYS_1},
+ {0, 0, 0}
+ },
+ [MDP_COMP_VPP0_SOUT] = {
+ {MDP_COMP_TYPE_PATH, 0, MT8195_MDP_COMP_VPP0_SOUT, MDP_MM_SUBSYS_1},
+ {4, 9, 0}
+ },
+ [MDP_COMP_VPP1_SOUT] = {
+ {MDP_COMP_TYPE_PATH, 1, MT8195_MDP_COMP_VPP1_SOUT, MDP_MM_SUBSYS_0},
+ {2, 13, 0}
+ },
+ [MDP_COMP_VDO0DL0] = {
+ {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO0DL0, MDP_MM_SUBSYS_1},
+ {1, 15, 0}
+ },
+ [MDP_COMP_VDO1DL0] = {
+ {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO1DL0, MDP_MM_SUBSYS_1},
+ {1, 17, 0}
+ },
+ [MDP_COMP_VDO0DL1] = {
+ {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO0DL1, MDP_MM_SUBSYS_1},
+ {1, 18, 0}
+ },
+ [MDP_COMP_VDO1DL1] = {
+ {MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO1DL1, MDP_MM_SUBSYS_1},
+ {1, 16, 0}
+ },
+};
+
static const struct of_device_id mt8183_sub_comp_dt_ids[] = {
{
.compatible = "mediatek,mt8183-mdp3-wdma",
@@ -157,6 +556,10 @@ static const struct of_device_id mt8183_sub_comp_dt_ids[] = {
{}
};
+static const struct of_device_id mt8195_sub_comp_dt_ids[] = {
+ {}
+};
+
/*
* All 10-bit related formats are not added in the basic format list,
* please add the corresponding format settings before use.
@@ -382,6 +785,222 @@ static const struct mdp_format mt8183_formats[] = {
}
};
+static const struct mdp_format mt8195_formats[] = {
+ {
+ .pixelformat = V4L2_PIX_FMT_GREY,
+ .mdp_color = MDP_COLOR_GREY,
+ .depth = { 8 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_RGB565X,
+ .mdp_color = MDP_COLOR_BGR565,
+ .depth = { 16 },
+ .row_depth = { 16 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_RGB565,
+ .mdp_color = MDP_COLOR_RGB565,
+ .depth = { 16 },
+ .row_depth = { 16 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_RGB24,
+ .mdp_color = MDP_COLOR_RGB888,
+ .depth = { 24 },
+ .row_depth = { 24 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_BGR24,
+ .mdp_color = MDP_COLOR_BGR888,
+ .depth = { 24 },
+ .row_depth = { 24 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_ABGR32,
+ .mdp_color = MDP_COLOR_BGRA8888,
+ .depth = { 32 },
+ .row_depth = { 32 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_ARGB32,
+ .mdp_color = MDP_COLOR_ARGB8888,
+ .depth = { 32 },
+ .row_depth = { 32 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .mdp_color = MDP_COLOR_UYVY,
+ .depth = { 16 },
+ .row_depth = { 16 },
+ .num_planes = 1,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_VYUY,
+ .mdp_color = MDP_COLOR_VYUY,
+ .depth = { 16 },
+ .row_depth = { 16 },
+ .num_planes = 1,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .mdp_color = MDP_COLOR_YUYV,
+ .depth = { 16 },
+ .row_depth = { 16 },
+ .num_planes = 1,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YVYU,
+ .mdp_color = MDP_COLOR_YVYU,
+ .depth = { 16 },
+ .row_depth = { 16 },
+ .num_planes = 1,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YUV420,
+ .mdp_color = MDP_COLOR_I420,
+ .depth = { 12 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YVU420,
+ .mdp_color = MDP_COLOR_YV12,
+ .depth = { 12 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV12,
+ .mdp_color = MDP_COLOR_NV12,
+ .depth = { 12 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV21,
+ .mdp_color = MDP_COLOR_NV21,
+ .depth = { 12 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV16,
+ .mdp_color = MDP_COLOR_NV16,
+ .depth = { 16 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV61,
+ .mdp_color = MDP_COLOR_NV61,
+ .depth = { 16 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV12M,
+ .mdp_color = MDP_COLOR_NV12,
+ .depth = { 8, 4 },
+ .row_depth = { 8, 8 },
+ .num_planes = 2,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_MM21,
+ .mdp_color = MDP_COLOR_420_BLK,
+ .depth = { 8, 4 },
+ .row_depth = { 8, 8 },
+ .num_planes = 2,
+ .walign = 6,
+ .halign = 6,
+ .flags = MDP_FMT_FLAG_OUTPUT,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV21M,
+ .mdp_color = MDP_COLOR_NV21,
+ .depth = { 8, 4 },
+ .row_depth = { 8, 8 },
+ .num_planes = 2,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV16M,
+ .mdp_color = MDP_COLOR_NV16,
+ .depth = { 8, 8 },
+ .row_depth = { 8, 8 },
+ .num_planes = 2,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV61M,
+ .mdp_color = MDP_COLOR_NV61,
+ .depth = { 8, 8 },
+ .row_depth = { 8, 8 },
+ .num_planes = 2,
+ .walign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YUV420M,
+ .mdp_color = MDP_COLOR_I420,
+ .depth = { 8, 2, 2 },
+ .row_depth = { 8, 4, 4 },
+ .num_planes = 3,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YVU420M,
+ .mdp_color = MDP_COLOR_YV12,
+ .depth = { 8, 2, 2 },
+ .row_depth = { 8, 4, 4 },
+ .num_planes = 3,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YUV422M,
+ .mdp_color = MDP_COLOR_I422,
+ .depth = { 8, 4, 4 },
+ .row_depth = { 8, 4, 4 },
+ .num_planes = 3,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_YVU422M,
+ .mdp_color = MDP_COLOR_YV16,
+ .depth = { 8, 4, 4 },
+ .row_depth = { 8, 4, 4 },
+ .num_planes = 3,
+ .walign = 1,
+ .halign = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+ }
+};
+
static const struct mdp_limit mt8183_mdp_def_limit = {
.out_limit = {
.wmin = 16,
@@ -401,15 +1020,54 @@ static const struct mdp_limit mt8183_mdp_def_limit = {
.v_scale_down_max = 128,
};
+static const struct mdp_limit mt8195_mdp_def_limit = {
+ .out_limit = {
+ .wmin = 64,
+ .hmin = 64,
+ .wmax = 8192,
+ .hmax = 8192,
+ },
+ .cap_limit = {
+ .wmin = 64,
+ .hmin = 64,
+ .wmax = 8192,
+ .hmax = 8192,
+ },
+ .h_scale_up_max = 64,
+ .v_scale_up_max = 64,
+ .h_scale_down_max = 128,
+ .v_scale_down_max = 128,
+};
+
static const struct mdp_pipe_info mt8183_pipe_info[] = {
- [MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, 0},
- [MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, 1},
- [MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, 2},
- [MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, 3}
+ [MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, MDP_MM_SUBSYS_0, 0},
+ [MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, MDP_MM_SUBSYS_0, 1},
+ [MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, MDP_MM_SUBSYS_0, 2},
+ [MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, MDP_MM_SUBSYS_0, 3}
+};
+
+static const struct mdp_pipe_info mt8195_pipe_info[] = {
+ [MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, MDP_MM_SUBSYS_0, 0},
+ [MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, MDP_MM_SUBSYS_0, 1},
+ [MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, MDP_MM_SUBSYS_0, 2},
+ [MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, MDP_MM_SUBSYS_0, 3},
+ [MDP_PIPE_RDMA1] = {MDP_PIPE_RDMA1, MDP_MM_SUBSYS_1, 0},
+ [MDP_PIPE_RDMA2] = {MDP_PIPE_RDMA2, MDP_MM_SUBSYS_1, 1},
+ [MDP_PIPE_RDMA3] = {MDP_PIPE_RDMA3, MDP_MM_SUBSYS_1, 2},
+ [MDP_PIPE_SPLIT] = {MDP_PIPE_SPLIT, MDP_MM_SUBSYS_1, 3},
+ [MDP_PIPE_SPLIT2] = {MDP_PIPE_SPLIT2, MDP_MM_SUBSYS_1, 4},
+ [MDP_PIPE_VPP1_SOUT] = {MDP_PIPE_VPP1_SOUT, MDP_MM_SUBSYS_0, 4},
+ [MDP_PIPE_VPP0_SOUT] = {MDP_PIPE_VPP0_SOUT, MDP_MM_SUBSYS_1, 5},
+};
+
+static const struct v4l2_rect mt8195_mdp_pp_criteria = {
+ .width = 1920,
+ .height = 1080,
};
const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
.mdp_plat_id = MT8183,
+ .mdp_con_res = 0x14001000,
.mdp_probe_infra = mt8183_mdp_probe_infra,
.mdp_cfg = &mt8183_plat_cfg,
.mdp_mutex_table_idx = mt8183_mutex_idx,
@@ -421,6 +1079,25 @@ const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
.def_limit = &mt8183_mdp_def_limit,
.pipe_info = mt8183_pipe_info,
.pipe_info_len = ARRAY_SIZE(mt8183_pipe_info),
+ .pp_used = MDP_PP_USED_1,
+};
+
+const struct mtk_mdp_driver_data mt8195_mdp_driver_data = {
+ .mdp_plat_id = MT8195,
+ .mdp_con_res = 0x14001000,
+ .mdp_probe_infra = mt8195_mdp_probe_infra,
+ .mdp_sub_comp_dt_ids = mt8195_sub_comp_dt_ids,
+ .mdp_cfg = &mt8195_plat_cfg,
+ .mdp_mutex_table_idx = mt8195_mutex_idx,
+ .comp_data = mt8195_mdp_comp_data,
+ .comp_data_len = ARRAY_SIZE(mt8195_mdp_comp_data),
+ .format = mt8195_formats,
+ .format_len = ARRAY_SIZE(mt8195_formats),
+ .def_limit = &mt8195_mdp_def_limit,
+ .pipe_info = mt8195_pipe_info,
+ .pipe_info_len = ARRAY_SIZE(mt8195_pipe_info),
+ .pp_criteria = &mt8195_mdp_pp_criteria,
+ .pp_used = MDP_PP_USED_2,
};
s32 mdp_cfg_get_id_inner(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id)
@@ -451,3 +1128,11 @@ enum mtk_mdp_comp_id mdp_cfg_get_id_public(struct mdp_dev *mdp_dev, s32 inner_id
err_public_id:
return public_id;
}
+
+bool mdp_cfg_comp_is_dummy(struct mdp_dev *mdp_dev, s32 inner_id)
+{
+ enum mtk_mdp_comp_id id = mdp_cfg_get_id_public(mdp_dev, inner_id);
+ enum mdp_comp_type type = mdp_dev->mdp_data->comp_data[id].match.type;
+
+ return (type == MDP_COMP_TYPE_DUMMY);
+}
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h
new file mode 100644
index 000000000000..4b9513e54543
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_aal.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_AAL_H__
+#define __MDP_REG_AAL_H__
+
+#define MDP_AAL_EN (0x000)
+#define MDP_AAL_CFG (0x020)
+#define MDP_AAL_SIZE (0x030)
+#define MDP_AAL_OUTPUT_SIZE (0x034)
+#define MDP_AAL_OUTPUT_OFFSET (0x038)
+#define MDP_AAL_CFG_MAIN (0x200)
+
+/* MASK */
+#define MDP_AAL_EN_MASK (0x01)
+#define MDP_AAL_CFG_MASK (0x70FF00B3)
+#define MDP_AAL_SIZE_MASK (0x1FFF1FFF)
+#define MDP_AAL_OUTPUT_SIZE_MASK (0x1FFF1FFF)
+#define MDP_AAL_OUTPUT_OFFSET_MASK (0x0FF00FF)
+#define MDP_AAL_CFG_MAIN_MASK (0x0FE)
+
+#endif // __MDP_REG_AAL_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_color.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_color.h
new file mode 100644
index 000000000000..f72503975b24
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_color.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_COLOR_H__
+#define __MDP_REG_COLOR_H__
+
+#define MDP_COLOR_WIN_X_MAIN (0x40C)
+#define MDP_COLOR_WIN_Y_MAIN (0x410)
+#define MDP_COLOR_START (0xC00)
+#define MDP_COLOR_INTEN (0xC04)
+#define MDP_COLOR_OUT_SEL (0xC0C)
+#define MDP_COLOR_INTERNAL_IP_WIDTH (0xC50)
+#define MDP_COLOR_INTERNAL_IP_HEIGHT (0xC54)
+#define MDP_COLOR_CM1_EN (0xC60)
+#define MDP_COLOR_CM2_EN (0xCA0)
+
+/* MASK */
+#define MDP_COLOR_WIN_X_MAIN_MASK (0xFFFFFFFF)
+#define MDP_COLOR_WIN_Y_MAIN_MASK (0xFFFFFFFF)
+#define MDP_COLOR_START_MASK (0x0FF013F)
+#define MDP_COLOR_INTEN_MASK (0x07)
+#define MDP_COLOR_OUT_SEL_MASK (0x0777)
+#define MDP_COLOR_INTERNAL_IP_WIDTH_MASK (0x03FFF)
+#define MDP_COLOR_INTERNAL_IP_HEIGHT_MASK (0x03FFF)
+#define MDP_COLOR_CM1_EN_MASK (0x03)
+#define MDP_COLOR_CM2_EN_MASK (0x017)
+
+#endif // __MDP_REG_COLOR_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h
new file mode 100644
index 000000000000..d90bcad33a59
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_fg.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_FG_H__
+#define __MDP_REG_FG_H__
+
+#define MDP_FG_TRIGGER (0x0)
+#define MDP_FG_FG_CTRL_0 (0x20)
+#define MDP_FG_FG_CK_EN (0x24)
+#define MDP_FG_TILE_INFO_0 (0x418)
+#define MDP_FG_TILE_INFO_1 (0x41c)
+
+/* MASK */
+#define MDP_FG_TRIGGER_MASK (0x00000007)
+#define MDP_FG_FG_CTRL_0_MASK (0x00000033)
+#define MDP_FG_FG_CK_EN_MASK (0x0000000F)
+#define MDP_FG_TILE_INFO_0_MASK (0xFFFFFFFF)
+#define MDP_FG_TILE_INFO_1_MASK (0xFFFFFFFF)
+
+#endif //__MDP_REG_FG_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h
new file mode 100644
index 000000000000..c19fbba39fc0
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_hdr.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_HDR_H__
+#define __MDP_REG_HDR_H__
+
+#define MDP_HDR_TOP (0x000)
+#define MDP_HDR_RELAY (0x004)
+#define MDP_HDR_SIZE_0 (0x014)
+#define MDP_HDR_SIZE_1 (0x018)
+#define MDP_HDR_SIZE_2 (0x01C)
+#define MDP_HDR_HIST_CTRL_0 (0x020)
+#define MDP_HDR_HIST_CTRL_1 (0x024)
+#define MDP_HDR_HIST_ADDR (0x0DC)
+#define MDP_HDR_TILE_POS (0x118)
+
+/* MASK */
+#define MDP_HDR_RELAY_MASK (0x01)
+#define MDP_HDR_TOP_MASK (0xFF0FEB6D)
+#define MDP_HDR_SIZE_0_MASK (0x1FFF1FFF)
+#define MDP_HDR_SIZE_1_MASK (0x1FFF1FFF)
+#define MDP_HDR_SIZE_2_MASK (0x1FFF1FFF)
+#define MDP_HDR_HIST_CTRL_0_MASK (0x1FFF1FFF)
+#define MDP_HDR_HIST_CTRL_1_MASK (0x1FFF1FFF)
+#define MDP_HDR_HIST_ADDR_MASK (0xBF3F2F3F)
+#define MDP_HDR_TILE_POS_MASK (0x1FFF1FFF)
+
+#endif // __MDP_REG_HDR_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h
new file mode 100644
index 000000000000..46be27e2a656
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_merge.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_MERGE_H__
+#define __MDP_REG_MERGE_H__
+
+#define MDP_MERGE_ENABLE (0x000)
+#define MDP_MERGE_CFG_0 (0x010)
+#define MDP_MERGE_CFG_4 (0x020)
+#define MDP_MERGE_CFG_12 (0x040)
+#define MDP_MERGE_CFG_24 (0x070)
+#define MDP_MERGE_CFG_25 (0x074)
+
+/* MASK */
+#define MDP_MERGE_ENABLE_MASK (0xFFFFFFFF)
+#define MDP_MERGE_CFG_0_MASK (0xFFFFFFFF)
+#define MDP_MERGE_CFG_4_MASK (0xFFFFFFFF)
+#define MDP_MERGE_CFG_12_MASK (0xFFFFFFFF)
+#define MDP_MERGE_CFG_24_MASK (0xFFFFFFFF)
+#define MDP_MERGE_CFG_25_MASK (0xFFFFFFFF)
+
+#endif //__MDP_REG_MERGE_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h
new file mode 100644
index 000000000000..21d2d0323293
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_ovl.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_OVL_H__
+#define __MDP_REG_OVL_H__
+
+#define MDP_OVL_EN (0x00c)
+#define MDP_OVL_ROI_SIZE (0x020)
+#define MDP_OVL_DP_CON (0x024)
+#define MDP_OVL_SRC_CON (0x02c)
+#define MDP_OVL_L0_CON (0x030)
+#define MDP_OVL_L0_SRC_SIZE (0x038)
+
+/* MASK */
+#define MDP_OVL_DP_CON_MASK (0x0FFFFFFF)
+#define MDP_OVL_EN_MASK (0xB07D07B1)
+#define MDP_OVL_L0_CON_MASK (0xFFFFFFFF)
+#define MDP_OVL_L0_SRC_SIZE_MASK (0x1FFF1FFF)
+#define MDP_OVL_ROI_SIZE_MASK (0x1FFF1FFF)
+#define MDP_OVL_SRC_CON_MASK (0x0000031F)
+
+#endif //__MDP_REG_OVL_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h
new file mode 100644
index 000000000000..0e89f1db19ed
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_pad.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_PAD_H__
+#define __MDP_REG_PAD_H__
+
+#define MDP_PAD_CON (0x000)
+#define MDP_PAD_PIC_SIZE (0x004)
+#define MDP_PAD_W_SIZE (0x008)
+#define MDP_PAD_H_SIZE (0x00c)
+
+/* MASK */
+#define MDP_PAD_CON_MASK (0x00000007)
+#define MDP_PAD_PIC_SIZE_MASK (0xFFFFFFFF)
+#define MDP_PAD_W_SIZE_MASK (0x1FFF1FFF)
+#define MDP_PAD_H_SIZE_MASK (0x1FFF1FFF)
+
+#endif // __MDP_REG_PAD_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h
index be4065e252d3..0affb2a3b958 100644
--- a/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h
@@ -26,6 +26,18 @@
#define MDP_RDMA_SRC_OFFSET_2 0x128
#define MDP_RDMA_SRC_OFFSET_0_P 0x148
#define MDP_RDMA_TRANSFORM_0 0x200
+#define MDP_RDMA_DMABUF_CON_0 0x240
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_0 0x248
+#define MDP_RDMA_ULTRA_TH_LOW_CON_0 0x250
+#define MDP_RDMA_DMABUF_CON_1 0x258
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_1 0x260
+#define MDP_RDMA_ULTRA_TH_LOW_CON_1 0x268
+#define MDP_RDMA_DMABUF_CON_2 0x270
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_2 0x278
+#define MDP_RDMA_ULTRA_TH_LOW_CON_2 0x280
+#define MDP_RDMA_DMABUF_CON_3 0x288
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_3 0x290
+#define MDP_RDMA_ULTRA_TH_LOW_CON_3 0x298
#define MDP_RDMA_RESV_DUMMY_0 0x2a0
#define MDP_RDMA_MON_STA_1 0x408
#define MDP_RDMA_SRC_BASE_0 0xf00
@@ -54,6 +66,18 @@
#define MDP_RDMA_SRC_OFFSET_2_MASK 0xffffffff
#define MDP_RDMA_SRC_OFFSET_0_P_MASK 0xffffffff
#define MDP_RDMA_TRANSFORM_0_MASK 0xff110777
+#define MDP_RDMA_DMABUF_CON_0_MASK 0x0fff00ff
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_0_MASK 0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_0_MASK 0x3fffffff
+#define MDP_RDMA_DMABUF_CON_1_MASK 0x0f7f007f
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_1_MASK 0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_1_MASK 0x3fffffff
+#define MDP_RDMA_DMABUF_CON_2_MASK 0x0f3f003f
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_2_MASK 0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_2_MASK 0x3fffffff
+#define MDP_RDMA_DMABUF_CON_3_MASK 0x0f3f003f
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_3_MASK 0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_3_MASK 0x3fffffff
#define MDP_RDMA_RESV_DUMMY_0_MASK 0xffffffff
#define MDP_RDMA_MON_STA_1_MASK 0xffffffff
#define MDP_RDMA_SRC_BASE_0_MASK 0xffffffff
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h
index 484f6d60641f..187531db8e3b 100644
--- a/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h
@@ -20,6 +20,7 @@
#define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET 0x02c
#define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET 0x030
#define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET 0x034
+#define RSZ_ETC_CONTROL 0x22c
/* MASK */
#define PRZ_ENABLE_MASK 0x00010001
@@ -35,5 +36,6 @@
#define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET_MASK 0x001fffff
#define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET_MASK 0x0000ffff
#define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET_MASK 0x001fffff
+#define RSZ_ETC_CONTROL_MASK 0xff770000
#endif // __MDP_REG_RSZ_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h
new file mode 100644
index 000000000000..83b5f9b432d8
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_tdshp.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_TDSHP_H__
+#define __MDP_REG_TDSHP_H__
+
+#define MDP_HIST_CFG_00 (0x064)
+#define MDP_HIST_CFG_01 (0x068)
+#define MDP_TDSHP_CTRL (0x100)
+#define MDP_TDSHP_CFG (0x110)
+#define MDP_TDSHP_INPUT_SIZE (0x120)
+#define MDP_TDSHP_OUTPUT_OFFSET (0x124)
+#define MDP_TDSHP_OUTPUT_SIZE (0x128)
+#define MDP_LUMA_HIST_INIT (0x200)
+#define MDP_DC_TWO_D_W1_RESULT_INIT (0x260)
+#define MDP_CONTOUR_HIST_INIT (0x398)
+
+/* MASK */
+#define MDP_HIST_CFG_00_MASK (0xFFFFFFFF)
+#define MDP_HIST_CFG_01_MASK (0xFFFFFFFF)
+#define MDP_LUMA_HIST_MASK (0xFFFFFFFF)
+#define MDP_TDSHP_CTRL_MASK (0x07)
+#define MDP_TDSHP_CFG_MASK (0x03F7)
+#define MDP_TDSHP_INPUT_SIZE_MASK (0x1FFF1FFF)
+#define MDP_TDSHP_OUTPUT_OFFSET_MASK (0x0FF00FF)
+#define MDP_TDSHP_OUTPUT_SIZE_MASK (0x1FFF1FFF)
+#define MDP_LUMA_HIST_INIT_MASK (0xFFFFFFFF)
+#define MDP_DC_TWO_D_W1_RESULT_INIT_MASK (0x007FFFFF)
+#define MDP_CONTOUR_HIST_INIT_MASK (0xFFFFFFFF)
+
+#endif // __MDP_REG_TDSHP_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h
index 6d3ff0e2b672..b6f016d2c29d 100644
--- a/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h
@@ -17,14 +17,18 @@
#define VIDO_STRIDE 0x030
#define VIDO_OFST_ADDR_C 0x038
#define VIDO_STRIDE_C 0x03c
+#define VIDO_CTRL_2 0x048
#define VIDO_DITHER 0x054
#define VIDO_STRIDE_V 0x06c
#define VIDO_OFST_ADDR_V 0x068
#define VIDO_RSV_1 0x070
+#define VIDO_DMA_PREULTRA 0x074
#define VIDO_IN_SIZE 0x078
#define VIDO_ROT_EN 0x07c
#define VIDO_FIFO_TEST 0x080
#define VIDO_MAT_CTRL 0x084
+#define VIDO_SCAN_10BIT 0x0dc
+#define VIDO_PENDING_ZERO 0x0e0
#define VIDO_BASE_ADDR 0xf00
#define VIDO_BASE_ADDR_C 0xf04
#define VIDO_BASE_ADDR_V 0xf08
@@ -40,14 +44,18 @@
#define VIDO_STRIDE_MASK 0x0000ffff
#define VIDO_OFST_ADDR_C_MASK 0x0fffffff
#define VIDO_STRIDE_C_MASK 0x0000ffff
+#define VIDO_CTRL_2_MASK 0x0000000f
#define VIDO_DITHER_MASK 0xff000001
#define VIDO_STRIDE_V_MASK 0x0000ffff
#define VIDO_OFST_ADDR_V_MASK 0x0fffffff
#define VIDO_RSV_1_MASK 0xffffffff
+#define VIDO_DMA_PREULTRA_MASK 0x00ffffff
#define VIDO_IN_SIZE_MASK 0x1fff1fff
#define VIDO_ROT_EN_MASK 0x00000001
#define VIDO_FIFO_TEST_MASK 0x00000fff
#define VIDO_MAT_CTRL_MASK 0x000000f3
+#define VIDO_SCAN_10BIT_MASK 0x0000000f
+#define VIDO_PENDING_ZERO_MASK 0x07ffffff
#define VIDO_BASE_ADDR_MASK 0xffffffff
#define VIDO_BASE_ADDR_C_MASK 0xffffffff
#define VIDO_BASE_ADDR_V_MASK 0xffffffff
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h b/drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h
new file mode 100644
index 000000000000..b09f48222d24
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_sm_mt8195.h
@@ -0,0 +1,283 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_SM_MT8195_H__
+#define __MDP_SM_MT8195_H__
+
+#include "mtk-mdp3-type.h"
+
+/*
+ * ISP-MDP generic output information
+ * MD5 of the target SCP prebuild:
+ * a49ec487e458b5971880f1b63dc2a9d5
+ */
+
+#define IMG_MAX_SUBFRAMES_8195 20
+
+struct img_comp_frame_8195 {
+ u32 output_disable;
+ u32 bypass;
+ u32 in_width;
+ u32 in_height;
+ u32 out_width;
+ u32 out_height;
+ struct img_crop crop;
+ u32 in_total_width;
+ u32 out_total_width;
+} __packed;
+
+struct img_comp_subfrm_8195 {
+ u32 tile_disable;
+ struct img_region in;
+ struct img_region out;
+ struct img_offset luma;
+ struct img_offset chroma;
+ s32 out_vertical; /* Output vertical index */
+ s32 out_horizontal; /* Output horizontal index */
+} __packed;
+
+struct mdp_rdma_subfrm_8195 {
+ u32 offset[IMG_MAX_PLANES];
+ u32 offset_0_p;
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+ u32 in_tile_xleft;
+ u32 in_tile_ytop;
+} __packed;
+
+struct mdp_rdma_data_8195 {
+ u32 src_ctrl;
+ u32 comp_ctrl;
+ u32 control;
+ u32 iova[IMG_MAX_PLANES];
+ u32 iova_end[IMG_MAX_PLANES];
+ u32 mf_bkgd;
+ u32 mf_bkgd_in_pxl;
+ u32 sf_bkgd;
+ u32 ufo_dec_y;
+ u32 ufo_dec_c;
+ u32 transform;
+ u32 dmabuf_con0;
+ u32 ultra_th_high_con0;
+ u32 ultra_th_low_con0;
+ u32 dmabuf_con1;
+ u32 ultra_th_high_con1;
+ u32 ultra_th_low_con1;
+ u32 dmabuf_con2;
+ u32 ultra_th_high_con2;
+ u32 ultra_th_low_con2;
+ u32 dmabuf_con3;
+ struct mdp_rdma_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_fg_subfrm_8195 {
+ u32 info_0;
+ u32 info_1;
+} __packed;
+
+struct mdp_fg_data_8195 {
+ u32 ctrl_0;
+ u32 ck_en;
+ struct mdp_fg_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_hdr_subfrm_8195 {
+ u32 win_size;
+ u32 src;
+ u32 clip_ofst0;
+ u32 clip_ofst1;
+ u32 hist_ctrl_0;
+ u32 hist_ctrl_1;
+ u32 hdr_top;
+ u32 hist_addr;
+} __packed;
+
+struct mdp_hdr_data_8195 {
+ u32 top;
+ u32 relay;
+ struct mdp_hdr_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_aal_subfrm_8195 {
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+} __packed;
+
+struct mdp_aal_data_8195 {
+ u32 cfg_main;
+ u32 cfg;
+ struct mdp_aal_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_rsz_subfrm_8195 {
+ u32 control2;
+ u32 src;
+ u32 clip;
+ u32 hdmirx_en;
+ u32 luma_h_int_ofst;
+ u32 luma_h_sub_ofst;
+ u32 luma_v_int_ofst;
+ u32 luma_v_sub_ofst;
+ u32 chroma_h_int_ofst;
+ u32 chroma_h_sub_ofst;
+ u32 rsz_switch;
+ u32 merge_cfg;
+} __packed;
+
+struct mdp_rsz_data_8195 {
+ u32 coeff_step_x;
+ u32 coeff_step_y;
+ u32 control1;
+ u32 control2;
+ u32 etc_control;
+ u32 prz_enable;
+ u32 ibse_softclip;
+ u32 tap_adapt;
+ u32 ibse_gaincontrol1;
+ u32 ibse_gaincontrol2;
+ u32 ibse_ylevel_1;
+ u32 ibse_ylevel_2;
+ u32 ibse_ylevel_3;
+ u32 ibse_ylevel_4;
+ u32 ibse_ylevel_5;
+ struct mdp_rsz_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_tdshp_subfrm_8195 {
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+ u32 hist_cfg_0;
+ u32 hist_cfg_1;
+} __packed;
+
+struct mdp_tdshp_data_8195 {
+ u32 cfg;
+ struct mdp_tdshp_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_color_subfrm_8195 {
+ u32 in_hsize;
+ u32 in_vsize;
+} __packed;
+
+struct mdp_color_data_8195 {
+ u32 start;
+ struct mdp_color_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_ovl_subfrm_8195 {
+ u32 L0_src_size;
+ u32 roi_size;
+} __packed;
+
+struct mdp_ovl_data_8195 {
+ u32 L0_con;
+ u32 src_con;
+ struct mdp_ovl_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_pad_subfrm_8195 {
+ u32 pic_size;
+} __packed;
+
+struct mdp_pad_data_8195 {
+ struct mdp_pad_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_tcc_subfrm_8195 {
+ u32 pic_size;
+} __packed;
+
+struct mdp_tcc_data_8195 {
+ struct mdp_tcc_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_wrot_subfrm_8195 {
+ u32 offset[IMG_MAX_PLANES];
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+ u32 main_buf;
+} __packed;
+
+struct mdp_wrot_data_8195 {
+ u32 iova[IMG_MAX_PLANES];
+ u32 control;
+ u32 stride[IMG_MAX_PLANES];
+ u32 mat_ctrl;
+ u32 fifo_test;
+ u32 filter;
+ u32 pre_ultra;
+ u32 framesize;
+ u32 afbc_yuvtrans;
+ u32 scan_10bit;
+ u32 pending_zero;
+ u32 bit_number;
+ u32 pvric;
+ u32 vpp02vpp1;
+ struct mdp_wrot_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct mdp_wdma_subfrm_8195 {
+ u32 offset[IMG_MAX_PLANES];
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+} __packed;
+
+struct mdp_wdma_data_8195 {
+ u32 wdma_cfg;
+ u32 iova[IMG_MAX_PLANES];
+ u32 w_in_byte;
+ u32 uv_stride;
+ struct mdp_wdma_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct isp_data_8195 {
+ u64 dl_flags; /* 1 << (enum mdp_comp_type) */
+ u32 smxi_iova[4];
+ u32 cq_idx;
+ u32 cq_iova;
+ u32 tpipe_iova[IMG_MAX_SUBFRAMES_8195];
+} __packed;
+
+struct img_compparam_8195 {
+ u32 type; /* enum mdp_comp_id */
+ u32 id; /* engine alias_id */
+ u32 input;
+ u32 outputs[IMG_MAX_HW_OUTPUTS];
+ u32 num_outputs;
+ struct img_comp_frame_8195 frame;
+ struct img_comp_subfrm_8195 subfrms[IMG_MAX_SUBFRAMES_8195];
+ u32 num_subfrms;
+ union {
+ struct mdp_rdma_data_8195 rdma;
+ struct mdp_fg_data_8195 fg;
+ struct mdp_hdr_data_8195 hdr;
+ struct mdp_aal_data_8195 aal;
+ struct mdp_rsz_data_8195 rsz;
+ struct mdp_tdshp_data_8195 tdshp;
+ struct mdp_color_data_8195 color;
+ struct mdp_ovl_data_8195 ovl;
+ struct mdp_pad_data_8195 pad;
+ struct mdp_tcc_data_8195 tcc;
+ struct mdp_wrot_data_8195 wrot;
+ struct mdp_wdma_data_8195 wdma;
+ struct isp_data_8195 isp;
+ };
+} __packed;
+
+struct img_config_8195 {
+ struct img_compparam_8195 components[IMG_MAX_COMPONENTS];
+ u32 num_components;
+ struct img_mmsys_ctrl ctrls[IMG_MAX_SUBFRAMES_8195];
+ u32 num_subfrms;
+} __packed;
+
+#endif /* __MDP_SM_MT8195_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h
index 22b8b9a10ef7..f83ac408306e 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h
@@ -10,6 +10,7 @@
#include <linux/err.h>
#include "mdp_sm_mt8183.h"
+#include "mdp_sm_mt8195.h"
#include "mtk-mdp3-type.h"
/* ISP-MDP generic input information */
@@ -115,6 +116,7 @@ struct img_frameparam {
/* Platform config indicator */
#define MT8183 8183
+#define MT8195 8195
#define CFG_CHECK(plat, p_id) ((plat) == (p_id))
@@ -137,12 +139,14 @@ struct img_frameparam {
struct img_config {
union {
struct img_config_8183 config_8183;
+ struct img_config_8195 config_8195;
};
} __packed;
struct img_compparam {
union {
struct img_compparam_8183 comp_8183;
+ struct img_compparam_8195 comp_8195;
};
} __packed;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h
index dee57cc4a954..49cdf45f6e59 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cfg.h
@@ -10,11 +10,13 @@
#include <linux/types.h>
extern const struct mtk_mdp_driver_data mt8183_mdp_driver_data;
+extern const struct mtk_mdp_driver_data mt8195_mdp_driver_data;
struct mdp_dev;
enum mtk_mdp_comp_id;
s32 mdp_cfg_get_id_inner(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id);
enum mtk_mdp_comp_id mdp_cfg_get_id_public(struct mdp_dev *mdp_dev, s32 id);
+bool mdp_cfg_comp_is_dummy(struct mdp_dev *mdp_dev, s32 inner_id);
#endif /* __MTK_MDP3_CFG_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index 6adac857a477..1d64bac34b90 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -6,6 +6,7 @@
#include <linux/mailbox_controller.h>
#include <linux/platform_device.h>
+#include "mtk-mdp3-cfg.h"
#include "mtk-mdp3-cmdq.h"
#include "mtk-mdp3-comp.h"
#include "mtk-mdp3-core.h"
@@ -39,85 +40,192 @@ static bool is_output_disabled(int p_id, const struct img_compparam *param, u32
num = CFG_COMP(MT8183, param, num_subfrms);
dis_output = CFG_COMP(MT8183, param, frame.output_disable);
dis_tile = CFG_COMP(MT8183, param, frame.output_disable);
+ } else if (CFG_CHECK(MT8195, p_id)) {
+ num = CFG_COMP(MT8195, param, num_subfrms);
+ dis_output = CFG_COMP(MT8195, param, frame.output_disable);
+ dis_tile = CFG_COMP(MT8195, param, frame.output_disable);
}
return (count < num) ? (dis_output || dis_tile) : true;
}
-static int mdp_path_subfrm_require(const struct mdp_path *path,
- struct mdp_cmdq_cmd *cmd,
- s32 *mutex_id, u32 count)
+static struct mtk_mutex *__get_mutex(const struct mdp_dev *mdp_dev,
+ const struct mdp_pipe_info *p)
{
- const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
- const struct mdp_comp_ctx *ctx;
- const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data;
- struct device *dev = &path->mdp_dev->pdev->dev;
- struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
- int id, index;
- u32 num_comp = 0;
+ return mdp_dev->mm_subsys[p->sub_id].mdp_mutex[p->mutex_id];
+}
- if (CFG_CHECK(MT8183, p_id))
- num_comp = CFG_GET(MT8183, path->config, num_components);
+static u8 __get_pp_num(enum mdp_stream_type type)
+{
+ switch (type) {
+ case MDP_STREAM_TYPE_DUAL_BITBLT:
+ return MDP_PP_USED_2;
+ default:
+ return MDP_PP_USED_1;
+ }
+}
- /* Decide which mutex to use based on the current pipeline */
- switch (path->comps[0].comp->public_id) {
+static enum mdp_pipe_id __get_pipe(const struct mdp_dev *mdp_dev,
+ enum mtk_mdp_comp_id id)
+{
+ enum mdp_pipe_id pipe_id;
+
+ switch (id) {
case MDP_COMP_RDMA0:
- index = MDP_PIPE_RDMA0;
+ pipe_id = MDP_PIPE_RDMA0;
break;
case MDP_COMP_ISP_IMGI:
- index = MDP_PIPE_IMGI;
+ pipe_id = MDP_PIPE_IMGI;
break;
case MDP_COMP_WPEI:
- index = MDP_PIPE_WPEI;
+ pipe_id = MDP_PIPE_WPEI;
break;
case MDP_COMP_WPEI2:
- index = MDP_PIPE_WPEI2;
+ pipe_id = MDP_PIPE_WPEI2;
+ break;
+ case MDP_COMP_RDMA1:
+ pipe_id = MDP_PIPE_RDMA1;
+ break;
+ case MDP_COMP_RDMA2:
+ pipe_id = MDP_PIPE_RDMA2;
+ break;
+ case MDP_COMP_RDMA3:
+ pipe_id = MDP_PIPE_RDMA3;
break;
default:
- dev_err(dev, "Unknown pipeline and no mutex is assigned");
- return -EINVAL;
+ /* Avoid exceptions when operating MUTEX */
+ pipe_id = MDP_PIPE_RDMA0;
+ dev_err(&mdp_dev->pdev->dev, "Unknown pipeline id %d", id);
+ break;
+ }
+
+ return pipe_id;
+}
+
+static struct img_config *__get_config_offset(struct mdp_dev *mdp,
+ struct mdp_cmdq_param *param,
+ u8 pp_idx)
+{
+ const int p_id = mdp->mdp_data->mdp_plat_id;
+ struct device *dev = &mdp->pdev->dev;
+ void *cfg_c, *cfg_n;
+ long bound = mdp->vpu.config_size;
+
+ if (pp_idx >= mdp->mdp_data->pp_used)
+ goto err_param;
+
+ if (CFG_CHECK(MT8183, p_id))
+ cfg_c = CFG_OFST(MT8183, param->config, pp_idx);
+ else if (CFG_CHECK(MT8195, p_id))
+ cfg_c = CFG_OFST(MT8195, param->config, pp_idx);
+ else
+ goto err_param;
+
+ if (CFG_CHECK(MT8183, p_id))
+ cfg_n = CFG_OFST(MT8183, param->config, pp_idx + 1);
+ else if (CFG_CHECK(MT8195, p_id))
+ cfg_n = CFG_OFST(MT8195, param->config, pp_idx + 1);
+ else
+ goto err_param;
+
+ if ((long)cfg_n - (long)mdp->vpu.config > bound) {
+ dev_err(dev, "config offset %ld OOB %ld\n", (long)cfg_n, bound);
+ cfg_c = ERR_PTR(-EFAULT);
}
- *mutex_id = data->pipe_info[index].mutex_id;
+
+ return (struct img_config *)cfg_c;
+
+err_param:
+ cfg_c = ERR_PTR(-EINVAL);
+ return (struct img_config *)cfg_c;
+}
+
+static int mdp_path_subfrm_require(const struct mdp_path *path,
+ struct mdp_cmdq_cmd *cmd,
+ struct mdp_pipe_info *p, u32 count)
+{
+ const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
+ const struct mdp_comp_ctx *ctx;
+ const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data;
+ struct mtk_mutex *mutex;
+ int id, index;
+ u32 num_comp = 0;
+
+ if (CFG_CHECK(MT8183, p_id))
+ num_comp = CFG_GET(MT8183, path->config, num_components);
+ else if (CFG_CHECK(MT8195, p_id))
+ num_comp = CFG_GET(MT8195, path->config, num_components);
+
+ /* Decide which mutex to use based on the current pipeline */
+ index = __get_pipe(path->mdp_dev, path->comps[0].comp->public_id);
+ memcpy(p, &data->pipe_info[index], sizeof(struct mdp_pipe_info));
+ mutex = __get_mutex(path->mdp_dev, p);
/* Set mutex mod */
for (index = 0; index < num_comp; index++) {
+ s32 inner_id = MDP_COMP_NONE;
+ const u32 *mutex_idx;
+ const struct mdp_comp_blend *b;
+
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
+
ctx = &path->comps[index];
if (is_output_disabled(p_id, ctx->param, count))
continue;
+
+ mutex_idx = data->mdp_mutex_table_idx;
id = ctx->comp->public_id;
- mtk_mutex_write_mod(mutex[*mutex_id],
- data->mdp_mutex_table_idx[id], false);
+ mtk_mutex_write_mod(mutex, mutex_idx[id], false);
+
+ b = &data->comp_data[id].blend;
+ if (b && b->aid_mod)
+ mtk_mutex_write_mod(mutex, mutex_idx[b->b_id], false);
}
- mtk_mutex_write_sof(mutex[*mutex_id],
- MUTEX_SOF_IDX_SINGLE_MODE);
+ mtk_mutex_write_sof(mutex, MUTEX_SOF_IDX_SINGLE_MODE);
return 0;
}
static int mdp_path_subfrm_run(const struct mdp_path *path,
struct mdp_cmdq_cmd *cmd,
- s32 *mutex_id, u32 count)
+ struct mdp_pipe_info *p, u32 count)
{
const int p_id = path->mdp_dev->mdp_data->mdp_plat_id;
const struct mdp_comp_ctx *ctx;
struct device *dev = &path->mdp_dev->pdev->dev;
- struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
+ struct mtk_mutex *mutex;
int index;
u32 num_comp = 0;
s32 event;
+ s32 inner_id = MDP_COMP_NONE;
- if (-1 == *mutex_id) {
+ if (-1 == p->mutex_id) {
dev_err(dev, "Incorrect mutex id");
return -EINVAL;
}
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
+ else if (CFG_CHECK(MT8195, p_id))
+ num_comp = CFG_GET(MT8195, path->config, num_components);
/* Wait WROT SRAM shared to DISP RDMA */
/* Clear SOF event for each engine */
for (index = 0; index < num_comp; index++) {
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
ctx = &path->comps[index];
if (is_output_disabled(p_id, ctx->param, count))
continue;
@@ -127,10 +235,18 @@ static int mdp_path_subfrm_run(const struct mdp_path *path,
}
/* Enable the mutex */
- mtk_mutex_enable_by_cmdq(mutex[*mutex_id], (void *)&cmd->pkt);
+ mutex = __get_mutex(path->mdp_dev, p);
+ mtk_mutex_enable_by_cmdq(mutex, (void *)&cmd->pkt);
/* Wait SOF events and clear mutex modules (optional) */
for (index = 0; index < num_comp; index++) {
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
ctx = &path->comps[index];
if (is_output_disabled(p_id, ctx->param, count))
continue;
@@ -151,13 +267,26 @@ static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
+ else if (CFG_CHECK(MT8195, p_id))
+ num_comp = CFG_GET(MT8195, path->config, num_components);
if (num_comp < 1)
return -EINVAL;
for (index = 0; index < num_comp; index++) {
+ s32 inner_id = MDP_COMP_NONE;
+
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
if (CFG_CHECK(MT8183, p_id))
param = (void *)CFG_ADDR(MT8183, path->config, components[index]);
+ else if (CFG_CHECK(MT8195, p_id))
+ param = (void *)CFG_ADDR(MT8195, path->config, components[index]);
ret = mdp_comp_ctx_config(mdp, &path->comps[index],
param, path->param);
if (ret)
@@ -174,18 +303,23 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
const struct img_mmsys_ctrl *ctrl = NULL;
const struct img_mux *set;
struct mdp_comp_ctx *ctx;
- s32 mutex_id;
+ struct mdp_pipe_info pipe;
int index, ret;
u32 num_comp = 0;
+ s32 inner_id = MDP_COMP_NONE;
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
+ else if (CFG_CHECK(MT8195, p_id))
+ num_comp = CFG_GET(MT8195, path->config, num_components);
if (CFG_CHECK(MT8183, p_id))
ctrl = CFG_ADDR(MT8183, path->config, ctrls[count]);
+ else if (CFG_CHECK(MT8195, p_id))
+ ctrl = CFG_ADDR(MT8195, path->config, ctrls[count]);
/* Acquire components */
- ret = mdp_path_subfrm_require(path, cmd, &mutex_id, count);
+ ret = mdp_path_subfrm_require(path, cmd, &pipe, count);
if (ret)
return ret;
/* Enable mux settings */
@@ -196,6 +330,13 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
}
/* Config sub-frame information */
for (index = (num_comp - 1); index >= 0; index--) {
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
ctx = &path->comps[index];
if (is_output_disabled(p_id, ctx->param, count))
continue;
@@ -204,11 +345,18 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
return ret;
}
/* Run components */
- ret = mdp_path_subfrm_run(path, cmd, &mutex_id, count);
+ ret = mdp_path_subfrm_run(path, cmd, &pipe, count);
if (ret)
return ret;
/* Wait components done */
for (index = 0; index < num_comp; index++) {
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
ctx = &path->comps[index];
if (is_output_disabled(p_id, ctx->param, count))
continue;
@@ -218,6 +366,13 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
}
/* Advance to the next sub-frame */
for (index = 0; index < num_comp; index++) {
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
ctx = &path->comps[index];
ret = call_op(ctx, advance_subfrm, cmd, count);
if (ret)
@@ -241,16 +396,28 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
int index, count, ret;
u32 num_comp = 0;
u32 num_sub = 0;
+ s32 inner_id = MDP_COMP_NONE;
if (CFG_CHECK(MT8183, p_id))
num_comp = CFG_GET(MT8183, path->config, num_components);
+ else if (CFG_CHECK(MT8195, p_id))
+ num_comp = CFG_GET(MT8195, path->config, num_components);
if (CFG_CHECK(MT8183, p_id))
num_sub = CFG_GET(MT8183, path->config, num_subfrms);
+ else if (CFG_CHECK(MT8195, p_id))
+ num_sub = CFG_GET(MT8195, path->config, num_subfrms);
/* Config path frame */
/* Reset components */
for (index = 0; index < num_comp; index++) {
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
ctx = &path->comps[index];
ret = call_op(ctx, init_comp, cmd);
if (ret)
@@ -263,7 +430,17 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
ctx = &path->comps[index];
if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
+
+ if (CFG_CHECK(MT8183, p_id))
out = CFG_COMP(MT8183, ctx->param, outputs[0]);
+ else if (CFG_CHECK(MT8195, p_id))
+ out = CFG_COMP(MT8195, ctx->param, outputs[0]);
compose = path->composes[out];
ret = call_op(ctx, config_frame, cmd, compose);
@@ -279,6 +456,13 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
}
/* Post processing information */
for (index = 0; index < num_comp; index++) {
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[index].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[index].type);
+
+ if (mdp_cfg_comp_is_dummy(path->mdp_dev, inner_id))
+ continue;
ctx = &path->comps[index];
ret = call_op(ctx, post_process, cmd);
if (ret)
@@ -328,18 +512,31 @@ static void mdp_auto_release_work(struct work_struct *work)
{
struct mdp_cmdq_cmd *cmd;
struct mdp_dev *mdp;
- int id;
+ struct mtk_mutex *mutex;
+ enum mdp_pipe_id pipe_id;
cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work);
mdp = cmd->mdp;
- id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
- mtk_mutex_unprepare(mdp->mdp_mutex[id]);
+ pipe_id = __get_pipe(mdp, cmd->comps[0].public_id);
+ mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]);
+ mtk_mutex_unprepare(mutex);
mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
cmd->num_comps);
- atomic_dec(&mdp->job_count);
- wake_up(&mdp->callback_wq);
+ if (atomic_dec_and_test(&mdp->job_count)) {
+ if (cmd->mdp_ctx)
+ mdp_m2m_job_finish(cmd->mdp_ctx);
+
+ if (cmd->user_cmdq_cb) {
+ struct cmdq_cb_data user_cb_data;
+
+ user_cb_data.sta = cmd->data->sta;
+ user_cb_data.pkt = cmd->data->pkt;
+ cmd->user_cmdq_cb(user_cb_data);
+ }
+ wake_up(&mdp->callback_wq);
+ }
mdp_cmdq_pkt_destroy(&cmd->pkt);
kfree(cmd->comps);
@@ -354,7 +551,7 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
struct cmdq_cb_data *data;
struct mdp_dev *mdp;
struct device *dev;
- int id;
+ enum mdp_pipe_id pipe_id;
if (!mssg) {
pr_info("%s:no callback data\n", __func__);
@@ -363,30 +560,23 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
data = (struct cmdq_cb_data *)mssg;
cmd = container_of(data->pkt, struct mdp_cmdq_cmd, pkt);
+ cmd->data = data;
mdp = cmd->mdp;
dev = &mdp->pdev->dev;
- if (cmd->mdp_ctx)
- mdp_m2m_job_finish(cmd->mdp_ctx);
-
- if (cmd->user_cmdq_cb) {
- struct cmdq_cb_data user_cb_data;
-
- user_cb_data.sta = data->sta;
- user_cb_data.pkt = data->pkt;
- cmd->user_cmdq_cb(user_cb_data);
- }
-
INIT_WORK(&cmd->auto_release_work, mdp_auto_release_work);
if (!queue_work(mdp->clock_wq, &cmd->auto_release_work)) {
+ struct mtk_mutex *mutex;
+
dev_err(dev, "%s:queue_work fail!\n", __func__);
- id = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
- mtk_mutex_unprepare(mdp->mdp_mutex[id]);
+ pipe_id = __get_pipe(mdp, cmd->comps[0].public_id);
+ mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]);
+ mtk_mutex_unprepare(mutex);
mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
cmd->num_comps);
- atomic_dec(&mdp->job_count);
- wake_up(&mdp->callback_wq);
+ if (atomic_dec_and_test(&mdp->job_count))
+ wake_up(&mdp->callback_wq);
mdp_cmdq_pkt_destroy(&cmd->pkt);
kfree(cmd->comps);
@@ -396,34 +586,48 @@ static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
}
}
-int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
+static struct mdp_cmdq_cmd *mdp_cmdq_prepare(struct mdp_dev *mdp,
+ struct mdp_cmdq_param *param,
+ u8 pp_idx)
{
struct mdp_path *path = NULL;
struct mdp_cmdq_cmd *cmd = NULL;
struct mdp_comp *comps = NULL;
struct device *dev = &mdp->pdev->dev;
const int p_id = mdp->mdp_data->mdp_plat_id;
- int i, ret;
- u32 num_comp = 0;
-
- atomic_inc(&mdp->job_count);
- if (atomic_read(&mdp->suspended)) {
- atomic_dec(&mdp->job_count);
- return -ECANCELED;
+ struct img_config *config;
+ struct mtk_mutex *mutex = NULL;
+ enum mdp_pipe_id pipe_id;
+ int i, ret = -ECANCELED;
+ u32 num_comp;
+
+ config = __get_config_offset(mdp, param, pp_idx);
+ if (IS_ERR(config)) {
+ ret = PTR_ERR(config);
+ goto err_uninit;
}
+ if (CFG_CHECK(MT8183, p_id))
+ num_comp = CFG_GET(MT8183, config, num_components);
+ else if (CFG_CHECK(MT8195, p_id))
+ num_comp = CFG_GET(MT8195, config, num_components);
+ else
+ goto err_uninit;
+
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd) {
ret = -ENOMEM;
- goto err_cancel_job;
+ goto err_uninit;
}
- ret = mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K);
+ ret = mdp_cmdq_pkt_create(mdp->cmdq_clt[pp_idx], &cmd->pkt, SZ_16K);
if (ret)
goto err_free_cmd;
if (CFG_CHECK(MT8183, p_id)) {
num_comp = CFG_GET(MT8183, param->config, num_components);
+ } else if (CFG_CHECK(MT8195, p_id)) {
+ num_comp = CFG_GET(MT8195, param->config, num_components);
} else {
ret = -EINVAL;
goto err_destroy_pkt;
@@ -440,15 +644,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
goto err_free_comps;
}
- i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
- ret = mtk_mutex_prepare(mdp->mdp_mutex[i]);
- if (ret) {
- dev_err(dev, "Fail to enable mutex clk\n");
- goto err_free_path;
- }
-
path->mdp_dev = mdp;
- path->config = param->config;
+ path->config = config;
path->param = param->param;
for (i = 0; i < param->param->num_outputs; i++) {
path->bounds[i].left = 0;
@@ -462,22 +659,40 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
}
ret = mdp_path_ctx_init(mdp, path);
if (ret) {
- dev_err(dev, "mdp_path_ctx_init error\n");
+ dev_err(dev, "mdp_path_ctx_init error %d\n", pp_idx);
+ goto err_free_path;
+ }
+
+ pipe_id = __get_pipe(mdp, path->comps[0].comp->public_id);
+ mutex = __get_mutex(mdp, &mdp->mdp_data->pipe_info[pipe_id]);
+ ret = mtk_mutex_prepare(mutex);
+ if (ret) {
+ dev_err(dev, "Fail to enable mutex %d clk\n", pp_idx);
goto err_free_path;
}
ret = mdp_path_config(mdp, cmd, path);
if (ret) {
- dev_err(dev, "mdp_path_config error\n");
+ dev_err(dev, "mdp_path_config error %d\n", pp_idx);
goto err_free_path;
}
cmdq_pkt_finalize(&cmd->pkt);
- for (i = 0; i < num_comp; i++)
+ for (i = 0; i < num_comp; i++) {
+ s32 inner_id = MDP_COMP_NONE;
+
+ if (CFG_CHECK(MT8183, p_id))
+ inner_id = CFG_GET(MT8183, path->config, components[i].type);
+ else if (CFG_CHECK(MT8195, p_id))
+ inner_id = CFG_GET(MT8195, path->config, components[i].type);
+
+ if (mdp_cfg_comp_is_dummy(mdp, inner_id))
+ continue;
memcpy(&comps[i], path->comps[i].comp,
sizeof(struct mdp_comp));
+ }
- mdp->cmdq_clt->client.rx_callback = mdp_handle_cmdq_callback;
+ mdp->cmdq_clt[pp_idx]->client.rx_callback = mdp_handle_cmdq_callback;
cmd->mdp = mdp;
cmd->user_cmdq_cb = param->cmdq_cb;
cmd->user_cb_data = param->cb_data;
@@ -485,29 +700,12 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
cmd->num_comps = num_comp;
cmd->mdp_ctx = param->mdp_ctx;
- ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps);
- if (ret)
- goto err_free_path;
-
- dma_sync_single_for_device(mdp->cmdq_clt->chan->mbox->dev,
- cmd->pkt.pa_base, cmd->pkt.cmd_buf_size,
- DMA_TO_DEVICE);
- ret = mbox_send_message(mdp->cmdq_clt->chan, &cmd->pkt);
- if (ret < 0) {
- dev_err(dev, "mbox send message fail %d!\n", ret);
- goto err_clock_off;
- }
- mbox_client_txdone(mdp->cmdq_clt->chan, 0);
-
kfree(path);
- return 0;
+ return cmd;
-err_clock_off:
- mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
- cmd->num_comps);
err_free_path:
- i = mdp->mdp_data->pipe_info[MDP_PIPE_RDMA0].mutex_id;
- mtk_mutex_unprepare(mdp->mdp_mutex[i]);
+ if (mutex)
+ mtk_mutex_unprepare(mutex);
kfree(path);
err_free_comps:
kfree(comps);
@@ -515,8 +713,58 @@ err_destroy_pkt:
mdp_cmdq_pkt_destroy(&cmd->pkt);
err_free_cmd:
kfree(cmd);
+err_uninit:
+ return ERR_PTR(ret);
+}
+
+int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
+{
+ struct mdp_cmdq_cmd *cmd[MDP_PP_MAX] = {NULL};
+ struct device *dev = &mdp->pdev->dev;
+ int i, ret;
+ u8 pp_used = __get_pp_num(param->param->type);
+
+ atomic_set(&mdp->job_count, pp_used);
+ if (atomic_read(&mdp->suspended)) {
+ atomic_set(&mdp->job_count, 0);
+ return -ECANCELED;
+ }
+
+ for (i = 0; i < pp_used; i++) {
+ cmd[i] = mdp_cmdq_prepare(mdp, param, i);
+ if (IS_ERR_OR_NULL(cmd[i])) {
+ ret = PTR_ERR(cmd[i]);
+ goto err_cancel_job;
+ }
+ }
+
+ for (i = 0; i < pp_used; i++) {
+ ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd[i]->comps, cmd[i]->num_comps);
+ if (ret)
+ goto err_clock_off;
+ }
+
+ for (i = 0; i < pp_used; i++) {
+ dma_sync_single_for_device(mdp->cmdq_clt[i]->chan->mbox->dev,
+ cmd[i]->pkt.pa_base, cmd[i]->pkt.cmd_buf_size,
+ DMA_TO_DEVICE);
+
+ ret = mbox_send_message(mdp->cmdq_clt[i]->chan, &cmd[i]->pkt);
+ if (ret < 0) {
+ dev_err(dev, "mbox send message fail %d!\n", ret);
+ i = pp_used;
+ goto err_clock_off;
+ }
+ mbox_client_txdone(mdp->cmdq_clt[i]->chan, 0);
+ }
+ return 0;
+
+err_clock_off:
+ while (--i >= 0)
+ mdp_comp_clocks_off(&mdp->pdev->dev, cmd[i]->comps,
+ cmd[i]->num_comps);
err_cancel_job:
- atomic_dec(&mdp->job_count);
+ atomic_set(&mdp->job_count, 0);
return ret;
}
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h
index 43475b862ddb..53a30ad7e0b0 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h
@@ -29,6 +29,7 @@ struct mdp_cmdq_cmd {
struct cmdq_pkt pkt;
s32 *event;
struct mdp_dev *mdp;
+ struct cmdq_cb_data *data;
void (*user_cmdq_cb)(struct cmdq_cb_data data);
void *user_cb_data;
struct mdp_comp *comps;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
index 575c8d52acd1..8f62fb167156 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
@@ -13,11 +13,19 @@
#include "mtk-mdp3-core.h"
#include "mtk-mdp3-regs.h"
-#include "mdp_reg_rdma.h"
+#include "mdp_reg_aal.h"
#include "mdp_reg_ccorr.h"
+#include "mdp_reg_color.h"
+#include "mdp_reg_fg.h"
+#include "mdp_reg_hdr.h"
+#include "mdp_reg_merge.h"
+#include "mdp_reg_ovl.h"
+#include "mdp_reg_pad.h"
+#include "mdp_reg_rdma.h"
#include "mdp_reg_rsz.h"
-#include "mdp_reg_wrot.h"
+#include "mdp_reg_tdshp.h"
#include "mdp_reg_wdma.h"
+#include "mdp_reg_wrot.h"
static u32 mdp_comp_alias_id[MDP_COMP_TYPE_COUNT];
static int p_id;
@@ -85,6 +93,7 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx,
bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
phys_addr_t base = ctx->comp->reg_base;
u8 subsys_id = ctx->comp->subsys_id;
+ u32 rdma_con_mask = 0;
u32 reg = 0;
if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
@@ -105,6 +114,8 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx,
/* Setup source frame info */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.src_ctrl);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.src_ctrl);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg,
0x03C8FE0F);
@@ -113,69 +124,163 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx,
/* Setup source buffer base */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_y);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_y);
MM_REG_WRITE(cmd, subsys_id,
base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y,
reg, 0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_c);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_c);
MM_REG_WRITE(cmd, subsys_id,
base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C,
reg, 0xFFFFFFFF);
+
/* Set 10bit source frame pitch */
if (block10bit) {
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd_in_pxl);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd_in_pxl);
MM_REG_WRITE(cmd, subsys_id,
base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL,
reg, 0x001FFFFF);
}
}
- if (CFG_CHECK(MT8183, p_id))
+ if (CFG_CHECK(MT8183, p_id)) {
reg = CFG_COMP(MT8183, ctx->param, rdma.control);
+ rdma_con_mask = 0x1110;
+ } else if (CFG_CHECK(MT8195, p_id)) {
+ reg = CFG_COMP(MT8195, ctx->param, rdma.control);
+ rdma_con_mask = 0x1130;
+ }
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, reg,
- 0x1110);
+ rdma_con_mask);
+
/* Setup source buffer base */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.iova[0]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.iova[0]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg,
0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.iova[1]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.iova[1]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg,
0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.iova[2]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.iova[2]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg,
0xFFFFFFFF);
+
/* Setup source buffer end */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[0]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[0]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0,
reg, 0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[1]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[1]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1,
reg, 0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[2]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[2]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2,
reg, 0xFFFFFFFF);
+
/* Setup source frame pitch */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
reg, 0x001FFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.sf_bkgd);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.sf_bkgd);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE,
reg, 0x001FFFFF);
+
/* Setup color transform */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.transform);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.transform);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0,
reg, 0x0F110000);
+ if (!mdp_cfg || !mdp_cfg->rdma_esl_setting)
+ goto rdma_config_done;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_0,
+ reg, 0x0FFF00FF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_0,
+ reg, 0x3FFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_0,
+ reg, 0x3FFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con1);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_1,
+ reg, 0x0F7F007F);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con1);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_1,
+ reg, 0x3FFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con1);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_1,
+ reg, 0x3FFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con2);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_2,
+ reg, 0x0F3F003F);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con2);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_2,
+ reg, 0x3FFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con2);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_2,
+ reg, 0x3FFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con3);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_3,
+ reg, 0x0F3F003F);
+
+rdma_config_done:
return 0;
}
@@ -197,6 +302,8 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
/* Set Y pixel offset */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[0]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[0]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0,
reg, 0xFFFFFFFF);
@@ -205,6 +312,8 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
if (mdp_cfg->rdma_support_10bit && block10bit && en_ufo) {
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset_0_p);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset_0_p);
MM_REG_WRITE(cmd, subsys_id, base,
MDP_RDMA_SRC_OFFSET_0_P,
reg, 0xFFFFFFFF);
@@ -214,32 +323,49 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
/* Set U pixel offset */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[1]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[1]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1,
reg, 0xFFFFFFFF);
+
/* Set V pixel offset */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[2]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[2]);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2,
reg, 0xFFFFFFFF);
+
/* Set source size */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].src);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].src);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg,
0x1FFF1FFF);
+
/* Set target size */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE,
reg, 0x1FFF1FFF);
+
/* Set crop offset */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip_ofst);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip_ofst);
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1,
reg, 0x003F001F);
if (CFG_CHECK(MT8183, p_id)) {
csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
+ } else if (CFG_CHECK(MT8195, p_id)) {
+ csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left);
+ csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right);
}
if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only)
if ((csf_r - csf_l + 1) > 320)
@@ -251,14 +377,20 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
{
+ const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
phys_addr_t base = ctx->comp->reg_base;
u8 subsys_id = ctx->comp->subsys_id;
- if (ctx->comp->alias_id == 0)
- MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
- else
- dev_err(dev, "Do not support RDMA1_DONE event\n");
+ if (!mdp_cfg)
+ return -EINVAL;
+
+ if (ctx->comp->alias_id >= mdp_cfg->rdma_event_num) {
+ dev_err(dev, "Invalid RDMA event %d\n", ctx->comp->alias_id);
+ return -EINVAL;
+ }
+
+ MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
/* Disable RDMA */
MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
@@ -283,6 +415,14 @@ static int init_rsz(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16));
/* Enable RSZ */
MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0));
+
+ if (CFG_CHECK(MT8195, p_id)) {
+ struct device *dev;
+
+ dev = ctx->comp->mdp_dev->mm_subsys[MDP_MM_SUBSYS_1].mmsys;
+ mtk_mmsys_vpp_rsz_dcm_config(dev, true, NULL);
+ }
+
return 0;
}
@@ -290,13 +430,19 @@ static int config_rsz_frame(struct mdp_comp_ctx *ctx,
struct mdp_cmdq_cmd *cmd,
const struct v4l2_rect *compose)
{
+ const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
phys_addr_t base = ctx->comp->reg_base;
u8 subsys_id = ctx->comp->subsys_id;
bool bypass = FALSE;
u32 reg = 0;
+ if (mdp_cfg && mdp_cfg->rsz_etc_control)
+ MM_REG_WRITE(cmd, subsys_id, base, RSZ_ETC_CONTROL, 0x0, 0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
bypass = CFG_COMP(MT8183, ctx->param, frame.bypass);
+ else if (CFG_CHECK(MT8195, p_id))
+ bypass = CFG_COMP(MT8195, ctx->param, frame.bypass);
if (bypass) {
/* Disable RSZ */
@@ -306,20 +452,32 @@ static int config_rsz_frame(struct mdp_comp_ctx *ctx,
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rsz.control1);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.control1);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, reg,
0x03FFFDF3);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rsz.control2);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.control2);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
0x0FFFC290);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_x);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_x);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP,
reg, 0x007FFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_y);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_y);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP,
reg, 0x007FFFFF);
+
return 0;
}
@@ -331,19 +489,28 @@ static int config_rsz_subfrm(struct mdp_comp_ctx *ctx,
u8 subsys_id = ctx->comp->subsys_id;
u32 csf_l = 0, csf_r = 0;
u32 reg = 0;
+ u32 id;
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].control2);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].control2);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg,
0x00003800);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].src);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].src);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg,
0xFFFFFFFF);
if (CFG_CHECK(MT8183, p_id)) {
csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
+ } else if (CFG_CHECK(MT8195, p_id)) {
+ csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left);
+ csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right);
}
if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample)
if ((csf_r - csf_l + 1) <= 16)
@@ -352,37 +519,99 @@ static int config_rsz_subfrm(struct mdp_comp_ctx *ctx,
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET,
reg, 0xFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left_subpix);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left_subpix);
MM_REG_WRITE(cmd, subsys_id,
base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET,
reg, 0x1FFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET,
reg, 0xFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top_subpix);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top_subpix);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET,
reg, 0x1FFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left);
MM_REG_WRITE(cmd, subsys_id,
base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET,
reg, 0xFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left_subpix);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left_subpix);
MM_REG_WRITE(cmd, subsys_id,
base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET,
reg, 0x1FFFFF);
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].clip);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].clip);
MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg,
0xFFFFFFFF);
+ if (CFG_CHECK(MT8195, p_id)) {
+ struct device *dev;
+ struct mdp_comp *merge;
+ const struct mtk_mdp_driver_data *data = ctx->comp->mdp_dev->mdp_data;
+ enum mtk_mdp_comp_id public_id = ctx->comp->public_id;
+
+ switch (public_id) {
+ case MDP_COMP_RSZ2:
+ merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE2];
+ break;
+ case MDP_COMP_RSZ3:
+ merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE3];
+ break;
+ default:
+ goto rsz_subfrm_done;
+ }
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].rsz_switch);
+
+ id = data->comp_data[public_id].match.alias_id;
+ dev = ctx->comp->mdp_dev->mm_subsys[MDP_MM_SUBSYS_1].mmsys;
+ mtk_mmsys_vpp_rsz_merge_config(dev, id, reg, NULL);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].merge_cfg);
+ MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+ MDP_MERGE_CFG_0, reg, 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+ MDP_MERGE_CFG_4, reg, 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+ MDP_MERGE_CFG_24, reg, 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+ MDP_MERGE_CFG_25, reg, 0xFFFFFFFF);
+
+ /* Bypass mode */
+ MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+ MDP_MERGE_CFG_12, BIT(0), 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+ MDP_MERGE_ENABLE, BIT(0), 0xFFFFFFFF);
+ }
+
+rsz_subfrm_done:
return 0;
}
@@ -399,6 +628,9 @@ static int advance_rsz_subfrm(struct mdp_comp_ctx *ctx,
if (CFG_CHECK(MT8183, p_id)) {
csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left);
csf_r = CFG_COMP(MT8183, ctx->param, subfrms[index].in.right);
+ } else if (CFG_CHECK(MT8195, p_id)) {
+ csf_l = CFG_COMP(MT8195, ctx->param, subfrms[index].in.left);
+ csf_r = CFG_COMP(MT8195, ctx->param, subfrms[index].in.right);
}
if ((csf_r - csf_l + 1) <= 16)
@@ -425,6 +657,11 @@ static int init_wrot(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
/* Reset WROT */
MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0));
MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0));
+
+ /* Reset setting */
+ if (CFG_CHECK(MT8195, p_id))
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, 0x0, 0xFFFFFFFF);
+
MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0));
MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0));
return 0;
@@ -442,57 +679,118 @@ static int config_wrot_frame(struct mdp_comp_ctx *ctx,
/* Write frame base address */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.iova[0]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.iova[0]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg,
0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.iova[1]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.iova[1]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg,
0xFFFFFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.iova[2]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.iova[2]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg,
0xFFFFFFFF);
+
+ if (mdp_cfg && mdp_cfg->wrot_support_10bit) {
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.scan_10bit);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_SCAN_10BIT,
+ reg, 0x0000000F);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.pending_zero);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_PENDING_ZERO,
+ reg, 0x04000000);
+ }
+
+ if (CFG_CHECK(MT8195, p_id)) {
+ reg = CFG_COMP(MT8195, ctx->param, wrot.bit_number);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL_2,
+ reg, 0x00000007);
+ }
+
/* Write frame related registers */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.control);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.control);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, reg,
0xF131510F);
+
+ /* Write pre-ultra threshold */
+ if (CFG_CHECK(MT8195, p_id)) {
+ reg = CFG_COMP(MT8195, ctx->param, wrot.pre_ultra);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_DMA_PREULTRA, reg,
+ 0x00FFFFFF);
+ }
+
/* Write frame Y pitch */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.stride[0]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.stride[0]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, reg,
0x0000FFFF);
+
/* Write frame UV pitch */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.stride[1]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.stride[1]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, reg,
0xFFFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.stride[2]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.stride[2]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, reg,
0xFFFF);
+
/* Write matrix control */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.mat_ctrl);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.mat_ctrl);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3);
/* Set the fixed ALPHA as 0xFF */
MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000,
0xFF000000);
+
/* Set VIDO_EOL_SEL */
MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31));
+
/* Set VIDO_FIFO_TEST */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.fifo_test);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.fifo_test);
+
if (reg != 0)
MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST,
reg, 0xFFF);
+
/* Filter enable */
if (mdp_cfg && mdp_cfg->wrot_filter_constraint) {
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.filter);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.filter);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
reg, 0x77);
+
+ /* Turn off WROT DMA DCM */
+ if (CFG_CHECK(MT8195, p_id))
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN,
+ (0x1 << 23) + (0x1 << 20), 0x900000);
}
return 0;
@@ -508,35 +806,54 @@ static int config_wrot_subfrm(struct mdp_comp_ctx *ctx,
/* Write Y pixel offset */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[0]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[0]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR,
reg, 0x0FFFFFFF);
+
/* Write U pixel offset */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[1]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[1]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C,
reg, 0x0FFFFFFF);
+
/* Write V pixel offset */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[2]);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[2]);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V,
reg, 0x0FFFFFFF);
+
/* Write source size */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].src);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].src);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, reg,
0x1FFF1FFF);
+
/* Write target size */
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, reg,
0x1FFF1FFF);
+
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip_ofst);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip_ofst);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, reg,
0x1FFF1FFF);
if (CFG_CHECK(MT8183, p_id))
reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].main_buf);
+ else if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].main_buf);
MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
reg, 0x1FFF7F00);
@@ -553,10 +870,15 @@ static int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
phys_addr_t base = ctx->comp->reg_base;
u8 subsys_id = ctx->comp->subsys_id;
- if (ctx->comp->alias_id == 0)
- MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
- else
- dev_err(dev, "Do not support WROT1_DONE event\n");
+ if (!mdp_cfg)
+ return -EINVAL;
+
+ if (ctx->comp->alias_id >= mdp_cfg->wrot_event_num) {
+ dev_err(dev, "Invalid WROT event %d!\n", ctx->comp->alias_id);
+ return -EINVAL;
+ }
+
+ MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0,
@@ -697,6 +1019,171 @@ static const struct mdp_comp_ops wdma_ops = {
.wait_comp_event = wait_wdma_event,
};
+static int reset_luma_hist(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 hist_num, i;
+
+ if (!mdp_cfg)
+ return -EINVAL;
+
+ hist_num = mdp_cfg->tdshp_hist_num;
+
+ /* Reset histogram */
+ for (i = 0; i <= hist_num; i++)
+ MM_REG_WRITE_MASK(cmd, subsys_id, base,
+ (MDP_LUMA_HIST_INIT + (i << 2)),
+ 0, 0xFFFFFFFF);
+
+ if (mdp_cfg->tdshp_constrain)
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_DC_TWO_D_W1_RESULT_INIT, 0, 0xFFFFFFFF);
+
+ if (mdp_cfg->tdshp_contour)
+ for (i = 0; i < hist_num; i++)
+ MM_REG_WRITE_MASK(cmd, subsys_id, base,
+ (MDP_CONTOUR_HIST_INIT + (i << 2)),
+ 0, 0xFFFFFFFF);
+
+ return 0;
+}
+
+static int init_tdshp(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CTRL, BIT(0), BIT(0));
+ /* Enable FIFO */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, BIT(1), BIT(1));
+
+ return reset_luma_hist(ctx, cmd);
+}
+
+static int config_tdshp_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, tdshp.cfg);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, reg, BIT(0));
+
+ return 0;
+}
+
+static int config_tdshp_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].src);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_INPUT_SIZE,
+ reg, MDP_TDSHP_INPUT_SIZE_MASK);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip_ofst);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_OFFSET,
+ reg, 0x00FF00FF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_SIZE,
+ reg, MDP_TDSHP_OUTPUT_SIZE_MASK);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_00, reg, 0xFFFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_1);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_01, reg, 0xFFFFFFFF);
+
+ return 0;
+}
+
+static const struct mdp_comp_ops tdshp_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_tdshp,
+ .config_frame = config_tdshp_frame,
+ .config_subfrm = config_tdshp_subfrm,
+};
+
+static int init_color(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_COLOR_START, 0x1, BIT(1) | BIT(0));
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_COLOR_WIN_X_MAIN, 0xFFFF0000, 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_COLOR_WIN_Y_MAIN, 0xFFFF0000, 0xFFFFFFFF);
+
+ /* Reset color matrix */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM1_EN, 0x0, BIT(0));
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM2_EN, 0x0, BIT(0));
+
+ /* Enable interrupt */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTEN, 0x7, 0x7);
+
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_OUT_SEL, 0x333, 0x333);
+
+ return 0;
+}
+
+static int config_color_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, color.start);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_START,
+ reg, MDP_COLOR_START_MASK);
+
+ return 0;
+}
+
+static int config_color_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_hsize);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_WIDTH,
+ reg, 0x00003FFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_vsize);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_HEIGHT,
+ reg, 0x00003FFF);
+
+ return 0;
+}
+
+static const struct mdp_comp_ops color_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_color,
+ .config_frame = config_color_frame,
+ .config_subfrm = config_color_subfrm,
+};
+
static int init_ccorr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
{
phys_addr_t base = ctx->comp->reg_base;
@@ -738,12 +1225,318 @@ static const struct mdp_comp_ops ccorr_ops = {
.config_subfrm = config_ccorr_subfrm,
};
+static int init_aal(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+
+ /* Always set MDP_AAL enable to 1 */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_EN, BIT(0), BIT(0));
+
+ return 0;
+}
+
+static int config_aal_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, aal.cfg_main);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG_MAIN, reg, BIT(7));
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, aal.cfg);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG, reg, BIT(0));
+
+ return 0;
+}
+
+static int config_aal_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].src);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_SIZE,
+ reg, MDP_AAL_SIZE_MASK);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip_ofst);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_OFFSET,
+ reg, 0x00FF00FF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_SIZE,
+ reg, MDP_AAL_OUTPUT_SIZE_MASK);
+
+ return 0;
+}
+
+static const struct mdp_comp_ops aal_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_aal,
+ .config_frame = config_aal_frame,
+ .config_subfrm = config_aal_subfrm,
+};
+
+static int init_hdr(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+
+ /* Always set MDP_HDR enable to 1 */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, BIT(0), BIT(0));
+
+ return 0;
+}
+
+static int config_hdr_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.top);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(29) | BIT(28));
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.relay);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_RELAY, reg, BIT(0));
+
+ return 0;
+}
+
+static int config_hdr_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].win_size);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TILE_POS,
+ reg, MDP_HDR_TILE_POS_MASK);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].src);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_0, reg, 0x1FFF1FFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_1, reg, 0x1FFF1FFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst1);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_2, reg, 0x1FFF1FFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_0, reg, 0x00003FFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_1);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_1, reg, 0x00003FFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hdr_top);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(6) | BIT(5));
+
+ /* Enable histogram */
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_addr);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_ADDR, reg, BIT(9));
+
+ return 0;
+}
+
+static const struct mdp_comp_ops hdr_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_hdr,
+ .config_frame = config_hdr_frame,
+ .config_subfrm = config_hdr_subfrm,
+};
+
+static int init_fg(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, BIT(2), BIT(2));
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, 0x0, BIT(2));
+
+ return 0;
+}
+
+static int config_fg_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, fg.ctrl_0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CTRL_0, reg, BIT(0));
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, fg.ck_en);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CK_EN, reg, 0x7);
+
+ return 0;
+}
+
+static int config_fg_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_0);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_0, reg, 0xFFFFFFFF);
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_1);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_1, reg, 0xFFFFFFFF);
+
+ return 0;
+}
+
+static const struct mdp_comp_ops fg_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_fg,
+ .config_frame = config_fg_frame,
+ .config_subfrm = config_fg_subfrm,
+};
+
+static int init_ovl(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_EN,
+ BIT(0), MDP_OVL_EN_MASK);
+
+ /* Set to relay mode */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON,
+ BIT(9), MDP_OVL_SRC_CON_MASK);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_DP_CON,
+ BIT(0), MDP_OVL_DP_CON_MASK);
+
+ return 0;
+}
+
+static int config_ovl_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, ovl.L0_con);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_CON, reg, BIT(29) | BIT(28));
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, ovl.src_con);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON, reg, BIT(0));
+
+ return 0;
+}
+
+static int config_ovl_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].L0_src_size);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_SRC_SIZE,
+ reg, MDP_OVL_L0_SRC_SIZE_MASK);
+
+ /* Setup output size */
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].roi_size);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_ROI_SIZE,
+ reg, MDP_OVL_ROI_SIZE_MASK);
+
+ return 0;
+}
+
+static const struct mdp_comp_ops ovl_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_ovl,
+ .config_frame = config_ovl_frame,
+ .config_subfrm = config_ovl_subfrm,
+};
+
+static int init_pad(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_CON,
+ BIT(1), MDP_PAD_CON_MASK);
+ /* Reset */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_W_SIZE,
+ 0, MDP_PAD_W_SIZE_MASK);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_H_SIZE,
+ 0, MDP_PAD_H_SIZE_MASK);
+
+ return 0;
+}
+
+static int config_pad_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ phys_addr_t base = ctx->comp->reg_base;
+ u16 subsys_id = ctx->comp->subsys_id;
+ u32 reg = 0;
+
+ if (CFG_CHECK(MT8195, p_id))
+ reg = CFG_COMP(MT8195, ctx->param, pad.subfrms[index].pic_size);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_PIC_SIZE,
+ reg, MDP_PAD_PIC_SIZE_MASK);
+
+ return 0;
+}
+
+static const struct mdp_comp_ops pad_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_pad,
+ .config_subfrm = config_pad_subfrm,
+};
+
static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = {
[MDP_COMP_TYPE_RDMA] = &rdma_ops,
[MDP_COMP_TYPE_RSZ] = &rsz_ops,
[MDP_COMP_TYPE_WROT] = &wrot_ops,
[MDP_COMP_TYPE_WDMA] = &wdma_ops,
+ [MDP_COMP_TYPE_TDSHP] = &tdshp_ops,
+ [MDP_COMP_TYPE_COLOR] = &color_ops,
[MDP_COMP_TYPE_CCORR] = &ccorr_ops,
+ [MDP_COMP_TYPE_AAL] = &aal_ops,
+ [MDP_COMP_TYPE_HDR] = &hdr_ops,
+ [MDP_COMP_TYPE_FG] = &fg_ops,
+ [MDP_COMP_TYPE_OVL] = &ovl_ops,
+ [MDP_COMP_TYPE_PAD] = &pad_ops,
};
static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = {
@@ -762,6 +1555,42 @@ static const struct of_device_id mdp_comp_dt_ids[] __maybe_unused = {
}, {
.compatible = "mediatek,mt8183-mdp3-wdma",
.data = (void *)MDP_COMP_TYPE_WDMA,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-rdma",
+ .data = (void *)MDP_COMP_TYPE_RDMA,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-split",
+ .data = (void *)MDP_COMP_TYPE_SPLIT,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-stitch",
+ .data = (void *)MDP_COMP_TYPE_STITCH,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-fg",
+ .data = (void *)MDP_COMP_TYPE_FG,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-hdr",
+ .data = (void *)MDP_COMP_TYPE_HDR,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-aal",
+ .data = (void *)MDP_COMP_TYPE_AAL,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-merge",
+ .data = (void *)MDP_COMP_TYPE_MERGE,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-tdshp",
+ .data = (void *)MDP_COMP_TYPE_TDSHP,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-color",
+ .data = (void *)MDP_COMP_TYPE_COLOR,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-ovl",
+ .data = (void *)MDP_COMP_TYPE_OVL,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-padding",
+ .data = (void *)MDP_COMP_TYPE_PAD,
+ }, {
+ .compatible = "mediatek,mt8195-mdp3-tcc",
+ .data = (void *)MDP_COMP_TYPE_TCC,
},
{}
};
@@ -853,9 +1682,26 @@ int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num)
int i, ret;
for (i = 0; i < num; i++) {
+ struct mdp_dev *m = comps[i].mdp_dev;
+ enum mtk_mdp_comp_id id;
+ const struct mdp_comp_blend *b;
+
+ /* Bypass the dummy component*/
+ if (!m)
+ continue;
+
ret = mdp_comp_clock_on(dev, &comps[i]);
if (ret)
return ret;
+
+ id = comps[i].public_id;
+ b = &m->mdp_data->comp_data[id].blend;
+
+ if (b && b->aid_clk) {
+ ret = mdp_comp_clock_on(dev, m->comp[b->b_id]);
+ if (ret)
+ return ret;
+ }
}
return 0;
@@ -865,8 +1711,23 @@ void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num)
{
int i;
- for (i = 0; i < num; i++)
+ for (i = 0; i < num; i++) {
+ struct mdp_dev *m = comps[i].mdp_dev;
+ enum mtk_mdp_comp_id id;
+ const struct mdp_comp_blend *b;
+
+ /* Bypass the dummy component*/
+ if (!m)
+ continue;
+
mdp_comp_clock_off(dev, &comps[i]);
+
+ id = comps[i].public_id;
+ b = &m->mdp_data->comp_data[id].blend;
+
+ if (b && b->aid_clk)
+ mdp_comp_clock_off(dev, m->comp[b->b_id]);
+ }
}
static int mdp_get_subsys_id(struct mdp_dev *mdp, struct device *dev,
@@ -1174,6 +2035,8 @@ int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
if (CFG_CHECK(MT8183, p_id))
arg = CFG_COMP(MT8183, param, type);
+ else if (CFG_CHECK(MT8195, p_id))
+ arg = CFG_COMP(MT8195, param, type);
else
return -EINVAL;
public_id = mdp_cfg_get_id_public(mdp, arg);
@@ -1191,16 +2054,22 @@ int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
ctx->param = param;
if (CFG_CHECK(MT8183, p_id))
arg = CFG_COMP(MT8183, param, input);
+ else if (CFG_CHECK(MT8195, p_id))
+ arg = CFG_COMP(MT8195, param, input);
else
return -EINVAL;
ctx->input = &frame->inputs[arg];
if (CFG_CHECK(MT8183, p_id))
idx = CFG_COMP(MT8183, param, num_outputs);
+ else if (CFG_CHECK(MT8195, p_id))
+ idx = CFG_COMP(MT8195, param, num_outputs);
else
return -EINVAL;
for (i = 0; i < idx; i++) {
if (CFG_CHECK(MT8183, p_id))
arg = CFG_COMP(MT8183, param, outputs[i]);
+ else if (CFG_CHECK(MT8195, p_id))
+ arg = CFG_COMP(MT8195, param, outputs[i]);
else
return -EINVAL;
ctx->outputs[i] = &frame->outputs[arg];
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
index 20d2bcb77ef9..3e5d2da1c807 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
@@ -84,22 +84,66 @@ enum mtk_mdp_comp_id {
MDP_COMP_CAMIN, /* 9 */
MDP_COMP_CAMIN2, /* 10 */
MDP_COMP_RDMA0, /* 11 */
- MDP_COMP_AAL0, /* 12 */
- MDP_COMP_CCORR0, /* 13 */
- MDP_COMP_RSZ0, /* 14 */
- MDP_COMP_RSZ1, /* 15 */
- MDP_COMP_TDSHP0, /* 16 */
- MDP_COMP_COLOR0, /* 17 */
- MDP_COMP_PATH0_SOUT, /* 18 */
- MDP_COMP_PATH1_SOUT, /* 19 */
- MDP_COMP_WROT0, /* 20 */
- MDP_COMP_WDMA, /* 21 */
-
- /* Dummy Engine */
- MDP_COMP_RDMA1, /* 22 */
- MDP_COMP_RSZ2, /* 23 */
- MDP_COMP_TDSHP1, /* 24 */
- MDP_COMP_WROT1, /* 25 */
+ MDP_COMP_RDMA1, /* 12 */
+ MDP_COMP_RDMA2, /* 13 */
+ MDP_COMP_RDMA3, /* 14 */
+ MDP_COMP_AAL0, /* 15 */
+ MDP_COMP_AAL1, /* 16 */
+ MDP_COMP_AAL2, /* 17 */
+ MDP_COMP_AAL3, /* 18 */
+ MDP_COMP_CCORR0, /* 19 */
+ MDP_COMP_RSZ0, /* 20 */
+ MDP_COMP_RSZ1, /* 21 */
+ MDP_COMP_RSZ2, /* 22 */
+ MDP_COMP_RSZ3, /* 23 */
+ MDP_COMP_TDSHP0, /* 24 */
+ MDP_COMP_TDSHP1, /* 25 */
+ MDP_COMP_TDSHP2, /* 26 */
+ MDP_COMP_TDSHP3, /* 27 */
+ MDP_COMP_COLOR0, /* 28 */
+ MDP_COMP_COLOR1, /* 29 */
+ MDP_COMP_COLOR2, /* 30 */
+ MDP_COMP_COLOR3, /* 31 */
+ MDP_COMP_PATH0_SOUT, /* 32 */
+ MDP_COMP_PATH1_SOUT, /* 33 */
+ MDP_COMP_WROT0, /* 34 */
+ MDP_COMP_WROT1, /* 35 */
+ MDP_COMP_WROT2, /* 36 */
+ MDP_COMP_WROT3, /* 37 */
+ MDP_COMP_WDMA, /* 38 */
+ MDP_COMP_SPLIT, /* 39 */
+ MDP_COMP_SPLIT2, /* 40 */
+ MDP_COMP_STITCH, /* 41 */
+ MDP_COMP_FG0, /* 42 */
+ MDP_COMP_FG1, /* 43 */
+ MDP_COMP_FG2, /* 44 */
+ MDP_COMP_FG3, /* 45 */
+ MDP_COMP_TO_SVPP2MOUT, /* 46 */
+ MDP_COMP_TO_SVPP3MOUT, /* 47 */
+ MDP_COMP_TO_WARP0MOUT, /* 48 */
+ MDP_COMP_TO_WARP1MOUT, /* 49 */
+ MDP_COMP_VPP0_SOUT, /* 50 */
+ MDP_COMP_VPP1_SOUT, /* 51 */
+ MDP_COMP_PQ0_SOUT, /* 52 */
+ MDP_COMP_PQ1_SOUT, /* 53 */
+ MDP_COMP_HDR0, /* 54 */
+ MDP_COMP_HDR1, /* 55 */
+ MDP_COMP_HDR2, /* 56 */
+ MDP_COMP_HDR3, /* 57 */
+ MDP_COMP_OVL0, /* 58 */
+ MDP_COMP_OVL1, /* 59 */
+ MDP_COMP_PAD0, /* 60 */
+ MDP_COMP_PAD1, /* 61 */
+ MDP_COMP_PAD2, /* 62 */
+ MDP_COMP_PAD3, /* 63 */
+ MDP_COMP_TCC0, /* 64 */
+ MDP_COMP_TCC1, /* 65 */
+ MDP_COMP_MERGE2, /* 66 */
+ MDP_COMP_MERGE3, /* 67 */
+ MDP_COMP_VDO0DL0, /* 68 */
+ MDP_COMP_VDO1DL0, /* 69 */
+ MDP_COMP_VDO0DL1, /* 70 */
+ MDP_COMP_VDO1DL1, /* 71 */
MDP_MAX_COMP_COUNT /* ALWAYS keep at the end */
};
@@ -117,12 +161,21 @@ enum mdp_comp_type {
MDP_COMP_TYPE_COLOR,
MDP_COMP_TYPE_DRE,
MDP_COMP_TYPE_CCORR,
+ MDP_COMP_TYPE_AAL,
+ MDP_COMP_TYPE_TCC,
MDP_COMP_TYPE_HDR,
+ MDP_COMP_TYPE_SPLIT,
+ MDP_COMP_TYPE_STITCH,
+ MDP_COMP_TYPE_FG,
+ MDP_COMP_TYPE_OVL,
+ MDP_COMP_TYPE_PAD,
+ MDP_COMP_TYPE_MERGE,
MDP_COMP_TYPE_IMGI,
MDP_COMP_TYPE_WPEI,
MDP_COMP_TYPE_EXTO, /* External path */
MDP_COMP_TYPE_DL_PATH, /* Direct-link path */
+ MDP_COMP_TYPE_DUMMY,
MDP_COMP_TYPE_COUNT /* ALWAYS keep at the end */
};
@@ -138,6 +191,7 @@ struct mdp_comp_match {
enum mdp_comp_type type;
u32 alias_id;
s32 inner_id;
+ s32 subsys_id;
};
/* Used to describe the item order in MDP property */
@@ -147,9 +201,16 @@ struct mdp_comp_info {
u32 dts_reg_ofst;
};
+struct mdp_comp_blend {
+ enum mtk_mdp_comp_id b_id;
+ bool aid_mod;
+ bool aid_clk;
+};
+
struct mdp_comp_data {
struct mdp_comp_match match;
struct mdp_comp_info info;
+ struct mdp_comp_blend blend;
};
struct mdp_comp_ops;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
index 94f4ed78523b..5209f531ef8d 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
@@ -21,14 +21,21 @@ static const struct of_device_id mdp_of_ids[] = {
{ .compatible = "mediatek,mt8183-mdp3-rdma",
.data = &mt8183_mdp_driver_data,
},
+ { .compatible = "mediatek,mt8195-mdp3-rdma",
+ .data = &mt8195_mdp_driver_data,
+ },
+ { .compatible = "mediatek,mt8195-mdp3-wrot",
+ .data = &mt8195_mdp_driver_data,
+ },
{},
};
MODULE_DEVICE_TABLE(of, mdp_of_ids);
static struct platform_device *__get_pdev_by_id(struct platform_device *pdev,
+ struct platform_device *from,
enum mdp_infra_id id)
{
- struct device_node *node;
+ struct device_node *node, *f = NULL;
struct platform_device *mdp_pdev = NULL;
const struct mtk_mdp_driver_data *mdp_data;
const char *compat;
@@ -46,9 +53,14 @@ static struct platform_device *__get_pdev_by_id(struct platform_device *pdev,
dev_err(&pdev->dev, "have no driver data to find node\n");
return NULL;
}
+
compat = mdp_data->mdp_probe_infra[id].compatible;
+ if (strlen(compat) == 0)
+ return NULL;
- node = of_find_compatible_node(NULL, NULL, compat);
+ if (from)
+ f = from->dev.of_node;
+ node = of_find_compatible_node(f, NULL, compat);
if (WARN_ON(!node)) {
dev_err(&pdev->dev, "find node from id %d failed\n", id);
return NULL;
@@ -130,6 +142,10 @@ void mdp_video_device_release(struct video_device *vdev)
struct mdp_dev *mdp = (struct mdp_dev *)video_get_drvdata(vdev);
int i;
+ for (i = 0; i < mdp->mdp_data->pp_used; i++)
+ if (mdp->cmdq_clt[i])
+ cmdq_mbox_destroy(mdp->cmdq_clt[i]);
+
scp_put(mdp->scp);
destroy_workqueue(mdp->job_wq);
@@ -140,19 +156,72 @@ void mdp_video_device_release(struct video_device *vdev)
vb2_dma_contig_clear_max_seg_size(&mdp->pdev->dev);
mdp_comp_destroy(mdp);
- for (i = 0; i < MDP_PIPE_MAX; i++)
- mtk_mutex_put(mdp->mdp_mutex[i]);
+ for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) {
+ enum mdp_mm_subsys_id idx;
+ struct mtk_mutex *m;
+ u32 m_id;
+
+ idx = mdp->mdp_data->pipe_info[i].sub_id;
+ m_id = mdp->mdp_data->pipe_info[i].mutex_id;
+ m = mdp->mm_subsys[idx].mdp_mutex[m_id];
+ if (!IS_ERR_OR_NULL(m))
+ mtk_mutex_put(m);
+ }
mdp_vpu_shared_mem_free(&mdp->vpu);
v4l2_m2m_release(mdp->m2m_dev);
kfree(mdp);
}
+static int mdp_mm_subsys_deploy(struct mdp_dev *mdp, enum mdp_infra_id id)
+{
+ struct platform_device *mm_pdev = NULL;
+ struct device **dev;
+ int i;
+
+ if (!mdp)
+ return -EINVAL;
+
+ for (i = 0; i < MDP_MM_SUBSYS_MAX; i++) {
+ const char *compat;
+ enum mdp_infra_id sub_id = id + i;
+
+ switch (id) {
+ case MDP_INFRA_MMSYS:
+ dev = &mdp->mm_subsys[i].mmsys;
+ break;
+ case MDP_INFRA_MUTEX:
+ dev = &mdp->mm_subsys[i].mutex;
+ break;
+ default:
+ dev_err(&mdp->pdev->dev, "Unknown infra id %d", id);
+ return -EINVAL;
+ }
+
+ /*
+ * Not every chip has multiple multimedia subsystems, so
+ * the config may be null.
+ */
+ compat = mdp->mdp_data->mdp_probe_infra[sub_id].compatible;
+ if (strlen(compat) == 0)
+ continue;
+
+ mm_pdev = __get_pdev_by_id(mdp->pdev, mm_pdev, sub_id);
+ if (WARN_ON(!mm_pdev))
+ return -ENODEV;
+
+ *dev = &mm_pdev->dev;
+ }
+
+ return 0;
+}
+
static int mdp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mdp_dev *mdp;
struct platform_device *mm_pdev;
+ struct resource *res;
int ret, i, mutex_id;
mdp = kzalloc(sizeof(*mdp), GFP_KERNEL);
@@ -164,25 +233,34 @@ static int mdp_probe(struct platform_device *pdev)
mdp->pdev = pdev;
mdp->mdp_data = of_device_get_match_data(&pdev->dev);
- mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MMSYS);
- if (!mm_pdev) {
- ret = -ENODEV;
- goto err_destroy_device;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res->start != mdp->mdp_data->mdp_con_res) {
+ platform_set_drvdata(pdev, mdp);
+ goto success_return;
}
- mdp->mdp_mmsys = &mm_pdev->dev;
- mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MUTEX);
- if (WARN_ON(!mm_pdev)) {
- ret = -ENODEV;
+ ret = mdp_mm_subsys_deploy(mdp, MDP_INFRA_MMSYS);
+ if (ret)
goto err_destroy_device;
- }
+
+ ret = mdp_mm_subsys_deploy(mdp, MDP_INFRA_MUTEX);
+ if (ret)
+ goto err_destroy_device;
+
for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) {
+ enum mdp_mm_subsys_id idx;
+ struct mtk_mutex **m;
+
+ idx = mdp->mdp_data->pipe_info[i].sub_id;
mutex_id = mdp->mdp_data->pipe_info[i].mutex_id;
- if (!IS_ERR_OR_NULL(mdp->mdp_mutex[mutex_id]))
+ m = &mdp->mm_subsys[idx].mdp_mutex[mutex_id];
+
+ if (!IS_ERR_OR_NULL(*m))
continue;
- mdp->mdp_mutex[mutex_id] = mtk_mutex_get(&mm_pdev->dev);
- if (IS_ERR(mdp->mdp_mutex[mutex_id])) {
- ret = PTR_ERR(mdp->mdp_mutex[mutex_id]);
+
+ *m = mtk_mutex_get(mdp->mm_subsys[idx].mutex);
+ if (IS_ERR(*m)) {
+ ret = PTR_ERR(*m);
goto err_free_mutex;
}
}
@@ -210,7 +288,7 @@ static int mdp_probe(struct platform_device *pdev)
mdp->scp = scp_get(pdev);
if (!mdp->scp) {
- mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_SCP);
+ mm_pdev = __get_pdev_by_id(pdev, NULL, MDP_INFRA_SCP);
if (WARN_ON(!mm_pdev)) {
dev_err(&pdev->dev, "Could not get scp device\n");
ret = -ENODEV;
@@ -225,10 +303,12 @@ static int mdp_probe(struct platform_device *pdev)
mutex_init(&mdp->vpu_lock);
mutex_init(&mdp->m2m_lock);
- mdp->cmdq_clt = cmdq_mbox_create(dev, 0);
- if (IS_ERR(mdp->cmdq_clt)) {
- ret = PTR_ERR(mdp->cmdq_clt);
- goto err_put_scp;
+ for (i = 0; i < mdp->mdp_data->pp_used; i++) {
+ mdp->cmdq_clt[i] = cmdq_mbox_create(dev, i);
+ if (IS_ERR(mdp->cmdq_clt[i])) {
+ ret = PTR_ERR(mdp->cmdq_clt[i]);
+ goto err_mbox_destroy;
+ }
}
init_waitqueue_head(&mdp->callback_wq);
@@ -250,14 +330,15 @@ static int mdp_probe(struct platform_device *pdev)
goto err_unregister_device;
}
+success_return:
dev_dbg(dev, "mdp-%d registered successfully\n", pdev->id);
return 0;
err_unregister_device:
v4l2_device_unregister(&mdp->v4l2_dev);
err_mbox_destroy:
- cmdq_mbox_destroy(mdp->cmdq_clt);
-err_put_scp:
+ while (--i >= 0)
+ cmdq_mbox_destroy(mdp->cmdq_clt[i]);
scp_put(mdp->scp);
err_destroy_clock_wq:
destroy_workqueue(mdp->clock_wq);
@@ -266,9 +347,16 @@ err_destroy_job_wq:
err_deinit_comp:
mdp_comp_destroy(mdp);
err_free_mutex:
- for (i = 0; i < mdp->mdp_data->pipe_info_len; i++)
- if (!IS_ERR_OR_NULL(mdp->mdp_mutex[i]))
- mtk_mutex_put(mdp->mdp_mutex[i]);
+ for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) {
+ enum mdp_mm_subsys_id idx;
+ struct mtk_mutex *m;
+
+ idx = mdp->mdp_data->pipe_info[i].sub_id;
+ mutex_id = mdp->mdp_data->pipe_info[i].mutex_id;
+ m = mdp->mm_subsys[idx].mdp_mutex[mutex_id];
+ if (!IS_ERR_OR_NULL(m))
+ mtk_mutex_put(m);
+ }
err_destroy_device:
kfree(mdp);
err_return:
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
index 7e21d226ceb8..8c09e984fd01 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
@@ -19,12 +19,24 @@
#define MDP_PHANDLE_NAME "mediatek,mdp3"
enum mdp_infra_id {
+ /*
+ * Due to the sequential nature of function "mdp_mm_subsys_deploy",
+ * adding new enum. necessitates careful consideration.
+ */
MDP_INFRA_MMSYS,
+ MDP_INFRA_MMSYS2,
MDP_INFRA_MUTEX,
+ MDP_INFRA_MUTEX2,
MDP_INFRA_SCP,
MDP_INFRA_MAX
};
+enum mdp_mm_subsys_id {
+ MDP_MM_SUBSYS_0,
+ MDP_MM_SUBSYS_1,
+ MDP_MM_SUBSYS_MAX,
+};
+
enum mdp_buffer_usage {
MDP_BUFFER_USAGE_HW_READ,
MDP_BUFFER_USAGE_MDP,
@@ -37,8 +49,16 @@ struct mdp_platform_config {
bool rdma_support_10bit;
bool rdma_rsz1_sram_sharing;
bool rdma_upsample_repeat_only;
+ bool rdma_esl_setting;
+ u32 rdma_event_num;
bool rsz_disable_dcm_small_sample;
+ bool rsz_etc_control;
bool wrot_filter_constraint;
+ bool wrot_support_10bit;
+ u32 wrot_event_num;
+ u32 tdshp_hist_num;
+ bool tdshp_constrain;
+ bool tdshp_contour;
};
/* indicate which mutex is used by each pipepline */
@@ -47,11 +67,27 @@ enum mdp_pipe_id {
MDP_PIPE_WPEI2,
MDP_PIPE_IMGI,
MDP_PIPE_RDMA0,
+ MDP_PIPE_RDMA1,
+ MDP_PIPE_RDMA2,
+ MDP_PIPE_RDMA3,
+ MDP_PIPE_SPLIT,
+ MDP_PIPE_SPLIT2,
+ MDP_PIPE_VPP0_SOUT,
+ MDP_PIPE_VPP1_SOUT,
MDP_PIPE_MAX
};
+/* MDP parallel pipe control */
+enum {
+ MDP_PP_USED_1 = 1,
+ MDP_PP_USED_2 = 2,
+};
+
+#define MDP_PP_MAX MDP_PP_USED_2
+
struct mtk_mdp_driver_data {
const int mdp_plat_id;
+ const resource_size_t mdp_con_res;
const struct of_device_id *mdp_probe_infra;
const struct mdp_platform_config *mdp_cfg;
const u32 *mdp_mutex_table_idx;
@@ -63,12 +99,19 @@ struct mtk_mdp_driver_data {
const struct mdp_limit *def_limit;
const struct mdp_pipe_info *pipe_info;
unsigned int pipe_info_len;
+ const struct v4l2_rect *pp_criteria;
+ const u8 pp_used;
+};
+
+struct mdp_mm_subsys {
+ struct device *mmsys;
+ struct device *mutex;
+ struct mtk_mutex *mdp_mutex[MDP_PIPE_MAX];
};
struct mdp_dev {
struct platform_device *pdev;
- struct device *mdp_mmsys;
- struct mtk_mutex *mdp_mutex[MDP_PIPE_MAX];
+ struct mdp_mm_subsys mm_subsys[MDP_MM_SUBSYS_MAX];
struct mdp_comp *comp[MDP_MAX_COMP_COUNT];
const struct mtk_mdp_driver_data *mdp_data;
@@ -82,7 +125,7 @@ struct mdp_dev {
s32 vpu_count;
u32 id_count;
struct ida mdp_ida;
- struct cmdq_client *cmdq_clt;
+ struct cmdq_client *cmdq_clt[MDP_PP_MAX];
wait_queue_head_t callback_wq;
struct v4l2_device v4l2_dev;
@@ -96,6 +139,7 @@ struct mdp_dev {
struct mdp_pipe_info {
enum mdp_pipe_id pipe_id;
+ enum mdp_mm_subsys_id sub_id;
u32 mutex_id;
};
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
index a298c1b15b9e..35a8b059bde5 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
@@ -87,6 +87,9 @@ static void mdp_m2m_device_run(void *priv)
dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
mdp_set_dst_config(&param.outputs[0], frame, &dst_vb->vb2_buf);
+ if (mdp_check_pp_enable(ctx->mdp_dev, frame))
+ param.type = MDP_STREAM_TYPE_DUAL_BITBLT;
+
ret = mdp_vpu_process(&ctx->mdp_dev->vpu, &param);
if (ret) {
dev_err(&ctx->mdp_dev->pdev->dev,
@@ -101,6 +104,18 @@ static void mdp_m2m_device_run(void *priv)
task.cb_data = NULL;
task.mdp_ctx = ctx;
+ if (atomic_read(&ctx->mdp_dev->job_count)) {
+ ret = wait_event_timeout(ctx->mdp_dev->callback_wq,
+ !atomic_read(&ctx->mdp_dev->job_count),
+ 2 * HZ);
+ if (ret == 0) {
+ dev_err(&ctx->mdp_dev->pdev->dev,
+ "%d jobs not yet done\n",
+ atomic_read(&ctx->mdp_dev->job_count));
+ goto worker_end;
+ }
+ }
+
ret = mdp_cmdq_send(ctx->mdp_dev, &task);
if (ret) {
dev_err(&ctx->mdp_dev->pdev->dev,
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
index 9b436b911d92..657356f87743 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
@@ -304,6 +304,24 @@ int mdp_check_scaling_ratio(const struct v4l2_rect *crop,
return 0;
}
+bool mdp_check_pp_enable(struct mdp_dev *mdp, struct mdp_frame *frame)
+{
+ u32 s, r1, r2;
+
+ if (!mdp || !frame)
+ return false;
+
+ if (!mdp->mdp_data->pp_criteria)
+ return false;
+
+ s = mdp->mdp_data->pp_criteria->width *
+ mdp->mdp_data->pp_criteria->height;
+ r1 = frame->crop.c.width * frame->crop.c.height;
+ r2 = frame->compose.width * frame->compose.height;
+
+ return (r1 >= s || r2 >= s);
+}
+
/* Stride that is accepted by MDP HW */
static u32 mdp_fmt_get_stride(const struct mdp_format *fmt,
u32 bytesperline, unsigned int plane)
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h
index e9ab8ac2c0e8..b0c8f9f00820 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h
@@ -368,6 +368,7 @@ int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r,
int mdp_check_scaling_ratio(const struct v4l2_rect *crop,
const struct v4l2_rect *compose, s32 rotation,
const struct mdp_limit *limit);
+bool mdp_check_pp_enable(struct mdp_dev *mdp, struct mdp_frame *frame);
void mdp_set_src_config(struct img_input *in,
struct mdp_frame *frame, struct vb2_buffer *vb);
void mdp_set_dst_config(struct img_output *out,
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
index 49fc2e9d45dd..da3a892ad867 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
@@ -198,6 +198,7 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
};
struct mdp_dev *mdp = vpu_to_mdp(vpu);
int err;
+ u8 pp_num = mdp->mdp_data->pp_used;
init_completion(&vpu->ipi_acked);
vpu->scp = scp;
@@ -211,7 +212,7 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
mutex_lock(vpu->lock);
vpu->work_size = ALIGN(vpu->work_size, 64);
vpu->param_size = ALIGN(sizeof(struct img_ipi_frameparam), 64);
- vpu->config_size = ALIGN(sizeof(struct img_config), 64);
+ vpu->config_size = ALIGN(sizeof(struct img_config) * pp_num, 64);
err = mdp_vpu_shared_mem_alloc(vpu);
mutex_unlock(vpu->lock);
if (err) {
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
index 9f6e4b59455d..4c34344dc7dc 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
@@ -29,15 +29,7 @@ static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
mtk_vcodec_ipi_handler handler,
const char *name, void *priv)
{
- /*
- * The handler we receive takes a void * as its first argument. We
- * cannot change this because it needs to be passed down to the rproc
- * subsystem when SCP is used. VPU takes a const argument, which is
- * more constrained, so the conversion below is safe.
- */
- ipi_handler_t handler_const = (ipi_handler_t)handler;
-
- return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
+ return vpu_ipi_register(fw->pdev, id, handler, name, priv);
}
static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h
index ece27c880e50..1af075fc0194 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.h
@@ -39,7 +39,6 @@ struct vdec_fb {
/**
* struct mtk_video_dec_buf - Private data related to each VB2 buffer.
* @m2m_buf: M2M buffer
- * @list: link list
* @used: Capture buffer contain decoded frame data and keep in
* codec data structure
* @queued_in_vb2: Capture buffer is queue in vb2
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
index d54b3833790d..b903e39fee89 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
@@ -566,7 +566,7 @@ static void mtk_vcodec_dec_fill_h264_level(struct v4l2_ctrl_config *cfg,
default:
cfg->max = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
break;
- };
+ }
}
static void mtk_vcodec_dec_fill_h264_profile(struct v4l2_ctrl_config *cfg,
@@ -580,7 +580,7 @@ static void mtk_vcodec_dec_fill_h264_profile(struct v4l2_ctrl_config *cfg,
default:
cfg->max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
break;
- };
+ }
}
static void mtk_vcodec_dec_fill_h265_level(struct v4l2_ctrl_config *cfg,
@@ -596,7 +596,7 @@ static void mtk_vcodec_dec_fill_h265_level(struct v4l2_ctrl_config *cfg,
default:
cfg->max = V4L2_MPEG_VIDEO_HEVC_LEVEL_4;
break;
- };
+ }
}
static void mtk_vcodec_dec_fill_h265_profile(struct v4l2_ctrl_config *cfg,
@@ -610,7 +610,7 @@ static void mtk_vcodec_dec_fill_h265_profile(struct v4l2_ctrl_config *cfg,
default:
cfg->max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE;
break;
- };
+ }
}
static void mtk_vcodec_dec_fill_vp9_level(struct v4l2_ctrl_config *cfg,
@@ -630,7 +630,7 @@ static void mtk_vcodec_dec_fill_vp9_level(struct v4l2_ctrl_config *cfg,
default:
cfg->max = V4L2_MPEG_VIDEO_VP9_LEVEL_4_0;
break;
- };
+ }
}
static void mtk_vcodec_dec_fill_vp9_profile(struct v4l2_ctrl_config *cfg,
@@ -644,7 +644,7 @@ static void mtk_vcodec_dec_fill_vp9_profile(struct v4l2_ctrl_config *cfg,
default:
cfg->max = V4L2_MPEG_VIDEO_VP9_PROFILE_1;
break;
- };
+ }
}
static void mtk_vcodec_dec_reset_controls(struct v4l2_ctrl_config *cfg,
@@ -680,7 +680,7 @@ static void mtk_vcodec_dec_reset_controls(struct v4l2_ctrl_config *cfg,
break;
default:
break;
- };
+ }
}
static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_dec_ctx *ctx)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
index f64b21c07169..f677e499fefa 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
@@ -37,7 +37,6 @@
* @bs_sz: bitstream size
* @resolution_changed:resolution change flag 1 - changed, 0 - not change
* @frame_header_type: current frame header type
- * @wait_key_frame: wait key frame coming
* @crc: used to check whether hardware's status is right
* @reserved: reserved, currently unused
*/
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
index 69d37b93bd35..cf48d09b78d7 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
@@ -141,7 +141,6 @@ struct vdec_vp9_slice_frame_counts {
* @skip: skip counts.
* @y_mode: Y prediction mode counts.
* @filter: interpolation filter counts.
- * @mv_joint: motion vector joint counts.
* @sign: motion vector sign counts.
* @classes: motion vector class counts.
* @class0: motion vector class0 bit counts.
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h
index fbb3f34a73f0..aa7d08afc2f4 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.h
@@ -22,7 +22,6 @@ struct mtk_vcodec_dec_ctx;
* in place of inst_addr in messages.
* @signaled : 1 - Host has received ack message from VPU, 0 - not received
* @ctx : context for v4l2 layer integration
- * @dev : platform device of VPU
* @wq : wait queue to wait VPU message ack
* @handler : ipi handler for each decoder
* @codec_type : use codec type to separate different codecs
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h
index 82246401ed4a..908d8179b2d2 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h
@@ -26,7 +26,6 @@
/**
* struct mtk_video_enc_buf - Private data related to each VB2 buffer.
* @m2m_buf: M2M buffer
- * @list: list that buffer link to
* @param_change: Types of encode parameter change before encoding this
* buffer
* @enc_params: Encode parameters changed before encode this buffer
diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.c b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
index 7243604a82a5..724ae7c2ab3b 100644
--- a/drivers/media/platform/mediatek/vpu/mtk_vpu.c
+++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
@@ -635,7 +635,7 @@ OUT_LOAD_FW:
}
EXPORT_SYMBOL_GPL(vpu_load_firmware);
-static void vpu_init_ipi_handler(const void *data, unsigned int len, void *priv)
+static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)
{
struct mtk_vpu *vpu = priv;
const struct vpu_run *run = data;
diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.h b/drivers/media/platform/mediatek/vpu/mtk_vpu.h
index a56053ff135a..da05f3e74081 100644
--- a/drivers/media/platform/mediatek/vpu/mtk_vpu.h
+++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.h
@@ -17,7 +17,7 @@
* VPU interfaces with other blocks by share memory and interrupt.
*/
-typedef void (*ipi_handler_t) (const void *data,
+typedef void (*ipi_handler_t) (void *data,
unsigned int len,
void *priv);
diff --git a/drivers/media/platform/nuvoton/npcm-video.c b/drivers/media/platform/nuvoton/npcm-video.c
index a1fcb616b256..60fbb9140035 100644
--- a/drivers/media/platform/nuvoton/npcm-video.c
+++ b/drivers/media/platform/nuvoton/npcm-video.c
@@ -1785,7 +1785,7 @@ static int npcm_video_probe(struct platform_device *pdev)
return 0;
}
-static int npcm_video_remove(struct platform_device *pdev)
+static void npcm_video_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
@@ -1798,8 +1798,6 @@ static int npcm_video_remove(struct platform_device *pdev)
if (video->ece.enable)
npcm_video_ece_stop(video);
of_reserved_mem_device_release(dev);
-
- return 0;
}
static const struct of_device_id npcm_video_match[] = {
@@ -1816,7 +1814,7 @@ static struct platform_driver npcm_video_driver = {
.of_match_table = npcm_video_match,
},
.probe = npcm_video_probe,
- .remove = npcm_video_remove,
+ .remove_new = npcm_video_remove,
};
module_platform_driver(npcm_video_driver);
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
index 64112b63298c..cc97790ed30f 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -1373,6 +1373,8 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
q_data_cap->crop.top = 0;
q_data_cap->crop.width = jpeg_src_buf->w;
q_data_cap->crop.height = jpeg_src_buf->h;
+ q_data_cap->bytesperline[0] = 0;
+ q_data_cap->bytesperline[1] = 0;
/*
* align up the resolution for CAST IP,
@@ -1752,6 +1754,14 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,
static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
{
+ u32 bytesperline[2];
+
+ bytesperline[0] = q->bytesperline[0];
+ bytesperline[1] = q->bytesperline[0]; /*imx-jpeg only support the same line pitch*/
+ v4l_bound_align_image(&bytesperline[0], 0, MXC_JPEG_MAX_LINE, 2,
+ &bytesperline[1], 0, MXC_JPEG_MAX_LINE, 2,
+ 0);
+
/* Bytes distance between the leftmost pixels in two adjacent lines */
if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
/* bytesperline unused for compressed formats */
@@ -1775,6 +1785,12 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
q->bytesperline[0] = q->w_adjusted * DIV_ROUND_UP(precision, 8);
q->bytesperline[1] = 0;
}
+
+ if (q->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
+ q->bytesperline[0] = max(q->bytesperline[0], bytesperline[0]);
+ if (q->fmt->mem_planes > 1)
+ q->bytesperline[1] = max(q->bytesperline[1], bytesperline[1]);
+ }
}
static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
index dc4afeeff5b6..86e324b21aed 100644
--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
@@ -22,6 +22,7 @@
#define MXC_JPEG_MIN_HEIGHT 64
#define MXC_JPEG_MAX_WIDTH 0x2000
#define MXC_JPEG_MAX_HEIGHT 0x2000
+#define MXC_JPEG_MAX_LINE 0x8000
#define MXC_JPEG_MAX_CFG_STREAM 0x1000
#define MXC_JPEG_H_ALIGN 3
#define MXC_JPEG_W_ALIGN 3
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
index f73facb97dc5..c2013995049c 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
@@ -506,7 +506,7 @@ err_pm:
return ret;
}
-static int mxc_isi_remove(struct platform_device *pdev)
+static void mxc_isi_remove(struct platform_device *pdev)
{
struct mxc_isi_dev *isi = platform_get_drvdata(pdev);
unsigned int i;
@@ -523,8 +523,6 @@ static int mxc_isi_remove(struct platform_device *pdev)
mxc_isi_v4l2_cleanup(isi);
pm_runtime_disable(isi->dev);
-
- return 0;
}
static const struct of_device_id mxc_isi_of_match[] = {
@@ -537,7 +535,7 @@ MODULE_DEVICE_TABLE(of, mxc_isi_of_match);
static struct platform_driver mxc_isi_driver = {
.probe = mxc_isi_probe,
- .remove = mxc_isi_remove,
+ .remove_new = mxc_isi_remove,
.driver = {
.of_match_table = mxc_isi_of_match,
.name = MXC_ISI_DRIVER_NAME,
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
index 575f17337388..93a55c97cd17 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
@@ -161,7 +161,6 @@ mxc_isi_crossbar_xlate_streams(struct mxc_isi_crossbar *xbar,
pad = media_pad_remote_pad_first(&xbar->pads[sink_pad]);
sd = media_entity_to_v4l2_subdev(pad->entity);
-
if (!sd) {
dev_dbg(xbar->isi->dev,
"no entity connected to crossbar input %u\n",
@@ -469,7 +468,8 @@ int mxc_isi_crossbar_init(struct mxc_isi_dev *isi)
}
for (i = 0; i < xbar->num_sinks; ++i)
- xbar->pads[i].flags = MEDIA_PAD_FL_SINK;
+ xbar->pads[i].flags = MEDIA_PAD_FL_SINK
+ | MEDIA_PAD_FL_MUST_CONNECT;
for (i = 0; i < xbar->num_sources; ++i)
xbar->pads[i + xbar->num_sinks].flags = MEDIA_PAD_FL_SOURCE;
diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
index 19e80b95ffea..5623914f95e6 100644
--- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
+++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-hw.c
@@ -215,8 +215,7 @@ static void mxc_isi_channel_set_csc(struct mxc_isi_pipe *pipe,
[MXC_ISI_ENC_RGB] = "RGB",
[MXC_ISI_ENC_YUV] = "YUV",
};
- const u32 *coeffs;
- bool cscen = true;
+ const u32 *coeffs = NULL;
u32 val;
val = mxc_isi_read(pipe, CHNL_IMG_CTRL);
@@ -235,14 +234,13 @@ static void mxc_isi_channel_set_csc(struct mxc_isi_pipe *pipe,
val |= CHNL_IMG_CTRL_CSC_MODE(CHNL_IMG_CTRL_CSC_MODE_RGB2YCBCR);
} else {
/* Bypass CSC */
- cscen = false;
val |= CHNL_IMG_CTRL_CSC_BYPASS;
}
dev_dbg(pipe->isi->dev, "CSC: %s -> %s\n",
encodings[in_encoding], encodings[out_encoding]);
- if (cscen) {
+ if (coeffs) {
mxc_isi_write(pipe, CHNL_CSC_COEFF0, coeffs[0]);
mxc_isi_write(pipe, CHNL_CSC_COEFF1, coeffs[1]);
mxc_isi_write(pipe, CHNL_CSC_COEFF2, coeffs[2]);
@@ -253,7 +251,7 @@ static void mxc_isi_channel_set_csc(struct mxc_isi_pipe *pipe,
mxc_isi_write(pipe, CHNL_IMG_CTRL, val);
- *bypass = !cscen;
+ *bypass = !coeffs;
}
void mxc_isi_channel_set_alpha(struct mxc_isi_pipe *pipe, u8 alpha)
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 7ef341bf21cc..6a77de374454 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -427,7 +427,6 @@ enum venus_inst_modes {
* @error: an error returned during last HFI sync operation
* @session_error: a flag rised by HFI interface in case of session error
* @ops: HFI operations
- * @priv: a private for HFI operations callbacks
* @session_type: the type of the session (decoder or encoder)
* @hprop: a union used as a holder by get property
* @core_acquired: the Core has been acquired
diff --git a/drivers/media/platform/renesas/Kconfig b/drivers/media/platform/renesas/Kconfig
index ed788e991f74..c7fc718a30a5 100644
--- a/drivers/media/platform/renesas/Kconfig
+++ b/drivers/media/platform/renesas/Kconfig
@@ -14,6 +14,22 @@ config VIDEO_RENESAS_CEU
help
This is a v4l2 driver for the Renesas CEU Interface
+config VIDEO_RCAR_CSI2
+ tristate "R-Car MIPI CSI-2 Receiver"
+ depends on V4L_PLATFORM_DRIVERS
+ depends on VIDEO_DEV && OF
+ depends on ARCH_RENESAS || COMPILE_TEST
+ select MEDIA_CONTROLLER
+ select VIDEO_V4L2_SUBDEV_API
+ select RESET_CONTROLLER
+ select V4L2_FWNODE
+ help
+ Support for Renesas R-Car MIPI CSI-2 receiver.
+ Supports R-Car Gen3 and RZ/G2 SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-csi2.
+
config VIDEO_RCAR_ISP
tristate "R-Car Image Signal Processor (ISP)"
depends on V4L_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/renesas/Makefile b/drivers/media/platform/renesas/Makefile
index 55854e868887..50774a20330c 100644
--- a/drivers/media/platform/renesas/Makefile
+++ b/drivers/media/platform/renesas/Makefile
@@ -7,6 +7,7 @@ obj-y += rcar-vin/
obj-y += rzg2l-cru/
obj-y += vsp1/
+obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
obj-$(CONFIG_VIDEO_RCAR_DRIF) += rcar_drif.o
obj-$(CONFIG_VIDEO_RCAR_ISP) += rcar-isp.o
obj-$(CONFIG_VIDEO_RENESAS_CEU) += renesas-ceu.o
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c b/drivers/media/platform/renesas/rcar-csi2.c
index 582d5e35db0e..582d5e35db0e 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/renesas/rcar-csi2.c
diff --git a/drivers/media/platform/renesas/rcar-isp.c b/drivers/media/platform/renesas/rcar-isp.c
index 530d65fc546b..4512ac338ca5 100644
--- a/drivers/media/platform/renesas/rcar-isp.c
+++ b/drivers/media/platform/renesas/rcar-isp.c
@@ -518,6 +518,7 @@ static void risp_remove(struct platform_device *pdev)
static struct platform_driver rcar_isp_driver = {
.driver = {
.name = "rcar-isp",
+ .suppress_bind_attrs = true,
.of_match_table = risp_of_id_table,
},
.probe = risp_probe,
diff --git a/drivers/media/platform/renesas/rcar-vin/Kconfig b/drivers/media/platform/renesas/rcar-vin/Kconfig
index de55fe63d84c..2ec857ab83cb 100644
--- a/drivers/media/platform/renesas/rcar-vin/Kconfig
+++ b/drivers/media/platform/renesas/rcar-vin/Kconfig
@@ -1,20 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
-config VIDEO_RCAR_CSI2
- tristate "R-Car MIPI CSI-2 Receiver"
- depends on V4L_PLATFORM_DRIVERS
- depends on VIDEO_DEV && OF
- depends on ARCH_RENESAS || COMPILE_TEST
- select MEDIA_CONTROLLER
- select VIDEO_V4L2_SUBDEV_API
- select RESET_CONTROLLER
- select V4L2_FWNODE
- help
- Support for Renesas R-Car MIPI CSI-2 receiver.
- Supports R-Car Gen3 and RZ/G2 SoCs.
-
- To compile this driver as a module, choose M here: the
- module will be called rcar-csi2.
-
config VIDEO_RCAR_VIN
tristate "R-Car Video Input (VIN) Driver"
depends on V4L_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/renesas/rcar-vin/Makefile b/drivers/media/platform/renesas/rcar-vin/Makefile
index 00d809f5d2c1..5938ad6290c8 100644
--- a/drivers/media/platform/renesas/rcar-vin/Makefile
+++ b/drivers/media/platform/renesas/rcar-vin/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
-obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o
obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
index 811603f18af0..a5a99b004322 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
@@ -133,9 +133,6 @@ struct rzg2l_cru_dev {
struct v4l2_pix_format format;
};
-void rzg2l_cru_vclk_unprepare(struct rzg2l_cru_dev *cru);
-int rzg2l_cru_vclk_prepare(struct rzg2l_cru_dev *cru);
-
int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru);
void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru);
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
index d20f4eff93a4..e68fcdaea207 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
@@ -108,6 +108,7 @@ struct rzg2l_csi2 {
struct reset_control *presetn;
struct reset_control *cmn_rstb;
struct clk *sysclk;
+ struct clk *vclk;
unsigned long vclk_rate;
struct v4l2_subdev subdev;
@@ -361,7 +362,7 @@ static int rzg2l_csi2_dphy_setting(struct v4l2_subdev *sd, bool on)
return rzg2l_csi2_dphy_disable(csi2);
}
-static void rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2)
+static int rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2)
{
unsigned long vclk_rate = csi2->vclk_rate / HZ_PER_MHZ;
u32 frrskw, frrclk, frrskw_coeff, frrclk_coeff;
@@ -386,11 +387,15 @@ static void rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2)
rzg2l_csi2_write(csi2, CSI2nDTEL, 0xf778ff0f);
rzg2l_csi2_write(csi2, CSI2nDTEH, 0x00ffff1f);
+ clk_disable_unprepare(csi2->vclk);
+
/* Enable LINK reception */
rzg2l_csi2_write(csi2, CSI2nMCT3, CSI2nMCT3_RXEN);
+
+ return clk_prepare_enable(csi2->vclk);
}
-static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2)
+static int rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2)
{
unsigned int timeout = VSRSTS_RETRIES;
@@ -409,18 +414,21 @@ static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2)
if (!timeout)
dev_err(csi2->dev, "Clearing CSI2nRTST.VSRSTS timed out\n");
+
+ return 0;
}
static int rzg2l_csi2_mipi_link_setting(struct v4l2_subdev *sd, bool on)
{
struct rzg2l_csi2 *csi2 = sd_to_csi2(sd);
+ int ret;
if (on)
- rzg2l_csi2_mipi_link_enable(csi2);
+ ret = rzg2l_csi2_mipi_link_enable(csi2);
else
- rzg2l_csi2_mipi_link_disable(csi2);
+ ret = rzg2l_csi2_mipi_link_disable(csi2);
- return 0;
+ return ret;
}
static int rzg2l_csi2_s_stream(struct v4l2_subdev *sd, int enable)
@@ -731,7 +739,6 @@ static const struct media_entity_operations rzg2l_csi2_entity_ops = {
static int rzg2l_csi2_probe(struct platform_device *pdev)
{
struct rzg2l_csi2 *csi2;
- struct clk *vclk;
int ret;
csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
@@ -757,12 +764,11 @@ static int rzg2l_csi2_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(csi2->sysclk),
"Failed to get system clk\n");
- vclk = clk_get(&pdev->dev, "video");
- if (IS_ERR(vclk))
- return dev_err_probe(&pdev->dev, PTR_ERR(vclk),
+ csi2->vclk = devm_clk_get(&pdev->dev, "video");
+ if (IS_ERR(csi2->vclk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(csi2->vclk),
"Failed to get video clock\n");
- csi2->vclk_rate = clk_get_rate(vclk);
- clk_put(vclk);
+ csi2->vclk_rate = clk_get_rate(csi2->vclk);
csi2->dev = &pdev->dev;
@@ -834,7 +840,7 @@ static void rzg2l_csi2_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
}
-static int __maybe_unused rzg2l_csi2_pm_runtime_suspend(struct device *dev)
+static int rzg2l_csi2_pm_runtime_suspend(struct device *dev)
{
struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev);
@@ -843,7 +849,7 @@ static int __maybe_unused rzg2l_csi2_pm_runtime_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused rzg2l_csi2_pm_runtime_resume(struct device *dev)
+static int rzg2l_csi2_pm_runtime_resume(struct device *dev)
{
struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev);
@@ -851,7 +857,8 @@ static int __maybe_unused rzg2l_csi2_pm_runtime_resume(struct device *dev)
}
static const struct dev_pm_ops rzg2l_csi2_pm_ops = {
- SET_RUNTIME_PM_OPS(rzg2l_csi2_pm_runtime_suspend, rzg2l_csi2_pm_runtime_resume, NULL)
+ RUNTIME_PM_OPS(rzg2l_csi2_pm_runtime_suspend,
+ rzg2l_csi2_pm_runtime_resume, NULL)
};
static const struct of_device_id rzg2l_csi2_of_table[] = {
@@ -865,7 +872,7 @@ static struct platform_driver rzg2l_csi2_pdrv = {
.driver = {
.name = "rzg2l-csi2",
.of_match_table = rzg2l_csi2_of_table,
- .pm = &rzg2l_csi2_pm_ops,
+ .pm = pm_ptr(&rzg2l_csi2_pm_ops),
},
};
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c
index 9f351a05893e..ac8ebae4ed07 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c
@@ -5,6 +5,7 @@
* Copyright (C) 2022 Renesas Electronics Corp.
*/
+#include <linux/delay.h>
#include "rzg2l-cru.h"
struct rzg2l_cru_ip_format {
@@ -71,26 +72,17 @@ static int rzg2l_cru_ip_s_stream(struct v4l2_subdev *sd, int enable)
if (ret)
return ret;
+ fsleep(1000);
+
ret = rzg2l_cru_start_image_processing(cru);
if (ret) {
v4l2_subdev_call(cru->ip.remote, video, post_streamoff);
return ret;
}
- rzg2l_cru_vclk_unprepare(cru);
-
ret = v4l2_subdev_call(cru->ip.remote, video, s_stream, enable);
- if (ret == -ENOIOCTLCMD)
- ret = 0;
- if (!ret) {
- ret = rzg2l_cru_vclk_prepare(cru);
- if (!ret)
- return 0;
- } else {
- /* enable back vclk so that s_stream in error path disables it */
- if (rzg2l_cru_vclk_prepare(cru))
- dev_err(cru->dev, "Failed to enable vclk\n");
- }
+ if (!ret || ret == -ENOIOCTLCMD)
+ return 0;
s_stream_ret = ret;
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
index d0ffa90bc656..b16b8af6e8f8 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
@@ -430,13 +430,6 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru)
spin_lock_irqsave(&cru->qlock, flags);
- /* Initialize image convert */
- ret = rzg2l_cru_initialize_image_conv(cru, fmt);
- if (ret) {
- spin_unlock_irqrestore(&cru->qlock, flags);
- return ret;
- }
-
/* Select a video input */
rzg2l_cru_write(cru, CRUnCTRL, CRUnCTRL_VINSEL(0));
@@ -450,6 +443,13 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru)
/* Initialize the AXI master */
rzg2l_cru_initialize_axi(cru);
+ /* Initialize image convert */
+ ret = rzg2l_cru_initialize_image_conv(cru, fmt);
+ if (ret) {
+ spin_unlock_irqrestore(&cru->qlock, flags);
+ return ret;
+ }
+
/* Enable interrupt */
rzg2l_cru_write(cru, CRUnIE, CRUnIE_EFE);
@@ -461,16 +461,6 @@ int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru)
return 0;
}
-void rzg2l_cru_vclk_unprepare(struct rzg2l_cru_dev *cru)
-{
- clk_disable_unprepare(cru->vclk);
-}
-
-int rzg2l_cru_vclk_prepare(struct rzg2l_cru_dev *cru)
-{
- return clk_prepare_enable(cru->vclk);
-}
-
static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on)
{
struct media_pipeline *pipe;
@@ -499,39 +489,24 @@ static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on)
video_device_pipeline_stop(&cru->vdev);
- pm_runtime_put_sync(cru->dev);
- clk_disable_unprepare(cru->vclk);
-
return stream_off_ret;
}
- ret = pm_runtime_resume_and_get(cru->dev);
- if (ret)
- return ret;
-
- ret = clk_prepare_enable(cru->vclk);
- if (ret)
- goto err_pm_put;
-
ret = rzg2l_cru_mc_validate_format(cru, sd, pad);
if (ret)
- goto err_vclk_disable;
+ return ret;
pipe = media_entity_pipeline(&sd->entity) ? : &cru->vdev.pipe;
ret = video_device_pipeline_start(&cru->vdev, pipe);
if (ret)
- goto err_vclk_disable;
+ return ret;
ret = v4l2_subdev_call(sd, video, pre_streamon, 0);
- if (ret == -ENOIOCTLCMD)
- ret = 0;
- if (ret)
+ if (ret && ret != -ENOIOCTLCMD)
goto pipe_line_stop;
ret = v4l2_subdev_call(sd, video, s_stream, 1);
- if (ret == -ENOIOCTLCMD)
- ret = 0;
- if (ret)
+ if (ret && ret != -ENOIOCTLCMD)
goto err_s_stream;
return 0;
@@ -542,12 +517,6 @@ err_s_stream:
pipe_line_stop:
video_device_pipeline_stop(&cru->vdev);
-err_vclk_disable:
- clk_disable_unprepare(cru->vclk);
-
-err_pm_put:
- pm_runtime_put_sync(cru->dev);
-
return ret;
}
@@ -646,25 +615,33 @@ static int rzg2l_cru_start_streaming_vq(struct vb2_queue *vq, unsigned int count
struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq);
int ret;
+ ret = pm_runtime_resume_and_get(cru->dev);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(cru->vclk);
+ if (ret)
+ goto err_pm_put;
+
/* Release reset state */
ret = reset_control_deassert(cru->aresetn);
if (ret) {
dev_err(cru->dev, "failed to deassert aresetn\n");
- return ret;
+ goto err_vclk_disable;
}
ret = reset_control_deassert(cru->presetn);
if (ret) {
reset_control_assert(cru->aresetn);
dev_err(cru->dev, "failed to deassert presetn\n");
- return ret;
+ goto assert_aresetn;
}
ret = request_irq(cru->image_conv_irq, rzg2l_cru_irq,
IRQF_SHARED, KBUILD_MODNAME, cru);
if (ret) {
dev_err(cru->dev, "failed to request irq\n");
- goto assert_resets;
+ goto assert_presetn;
}
/* Allocate scratch buffer. */
@@ -696,10 +673,18 @@ out:
free_image_conv_irq:
free_irq(cru->image_conv_irq, cru);
-assert_resets:
+assert_presetn:
reset_control_assert(cru->presetn);
+
+assert_aresetn:
reset_control_assert(cru->aresetn);
+err_vclk_disable:
+ clk_disable_unprepare(cru->vclk);
+
+err_pm_put:
+ pm_runtime_put_sync(cru->dev);
+
return ret;
}
@@ -714,9 +699,11 @@ static void rzg2l_cru_stop_streaming_vq(struct vb2_queue *vq)
cru->scratch, cru->scratch_phys);
free_irq(cru->image_conv_irq, cru);
- reset_control_assert(cru->presetn);
-
return_unused_buffers(cru, VB2_BUF_STATE_ERROR);
+
+ reset_control_assert(cru->presetn);
+ clk_disable_unprepare(cru->vclk);
+ pm_runtime_put_sync(cru->dev);
}
static const struct vb2_ops rzg2l_cru_qops = {
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
index c381c22135a2..2bddb4fa8a5c 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
@@ -47,13 +47,18 @@ enum rkisp1_plane {
* @fourcc: pixel format
* @fmt_type: helper filed for pixel format
* @uv_swap: if cb cr swapped, for yuv
+ * @yc_swap: if y and cb/cr swapped, for yuv
+ * @byte_swap: if byte pairs are swapped, for raw
* @write_format: defines how YCbCr self picture data is written to memory
- * @output_format: defines sp output format
+ * @output_format: defines the output format (RKISP1_CIF_MI_INIT_MP_OUTPUT_* for
+ * the main path and RKISP1_MI_CTRL_SP_OUTPUT_* for the self path)
* @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 uv_swap : 1;
+ u32 yc_swap : 1;
+ u32 byte_swap : 1;
u32 write_format;
u32 output_format;
u32 mbus;
@@ -94,36 +99,50 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
.fourcc = V4L2_PIX_FMT_YUYV,
.uv_swap = 0,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
+ .mbus = MEDIA_BUS_FMT_YUYV8_2X8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .uv_swap = 0,
+ .yc_swap = 1,
+ .write_format = RKISP1_MI_CTRL_MP_WRITE_YUVINT,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
.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,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
}, {
.fourcc = V4L2_PIX_FMT_NV16,
.uv_swap = 0,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
}, {
.fourcc = V4L2_PIX_FMT_NV61,
.uv_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
}, {
.fourcc = V4L2_PIX_FMT_NV16M,
.uv_swap = 0,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
}, {
.fourcc = V4L2_PIX_FMT_NV61M,
.uv_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
.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,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422,
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
},
/* yuv400 */
@@ -131,6 +150,7 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
.fourcc = V4L2_PIX_FMT_GREY,
.uv_swap = 0,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400,
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
},
/* yuv420 */
@@ -138,81 +158,107 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_mp_fmts[] = {
.fourcc = V4L2_PIX_FMT_NV21,
.uv_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
}, {
.fourcc = V4L2_PIX_FMT_NV12,
.uv_swap = 0,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
}, {
.fourcc = V4L2_PIX_FMT_NV21M,
.uv_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
}, {
.fourcc = V4L2_PIX_FMT_NV12M,
.uv_swap = 0,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_SPLA,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
.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,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
.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,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420,
.mbus = MEDIA_BUS_FMT_YUYV8_1_5X8,
},
/* raw */
{
.fourcc = V4L2_PIX_FMT_SRGGB8,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
.mbus = MEDIA_BUS_FMT_SRGGB8_1X8,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG8,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
.mbus = MEDIA_BUS_FMT_SGRBG8_1X8,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG8,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
.mbus = MEDIA_BUS_FMT_SGBRG8_1X8,
}, {
.fourcc = V4L2_PIX_FMT_SBGGR8,
.write_format = RKISP1_MI_CTRL_MP_WRITE_YUV_PLA_OR_RAW8,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8,
.mbus = MEDIA_BUS_FMT_SBGGR8_1X8,
}, {
.fourcc = V4L2_PIX_FMT_SRGGB10,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
.mbus = MEDIA_BUS_FMT_SRGGB10_1X10,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG10,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
.mbus = MEDIA_BUS_FMT_SGRBG10_1X10,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG10,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
.mbus = MEDIA_BUS_FMT_SGBRG10_1X10,
}, {
.fourcc = V4L2_PIX_FMT_SBGGR10,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10,
.mbus = MEDIA_BUS_FMT_SBGGR10_1X10,
}, {
.fourcc = V4L2_PIX_FMT_SRGGB12,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
.mbus = MEDIA_BUS_FMT_SRGGB12_1X12,
}, {
.fourcc = V4L2_PIX_FMT_SGRBG12,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
.mbus = MEDIA_BUS_FMT_SGRBG12_1X12,
}, {
.fourcc = V4L2_PIX_FMT_SGBRG12,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
.mbus = MEDIA_BUS_FMT_SGBRG12_1X12,
}, {
.fourcc = V4L2_PIX_FMT_SBGGR12,
+ .byte_swap = 1,
.write_format = RKISP1_MI_CTRL_MP_WRITE_RAW12,
+ .output_format = RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12,
.mbus = MEDIA_BUS_FMT_SBGGR12_1X12,
},
};
@@ -230,6 +276,13 @@ static const struct rkisp1_capture_fmt_cfg rkisp1_sp_fmts[] = {
.output_format = RKISP1_MI_CTRL_SP_OUTPUT_YUV422,
.mbus = MEDIA_BUS_FMT_YUYV8_2X8,
}, {
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .uv_swap = 0,
+ .yc_swap = 1,
+ .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,
@@ -442,6 +495,14 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
rkisp1_write(rkisp1, cap->config->mi.cr_size_init,
rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
+ if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_LLENGTH, cap->stride);
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_WIDTH, pixm->width);
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_HEIGHT, pixm->height);
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_MP_Y_PIC_SIZE,
+ cap->stride * pixm->height);
+ }
+
rkisp1_irq_frame_end_enable(cap);
/* set uv swapping for semiplanar formats */
@@ -454,6 +515,25 @@ static void rkisp1_mp_config(struct rkisp1_capture *cap)
rkisp1_write(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL, reg);
}
+ /*
+ * U/V swapping with the MI_XTD_FORMAT_CTRL register only works for
+ * NV12/NV21 and NV16/NV61, so instead use byte swap to support UYVY.
+ * YVYU and VYUY cannot be supported with this method.
+ */
+ if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
+ reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
+ if (cap->pix.cfg->yc_swap || cap->pix.cfg->byte_swap)
+ reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
+ else
+ reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES;
+
+ reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT;
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
+
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT,
+ cap->pix.cfg->output_format);
+ }
+
rkisp1_mi_config_ctrl(cap);
reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
@@ -479,11 +559,11 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
rkisp1_write(rkisp1, cap->config->mi.cr_size_init,
rkisp1_pixfmt_comp_size(pixm, RKISP1_PLANE_CR));
- rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_LLENGTH, cap->sp_y_stride);
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_LLENGTH, cap->stride);
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_WIDTH, pixm->width);
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_HEIGHT, pixm->height);
rkisp1_write(rkisp1, RKISP1_CIF_MI_SP_Y_PIC_SIZE,
- cap->sp_y_stride * pixm->height);
+ cap->stride * pixm->height);
rkisp1_irq_frame_end_enable(cap);
@@ -497,6 +577,20 @@ static void rkisp1_sp_config(struct rkisp1_capture *cap)
rkisp1_write(rkisp1, RKISP1_CIF_MI_XTD_FORMAT_CTRL, reg);
}
+ /*
+ * U/V swapping with the MI_XTD_FORMAT_CTRL register only works for
+ * NV12/NV21 and NV16/NV61, so instead use byte swap to support UYVY.
+ * YVYU and VYUY cannot be supported with this method.
+ */
+ if (rkisp1_has_feature(rkisp1, MAIN_STRIDE)) {
+ reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT);
+ if (cap->pix.cfg->yc_swap)
+ reg |= RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES;
+ else
+ reg &= ~RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES;
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT, reg);
+ }
+
rkisp1_mi_config_ctrl(cap);
mi_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_MI_CTRL);
@@ -640,11 +734,13 @@ static void rkisp1_dummy_buf_destroy(struct rkisp1_capture *cap)
static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
{
+ u8 shift = rkisp1_has_feature(cap->rkisp1, DMA_34BIT) ? 2 : 0;
+
cap->buf.curr = cap->buf.next;
cap->buf.next = NULL;
if (!list_empty(&cap->buf.queue)) {
- u32 *buff_addr;
+ dma_addr_t *buff_addr;
cap->buf.next = list_first_entry(&cap->buf.queue, struct rkisp1_buffer, queue);
list_del(&cap->buf.next->queue);
@@ -652,7 +748,7 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
buff_addr = cap->buf.next->buff_addr;
rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
- buff_addr[RKISP1_PLANE_Y]);
+ buff_addr[RKISP1_PLANE_Y] >> shift);
/*
* In order to support grey format we capture
* YUV422 planar format from the camera and
@@ -661,17 +757,17 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
if (cap->pix.cfg->fourcc == V4L2_PIX_FMT_GREY) {
rkisp1_write(cap->rkisp1,
cap->config->mi.cb_base_ad_init,
- cap->buf.dummy.dma_addr);
+ cap->buf.dummy.dma_addr >> shift);
rkisp1_write(cap->rkisp1,
cap->config->mi.cr_base_ad_init,
- cap->buf.dummy.dma_addr);
+ cap->buf.dummy.dma_addr >> shift);
} else {
rkisp1_write(cap->rkisp1,
cap->config->mi.cb_base_ad_init,
- buff_addr[RKISP1_PLANE_CB]);
+ buff_addr[RKISP1_PLANE_CB] >> shift);
rkisp1_write(cap->rkisp1,
cap->config->mi.cr_base_ad_init,
- buff_addr[RKISP1_PLANE_CR]);
+ buff_addr[RKISP1_PLANE_CR] >> shift);
}
} else {
/*
@@ -679,11 +775,11 @@ static void rkisp1_set_next_buf(struct rkisp1_capture *cap)
* throw data if there is no available buffer.
*/
rkisp1_write(cap->rkisp1, cap->config->mi.y_base_ad_init,
- cap->buf.dummy.dma_addr);
+ cap->buf.dummy.dma_addr >> shift);
rkisp1_write(cap->rkisp1, cap->config->mi.cb_base_ad_init,
- cap->buf.dummy.dma_addr);
+ cap->buf.dummy.dma_addr >> shift);
rkisp1_write(cap->rkisp1, cap->config->mi.cr_base_ad_init,
- cap->buf.dummy.dma_addr);
+ cap->buf.dummy.dma_addr >> shift);
}
/* Set plane offsets */
@@ -722,6 +818,7 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
{
struct device *dev = ctx;
struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
+ unsigned int dev_count = rkisp1_path_count(rkisp1);
unsigned int i;
u32 status;
@@ -734,7 +831,7 @@ irqreturn_t rkisp1_capture_isr(int irq, void *ctx)
rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, status);
- for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); ++i) {
+ for (i = 0; i < dev_count; ++i) {
struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
if (!(status & RKISP1_CIF_MI_FRAME(cap)))
@@ -891,6 +988,7 @@ 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];
+ bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
cap->ops->set_data_path(cap);
cap->ops->config(cap);
@@ -899,19 +997,40 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap)
spin_lock_irq(&cap->buf.lock);
rkisp1_set_next_buf(cap);
cap->ops->enable(cap);
- /* It's safe to configure ACTIVE and SHADOW registers for the
- * first stream. While when the second is starting, do NOT
- * force update because it also updates the first one.
+
+ /*
+ * It's safe to configure ACTIVE and SHADOW registers for the first
+ * stream. While when the second is starting, do NOT force update
+ * because it also updates the first one.
*
- * The latter case would drop one more buffer(that is 2) since
- * there's no buffer in a shadow register when the second FE received.
- * This's also required because the second FE maybe corrupt
- * especially when run at 120fps.
+ * The latter case would drop one more buffer(that is 2) since there's
+ * no buffer in a shadow register 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,
- RKISP1_CIF_MI_INIT_SOFT_UPD);
+ if (!has_self_path || !other->is_streaming) {
+ u32 reg;
+
+ /*
+ * Force cfg update.
+ *
+ * The ISP8000 (implementing the MAIN_STRIDE feature) as a
+ * mp_output_format field in the CIF_MI_INIT register that must
+ * be preserved. It can be read back, but it is not clear what
+ * other register bits will return. Mask them out.
+ *
+ * On Rockchip platforms, the CIF_MI_INIT register is marked as
+ * write-only and reads as zeros. We can skip reading it.
+ */
+ if (rkisp1_has_feature(rkisp1, MAIN_STRIDE))
+ reg = rkisp1_read(rkisp1, RKISP1_CIF_MI_INIT)
+ & RKISP1_CIF_MI_INIT_MP_OUTPUT_MASK;
+ else
+ reg = 0;
+
+ reg |= RKISP1_CIF_MI_INIT_SOFT_UPD;
+ rkisp1_write(rkisp1, RKISP1_CIF_MI_INIT, reg);
+
rkisp1_set_next_buf(cap);
}
spin_unlock_irq(&cap->buf.lock);
@@ -1095,8 +1214,8 @@ static const struct vb2_ops rkisp1_vb2_ops = {
*/
static const struct v4l2_format_info *
-rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
- enum rkisp1_stream_id id)
+rkisp1_fill_pixfmt(const struct rkisp1_capture *cap,
+ struct v4l2_pix_format_mplane *pixm)
{
struct v4l2_plane_pix_format *plane_y = &pixm->plane_fmt[0];
const struct v4l2_format_info *info;
@@ -1109,10 +1228,13 @@ rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
/*
* The SP supports custom strides, expressed as a number of pixels for
- * the Y plane. Clamp the stride to a reasonable value to avoid integer
- * overflows when calculating the bytesperline and sizeimage values.
+ * the Y plane, and so does the MP in ISP versions that have the
+ * MAIN_STRIDE feature. Clamp the stride to a reasonable value to avoid
+ * integer overflows when calculating the bytesperline and sizeimage
+ * values.
*/
- if (id == RKISP1_SELFPATH)
+ if (cap->id == RKISP1_SELFPATH ||
+ rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE))
stride = clamp(DIV_ROUND_UP(plane_y->bytesperline, info->bpp[0]),
pixm->width, 65536U);
else
@@ -1147,10 +1269,14 @@ rkisp1_fill_pixfmt(struct v4l2_pix_format_mplane *pixm,
static const struct rkisp1_capture_fmt_cfg *
rkisp1_find_fmt_cfg(const struct rkisp1_capture *cap, const u32 pixelfmt)
{
+ bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE);
unsigned int i;
for (i = 0; i < cap->config->fmt_size; i++) {
- if (cap->config->fmts[i].fourcc == pixelfmt)
+ const struct rkisp1_capture_fmt_cfg *fmt = &cap->config->fmts[i];
+
+ if (fmt->fourcc == pixelfmt &&
+ (!fmt->yc_swap || yc_swap_support))
return &cap->config->fmts[i];
}
return NULL;
@@ -1187,7 +1313,7 @@ static void rkisp1_try_fmt(const struct rkisp1_capture *cap,
pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
pixm->quantization = V4L2_QUANTIZATION_DEFAULT;
- info = rkisp1_fill_pixfmt(pixm, cap->id);
+ info = rkisp1_fill_pixfmt(cap, pixm);
if (fmt_cfg)
*fmt_cfg = fmt;
@@ -1199,12 +1325,9 @@ 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];
+ cap->pix.fmt = *pixm;
+ cap->stride = pixm->plane_fmt[0].bytesperline / cap->pix.info->bpp[0];
}
static int rkisp1_try_fmt_vid_cap_mplane(struct file *file, void *fh,
@@ -1222,23 +1345,29 @@ static int rkisp1_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
{
struct rkisp1_capture *cap = video_drvdata(file);
const struct rkisp1_capture_fmt_cfg *fmt = NULL;
+ bool yc_swap_support = rkisp1_has_feature(cap->rkisp1, MAIN_STRIDE);
unsigned int i, n = 0;
- if (!f->mbus_code) {
- if (f->index >= cap->config->fmt_size)
- return -EINVAL;
+ if (f->index >= cap->config->fmt_size)
+ return -EINVAL;
+ if (!f->mbus_code && yc_swap_support) {
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)
+ fmt = &cap->config->fmts[i];
+
+ if (f->mbus_code && fmt->mbus != f->mbus_code)
+ continue;
+
+ if (!yc_swap_support && fmt->yc_swap)
continue;
if (n++ == f->index) {
- f->pixelformat = cap->config->fmts[i].fourcc;
+ f->pixelformat = fmt->fourcc;
return 0;
}
}
@@ -1501,10 +1630,11 @@ rkisp1_capture_init(struct rkisp1_device *rkisp1, enum rkisp1_stream_id id)
int rkisp1_capture_devs_register(struct rkisp1_device *rkisp1)
{
+ unsigned int dev_count = rkisp1_path_count(rkisp1);
unsigned int i;
int ret;
- for (i = 0; i < ARRAY_SIZE(rkisp1->capture_devs); i++) {
+ for (i = 0; i < dev_count; i++) {
struct rkisp1_capture *cap = &rkisp1->capture_devs[i];
rkisp1_capture_init(rkisp1, i);
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
index b757f75edecf..26573f6ae575 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
@@ -24,6 +24,7 @@
#include "rkisp1-regs.h"
struct dentry;
+struct regmap;
/*
* flags on the 'direction' field in struct rkisp1_mbus_info' that indicate
@@ -110,6 +111,10 @@ enum rkisp1_isp_pad {
* enum rkisp1_feature - ISP features
*
* @RKISP1_FEATURE_MIPI_CSI2: The ISP has an internal MIPI CSI-2 receiver
+ * @RKISP1_FEATURE_MAIN_STRIDE: The ISP supports configurable stride on the main path
+ * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path
+ * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input
+ * @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA addresses
*
* The ISP features are stored in a bitmask in &rkisp1_info.features and allow
* the driver to implement support for features present in some ISP versions
@@ -117,8 +122,15 @@ enum rkisp1_isp_pad {
*/
enum rkisp1_feature {
RKISP1_FEATURE_MIPI_CSI2 = BIT(0),
+ RKISP1_FEATURE_MAIN_STRIDE = BIT(1),
+ RKISP1_FEATURE_SELF_PATH = BIT(2),
+ RKISP1_FEATURE_DUAL_CROP = BIT(3),
+ RKISP1_FEATURE_DMA_34BIT = BIT(4),
};
+#define rkisp1_has_feature(rkisp1, feature) \
+ ((rkisp1)->info->features & RKISP1_FEATURE_##feature)
+
/*
* struct rkisp1_info - Model-specific ISP Information
*
@@ -229,7 +241,7 @@ struct rkisp1_vdev_node {
struct rkisp1_buffer {
struct vb2_v4l2_buffer vb;
struct list_head queue;
- u32 buff_addr[VIDEO_MAX_PLANES];
+ dma_addr_t buff_addr[VIDEO_MAX_PLANES];
};
/*
@@ -263,7 +275,7 @@ struct rkisp1_device;
* 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.
+ * @stride: the line stride for the first plane, in pixel units
* @buf.lock: lock to protect buf.queue
* @buf.queue: queued buffer list
* @buf.dummy: dummy space to store dropped data
@@ -284,7 +296,7 @@ struct rkisp1_capture {
bool is_streaming;
bool is_stopping;
wait_queue_head_t done;
- unsigned int sp_y_stride;
+ unsigned int stride;
struct {
/* protects queue, curr and next */
spinlock_t lock;
@@ -435,6 +447,8 @@ struct rkisp1_debug {
* @dev: a pointer to the struct device
* @clk_size: number of clocks
* @clks: array of clocks
+ * @gasket: the gasket - i.MX8MP only
+ * @gasket_id: the gasket ID (0 or 1) - i.MX8MP only
* @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
@@ -457,6 +471,8 @@ struct rkisp1_device {
struct device *dev;
unsigned int clk_size;
struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK];
+ struct regmap *gasket;
+ unsigned int gasket_id;
struct v4l2_device v4l2_dev;
struct media_device media_dev;
struct v4l2_async_notifier notifier;
@@ -527,6 +543,19 @@ int rkisp1_cap_enum_mbus_codes(struct rkisp1_capture *cap,
const struct rkisp1_mbus_info *rkisp1_mbus_info_get_by_index(unsigned int index);
/*
+ * rkisp1_path_count - Return the number of paths supported by the device
+ *
+ * Some devices only have a main path, while other device have both a main path
+ * and a self path. This function returns the number of paths that this device
+ * has, based on the feature flags. It should be used insted of checking
+ * ARRAY_SIZE of capture_devs/resizer_devs.
+ */
+static inline unsigned int rkisp1_path_count(struct rkisp1_device *rkisp1)
+{
+ return rkisp1_has_feature(rkisp1, SELF_PATH) ? 2 : 1;
+}
+
+/*
* rkisp1_sd_adjust_crop_rect - adjust a rectangle to fit into another rectangle.
*
* @crop: rectangle to adjust.
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 73cf08a74011..bb0202386c70 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
@@ -207,7 +208,7 @@ static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
switch (reg) {
case 0:
/* MIPI CSI-2 port */
- if (!(rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)) {
+ if (!rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
dev_err(rkisp1->dev,
"internal CSI must be available for port 0\n");
ret = -EINVAL;
@@ -358,10 +359,11 @@ static const struct dev_pm_ops rkisp1_pm_ops = {
static int rkisp1_create_links(struct rkisp1_device *rkisp1)
{
+ unsigned int dev_count = rkisp1_path_count(rkisp1);
unsigned int i;
int ret;
- if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
+ if (rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
/* Link the CSI receiver to the ISP. */
ret = media_create_pad_link(&rkisp1->csi.sd.entity,
RKISP1_CSI_PAD_SRC,
@@ -373,7 +375,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
}
/* create ISP->RSZ->CAP links */
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < dev_count; i++) {
struct media_entity *resizer =
&rkisp1->resizer_devs[i].sd.entity;
struct media_entity *capture =
@@ -413,7 +415,7 @@ static int rkisp1_create_links(struct rkisp1_device *rkisp1)
static void rkisp1_entities_unregister(struct rkisp1_device *rkisp1)
{
- if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
+ if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
rkisp1_csi_unregister(rkisp1);
rkisp1_params_unregister(rkisp1);
rkisp1_stats_unregister(rkisp1);
@@ -446,7 +448,7 @@ static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
if (ret)
goto error;
- if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
+ if (rkisp1_has_feature(rkisp1, MIPI_CSI2)) {
ret = rkisp1_csi_register(rkisp1);
if (ret)
goto error;
@@ -505,7 +507,9 @@ static const struct rkisp1_info px30_isp_info = {
.isrs = px30_isp_isrs,
.isr_size = ARRAY_SIZE(px30_isp_isrs),
.isp_ver = RKISP1_V12,
- .features = RKISP1_FEATURE_MIPI_CSI2,
+ .features = RKISP1_FEATURE_MIPI_CSI2
+ | RKISP1_FEATURE_SELF_PATH
+ | RKISP1_FEATURE_DUAL_CROP,
};
static const char * const rk3399_isp_clks[] = {
@@ -524,7 +528,29 @@ static const struct rkisp1_info rk3399_isp_info = {
.isrs = rk3399_isp_isrs,
.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
.isp_ver = RKISP1_V10,
- .features = RKISP1_FEATURE_MIPI_CSI2,
+ .features = RKISP1_FEATURE_MIPI_CSI2
+ | RKISP1_FEATURE_SELF_PATH
+ | RKISP1_FEATURE_DUAL_CROP,
+};
+
+static const char * const imx8mp_isp_clks[] = {
+ "isp",
+ "hclk",
+ "aclk",
+};
+
+static const struct rkisp1_isr_data imx8mp_isp_isrs[] = {
+ { NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) },
+};
+
+static const struct rkisp1_info imx8mp_isp_info = {
+ .clks = imx8mp_isp_clks,
+ .clk_size = ARRAY_SIZE(imx8mp_isp_clks),
+ .isrs = imx8mp_isp_isrs,
+ .isr_size = ARRAY_SIZE(imx8mp_isp_isrs),
+ .isp_ver = RKISP1_V_IMX8MP,
+ .features = RKISP1_FEATURE_MAIN_STRIDE
+ | RKISP1_FEATURE_DMA_34BIT,
};
static const struct of_device_id rkisp1_of_match[] = {
@@ -536,6 +562,10 @@ static const struct of_device_id rkisp1_of_match[] = {
.compatible = "rockchip,rk3399-cif-isp",
.data = &rk3399_isp_info,
},
+ {
+ .compatible = "fsl,imx8mp-isp",
+ .data = &imx8mp_isp_info,
+ },
{},
};
MODULE_DEVICE_TABLE(of, rkisp1_of_match);
@@ -547,6 +577,7 @@ static int rkisp1_probe(struct platform_device *pdev)
struct rkisp1_device *rkisp1;
struct v4l2_device *v4l2_dev;
unsigned int i;
+ u64 dma_mask;
int ret, irq;
u32 cif_id;
@@ -560,6 +591,13 @@ static int rkisp1_probe(struct platform_device *pdev)
dev_set_drvdata(dev, rkisp1);
rkisp1->dev = dev;
+ dma_mask = rkisp1_has_feature(rkisp1, DMA_34BIT) ? DMA_BIT_MASK(34) :
+ DMA_BIT_MASK(32);
+
+ ret = dma_set_mask_and_coherent(dev, dma_mask);
+ if (ret)
+ return ret;
+
mutex_init(&rkisp1->stream_lock);
rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
@@ -596,6 +634,21 @@ static int rkisp1_probe(struct platform_device *pdev)
return ret;
rkisp1->clk_size = info->clk_size;
+ if (info->isp_ver == RKISP1_V_IMX8MP) {
+ unsigned int id;
+
+ rkisp1->gasket = syscon_regmap_lookup_by_phandle_args(dev->of_node,
+ "fsl,blk-ctrl",
+ 1, &id);
+ if (IS_ERR(rkisp1->gasket)) {
+ ret = PTR_ERR(rkisp1->gasket);
+ dev_err(dev, "failed to get gasket: %d\n", ret);
+ return ret;
+ }
+
+ rkisp1->gasket_id = id;
+ }
+
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_resume_and_get(&pdev->dev);
@@ -650,7 +703,7 @@ static int rkisp1_probe(struct platform_device *pdev)
err_unreg_entities:
rkisp1_entities_unregister(rkisp1);
err_cleanup_csi:
- if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
+ if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
rkisp1_csi_cleanup(rkisp1);
err_unreg_media_dev:
media_device_unregister(&rkisp1->media_dev);
@@ -671,7 +724,7 @@ static void rkisp1_remove(struct platform_device *pdev)
v4l2_async_nf_cleanup(&rkisp1->notifier);
rkisp1_entities_unregister(rkisp1);
- if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
+ if (rkisp1_has_feature(rkisp1, MIPI_CSI2))
rkisp1_csi_cleanup(rkisp1);
rkisp1_debug_cleanup(rkisp1);
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
index 78a1f7a1499b..e45a213baf49 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
@@ -10,6 +10,7 @@
#include <linux/iopoll.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
@@ -53,6 +54,115 @@
* +---------------------------------------------------------+
*/
+/* -----------------------------------------------------------------------------
+ * Media block control (i.MX8MP only)
+ */
+
+#define ISP_DEWARP_CONTROL 0x0138
+
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY BIT(22)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_RISING (0 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_NEGATIVE (1 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE (2 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_FALLING (3 << 20)
+#define ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK GENMASK(21, 20)
+#define ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE BIT(19)
+#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt) ((dt) << 13)
+#define ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK GENMASK(18, 13)
+
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY BIT(12)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_RISING (0 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_NEGATIVE (1 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE (2 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_FALLING (3 << 10)
+#define ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK GENMASK(11, 10)
+#define ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE BIT(9)
+#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt) ((dt) << 3)
+#define ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK GENMASK(8, 3)
+
+#define ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE BIT(1)
+#define ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE BIT(0)
+
+static int rkisp1_gasket_enable(struct rkisp1_device *rkisp1,
+ struct media_pad *source)
+{
+ struct v4l2_subdev *source_sd;
+ struct v4l2_mbus_frame_desc fd;
+ unsigned int dt;
+ u32 mask;
+ u32 val;
+ int ret;
+
+ /*
+ * Configure and enable the gasket with the CSI-2 data type. Set the
+ * vsync polarity as active high, as that is what the ISP is configured
+ * to expect in ISP_ACQ_PROP. Enable left justification, as the i.MX8MP
+ * ISP has a 16-bit wide input and expects data to be left-aligned.
+ */
+
+ source_sd = media_entity_to_v4l2_subdev(source->entity);
+ ret = v4l2_subdev_call(source_sd, pad, get_frame_desc,
+ source->index, &fd);
+ if (ret) {
+ dev_err(rkisp1->dev,
+ "failed to get frame descriptor from '%s':%u: %d\n",
+ source_sd->name, 0, ret);
+ return ret;
+ }
+
+ if (fd.num_entries != 1) {
+ dev_err(rkisp1->dev, "invalid frame descriptor for '%s':%u\n",
+ source_sd->name, 0);
+ return -EINVAL;
+ }
+
+ dt = fd.entry[0].bus.csi2.dt;
+
+ if (rkisp1->gasket_id == 0) {
+ mask = ISP_DEWARP_CONTROL_MIPI_CSI1_HS_POLARITY
+ | ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_MASK
+ | ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
+ | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
+ | ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
+ val = ISP_DEWARP_CONTROL_MIPI_CSI1_VS_SEL_POSITIVE
+ | ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
+ | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE(dt);
+ } else {
+ mask = ISP_DEWARP_CONTROL_MIPI_CSI2_HS_POLARITY
+ | ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_MASK
+ | ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
+ | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
+ | ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
+ val = ISP_DEWARP_CONTROL_MIPI_CSI2_VS_SEL_POSITIVE
+ | ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
+ | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE(dt);
+ }
+
+ regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
+
+ return 0;
+}
+
+static void rkisp1_gasket_disable(struct rkisp1_device *rkisp1)
+{
+ u32 mask;
+ u32 val;
+
+ if (rkisp1->gasket_id == 1) {
+ mask = ISP_DEWARP_CONTROL_MIPI_ISP2_LEFT_JUST_MODE
+ | ISP_DEWARP_CONTROL_MIPI_ISP2_DATA_TYPE_MASK
+ | ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
+ val = ISP_DEWARP_CONTROL_GPR_ISP_1_DISABLE;
+ } else {
+ mask = ISP_DEWARP_CONTROL_MIPI_ISP1_LEFT_JUST_MODE
+ | ISP_DEWARP_CONTROL_MIPI_ISP1_DATA_TYPE_MASK
+ | ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
+ val = ISP_DEWARP_CONTROL_GPR_ISP_0_DISABLE;
+ }
+
+ regmap_update_bits(rkisp1->gasket, ISP_DEWARP_CONTROL, mask, val);
+}
+
/* ----------------------------------------------------------------------------
* Camera Interface registers configurations
*/
@@ -291,6 +401,9 @@ static void rkisp1_isp_stop(struct rkisp1_isp *isp)
RKISP1_CIF_VI_IRCL_MIPI_SW_RST |
RKISP1_CIF_VI_IRCL_ISP_SW_RST);
rkisp1_write(rkisp1, RKISP1_CIF_VI_IRCL, 0x0);
+
+ if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP)
+ rkisp1_gasket_disable(rkisp1);
}
static void rkisp1_config_clk(struct rkisp1_isp *isp)
@@ -315,16 +428,24 @@ static void rkisp1_config_clk(struct rkisp1_isp *isp)
}
}
-static void rkisp1_isp_start(struct rkisp1_isp *isp,
- struct v4l2_subdev_state *sd_state)
+static int rkisp1_isp_start(struct rkisp1_isp *isp,
+ struct v4l2_subdev_state *sd_state,
+ struct media_pad *source)
{
struct rkisp1_device *rkisp1 = isp->rkisp1;
const struct v4l2_mbus_framefmt *src_fmt;
const struct rkisp1_mbus_info *src_info;
u32 val;
+ int ret;
rkisp1_config_clk(isp);
+ if (rkisp1->info->isp_ver == RKISP1_V_IMX8MP) {
+ ret = rkisp1_gasket_enable(rkisp1, source);
+ if (ret)
+ return ret;
+ }
+
/* Activate ISP */
val = rkisp1_read(rkisp1, RKISP1_CIF_ISP_CTRL);
val |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD |
@@ -338,6 +459,8 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp,
if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)
rkisp1_params_post_configure(&rkisp1->params);
+
+ return 0;
}
/* ----------------------------------------------------------------------------
@@ -848,7 +971,9 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
if (ret)
goto out_unlock;
- rkisp1_isp_start(isp, sd_state);
+ ret = rkisp1_isp_start(isp, sd_state, source_pad);
+ if (ret)
+ goto out_unlock;
ret = v4l2_subdev_call(rkisp1->source, video, s_stream, true);
if (ret) {
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
index bea69a0d766a..fccf4c17ee8d 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
@@ -144,6 +144,15 @@
/* MI_INIT */
#define RKISP1_CIF_MI_INIT_SKIP BIT(2)
#define RKISP1_CIF_MI_INIT_SOFT_UPD BIT(4)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV400 (0 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV420 (1 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV422 (2 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_YUV444 (3 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW12 (4 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW8 (5 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_JPEG (6 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_RAW10 (7 << 5)
+#define RKISP1_CIF_MI_INIT_MP_OUTPUT_MASK (15 << 5)
/* MI_CTRL_SHD */
#define RKISP1_CIF_MI_CTRL_SHD_MP_IN_ENABLED BIT(0)
@@ -207,6 +216,24 @@
#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)
+/* MI_OUTPUT_ALIGN_FORMAT */
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_LSB_ALIGNMENT BIT(0)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_BYTES BIT(1)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_WORDS BIT(2)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_MP_BYTE_SWAP_DWORDS BIT(3)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_BYTES BIT(4)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_WORDS BIT(5)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_SP_BYTE_SWAP_DWORDS BIT(6)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_BYTES BIT(7)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_WORDS BIT(8)
+#define RKISP1_CIF_OUTPUT_ALIGN_FORMAT_DMA_BYTE_SWAP_DWORDS BIT(9)
+
+/* MI_MP_OUTPUT_FIFO_SIZE */
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_FULL (0 << 0)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_HALF (1 << 0)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_QUARTER (2 << 0)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE_OUTPUT_FIFO_DEPTH_EIGHT (3 << 0)
+
/* VI_CCL */
#define RKISP1_CIF_CCL_CIF_CLK_DIS BIT(2)
/* VI_ISP_CLK_CTRL */
@@ -1000,6 +1027,15 @@
#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_MI_MP_HANDSHAKE_0 (RKISP1_CIF_MI_BASE + 0x0000014C)
+#define RKISP1_CIF_MI_MP_Y_LLENGTH (RKISP1_CIF_MI_BASE + 0x00000150)
+#define RKISP1_CIF_MI_MP_Y_SLICE_OFFSET (RKISP1_CIF_MI_BASE + 0x00000154)
+#define RKISP1_CIF_MI_MP_C_SLICE_OFFSET (RKISP1_CIF_MI_BASE + 0x00000158)
+#define RKISP1_CIF_MI_OUTPUT_ALIGN_FORMAT (RKISP1_CIF_MI_BASE + 0x0000015C)
+#define RKISP1_CIF_MI_MP_OUTPUT_FIFO_SIZE (RKISP1_CIF_MI_BASE + 0x00000160)
+#define RKISP1_CIF_MI_MP_Y_PIC_WIDTH (RKISP1_CIF_MI_BASE + 0x00000164)
+#define RKISP1_CIF_MI_MP_Y_PIC_HEIGHT (RKISP1_CIF_MI_BASE + 0x00000168)
+#define RKISP1_CIF_MI_MP_Y_PIC_SIZE (RKISP1_CIF_MI_BASE + 0x0000016C)
#define RKISP1_CIF_SMIA_BASE 0x00001a00
#define RKISP1_CIF_SMIA_CTRL (RKISP1_CIF_SMIA_BASE + 0x00000000)
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
index a8e377701302..6f3931ca5b51 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
@@ -444,11 +444,12 @@ static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz,
sink_fmt = v4l2_subdev_state_get_format(sd_state, RKISP1_RSZ_PAD_SINK);
sink_crop = v4l2_subdev_state_get_crop(sd_state, RKISP1_RSZ_PAD_SINK);
- /* Not crop for MP bayer raw data */
+ /* Not crop for MP bayer raw data, or for devices lacking dual crop. */
mbus_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
- if (rsz->id == RKISP1_MAINPATH &&
- mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
+ if ((rsz->id == RKISP1_MAINPATH &&
+ mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) ||
+ !rkisp1_has_feature(rsz->rkisp1, DUAL_CROP)) {
sink_crop->left = 0;
sink_crop->top = 0;
sink_crop->width = sink_fmt->width;
@@ -631,21 +632,24 @@ static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable)
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;
+ bool has_self_path = rkisp1_has_feature(rkisp1, SELF_PATH);
struct v4l2_subdev_state *sd_state;
if (!enable) {
- rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
+ if (rkisp1_has_feature(rkisp1, DUAL_CROP))
+ rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC);
return 0;
}
- if (other->is_streaming)
+ if (has_self_path && other->is_streaming)
when = RKISP1_SHADOW_REGS_ASYNC;
sd_state = v4l2_subdev_lock_and_get_active_state(sd);
rkisp1_rsz_config(rsz, sd_state, when);
- rkisp1_dcrop_config(rsz, sd_state);
+ if (rkisp1_has_feature(rkisp1, DUAL_CROP))
+ rkisp1_dcrop_config(rsz, sd_state);
v4l2_subdev_unlock_state(sd_state);
@@ -731,10 +735,11 @@ err_entity_cleanup:
int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1)
{
+ unsigned int dev_count = rkisp1_path_count(rkisp1);
unsigned int i;
int ret;
- for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) {
+ for (i = 0; i < dev_count; i++) {
struct rkisp1_resizer *rsz = &rkisp1->resizer_devs[i];
rsz->rkisp1 = rkisp1;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
index 05cafba1c728..ffa4ea21387d 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c
@@ -180,7 +180,7 @@ void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
struct fimc_vid_cap *cap = &fimc->vid_cap;
struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe);
struct v4l2_subdev *csis = p->subdevs[IDX_CSIS];
- struct fimc_frame *f = &cap->ctx->d_frame;
+ const struct fimc_frame *f = &cap->ctx->d_frame;
struct fimc_vid_buffer *v_buf;
if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
@@ -342,8 +342,8 @@ static int queue_setup(struct vb2_queue *vq,
unsigned int sizes[], struct device *alloc_devs[])
{
struct fimc_ctx *ctx = vq->drv_priv;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_fmt *fmt = frame->fmt;
+ const struct fimc_frame *frame = &ctx->d_frame;
+ const struct fimc_fmt *fmt = frame->fmt;
unsigned long wh = frame->f_width * frame->f_height;
int i;
@@ -559,18 +559,18 @@ static const struct v4l2_file_operations fimc_capture_fops = {
* Format and crop negotiation helpers
*/
-static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
- u32 *width, u32 *height,
- u32 *code, u32 *fourcc, int pad)
+static const struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
+ u32 *width, u32 *height,
+ u32 *code, u32 *fourcc, int pad)
{
bool rotation = ctx->rotation == 90 || ctx->rotation == 270;
struct fimc_dev *fimc = ctx->fimc_dev;
const struct fimc_variant *var = fimc->variant;
const struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *dst = &ctx->d_frame;
+ const struct fimc_frame *dst = &ctx->d_frame;
u32 depth, min_w, max_w, min_h, align_h = 3;
+ const struct fimc_fmt *ffmt;
u32 mask = FMT_FLAGS_CAM;
- struct fimc_fmt *ffmt;
/* Conversion from/to JPEG or User Defined format is not supported */
if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
@@ -644,7 +644,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx,
struct fimc_dev *fimc = ctx->fimc_dev;
const struct fimc_variant *var = fimc->variant;
const struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *sink = &ctx->s_frame;
+ const struct fimc_frame *sink = &ctx->s_frame;
u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
u32 align_sz = 0, align_h = 4;
u32 max_sc_h, max_sc_v;
@@ -722,7 +722,7 @@ static int fimc_cap_querycap(struct file *file, void *priv,
static int fimc_cap_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM | FMT_FLAGS_M2M,
f->index);
@@ -757,7 +757,7 @@ static struct media_entity *fimc_pipeline_get_head(struct media_entity *me)
*/
static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
struct v4l2_mbus_framefmt *tfmt,
- struct fimc_fmt **fmt_id,
+ const struct fimc_fmt **fmt_id,
bool set)
{
struct fimc_dev *fimc = ctx->fimc_dev;
@@ -768,8 +768,8 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
: V4L2_SUBDEV_FORMAT_TRY,
};
struct v4l2_mbus_framefmt *mf = &sfmt.format;
+ const struct fimc_fmt *ffmt;
struct media_entity *me;
- struct fimc_fmt *ffmt;
struct media_pad *pad;
int ret, i = 1;
u32 fcc;
@@ -903,8 +903,8 @@ static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
*/
static int __video_try_or_set_format(struct fimc_dev *fimc,
struct v4l2_format *f, bool try,
- struct fimc_fmt **inp_fmt,
- struct fimc_fmt **out_fmt)
+ const struct fimc_fmt **inp_fmt,
+ const struct fimc_fmt **out_fmt)
{
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
struct fimc_vid_cap *vc = &fimc->vid_cap;
@@ -986,7 +986,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL;
+ const struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL;
return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt);
}
@@ -1010,9 +1010,9 @@ static int __fimc_capture_set_format(struct fimc_dev *fimc,
{
struct fimc_vid_cap *vc = &fimc->vid_cap;
struct fimc_ctx *ctx = vc->ctx;
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ const struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
struct fimc_frame *ff = &ctx->d_frame;
- struct fimc_fmt *inp_fmt = NULL;
+ const struct fimc_fmt *inp_fmt = NULL;
int ret, i;
if (vb2_is_busy(&fimc->vid_cap.vbq))
@@ -1132,7 +1132,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
/* Don't call FIMC subdev operation to avoid nested locking */
if (sd == &vc->subdev) {
- struct fimc_frame *ff = &vc->ctx->s_frame;
+ const struct fimc_frame *ff = &vc->ctx->s_frame;
sink_fmt.format.width = ff->f_width;
sink_fmt.format.height = ff->f_height;
sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0;
@@ -1158,7 +1158,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
if (sd == p->subdevs[IDX_SENSOR] &&
fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
- struct fimc_frame *frame = &vc->ctx->d_frame;
+ const struct fimc_frame *frame = &vc->ctx->d_frame;
unsigned int i;
ret = fimc_get_sensor_frame_desc(sd, plane_fmt,
@@ -1263,7 +1263,7 @@ static int fimc_cap_g_selection(struct file *file, void *fh,
{
struct fimc_dev *fimc = video_drvdata(file);
struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
+ const struct fimc_frame *f = &ctx->s_frame;
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1460,7 +1460,7 @@ static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index);
if (!fmt)
@@ -1475,7 +1475,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
{
struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *ff = &ctx->s_frame;
+ const struct fimc_frame *ff = &ctx->s_frame;
struct v4l2_mbus_framefmt *mf;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
@@ -1519,7 +1519,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
struct fimc_vid_cap *vc = &fimc->vid_cap;
struct fimc_ctx *ctx = vc->ctx;
struct fimc_frame *ff;
- struct fimc_fmt *ffmt;
+ const struct fimc_fmt *ffmt;
dbg("pad%d: code: 0x%x, %dx%d",
fmt->pad, mf->code, mf->width, mf->height);
@@ -1582,7 +1582,7 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
{
struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
+ const struct fimc_frame *f = &ctx->s_frame;
struct v4l2_rect *r = &sel->r;
struct v4l2_rect *try_sel;
@@ -1715,9 +1715,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
{
struct video_device *vfd = &fimc->vid_cap.ve.vdev;
struct vb2_queue *q = &fimc->vid_cap.vbq;
- struct fimc_ctx *ctx;
struct fimc_vid_cap *vid_cap;
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
+ struct fimc_ctx *ctx;
int ret = -ENOMEM;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c
index 0be687b01ce5..aae74b501a42 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c
@@ -29,11 +29,11 @@
#include "fimc-reg.h"
#include "media-dev.h"
-static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
+static const char *fimc_clocks[MAX_FIMC_CLOCKS] = {
"sclk_fimc", "fimc"
};
-static struct fimc_fmt fimc_formats[] = {
+static const struct fimc_fmt fimc_formats[] = {
{
.fourcc = V4L2_PIX_FMT_RGB565,
.depth = { 16 },
@@ -180,7 +180,7 @@ static struct fimc_fmt fimc_formats[] = {
},
};
-struct fimc_fmt *fimc_get_format(unsigned int index)
+const struct fimc_fmt *fimc_get_format(unsigned int index)
{
if (index >= ARRAY_SIZE(fimc_formats))
return NULL;
@@ -228,8 +228,8 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
const struct fimc_variant *variant = ctx->fimc_dev->variant;
struct device *dev = &ctx->fimc_dev->pdev->dev;
struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *s_frame = &ctx->s_frame;
- struct fimc_frame *d_frame = &ctx->d_frame;
+ const struct fimc_frame *s_frame = &ctx->s_frame;
+ const struct fimc_frame *d_frame = &ctx->d_frame;
int tx, ty, sx, sy;
int ret;
@@ -326,7 +326,7 @@ out:
/* The color format (colplanes, memplanes) must be already configured. */
int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
- struct fimc_frame *frame, struct fimc_addr *addr)
+ const struct fimc_frame *frame, struct fimc_addr *addr)
{
int ret = 0;
u32 pix_size;
@@ -670,7 +670,7 @@ void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
v4l2_ctrl_unlock(ctrl);
}
-void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f)
+void __fimc_get_format(const struct fimc_frame *frame, struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
int i;
@@ -695,7 +695,7 @@ void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f)
* @height: requested pixel height
* @pix: multi-plane format to adjust
*/
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
+void fimc_adjust_mplane_format(const struct fimc_fmt *fmt, u32 width, u32 height,
struct v4l2_pix_format_mplane *pix)
{
u32 bytesperline = 0;
@@ -752,10 +752,11 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
* @mask: the color flags to match
* @index: offset in the fimc_formats array, ignored if negative
*/
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index)
+const struct fimc_fmt *fimc_find_format(const u32 *pixelformat,
+ const u32 *mbus_code,
+ unsigned int mask, int index)
{
- struct fimc_fmt *fmt, *def_fmt = NULL;
+ const struct fimc_fmt *fmt, *def_fmt = NULL;
unsigned int i;
int id = 0;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.h b/drivers/media/platform/samsung/exynos4-is/fimc-core.h
index 2b0760add092..63385152a2ff 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.h
@@ -257,7 +257,7 @@ struct fimc_frame {
unsigned int bytesperline[VIDEO_MAX_PLANES];
struct fimc_addr addr;
struct fimc_dma_offset dma_offset;
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
u8 alpha;
};
@@ -515,7 +515,7 @@ static inline void set_frame_crop(struct fimc_frame *f,
f->height = height;
}
-static inline u32 fimc_get_format_depth(struct fimc_fmt *ff)
+static inline u32 fimc_get_format_depth(const struct fimc_fmt *ff)
{
u32 i, depth = 0;
@@ -557,7 +557,7 @@ static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
return ret;
}
-static inline int tiled_fmt(struct fimc_fmt *fmt)
+static inline int tiled_fmt(const struct fimc_fmt *fmt)
{
return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
}
@@ -575,7 +575,7 @@ static inline bool fimc_user_defined_mbus_fmt(u32 code)
}
/* Return the alpha component bit mask */
-static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
+static inline int fimc_get_alpha_mask(const struct fimc_fmt *fmt)
{
switch (fmt->color) {
case FIMC_FMT_RGB444: return 0x0f;
@@ -610,25 +610,24 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
/* -----------------------------------------------------*/
/* fimc-core.c */
-int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f);
int fimc_ctrls_create(struct fimc_ctx *ctx);
void fimc_ctrls_delete(struct fimc_ctx *ctx);
void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
-void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f);
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
+void __fimc_get_format(const struct fimc_frame *frame, struct v4l2_format *f);
+void fimc_adjust_mplane_format(const struct fimc_fmt *fmt, u32 width, u32 height,
struct v4l2_pix_format_mplane *pix);
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index);
-struct fimc_fmt *fimc_get_format(unsigned int index);
+const struct fimc_fmt *fimc_find_format(const u32 *pixelformat,
+ const u32 *mbus_code,
+ unsigned int mask, int index);
+const struct fimc_fmt *fimc_get_format(unsigned int index);
int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
int dw, int dh, int rotation);
int fimc_set_scaler_info(struct fimc_ctx *ctx);
int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
- struct fimc_frame *frame, struct fimc_addr *addr);
+ const struct fimc_frame *frame, struct fimc_addr *addr);
void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
void fimc_set_yuv_order(struct fimc_ctx *ctx);
void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
index a08c87ef6e2d..39aab667910d 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
@@ -175,7 +175,7 @@ static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
return -EINVAL;
}
- ep = of_graph_get_next_endpoint(node, NULL);
+ ep = of_graph_get_endpoint_by_regs(node, 0, -1);
if (!ep)
return -ENXIO;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c b/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c
index 8fa26969c411..06c4352562b3 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c
@@ -40,7 +40,7 @@ static int isp_video_capture_queue_setup(struct vb2_queue *vq,
unsigned int sizes[], struct device *alloc_devs[])
{
struct fimc_isp *isp = vb2_get_drv_priv(vq);
- struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt;
+ const struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt;
const struct fimc_fmt *fmt = isp->video_capture.format;
unsigned int wh, i;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c
index 57996b4104b4..2483277a6cb0 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.c
@@ -124,7 +124,7 @@ static const u32 src_pixfmt_map[8][3] = {
};
/* Set camera input pixel format and resolution */
-void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
+void flite_hw_set_source_format(struct fimc_lite *dev, const struct flite_frame *f)
{
u32 pixelcode = f->fmt->mbus_code;
int i = ARRAY_SIZE(src_pixfmt_map);
@@ -155,7 +155,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
}
/* Set the camera host input window offsets (cropping) */
-void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f)
+void flite_hw_set_window_offset(struct fimc_lite *dev, const struct flite_frame *f)
{
u32 hoff2, voff2;
u32 cfg;
@@ -186,7 +186,7 @@ static void flite_hw_set_camera_port(struct fimc_lite *dev, int id)
/* Select serial or parallel bus, camera port (A,B) and set signals polarity */
void flite_hw_set_camera_bus(struct fimc_lite *dev,
- struct fimc_source_info *si)
+ const struct fimc_source_info *si)
{
u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
unsigned int flags = si->flags;
@@ -226,7 +226,8 @@ static void flite_hw_set_pack12(struct fimc_lite *dev, int on)
writel(cfg, dev->regs + FLITE_REG_CIODMAFMT);
}
-static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
+static void flite_hw_set_out_order(struct fimc_lite *dev,
+ const struct flite_frame *f)
{
static const u32 pixcode[4][2] = {
{ MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR },
@@ -244,7 +245,7 @@ static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
writel(cfg | pixcode[i][1], dev->regs + FLITE_REG_CIODMAFMT);
}
-void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f)
+void flite_hw_set_dma_window(struct fimc_lite *dev, const struct flite_frame *f)
{
u32 cfg;
@@ -294,7 +295,7 @@ void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index)
}
/* Enable/disable output DMA, set output pixel size and offsets (composition) */
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
+void flite_hw_set_output_dma(struct fimc_lite *dev, const struct flite_frame *f,
bool enable)
{
u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h
index c5656e902750..c5ec36dfb2f9 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite-reg.h
@@ -133,15 +133,13 @@ void flite_hw_set_interrupt_mask(struct fimc_lite *dev);
void flite_hw_capture_start(struct fimc_lite *dev);
void flite_hw_capture_stop(struct fimc_lite *dev);
void flite_hw_set_camera_bus(struct fimc_lite *dev,
- struct fimc_source_info *s_info);
-void flite_hw_set_camera_polarity(struct fimc_lite *dev,
- struct fimc_source_info *cam);
-void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f);
-void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f);
+ const struct fimc_source_info *s_info);
+void flite_hw_set_window_offset(struct fimc_lite *dev, const struct flite_frame *f);
+void flite_hw_set_source_format(struct fimc_lite *dev, const struct flite_frame *f);
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
+void flite_hw_set_output_dma(struct fimc_lite *dev, const struct flite_frame *f,
bool enable);
-void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
+void flite_hw_set_dma_window(struct fimc_lite *dev, const struct flite_frame *f);
void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf);
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c
index 7898c9bebb04..d1d860fa3454 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite.c
@@ -738,7 +738,7 @@ static int fimc_lite_try_fmt_mplane(struct file *file, void *fh,
static int fimc_lite_s_fmt_mplane(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
+ const struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
struct fimc_lite *fimc = video_drvdata(file);
struct flite_frame *frame = &fimc->out_frame;
const struct fimc_fmt *fmt = NULL;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-lite.h b/drivers/media/platform/samsung/exynos4-is/fimc-lite.h
index ddf29e0b5b1c..2d96fb00a5c6 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-lite.h
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-lite.h
@@ -117,8 +117,6 @@ struct flite_buffer {
* @ctrl_handler: v4l2 control handler
* @test_pattern: test pattern controls
* @index: FIMC-LITE platform device index
- * @pipeline: video capture pipeline data structure
- * @pipeline_ops: media pipeline ops for the video node driver
* @slock: spinlock protecting this data structure and the hw registers
* @lock: mutex serializing video device and the subdev operations
* @clock: FIMC-LITE gate clock
@@ -134,7 +132,6 @@ struct flite_buffer {
* @active_buf_q: the queue head of buffers scheduled in hardware
* @vb_queue: vb2 buffers queue
* @buf_index: helps to keep track of the DMA start address register index
- * @active_buf_count: number of video buffers scheduled in hardware
* @frame_count: the captured frames counter
* @reqbufs_count: the number of buffers requested with REQBUFS ioctl
* @events: event info
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c
index df8e2aa454d8..199997eec1cc 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c
@@ -170,7 +170,7 @@ static int fimc_queue_setup(struct vb2_queue *vq,
unsigned int sizes[], struct device *alloc_devs[])
{
struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- struct fimc_frame *f;
+ const struct fimc_frame *f;
int i;
f = ctx_get_frame(ctx, vq->type);
@@ -192,7 +192,7 @@ static int fimc_queue_setup(struct vb2_queue *vq,
static int fimc_buf_prepare(struct vb2_buffer *vb)
{
struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_frame *frame;
+ const struct fimc_frame *frame;
int i;
frame = ctx_get_frame(ctx, vb->vb2_queue->type);
@@ -237,7 +237,7 @@ static int fimc_m2m_querycap(struct file *file, void *fh,
static int fimc_m2m_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
f->index);
@@ -252,7 +252,7 @@ static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f)
{
struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
+ const struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
if (IS_ERR(frame))
return PTR_ERR(frame);
@@ -266,7 +266,7 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
struct fimc_dev *fimc = ctx->fimc_dev;
const struct fimc_variant *variant = fimc->variant;
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
u32 max_w, mod_x, mod_y;
if (!IS_M2M(f->type))
@@ -314,8 +314,9 @@ static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
return fimc_try_fmt_mplane(ctx, f);
}
-static void __set_frame_format(struct fimc_frame *frame, struct fimc_fmt *fmt,
- struct v4l2_pix_format_mplane *pixm)
+static void __set_frame_format(struct fimc_frame *frame,
+ const struct fimc_fmt *fmt,
+ const struct v4l2_pix_format_mplane *pixm)
{
int i;
@@ -340,7 +341,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
{
struct fimc_ctx *ctx = fh_to_ctx(fh);
struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
struct vb2_queue *vq;
struct fimc_frame *frame;
int ret;
@@ -378,7 +379,7 @@ static int fimc_m2m_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame;
+ const struct fimc_frame *frame;
frame = ctx_get_frame(ctx, s->type);
if (IS_ERR(frame))
@@ -428,7 +429,7 @@ static int fimc_m2m_try_selection(struct fimc_ctx *ctx,
struct v4l2_selection *s)
{
struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_frame *f;
+ const struct fimc_frame *f;
u32 min_size, halign, depth = 0;
int i;
@@ -588,7 +589,7 @@ static int fimc_m2m_set_default_format(struct fimc_ctx *ctx)
.sizeimage = 800 * 4 * 600,
},
};
- struct fimc_fmt *fmt;
+ const struct fimc_fmt *fmt;
fmt = fimc_find_format(&pixm.pixelformat, NULL, FMT_FLAGS_M2M, 0);
if (!fmt)
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c
index 95165a2cc7d1..b4ee39e471e7 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.c
@@ -105,7 +105,7 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx)
{
u32 cfg;
struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
+ const struct fimc_frame *frame = &ctx->d_frame;
dbg("w= %d, h= %d color: %d", frame->width,
frame->height, frame->fmt->color);
@@ -147,7 +147,7 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx)
static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
{
struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
+ const struct fimc_frame *frame = &ctx->d_frame;
u32 cfg;
cfg = (frame->f_height << 16) | frame->f_width;
@@ -166,9 +166,9 @@ static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
{
struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
- struct fimc_fmt *fmt = frame->fmt;
+ const struct fimc_frame *frame = &ctx->d_frame;
+ const struct fimc_dma_offset *offset = &frame->dma_offset;
+ const struct fimc_fmt *fmt = frame->fmt;
u32 cfg;
/* Set the input dma offsets. */
@@ -248,8 +248,8 @@ static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
{
struct fimc_dev *dev = ctx->fimc_dev;
struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *src_frame = &ctx->s_frame;
- struct fimc_frame *dst_frame = &ctx->d_frame;
+ const struct fimc_frame *src_frame = &ctx->s_frame;
+ const struct fimc_frame *dst_frame = &ctx->d_frame;
u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
@@ -388,7 +388,7 @@ void fimc_hw_set_effect(struct fimc_ctx *ctx)
void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
{
struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
+ const struct fimc_frame *frame = &ctx->d_frame;
u32 cfg;
if (!(frame->fmt->flags & FMT_HAS_ALPHA))
@@ -403,7 +403,7 @@ void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
{
struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
+ const struct fimc_frame *frame = &ctx->s_frame;
u32 cfg_o = 0;
u32 cfg_r = 0;
@@ -420,8 +420,8 @@ static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
{
struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
+ const struct fimc_frame *frame = &ctx->s_frame;
+ const struct fimc_dma_offset *offset = &frame->dma_offset;
u32 cfg;
/* Set the pixel offsets. */
@@ -526,7 +526,7 @@ void fimc_hw_set_output_path(struct fimc_ctx *ctx)
writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
}
-void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *addr)
+void fimc_hw_set_input_addr(struct fimc_dev *dev, const struct fimc_addr *addr)
{
u32 cfg = readl(dev->regs + FIMC_REG_CIREAL_ISIZE);
cfg |= FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
@@ -541,7 +541,7 @@ void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *addr)
}
void fimc_hw_set_output_addr(struct fimc_dev *dev,
- struct fimc_addr *addr, int index)
+ const struct fimc_addr *addr, int index)
{
int i = (index == -1) ? 0 : index;
do {
@@ -554,7 +554,7 @@ void fimc_hw_set_output_addr(struct fimc_dev *dev,
}
int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct fimc_source_info *cam)
+ const struct fimc_source_info *cam)
{
u32 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
@@ -598,8 +598,8 @@ static const struct mbus_pixfmt_desc pix_desc[] = {
int fimc_hw_set_camera_source(struct fimc_dev *fimc,
struct fimc_source_info *source)
{
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct fimc_frame *f = &vc->ctx->s_frame;
+ const struct fimc_vid_cap *vc = &fimc->vid_cap;
+ const struct fimc_frame *f = &vc->ctx->s_frame;
u32 bus_width, cfg = 0;
int i;
@@ -648,7 +648,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
return 0;
}
-void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
+void fimc_hw_set_camera_offset(struct fimc_dev *fimc, const struct fimc_frame *f)
{
u32 hoff2, voff2;
@@ -668,9 +668,9 @@ void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
}
int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct fimc_source_info *source)
+ const struct fimc_source_info *source)
{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+ const struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
u32 csis_data_alignment = 32;
u32 cfg, tmp;
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-reg.h b/drivers/media/platform/samsung/exynos4-is/fimc-reg.h
index b9b33aa1f12f..9714f4309655 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-reg.h
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-reg.h
@@ -302,16 +302,16 @@ void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
void fimc_hw_set_input_path(struct fimc_ctx *ctx);
void fimc_hw_set_output_path(struct fimc_ctx *ctx);
-void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *addr);
-void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *addr,
+void fimc_hw_set_input_addr(struct fimc_dev *fimc, const struct fimc_addr *addr);
+void fimc_hw_set_output_addr(struct fimc_dev *fimc, const struct fimc_addr *addr,
int index);
int fimc_hw_set_camera_source(struct fimc_dev *fimc,
struct fimc_source_info *cam);
-void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
+void fimc_hw_set_camera_offset(struct fimc_dev *fimc, const struct fimc_frame *f);
int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct fimc_source_info *cam);
+ const struct fimc_source_info *cam);
int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct fimc_source_info *cam);
+ const struct fimc_source_info *cam);
void fimc_hw_clear_irq(struct fimc_dev *dev);
void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on);
void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on);
diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
index aae8a8b2c0f4..4b9b20ba3504 100644
--- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
@@ -727,7 +727,8 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
&state->max_num_lanes))
return -EINVAL;
- node = of_graph_get_next_endpoint(node, NULL);
+ /* from port@3 or port@4 */
+ node = of_graph_get_endpoint_by_regs(node, -1, -1);
if (!node) {
dev_err(&pdev->dev, "No port node at %pOF\n",
pdev->dev.of_node);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index fbb047eadf5a..50451984d59f 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -183,7 +183,7 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work)
mfc_err("Error: some instance may be closing/opening\n");
spin_lock_irqsave(&dev->irqlock, flags);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
ctx = dev->ctx[i];
@@ -211,9 +211,9 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work)
mfc_err("Failed to reload FW\n");
goto unlock;
}
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
ret = s5p_mfc_init_hw(dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
if (ret)
mfc_err("Failed to reinit FW\n");
}
@@ -393,7 +393,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_ctx(ctx, reason, err);
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
return;
}
@@ -465,7 +465,7 @@ leave_handle_frame:
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
wake_up_ctx(ctx, reason, err);
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
/* if suspending, wake up device and do not try_run again*/
if (test_bit(0, &dev->enter_suspend))
wake_up_dev(dev, reason, err);
@@ -509,7 +509,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev,
}
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
wake_up_dev(dev, reason, err);
}
@@ -565,7 +565,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
clear_work_bit(ctx);
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
wake_up_ctx(ctx, reason, err);
}
@@ -601,7 +601,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
}
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
wake_up(&ctx->queue);
if (ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
@@ -610,7 +610,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
} else {
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
wake_up(&ctx->queue);
}
@@ -638,7 +638,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx)
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
wake_up(&ctx->queue);
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
}
@@ -690,7 +690,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
}
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
wake_up_ctx(ctx, reason, err);
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
} else {
@@ -754,7 +754,7 @@ irq_cleanup_hw:
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
mfc_err("Failed to unlock hw\n");
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
clear_work_bit(ctx);
wake_up(&ctx->queue);
@@ -841,20 +841,20 @@ static int s5p_mfc_open(struct file *file)
dev->watchdog_timer.expires = jiffies +
msecs_to_jiffies(MFC_WATCHDOG_INTERVAL);
add_timer(&dev->watchdog_timer);
- ret = s5p_mfc_power_on();
+ ret = s5p_mfc_power_on(dev);
if (ret < 0) {
mfc_err("power on failed\n");
goto err_pwr_enable;
}
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
ret = s5p_mfc_load_firmware(dev);
if (ret) {
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
goto err_load_fw;
}
/* Init the FW */
ret = s5p_mfc_init_hw(dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
if (ret)
goto err_init_hw;
}
@@ -931,7 +931,7 @@ err_init_hw:
err_load_fw:
err_pwr_enable:
if (dev->num_inst == 1) {
- if (s5p_mfc_power_off() < 0)
+ if (s5p_mfc_power_off(dev) < 0)
mfc_err("power off failed\n");
del_timer_sync(&dev->watchdog_timer);
}
@@ -963,7 +963,7 @@ static int s5p_mfc_release(struct file *file)
vb2_queue_release(&ctx->vq_src);
vb2_queue_release(&ctx->vq_dst);
if (dev) {
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
/* Mark context as idle */
clear_work_bit_irqsave(ctx);
@@ -983,12 +983,12 @@ static int s5p_mfc_release(struct file *file)
mfc_debug(2, "Last instance\n");
s5p_mfc_deinit_hw(dev);
del_timer_sync(&dev->watchdog_timer);
- s5p_mfc_clock_off();
- if (s5p_mfc_power_off() < 0)
+ s5p_mfc_clock_off(dev);
+ if (s5p_mfc_power_off(dev) < 0)
mfc_err("Power off failed\n");
} else {
mfc_debug(2, "Shutting down clock\n");
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
}
}
if (dev)
@@ -1520,20 +1520,20 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(s5p_mfc_suspend, s5p_mfc_resume)
};
-static struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = {
+static const struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = {
.h264_ctx = MFC_H264_CTX_BUF_SIZE,
.non_h264_ctx = MFC_CTX_BUF_SIZE,
.dsc = DESC_BUF_SIZE,
.shm = SHARED_BUF_SIZE,
};
-static struct s5p_mfc_buf_size buf_size_v5 = {
+static const struct s5p_mfc_buf_size buf_size_v5 = {
.fw = MAX_FW_SIZE,
.cpb = MAX_CPB_SIZE,
.priv = &mfc_buf_size_v5,
};
-static struct s5p_mfc_variant mfc_drvdata_v5 = {
+static const struct s5p_mfc_variant mfc_drvdata_v5 = {
.version = MFC_VERSION,
.version_bit = MFC_V5_BIT,
.port_num = MFC_NUM_PORTS,
@@ -1544,7 +1544,7 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = {
.use_clock_gating = true,
};
-static struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
+static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
.dev_ctx = MFC_CTX_BUF_SIZE_V6,
.h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V6,
.other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V6,
@@ -1552,13 +1552,13 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
.other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V6,
};
-static struct s5p_mfc_buf_size buf_size_v6 = {
+static const struct s5p_mfc_buf_size buf_size_v6 = {
.fw = MAX_FW_SIZE_V6,
.cpb = MAX_CPB_SIZE_V6,
.priv = &mfc_buf_size_v6,
};
-static struct s5p_mfc_variant mfc_drvdata_v6 = {
+static const struct s5p_mfc_variant mfc_drvdata_v6 = {
.version = MFC_VERSION_V6,
.version_bit = MFC_V6_BIT,
.port_num = MFC_NUM_PORTS_V6,
@@ -1573,7 +1573,7 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = {
.num_clocks = 1,
};
-static struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = {
+static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = {
.dev_ctx = MFC_CTX_BUF_SIZE_V7,
.h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V7,
.other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V7,
@@ -1581,13 +1581,13 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = {
.other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V7,
};
-static struct s5p_mfc_buf_size buf_size_v7 = {
+static const struct s5p_mfc_buf_size buf_size_v7 = {
.fw = MAX_FW_SIZE_V7,
.cpb = MAX_CPB_SIZE_V7,
.priv = &mfc_buf_size_v7,
};
-static struct s5p_mfc_variant mfc_drvdata_v7 = {
+static const struct s5p_mfc_variant mfc_drvdata_v7 = {
.version = MFC_VERSION_V7,
.version_bit = MFC_V7_BIT,
.port_num = MFC_NUM_PORTS_V7,
@@ -1597,7 +1597,7 @@ static struct s5p_mfc_variant mfc_drvdata_v7 = {
.num_clocks = 1,
};
-static struct s5p_mfc_variant mfc_drvdata_v7_3250 = {
+static const struct s5p_mfc_variant mfc_drvdata_v7_3250 = {
.version = MFC_VERSION_V7,
.version_bit = MFC_V7_BIT,
.port_num = MFC_NUM_PORTS_V7,
@@ -1607,7 +1607,7 @@ static struct s5p_mfc_variant mfc_drvdata_v7_3250 = {
.num_clocks = 2,
};
-static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = {
+static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = {
.dev_ctx = MFC_CTX_BUF_SIZE_V8,
.h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V8,
.other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V8,
@@ -1615,13 +1615,13 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = {
.other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V8,
};
-static struct s5p_mfc_buf_size buf_size_v8 = {
+static const struct s5p_mfc_buf_size buf_size_v8 = {
.fw = MAX_FW_SIZE_V8,
.cpb = MAX_CPB_SIZE_V8,
.priv = &mfc_buf_size_v8,
};
-static struct s5p_mfc_variant mfc_drvdata_v8 = {
+static const struct s5p_mfc_variant mfc_drvdata_v8 = {
.version = MFC_VERSION_V8,
.version_bit = MFC_V8_BIT,
.port_num = MFC_NUM_PORTS_V8,
@@ -1631,7 +1631,7 @@ static struct s5p_mfc_variant mfc_drvdata_v8 = {
.num_clocks = 1,
};
-static struct s5p_mfc_variant mfc_drvdata_v8_5433 = {
+static const struct s5p_mfc_variant mfc_drvdata_v8_5433 = {
.version = MFC_VERSION_V8,
.version_bit = MFC_V8_BIT,
.port_num = MFC_NUM_PORTS_V8,
@@ -1641,7 +1641,7 @@ static struct s5p_mfc_variant mfc_drvdata_v8_5433 = {
.num_clocks = 3,
};
-static struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = {
+static const struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = {
.dev_ctx = MFC_CTX_BUF_SIZE_V10,
.h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V10,
.other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V10,
@@ -1650,13 +1650,13 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = {
.other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V10,
};
-static struct s5p_mfc_buf_size buf_size_v10 = {
+static const struct s5p_mfc_buf_size buf_size_v10 = {
.fw = MAX_FW_SIZE_V10,
.cpb = MAX_CPB_SIZE_V10,
.priv = &mfc_buf_size_v10,
};
-static struct s5p_mfc_variant mfc_drvdata_v10 = {
+static const struct s5p_mfc_variant mfc_drvdata_v10 = {
.version = MFC_VERSION_V10,
.version_bit = MFC_V10_BIT,
.port_num = MFC_NUM_PORTS_V10,
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c
index 774c573dc075..196d8c99647b 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.c
@@ -12,14 +12,10 @@
#include "s5p_mfc_cmd_v5.h"
#include "s5p_mfc_cmd_v6.h"
-static struct s5p_mfc_hw_cmds *s5p_mfc_cmds;
-
void s5p_mfc_init_hw_cmds(struct s5p_mfc_dev *dev)
{
if (IS_MFCV6_PLUS(dev))
- s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v6();
+ dev->mfc_cmds = s5p_mfc_init_hw_cmds_v6();
else
- s5p_mfc_cmds = s5p_mfc_init_hw_cmds_v5();
-
- dev->mfc_cmds = s5p_mfc_cmds;
+ dev->mfc_cmds = s5p_mfc_init_hw_cmds_v5();
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h
index 945d12fdceb7..172c5a63b58e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd.h
@@ -19,7 +19,7 @@ struct s5p_mfc_cmd_args {
struct s5p_mfc_hw_cmds {
int (*cmd_host2risc)(struct s5p_mfc_dev *dev, int cmd,
- struct s5p_mfc_cmd_args *args);
+ const struct s5p_mfc_cmd_args *args);
int (*sys_init_cmd)(struct s5p_mfc_dev *dev);
int (*sleep_cmd)(struct s5p_mfc_dev *dev);
int (*wakeup_cmd)(struct s5p_mfc_dev *dev);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c
index 327e54e70611..82ee6d300c73 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.c
@@ -14,7 +14,7 @@
/* This function is used to send a command to the MFC */
static int s5p_mfc_cmd_host2risc_v5(struct s5p_mfc_dev *dev, int cmd,
- struct s5p_mfc_cmd_args *args)
+ const struct s5p_mfc_cmd_args *args)
{
int cur_cmd;
unsigned long timeout;
@@ -148,7 +148,7 @@ static int s5p_mfc_close_inst_cmd_v5(struct s5p_mfc_ctx *ctx)
}
/* Initialize cmd function pointers for MFC v5 */
-static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = {
+static const struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = {
.cmd_host2risc = s5p_mfc_cmd_host2risc_v5,
.sys_init_cmd = s5p_mfc_sys_init_cmd_v5,
.sleep_cmd = s5p_mfc_sleep_cmd_v5,
@@ -157,7 +157,7 @@ static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v5 = {
.close_inst_cmd = s5p_mfc_close_inst_cmd_v5,
};
-struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void)
+const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void)
{
return &s5p_mfc_cmds_v5;
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h
index 6eafa514aebc..c626376053c4 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v5.h
@@ -11,6 +11,6 @@
#include "s5p_mfc_common.h"
-struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void);
+const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v5(void);
#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c
index f8588e52dfc8..47bc3014b5d8 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.c
@@ -15,7 +15,7 @@
#include "s5p_mfc_cmd_v6.h"
static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
- struct s5p_mfc_cmd_args *args)
+ const struct s5p_mfc_cmd_args *args)
{
mfc_debug(2, "Issue the command: %d\n", cmd);
@@ -32,7 +32,7 @@ static int s5p_mfc_cmd_host2risc_v6(struct s5p_mfc_dev *dev, int cmd,
static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
{
struct s5p_mfc_cmd_args h2r_args;
- struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
+ const struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
int ret;
ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_dev_context_buffer, dev);
@@ -154,7 +154,7 @@ static int s5p_mfc_close_inst_cmd_v6(struct s5p_mfc_ctx *ctx)
}
/* Initialize cmd function pointers for MFC v6 */
-static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = {
+static const struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = {
.cmd_host2risc = s5p_mfc_cmd_host2risc_v6,
.sys_init_cmd = s5p_mfc_sys_init_cmd_v6,
.sleep_cmd = s5p_mfc_sleep_cmd_v6,
@@ -163,7 +163,7 @@ static struct s5p_mfc_hw_cmds s5p_mfc_cmds_v6 = {
.close_inst_cmd = s5p_mfc_close_inst_cmd_v6,
};
-struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void)
+const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void)
{
return &s5p_mfc_cmds_v6;
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h
index 9dc44460cc38..29083436f517 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_cmd_v6.h
@@ -11,6 +11,6 @@
#include "s5p_mfc_common.h"
-struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void);
+const struct s5p_mfc_hw_cmds *s5p_mfc_init_hw_cmds_v6(void);
#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
index 59450b324f7d..3cc2a4f5c40a 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_common.h
@@ -221,15 +221,15 @@ struct s5p_mfc_buf_size_v6 {
struct s5p_mfc_buf_size {
unsigned int fw;
unsigned int cpb;
- void *priv;
+ const void *priv;
};
struct s5p_mfc_variant {
unsigned int version;
unsigned int port_num;
u32 version_bit;
- struct s5p_mfc_buf_size *buf_size;
- char *fw_name[MFC_FW_MAX_VERSIONS];
+ const struct s5p_mfc_buf_size *buf_size;
+ const char *fw_name[MFC_FW_MAX_VERSIONS];
const char *clk_names[MFC_MAX_CLOCKS];
int num_clocks;
bool use_clock_gating;
@@ -340,8 +340,8 @@ struct s5p_mfc_dev {
struct s5p_mfc_priv_buf ctx_buf;
int warn_start;
- struct s5p_mfc_hw_ops *mfc_ops;
- struct s5p_mfc_hw_cmds *mfc_cmds;
+ const struct s5p_mfc_hw_ops *mfc_ops;
+ const struct s5p_mfc_hw_cmds *mfc_cmds;
const struct s5p_mfc_regs *mfc_regs;
enum s5p_mfc_fw_ver fw_ver;
bool fw_get_done;
@@ -612,7 +612,6 @@ struct s5p_mfc_codec_ops {
* @chroma_dpb_size: dpb buffer size for chroma
* @me_buffer_size: size of the motion estimation buffer
* @tmv_buffer_size: size of temporal predictor motion vector buffer
- * @frame_type: used to force the type of the next encoded frame
* @ref_queue: list of the reference buffers for encoding
* @force_frame_type: encoder's frame type forcing control
* @ref_queue_cnt: number of the buffers in the reference list
@@ -639,8 +638,8 @@ struct s5p_mfc_ctx {
unsigned int int_err;
wait_queue_head_t queue;
- struct s5p_mfc_fmt *src_fmt;
- struct s5p_mfc_fmt *dst_fmt;
+ const struct s5p_mfc_fmt *src_fmt;
+ const struct s5p_mfc_fmt *dst_fmt;
struct vb2_queue vq_src;
struct vb2_queue vq_dst;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
index 503487f34a80..625d77b2be0f 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
@@ -221,7 +221,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
/* 0. MFC reset */
mfc_debug(2, "MFC reset..\n");
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
dev->risc_on = 0;
ret = s5p_mfc_reset(dev);
if (ret) {
@@ -249,7 +249,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) {
mfc_err("Failed to load firmware\n");
s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
return -EIO;
}
s5p_mfc_clean_dev_int_flags(dev);
@@ -258,14 +258,14 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
if (ret) {
mfc_err("Failed to send command to MFC - timeout\n");
s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
return ret;
}
mfc_debug(2, "Ok, now will wait for completion of hardware init\n");
if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) {
mfc_err("Failed to init hardware\n");
s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
return -EIO;
}
dev->int_cond = 0;
@@ -275,7 +275,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
mfc_err("Failed to init firmware - error: %d int: %d\n",
dev->int_err, dev->int_type);
s5p_mfc_reset(dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
return -EIO;
}
if (IS_MFCV6_PLUS(dev))
@@ -285,7 +285,7 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
(ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
mfc_debug_leave();
return 0;
}
@@ -294,12 +294,12 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
/* Deinitialize hardware */
void s5p_mfc_deinit_hw(struct s5p_mfc_dev *dev)
{
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
s5p_mfc_reset(dev);
s5p_mfc_hw_call(dev->mfc_ops, release_dev_context_buffer, dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
}
int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
@@ -307,7 +307,7 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
int ret;
mfc_debug_enter();
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
s5p_mfc_clean_dev_int_flags(dev);
ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev);
if (ret) {
@@ -318,7 +318,7 @@ int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
mfc_err("Failed to sleep\n");
return -EIO;
}
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
dev->int_cond = 0;
if (dev->int_err != 0 || dev->int_type !=
S5P_MFC_R2H_CMD_SLEEP_RET) {
@@ -390,12 +390,12 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
mfc_debug_enter();
/* 0. MFC reset */
mfc_debug(2, "MFC reset..\n");
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
dev->risc_on = 0;
ret = s5p_mfc_reset(dev);
if (ret) {
mfc_err("Failed to reset MFC - timeout\n");
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
return ret;
}
mfc_debug(2, "Done MFC reset..\n");
@@ -410,7 +410,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
else
ret = s5p_mfc_wait_wakeup(dev);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
if (ret)
return ret;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
index 3957f28d4547..91e102d4ec4e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.c
@@ -27,7 +27,7 @@
#include "s5p_mfc_opr.h"
#include "s5p_mfc_pm.h"
-static struct s5p_mfc_fmt formats[] = {
+static const struct s5p_mfc_fmt formats[] = {
{
.fourcc = V4L2_PIX_FMT_NV12MT_16X16,
.codec_mode = S5P_MFC_CODEC_NONE,
@@ -177,7 +177,7 @@ static struct s5p_mfc_fmt formats[] = {
#define NUM_FORMATS ARRAY_SIZE(formats)
/* Find selected format description */
-static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
+static const struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
{
unsigned int i;
@@ -406,7 +406,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_fmt *fmt;
+ const struct s5p_mfc_fmt *fmt;
mfc_debug(2, "Type is %d\n", f->type);
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
@@ -445,7 +445,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
int ret = 0;
struct v4l2_pix_format_mplane *pix_mp;
- struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
+ const struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
mfc_debug_enter();
ret = vidioc_try_fmt(file, priv, f);
@@ -496,7 +496,7 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
{
int ret = 0;
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
if (reqbufs->count == 0) {
mfc_debug(2, "Freeing buffers\n");
@@ -533,7 +533,7 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
ret = -EINVAL;
}
out:
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
if (ret)
mfc_err("Failed allocating buffers for OUTPUT queue\n");
return ret;
@@ -544,7 +544,7 @@ static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
{
int ret = 0;
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
if (reqbufs->count == 0) {
mfc_debug(2, "Freeing buffers\n");
@@ -587,7 +587,7 @@ static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
ret = -EINVAL;
}
out:
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
if (ret)
mfc_err("Failed allocating buffers for CAPTURE queue\n");
return ret;
@@ -1159,7 +1159,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
}
-static struct vb2_ops s5p_mfc_dec_qops = {
+static const struct vb2_ops s5p_mfc_dec_qops = {
.queue_setup = s5p_mfc_queue_setup,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
@@ -1174,7 +1174,7 @@ const struct s5p_mfc_codec_ops *get_dec_codec_ops(void)
return &decoder_codec_ops;
}
-struct vb2_ops *get_dec_queue_ops(void)
+const struct vb2_ops *get_dec_queue_ops(void)
{
return &s5p_mfc_dec_qops;
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h
index 0c52ab46cff7..47a6eb9a8fc0 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_dec.h
@@ -10,9 +10,8 @@
#define S5P_MFC_DEC_H_
const struct s5p_mfc_codec_ops *get_dec_codec_ops(void);
-struct vb2_ops *get_dec_queue_ops(void);
+const struct vb2_ops *get_dec_queue_ops(void);
const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void);
-struct s5p_mfc_fmt *get_dec_def_fmt(bool src);
int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx);
void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx);
void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
index ef8bb40b9712..81cbb36fb382 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
@@ -30,7 +30,7 @@
#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12M
#define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264
-static struct s5p_mfc_fmt formats[] = {
+static const struct s5p_mfc_fmt formats[] = {
{
.fourcc = V4L2_PIX_FMT_NV12MT_16X16,
.codec_mode = S5P_MFC_CODEC_NONE,
@@ -111,7 +111,7 @@ static struct s5p_mfc_fmt formats[] = {
};
#define NUM_FORMATS ARRAY_SIZE(formats)
-static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
+static const struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
{
unsigned int i;
@@ -1431,7 +1431,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
struct s5p_mfc_dev *dev = video_drvdata(file);
- struct s5p_mfc_fmt *fmt;
+ const struct s5p_mfc_fmt *fmt;
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
@@ -2392,7 +2392,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = {
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
-static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
+static int check_vb_with_fmt(const struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
{
int i;
@@ -2650,7 +2650,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
}
-static struct vb2_ops s5p_mfc_enc_qops = {
+static const struct vb2_ops s5p_mfc_enc_qops = {
.queue_setup = s5p_mfc_queue_setup,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
@@ -2666,7 +2666,7 @@ const struct s5p_mfc_codec_ops *get_enc_codec_ops(void)
return &encoder_codec_ops;
}
-struct vb2_ops *get_enc_queue_ops(void)
+const struct vb2_ops *get_enc_queue_ops(void)
{
return &s5p_mfc_enc_qops;
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h
index 3f1b1a037a4f..62d6db67fd91 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.h
@@ -10,9 +10,8 @@
#define S5P_MFC_ENC_H_
const struct s5p_mfc_codec_ops *get_enc_codec_ops(void);
-struct vb2_ops *get_enc_queue_ops(void);
+const struct vb2_ops *get_enc_queue_ops(void);
const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void);
-struct s5p_mfc_fmt *get_enc_def_fmt(bool src);
int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx);
void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx);
void s5p_mfc_enc_init(struct s5p_mfc_ctx *ctx);
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c
index 673962301173..5ba791fa3676 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr.c
@@ -14,18 +14,15 @@
#include "s5p_mfc_opr_v5.h"
#include "s5p_mfc_opr_v6.h"
-static struct s5p_mfc_hw_ops *s5p_mfc_ops;
-
void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev)
{
if (IS_MFCV6_PLUS(dev)) {
- s5p_mfc_ops = s5p_mfc_init_hw_ops_v6();
+ dev->mfc_ops = s5p_mfc_init_hw_ops_v6();
dev->warn_start = S5P_FIMV_ERR_WARNINGS_START_V6;
} else {
- s5p_mfc_ops = s5p_mfc_init_hw_ops_v5();
+ dev->mfc_ops = s5p_mfc_init_hw_ops_v5();
dev->warn_start = S5P_FIMV_ERR_WARNINGS_START;
}
- dev->mfc_ops = s5p_mfc_ops;
}
void s5p_mfc_init_regs(struct s5p_mfc_dev *dev)
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
index fcfaf125a5a1..365f552e604b 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.c
@@ -34,7 +34,7 @@
static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
+ const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
int ret;
ctx->dsc.size = buf_size->dsc;
@@ -200,7 +200,7 @@ static void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx)
static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
+ const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
int ret;
if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||
@@ -345,7 +345,7 @@ static void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx)
static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
+ const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;
mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR);
mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE);
@@ -676,7 +676,7 @@ static int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx)
static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
unsigned int reg;
unsigned int shm;
@@ -759,8 +759,8 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
unsigned int reg;
unsigned int shm;
@@ -916,8 +916,8 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
unsigned int reg;
unsigned int shm;
unsigned int framerate;
@@ -995,8 +995,8 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
unsigned int reg;
unsigned int shm;
@@ -1348,7 +1348,7 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev)
* Last frame has already been sent to MFC.
* Now obtaining frames from MFC buffer
*/
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
s5p_mfc_clean_ctx_int_flags(ctx);
if (ctx->type == MFCINST_DECODER) {
@@ -1424,7 +1424,7 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev)
* scheduled, reduce the clock count as no one will
* ever do this, because no interrupt related to this try_run
* will ever come from hardware. */
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
}
}
@@ -1593,7 +1593,7 @@ static unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx)
}
/* Initialize opr function pointers for MFC v5 */
-static struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = {
+static const struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = {
.alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v5,
.release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v5,
.alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v5,
@@ -1633,7 +1633,7 @@ static struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = {
.get_crop_info_v = s5p_mfc_get_crop_info_v_v5,
};
-struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void)
+const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void)
{
return &s5p_mfc_ops_v5;
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h
index b53d376ead60..0b98c619676e 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v5.h
@@ -78,5 +78,5 @@ enum MFC_SHM_OFS {
FRAME_PACK_SEI_INFO = 0x17c, /* E */
};
-struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void);
+const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void);
#endif /* S5P_MFC_OPR_H_ */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
index fd945211d28e..73f7af674c01 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
@@ -383,7 +383,7 @@ static void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx)
static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
- struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
+ const struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
int ret;
mfc_debug_enter();
@@ -443,7 +443,7 @@ static void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx)
/* Allocate context buffers for SYS_INIT */
static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev)
{
- struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
+ const struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;
int ret;
mfc_debug_enter();
@@ -587,7 +587,7 @@ static int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
{
struct s5p_mfc_dev *dev = ctx->dev;
const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
- struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
+ const struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
mfc_debug_enter();
mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n"
@@ -863,7 +863,7 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
unsigned int reg = 0;
mfc_debug_enter();
@@ -1349,8 +1349,8 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
unsigned int reg = 0;
mfc_debug_enter();
@@ -1431,8 +1431,8 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
unsigned int reg = 0;
mfc_debug_enter();
@@ -1501,8 +1501,8 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8;
unsigned int reg = 0;
unsigned int val = 0;
@@ -1897,8 +1897,8 @@ static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx)
{
struct s5p_mfc_dev *dev = ctx->dev;
const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs;
- struct s5p_mfc_enc_params *p = &ctx->enc_params;
- struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
+ const struct s5p_mfc_enc_params *p = &ctx->enc_params;
+ const struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264;
int i;
if (p_h264->aso) {
@@ -2165,7 +2165,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
/* Last frame has already been sent to MFC
* Now obtaining frames from MFC buffer */
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(dev);
s5p_mfc_clean_ctx_int_flags(ctx);
if (ctx->type == MFCINST_DECODER) {
@@ -2245,7 +2245,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
* scheduled, reduce the clock count as no one will
* ever do this, because no interrupt related to this try_run
* will ever come from hardware. */
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(dev);
}
}
@@ -2261,9 +2261,9 @@ s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned long ofs)
{
int ret;
- s5p_mfc_clock_on();
+ s5p_mfc_clock_on(ctx->dev);
ret = readl((void __iomem *)ofs);
- s5p_mfc_clock_off();
+ s5p_mfc_clock_off(ctx->dev);
return ret;
}
@@ -2657,7 +2657,7 @@ done:
}
/* Initialize opr function pointers for MFC v6 */
-static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = {
+static const struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = {
.alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v6,
.release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v6,
.alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v6,
@@ -2701,7 +2701,7 @@ static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = {
.get_e_min_scratch_buf_size = s5p_mfc_get_e_min_scratch_buf_size,
};
-struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void)
+const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void)
{
return &s5p_mfc_ops_v6;
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
index 94ecb0e6e7c7..7fc1307675d8 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.h
@@ -51,6 +51,6 @@
#define FRAME_DELTA_DEFAULT 1
-struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void);
+const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void);
const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev);
#endif /* S5P_MFC_OPR_V6_H_ */
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c
index 187849841a28..ae4241408383 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c
@@ -14,17 +14,11 @@
#include "s5p_mfc_debug.h"
#include "s5p_mfc_pm.h"
-static struct s5p_mfc_pm *pm;
-static struct s5p_mfc_dev *p_dev;
-static atomic_t clk_ref;
-
int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
{
+ struct s5p_mfc_pm *pm = &dev->pm;
int i;
- pm = &dev->pm;
- p_dev = dev;
-
pm->num_clocks = dev->variant->num_clocks;
pm->clk_names = dev->variant->clk_names;
pm->device = &dev->plat_dev->dev;
@@ -49,70 +43,63 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
pm->clock_gate = pm->clocks[0];
pm_runtime_enable(pm->device);
- atomic_set(&clk_ref, 0);
return 0;
}
void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
{
- pm_runtime_disable(pm->device);
+ pm_runtime_disable(dev->pm.device);
}
-int s5p_mfc_clock_on(void)
+int s5p_mfc_clock_on(struct s5p_mfc_dev *dev)
{
- atomic_inc(&clk_ref);
- mfc_debug(3, "+ %d\n", atomic_read(&clk_ref));
-
- return clk_enable(pm->clock_gate);
+ return clk_enable(dev->pm.clock_gate);
}
-void s5p_mfc_clock_off(void)
+void s5p_mfc_clock_off(struct s5p_mfc_dev *dev)
{
- atomic_dec(&clk_ref);
- mfc_debug(3, "- %d\n", atomic_read(&clk_ref));
-
- clk_disable(pm->clock_gate);
+ clk_disable(dev->pm.clock_gate);
}
-int s5p_mfc_power_on(void)
+int s5p_mfc_power_on(struct s5p_mfc_dev *dev)
{
int i, ret = 0;
- ret = pm_runtime_resume_and_get(pm->device);
+ ret = pm_runtime_resume_and_get(dev->pm.device);
if (ret < 0)
return ret;
/* clock control */
- for (i = 0; i < pm->num_clocks; i++) {
- ret = clk_prepare_enable(pm->clocks[i]);
+ for (i = 0; i < dev->pm.num_clocks; i++) {
+ ret = clk_prepare_enable(dev->pm.clocks[i]);
if (ret < 0) {
mfc_err("clock prepare failed for clock: %s\n",
- pm->clk_names[i]);
+ dev->pm.clk_names[i]);
goto err;
}
}
/* prepare for software clock gating */
- clk_disable(pm->clock_gate);
+ clk_disable(dev->pm.clock_gate);
return 0;
err:
while (--i >= 0)
- clk_disable_unprepare(pm->clocks[i]);
- pm_runtime_put(pm->device);
+ clk_disable_unprepare(dev->pm.clocks[i]);
+ pm_runtime_put(dev->pm.device);
return ret;
}
-int s5p_mfc_power_off(void)
+int s5p_mfc_power_off(struct s5p_mfc_dev *dev)
{
int i;
/* finish software clock gating */
- clk_enable(pm->clock_gate);
+ clk_enable(dev->pm.clock_gate);
- for (i = 0; i < pm->num_clocks; i++)
- clk_disable_unprepare(pm->clocks[i]);
+ for (i = 0; i < dev->pm.num_clocks; i++)
+ clk_disable_unprepare(dev->pm.clocks[i]);
- return pm_runtime_put_sync(pm->device);
+ return pm_runtime_put_sync(dev->pm.device);
}
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h
index 4159d2364e87..9c71036f0385 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.h
@@ -12,9 +12,9 @@
int s5p_mfc_init_pm(struct s5p_mfc_dev *dev);
void s5p_mfc_final_pm(struct s5p_mfc_dev *dev);
-int s5p_mfc_clock_on(void);
-void s5p_mfc_clock_off(void);
-int s5p_mfc_power_on(void);
-int s5p_mfc_power_off(void);
+int s5p_mfc_clock_on(struct s5p_mfc_dev *dev);
+void s5p_mfc_clock_off(struct s5p_mfc_dev *dev);
+int s5p_mfc_power_on(struct s5p_mfc_dev *dev);
+int s5p_mfc_power_off(struct s5p_mfc_dev *dev);
#endif /* S5P_MFC_PM_H_ */
diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
index c4610e305546..ff3331af9406 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
@@ -1855,7 +1855,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi)
struct device_node *ep;
int ret;
- ep = of_graph_get_next_endpoint(dcmi->dev->of_node, NULL);
+ ep = of_graph_get_endpoint_by_regs(dcmi->dev->of_node, 0, -1);
if (!ep) {
dev_err(dcmi->dev, "Failed to get next endpoint\n");
return -EINVAL;
@@ -1907,7 +1907,7 @@ static int dcmi_probe(struct platform_device *pdev)
"Could not get reset control\n");
/* Get bus characteristics from devicetree */
- np = of_graph_get_next_endpoint(np, NULL);
+ np = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!np) {
dev_err(&pdev->dev, "Could not find the endpoint\n");
return -ENODEV;
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
index 32c6619be9a2..bce821eb71ce 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -517,7 +517,7 @@ static int dcmipp_probe(struct platform_device *pdev)
return 0;
}
-static int dcmipp_remove(struct platform_device *pdev)
+static void dcmipp_remove(struct platform_device *pdev)
{
struct dcmipp_device *dcmipp = platform_get_drvdata(pdev);
unsigned int i;
@@ -534,8 +534,6 @@ static int dcmipp_remove(struct platform_device *pdev)
media_device_cleanup(&dcmipp->mdev);
v4l2_device_unregister(&dcmipp->v4l2_dev);
-
- return 0;
}
static int dcmipp_runtime_suspend(struct device *dev)
@@ -588,7 +586,7 @@ static const struct dev_pm_ops dcmipp_pm_ops = {
static struct platform_driver dcmipp_pdrv = {
.probe = dcmipp_probe,
- .remove = dcmipp_remove,
+ .remove_new = dcmipp_remove,
.driver = {
.name = DCMIPP_PDEV_NAME,
.of_match_table = dcmipp_of_match,
diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
index 954fabec27f6..a1c35a2b68ed 100644
--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
@@ -66,6 +66,7 @@ static void deinterlace_device_run(void *priv)
struct vb2_v4l2_buffer *src, *dst;
unsigned int hstep, vstep;
dma_addr_t addr;
+ int i;
src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
@@ -160,6 +161,26 @@ static void deinterlace_device_run(void *priv)
deinterlace_write(dev, DEINTERLACE_CH1_HORZ_FACT, hstep);
deinterlace_write(dev, DEINTERLACE_CH1_VERT_FACT, vstep);
+ /* neutral filter coefficients */
+ deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
+ DEINTERLACE_FRM_CTRL_COEF_ACCESS);
+ readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
+ val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
+
+ for (i = 0; i < 32; i++) {
+ deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
+ DEINTERLACE_IDENTITY_COEF);
+ deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
+ DEINTERLACE_IDENTITY_COEF);
+ deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
+ DEINTERLACE_IDENTITY_COEF);
+ deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
+ DEINTERLACE_IDENTITY_COEF);
+ }
+
+ deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
+ DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
+
deinterlace_clr_set_bits(dev, DEINTERLACE_FIELD_CTRL,
DEINTERLACE_FIELD_CTRL_FIELD_CNT_MSK,
DEINTERLACE_FIELD_CTRL_FIELD_CNT(ctx->field));
@@ -248,7 +269,6 @@ static irqreturn_t deinterlace_irq(int irq, void *data)
static void deinterlace_init(struct deinterlace_dev *dev)
{
u32 val;
- int i;
deinterlace_write(dev, DEINTERLACE_BYPASS,
DEINTERLACE_BYPASS_CSC);
@@ -284,27 +304,7 @@ static void deinterlace_init(struct deinterlace_dev *dev)
deinterlace_clr_set_bits(dev, DEINTERLACE_CHROMA_DIFF,
DEINTERLACE_CHROMA_DIFF_TH_MSK,
- DEINTERLACE_CHROMA_DIFF_TH(5));
-
- /* neutral filter coefficients */
- deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
- DEINTERLACE_FRM_CTRL_COEF_ACCESS);
- readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
- val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
-
- for (i = 0; i < 32; i++) {
- deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
- DEINTERLACE_IDENTITY_COEF);
- deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
- DEINTERLACE_IDENTITY_COEF);
- deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
- DEINTERLACE_IDENTITY_COEF);
- deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
- DEINTERLACE_IDENTITY_COEF);
- }
-
- deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
- DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
+ DEINTERLACE_CHROMA_DIFF_TH(31));
}
static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file)
@@ -929,11 +929,18 @@ static int deinterlace_runtime_resume(struct device *device)
return ret;
}
+ ret = reset_control_deassert(dev->rstc);
+ if (ret) {
+ dev_err(dev->dev, "Failed to apply reset\n");
+
+ goto err_exclusive_rate;
+ }
+
ret = clk_prepare_enable(dev->bus_clk);
if (ret) {
dev_err(dev->dev, "Failed to enable bus clock\n");
- goto err_exclusive_rate;
+ goto err_rst;
}
ret = clk_prepare_enable(dev->mod_clk);
@@ -950,23 +957,16 @@ static int deinterlace_runtime_resume(struct device *device)
goto err_mod_clk;
}
- ret = reset_control_deassert(dev->rstc);
- if (ret) {
- dev_err(dev->dev, "Failed to apply reset\n");
-
- goto err_ram_clk;
- }
-
deinterlace_init(dev);
return 0;
-err_ram_clk:
- clk_disable_unprepare(dev->ram_clk);
err_mod_clk:
clk_disable_unprepare(dev->mod_clk);
err_bus_clk:
clk_disable_unprepare(dev->bus_clk);
+err_rst:
+ reset_control_assert(dev->rstc);
err_exclusive_rate:
clk_rate_exclusive_put(dev->mod_clk);
@@ -977,11 +977,12 @@ static int deinterlace_runtime_suspend(struct device *device)
{
struct deinterlace_dev *dev = dev_get_drvdata(device);
- reset_control_assert(dev->rstc);
-
clk_disable_unprepare(dev->ram_clk);
clk_disable_unprepare(dev->mod_clk);
clk_disable_unprepare(dev->bus_clk);
+
+ reset_control_assert(dev->rstc);
+
clk_rate_exclusive_put(dev->mod_clk);
return 0;
diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c
index 63cdfed37bc9..f4e1fa76bf37 100644
--- a/drivers/media/platform/ti/davinci/vpif.c
+++ b/drivers/media/platform/ti/davinci/vpif.c
@@ -465,8 +465,7 @@ static int vpif_probe(struct platform_device *pdev)
* so their devices need to be registered manually here
* for their legacy platform_drivers to work.
*/
- endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
- endpoint);
+ endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 0, -1);
if (!endpoint)
return 0;
of_node_put(endpoint);
diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
index 59b30fc43144..6da83d0cffaa 100644
--- a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
+++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
@@ -159,6 +159,12 @@ static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = {
.bpp = 8,
.size = SHIM_DMACNTX_SIZE_8,
}, {
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .code = MEDIA_BUS_FMT_Y8_1X8,
+ .csi_dt = MIPI_CSI2_DT_RAW8,
+ .bpp = 8,
+ .size = SHIM_DMACNTX_SIZE_8,
+ }, {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.code = MEDIA_BUS_FMT_SBGGR10_1X10,
.csi_dt = MIPI_CSI2_DT_RAW10,
@@ -182,6 +188,24 @@ static const struct ti_csi2rx_fmt ti_csi2rx_formats[] = {
.csi_dt = MIPI_CSI2_DT_RAW10,
.bpp = 16,
.size = SHIM_DMACNTX_SIZE_16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB565X,
+ .code = MEDIA_BUS_FMT_RGB565_1X16,
+ .csi_dt = MIPI_CSI2_DT_RGB565,
+ .bpp = 16,
+ .size = SHIM_DMACNTX_SIZE_16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_XBGR32,
+ .code = MEDIA_BUS_FMT_RGB888_1X24,
+ .csi_dt = MIPI_CSI2_DT_RGB888,
+ .bpp = 32,
+ .size = SHIM_DMACNTX_SIZE_32,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGBX32,
+ .code = MEDIA_BUS_FMT_BGR888_1X24,
+ .csi_dt = MIPI_CSI2_DT_RGB888,
+ .bpp = 32,
+ .size = SHIM_DMACNTX_SIZE_32,
},
/* More formats can be supported but they are not listed for now. */
@@ -1065,7 +1089,6 @@ static void ti_csi2rx_cleanup_vb2q(struct ti_csi2rx_dev *csi)
static int ti_csi2rx_probe(struct platform_device *pdev)
{
struct ti_csi2rx_dev *csi;
- struct resource *res;
int ret;
csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
@@ -1076,9 +1099,7 @@ static int ti_csi2rx_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, csi);
mutex_init(&csi->mutex);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- csi->shim = devm_ioremap_resource(&pdev->dev, res);
+ csi->shim = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(csi->shim)) {
ret = PTR_ERR(csi->shim);
goto err_mutex;
@@ -1121,7 +1142,7 @@ err_mutex:
return ret;
}
-static int ti_csi2rx_remove(struct platform_device *pdev)
+static void ti_csi2rx_remove(struct platform_device *pdev)
{
struct ti_csi2rx_dev *csi = platform_get_drvdata(pdev);
@@ -1133,8 +1154,6 @@ static int ti_csi2rx_remove(struct platform_device *pdev)
ti_csi2rx_cleanup_dma(csi);
mutex_destroy(&csi->mutex);
-
- return 0;
}
static const struct of_device_id ti_csi2rx_of_match[] = {
@@ -1145,7 +1164,7 @@ MODULE_DEVICE_TABLE(of, ti_csi2rx_of_match);
static struct platform_driver ti_csi2rx_pdrv = {
.probe = ti_csi2rx_probe,
- .remove = ti_csi2rx_remove,
+ .remove_new = ti_csi2rx_remove,
.driver = {
.name = TI_CSI2RX_MODULE_NAME,
.of_match_table = ti_csi2rx_of_match,
diff --git a/drivers/media/platform/verisilicon/Kconfig b/drivers/media/platform/verisilicon/Kconfig
index 24b927d8f182..9a34d14c6e40 100644
--- a/drivers/media/platform/verisilicon/Kconfig
+++ b/drivers/media/platform/verisilicon/Kconfig
@@ -4,7 +4,7 @@ comment "Verisilicon media platform drivers"
config VIDEO_HANTRO
tristate "Hantro VPU driver"
- depends on ARCH_MXC || ARCH_ROCKCHIP || ARCH_AT91 || ARCH_SUNXI || COMPILE_TEST
+ depends on ARCH_MXC || ARCH_ROCKCHIP || ARCH_AT91 || ARCH_SUNXI || ARCH_STM32 || COMPILE_TEST
depends on V4L_MEM2MEM_DRIVERS
depends on VIDEO_DEV
select MEDIA_CONTROLLER
@@ -15,8 +15,8 @@ config VIDEO_HANTRO
select V4L2_VP9
help
Support for the Hantro IP based Video Processing Units present on
- Rockchip and NXP i.MX8M SoCs, which accelerate video and image
- encoding and decoding.
+ Rockchip, NXP i.MX8M and STM32MP25 SoCs, which accelerate video
+ and image encoding and decoding.
To compile this driver as a module, choose M here: the module
will be called hantro-vpu.
@@ -51,3 +51,11 @@ config VIDEO_HANTRO_SUNXI
default y
help
Enable support for H6 SoC.
+
+config VIDEO_HANTRO_STM32MP25
+ bool "Hantro STM32MP25 support"
+ depends on VIDEO_HANTRO
+ depends on ARCH_STM32 || COMPILE_TEST
+ default y
+ help
+ Enable support for STM32MP25 SoCs.
diff --git a/drivers/media/platform/verisilicon/Makefile b/drivers/media/platform/verisilicon/Makefile
index 6ad2ef885920..eb38a1833b02 100644
--- a/drivers/media/platform/verisilicon/Makefile
+++ b/drivers/media/platform/verisilicon/Makefile
@@ -39,3 +39,6 @@ hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \
hantro-vpu-$(CONFIG_VIDEO_HANTRO_SUNXI) += \
sunxi_vpu_hw.o
+
+hantro-vpu-$(CONFIG_VIDEO_HANTRO_STM32MP25) += \
+ stm32mp25_vpu_hw.o
diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h
index 6f5eb975d0e3..811260dc3c77 100644
--- a/drivers/media/platform/verisilicon/hantro.h
+++ b/drivers/media/platform/verisilicon/hantro.h
@@ -237,7 +237,6 @@ struct hantro_dev {
* @codec_ops: Set of operations related to codec mode.
* @postproc: Post-processing context.
* @h264_dec: H.264-decoding context.
- * @jpeg_enc: JPEG-encoding context.
* @mpeg2_dec: MPEG-2-decoding context.
* @vp8_dec: VP8-decoding context.
* @hevc_dec: HEVC-decoding context.
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
index db3df6cc4513..34b123dafd89 100644
--- a/drivers/media/platform/verisilicon/hantro_drv.c
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
@@ -736,6 +736,10 @@ static const struct of_device_id of_hantro_match[] = {
#ifdef CONFIG_VIDEO_HANTRO_SUNXI
{ .compatible = "allwinner,sun50i-h6-vpu-g2", .data = &sunxi_vpu_variant, },
#endif
+#ifdef CONFIG_VIDEO_HANTRO_STM32MP25
+ { .compatible = "st,stm32mp25-vdec", .data = &stm32mp25_vdec_variant, },
+ { .compatible = "st,stm32mp25-venc", .data = &stm32mp25_venc_variant, },
+#endif
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_hantro_match);
diff --git a/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c b/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c
index 9de7f05eff2a..ad5c1a6634f5 100644
--- a/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c
+++ b/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c
@@ -243,7 +243,7 @@ static void set_buffers(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf)
vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DIR_MV);
}
- /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */
+ /* Auxiliary buffer prepared in hantro_h264_dec_init(). */
vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, G1_REG_ADDR_QTABLE);
}
diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h
index 9aec8a79acdc..7737320cc8cc 100644
--- a/drivers/media/platform/verisilicon/hantro_hw.h
+++ b/drivers/media/platform/verisilicon/hantro_hw.h
@@ -408,6 +408,8 @@ extern const struct hantro_variant rk3568_vpu_variant;
extern const struct hantro_variant rk3588_vpu981_variant;
extern const struct hantro_variant sama5d4_vdec_variant;
extern const struct hantro_variant sunxi_vpu_variant;
+extern const struct hantro_variant stm32mp25_vdec_variant;
+extern const struct hantro_variant stm32mp25_venc_variant;
extern const struct hantro_postproc_ops hantro_g1_postproc_ops;
extern const struct hantro_postproc_ops hantro_g2_postproc_ops;
diff --git a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c
index 46c1a83bcc4e..6da87f5184bc 100644
--- a/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c
@@ -460,7 +460,7 @@ static void set_buffers(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *src_buf)
vdpu_write_relaxed(vpu, dst_dma + offset, VDPU_REG_DIR_MV_BASE);
}
- /* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */
+ /* Auxiliary buffer prepared in hantro_h264_dec_init(). */
vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, VDPU_REG_QTABLE_BASE);
}
diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h b/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h
index 182e6c830ff6..850ff0f84424 100644
--- a/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h
+++ b/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h
@@ -118,7 +118,7 @@
#define av1_mcomp_filt_type AV1_DEC_REG(11, 8, 0x7)
#define av1_multicore_expect_context_update AV1_DEC_REG(11, 11, 0x1)
#define av1_multicore_sbx_offset AV1_DEC_REG(11, 12, 0x7f)
-#define av1_ulticore_tile_col AV1_DEC_REG(11, 19, 0x7f)
+#define av1_multicore_tile_col AV1_DEC_REG(11, 19, 0x7f)
#define av1_transform_mode AV1_DEC_REG(11, 27, 0x7)
#define av1_dec_tile_size_mag AV1_DEC_REG(11, 30, 0x3)
diff --git a/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c b/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c
new file mode 100644
index 000000000000..833821120b20
--- /dev/null
+++ b/drivers/media/platform/verisilicon/stm32mp25_vpu_hw.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * STM32MP25 video codec driver
+ *
+ * Copyright (C) STMicroelectronics SA 2024
+ * Authors: Hugues Fruchet <hugues.fruchet@foss.st.com>
+ * for STMicroelectronics.
+ *
+ */
+
+#include "hantro.h"
+#include "hantro_jpeg.h"
+#include "hantro_h1_regs.h"
+
+/*
+ * Supported formats.
+ */
+
+static const struct hantro_fmt stm32mp25_vdec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
+ .frmsize = {
+ .min_width = FMT_MIN_WIDTH,
+ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+ .min_height = FMT_MIN_HEIGHT,
+ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_VP8_FRAME,
+ .codec_mode = HANTRO_MODE_VP8_DEC,
+ .max_depth = 2,
+ .frmsize = {
+ .min_width = FMT_MIN_WIDTH,
+ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+ .min_height = FMT_MIN_HEIGHT,
+ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_H264_SLICE,
+ .codec_mode = HANTRO_MODE_H264_DEC,
+ .max_depth = 2,
+ .frmsize = {
+ .min_width = FMT_MIN_WIDTH,
+ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+ .min_height = FMT_MIN_HEIGHT,
+ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+};
+
+static const struct hantro_fmt stm32mp25_venc_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_YUV420M,
+ .codec_mode = HANTRO_MODE_NONE,
+ .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420P,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV12M,
+ .codec_mode = HANTRO_MODE_NONE,
+ .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420SP,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .codec_mode = HANTRO_MODE_NONE,
+ .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUYV422,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .codec_mode = HANTRO_MODE_NONE,
+ .enc_fmt = ROCKCHIP_VPU_ENC_FMT_UYVY422,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_JPEG,
+ .codec_mode = HANTRO_MODE_JPEG_ENC,
+ .max_depth = 2,
+ .header_size = JPEG_HEADER_SIZE,
+ .frmsize = {
+ .min_width = 96,
+ .max_width = FMT_4K_WIDTH,
+ .step_width = MB_DIM,
+ .min_height = 96,
+ .max_height = FMT_4K_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+};
+
+static irqreturn_t stm32mp25_venc_irq(int irq, void *dev_id)
+{
+ struct hantro_dev *vpu = dev_id;
+ enum vb2_buffer_state state;
+ u32 status;
+
+ status = vepu_read(vpu, H1_REG_INTERRUPT);
+ state = (status & H1_REG_INTERRUPT_FRAME_RDY) ?
+ VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
+
+ vepu_write(vpu, H1_REG_INTERRUPT_BIT, H1_REG_INTERRUPT);
+
+ hantro_irq_done(vpu, state);
+
+ return IRQ_HANDLED;
+}
+
+static void stm32mp25_venc_reset(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+
+ reset_control_reset(vpu->resets);
+}
+
+/*
+ * Supported codec ops.
+ */
+
+static const struct hantro_codec_ops stm32mp25_vdec_codec_ops[] = {
+ [HANTRO_MODE_VP8_DEC] = {
+ .run = hantro_g1_vp8_dec_run,
+ .reset = hantro_g1_reset,
+ .init = hantro_vp8_dec_init,
+ .exit = hantro_vp8_dec_exit,
+ },
+ [HANTRO_MODE_H264_DEC] = {
+ .run = hantro_g1_h264_dec_run,
+ .reset = hantro_g1_reset,
+ .init = hantro_h264_dec_init,
+ .exit = hantro_h264_dec_exit,
+ },
+};
+
+static const struct hantro_codec_ops stm32mp25_venc_codec_ops[] = {
+ [HANTRO_MODE_JPEG_ENC] = {
+ .run = hantro_h1_jpeg_enc_run,
+ .reset = stm32mp25_venc_reset,
+ .done = hantro_h1_jpeg_enc_done,
+ },
+};
+
+/*
+ * Variants.
+ */
+
+static const struct hantro_irq stm32mp25_vdec_irqs[] = {
+ { "vdec", hantro_g1_irq },
+};
+
+static const char * const stm32mp25_vdec_clk_names[] = { "vdec-clk" };
+
+const struct hantro_variant stm32mp25_vdec_variant = {
+ .dec_fmts = stm32mp25_vdec_fmts,
+ .num_dec_fmts = ARRAY_SIZE(stm32mp25_vdec_fmts),
+ .codec = HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
+ .codec_ops = stm32mp25_vdec_codec_ops,
+ .irqs = stm32mp25_vdec_irqs,
+ .num_irqs = ARRAY_SIZE(stm32mp25_vdec_irqs),
+ .clk_names = stm32mp25_vdec_clk_names,
+ .num_clocks = ARRAY_SIZE(stm32mp25_vdec_clk_names),
+};
+
+static const struct hantro_irq stm32mp25_venc_irqs[] = {
+ { "venc", stm32mp25_venc_irq },
+};
+
+static const char * const stm32mp25_venc_clk_names[] = {
+ "venc-clk"
+};
+
+const struct hantro_variant stm32mp25_venc_variant = {
+ .enc_fmts = stm32mp25_venc_fmts,
+ .num_enc_fmts = ARRAY_SIZE(stm32mp25_venc_fmts),
+ .codec = HANTRO_JPEG_ENCODER,
+ .codec_ops = stm32mp25_venc_codec_ops,
+ .irqs = stm32mp25_venc_irqs,
+ .num_irqs = ARRAY_SIZE(stm32mp25_venc_irqs),
+ .clk_names = stm32mp25_venc_clk_names,
+ .num_clocks = ARRAY_SIZE(stm32mp25_venc_clk_names)
+};
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
index 93ef78bf62e6..601edd9acd5b 100644
--- a/drivers/media/platform/xilinx/Kconfig
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -26,10 +26,10 @@ config VIDEO_XILINX_TPG
depends on VIDEO_XILINX
select VIDEO_XILINX_VTC
help
- Driver for the Xilinx Video Test Pattern Generator
+ Driver for the Xilinx Video Test Pattern Generator
config VIDEO_XILINX_VTC
tristate "Xilinx Video Timing Controller"
depends on VIDEO_XILINX
help
- Driver for the Xilinx Video Timing Controller
+ Driver for the Xilinx Video Timing Controller
diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
index 8b04e12af286..613949df897d 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
@@ -45,28 +45,28 @@
#define LNB_HIGH_FREQ 10600000 /* transition frequency */
static unsigned int drop_tslock_prob_on_low_snr;
-module_param(drop_tslock_prob_on_low_snr, uint, 0);
+module_param(drop_tslock_prob_on_low_snr, uint, 0444);
MODULE_PARM_DESC(drop_tslock_prob_on_low_snr,
"Probability of losing the TS lock if the signal quality is bad");
static unsigned int recover_tslock_prob_on_good_snr;
-module_param(recover_tslock_prob_on_good_snr, uint, 0);
+module_param(recover_tslock_prob_on_good_snr, uint, 0444);
MODULE_PARM_DESC(recover_tslock_prob_on_good_snr,
"Probability recovering the TS lock when the signal improves");
static unsigned int mock_power_up_delay_msec;
-module_param(mock_power_up_delay_msec, uint, 0);
+module_param(mock_power_up_delay_msec, uint, 0444);
MODULE_PARM_DESC(mock_power_up_delay_msec, "Simulate a power up delay");
static unsigned int mock_tune_delay_msec;
-module_param(mock_tune_delay_msec, uint, 0);
+module_param(mock_tune_delay_msec, uint, 0444);
MODULE_PARM_DESC(mock_tune_delay_msec, "Simulate a tune delay");
static unsigned int vidtv_valid_dvb_t_freqs[NUM_VALID_TUNER_FREQS] = {
474000000
};
-module_param_array(vidtv_valid_dvb_t_freqs, uint, NULL, 0);
+module_param_array(vidtv_valid_dvb_t_freqs, uint, NULL, 0444);
MODULE_PARM_DESC(vidtv_valid_dvb_t_freqs,
"Valid DVB-T frequencies to simulate, in Hz");
@@ -74,19 +74,19 @@ static unsigned int vidtv_valid_dvb_c_freqs[NUM_VALID_TUNER_FREQS] = {
474000000
};
-module_param_array(vidtv_valid_dvb_c_freqs, uint, NULL, 0);
+module_param_array(vidtv_valid_dvb_c_freqs, uint, NULL, 0444);
MODULE_PARM_DESC(vidtv_valid_dvb_c_freqs,
"Valid DVB-C frequencies to simulate, in Hz");
static unsigned int vidtv_valid_dvb_s_freqs[NUM_VALID_TUNER_FREQS] = {
11362000
};
-module_param_array(vidtv_valid_dvb_s_freqs, uint, NULL, 0);
+module_param_array(vidtv_valid_dvb_s_freqs, uint, NULL, 0444);
MODULE_PARM_DESC(vidtv_valid_dvb_s_freqs,
"Valid DVB-S/S2 frequencies to simulate at Ku-Band, in kHz");
static unsigned int max_frequency_shift_hz;
-module_param(max_frequency_shift_hz, uint, 0);
+module_param(max_frequency_shift_hz, uint, 0444);
MODULE_PARM_DESC(max_frequency_shift_hz,
"Maximum shift in HZ allowed when tuning in a channel");
@@ -96,24 +96,24 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums);
* Influences the signal acquisition time. See ISO/IEC 13818-1 : 2000. p. 113.
*/
static unsigned int si_period_msec = 40;
-module_param(si_period_msec, uint, 0);
+module_param(si_period_msec, uint, 0444);
MODULE_PARM_DESC(si_period_msec, "How often to send SI packets. Default: 40ms");
static unsigned int pcr_period_msec = 40;
-module_param(pcr_period_msec, uint, 0);
+module_param(pcr_period_msec, uint, 0444);
MODULE_PARM_DESC(pcr_period_msec,
"How often to send PCR packets. Default: 40ms");
static unsigned int mux_rate_kbytes_sec = 4096;
-module_param(mux_rate_kbytes_sec, uint, 0);
+module_param(mux_rate_kbytes_sec, uint, 0444);
MODULE_PARM_DESC(mux_rate_kbytes_sec, "Mux rate: will pad stream if below");
static unsigned int pcr_pid = 0x200;
-module_param(pcr_pid, uint, 0);
+module_param(pcr_pid, uint, 0444);
MODULE_PARM_DESC(pcr_pid, "PCR PID for all channels: defaults to 0x200");
static unsigned int mux_buf_sz_pkts;
-module_param(mux_buf_sz_pkts, uint, 0);
+module_param(mux_buf_sz_pkts, uint, 0444);
MODULE_PARM_DESC(mux_buf_sz_pkts,
"Size for the internal mux buffer in multiples of 188 bytes");
diff --git a/drivers/media/test-drivers/visl/visl-core.c b/drivers/media/test-drivers/visl/visl-core.c
index 68dac896277b..c46464bcaf2e 100644
--- a/drivers/media/test-drivers/visl/visl-core.c
+++ b/drivers/media/test-drivers/visl/visl-core.c
@@ -64,30 +64,35 @@ MODULE_PARM_DESC(visl_transtime_ms, " simulated process time in milliseconds.");
* particular number of frames
*/
int visl_dprintk_frame_start = -1;
-module_param(visl_dprintk_frame_start, int, 0);
+module_param(visl_dprintk_frame_start, int, 0444);
MODULE_PARM_DESC(visl_dprintk_frame_start,
" a frame number to start tracing with dprintk");
unsigned int visl_dprintk_nframes;
-module_param(visl_dprintk_nframes, uint, 0);
+module_param(visl_dprintk_nframes, uint, 0444);
MODULE_PARM_DESC(visl_dprintk_nframes,
" the number of frames to trace with dprintk");
bool keep_bitstream_buffers;
-module_param(keep_bitstream_buffers, bool, false);
+module_param(keep_bitstream_buffers, bool, 0444);
MODULE_PARM_DESC(keep_bitstream_buffers,
" keep bitstream buffers in debugfs after streaming is stopped");
int bitstream_trace_frame_start = -1;
-module_param(bitstream_trace_frame_start, int, 0);
+module_param(bitstream_trace_frame_start, int, 0444);
MODULE_PARM_DESC(bitstream_trace_frame_start,
" a frame number to start dumping the bitstream through debugfs");
unsigned int bitstream_trace_nframes;
-module_param(bitstream_trace_nframes, uint, 0);
+module_param(bitstream_trace_nframes, uint, 0444);
MODULE_PARM_DESC(bitstream_trace_nframes,
" the number of frames to dump the bitstream through debugfs");
+bool tpg_verbose;
+module_param(tpg_verbose, bool, 0644);
+MODULE_PARM_DESC(tpg_verbose,
+ " add more verbose information on the generated output frames");
+
static const struct visl_ctrl_desc visl_fwht_ctrl_descs[] = {
{
.cfg.id = V4L2_CID_STATELESS_FWHT_PARAMS,
diff --git a/drivers/media/test-drivers/visl/visl-dec.c b/drivers/media/test-drivers/visl/visl-dec.c
index f21260054e0f..6a9639bd4d61 100644
--- a/drivers/media/test-drivers/visl/visl-dec.c
+++ b/drivers/media/test-drivers/visl/visl-dec.c
@@ -42,6 +42,22 @@ static void *plane_vaddr(struct tpg_data *tpg, struct vb2_buffer *buf,
return vbuf;
}
+static void visl_print_ts_idx(u8 **buf, __kernel_size_t *buflen, const char *name,
+ u64 ts, struct vb2_buffer *vb2_buf)
+{
+ u32 len;
+
+ if (tpg_verbose && vb2_buf) {
+ len = scnprintf(*buf, *buflen, "%s: %lld, vb2_idx: %d\n", name,
+ ts, vb2_buf->index);
+ } else {
+ len = scnprintf(*buf, *buflen, "%s: %lld\n", name, ts);
+ }
+
+ *buf += len;
+ *buflen -= len;
+}
+
static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
__kernel_size_t buflen, struct visl_run *run)
{
@@ -63,9 +79,9 @@ static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
vb2_buf = vb2_find_buffer(cap_q, run->fwht.params->backward_ref_ts);
- scnprintf(buf, buflen, "backwards_ref_ts: %lld, vb2_idx: %d",
- run->fwht.params->backward_ref_ts,
- vb2_buf ? vb2_buf->index : -1);
+ visl_print_ts_idx(&buf, &buflen, "backwards_ref_ts",
+ run->fwht.params->backward_ref_ts, vb2_buf);
+
break;
}
@@ -76,13 +92,11 @@ static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
b_ref = vb2_find_buffer(cap_q, run->mpeg2.pic->backward_ref_ts);
f_ref = vb2_find_buffer(cap_q, run->mpeg2.pic->forward_ref_ts);
- scnprintf(buf, buflen,
- "backward_ref_ts: %llu, vb2_idx: %d\n"
- "forward_ref_ts: %llu, vb2_idx: %d\n",
- run->mpeg2.pic->backward_ref_ts,
- b_ref ? b_ref->index : -1,
- run->mpeg2.pic->forward_ref_ts,
- f_ref ? f_ref->index : -1);
+ visl_print_ts_idx(&buf, &buflen, "backward_ref_ts",
+ run->mpeg2.pic->backward_ref_ts, b_ref);
+ visl_print_ts_idx(&buf, &buflen, "forward_ref_ts",
+ run->mpeg2.pic->forward_ref_ts, f_ref);
+
break;
}
@@ -95,16 +109,13 @@ static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
golden = vb2_find_buffer(cap_q, run->vp8.frame->golden_frame_ts);
alt = vb2_find_buffer(cap_q, run->vp8.frame->alt_frame_ts);
- scnprintf(buf, buflen,
- "last_ref_ts: %llu, vb2_idx: %d\n"
- "golden_ref_ts: %llu, vb2_idx: %d\n"
- "alt_ref_ts: %llu, vb2_idx: %d\n",
- run->vp8.frame->last_frame_ts,
- last ? last->index : -1,
- run->vp8.frame->golden_frame_ts,
- golden ? golden->index : -1,
- run->vp8.frame->alt_frame_ts,
- alt ? alt->index : -1);
+ visl_print_ts_idx(&buf, &buflen, "last_ref_ts",
+ run->vp8.frame->last_frame_ts, last);
+ visl_print_ts_idx(&buf, &buflen, "golden_ref_ts",
+ run->vp8.frame->golden_frame_ts, golden);
+ visl_print_ts_idx(&buf, &buflen, "alt_ref_ts",
+ run->vp8.frame->alt_frame_ts, alt);
+
break;
}
@@ -117,28 +128,32 @@ static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
golden = vb2_find_buffer(cap_q, run->vp9.frame->golden_frame_ts);
alt = vb2_find_buffer(cap_q, run->vp9.frame->alt_frame_ts);
- scnprintf(buf, buflen,
- "last_ref_ts: %llu, vb2_idx: %d\n"
- "golden_ref_ts: %llu, vb2_idx: %d\n"
- "alt_ref_ts: %llu, vb2_idx: %d\n",
- run->vp9.frame->last_frame_ts,
- last ? last->index : -1,
- run->vp9.frame->golden_frame_ts,
- golden ? golden->index : -1,
- run->vp9.frame->alt_frame_ts,
- alt ? alt->index : -1);
+ visl_print_ts_idx(&buf, &buflen, "last_ref_ts",
+ run->vp9.frame->last_frame_ts, last);
+ visl_print_ts_idx(&buf, &buflen, "golden_ref_ts",
+ run->vp9.frame->golden_frame_ts, golden);
+ visl_print_ts_idx(&buf, &buflen, "alt_ref_ts",
+ run->vp9.frame->alt_frame_ts, alt);
+
break;
}
case VISL_CODEC_H264: {
char entry[] = "dpb[%d]:%u, vb2_index: %d\n";
+ char entry_stable[] = "dpb[%d]:%u\n";
struct vb2_buffer *vb2_buf;
for (i = 0; i < ARRAY_SIZE(run->h264.dpram->dpb); i++) {
- vb2_buf = vb2_find_buffer(cap_q, run->h264.dpram->dpb[i].reference_ts);
- len = scnprintf(buf, buflen, entry, i,
- run->h264.dpram->dpb[i].reference_ts,
- vb2_buf ? vb2_buf->index : -1);
+ vb2_buf = vb2_find_buffer(cap_q,
+ run->h264.dpram->dpb[i].reference_ts);
+ if (tpg_verbose && vb2_buf) {
+ len = scnprintf(buf, buflen, entry, i,
+ run->h264.dpram->dpb[i].reference_ts,
+ vb2_buf->index);
+ } else {
+ len = scnprintf(buf, buflen, entry_stable, i,
+ run->h264.dpram->dpb[i].reference_ts);
+ }
buf += len;
buflen -= len;
}
@@ -148,13 +163,20 @@ static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
case VISL_CODEC_HEVC: {
char entry[] = "dpb[%d]:%u, vb2_index: %d\n";
+ char entry_stable[] = "dpb[%d]:%u\n";
struct vb2_buffer *vb2_buf;
for (i = 0; i < ARRAY_SIZE(run->hevc.dpram->dpb); i++) {
vb2_buf = vb2_find_buffer(cap_q, run->hevc.dpram->dpb[i].timestamp);
- len = scnprintf(buf, buflen, entry, i,
- run->hevc.dpram->dpb[i].timestamp,
- vb2_buf ? vb2_buf->index : -1);
+ if (tpg_verbose && vb2_buf) {
+ len = scnprintf(buf, buflen, entry, i,
+ run->hevc.dpram->dpb[i].timestamp,
+ vb2_buf->index);
+ } else {
+ len = scnprintf(buf, buflen, entry_stable, i,
+ run->hevc.dpram->dpb[i].timestamp);
+ }
+
buf += len;
buflen -= len;
}
@@ -171,43 +193,38 @@ static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
int idx_alt2 = run->av1.frame->ref_frame_idx[ALT2_BUF_IDX];
int idx_alt = run->av1.frame->ref_frame_idx[ALT_BUF_IDX];
+ const u64 *reference_frame_ts = run->av1.frame->reference_frame_ts;
+
struct vb2_buffer *ref_last =
- vb2_find_buffer(cap_q, run->av1.frame->reference_frame_ts[idx_last]);
+ vb2_find_buffer(cap_q, reference_frame_ts[idx_last]);
struct vb2_buffer *ref_last2 =
- vb2_find_buffer(cap_q, run->av1.frame->reference_frame_ts[idx_last2]);
+ vb2_find_buffer(cap_q, reference_frame_ts[idx_last2]);
struct vb2_buffer *ref_last3 =
- vb2_find_buffer(cap_q, run->av1.frame->reference_frame_ts[idx_last3]);
+ vb2_find_buffer(cap_q, reference_frame_ts[idx_last3]);
struct vb2_buffer *ref_golden =
- vb2_find_buffer(cap_q, run->av1.frame->reference_frame_ts[idx_golden]);
+ vb2_find_buffer(cap_q, reference_frame_ts[idx_golden]);
struct vb2_buffer *ref_bwd =
- vb2_find_buffer(cap_q, run->av1.frame->reference_frame_ts[idx_bwd]);
+ vb2_find_buffer(cap_q, reference_frame_ts[idx_bwd]);
struct vb2_buffer *ref_alt2 =
- vb2_find_buffer(cap_q, run->av1.frame->reference_frame_ts[idx_alt2]);
+ vb2_find_buffer(cap_q, reference_frame_ts[idx_alt2]);
struct vb2_buffer *ref_alt =
- vb2_find_buffer(cap_q, run->av1.frame->reference_frame_ts[idx_alt]);
-
- scnprintf(buf, buflen,
- "ref_last_ts: %llu, vb2_idx: %d\n"
- "ref_last2_ts: %llu, vb2_idx: %d\n"
- "ref_last3_ts: %llu, vb2_idx: %d\n"
- "ref_golden_ts: %llu, vb2_idx: %d\n"
- "ref_bwd_ts: %llu, vb2_idx: %d\n"
- "ref_alt2_ts: %llu, vb2_idx: %d\n"
- "ref_alt_ts: %llu, vb2_idx: %d\n",
- run->av1.frame->reference_frame_ts[idx_last],
- ref_last ? ref_last->index : -1,
- run->av1.frame->reference_frame_ts[idx_last2],
- ref_last2 ? ref_last2->index : -1,
- run->av1.frame->reference_frame_ts[idx_last3],
- ref_last3 ? ref_last3->index : -1,
- run->av1.frame->reference_frame_ts[idx_golden],
- ref_golden ? ref_golden->index : -1,
- run->av1.frame->reference_frame_ts[idx_bwd],
- ref_bwd ? ref_bwd->index : -1,
- run->av1.frame->reference_frame_ts[idx_alt2],
- ref_alt2 ? ref_alt2->index : -1,
- run->av1.frame->reference_frame_ts[idx_alt],
- ref_alt ? ref_alt->index : -1);
+ vb2_find_buffer(cap_q, reference_frame_ts[idx_alt]);
+
+ visl_print_ts_idx(&buf, &buflen, "ref_last_ts",
+ reference_frame_ts[idx_last], ref_last);
+ visl_print_ts_idx(&buf, &buflen, "ref_last2_ts",
+ reference_frame_ts[idx_last2], ref_last2);
+ visl_print_ts_idx(&buf, &buflen, "ref_last3_ts",
+ reference_frame_ts[idx_last3], ref_last3);
+ visl_print_ts_idx(&buf, &buflen, "ref_golden_ts",
+ reference_frame_ts[idx_golden], ref_golden);
+ visl_print_ts_idx(&buf, &buflen, "ref_bwd_ts",
+ reference_frame_ts[idx_bwd], ref_bwd);
+ visl_print_ts_idx(&buf, &buflen, "ref_alt2_ts",
+ reference_frame_ts[idx_alt2], ref_alt2);
+ visl_print_ts_idx(&buf, &buflen, "ref_alt_ts",
+ reference_frame_ts[idx_alt], ref_alt);
+
break;
}
}
@@ -254,15 +271,23 @@ static void visl_tpg_fill_sequence(struct visl_ctx *ctx,
struct visl_run *run, char buf[], size_t bufsz)
{
u32 stream_ms;
-
- stream_ms = jiffies_to_msecs(get_jiffies_64() - ctx->capture_streamon_jiffies);
+ int len;
+
+ if (tpg_verbose) {
+ stream_ms = jiffies_to_msecs(get_jiffies_64() - ctx->capture_streamon_jiffies);
+
+ len = scnprintf(buf, bufsz,
+ "stream time: %02d:%02d:%02d:%03d ",
+ (stream_ms / (60 * 60 * 1000)) % 24,
+ (stream_ms / (60 * 1000)) % 60,
+ (stream_ms / 1000) % 60,
+ stream_ms % 1000);
+ buf += len;
+ bufsz -= len;
+ }
scnprintf(buf, bufsz,
- "stream time: %02d:%02d:%02d:%03d sequence:%u timestamp:%lld field:%s",
- (stream_ms / (60 * 60 * 1000)) % 24,
- (stream_ms / (60 * 1000)) % 60,
- (stream_ms / 1000) % 60,
- stream_ms % 1000,
+ "sequence:%u timestamp:%lld field:%s",
run->dst->sequence,
run->dst->vb2_buf.timestamp,
(run->dst->field == V4L2_FIELD_ALTERNATE) ?
@@ -270,6 +295,35 @@ static void visl_tpg_fill_sequence(struct visl_ctx *ctx,
" top" : " bottom") : "none");
}
+static bool visl_tpg_fill_codec_specific(struct visl_ctx *ctx,
+ struct visl_run *run,
+ char buf[], size_t bufsz)
+{
+ /*
+ * To add variability, we need a value that is stable for a given
+ * input but is different than already shown fields.
+ * The pic order count value defines the display order of the frames
+ * (which can be different than the decoding order that is shown with
+ * the sequence number).
+ * Therefore it is stable for a given input and will add a different
+ * value that is more specific to the way the input is encoded.
+ */
+ switch (ctx->current_codec) {
+ case VISL_CODEC_H264:
+ scnprintf(buf, bufsz,
+ "H264: %u", run->h264.dpram->pic_order_cnt_lsb);
+ break;
+ case VISL_CODEC_HEVC:
+ scnprintf(buf, bufsz,
+ "HEVC: %d", run->hevc.dpram->pic_order_cnt_val);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run)
{
u8 *basep[TPG_MAX_PLANES][2];
@@ -302,6 +356,13 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run)
frame_dprintk(ctx->dev, run->dst->sequence, "");
line++;
+ if (visl_tpg_fill_codec_specific(ctx, run, buf, TPG_STR_BUF_SZ)) {
+ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
+ frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
+ frame_dprintk(ctx->dev, run->dst->sequence, "");
+ line++;
+ }
+
visl_get_ref_frames(ctx, buf, TPG_STR_BUF_SZ, run);
while ((line_str = strsep(&tmp, "\n")) && strlen(line_str)) {
@@ -338,35 +399,37 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run)
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
}
- line++;
- frame_dprintk(ctx->dev, run->dst->sequence, "");
- scnprintf(buf, TPG_STR_BUF_SZ, "Output queue status:");
- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
- frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
+ if (tpg_verbose) {
+ line++;
+ frame_dprintk(ctx->dev, run->dst->sequence, "");
+ scnprintf(buf, TPG_STR_BUF_SZ, "Output queue status:");
+ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
+ frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
- len = 0;
- for (i = 0; i < vb2_get_num_buffers(out_q); i++) {
- char entry[] = "index: %u, state: %s, request_fd: %d, ";
- u32 old_len = len;
- struct vb2_buffer *vb2;
- char *q_status;
+ len = 0;
+ for (i = 0; i < vb2_get_num_buffers(out_q); i++) {
+ char entry[] = "index: %u, state: %s, request_fd: %d, ";
+ u32 old_len = len;
+ struct vb2_buffer *vb2;
+ char *q_status;
- vb2 = vb2_get_buffer(out_q, i);
- if (!vb2)
- continue;
+ vb2 = vb2_get_buffer(out_q, i);
+ if (!vb2)
+ continue;
- q_status = visl_get_vb2_state(vb2->state);
+ q_status = visl_get_vb2_state(vb2->state);
- len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
- entry, i, q_status,
- to_vb2_v4l2_buffer(vb2)->request_fd);
+ len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
+ entry, i, q_status,
+ to_vb2_v4l2_buffer(vb2)->request_fd);
- len += visl_fill_bytesused(to_vb2_v4l2_buffer(vb2),
- &buf[len],
- TPG_STR_BUF_SZ - len);
+ len += visl_fill_bytesused(to_vb2_v4l2_buffer(vb2),
+ &buf[len],
+ TPG_STR_BUF_SZ - len);
- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
- frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
+ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
+ frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
+ }
}
line++;
@@ -398,32 +461,34 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run)
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
}
- line++;
- frame_dprintk(ctx->dev, run->dst->sequence, "");
- scnprintf(buf, TPG_STR_BUF_SZ, "Capture queue status:");
- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
- frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
+ if (tpg_verbose) {
+ line++;
+ frame_dprintk(ctx->dev, run->dst->sequence, "");
+ scnprintf(buf, TPG_STR_BUF_SZ, "Capture queue status:");
+ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
+ frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
- len = 0;
- for (i = 0; i < vb2_get_num_buffers(cap_q); i++) {
- u32 old_len = len;
- struct vb2_buffer *vb2;
- char *q_status;
+ len = 0;
+ for (i = 0; i < vb2_get_num_buffers(cap_q); i++) {
+ u32 old_len = len;
+ struct vb2_buffer *vb2;
+ char *q_status;
- vb2 = vb2_get_buffer(cap_q, i);
- if (!vb2)
- continue;
+ vb2 = vb2_get_buffer(cap_q, i);
+ if (!vb2)
+ continue;
- q_status = visl_get_vb2_state(vb2->state);
+ q_status = visl_get_vb2_state(vb2->state);
- len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
- "index: %u, status: %s, timestamp: %llu, is_held: %d",
- vb2->index, q_status,
- vb2->timestamp,
- to_vb2_v4l2_buffer(vb2)->is_held);
+ len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
+ "index: %u, status: %s, timestamp: %llu, is_held: %d",
+ vb2->index, q_status,
+ vb2->timestamp,
+ to_vb2_v4l2_buffer(vb2)->is_held);
- tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
- frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
+ tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
+ frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
+ }
}
}
diff --git a/drivers/media/test-drivers/visl/visl.h b/drivers/media/test-drivers/visl/visl.h
index c593b1337f11..434e9efbf9b2 100644
--- a/drivers/media/test-drivers/visl/visl.h
+++ b/drivers/media/test-drivers/visl/visl.h
@@ -85,6 +85,7 @@ extern unsigned int visl_dprintk_nframes;
extern bool keep_bitstream_buffers;
extern int bitstream_trace_frame_start;
extern unsigned int bitstream_trace_nframes;
+extern bool tpg_verbose;
#define frame_dprintk(dev, current, fmt, arg...) \
do { \
diff --git a/drivers/media/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c
index f0371d004b36..a7e721baaa99 100644
--- a/drivers/media/tuners/tda18271-fe.c
+++ b/drivers/media/tuners/tda18271-fe.c
@@ -470,7 +470,6 @@ static int tda18271_powerscan(struct dvb_frontend *fe,
/* algorithm initialization */
sgn = 1;
*freq_out = *freq_in;
- bcal = 0;
count = 0;
wait = false;
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index 57ded9ff3f04..29bc63021c5a 100644
--- a/drivers/media/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -1515,10 +1515,10 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
{
struct xc4000_priv *priv = fe->tuner_priv;
+ mutex_lock(&priv->lock);
*freq = priv->freq_hz + priv->freq_offset;
if (debug) {
- mutex_lock(&priv->lock);
if ((priv->cur_fw.type
& (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
u16 snr = 0;
@@ -1529,8 +1529,8 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
return 0;
}
}
- mutex_unlock(&priv->lock);
}
+ mutex_unlock(&priv->lock);
dprintk(1, "%s()\n", __func__);
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index 3b75d062e602..343a4433ed24 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1759,7 +1759,7 @@ int cx231xx_417_register(struct cx231xx *dev)
dev->mpeg_ctrl_handler.ops = &cx231xx_ops;
if (dev->sd_cx25840)
v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl,
- dev->sd_cx25840->ctrl_handler, NULL, false);
+ dev->sd_cx25840->ctrl_handler, NULL, true);
if (dev->mpeg_ctrl_handler.hdl.error) {
err = dev->mpeg_ctrl_handler.hdl.error;
dprintk(3, "%s: can't add cx25840 controls\n", dev->name);
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index 0990aa4a17bb..cbb0541d4dc1 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -126,8 +126,6 @@ struct usb_data_stream_properties {
* @caps: capabilities of the DVB USB device.
* @pid_filter_count: number of PID filter position in the optional hardware
* PID-filter.
- * @num_frontends: number of frontends of the DVB USB adapter.
- * @frontend_ctrl: called to power on/off active frontend.
* @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
* device (not URB submitting/killing).
* This callback will be called without data URBs being active - data URBs
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 4d037c92af7c..bae76023cf71 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -4094,6 +4094,10 @@ static int em28xx_usb_probe(struct usb_interface *intf,
* topology will likely change after the load of the em28xx subdrivers.
*/
#ifdef CONFIG_MEDIA_CONTROLLER
+ /*
+ * No need to check the return value, the device will still be
+ * usable without media controller API.
+ */
retval = media_device_register(dev->media_dev);
#endif
diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
index 0c24e2984304..eb03f98b2ef1 100644
--- a/drivers/media/usb/go7007/go7007-driver.c
+++ b/drivers/media/usb/go7007/go7007-driver.c
@@ -80,7 +80,7 @@ static int go7007_load_encoder(struct go7007 *go)
const struct firmware *fw_entry;
char fw_name[] = "go7007/go7007fw.bin";
void *bounce;
- int fw_len, rv = 0;
+ int fw_len;
u16 intr_val, intr_data;
if (go->boot_fw == NULL) {
@@ -109,9 +109,11 @@ static int go7007_load_encoder(struct go7007 *go)
go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
(intr_val & ~0x1) != 0x5a5a) {
v4l2_err(go, "error transferring firmware\n");
- rv = -1;
+ kfree(go->boot_fw);
+ go->boot_fw = NULL;
+ return -1;
}
- return rv;
+ return 0;
}
MODULE_FIRMWARE("go7007/go7007fw.bin");
diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c
index eeb85981e02b..762c13e49bfa 100644
--- a/drivers/media/usb/go7007/go7007-usb.c
+++ b/drivers/media/usb/go7007/go7007-usb.c
@@ -1201,7 +1201,9 @@ static int go7007_usb_probe(struct usb_interface *intf,
u16 channel;
/* read channel number from GPIO[1:0] */
- go7007_read_addr(go, 0x3c81, &channel);
+ if (go7007_read_addr(go, 0x3c81, &channel))
+ goto allocfail;
+
channel &= 0x3;
go->board_id = GO7007_BOARDID_ADLINK_MPG24;
usb->board = board = &board_adlink_mpg24;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c
index 1764674de98b..73c95ba2328a 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-context.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c
@@ -90,8 +90,10 @@ static void pvr2_context_destroy(struct pvr2_context *mp)
}
-static void pvr2_context_notify(struct pvr2_context *mp)
+static void pvr2_context_notify(void *ptr)
{
+ struct pvr2_context *mp = ptr;
+
pvr2_context_set_notify(mp,!0);
}
@@ -106,9 +108,7 @@ static void pvr2_context_check(struct pvr2_context *mp)
pvr2_trace(PVR2_TRACE_CTXT,
"pvr2_context %p (initialize)", mp);
/* Finish hardware initialization */
- if (pvr2_hdw_initialize(mp->hdw,
- (void (*)(void *))pvr2_context_notify,
- mp)) {
+ if (pvr2_hdw_initialize(mp->hdw, pvr2_context_notify, mp)) {
mp->video_stream.stream =
pvr2_hdw_get_video_stream(mp->hdw);
/* Trigger interface initialization. By doing this
@@ -267,9 +267,9 @@ static void pvr2_context_exit(struct pvr2_context *mp)
void pvr2_context_disconnect(struct pvr2_context *mp)
{
pvr2_hdw_disconnect(mp->hdw);
- mp->disconnect_flag = !0;
if (!pvr2_context_shutok())
pvr2_context_notify(mp);
+ mp->disconnect_flag = !0;
}
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 26811efe0fb5..3610139fb9ad 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -33,9 +33,6 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
for (;;) {
if (kthread_should_stop()) break;
- /* Not sure about this... */
- try_to_freeze();
-
bp = pvr2_stream_get_ready_buffer(stream);
if (bp != NULL) {
count = pvr2_buffer_get_count(bp);
@@ -62,8 +59,7 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
/* Wait until more buffers become available or we're
told not to wait any longer. */
- ret = wait_event_interruptible(
- adap->buffer_wait_data,
+ ret = wait_event_freezable(adap->buffer_wait_data,
(pvr2_stream_get_ready_count(stream) > 0) ||
kthread_should_stop());
if (ret < 0) break;
@@ -88,8 +84,10 @@ static int pvr2_dvb_feed_thread(void *data)
return stat;
}
-static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap)
+static void pvr2_dvb_notify(void *ptr)
{
+ struct pvr2_dvb_adapter *adap = ptr;
+
wake_up(&adap->buffer_wait_data);
}
@@ -149,7 +147,7 @@ static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap)
}
pvr2_stream_set_callback(pvr->video_stream.stream,
- (pvr2_stream_callback) pvr2_dvb_notify, adap);
+ pvr2_dvb_notify, adap);
ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT);
if (ret < 0) return ret;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index c04ab7258d64..d608b793fa84 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -1033,8 +1033,10 @@ static int pvr2_v4l2_open(struct file *file)
}
-static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
+static void pvr2_v4l2_notify(void *ptr)
{
+ struct pvr2_v4l2_fh *fhp = ptr;
+
wake_up(&fhp->wait_data);
}
@@ -1067,7 +1069,7 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
hdw = fh->channel.mc_head->hdw;
sp = fh->pdi->stream->stream;
- pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
+ pvr2_stream_set_callback(sp, pvr2_v4l2_notify, fh);
pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
return pvr2_ioread_set_enabled(fh->rhp,!0);
@@ -1198,11 +1200,6 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->minor_type = pvr2_v4l_type_video;
nr_ptr = video_nr;
caps |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO;
- if (!dip->stream) {
- pr_err(KBUILD_MODNAME
- ": Failed to set up pvrusb2 v4l video dev due to missing stream instance\n");
- return;
- }
break;
case VFL_TYPE_VBI:
dip->config = pvr2_config_vbi;
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 3c2627712fe9..8e1de1e8bd12 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -1906,9 +1906,10 @@ static int s2255_get_fx2fw(struct s2255_dev *dev)
{
int fw;
int ret;
- unsigned char transBuffer[64];
- ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
- S2255_VR_IN);
+ u8 transBuffer[2] = {};
+
+ ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer,
+ sizeof(transBuffer), S2255_VR_IN);
if (ret < 0)
dprintk(dev, 2, "get fw error: %x\n", ret);
fw = transBuffer[0] + (transBuffer[1] << 8);
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
index 62a583040cd4..702f1c8bd2ab 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -963,15 +963,8 @@ ctrl_fail:
void usbtv_video_free(struct usbtv *usbtv)
{
- mutex_lock(&usbtv->vb2q_lock);
- mutex_lock(&usbtv->v4l2_lock);
-
- usbtv_stop(usbtv);
vb2_video_unregister_device(&usbtv->vdev);
v4l2_device_disconnect(&usbtv->v4l2_dev);
- mutex_unlock(&usbtv->v4l2_lock);
- mutex_unlock(&usbtv->vb2q_lock);
-
v4l2_device_put(&usbtv->v4l2_dev);
}
diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
index 10005c80f43b..ee3475bed37f 100644
--- a/drivers/media/v4l2-core/v4l2-cci.c
+++ b/drivers/media/v4l2-core/v4l2-cci.c
@@ -32,7 +32,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
ret = regmap_bulk_read(map, reg, buf, len);
if (ret) {
- dev_err(regmap_get_device(map), "Error reading reg 0x%4x: %d\n",
+ dev_err(regmap_get_device(map), "Error reading reg 0x%04x: %d\n",
reg, ret);
goto out;
}
@@ -131,7 +131,7 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
ret = regmap_bulk_write(map, reg, buf, len);
if (ret)
- dev_err(regmap_get_device(map), "Error writing reg 0x%4x: %d\n",
+ dev_err(regmap_get_device(map), "Error writing reg 0x%04x: %d\n",
reg, ret);
out:
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 273d83de2a87..d34d210908d9 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -585,3 +585,50 @@ u32 v4l2_fraction_to_interval(u32 numerator, u32 denominator)
return denominator ? numerator * multiplier / denominator : 0;
}
EXPORT_SYMBOL_GPL(v4l2_fraction_to_interval);
+
+int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
+ unsigned int num_of_fw_link_freqs,
+ const s64 *driver_link_freqs,
+ unsigned int num_of_driver_link_freqs,
+ unsigned long *bitmap)
+{
+ unsigned int i;
+
+ *bitmap = 0;
+
+ if (!num_of_fw_link_freqs) {
+ dev_err(dev, "no link frequencies in firmware\n");
+ return -ENODATA;
+ }
+
+ for (i = 0; i < num_of_fw_link_freqs; i++) {
+ unsigned int j;
+
+ for (j = 0; j < num_of_driver_link_freqs; j++) {
+ if (fw_link_freqs[i] != driver_link_freqs[j])
+ continue;
+
+ dev_dbg(dev, "enabling link frequency %lld Hz\n",
+ driver_link_freqs[j]);
+ *bitmap |= BIT(j);
+ break;
+ }
+ }
+
+ if (!*bitmap) {
+ dev_err(dev, "no matching link frequencies found\n");
+
+ dev_dbg(dev, "specified in firmware:\n");
+ for (i = 0; i < num_of_fw_link_freqs; i++)
+ dev_dbg(dev, "\t%llu Hz\n", fw_link_freqs[i]);
+
+ dev_dbg(dev, "driver supported:\n");
+ for (i = 0; i < num_of_driver_link_freqs; i++)
+ dev_dbg(dev, "\t%lld Hz\n", driver_link_freqs[i]);
+
+ return -ENOENT;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c
index 002ea6588edf..d9a422017bd9 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -1179,7 +1179,7 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
return -EINVAL;
/* Use mask to see if this menu item should be skipped */
- if (ctrl->menu_skip_mask & (1ULL << i))
+ if (i < BITS_PER_LONG_LONG && (ctrl->menu_skip_mask & BIT_ULL(i)))
return -EINVAL;
/* Empty menu items should also be skipped */
if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index a662fb60f73f..c4d995f32191 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -1504,11 +1504,12 @@ int check_range(enum v4l2_ctrl_type type,
return 0;
case V4L2_CTRL_TYPE_MENU:
case V4L2_CTRL_TYPE_INTEGER_MENU:
- if (min > max || def < min || def > max)
+ if (min > max || def < min || def > max ||
+ min < 0 || (step && max >= BITS_PER_LONG_LONG))
return -ERANGE;
/* Note: step == menu_skip_mask for menu controls.
So here we check if the default value is masked out. */
- if (step && ((1 << def) & step))
+ if (def < BITS_PER_LONG_LONG && (step & BIT_ULL(def)))
return -EINVAL;
return 0;
case V4L2_CTRL_TYPE_STRING:
@@ -2503,7 +2504,8 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
/* Log the control name and value */
-static void log_ctrl(const struct v4l2_ctrl *ctrl,
+static void log_ctrl(const struct v4l2_ctrl_handler *hdl,
+ struct v4l2_ctrl *ctrl,
const char *prefix, const char *colon)
{
if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY))
@@ -2513,7 +2515,11 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl,
pr_info("%s%s%s: ", prefix, colon, ctrl->name);
+ if (ctrl->handler != hdl)
+ v4l2_ctrl_lock(ctrl);
ctrl->type_ops->log(ctrl);
+ if (ctrl->handler != hdl)
+ v4l2_ctrl_unlock(ctrl);
if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
V4L2_CTRL_FLAG_GRABBED |
@@ -2532,7 +2538,7 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl,
void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
const char *prefix)
{
- struct v4l2_ctrl *ctrl;
+ struct v4l2_ctrl_ref *ref;
const char *colon = "";
int len;
@@ -2544,9 +2550,12 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
if (len && prefix[len - 1] != ' ')
colon = ": ";
mutex_lock(hdl->lock);
- list_for_each_entry(ctrl, &hdl->ctrls, node)
- if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
- log_ctrl(ctrl, prefix, colon);
+ list_for_each_entry(ref, &hdl->ctrl_refs, node) {
+ if (ref->from_other_dev ||
+ (ref->ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
+ continue;
+ log_ctrl(hdl, ref->ctrl, prefix, colon);
+ }
mutex_unlock(hdl->lock);
}
EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 33076af4dfdb..6e7b8b682d13 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -3028,7 +3028,7 @@ static long __video_do_ioctl(struct file *file,
if (v4l2_is_known_ioctl(cmd)) {
info = &v4l2_ioctls[_IOC_NR(cmd)];
- if (!test_bit(_IOC_NR(cmd), vfd->valid_ioctls) &&
+ if (!is_valid_ioctl(vfd, cmd) &&
!((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
goto done;
diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c
index 52d349e72b8c..4bb91359e3a9 100644
--- a/drivers/media/v4l2-core/v4l2-mc.c
+++ b/drivers/media/v4l2-core/v4l2-mc.c
@@ -337,12 +337,18 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd,
src_idx = media_entity_get_fwnode_pad(&src_sd->entity,
endpoint,
MEDIA_PAD_FL_SOURCE);
- if (src_idx < 0)
+ if (src_idx < 0) {
+ dev_dbg(src_sd->dev, "no source pad found for %pfw\n",
+ endpoint);
continue;
+ }
remote_ep = fwnode_graph_get_remote_endpoint(endpoint);
- if (!remote_ep)
+ if (!remote_ep) {
+ dev_dbg(src_sd->dev, "no remote ep found for %pfw\n",
+ endpoint);
continue;
+ }
/*
* ask the sink to verify it owns the remote endpoint,
@@ -353,8 +359,12 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd,
MEDIA_PAD_FL_SINK);
fwnode_handle_put(remote_ep);
- if (sink_idx < 0 || sink_idx != sink->index)
+ if (sink_idx < 0 || sink_idx != sink->index) {
+ dev_dbg(src_sd->dev,
+ "sink pad index mismatch or error (is %d, expected %u)\n",
+ sink_idx, sink->index);
continue;
+ }
/*
* the source endpoint corresponds to one of its source pads,
@@ -367,8 +377,13 @@ int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd,
src = &src_sd->entity.pads[src_idx];
/* skip if link already exists */
- if (media_entity_find_link(src, sink))
+ if (media_entity_find_link(src, sink)) {
+ dev_dbg(src_sd->dev,
+ "link %s:%d -> %s:%d already exists\n",
+ src_sd->entity.name, src_idx,
+ sink->entity->name, sink_idx);
continue;
+ }
dev_dbg(src_sd->dev, "creating link %s:%d -> %s:%d\n",
src_sd->entity.name, src_idx,
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 9e983176542b..75517134a5e9 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -1087,11 +1087,17 @@ static int v4l2_m2m_register_entity(struct media_device *mdev,
entity->function = function;
ret = media_entity_pads_init(entity, num_pads, pads);
- if (ret)
+ if (ret) {
+ kfree(entity->name);
+ entity->name = NULL;
return ret;
+ }
ret = media_device_register_entity(mdev, entity);
- if (ret)
+ if (ret) {
+ kfree(entity->name);
+ entity->name = NULL;
return ret;
+ }
return 0;
}
diff --git a/drivers/staging/media/atomisp/TODO b/drivers/staging/media/atomisp/TODO
index d99cc898cd99..bfef99997a1d 100644
--- a/drivers/staging/media/atomisp/TODO
+++ b/drivers/staging/media/atomisp/TODO
@@ -29,16 +29,6 @@ TODO
1. Items which MUST be fixed before the driver can be moved out of staging:
-* The atomisp ov2680 and ov5693 sensor drivers bind to the same hw-ids as
- the standard ov2680 and ov5693 drivers under drivers/media/i2c, which
- conflicts. Drop the atomisp private ov2680 and ov5693 drivers:
- * Port various ov2680 improvements from atomisp_ov2680.c to regular ov2680.c
- and switch to regular ov2680 driver
- * Make atomisp work with the regular ov5693 driver and drop atomisp_ov5693
-
-* Fix atomisp causing the whole machine to hang in its probe() error-exit
- path taken in the firmware missing case
-
* Remove/disable private IOCTLs
* Remove/disable custom v4l2-ctrls
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
index 55ea422291ba..ade28950db73 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -77,9 +77,6 @@
/*
* GC2235 System control registers
*/
-/*
- * GC2235 System control registers
- */
#define GC2235_SENSOR_ID_H 0xF0
#define GC2235_SENSOR_ID_L 0xF1
#define GC2235_RESET_RELATED 0xFE
@@ -167,7 +164,7 @@ enum gc2235_tok_type {
GC2235_TOK_MASK = 0xfff0
};
-/**
+/*
* struct gc2235_reg - MI sensor register format
* @type: type of the register
* @reg: 8-bit offset to register
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index d0db2efe0045..8593ba90605f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -3721,22 +3721,34 @@ apply_min_padding:
*padding_h = max_t(u32, *padding_h, min_pad_h);
}
-static int atomisp_set_crop(struct atomisp_device *isp,
- const struct v4l2_mbus_framefmt *format,
- struct v4l2_subdev_state *sd_state,
- int which)
+static int atomisp_set_crop_and_fmt(struct atomisp_device *isp,
+ struct v4l2_mbus_framefmt *ffmt,
+ int which)
{
struct atomisp_input_subdev *input = &isp->inputs[isp->asd.input_curr];
struct v4l2_subdev_selection sel = {
.which = which,
.target = V4L2_SEL_TGT_CROP,
- .r.width = format->width,
- .r.height = format->height,
+ .r.width = ffmt->width,
+ .r.height = ffmt->height,
};
- int ret;
+ struct v4l2_subdev_format format = {
+ .which = which,
+ .format = *ffmt,
+ };
+ struct v4l2_subdev_state *sd_state;
+ int ret = 0;
+
+ if (!input->camera)
+ return -EINVAL;
+
+ sd_state = (which == V4L2_SUBDEV_FORMAT_TRY) ? input->try_sd_state :
+ input->camera->active_state;
+ if (sd_state)
+ v4l2_subdev_lock_state(sd_state);
if (!input->crop_support)
- return 0;
+ goto set_fmt;
/* Cropping is done before binning, when binning double the crop rect */
if (input->binning_support && sel.r.width <= (input->native_rect.width / 2) &&
@@ -3757,6 +3769,14 @@ static int atomisp_set_crop(struct atomisp_device *isp,
dev_err(isp->dev, "Error setting crop to %ux%u @%ux%u: %d\n",
sel.r.width, sel.r.height, sel.r.left, sel.r.top, ret);
+set_fmt:
+ if (ret == 0)
+ ret = v4l2_subdev_call(input->camera, pad, set_fmt, sd_state, &format);
+
+ if (sd_state)
+ v4l2_subdev_unlock_state(sd_state);
+
+ *ffmt = format.format;
return ret;
}
@@ -3767,16 +3787,10 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f,
{
const struct atomisp_format_bridge *fmt, *snr_fmt;
struct atomisp_sub_device *asd = &isp->asd;
- struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr];
- struct v4l2_subdev_format format = {
- .which = V4L2_SUBDEV_FORMAT_TRY,
- };
+ struct v4l2_mbus_framefmt ffmt = { };
u32 padding_w, padding_h;
int ret;
- if (!input->camera)
- return -EINVAL;
-
fmt = atomisp_get_format_bridge(f->pixelformat);
/* Currently, raw formats are broken!!! */
if (!fmt || fmt->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
@@ -3797,38 +3811,27 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f,
* the set_fmt call, like atomisp_set_fmt_to_snr() does.
*/
atomisp_get_padding(isp, f->width, f->height, &padding_w, &padding_h);
- v4l2_fill_mbus_format(&format.format, f, fmt->mbus_code);
- format.format.width += padding_w;
- format.format.height += padding_h;
-
- dev_dbg(isp->dev, "try_mbus_fmt: asking for %ux%u\n",
- format.format.width, format.format.height);
-
- v4l2_subdev_lock_state(input->try_sd_state);
+ v4l2_fill_mbus_format(&ffmt, f, fmt->mbus_code);
+ ffmt.width += padding_w;
+ ffmt.height += padding_h;
- ret = atomisp_set_crop(isp, &format.format, input->try_sd_state,
- V4L2_SUBDEV_FORMAT_TRY);
- if (ret == 0)
- ret = v4l2_subdev_call(input->camera, pad, set_fmt,
- input->try_sd_state, &format);
-
- v4l2_subdev_unlock_state(input->try_sd_state);
+ dev_dbg(isp->dev, "try_mbus_fmt: try %ux%u\n", ffmt.width, ffmt.height);
+ ret = atomisp_set_crop_and_fmt(isp, &ffmt, V4L2_SUBDEV_FORMAT_TRY);
if (ret)
return ret;
- dev_dbg(isp->dev, "try_mbus_fmt: got %ux%u\n",
- format.format.width, format.format.height);
+ dev_dbg(isp->dev, "try_mbus_fmt: got %ux%u\n", ffmt.width, ffmt.height);
- snr_fmt = atomisp_get_format_bridge_from_mbus(format.format.code);
+ snr_fmt = atomisp_get_format_bridge_from_mbus(ffmt.code);
if (!snr_fmt) {
dev_err(isp->dev, "unknown sensor format 0x%8.8x\n",
- format.format.code);
+ ffmt.code);
return -EINVAL;
}
- f->width = format.format.width - padding_w;
- f->height = format.format.height - padding_h;
+ f->width = ffmt.width - padding_w;
+ f->height = ffmt.height - padding_h;
/*
* If the format is jpeg or custom RAW, then the width and height will
@@ -4236,28 +4239,22 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
struct atomisp_sub_device *asd = pipe->asd;
struct atomisp_device *isp = asd->isp;
- struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr];
const struct atomisp_format_bridge *format;
- struct v4l2_subdev_state *act_sd_state;
- struct v4l2_subdev_format vformat = {
- .which = V4L2_SUBDEV_FORMAT_TRY,
- };
- struct v4l2_mbus_framefmt *ffmt = &vformat.format;
- struct v4l2_mbus_framefmt *req_ffmt;
+ struct v4l2_mbus_framefmt req_ffmt, ffmt = { };
struct atomisp_input_stream_info *stream_info =
- (struct atomisp_input_stream_info *)ffmt->reserved;
+ (struct atomisp_input_stream_info *)&ffmt.reserved;
int ret;
format = atomisp_get_format_bridge(f->pixelformat);
if (!format)
return -EINVAL;
- v4l2_fill_mbus_format(ffmt, f, format->mbus_code);
- ffmt->height += asd->sink_pad_padding_h + dvs_env_h;
- ffmt->width += asd->sink_pad_padding_w + dvs_env_w;
+ v4l2_fill_mbus_format(&ffmt, f, format->mbus_code);
+ ffmt.height += asd->sink_pad_padding_h + dvs_env_h;
+ ffmt.width += asd->sink_pad_padding_w + dvs_env_w;
dev_dbg(isp->dev, "s_mbus_fmt: ask %ux%u (padding %ux%u, dvs %ux%u)\n",
- ffmt->width, ffmt->height, asd->sink_pad_padding_w, asd->sink_pad_padding_h,
+ ffmt.width, ffmt.height, asd->sink_pad_padding_w, asd->sink_pad_padding_h,
dvs_env_w, dvs_env_h);
__atomisp_init_stream_info(ATOMISP_INPUT_STREAM_GENERAL, stream_info);
@@ -4266,28 +4263,17 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
/* Disable dvs if resolution can't be supported by sensor */
if (asd->params.video_dis_en && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
- v4l2_subdev_lock_state(input->try_sd_state);
-
- ret = atomisp_set_crop(isp, &vformat.format, input->try_sd_state,
- V4L2_SUBDEV_FORMAT_TRY);
- if (ret == 0) {
- vformat.which = V4L2_SUBDEV_FORMAT_TRY;
- ret = v4l2_subdev_call(input->camera, pad, set_fmt,
- input->try_sd_state, &vformat);
- }
-
- v4l2_subdev_unlock_state(input->try_sd_state);
-
+ ret = atomisp_set_crop_and_fmt(isp, &ffmt, V4L2_SUBDEV_FORMAT_TRY);
if (ret)
return ret;
dev_dbg(isp->dev, "video dis: sensor width: %d, height: %d\n",
- ffmt->width, ffmt->height);
+ ffmt.width, ffmt.height);
- if (ffmt->width < req_ffmt->width ||
- ffmt->height < req_ffmt->height) {
- req_ffmt->height -= dvs_env_h;
- req_ffmt->width -= dvs_env_w;
+ if (ffmt.width < req_ffmt.width ||
+ ffmt.height < req_ffmt.height) {
+ req_ffmt.height -= dvs_env_h;
+ req_ffmt.width -= dvs_env_w;
ffmt = req_ffmt;
dev_warn(isp->dev,
"can not enable video dis due to sensor limitation.");
@@ -4295,32 +4281,21 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
}
}
- act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera);
-
- ret = atomisp_set_crop(isp, &vformat.format, act_sd_state,
- V4L2_SUBDEV_FORMAT_ACTIVE);
- if (ret == 0) {
- vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(input->camera, pad, set_fmt, act_sd_state, &vformat);
- }
-
- if (act_sd_state)
- v4l2_subdev_unlock_state(act_sd_state);
-
+ ret = atomisp_set_crop_and_fmt(isp, &ffmt, V4L2_SUBDEV_FORMAT_ACTIVE);
if (ret)
return ret;
__atomisp_update_stream_env(asd, ATOMISP_INPUT_STREAM_GENERAL, stream_info);
dev_dbg(isp->dev, "sensor width: %d, height: %d\n",
- ffmt->width, ffmt->height);
+ ffmt.width, ffmt.height);
- if (ffmt->width < ATOM_ISP_STEP_WIDTH ||
- ffmt->height < ATOM_ISP_STEP_HEIGHT)
+ if (ffmt.width < ATOM_ISP_STEP_WIDTH ||
+ ffmt.height < ATOM_ISP_STEP_HEIGHT)
return -EINVAL;
if (asd->params.video_dis_en && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
- (ffmt->width < req_ffmt->width || ffmt->height < req_ffmt->height)) {
+ (ffmt.width < req_ffmt.width || ffmt.height < req_ffmt.height)) {
dev_warn(isp->dev,
"can not enable video dis due to sensor limitation.");
asd->params.video_dis_en = false;
@@ -4328,9 +4303,9 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p
atomisp_subdev_set_ffmt(&asd->subdev, NULL,
V4L2_SUBDEV_FORMAT_ACTIVE,
- ATOMISP_SUBDEV_PAD_SINK, ffmt);
+ ATOMISP_SUBDEV_PAD_SINK, &ffmt);
- return css_input_resolution_changed(asd, ffmt);
+ return css_input_resolution_changed(asd, &ffmt);
}
int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
index 02f06294bbfe..6fe8b0b7467a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
@@ -757,7 +757,7 @@ int atomisp_css_init(struct atomisp_device *isp)
return ret;
/* Init ISP */
- err = ia_css_init(isp->dev, &isp->css_env.isp_css_env, NULL,
+ err = ia_css_init(isp->dev, &isp->css_env.isp_css_env,
(uint32_t)mmu_base_addr, IA_CSS_IRQ_TYPE_PULSE);
if (err) {
dev_err(isp->dev, "css init failed --- bad firmware?\n");
diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c
index 1df534bf54d3..ba7dd569a55a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_drvfs.c
@@ -27,31 +27,17 @@
#include "hmm/hmm.h"
#include "ia_css_debug.h"
+#define OPTION_BIN_LIST BIT(0)
+#define OPTION_BIN_RUN BIT(1)
+#define OPTION_VALID (OPTION_BIN_LIST | OPTION_BIN_RUN)
+
/*
- * _iunit_debug:
- * dbglvl: iunit css driver trace level
* dbgopt: iunit debug option:
* bit 0: binary list
* bit 1: running binary
* bit 2: memory statistic
-*/
-struct _iunit_debug {
- struct device_driver *drv;
- struct atomisp_device *isp;
- unsigned int dbglvl;
- unsigned int dbgfun;
- unsigned int dbgopt;
-};
-
-#define OPTION_BIN_LIST BIT(0)
-#define OPTION_BIN_RUN BIT(1)
-#define OPTION_VALID (OPTION_BIN_LIST \
- | OPTION_BIN_RUN)
-
-static struct _iunit_debug iunit_debug = {
- .dbglvl = 0,
- .dbgopt = OPTION_BIN_LIST,
-};
+ */
+static unsigned int dbgopt = OPTION_BIN_LIST;
static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
unsigned int opt)
@@ -88,34 +74,44 @@ opt_err:
return ret;
}
-static ssize_t iunit_dbglvl_show(struct device_driver *drv, char *buf)
+static ssize_t dbglvl_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- iunit_debug.dbglvl = dbg_level;
- return sysfs_emit(buf, "dtrace level:%u\n", iunit_debug.dbglvl);
+ unsigned int dbglvl = ia_css_debug_get_dtrace_level();
+
+ return sysfs_emit(buf, "dtrace level:%u\n", dbglvl);
}
-static ssize_t iunit_dbglvl_store(struct device_driver *drv, const char *buf,
- size_t size)
+static ssize_t dbglvl_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
{
- if (kstrtouint(buf, 10, &iunit_debug.dbglvl)
- || iunit_debug.dbglvl < 1
- || iunit_debug.dbglvl > 9) {
+ unsigned int dbglvl;
+ int ret;
+
+ ret = kstrtouint(buf, 10, &dbglvl);
+ if (ret)
+ return ret;
+
+ if (dbglvl < 1 || dbglvl > 9)
return -ERANGE;
- }
- ia_css_debug_set_dtrace_level(iunit_debug.dbglvl);
+ ia_css_debug_set_dtrace_level(dbglvl);
return size;
}
+static DEVICE_ATTR_RW(dbglvl);
-static ssize_t iunit_dbgfun_show(struct device_driver *drv, char *buf)
+static ssize_t dbgfun_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- iunit_debug.dbgfun = atomisp_get_css_dbgfunc();
- return sysfs_emit(buf, "dbgfun opt:%u\n", iunit_debug.dbgfun);
+ unsigned int dbgfun = atomisp_get_css_dbgfunc();
+
+ return sysfs_emit(buf, "dbgfun opt:%u\n", dbgfun);
}
-static ssize_t iunit_dbgfun_store(struct device_driver *drv, const char *buf,
- size_t size)
+static ssize_t dbgfun_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
{
+ struct atomisp_device *isp = dev_get_drvdata(dev);
unsigned int opt;
int ret;
@@ -123,23 +119,20 @@ static ssize_t iunit_dbgfun_store(struct device_driver *drv, const char *buf,
if (ret)
return ret;
- ret = atomisp_set_css_dbgfunc(iunit_debug.isp, opt);
- if (ret)
- return ret;
-
- iunit_debug.dbgfun = opt;
-
- return size;
+ return atomisp_set_css_dbgfunc(isp, opt);
}
+static DEVICE_ATTR_RW(dbgfun);
-static ssize_t iunit_dbgopt_show(struct device_driver *drv, char *buf)
+static ssize_t dbgopt_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- return sysfs_emit(buf, "option:0x%x\n", iunit_debug.dbgopt);
+ return sysfs_emit(buf, "option:0x%x\n", dbgopt);
}
-static ssize_t iunit_dbgopt_store(struct device_driver *drv, const char *buf,
- size_t size)
+static ssize_t dbgopt_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
{
+ struct atomisp_device *isp = dev_get_drvdata(dev);
unsigned int opt;
int ret;
@@ -147,56 +140,27 @@ static ssize_t iunit_dbgopt_store(struct device_driver *drv, const char *buf,
if (ret)
return ret;
- iunit_debug.dbgopt = opt;
- ret = iunit_dump_dbgopt(iunit_debug.isp, iunit_debug.dbgopt);
+ dbgopt = opt;
+ ret = iunit_dump_dbgopt(isp, dbgopt);
if (ret)
return ret;
return size;
}
+static DEVICE_ATTR_RW(dbgopt);
-static const struct driver_attribute iunit_drvfs_attrs[] = {
- __ATTR(dbglvl, 0644, iunit_dbglvl_show, iunit_dbglvl_store),
- __ATTR(dbgfun, 0644, iunit_dbgfun_show, iunit_dbgfun_store),
- __ATTR(dbgopt, 0644, iunit_dbgopt_show, iunit_dbgopt_store),
+static struct attribute *dbg_attrs[] = {
+ &dev_attr_dbglvl.attr,
+ &dev_attr_dbgfun.attr,
+ &dev_attr_dbgopt.attr,
+ NULL
};
-static int iunit_drvfs_create_files(struct device_driver *drv)
-{
- int i, ret = 0;
-
- for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
- ret |= driver_create_file(drv, &iunit_drvfs_attrs[i]);
-
- return ret;
-}
-
-static void iunit_drvfs_remove_files(struct device_driver *drv)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
- driver_remove_file(drv, &iunit_drvfs_attrs[i]);
-}
-
-int atomisp_drvfs_init(struct atomisp_device *isp)
-{
- struct device_driver *drv = isp->dev->driver;
- int ret;
-
- iunit_debug.isp = isp;
- iunit_debug.drv = drv;
-
- ret = iunit_drvfs_create_files(iunit_debug.drv);
- if (ret) {
- dev_err(isp->dev, "drvfs_create_files error: %d\n", ret);
- iunit_drvfs_remove_files(iunit_debug.drv);
- }
-
- return ret;
-}
+static const struct attribute_group dbg_attr_group = {
+ .attrs = dbg_attrs,
+};
-void atomisp_drvfs_exit(void)
-{
- iunit_drvfs_remove_files(iunit_debug.drv);
-}
+const struct attribute_group *dbg_attr_groups[] = {
+ &dbg_attr_group,
+ NULL
+};
diff --git a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h b/drivers/staging/media/atomisp/pci/atomisp_drvfs.h
index 8f4cc722b881..8495cc133c06 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_drvfs.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_drvfs.h
@@ -19,7 +19,8 @@
#ifndef __ATOMISP_DRVFS_H__
#define __ATOMISP_DRVFS_H__
-int atomisp_drvfs_init(struct atomisp_device *isp);
-void atomisp_drvfs_exit(void);
+#include <linux/sysfs.h>
+
+extern const struct attribute_group *dbg_attr_groups[];
#endif /* __ATOMISP_DRVFS_H__ */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h
index d5b077e602ca..bba9bc64d447 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h
@@ -192,6 +192,7 @@ struct atomisp_device {
struct dev_pm_domain pm_domain;
struct pm_qos_request pm_qos;
s32 max_isr_latency;
+ bool pm_only;
struct atomisp_mipi_csi2_device csi2_port[ATOMISP_CAMERA_NR_PORTS];
struct atomisp_tpg_device tpg;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 5b2d88c02d36..bb8e5e883b50 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -666,14 +666,6 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
return ret;
}
- /* select operating sensor */
- ret = v4l2_subdev_call(isp->inputs[input].camera, video, s_routing,
- 0, 0, 0);
- if (ret && (ret != -ENOIOCTLCMD)) {
- dev_err(isp->dev, "Failed to select sensor\n");
- return ret;
- }
-
if (!IS_ISP2401) {
motor = isp->inputs[input].motor;
} else {
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index 547e1444ad97..f736e54c7df3 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -55,10 +55,6 @@
/* G-Min addition: pull this in from intel_mid_pm.h */
#define CSTATE_EXIT_LATENCY_C1 1
-static uint skip_fwload;
-module_param(skip_fwload, uint, 0644);
-MODULE_PARM_DESC(skip_fwload, "Skip atomisp firmware load");
-
/* cross componnet debug message flag */
int dbg_level;
module_param(dbg_level, int, 0644);
@@ -552,7 +548,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
dev_dbg(isp->dev, "IUNIT power-%s.\n", enable ? "on" : "off");
/* WA for P-Unit, if DVFS enabled, ISP timeout observed */
- if (IS_CHT && enable) {
+ if (IS_CHT && enable && !isp->pm_only) {
punit_ddr_dvfs_enable(false);
msleep(20);
}
@@ -562,7 +558,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
val, MRFLD_ISPSSPM0_ISPSSC_MASK);
/* WA:Enable DVFS */
- if (IS_CHT && !enable)
+ if (IS_CHT && !enable && !isp->pm_only)
punit_ddr_dvfs_enable(true);
/*
@@ -591,9 +587,6 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
usleep_range(100, 150);
} while (1);
- if (enable)
- msleep(10);
-
dev_err(isp->dev, "IUNIT power-%s timeout.\n", enable ? "on" : "off");
return -EBUSY;
}
@@ -605,11 +598,15 @@ int atomisp_power_off(struct device *dev)
int ret;
u32 reg;
- atomisp_css_uninit(isp);
+ if (isp->pm_only) {
+ pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, 0);
+ } else {
+ atomisp_css_uninit(isp);
- ret = atomisp_mrfld_pre_power_down(isp);
- if (ret)
- return ret;
+ ret = atomisp_mrfld_pre_power_down(isp);
+ if (ret)
+ return ret;
+ }
/*
* MRFLD IUNIT DPHY is located in an always-power-on island
@@ -638,6 +635,9 @@ int atomisp_power_on(struct device *dev)
pci_restore_state(to_pci_dev(dev));
cpu_latency_qos_update_request(&isp->pm_qos, isp->max_isr_latency);
+ if (isp->pm_only)
+ return 0;
+
/*restore register values for iUnit and iUnitPHY registers*/
if (isp->saved_regs.pcicmdsts)
atomisp_restore_iunit_reg(isp);
@@ -1161,9 +1161,6 @@ atomisp_load_firmware(struct atomisp_device *isp)
int rc;
char *fw_path = NULL;
- if (skip_fwload)
- return NULL;
-
if (firmware_name[0] != '\0') {
fw_path = firmware_name;
} else {
@@ -1199,46 +1196,39 @@ atomisp_load_firmware(struct atomisp_device *isp)
return fw;
}
-/*
- * Check for flags the driver was compiled with against the PCI
- * device. Always returns true on other than ISP 2400.
- */
-static bool is_valid_device(struct pci_dev *pdev, const struct pci_device_id *id)
+static void atomisp_pm_init(struct atomisp_device *isp)
{
- const char *name;
- const char *product;
-
- product = dmi_get_system_info(DMI_PRODUCT_NAME);
-
- switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) {
- case ATOMISP_PCI_DEVICE_SOC_MRFLD:
- name = "Merrifield";
- break;
- case ATOMISP_PCI_DEVICE_SOC_BYT:
- name = "Baytrail";
- break;
- case ATOMISP_PCI_DEVICE_SOC_ANN:
- name = "Anniedale";
- break;
- case ATOMISP_PCI_DEVICE_SOC_CHT:
- name = "Cherrytrail";
- break;
- default:
- dev_err(&pdev->dev, "%s: unknown device ID %x04:%x04\n",
- product, id->vendor, id->device);
- return false;
- }
+ /*
+ * The atomisp does not use standard PCI power-management through the
+ * PCI config space. Instead this driver directly tells the P-Unit to
+ * disable the ISP over the IOSF. The standard PCI subsystem pm_ops will
+ * try to access the config space before (resume) / after (suspend) this
+ * driver has turned the ISP on / off, resulting in the following errors:
+ *
+ * "Unable to change power state from D0 to D3hot, device inaccessible"
+ * "Unable to change power state from D3cold to D0, device inaccessible"
+ *
+ * To avoid these errors override the pm_domain so that all the PCI
+ * subsys suspend / resume handling is skipped.
+ */
+ isp->pm_domain.ops.runtime_suspend = atomisp_power_off;
+ isp->pm_domain.ops.runtime_resume = atomisp_power_on;
+ isp->pm_domain.ops.suspend = atomisp_suspend;
+ isp->pm_domain.ops.resume = atomisp_resume;
- if (pdev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) {
- dev_err(&pdev->dev, "%s revision %d is not unsupported\n",
- name, pdev->revision);
- return false;
- }
+ cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE);
+ dev_pm_domain_set(isp->dev, &isp->pm_domain);
- dev_info(&pdev->dev, "Detected %s version %d (ISP240%c) on %s\n",
- name, pdev->revision, IS_ISP2401 ? '1' : '0', product);
+ pm_runtime_allow(isp->dev);
+ pm_runtime_put_sync_suspend(isp->dev);
+}
- return true;
+static void atomisp_pm_uninit(struct atomisp_device *isp)
+{
+ pm_runtime_get_sync(isp->dev);
+ pm_runtime_forbid(isp->dev);
+ dev_pm_domain_set(isp->dev, NULL);
+ cpu_latency_qos_remove_request(&isp->pm_qos);
}
#define ATOM_ISP_PCI_BAR 0
@@ -1249,10 +1239,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
struct atomisp_device *isp;
unsigned int start;
int err, val;
- u32 irq;
-
- if (!is_valid_device(pdev, id))
- return -ENODEV;
/* Pointer to struct device. */
atomisp_dev = &pdev->dev;
@@ -1261,32 +1247,16 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
if (!pdata)
dev_warn(&pdev->dev, "no platform data available\n");
- err = pcim_enable_device(pdev);
- if (err) {
- dev_err(&pdev->dev, "Failed to enable CI ISP device (%d)\n", err);
- return err;
- }
-
start = pci_resource_start(pdev, ATOM_ISP_PCI_BAR);
dev_dbg(&pdev->dev, "start: 0x%x\n", start);
- err = pcim_iomap_regions(pdev, BIT(ATOM_ISP_PCI_BAR), pci_name(pdev));
- if (err) {
- dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", err);
- goto ioremap_fail;
- }
-
isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
- if (!isp) {
- err = -ENOMEM;
- goto atomisp_dev_alloc_fail;
- }
+ if (!isp)
+ return -ENOMEM;
isp->dev = &pdev->dev;
- isp->base = pcim_iomap_table(pdev)[ATOM_ISP_PCI_BAR];
isp->saved_regs.ispmmadr = start;
-
- dev_dbg(&pdev->dev, "atomisp mmio base: %p\n", isp->base);
+ isp->asd.isp = isp;
mutex_init(&isp->mutex);
spin_lock_init(&isp->lock);
@@ -1389,8 +1359,12 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
break;
default:
dev_err(&pdev->dev, "un-supported IUNIT device\n");
- err = -ENODEV;
- goto atomisp_dev_alloc_fail;
+ return -ENODEV;
+ }
+
+ if (pdev->revision <= ATOMISP_PCI_REV_BYT_A0_MAX) {
+ dev_err(&pdev->dev, "revision %d is not unsupported\n", pdev->revision);
+ return -ENODEV;
}
dev_info(&pdev->dev, "ISP HPLL frequency base = %d MHz\n", isp->hpll_freq);
@@ -1400,29 +1374,43 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
/* Load isp firmware from user space */
isp->firmware = atomisp_load_firmware(isp);
if (!isp->firmware) {
- err = -ENOENT;
- dev_dbg(&pdev->dev, "Firmware load failed\n");
- goto load_fw_fail;
+ /* No firmware continue in pm-only mode for S0i3 support */
+ dev_info(&pdev->dev, "Continuing in power-management only mode\n");
+ isp->pm_only = true;
+ atomisp_pm_init(isp);
+ return 0;
}
err = sh_css_check_firmware_version(isp->dev, isp->firmware->data);
if (err) {
dev_dbg(&pdev->dev, "Firmware version check failed\n");
- goto fw_validation_fail;
+ goto error_release_firmware;
+ }
+
+ err = pcim_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to enable ISP PCI device (%d)\n", err);
+ goto error_release_firmware;
+ }
+
+ err = pcim_iomap_regions(pdev, BIT(ATOM_ISP_PCI_BAR), pci_name(pdev));
+ if (err) {
+ dev_err(&pdev->dev, "Failed to I/O memory remapping (%d)\n", err);
+ goto error_release_firmware;
}
+ isp->base = pcim_iomap_table(pdev)[ATOM_ISP_PCI_BAR];
+
pci_set_master(pdev);
err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
if (err < 0) {
dev_err(&pdev->dev, "Failed to enable msi (%d)\n", err);
- goto enable_msi_fail;
+ goto error_release_firmware;
}
atomisp_msi_irq_init(isp);
- cpu_latency_qos_add_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE);
-
/*
* for MRFLD, Software/firmware needs to write a 1 to bit 0 of
* the register at CSI_RECEIVER_SELECTION_REG to enable SH CSI
@@ -1459,13 +1447,13 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
err = atomisp_initialize_modules(isp);
if (err < 0) {
dev_err(&pdev->dev, "atomisp_initialize_modules (%d)\n", err);
- goto initialize_modules_fail;
+ goto error_irq_uninit;
}
err = atomisp_register_entities(isp);
if (err < 0) {
dev_err(&pdev->dev, "atomisp_register_entities failed (%d)\n", err);
- goto register_entities_fail;
+ goto error_uninitialize_modules;
}
INIT_WORK(&isp->assert_recovery_work, atomisp_assert_recovery_work);
@@ -1473,29 +1461,6 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
/* save the iunit context only once after all the values are init'ed. */
atomisp_save_iunit_reg(isp);
- /*
- * The atomisp does not use standard PCI power-management through the
- * PCI config space. Instead this driver directly tells the P-Unit to
- * disable the ISP over the IOSF. The standard PCI subsystem pm_ops will
- * try to access the config space before (resume) / after (suspend) this
- * driver has turned the ISP on / off, resulting in the following errors:
- *
- * "Unable to change power state from D0 to D3hot, device inaccessible"
- * "Unable to change power state from D3cold to D0, device inaccessible"
- *
- * To avoid these errors override the pm_domain so that all the PCI
- * subsys suspend / resume handling is skipped.
- */
- isp->pm_domain.ops.runtime_suspend = atomisp_power_off;
- isp->pm_domain.ops.runtime_resume = atomisp_power_on;
- isp->pm_domain.ops.suspend = atomisp_suspend;
- isp->pm_domain.ops.resume = atomisp_resume;
-
- dev_pm_domain_set(&pdev->dev, &isp->pm_domain);
-
- pm_runtime_put_noidle(&pdev->dev);
- pm_runtime_allow(&pdev->dev);
-
/* Init ISP memory management */
hmm_init();
@@ -1504,72 +1469,45 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
IRQF_SHARED, "isp_irq", isp);
if (err) {
dev_err(&pdev->dev, "Failed to request irq (%d)\n", err);
- goto request_irq_fail;
+ goto error_unregister_entities;
}
/* Load firmware into ISP memory */
err = atomisp_css_load_firmware(isp);
if (err) {
dev_err(&pdev->dev, "Failed to init css.\n");
- goto css_init_fail;
+ goto error_free_irq;
}
/* Clear FW image from memory */
release_firmware(isp->firmware);
isp->firmware = NULL;
isp->css_env.isp_css_fw.data = NULL;
+ atomisp_pm_init(isp);
+
err = v4l2_async_nf_register(&isp->notifier);
if (err) {
dev_err(isp->dev, "failed to register async notifier : %d\n", err);
- goto css_init_fail;
+ goto error_unload_firmware;
}
- atomisp_drvfs_init(isp);
-
return 0;
-css_init_fail:
+error_unload_firmware:
+ atomisp_pm_uninit(isp);
+ ia_css_unload_firmware();
+error_free_irq:
devm_free_irq(&pdev->dev, pdev->irq, isp);
-request_irq_fail:
+error_unregister_entities:
hmm_cleanup();
- pm_runtime_get_noresume(&pdev->dev);
- dev_pm_domain_set(&pdev->dev, NULL);
atomisp_unregister_entities(isp);
-register_entities_fail:
+error_uninitialize_modules:
atomisp_uninitialize_modules(isp);
-initialize_modules_fail:
- cpu_latency_qos_remove_request(&isp->pm_qos);
+error_irq_uninit:
atomisp_msi_irq_uninit(isp);
pci_free_irq_vectors(pdev);
-enable_msi_fail:
-fw_validation_fail:
+error_release_firmware:
release_firmware(isp->firmware);
-load_fw_fail:
- /*
- * Switch off ISP, as keeping it powered on would prevent
- * reaching S0ix states.
- *
- * The following lines have been copied from atomisp suspend path
- */
-
- pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
- irq &= BIT(INTR_IIR);
- pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq);
-
- pci_read_config_dword(pdev, PCI_INTERRUPT_CTRL, &irq);
- irq &= ~BIT(INTR_IER);
- pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, irq);
-
- atomisp_msi_irq_uninit(isp);
-
- /* Address later when we worry about the ...field chips */
- if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power(isp, false))
- dev_err(&pdev->dev, "Failed to switch off ISP\n");
-
-atomisp_dev_alloc_fail:
- pcim_iounmap_regions(pdev, BIT(ATOM_ISP_PCI_BAR));
-
-ioremap_fail:
return err;
}
@@ -1577,22 +1515,21 @@ static void atomisp_pci_remove(struct pci_dev *pdev)
{
struct atomisp_device *isp = pci_get_drvdata(pdev);
- dev_info(&pdev->dev, "Removing atomisp driver\n");
+ atomisp_pm_uninit(isp);
- atomisp_drvfs_exit();
+ if (isp->pm_only)
+ return;
+ /* Undo ia_css_init() from atomisp_power_on() */
+ atomisp_css_uninit(isp);
ia_css_unload_firmware();
+ devm_free_irq(&pdev->dev, pdev->irq, isp);
hmm_cleanup();
- pm_runtime_forbid(&pdev->dev);
- pm_runtime_get_noresume(&pdev->dev);
- dev_pm_domain_set(&pdev->dev, NULL);
- cpu_latency_qos_remove_request(&isp->pm_qos);
-
- atomisp_msi_irq_uninit(isp);
atomisp_unregister_entities(isp);
-
- release_firmware(isp->firmware);
+ atomisp_uninitialize_modules(isp);
+ atomisp_msi_irq_uninit(isp);
+ pci_free_irq_vectors(pdev);
}
static const struct pci_device_id atomisp_pci_tbl[] = {
@@ -1608,11 +1545,12 @@ static const struct pci_device_id atomisp_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, ATOMISP_PCI_DEVICE_SOC_CHT)},
{0,}
};
-
MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl);
-
static struct pci_driver atomisp_pci_driver = {
+ .driver = {
+ .dev_groups = dbg_attr_groups,
+ },
.name = "atomisp-isp2",
.id_table = atomisp_pci_tbl,
.probe = atomisp_pci_probe,
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
index 0579deac5535..e9846951f4ed 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
@@ -73,7 +73,7 @@ uint32_t ia_css_circbuf_pop(
/**
* @brief Extract a value out of the circular buffer.
- * Get a value at an arbitrary poistion in the circular
+ * Get a value at an arbitrary position in the circular
* buffer. The user should call "ia_css_circbuf_is_empty()"
* to avoid accessing to an empty buffer.
*
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c
index d9f7c143794d..198c9f6e6191 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/src/circbuf.c
@@ -24,7 +24,7 @@
**********************************************************************/
/*
* @brief Read the oldest element from the circular buffer.
- * Read the oldest element WITHOUT checking whehter the
+ * Read the oldest element WITHOUT checking whether the
* circular buffer is empty or not. The oldest element is
* also removed out from the circular buffer.
*
@@ -129,7 +129,7 @@ uint32_t ia_css_circbuf_extract(ia_css_circbuf_t *cb, int offset)
u32 src_pos;
u32 dest_pos;
- /* get the maximum offest */
+ /* get the maximum offset */
max_offset = ia_css_circbuf_get_offset(cb, cb->desc->start, cb->desc->end);
max_offset--;
@@ -207,7 +207,7 @@ bool ia_css_circbuf_increase_size(
{
u8 curr_size;
u8 curr_end;
- unsigned int i = 0;
+ unsigned int i;
if (!cb || sz_delta == 0)
return false;
diff --git a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
index d6e52b4971d6..f6838a8fc9d5 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
@@ -84,7 +84,7 @@ struct ia_css_blob_info {
memory_offsets; /** offset wrt hdr in bytes */
u32 prog_name_offset; /** offset wrt hdr in bytes */
u32 size; /** Size of blob */
- u32 padding_size; /** total cummulative of bytes added due to section alignment */
+ u32 padding_size; /** total accumulation of bytes added due to section alignment */
u32 icache_source; /** Position of icache in blob */
u32 icache_size; /** Size of icache section */
u32 icache_padding;/** bytes added due to icache section alignment */
@@ -408,7 +408,7 @@ struct ia_css_acc_sp {
};
/* Acceleration firmware descriptor.
- * This descriptor descibes either SP code (stand-alone), or
+ * This descriptor describes either SP code (stand-alone), or
* ISP code (a separate pipeline stage).
*/
struct ia_css_acc_fw_hdr {
diff --git a/drivers/staging/media/atomisp/pci/ia_css_control.h b/drivers/staging/media/atomisp/pci/ia_css_control.h
index 88f031a63ba2..6a473459b346 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_control.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_control.h
@@ -30,39 +30,28 @@
* environment in which the CSS code runs. This is
* used for host side memory access and message
* printing. May not be NULL.
- * @param[in] fw Firmware package containing the firmware for all
- * predefined ISP binaries.
- * if fw is NULL the firmware must be loaded before
- * through a call of ia_css_load_firmware
* @param[in] l1_base Base index (isp2400)
* of the L1 page table. This is a physical
* address or index.
* @param[in] irq_type The type of interrupt to be used (edge or level)
- * @return Returns -EINVAL in case of any
+ * @return Returns -EINVAL in case of any
* errors and 0 otherwise.
*
* This function initializes the API which includes allocating and initializing
- * internal data structures. This also interprets the firmware package. All
- * contents of this firmware package are copied into local data structures, so
- * the fw pointer could be freed after this function completes.
+ * internal data structures.
+ * ia_css_load_firmware() must be called to load the firmware before calling
+ * this function.
*/
int ia_css_init(struct device *dev,
- const struct ia_css_env *env,
- const struct ia_css_fw *fw,
- u32 l1_base,
- enum ia_css_irq_type irq_type);
+ const struct ia_css_env *env,
+ u32 l1_base,
+ enum ia_css_irq_type irq_type);
/* @brief Un-initialize the CSS API.
* @return None
*
- * This function deallocates all memory that has been allocated by the CSS API
- * Exception: if you explicitly loaded firmware through ia_css_load_firmware
- * you need to call ia_css_unload_firmware to deallocate the memory reserved
- * for the firmware.
- * After this function is called, no other CSS functions should be called
- * with the exception of ia_css_init which will re-initialize the CSS code,
- * ia_css_unload_firmware to unload the firmware or ia_css_load_firmware
- * to load new firmware
+ * This function deallocates all memory that has been allocated by the CSS API.
+ * After this function is called, no other CSS functions should be called.
*/
void
ia_css_uninit(void);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_firmware.h b/drivers/staging/media/atomisp/pci/ia_css_firmware.h
index 01d2faf557cf..d3a66128b4de 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_firmware.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_firmware.h
@@ -46,10 +46,6 @@ struct device;
* This function interprets the firmware package. All
* contents of this firmware package are copied into local data structures, so
* the fw pointer could be freed after this function completes.
- *
- * Rationale for this function is that it can be called before ia_css_init, and thus
- * speeds up ia_css_init (ia_css_init is called each time a stream is created but the
- * firmware only needs to be loaded once).
*/
int
ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
@@ -61,6 +57,8 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
* This function unloads the firmware loaded by ia_css_load_firmware.
* It is pointless to call this function if no firmware is loaded,
* but it won't harm. Use this to deallocate all memory associated with the firmware.
+ * This function may only be called when the CSS API is in uninitialized state
+ * (e.g. after calling ia_css_uninit()).
*/
void
ia_css_unload_firmware(void);
diff --git a/drivers/staging/media/atomisp/pci/ia_css_irq.h b/drivers/staging/media/atomisp/pci/ia_css_irq.h
index 26b1b3c8ba62..00e2fd1f9647 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_irq.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_irq.h
@@ -84,11 +84,11 @@ enum ia_css_irq_info {
IA_CSS_IRQ_INFO_ISP_BINARY_STATISTICS_READY = BIT(17),
/** ISP binary statistics are ready */
IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR = BIT(18),
- /** the input system in in error */
+ /** the input system is in error */
IA_CSS_IRQ_INFO_IF_ERROR = BIT(19),
- /** the input formatter in in error */
+ /** the input formatter is in error */
IA_CSS_IRQ_INFO_DMA_ERROR = BIT(20),
- /** the dma in in error */
+ /** the dma is in error */
IA_CSS_IRQ_INFO_ISYS_EVENTS_READY = BIT(21),
/** end-of-frame events are ready in the isys_event queue */
};
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
index 175c301ee96a..ecc98686f5cf 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
@@ -57,9 +57,9 @@ struct ia_css_hdr_exclusion_params {
};
/**
- * \brief HDR public paramterers.
+ * \brief HDR public parameters.
* \details Struct with all parameters for HDR that can be seet from
- * the CSS API. Currenly, only test parameters are defined.
+ * the CSS API. Currently, only test parameters are defined.
*/
struct ia_css_hdr_config {
struct ia_css_hdr_irradiance_params irradiance; /** HDR irradiance parameters */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c
index 946b074e8288..d25bf59273ba 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/macc/macc_1.0/ia_css_macc_table.host.c
@@ -19,7 +19,7 @@
/* Multi-Axes Color Correction table for ISP1.
* 64values = 2x2matrix for 16area, [s2.13]
- * ineffective: 16 of "identity 2x2 matix" {8192,0,0,8192}
+ * ineffective: 16 of "identity 2x2 matrix" {8192,0,0,8192}
*/
const struct ia_css_macc_table default_macc_table = {
{
@@ -36,7 +36,7 @@ const struct ia_css_macc_table default_macc_table = {
/* Multi-Axes Color Correction table for ISP2.
* 64values = 2x2matrix for 16area, [s1.12]
- * ineffective: 16 of "identity 2x2 matix" {4096,0,0,4096}
+ * ineffective: 16 of "identity 2x2 matrix" {4096,0,0,4096}
*/
const struct ia_css_macc_table default_macc2_table = {
{
diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h
index 61f23814e2fd..3ff61faf0621 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_global.h
@@ -19,7 +19,7 @@
#define N_CSI_PORTS (3)
//AM: Use previous define for this.
-//MIPI allows upto 4 channels.
+//MIPI allows up to 4 channels.
#define N_CHANNELS (4)
// 12KB = 256bit x 384 words
#define IB_CAPACITY_IN_WORDS (384)
diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h
index 447c7c5c55a1..523c948923f3 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_public.h
@@ -163,7 +163,7 @@ STORAGE_CLASS_INPUT_SYSTEM_H void receiver_port_reg_store(
const hrt_address reg,
const hrt_data value);
-/*! Read from a control register PORT[port_ID] of of RECEIVER[ID]
+/*! Read from a control register PORT[port_ID] of RECEIVER[ID]
\param ID[in] RECEIVER identifier
\param port_ID[in] mipi PORT identifier
diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
index 0f3729e55e14..130662f8e768 100644
--- a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
+++ b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
@@ -534,7 +534,7 @@ ia_css_binary_uninit(void) {
static int
binary_grid_deci_factor_log2(int width, int height)
{
- /* 3A/Shading decimation factor spcification (at August 2008)
+ /* 3A/Shading decimation factor specification (at August 2008)
* ------------------------------------------------------------------
* [Image Width (BQ)] [Decimation Factor (BQ)] [Resulting grid cells]
* 1280 ?c 32 40 ?c
diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
index 3d8741e7d5ca..9d2b5f9cbb14 100644
--- a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
+++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
@@ -693,7 +693,7 @@ static void pipeline_init_defaults(
static void ia_css_pipeline_set_zoom_stage(struct ia_css_pipeline *pipeline)
{
struct ia_css_pipeline_stage *stage = NULL;
- int err = 0;
+ int err;
assert(pipeline);
if (pipeline->pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c
index 2f1c2df59f71..0e430388b331 100644
--- a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c
+++ b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c
@@ -81,7 +81,7 @@ int ia_css_queue_uninit(ia_css_queue_t *qhandle)
int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item)
{
- int error = 0;
+ int error;
if (!qhandle)
return -EINVAL;
@@ -123,7 +123,7 @@ int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item)
/* c. Store the queue object */
/* Set only fields requiring update with
- * valid value. Avoids uncessary calls
+ * valid value. Avoids unnecessary calls
* to load/store functions
*/
ignore_desc_flags = QUEUE_IGNORE_SIZE_START_STEP_FLAGS;
@@ -138,7 +138,7 @@ int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item)
int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item)
{
- int error = 0;
+ int error;
if (!qhandle || NULL == item)
return -EINVAL;
@@ -180,7 +180,7 @@ int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item)
/* c. Store the queue object */
/* Set only fields requiring update with
- * valid value. Avoids uncessary calls
+ * valid value. Avoids unnecessary calls
* to load/store functions
*/
ignore_desc_flags = QUEUE_IGNORE_SIZE_END_STEP_FLAGS;
@@ -193,7 +193,7 @@ int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item)
int ia_css_queue_is_full(ia_css_queue_t *qhandle, bool *is_full)
{
- int error = 0;
+ int error;
if ((!qhandle) || (!is_full))
return -EINVAL;
@@ -225,7 +225,7 @@ int ia_css_queue_is_full(ia_css_queue_t *qhandle, bool *is_full)
int ia_css_queue_get_free_space(ia_css_queue_t *qhandle, uint32_t *size)
{
- int error = 0;
+ int error;
if ((!qhandle) || (!size))
return -EINVAL;
@@ -257,7 +257,7 @@ int ia_css_queue_get_free_space(ia_css_queue_t *qhandle, uint32_t *size)
int ia_css_queue_get_used_space(ia_css_queue_t *qhandle, uint32_t *size)
{
- int error = 0;
+ int error;
if ((!qhandle) || (!size))
return -EINVAL;
@@ -289,8 +289,8 @@ int ia_css_queue_get_used_space(ia_css_queue_t *qhandle, uint32_t *size)
int ia_css_queue_peek(ia_css_queue_t *qhandle, u32 offset, uint32_t *element)
{
- u32 num_elems = 0;
- int error = 0;
+ u32 num_elems;
+ int error;
if ((!qhandle) || (!element))
return -EINVAL;
@@ -338,7 +338,7 @@ int ia_css_queue_peek(ia_css_queue_t *qhandle, u32 offset, uint32_t *element)
int ia_css_queue_is_empty(ia_css_queue_t *qhandle, bool *is_empty)
{
- int error = 0;
+ int error;
if ((!qhandle) || (!is_empty))
return -EINVAL;
@@ -370,7 +370,7 @@ int ia_css_queue_is_empty(ia_css_queue_t *qhandle, bool *is_empty)
int ia_css_queue_get_size(ia_css_queue_t *qhandle, uint32_t *size)
{
- int error = 0;
+ int error;
if ((!qhandle) || (!size))
return -EINVAL;
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c
index 2e07dab8bf51..1f24db77fe38 100644
--- a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c
+++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c
@@ -198,7 +198,7 @@ void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool,
struct ia_css_rmgr_vbuf_handle **handle)
{
u32 i;
- bool succes = false;
+ bool success = false;
assert(pool);
assert(pool->recycle);
@@ -208,11 +208,11 @@ void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool,
if (!pool->handles[i]) {
ia_css_rmgr_refcount_retain_vbuf(handle);
pool->handles[i] = *handle;
- succes = true;
+ success = true;
break;
}
}
- assert(succes);
+ assert(success);
}
/*
diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c
index f35c90809414..938a4ea89c59 100644
--- a/drivers/staging/media/atomisp/pci/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/sh_css.c
@@ -174,8 +174,6 @@ static struct sh_css_hmm_buffer_record hmm_buffer_record[MAX_HMM_BUFFER_NUM];
#define GPIO_FLASH_PIN_MASK BIT(HIVE_GPIO_STROBE_TRIGGER_PIN)
-static bool fw_explicitly_loaded;
-
/*
* Local prototypes
*/
@@ -1360,7 +1358,6 @@ ia_css_unload_firmware(void)
ia_css_binary_uninit();
sh_css_unload_firmware();
}
- fw_explicitly_loaded = false;
}
static void
@@ -1405,13 +1402,9 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
my_css.flush = env->cpu_mem_env.flush;
}
- ia_css_unload_firmware(); /* in case we are called twice */
err = sh_css_load_firmware(dev, fw->data, fw->bytes);
- if (!err) {
+ if (!err)
err = ia_css_binary_init_infos();
- if (!err)
- fw_explicitly_loaded = true;
- }
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() leave\n");
return err;
@@ -1419,9 +1412,7 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
int
ia_css_init(struct device *dev, const struct ia_css_env *env,
- const struct ia_css_fw *fw,
- u32 mmu_l1_base,
- enum ia_css_irq_type irq_type)
+ u32 mmu_l1_base, enum ia_css_irq_type irq_type)
{
int err;
ia_css_spctrl_cfg spctrl_cfg;
@@ -1466,8 +1457,6 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
/* Check struct ia_css_init_dmem_cfg */
COMPILATION_ERROR_IF(sizeof(struct ia_css_sp_init_dmem_cfg) != SIZE_OF_IA_CSS_SP_INIT_DMEM_CFG_STRUCT);
- if (!fw && !fw_explicitly_loaded)
- return -EINVAL;
if (!env)
return -EINVAL;
@@ -1543,22 +1532,7 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
IA_CSS_LEAVE_ERR(err);
return err;
}
- if (fw) {
- ia_css_unload_firmware(); /* in case we already had firmware loaded */
- err = sh_css_load_firmware(dev, fw->data, fw->bytes);
- if (err) {
- IA_CSS_LEAVE_ERR(err);
- return err;
- }
- err = ia_css_binary_init_infos();
- if (err) {
- IA_CSS_LEAVE_ERR(err);
- return err;
- }
- fw_explicitly_loaded = false;
- my_css_save.loaded_fw = (struct ia_css_fw *)fw;
- }
if (!sh_css_setup_spctrl_config(&sh_css_sp_fw, SP_PROG_NAME, &spctrl_cfg))
return -EINVAL;
@@ -2163,9 +2137,6 @@ ia_css_uninit(void)
ifmtr_set_if_blocking_mode_reset = true;
}
- if (!fw_explicitly_loaded)
- ia_css_unload_firmware();
-
ia_css_spctrl_unload_fw(SP0_ID);
sh_css_sp_set_sp_running(false);
/* check and free any remaining mipi frames */
@@ -3635,7 +3606,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
assert(pipeline || pipe_id == IA_CSS_PIPE_ID_COPY);
- assert(sizeof(NULL) <= sizeof(ddr_buffer.kernel_ptr));
+ assert(sizeof(void *) <= sizeof(ddr_buffer.kernel_ptr));
ddr_buffer.kernel_ptr = HOST_ADDRESS(NULL);
ddr_buffer.cookie_ptr = buffer->driver_cookie;
ddr_buffer.timing_data = buffer->timing_data;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_defs.h b/drivers/staging/media/atomisp/pci/sh_css_defs.h
index 7eb10b226f0a..2afde974e75d 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_defs.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_defs.h
@@ -131,7 +131,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
* invalid rows/columns that result from filter initialization are skipped. */
#define SH_CSS_MIN_DVS_ENVELOPE 12U
-/* The FPGA system (vec_nelems == 16) only supports upto 5MP */
+/* The FPGA system (vec_nelems == 16) only supports up to 5MP */
#define SH_CSS_MAX_SENSOR_WIDTH 4608
#define SH_CSS_MAX_SENSOR_HEIGHT 3450
diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
index b7c1e164ee24..6e11fd771938 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
@@ -174,7 +174,7 @@ ia_css_mipi_frame_calculate_size(const unsigned int width,
mem_words = ((embedded_data_size_words + 7) >> 3) +
mem_words_for_first_line +
(((height + 1) >> 1) - 1) * mem_words_per_odd_line +
- /* ceil (height/2) - 1 (first line is calculated separatelly) */
+ /* ceil (height/2) - 1 (first line is calculated separately) */
(height >> 1) * mem_words_per_even_line + /* floor(height/2) */
mem_words_for_EOF;
@@ -537,7 +537,7 @@ send_mipi_frames(struct ia_css_pipe *pipe)
/* Hand-over the SP-internal mipi buffers */
for (i = 0; i < my_css.num_mipi_frames[port]; i++) {
- /* Need to include the ofset for port. */
+ /* Need to include the offset for port. */
sh_css_update_host2sp_mipi_frame(port * NUM_MIPI_FRAMES_PER_STREAM + i,
my_css.mipi_frames[port][i]);
sh_css_update_host2sp_mipi_metadata(port * NUM_MIPI_FRAMES_PER_STREAM + i,
diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c
index 1fd39a2fca98..95cca281e8a3 100644
--- a/drivers/staging/media/imx/imx-media-csc-scaler.c
+++ b/drivers/staging/media/imx/imx-media-csc-scaler.c
@@ -803,6 +803,7 @@ static int ipu_csc_scaler_release(struct file *file)
dev_dbg(priv->dev, "Releasing instance %p\n", ctx);
+ v4l2_ctrl_handler_free(&ctx->ctrl_hdlr);
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
diff --git a/drivers/staging/media/imx/imx-media-fim.c b/drivers/staging/media/imx/imx-media-fim.c
index e28a33d9dec7..ccbc0371fba2 100644
--- a/drivers/staging/media/imx/imx-media-fim.c
+++ b/drivers/staging/media/imx/imx-media-fim.c
@@ -401,7 +401,7 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim)
{
/* add the FIM controls to the calling subdev ctrl handler */
return v4l2_ctrl_add_handler(fim->sd->ctrl_handler,
- &fim->ctrl_handler, NULL, false);
+ &fim->ctrl_handler, NULL, true);
}
/* Called by the subdev in its subdev registered callback */
diff --git a/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h
index caa358e0bae4..4aa2797f5e3c 100644
--- a/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h
+++ b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h
@@ -2485,11 +2485,9 @@ struct ipu3_uapi_anr_config {
* &ipu3_uapi_yuvp1_y_ee_nr_config
* @yds: y down scaler config. See &ipu3_uapi_yuvp1_yds_config
* @chnr: chroma noise reduction config. See &ipu3_uapi_yuvp1_chnr_config
- * @reserved1: reserved
* @yds2: y channel down scaler config. See &ipu3_uapi_yuvp1_yds_config
* @tcc: total color correction config as defined in struct
* &ipu3_uapi_yuvp2_tcc_static_config
- * @reserved2: reserved
* @anr: advanced noise reduction config.See &ipu3_uapi_anr_config
* @awb_fr: AWB filter response config. See ipu3_uapi_awb_fr_config
* @ae: auto exposure config As specified by &ipu3_uapi_ae_config
@@ -2724,7 +2722,6 @@ struct ipu3_uapi_obgrid_param {
* @acc_ae: 0 = no update, 1 = update.
* @acc_af: 0 = no update, 1 = update.
* @acc_awb: 0 = no update, 1 = update.
- * @__acc_osys: 0 = no update, 1 = update.
* @reserved3: Not used.
* @lin_vmem_params: 0 = no update, 1 = update.
* @tnr3_vmem_params: 0 = no update, 1 = update.
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
index a66f034380c0..3df58eb3e882 100644
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
+++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
@@ -1069,6 +1069,11 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
/* Initialize subdev media entity */
+ imgu_sd->subdev.entity.ops = &imgu_media_ops;
+ for (i = 0; i < IMGU_NODE_NUM; i++) {
+ imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
+ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+ }
r = media_entity_pads_init(&imgu_sd->subdev.entity, IMGU_NODE_NUM,
imgu_sd->subdev_pads);
if (r) {
@@ -1076,11 +1081,6 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
"failed initialize subdev media entity (%d)\n", r);
return r;
}
- imgu_sd->subdev.entity.ops = &imgu_media_ops;
- for (i = 0; i < IMGU_NODE_NUM; i++) {
- imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
- MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
- }
/* Initialize subdev */
v4l2_subdev_init(&imgu_sd->subdev, &imgu_subdev_ops);
@@ -1177,15 +1177,15 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe,
}
/* Initialize media entities */
+ node->vdev_pad.flags = node->output ?
+ MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
+ vdev->entity.ops = NULL;
r = media_entity_pads_init(&vdev->entity, 1, &node->vdev_pad);
if (r) {
dev_err(dev, "failed initialize media entity (%d)\n", r);
mutex_destroy(&node->lock);
return r;
}
- node->vdev_pad.flags = node->output ?
- MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
- vdev->entity.ops = NULL;
/* Initialize vbq */
vbq->type = node->vdev_fmt.type;
diff --git a/drivers/staging/media/meson/vdec/vdec.h b/drivers/staging/media/meson/vdec/vdec.h
index 0906b8fb5cc6..258685177700 100644
--- a/drivers/staging/media/meson/vdec/vdec.h
+++ b/drivers/staging/media/meson/vdec/vdec.h
@@ -101,7 +101,6 @@ struct amvdec_core {
* @conf_esparser: mandatory call to let the vdec configure the ESPARSER
* @vififo_level: mandatory call to get the current amount of data
* in the VIFIFO
- * @use_offsets: mandatory call. Returns 1 if the VDEC supports vififo offsets
*/
struct amvdec_ops {
int (*start)(struct amvdec_session *sess);
diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/staging/media/starfive/camss/stf-capture.c
index 70c24b050a1b..ec5169e7b391 100644
--- a/drivers/staging/media/starfive/camss/stf-capture.c
+++ b/drivers/staging/media/starfive/camss/stf-capture.c
@@ -20,28 +20,28 @@ static const struct stfcamss_format_info stf_wr_fmts[] = {
.pixelformat = V4L2_PIX_FMT_SRGGB10,
.planes = 1,
.vsub = { 1 },
- .bpp = 10,
+ .bpp = 16,
},
{
.code = MEDIA_BUS_FMT_SGRBG10_1X10,
.pixelformat = V4L2_PIX_FMT_SGRBG10,
.planes = 1,
.vsub = { 1 },
- .bpp = 10,
+ .bpp = 16,
},
{
.code = MEDIA_BUS_FMT_SGBRG10_1X10,
.pixelformat = V4L2_PIX_FMT_SGBRG10,
.planes = 1,
.vsub = { 1 },
- .bpp = 10,
+ .bpp = 16,
},
{
.code = MEDIA_BUS_FMT_SBGGR10_1X10,
.pixelformat = V4L2_PIX_FMT_SBGGR10,
.planes = 1,
.vsub = { 1 },
- .bpp = 10,
+ .bpp = 16,
},
};
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index 52e94c8f2f01..780da4a8b5af 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -427,11 +427,11 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
unsigned int ctb_addr_x, ctb_addr_y;
struct cedrus_buffer *cedrus_buf;
dma_addr_t src_buf_addr;
- dma_addr_t src_buf_end_addr;
u32 chroma_log2_weight_denom;
u32 num_entry_point_offsets;
u32 output_pic_list_index;
u32 pic_order_cnt[2];
+ size_t slice_bytes;
u8 padding;
int count;
u32 reg;
@@ -443,6 +443,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
pred_weight_table = &slice_params->pred_weight_table;
num_entry_point_offsets = slice_params->num_entry_point_offsets;
cedrus_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
+ slice_bytes = vb2_get_plane_payload(&run->src->vb2_buf, 0);
/*
* If entry points offsets are present, we should get them
@@ -490,7 +491,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, 0);
- reg = slice_params->bit_size;
+ reg = slice_bytes * 8;
cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg);
/* Source beginning and end addresses. */
@@ -504,10 +505,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg);
- src_buf_end_addr = src_buf_addr +
- DIV_ROUND_UP(slice_params->bit_size, 8);
-
- reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
+ reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_addr + slice_bytes);
cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
/* Coding tree block address */
diff --git a/include/media/cec.h b/include/media/cec.h
index d77982685116..10c9cf6058b7 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -224,8 +224,6 @@ struct cec_adap_ops {
* @notifier: CEC notifier
* @pin: CEC pin status struct
* @cec_dir: debugfs cec directory
- * @status_file: debugfs cec status file
- * @error_inj_file: debugfs cec error injection file
* @sequence: transmit sequence counter
* @input_phys: remote control input_phys name
*
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 2b6cd343ee9e..0393b23129eb 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -225,6 +225,7 @@ enum media_pad_signal_type {
* @graph_obj: Embedded structure containing the media object common data
* @entity: Entity this pad belongs to
* @index: Pad index in the entity pads array, numbered from 0 to n
+ * @num_links: Number of links connected to this pad
* @sig_type: Type of the signal inside a media pad
* @flags: Pad flags, as defined in
* :ref:`include/uapi/linux/media.h <media_header>`
@@ -236,6 +237,7 @@ struct media_pad {
struct media_gobj graph_obj; /* must be first field in struct */
struct media_entity *entity;
u16 index;
+ u16 num_links;
enum media_pad_signal_type sig_type;
unsigned long flags;
@@ -337,10 +339,6 @@ enum media_entity_type {
* @info.dev: Contains device major and minor info.
* @info.dev.major: device node major, if the device is a devnode.
* @info.dev.minor: device node minor, if the device is a devnode.
- * @major: Devnode major number (zero if not applicable). Kept just
- * for backward compatibility.
- * @minor: Devnode minor number (zero if not applicable). Kept just
- * for backward compatibility.
*
* .. note::
*
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 739b0f0fc1a0..63ad36f04f72 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -536,9 +536,10 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
* V4L2_CID_LINK_FREQ control implemented by the transmitter, or value
* calculated based on the V4L2_CID_PIXEL_RATE implemented by the transmitter.
*
- * Returns link frequency on success, otherwise a negative error code:
- * -ENOENT: Link frequency or pixel rate control not found
- * -EINVAL: Invalid link frequency value
+ * Return:
+ * * >0: Link frequency
+ * * %-ENOENT: Link frequency or pixel rate control not found
+ * * %-EINVAL: Invalid link frequency value
*/
s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul,
unsigned int div);
@@ -547,6 +548,31 @@ void v4l2_simplify_fraction(u32 *numerator, u32 *denominator,
unsigned int n_terms, unsigned int threshold);
u32 v4l2_fraction_to_interval(u32 numerator, u32 denominator);
+/**
+ * v4l2_link_freq_to_bitmap - Figure out platform-supported link frequencies
+ * @dev: The struct device
+ * @fw_link_freqs: Array of link frequencies from firmware
+ * @num_of_fw_link_freqs: Number of entries in @fw_link_freqs
+ * @driver_link_freqs: Array of link frequencies supported by the driver
+ * @num_of_driver_link_freqs: Number of entries in @driver_link_freqs
+ * @bitmap: Bitmap of driver-supported link frequencies found in @fw_link_freqs
+ *
+ * This function checks which driver-supported link frequencies are enabled in
+ * system firmware and sets the corresponding bits in @bitmap (after first
+ * zeroing it).
+ *
+ * Return:
+ * * %0: Success
+ * * %-ENOENT: No match found between driver-supported link frequencies and
+ * those available in firmware.
+ * * %-ENODATA: No link frequencies were specified in firmware.
+ */
+int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
+ unsigned int num_of_fw_link_freqs,
+ const s64 *driver_link_freqs,
+ unsigned int num_of_driver_link_freqs,
+ unsigned long *bitmap);
+
static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
{
/*
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 56719a26a46c..8b86996b2719 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -72,6 +72,10 @@ struct vb2_buffer;
* argument to other ops in this structure.
* @put_userptr: inform the allocator that a USERPTR buffer will no longer
* be used.
+ * @prepare: called every time the buffer is passed from userspace to the
+ * driver, useful for cache synchronisation, optional.
+ * @finish: called every time the buffer is passed back from the driver
+ * to the userspace, also optional.
* @attach_dmabuf: attach a shared &struct dma_buf for a hardware operation;
* used for DMABUF memory types; dev is the alloc device
* dbuf is the shared dma_buf; returns ERR_PTR() on failure;
@@ -86,10 +90,6 @@ struct vb2_buffer;
* dmabuf.
* @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
* that this driver is done using the dmabuf for now.
- * @prepare: called every time the buffer is passed from userspace to the
- * driver, useful for cache synchronisation, optional.
- * @finish: called every time the buffer is passed back from the driver
- * to the userspace, also optional.
* @vaddr: return a kernel virtual address to a given memory buffer
* associated with the passed private structure or NULL if no
* such mapping exists.
@@ -271,11 +271,11 @@ struct vb2_buffer {
* skips cache sync/invalidation.
* skip_cache_sync_on_finish: when set buffer's ->finish() function
* skips cache sync/invalidation.
+ * planes: per-plane information; do not change
* queued_entry: entry on the queued buffers list, which holds
* all buffers queued from userspace
* done_entry: entry on the list that stores all buffers ready
* to be dequeued to userspace
- * vb2_plane: per-plane information; do not change
*/
enum vb2_buffer_state state;
unsigned int synced:1;
@@ -484,7 +484,6 @@ struct vb2_buf_ops {
* caller. For example, for V4L2, it should match
* the types defined on &enum v4l2_buf_type.
* @io_modes: supported io methods (see &enum vb2_io_modes).
- * @alloc_devs: &struct device memory type/allocator-specific per-plane device
* @dev: device to use for the default allocation context if the driver
* doesn't fill in the @alloc_devs array.
* @dma_attrs: DMA attributes to use for the DMA.
@@ -553,6 +552,7 @@ struct vb2_buf_ops {
* VIDIOC_REQBUFS will ensure at least @min_queued_buffers
* buffers will be allocated. Note that VIDIOC_CREATE_BUFS will not
* modify the requested buffer count.
+ * @alloc_devs: &struct device memory type/allocator-specific per-plane device
*/
/*
* Private elements (won't appear at the uAPI book):
@@ -577,6 +577,9 @@ struct vb2_buf_ops {
* @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
* buffers. Only set for capture queues if qbuf has not yet been
* called since poll() needs to return %EPOLLERR in that situation.
+ * @waiting_in_dqbuf: set by the core for the duration of a blocking DQBUF, when
+ * it has to wait for a buffer to become available with vb2_queue->lock
+ * released. Used to prevent destroying the queue by other threads.
* @is_multiplanar: set if buffer type is multiplanar
* @is_output: set if buffer type is output
* @copy_timestamp: set if vb2-core should set timestamps
diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
index 730673ecc63d..6eeaf8bf2362 100644
--- a/include/uapi/linux/rkisp1-config.h
+++ b/include/uapi/linux/rkisp1-config.h
@@ -175,16 +175,21 @@
/**
* enum rkisp1_cif_isp_version - ISP variants
*
- * @RKISP1_V10: used at least in rk3288 and rk3399
- * @RKISP1_V11: declared in the original vendor code, but not used
- * @RKISP1_V12: used at least in rk3326 and px30
- * @RKISP1_V13: used at least in rk1808
+ * @RKISP1_V10: Used at least in RK3288 and RK3399.
+ * @RKISP1_V11: Declared in the original vendor code, but not used. Same number
+ * of entries in grids and histogram as v10.
+ * @RKISP1_V12: Used at least in RK3326 and PX30.
+ * @RKISP1_V13: Used at least in RK1808. Same number of entries in grids and
+ * histogram as v12.
+ * @RKISP1_V_IMX8MP: Used in at least i.MX8MP. Same number of entries in grids
+ * and histogram as v10.
*/
enum rkisp1_cif_isp_version {
RKISP1_V10 = 10,
RKISP1_V11,
RKISP1_V12,
RKISP1_V13,
+ RKISP1_V_IMX8MP,
};
enum rkisp1_cif_isp_histogram_mode {
@@ -584,10 +589,9 @@ enum rkisp1_cif_isp_goc_mode {
* as is reported by the hw_revision field of the struct media_device_info
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
*
- * Versions <= V11 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10
- * entries, versions >= V12 have RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12
- * entries. RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES is equal to the maximum
- * of the two.
+ * V10 has RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10 entries, V12 has
+ * RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12 entries.
+ * RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES is equal to the maximum of the two.
*/
struct rkisp1_cif_isp_goc_config {
__u32 mode;
@@ -607,10 +611,10 @@ struct rkisp1_cif_isp_goc_config {
* as is reported by the hw_revision field of the struct media_device_info
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
*
- * Versions <= V11 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10
- * entries, versions >= V12 have RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12
- * entries. RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE is equal to the maximum
- * of the two.
+ * V10 has RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10 entries, V12 has
+ * RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12 entries.
+ * RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE is equal to the maximum of the
+ * two.
*/
struct rkisp1_cif_isp_hst_config {
__u32 mode;
@@ -902,9 +906,9 @@ struct rkisp1_cif_isp_bls_meas_val {
* as is reported by the hw_revision field of the struct media_device_info
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
*
- * Versions <= V11 have RKISP1_CIF_ISP_AE_MEAN_MAX_V10 entries,
- * versions >= V12 have RKISP1_CIF_ISP_AE_MEAN_MAX_V12 entries.
- * RKISP1_CIF_ISP_AE_MEAN_MAX is equal to the maximum of the two.
+ * V10 has RKISP1_CIF_ISP_AE_MEAN_MAX_V10 entries, V12 has
+ * RKISP1_CIF_ISP_AE_MEAN_MAX_V12 entries. RKISP1_CIF_ISP_AE_MEAN_MAX is equal
+ * to the maximum of the two.
*
* Image is divided into 5x5 blocks on V10 and 9x9 blocks on V12.
*/
@@ -944,21 +948,21 @@ struct rkisp1_cif_isp_af_stat {
* integer part.
*
* The window of the measurements area is divided to 5x5 sub-windows for
- * V10/V11 and to 9x9 sub-windows for V12. The histogram is then computed for
- * each sub-window independently and the final result is a weighted average of
- * the histogram measurements on all sub-windows. The window of the
- * measurements area and the weight of each sub-window are configurable using
+ * V10 and to 9x9 sub-windows for V12. The histogram is then computed for each
+ * sub-window independently and the final result is a weighted average of the
+ * histogram measurements on all sub-windows. The window of the measurements
+ * area and the weight of each sub-window are configurable using
* struct @rkisp1_cif_isp_hst_config.
*
- * The histogram contains 16 bins in V10/V11 and 32 bins in V12/V13.
+ * The histogram contains 16 bins in V10 and 32 bins in V12.
*
* The number of entries of @hist_bins depends on the hardware revision
* as is reported by the hw_revision field of the struct media_device_info
* that is returned by ioctl MEDIA_IOC_DEVICE_INFO.
*
- * Versions <= V11 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10 entries,
- * versions >= V12 have RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 entries.
- * RKISP1_CIF_ISP_HIST_BIN_N_MAX is equal to the maximum of the two.
+ * V10 has RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10 entries, V12 has
+ * RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12 entries. RKISP1_CIF_ISP_HIST_BIN_N_MAX is
+ * equal to the maximum of the two.
*/
struct rkisp1_cif_isp_hist_stat {
__u32 hist_bins[RKISP1_CIF_ISP_HIST_BIN_N_MAX];
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 68e7ac178cc2..a8015e5e7fa4 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1041,13 +1041,13 @@ struct v4l2_requestbuffers {
* struct v4l2_plane - plane info for multi-planar buffers
* @bytesused: number of bytes occupied by data in the plane (payload)
* @length: size of this plane (NOT the payload) in bytes
- * @mem_offset: when memory in the associated struct v4l2_buffer is
+ * @m.mem_offset: when memory in the associated struct v4l2_buffer is
* V4L2_MEMORY_MMAP, equals the offset from the start of
* the device memory for this plane (or is a "cookie" that
* should be passed to mmap() called on the video node)
- * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
+ * @m.userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
* pointing to this plane
- * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file
+ * @m.fd: when memory is V4L2_MEMORY_DMABUF, a userspace file
* descriptor associated with this plane
* @m: union of @mem_offset, @userptr and @fd
* @data_offset: offset in the plane to the start of data; usually 0,
@@ -1085,14 +1085,14 @@ struct v4l2_plane {
* @sequence: sequence count of this frame
* @memory: enum v4l2_memory; the method, in which the actual video data is
* passed
- * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
+ * @m.offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
* offset from the start of the device memory for this plane,
* (or a "cookie" that should be passed to mmap() as offset)
- * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
+ * @m.userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
* a userspace pointer pointing to this buffer
- * @fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF;
+ * @m.fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF;
* a userspace file descriptor associated with this buffer
- * @planes: for multiplanar buffers; userspace pointer to the array of plane
+ * @m.planes: for multiplanar buffers; userspace pointer to the array of plane
* info structs for this buffer
* @m: union of @offset, @userptr, @planes and @fd
* @length: size in bytes of the buffer (NOT its payload) for single-plane
@@ -2423,15 +2423,15 @@ struct v4l2_meta_format {
/**
* struct v4l2_format - stream data format
- * @type: enum v4l2_buf_type; type of the data stream
- * @pix: definition of an image format
- * @pix_mp: definition of a multiplanar image format
- * @win: definition of an overlaid image
- * @vbi: raw VBI capture or output parameters
- * @sliced: sliced VBI capture or output parameters
- * @raw_data: placeholder for future extensions and custom formats
- * @fmt: union of @pix, @pix_mp, @win, @vbi, @sliced, @sdr, @meta
- * and @raw_data
+ * @type: enum v4l2_buf_type; type of the data stream
+ * @fmt.pix: definition of an image format
+ * @fmt.pix_mp: definition of a multiplanar image format
+ * @fmt.win: definition of an overlaid image
+ * @fmt.vbi: raw VBI capture or output parameters
+ * @fmt.sliced: sliced VBI capture or output parameters
+ * @fmt.raw_data: placeholder for future extensions and custom formats
+ * @fmt: union of @pix, @pix_mp, @win, @vbi, @sliced, @sdr,
+ * @meta and @raw_data
*/
struct v4l2_format {
__u32 type;