aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml95
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml77
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml80
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml1
-rw-r--r--Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml1
-rw-r--r--Documentation/devicetree/bindings/media/nxp,dw100.yaml69
-rw-r--r--Documentation/devicetree/bindings/media/renesas,vsp1.yaml53
-rw-r--r--Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml68
-rw-r--r--Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml81
-rw-r--r--Documentation/driver-api/media/drivers/pxa_camera.rst2
-rw-r--r--Documentation/userspace-api/media/drivers/dw100.rst84
-rw-r--r--Documentation/userspace-api/media/drivers/index.rst1
-rw-r--r--Documentation/userspace-api/media/v4l/async.rst9
-rw-r--r--Documentation/userspace-api/media/v4l/dev-raw-vbi.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/dev-sdr.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/hist-v4l2.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/io.rst4
-rw-r--r--Documentation/userspace-api/media/v4l/vidioc-dqevent.rst5
-rw-r--r--Documentation/userspace-api/media/v4l/vidioc-querycap.rst3
-rw-r--r--Documentation/userspace-api/media/videodev2.h.rst.exceptions1
-rw-r--r--MAINTAINERS24
-rw-r--r--drivers/media/cec/platform/sti/stih-cec.c4
-rw-r--r--drivers/media/common/Kconfig1
-rw-r--r--drivers/media/common/Makefile2
-rw-r--r--drivers/media/common/videobuf2/videobuf2-core.c14
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dvb.c4
-rw-r--r--drivers/media/common/videobuf2/videobuf2-v4l2.c17
-rw-r--r--drivers/media/dvb-frontends/dib8000.c2
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c2
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.c2
-rw-r--r--drivers/media/dvb-frontends/tda1002x.h2
-rw-r--r--drivers/media/dvb-frontends/tda10048.c2
-rw-r--r--drivers/media/i2c/adv7511-v4l2.c4
-rw-r--r--drivers/media/i2c/adv7604.c4
-rw-r--r--drivers/media/i2c/adv7842.c4
-rw-r--r--drivers/media/i2c/cx25840/cx25840-ir.c2
-rw-r--r--drivers/media/i2c/tc358743.c2
-rw-r--r--drivers/media/pci/Kconfig4
-rw-r--r--drivers/media/pci/Makefile6
-rw-r--r--drivers/media/pci/cx18/cx18-av-audio.c2
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-core.c3
-rw-r--r--drivers/media/pci/cx23885/cx23888-ir.c2
-rw-r--r--drivers/media/pci/cx88/cx88-dsp.c2
-rw-r--r--drivers/media/pci/cx88/cx88-vbi.c9
-rw-r--r--drivers/media/pci/cx88/cx88-video.c43
-rw-r--r--drivers/media/pci/ivtv/ivtv-yuv.c2
-rw-r--r--drivers/media/pci/ngene/ngene.h78
-rw-r--r--drivers/media/pci/saa7164/saa7164-core.c2
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c2
-rw-r--r--drivers/media/pci/zoran/Kconfig (renamed from drivers/staging/media/zoran/Kconfig)0
-rw-r--r--drivers/media/pci/zoran/Makefile (renamed from drivers/staging/media/zoran/Makefile)0
-rw-r--r--drivers/media/pci/zoran/videocodec.c (renamed from drivers/staging/media/zoran/videocodec.c)7
-rw-r--r--drivers/media/pci/zoran/videocodec.h (renamed from drivers/staging/media/zoran/videocodec.h)190
-rw-r--r--drivers/media/pci/zoran/zoran.h (renamed from drivers/staging/media/zoran/zoran.h)30
-rw-r--r--drivers/media/pci/zoran/zoran_card.c (renamed from drivers/staging/media/zoran/zoran_card.c)56
-rw-r--r--drivers/media/pci/zoran/zoran_card.h (renamed from drivers/staging/media/zoran/zoran_card.h)9
-rw-r--r--drivers/media/pci/zoran/zoran_device.c (renamed from drivers/staging/media/zoran/zoran_device.c)37
-rw-r--r--drivers/media/pci/zoran/zoran_device.h60
-rw-r--r--drivers/media/pci/zoran/zoran_driver.c (renamed from drivers/staging/media/zoran/zoran_driver.c)59
-rw-r--r--drivers/media/pci/zoran/zr36016.c (renamed from drivers/staging/media/zoran/zr36016.c)142
-rw-r--r--drivers/media/pci/zoran/zr36016.h (renamed from drivers/staging/media/zoran/zr36016.h)0
-rw-r--r--drivers/media/pci/zoran/zr36050.c (renamed from drivers/staging/media/zoran/zr36050.c)182
-rw-r--r--drivers/media/pci/zoran/zr36050.h (renamed from drivers/staging/media/zoran/zr36050.h)0
-rw-r--r--drivers/media/pci/zoran/zr36057.h (renamed from drivers/staging/media/zoran/zr36057.h)130
-rw-r--r--drivers/media/pci/zoran/zr36060.c (renamed from drivers/staging/media/zoran/zr36060.c)7
-rw-r--r--drivers/media/pci/zoran/zr36060.h (renamed from drivers/staging/media/zoran/zr36060.h)86
-rw-r--r--drivers/media/platform/Kconfig1
-rw-r--r--drivers/media/platform/Makefile1
-rw-r--r--drivers/media/platform/amlogic/meson-ge2d/ge2d.c1
-rw-r--r--drivers/media/platform/amphion/vdec.c16
-rw-r--r--drivers/media/platform/amphion/venc.c2
-rw-r--r--drivers/media/platform/amphion/vpu.h1
-rw-r--r--drivers/media/platform/amphion/vpu_core.c84
-rw-r--r--drivers/media/platform/amphion/vpu_core.h1
-rw-r--r--drivers/media/platform/amphion/vpu_dbg.c9
-rw-r--r--drivers/media/platform/amphion/vpu_malone.c2
-rw-r--r--drivers/media/platform/intel/pxa_camera.c8
-rw-r--r--drivers/media/platform/marvell/mcam-core.h2
-rw-r--r--drivers/media/platform/mediatek/Kconfig1
-rw-r--r--drivers/media/platform/mediatek/Makefile1
-rw-r--r--drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c1
-rw-r--r--drivers/media/platform/mediatek/mdp3/Kconfig21
-rw-r--r--drivers/media/platform/mediatek/mdp3/Makefile6
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_ccorr.h19
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h65
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h39
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_wdma.h47
-rw-r--r--drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h55
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h290
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c466
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h43
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c1033
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h186
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c357
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h94
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c724
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.h48
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c735
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h373
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c313
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.h78
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c2
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c4
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h6
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c19
-rw-r--r--drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c14
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c200
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h24
-rw-r--r--drivers/media/platform/mediatek/vcodec/venc_vpu_if.c76
-rw-r--r--drivers/media/platform/nxp/Kconfig13
-rw-r--r--drivers/media/platform/nxp/Makefile2
-rw-r--r--drivers/media/platform/nxp/dw100/Kconfig16
-rw-r--r--drivers/media/platform/nxp/dw100/Makefile3
-rw-r--r--drivers/media/platform/nxp/dw100/dw100.c1707
-rw-r--r--drivers/media/platform/nxp/dw100/dw100_regs.h117
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1.h4
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_drv.c101
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_lif.c12
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_regs.h6
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_video.c2
-rw-r--r--drivers/media/platform/rockchip/rga/rga.c2
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-core.h2
-rw-r--r--drivers/media/platform/samsung/exynos4-is/fimc-is.c1
-rw-r--r--drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c5
-rw-r--r--drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c2
-rw-r--r--drivers/media/platform/ti/am437x/am437x-vpfe.h2
-rw-r--r--drivers/media/platform/ti/cal/cal-camerarx.c31
-rw-r--r--drivers/media/platform/ti/cal/cal-video.c5
-rw-r--r--drivers/media/platform/ti/cal/cal.c139
-rw-r--r--drivers/media/platform/ti/cal/cal.h7
-rw-r--r--drivers/media/platform/ti/davinci/Kconfig49
-rw-r--r--drivers/media/platform/ti/davinci/Makefile4
-rw-r--r--drivers/media/platform/ti/davinci/vpbe.c2
-rw-r--r--drivers/media/platform/ti/davinci/vpif.h60
-rw-r--r--drivers/media/platform/ti/davinci/vpif_capture.c6
-rw-r--r--drivers/media/platform/ti/davinci/vpif_capture.h2
-rw-r--r--drivers/media/platform/ti/davinci/vpif_display.c6
-rw-r--r--drivers/media/platform/ti/davinci/vpif_display.h6
-rw-r--r--drivers/media/platform/ti/omap/omap_voutlib.c2
-rw-r--r--drivers/media/platform/ti/omap3isp/isp.c2
-rw-r--r--drivers/media/platform/ti/omap3isp/ispvideo.c2
-rw-r--r--drivers/media/platform/verisilicon/Kconfig (renamed from drivers/staging/media/hantro/Kconfig)6
-rw-r--r--drivers/media/platform/verisilicon/Makefile (renamed from drivers/staging/media/hantro/Makefile)0
-rw-r--r--drivers/media/platform/verisilicon/hantro.h (renamed from drivers/staging/media/hantro/hantro.h)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_drv.c (renamed from drivers/staging/media/hantro/hantro_drv.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g1.c (renamed from drivers/staging/media/hantro/hantro_g1.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g1_h264_dec.c (renamed from drivers/staging/media/hantro/hantro_g1_h264_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c (renamed from drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g1_regs.h (renamed from drivers/staging/media/hantro/hantro_g1_regs.h)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g1_vp8_dec.c (renamed from drivers/staging/media/hantro/hantro_g1_vp8_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g2.c (renamed from drivers/staging/media/hantro/hantro_g2.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c (renamed from drivers/staging/media/hantro/hantro_g2_hevc_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g2_regs.h (renamed from drivers/staging/media/hantro/hantro_g2_regs.h)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c (renamed from drivers/staging/media/hantro/hantro_g2_vp9_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c (renamed from drivers/staging/media/hantro/hantro_h1_jpeg_enc.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_h1_regs.h (renamed from drivers/staging/media/hantro/hantro_h1_regs.h)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_h264.c (renamed from drivers/staging/media/hantro/hantro_h264.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_hevc.c (renamed from drivers/staging/media/hantro/hantro_hevc.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_hw.h (renamed from drivers/staging/media/hantro/hantro_hw.h)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_jpeg.c (renamed from drivers/staging/media/hantro/hantro_jpeg.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_jpeg.h (renamed from drivers/staging/media/hantro/hantro_jpeg.h)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_mpeg2.c (renamed from drivers/staging/media/hantro/hantro_mpeg2.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_postproc.c (renamed from drivers/staging/media/hantro/hantro_postproc.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_v4l2.c (renamed from drivers/staging/media/hantro/hantro_v4l2.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_v4l2.h (renamed from drivers/staging/media/hantro/hantro_v4l2.h)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_vp8.c (renamed from drivers/staging/media/hantro/hantro_vp8.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_vp9.c (renamed from drivers/staging/media/hantro/hantro_vp9.c)0
-rw-r--r--drivers/media/platform/verisilicon/hantro_vp9.h (renamed from drivers/staging/media/hantro/hantro_vp9.h)0
-rw-r--r--drivers/media/platform/verisilicon/imx8m_vpu_hw.c (renamed from drivers/staging/media/hantro/imx8m_vpu_hw.c)0
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c (renamed from drivers/staging/media/hantro/rockchip_vpu2_hw_h264_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c (renamed from drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c)0
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c (renamed from drivers/staging/media/hantro/rockchip_vpu2_hw_mpeg2_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu2_hw_vp8_dec.c (renamed from drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c)0
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu2_regs.h (renamed from drivers/staging/media/hantro/rockchip_vpu2_regs.h)0
-rw-r--r--drivers/media/platform/verisilicon/rockchip_vpu_hw.c (renamed from drivers/staging/media/hantro/rockchip_vpu_hw.c)0
-rw-r--r--drivers/media/platform/verisilicon/sama5d4_vdec_hw.c (renamed from drivers/staging/media/hantro/sama5d4_vdec_hw.c)0
-rw-r--r--drivers/media/platform/verisilicon/sunxi_vpu_hw.c (renamed from drivers/staging/media/hantro/sunxi_vpu_hw.c)0
-rw-r--r--drivers/media/platform/xilinx/xilinx-csi2rxss.c1
-rw-r--r--drivers/media/platform/xilinx/xilinx-vip.c2
-rw-r--r--drivers/media/platform/xilinx/xilinx-vipp.c9
-rw-r--r--drivers/media/test-drivers/vim2m.c2
-rw-r--r--drivers/media/test-drivers/vivid/vivid-core.h5
-rw-r--r--drivers/media/test-drivers/vivid/vivid-ctrls.c14
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-cap.c4
-rw-r--r--drivers/media/usb/Kconfig3
-rw-r--r--drivers/media/usb/Makefile3
-rw-r--r--drivers/media/usb/airspy/airspy.c6
-rw-r--r--drivers/media/usb/au0828/au0828-video.c4
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-vbi.c2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c2
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c4
-rw-r--r--drivers/media/usb/gspca/finepix.c2
-rw-r--r--drivers/media/usb/msi2500/msi2500.c2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-dvb.c2
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c117
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c17
-rw-r--r--drivers/media/usb/uvc/uvc_video.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-api.c62
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-core.c218
-rw-r--r--drivers/media/v4l2-core/v4l2-flash-led-class.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c6
-rw-r--r--drivers/staging/media/Kconfig29
-rw-r--r--drivers/staging/media/Makefile12
-rw-r--r--drivers/staging/media/av7110/TODO3
-rw-r--r--drivers/staging/media/deprecated/cpia2/Kconfig (renamed from drivers/media/usb/cpia2/Kconfig)5
-rw-r--r--drivers/staging/media/deprecated/cpia2/Makefile (renamed from drivers/media/usb/cpia2/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/cpia2/TODO6
-rw-r--r--drivers/staging/media/deprecated/cpia2/cpia2.h (renamed from drivers/media/usb/cpia2/cpia2.h)0
-rw-r--r--drivers/staging/media/deprecated/cpia2/cpia2_core.c (renamed from drivers/media/usb/cpia2/cpia2_core.c)0
-rw-r--r--drivers/staging/media/deprecated/cpia2/cpia2_registers.h (renamed from drivers/media/usb/cpia2/cpia2_registers.h)0
-rw-r--r--drivers/staging/media/deprecated/cpia2/cpia2_usb.c (renamed from drivers/media/usb/cpia2/cpia2_usb.c)0
-rw-r--r--drivers/staging/media/deprecated/cpia2/cpia2_v4l.c (renamed from drivers/media/usb/cpia2/cpia2_v4l.c)0
-rw-r--r--drivers/staging/media/deprecated/fsl-viu/Kconfig15
-rw-r--r--drivers/staging/media/deprecated/fsl-viu/Makefile2
-rw-r--r--drivers/staging/media/deprecated/fsl-viu/TODO7
-rw-r--r--drivers/staging/media/deprecated/fsl-viu/fsl-viu.c (renamed from drivers/media/platform/nxp/fsl-viu.c)0
-rw-r--r--drivers/staging/media/deprecated/meye/Kconfig (renamed from drivers/media/pci/meye/Kconfig)5
-rw-r--r--drivers/staging/media/deprecated/meye/Makefile (renamed from drivers/media/pci/meye/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/meye/TODO6
-rw-r--r--drivers/staging/media/deprecated/meye/meye.c (renamed from drivers/media/pci/meye/meye.c)0
-rw-r--r--drivers/staging/media/deprecated/meye/meye.h (renamed from drivers/media/pci/meye/meye.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/Kconfig5
-rw-r--r--drivers/staging/media/deprecated/saa7146/Makefile2
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/Kconfig (renamed from drivers/staging/media/av7110/Kconfig)20
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/Makefile (renamed from drivers/staging/media/av7110/Makefile)3
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/TODO9
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-bilingual-channel-select.rst (renamed from drivers/staging/media/av7110/audio-bilingual-channel-select.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-channel-select.rst (renamed from drivers/staging/media/av7110/audio-channel-select.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-clear-buffer.rst (renamed from drivers/staging/media/av7110/audio-clear-buffer.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-continue.rst (renamed from drivers/staging/media/av7110/audio-continue.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-fclose.rst (renamed from drivers/staging/media/av7110/audio-fclose.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-fopen.rst (renamed from drivers/staging/media/av7110/audio-fopen.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-fwrite.rst (renamed from drivers/staging/media/av7110/audio-fwrite.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-get-capabilities.rst (renamed from drivers/staging/media/av7110/audio-get-capabilities.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-get-status.rst (renamed from drivers/staging/media/av7110/audio-get-status.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-pause.rst (renamed from drivers/staging/media/av7110/audio-pause.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-play.rst (renamed from drivers/staging/media/av7110/audio-play.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-select-source.rst (renamed from drivers/staging/media/av7110/audio-select-source.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-set-av-sync.rst (renamed from drivers/staging/media/av7110/audio-set-av-sync.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-set-bypass-mode.rst (renamed from drivers/staging/media/av7110/audio-set-bypass-mode.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-set-id.rst (renamed from drivers/staging/media/av7110/audio-set-id.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-set-mixer.rst (renamed from drivers/staging/media/av7110/audio-set-mixer.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-set-mute.rst (renamed from drivers/staging/media/av7110/audio-set-mute.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-set-streamtype.rst (renamed from drivers/staging/media/av7110/audio-set-streamtype.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio-stop.rst (renamed from drivers/staging/media/av7110/audio-stop.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio.rst (renamed from drivers/staging/media/av7110/audio.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio_data_types.rst (renamed from drivers/staging/media/av7110/audio_data_types.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/audio_function_calls.rst (renamed from drivers/staging/media/av7110/audio_function_calls.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110.c (renamed from drivers/staging/media/av7110/av7110.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110.h (renamed from drivers/staging/media/av7110/av7110.h)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c (renamed from drivers/staging/media/av7110/av7110_av.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_av.h (renamed from drivers/staging/media/av7110/av7110_av.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c (renamed from drivers/staging/media/av7110/av7110_ca.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.h (renamed from drivers/staging/media/av7110/av7110_ca.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.c (renamed from drivers/staging/media/av7110/av7110_hw.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.h (renamed from drivers/staging/media/av7110/av7110_hw.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.c (renamed from drivers/staging/media/av7110/av7110_ipack.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.h (renamed from drivers/staging/media/av7110/av7110_ipack.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_ir.c (renamed from drivers/staging/media/av7110/av7110_ir.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/av7110_v4l.c (renamed from drivers/staging/media/av7110/av7110_v4l.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/budget-patch.c (renamed from drivers/staging/media/av7110/budget-patch.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.c (renamed from drivers/staging/media/av7110/dvb_filter.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.h (renamed from drivers/staging/media/av7110/dvb_filter.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/sp8870.c (renamed from drivers/staging/media/av7110/sp8870.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/sp8870.h (renamed from drivers/staging/media/av7110/sp8870.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-clear-buffer.rst (renamed from drivers/staging/media/av7110/video-clear-buffer.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-command.rst (renamed from drivers/staging/media/av7110/video-command.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-continue.rst (renamed from drivers/staging/media/av7110/video-continue.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-fast-forward.rst (renamed from drivers/staging/media/av7110/video-fast-forward.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-fclose.rst (renamed from drivers/staging/media/av7110/video-fclose.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-fopen.rst (renamed from drivers/staging/media/av7110/video-fopen.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-freeze.rst (renamed from drivers/staging/media/av7110/video-freeze.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-fwrite.rst (renamed from drivers/staging/media/av7110/video-fwrite.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-get-capabilities.rst (renamed from drivers/staging/media/av7110/video-get-capabilities.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-get-event.rst (renamed from drivers/staging/media/av7110/video-get-event.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-get-frame-count.rst (renamed from drivers/staging/media/av7110/video-get-frame-count.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-get-pts.rst (renamed from drivers/staging/media/av7110/video-get-pts.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-get-size.rst (renamed from drivers/staging/media/av7110/video-get-size.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-get-status.rst (renamed from drivers/staging/media/av7110/video-get-status.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-play.rst (renamed from drivers/staging/media/av7110/video-play.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-select-source.rst (renamed from drivers/staging/media/av7110/video-select-source.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-set-blank.rst (renamed from drivers/staging/media/av7110/video-set-blank.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-set-display-format.rst (renamed from drivers/staging/media/av7110/video-set-display-format.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-set-format.rst (renamed from drivers/staging/media/av7110/video-set-format.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-set-streamtype.rst (renamed from drivers/staging/media/av7110/video-set-streamtype.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-slowmotion.rst (renamed from drivers/staging/media/av7110/video-slowmotion.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-stillpicture.rst (renamed from drivers/staging/media/av7110/video-stillpicture.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-stop.rst (renamed from drivers/staging/media/av7110/video-stop.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video-try-command.rst (renamed from drivers/staging/media/av7110/video-try-command.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video.rst (renamed from drivers/staging/media/av7110/video.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video_function_calls.rst (renamed from drivers/staging/media/av7110/video_function_calls.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/av7110/video_types.rst (renamed from drivers/staging/media/av7110/video_types.rst)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/Kconfig (renamed from drivers/media/common/saa7146/Kconfig)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/Makefile (renamed from drivers/media/common/saa7146/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146.h (renamed from include/media/drv-intf/saa7146.h)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146_core.c (renamed from drivers/media/common/saa7146/saa7146_core.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146_fops.c (renamed from drivers/media/common/saa7146/saa7146_fops.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146_hlp.c (renamed from drivers/media/common/saa7146/saa7146_hlp.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146_i2c.c (renamed from drivers/media/common/saa7146/saa7146_i2c.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146_vbi.c (renamed from drivers/media/common/saa7146/saa7146_vbi.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146_video.c (renamed from drivers/media/common/saa7146/saa7146_video.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/common/saa7146_vv.h (renamed from include/media/drv-intf/saa7146_vv.h)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/saa7146/Kconfig (renamed from drivers/media/pci/saa7146/Kconfig)15
-rw-r--r--drivers/staging/media/deprecated/saa7146/saa7146/Makefile (renamed from drivers/media/pci/saa7146/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/saa7146/TODO7
-rw-r--r--drivers/staging/media/deprecated/saa7146/saa7146/hexium_gemini.c (renamed from drivers/media/pci/saa7146/hexium_gemini.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/saa7146/hexium_orion.c (renamed from drivers/media/pci/saa7146/hexium_orion.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/saa7146/mxb.c (renamed from drivers/media/pci/saa7146/mxb.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/Kconfig (renamed from drivers/media/pci/ttpci/Kconfig)17
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/Makefile (renamed from drivers/media/pci/ttpci/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/TODO7
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c (renamed from drivers/media/pci/ttpci/budget-av.c)2
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/budget-ci.c (renamed from drivers/media/pci/ttpci/budget-ci.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/budget-core.c (renamed from drivers/media/pci/ttpci/budget-core.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/budget.c (renamed from drivers/media/pci/ttpci/budget.c)0
-rw-r--r--drivers/staging/media/deprecated/saa7146/ttpci/budget.h (renamed from drivers/media/pci/ttpci/budget.h)2
-rw-r--r--drivers/staging/media/deprecated/stkwebcam/Kconfig (renamed from drivers/staging/media/stkwebcam/Kconfig)0
-rw-r--r--drivers/staging/media/deprecated/stkwebcam/Makefile (renamed from drivers/staging/media/stkwebcam/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/stkwebcam/TODO (renamed from drivers/staging/media/stkwebcam/TODO)0
-rw-r--r--drivers/staging/media/deprecated/stkwebcam/stk-sensor.c (renamed from drivers/staging/media/stkwebcam/stk-sensor.c)0
-rw-r--r--drivers/staging/media/deprecated/stkwebcam/stk-webcam.c (renamed from drivers/staging/media/stkwebcam/stk-webcam.c)0
-rw-r--r--drivers/staging/media/deprecated/stkwebcam/stk-webcam.h (renamed from drivers/staging/media/stkwebcam/stk-webcam.h)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/Kconfig (renamed from drivers/media/usb/tm6000/Kconfig)5
-rw-r--r--drivers/staging/media/deprecated/tm6000/Makefile (renamed from drivers/media/usb/tm6000/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/TODO7
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-alsa.c (renamed from drivers/media/usb/tm6000/tm6000-alsa.c)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-cards.c (renamed from drivers/media/usb/tm6000/tm6000-cards.c)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-core.c (renamed from drivers/media/usb/tm6000/tm6000-core.c)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-dvb.c (renamed from drivers/media/usb/tm6000/tm6000-dvb.c)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-i2c.c (renamed from drivers/media/usb/tm6000/tm6000-i2c.c)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-input.c (renamed from drivers/media/usb/tm6000/tm6000-input.c)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-regs.h (renamed from drivers/media/usb/tm6000/tm6000-regs.h)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-stds.c (renamed from drivers/media/usb/tm6000/tm6000-stds.c)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-usb-isoc.h (renamed from drivers/media/usb/tm6000/tm6000-usb-isoc.h)0
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000-video.c (renamed from drivers/media/usb/tm6000/tm6000-video.c)2
-rw-r--r--drivers/staging/media/deprecated/tm6000/tm6000.h (renamed from drivers/media/usb/tm6000/tm6000.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/Kconfig58
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/Makefile4
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/TODO7
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/ccdc_hw_device.h (renamed from drivers/media/platform/ti/davinci/ccdc_hw_device.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc.c (renamed from drivers/media/platform/ti/davinci/dm355_ccdc.c)2
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc.h (renamed from include/media/davinci/dm355_ccdc.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc_regs.h (renamed from drivers/media/platform/ti/davinci/dm355_ccdc_regs.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc.c (renamed from drivers/media/platform/ti/davinci/dm644x_ccdc.c)2
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc.h (renamed from include/media/davinci/dm644x_ccdc.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc_regs.h (renamed from drivers/media/platform/ti/davinci/dm644x_ccdc_regs.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/isif.c (renamed from drivers/media/platform/ti/davinci/isif.c)2
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/isif.h (renamed from include/media/davinci/isif.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/isif_regs.h (renamed from drivers/media/platform/ti/davinci/isif_regs.h)0
-rw-r--r--drivers/staging/media/deprecated/vpfe_capture/vpfe_capture.c (renamed from drivers/media/platform/ti/davinci/vpfe_capture.c)0
-rw-r--r--drivers/staging/media/deprecated/zr364xx/Kconfig (renamed from drivers/media/usb/zr364xx/Kconfig)7
-rw-r--r--drivers/staging/media/deprecated/zr364xx/Makefile (renamed from drivers/media/usb/zr364xx/Makefile)0
-rw-r--r--drivers/staging/media/deprecated/zr364xx/TODO7
-rw-r--r--drivers/staging/media/deprecated/zr364xx/zr364xx.c (renamed from drivers/media/usb/zr364xx/zr364xx.c)0
-rw-r--r--drivers/staging/media/hantro/TODO2
-rw-r--r--drivers/staging/media/imx/imx7-media-csi.c2
-rw-r--r--drivers/staging/media/meson/vdec/vdec_hevc.c6
-rw-r--r--drivers/staging/media/omap4iss/iss_video.c2
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus.c4
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus.h24
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_dec.c4
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_h264.c16
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_h265.c23
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c28
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_vp8.c43
-rw-r--r--drivers/staging/media/zoran/TODO19
-rw-r--r--drivers/staging/media/zoran/zoran_device.h60
-rw-r--r--include/media/davinci/vpbe_display.h6
-rw-r--r--include/media/v4l2-ctrls.h140
-rw-r--r--include/media/v4l2-mem2mem.h12
-rw-r--r--include/media/videobuf2-core.h16
-rw-r--r--include/media/videobuf2-dvb.h2
-rw-r--r--include/media/videobuf2-v4l2.h16
-rw-r--r--include/uapi/linux/dw100.h14
-rw-r--r--include/uapi/linux/v4l2-controls.h8
-rw-r--r--include/uapi/linux/videodev2.h7
380 files changed, 9472 insertions, 1463 deletions
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
new file mode 100644
index 000000000000..9cfc0c7d23e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Read Direct Memory Access
+
+maintainers:
+ - Matthias Brugger <matthias.bgg@gmail.com>
+ - Moudy Ho <moudy.ho@mediatek.com>
+
+description: |
+ MediaTek Read Direct Memory Access(RDMA) component used to do read DMA.
+ It contains one line buffer to store the sufficient pixel data, and
+ must be siblings to the central MMSYS_CONFIG node.
+ For a description of the MMSYS_CONFIG binding, see
+ Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+ for details.
+
+properties:
+ compatible:
+ items:
+ - const: mediatek,mt8183-mdp3-rdma
+
+ reg:
+ maxItems: 1
+
+ mediatek,gce-client-reg:
+ $ref: '/schemas/types.yaml#/definitions/phandle-array'
+ items:
+ items:
+ - description: phandle of GCE
+ - description: GCE subsys id
+ - description: register offset
+ - description: register size
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property. Each GCE subsys id is mapping to
+ a client defined in the header include/dt-bindings/gce/<chip>-gce.h.
+
+ mediatek,gce-events:
+ description:
+ The event id which is mapping to the specific hardware event signal
+ to gce. The event id is defined in the gce header
+ include/dt-bindings/gce/<chip>-gce.h of each chips.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: RDMA clock
+ - description: RSZ clock
+
+ iommus:
+ maxItems: 1
+
+ mboxes:
+ items:
+ - description: used for 1st data pipe from RDMA
+ - description: used for 2nd data pipe from RDMA
+
+required:
+ - compatible
+ - reg
+ - mediatek,gce-client-reg
+ - mediatek,gce-events
+ - power-domains
+ - clocks
+ - iommus
+ - mboxes
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt8183-clk.h>
+ #include <dt-bindings/gce/mt8183-gce.h>
+ #include <dt-bindings/power/mt8183-power.h>
+ #include <dt-bindings/memory/mt8183-larb-port.h>
+
+ mdp3_rdma0: mdp3-rdma0@14001000 {
+ compatible = "mediatek,mt8183-mdp3-rdma";
+ reg = <0x14001000 0x1000>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>;
+ mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>,
+ <CMDQ_EVENT_MDP_RDMA0_EOF>;
+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_MDP_RDMA0>,
+ <&mmsys CLK_MM_MDP_RSZ1>;
+ iommus = <&iommu>;
+ mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>,
+ <&gce 21 CMDQ_THR_PRIO_LOWEST>;
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
new file mode 100644
index 000000000000..78f9de6192ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rsz.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Resizer
+
+maintainers:
+ - Matthias Brugger <matthias.bgg@gmail.com>
+ - Moudy Ho <moudy.ho@mediatek.com>
+
+description: |
+ One of Media Data Path 3 (MDP3) components used to do frame resizing.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - mediatek,mt8183-mdp3-rsz
+
+ reg:
+ maxItems: 1
+
+ mediatek,gce-client-reg:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ items:
+ - description: phandle of GCE
+ - description: GCE subsys id
+ - description: register offset
+ - description: register size
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property. Each GCE subsys id is mapping to
+ a client defined in the header include/dt-bindings/gce/<chip>-gce.h.
+
+ mediatek,gce-events:
+ description:
+ The event id which is mapping to the specific hardware event signal
+ to gce. The event id is defined in the gce header
+ include/dt-bindings/gce/<chip>-gce.h of each chips.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ clocks:
+ minItems: 1
+
+required:
+ - compatible
+ - reg
+ - mediatek,gce-client-reg
+ - mediatek,gce-events
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt8183-clk.h>
+ #include <dt-bindings/gce/mt8183-gce.h>
+
+ mdp3_rsz0: mdp3-rsz0@14003000 {
+ compatible = "mediatek,mt8183-mdp3-rsz";
+ reg = <0x14003000 0x1000>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
+ mediatek,gce-events = <CMDQ_EVENT_MDP_RSZ0_SOF>,
+ <CMDQ_EVENT_MDP_RSZ0_EOF>;
+ clocks = <&mmsys CLK_MM_MDP_RSZ0>;
+ };
+
+ mdp3_rsz1: mdp3-rsz1@14004000 {
+ compatible = "mediatek,mt8183-mdp3-rsz";
+ reg = <0x14004000 0x1000>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
+ mediatek,gce-events = <CMDQ_EVENT_MDP_RSZ1_SOF>,
+ <CMDQ_EVENT_MDP_RSZ1_EOF>;
+ clocks = <&mmsys CLK_MM_MDP_RSZ1>;
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
new file mode 100644
index 000000000000..0baa77198fa2
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-wrot.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Write DMA with Rotation
+
+maintainers:
+ - Matthias Brugger <matthias.bgg@gmail.com>
+ - Moudy Ho <moudy.ho@mediatek.com>
+
+description: |
+ One of Media Data Path 3 (MDP3) components used to write DMA with frame rotation.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - mediatek,mt8183-mdp3-wrot
+
+ reg:
+ maxItems: 1
+
+ mediatek,gce-client-reg:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ items:
+ - description: phandle of GCE
+ - description: GCE subsys id
+ - description: register offset
+ - description: register size
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property. Each GCE subsys id is mapping to
+ a client defined in the header include/dt-bindings/gce/<chip>-gce.h.
+
+ mediatek,gce-events:
+ description:
+ The event id which is mapping to the specific hardware event signal
+ to gce. The event id is defined in the gce header
+ include/dt-bindings/gce/<chip>-gce.h of each chips.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+
+ iommus:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - mediatek,gce-client-reg
+ - mediatek,gce-events
+ - power-domains
+ - clocks
+ - iommus
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt8183-clk.h>
+ #include <dt-bindings/gce/mt8183-gce.h>
+ #include <dt-bindings/power/mt8183-power.h>
+ #include <dt-bindings/memory/mt8183-larb-port.h>
+
+ mdp3_wrot0: mdp3-wrot0@14005000 {
+ compatible = "mediatek,mt8183-mdp3-wrot";
+ reg = <0x14005000 0x1000>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
+ mediatek,gce-events = <CMDQ_EVENT_MDP_WROT0_SOF>,
+ <CMDQ_EVENT_MDP_WROT0_EOF>;
+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_MDP_WROT0>;
+ iommus = <&iommu>;
+ };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
index d36fcca04cbc..32aee09aea33 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -20,6 +20,7 @@ properties:
- mediatek,mt8173-vcodec-enc-vp8
- mediatek,mt8173-vcodec-enc
- mediatek,mt8183-vcodec-enc
+ - mediatek,mt8188-vcodec-enc
- mediatek,mt8192-vcodec-enc
- mediatek,mt8195-vcodec-enc
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index d4e2051beeb6..c4f20acdc1f8 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -57,6 +57,7 @@ properties:
enum:
- mediatek,mt8192-vcodec-dec
- mediatek,mt8186-vcodec-dec
+ - mediatek,mt8188-vcodec-dec
- mediatek,mt8195-vcodec-dec
reg:
diff --git a/Documentation/devicetree/bindings/media/nxp,dw100.yaml b/Documentation/devicetree/bindings/media/nxp,dw100.yaml
new file mode 100644
index 000000000000..21910ff0e1c3
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/nxp,dw100.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/nxp,dw100.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8MP DW100 Dewarper core
+
+maintainers:
+ - Xavier Roumegue <xavier.roumegue@oss.nxp.com>
+
+description: |-
+ The Dewarp Engine provides high-performance dewarp processing for the
+ correction of the distortion that is introduced in images produced by fisheye
+ and wide angle lenses. It is implemented with a line/tile-cache based
+ architecture. With configurable address mapping look up tables and per tile
+ processing, it successfully generates a corrected output image.
+ The engine can be used to perform scaling, cropping and pixel format
+ conversion.
+
+properties:
+ compatible:
+ enum:
+ - nxp,imx8mp-dw100
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: The AXI clock
+ - description: The AHB clock
+
+ clock-names:
+ items:
+ - const: axi
+ - const: ahb
+
+ power-domains:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - power-domains
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/imx8mp-clock.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/imx8mp-power.h>
+
+ dewarp: dwe@32e30000 {
+ compatible = "nxp,imx8mp-dw100";
+ reg = <0x32e30000 0x10000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX8MP_CLK_MEDIA_AXI_ROOT>,
+ <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
+ clock-names = "axi", "ahb";
+ power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_DWE>;
+ };
diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.yaml b/Documentation/devicetree/bindings/media/renesas,vsp1.yaml
index 990e9c1dbc43..7a8f32473852 100644
--- a/Documentation/devicetree/bindings/media/renesas,vsp1.yaml
+++ b/Documentation/devicetree/bindings/media/renesas,vsp1.yaml
@@ -17,6 +17,7 @@ description:
properties:
compatible:
enum:
+ - renesas,r9a07g044-vsp2 # RZ/G2L
- renesas,vsp1 # R-Car Gen2 and RZ/G1
- renesas,vsp2 # R-Car Gen3 and RZ/G2
@@ -26,8 +27,8 @@ properties:
interrupts:
maxItems: 1
- clocks:
- maxItems: 1
+ clocks: true
+ clock-names: true
power-domains:
maxItems: 1
@@ -50,17 +51,43 @@ required:
additionalProperties: false
-if:
- properties:
- compatible:
- items:
- - const: renesas,vsp1
-then:
- properties:
- renesas,fcp: false
-else:
- required:
- - renesas,fcp
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,vsp1
+ then:
+ properties:
+ renesas,fcp: false
+ else:
+ required:
+ - renesas,fcp
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: renesas,r9a07g044-vsp2
+ then:
+ properties:
+ clocks:
+ items:
+ - description: Main clock
+ - description: Register access clock
+ - description: Video clock
+ clock-names:
+ items:
+ - const: aclk
+ - const: pclk
+ - const: vclk
+ required:
+ - clock-names
+ else:
+ properties:
+ clocks:
+ maxItems: 1
+ clock-names: false
examples:
# R8A7790 (R-Car H2) VSP1-S
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..4380b98b0dfe
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek color correction
+
+maintainers:
+ - Matthias Brugger <matthias.bgg@gmail.com>
+ - Moudy Ho <moudy.ho@mediatek.com>
+
+description: |
+ MediaTek color correction with 3X3 matrix.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - mediatek,mt8183-mdp3-ccorr
+
+ reg:
+ maxItems: 1
+
+ mediatek,gce-client-reg:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ items:
+ - description: phandle of GCE
+ - description: GCE subsys id
+ - description: register offset
+ - description: register size
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property. Each GCE subsys id is mapping to
+ a client defined in the header include/dt-bindings/gce/<chip>-gce.h.
+
+ mediatek,gce-events:
+ description:
+ The event id which is mapping to the specific hardware event signal
+ to gce. The event id is defined in the gce header
+ include/dt-bindings/gce/<chip>-gce.h of each chips.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ clocks:
+ minItems: 1
+
+required:
+ - compatible
+ - reg
+ - mediatek,gce-client-reg
+ - mediatek,gce-events
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt8183-clk.h>
+ #include <dt-bindings/gce/mt8183-gce.h>
+
+ mdp3_ccorr: mdp3-ccorr@1401c000 {
+ compatible = "mediatek,mt8183-mdp3-ccorr";
+ reg = <0x1401c000 0x1000>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
+ mediatek,gce-events = <CMDQ_EVENT_MDP_CCORR_SOF>,
+ <CMDQ_EVENT_MDP_CCORR_EOF>;
+ clocks = <&mmsys CLK_MM_MDP_CCORR>;
+ };
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..69afb329e5f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek Write Direct Memory Access
+
+maintainers:
+ - Matthias Brugger <matthias.bgg@gmail.com>
+ - Moudy Ho <moudy.ho@mediatek.com>
+
+description: |
+ MediaTek Write Direct Memory Access(WDMA) component used to write
+ the data into DMA.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - mediatek,mt8183-mdp3-wdma
+
+ reg:
+ maxItems: 1
+
+ mediatek,gce-client-reg:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ items:
+ - description: phandle of GCE
+ - description: GCE subsys id
+ - description: register offset
+ - description: register size
+ description: The register of client driver can be configured by gce with
+ 4 arguments defined in this property. Each GCE subsys id is mapping to
+ a client defined in the header include/dt-bindings/gce/<chip>-gce.h.
+
+ mediatek,gce-events:
+ description:
+ The event id which is mapping to the specific hardware event signal
+ to gce. The event id is defined in the gce header
+ include/dt-bindings/gce/<chip>-gce.h of each chips.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+
+ iommus:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - mediatek,gce-client-reg
+ - mediatek,gce-events
+ - power-domains
+ - clocks
+ - iommus
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/mt8183-clk.h>
+ #include <dt-bindings/gce/mt8183-gce.h>
+ #include <dt-bindings/power/mt8183-power.h>
+ #include <dt-bindings/memory/mt8183-larb-port.h>
+
+ mdp3_wdma: mdp3-wdma@14006000 {
+ compatible = "mediatek,mt8183-mdp3-wdma";
+ reg = <0x14006000 0x1000>;
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
+ mediatek,gce-events = <CMDQ_EVENT_MDP_WDMA0_SOF>,
+ <CMDQ_EVENT_MDP_WDMA0_EOF>;
+ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_MDP_WDMA0>;
+ iommus = <&iommu>;
+ };
diff --git a/Documentation/driver-api/media/drivers/pxa_camera.rst b/Documentation/driver-api/media/drivers/pxa_camera.rst
index ee1bd96b66dd..46919919baac 100644
--- a/Documentation/driver-api/media/drivers/pxa_camera.rst
+++ b/Documentation/driver-api/media/drivers/pxa_camera.rst
@@ -19,7 +19,7 @@ Global video workflow
a) QCI stopped
Initially, the QCI interface is stopped.
- When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
+ When a buffer is queued, start_streaming is called and the QCI starts.
b) QCI started
More buffers can be queued while the QCI is started without halting the
diff --git a/Documentation/userspace-api/media/drivers/dw100.rst b/Documentation/userspace-api/media/drivers/dw100.rst
new file mode 100644
index 000000000000..fceea6ece622
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/dw100.rst
@@ -0,0 +1,84 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+DW100 dewarp driver
+===================
+
+The Vivante DW100 Dewarp Processor IP core found on i.MX8MP SoC applies a
+programmable geometrical transformation on the input image to correct distortion
+introduced by lenses.
+
+The transformation function is exposed by the hardware as a grid map with 16x16
+pixel macroblocks indexed using X, Y vertex coordinates.
+::
+
+ Image width
+ <--------------------------------------->
+
+ ^ .-------.-------.-------.-------.-------.
+ | | 16x16 | | | | |
+ I | | pixel | | | | |
+ m | | block | | | | |
+ a | .-------.-------.-------.-------.-------.
+ g | | | | | | |
+ e | | | | | | |
+ | | | | | | |
+ h | .-------.-------.-------.-------.-------.
+ e | | | | | | |
+ i | | | | | | |
+ g | | | | | | |
+ h | .-------.-------.-------.-------.-------.
+ t | | | | | | |
+ | | | | | | |
+ | | | | | | |
+ v '-------'-------'-------'-------'-------'
+
+ Grid of Image Blocks for Dewarping Map
+
+
+Each x, y coordinate register uses 16 bits to record the coordinate address in
+an unsigned 12.4 fixed point format (UQ12.4).
+::
+
+ .----------------------.--------..----------------------.--------.
+ | 31~20 | 19~16 || 15~4 | 3~0 |
+ | (integer) | (frac) || (integer) | (frac) |
+ '----------------------'--------''----------------------'--------'
+ <-------------------------------><------------------------------->
+ Y coordinate X coordinate
+
+ Remap Register Layout
+
+The dewarping map is set from applications using the
+V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP control. The control contains
+an array of u32 values storing (x, y) destination coordinates for each
+vertex of the grid. The x coordinate is stored in the 16 LSBs and the y
+coordinate in the 16 MSBs.
+
+The number of elements in the array must match the image size:
+
+.. code-block:: C
+
+ elems = (DIV_ROUND_UP(width, 16) + 1) * (DIV_ROUND_UP(height, 16) + 1);
+
+If the control has not been set by the application, the driver uses an identity
+map.
+
+More details on the DW100 hardware operations can be found in
+*chapter 13.15 DeWarp* of IMX8MP_ reference manual.
+
+The Vivante DW100 m2m driver implements the following driver-specific control:
+
+``V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP (__u32 array)``
+ Specifies to DW100 driver its dewarping map (aka LUT) blob as described in
+ *chapter 13.15.2.3 Dewarping Remap* of IMX8MP_ reference manual as an U32
+ dynamic array. The image is divided into many small 16x16 blocks. If the
+ width/height of the image is not divisible by 16, the size of the
+ rightmost/bottommost block is the remainder. The dewarping map only saves
+ the vertex coordinates of the block. The dewarping grid map is comprised of
+ vertex coordinates for x and y. Each x, y coordinate register uses 16 bits
+ (UQ12.4) to record the coordinate address, with the Y coordinate in the
+ upper bits and X in the lower bits. The driver modifies the dimensions of
+ this control when the sink format is changed, to reflect the new input
+ resolution.
+
+.. _IMX8MP: https://www.nxp.com/webapp/Download?colCode=IMX8MPRM
diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst
index 1a9038f5f9fa..32f82aed47d9 100644
--- a/Documentation/userspace-api/media/drivers/index.rst
+++ b/Documentation/userspace-api/media/drivers/index.rst
@@ -33,6 +33,7 @@ For more details see the file COPYING in the source distribution of Linux.
ccs
cx2341x-uapi
+ dw100
imx-uapi
max2175
meye-uapi
diff --git a/Documentation/userspace-api/media/v4l/async.rst b/Documentation/userspace-api/media/v4l/async.rst
deleted file mode 100644
index d6960ff5c382..000000000000
--- a/Documentation/userspace-api/media/v4l/async.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-
-.. _async:
-
-****************
-Asynchronous I/O
-****************
-
-This method is not defined yet.
diff --git a/Documentation/userspace-api/media/v4l/dev-raw-vbi.rst b/Documentation/userspace-api/media/v4l/dev-raw-vbi.rst
index 58f97c3a7792..2bec20d87928 100644
--- a/Documentation/userspace-api/media/v4l/dev-raw-vbi.rst
+++ b/Documentation/userspace-api/media/v4l/dev-raw-vbi.rst
@@ -41,7 +41,7 @@ Devices supporting the raw VBI capturing or output API set the
in the ``capabilities`` field of struct
:c:type:`v4l2_capability` returned by the
:ref:`VIDIOC_QUERYCAP` ioctl. At least one of the
-read/write, streaming or asynchronous I/O methods must be supported. VBI
+read/write or streaming I/O methods must be supported. VBI
devices may or may not have a tuner or modulator.
Supplemental Functions
diff --git a/Documentation/userspace-api/media/v4l/dev-sdr.rst b/Documentation/userspace-api/media/v4l/dev-sdr.rst
index 928884dfe09d..dfdeddbca41f 100644
--- a/Documentation/userspace-api/media/v4l/dev-sdr.rst
+++ b/Documentation/userspace-api/media/v4l/dev-sdr.rst
@@ -34,7 +34,7 @@ Devices supporting the SDR transmitter interface set the
device has an Digital to Analog Converter (DAC), which is a mandatory
element for the SDR transmitter.
-At least one of the read/write, streaming or asynchronous I/O methods
+At least one of the read/write or streaming I/O methods
must be supported.
diff --git a/Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst b/Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst
index 97ec2b115c71..44415822c7c5 100644
--- a/Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst
+++ b/Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst
@@ -36,7 +36,7 @@ Devices supporting the sliced VBI capturing or output API set the
respectively, in the ``capabilities`` field of struct
:c:type:`v4l2_capability` returned by the
:ref:`VIDIOC_QUERYCAP` ioctl. At least one of the
-read/write, streaming or asynchronous :ref:`I/O methods <io>` must be
+read/write or streaming :ref:`I/O methods <io>` must be
supported. Sliced VBI devices may have a tuner or modulator.
Supplemental Functions
diff --git a/Documentation/userspace-api/media/v4l/hist-v4l2.rst b/Documentation/userspace-api/media/v4l/hist-v4l2.rst
index 28a2750d5c8c..dbc04374dc22 100644
--- a/Documentation/userspace-api/media/v4l/hist-v4l2.rst
+++ b/Documentation/userspace-api/media/v4l/hist-v4l2.rst
@@ -316,7 +316,7 @@ This unnamed version was finally merged into Linux 2.5.46.
There are new fields to identify the driver, a new RDS device
function ``V4L2_CAP_RDS_CAPTURE``, the ``V4L2_CAP_AUDIO`` flag
indicates if the device has any audio connectors, another I/O
- capability ``V4L2_CAP_ASYNCIO`` can be flagged. In response to these
+ capability V4L2_CAP_ASYNCIO can be flagged. In response to these
changes the ``type`` field became a bit set and was merged into the
``flags`` field. ``V4L2_FLAG_TUNER`` was renamed to
``V4L2_CAP_TUNER``, ``V4L2_CAP_VIDEO_OVERLAY`` replaced
diff --git a/Documentation/userspace-api/media/v4l/io.rst b/Documentation/userspace-api/media/v4l/io.rst
index ce0cece6f35f..4b1964df9d73 100644
--- a/Documentation/userspace-api/media/v4l/io.rst
+++ b/Documentation/userspace-api/media/v4l/io.rst
@@ -17,8 +17,7 @@ read or write will fail at any time.
Other methods must be negotiated. To select the streaming I/O method
with memory mapped or user buffers applications call the
-:ref:`VIDIOC_REQBUFS` ioctl. The asynchronous I/O
-method is not defined yet.
+:ref:`VIDIOC_REQBUFS` ioctl.
Video overlay can be considered another I/O method, although the
application does not directly receive the image data. It is selected by
@@ -46,6 +45,5 @@ The following sections describe the various I/O methods in more detail.
mmap
userp
dmabuf
- async
buffer
field-order
diff --git a/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
index 6eb40073c906..8db103760930 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
@@ -332,6 +332,11 @@ call.
- 0x0004
- This control event was triggered because the minimum, maximum,
step or the default value of the control changed.
+ * - ``V4L2_EVENT_CTRL_CH_DIMENSIONS``
+ - 0x0008
+ - This control event was triggered because the dimensions of the
+ control changed. Note that the number of dimensions remains the
+ same.
.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.5cm}|
diff --git a/Documentation/userspace-api/media/v4l/vidioc-querycap.rst b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
index 63e23f6f95ee..6c57b8428356 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
@@ -244,9 +244,6 @@ specification the ioctl returns an ``EINVAL`` error code.
- 0x01000000
- The device supports the :c:func:`read()` and/or
:c:func:`write()` I/O methods.
- * - ``V4L2_CAP_ASYNCIO``
- - 0x02000000
- - The device supports the :ref:`asynchronous <async>` I/O methods.
* - ``V4L2_CAP_STREAMING``
- 0x04000000
- The device supports the :ref:`streaming <mmap>` I/O method.
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index 64b2c0b1f666..2a589d34b80e 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -514,6 +514,7 @@ replace define V4L2_EVENT_PRIVATE_START event-type
replace define V4L2_EVENT_CTRL_CH_VALUE ctrl-changes-flags
replace define V4L2_EVENT_CTRL_CH_FLAGS ctrl-changes-flags
replace define V4L2_EVENT_CTRL_CH_RANGE ctrl-changes-flags
+replace define V4L2_EVENT_CTRL_CH_DIMENSIONS ctrl-changes-flags
replace define V4L2_EVENT_SRC_CH_RESOLUTION src-changes-flags
diff --git a/MAINTAINERS b/MAINTAINERS
index f610d8bb82d0..1bf9e71bc8bb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8936,7 +8936,7 @@ S: Maintained
F: Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
F: Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
F: Documentation/devicetree/bindings/media/rockchip-vpu.yaml
-F: drivers/staging/media/hantro/
+F: drivers/media/platform/verisilicon/
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
M: Frank Seidel <frank@f-seidel.de>
@@ -13823,7 +13823,7 @@ MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
S: Orphan
W: http://popies.net/meye/
F: Documentation/userspace-api/media/drivers/meye*
-F: drivers/media/pci/meye/
+F: drivers/staging/media/deprecated/meye/
F: include/uapi/linux/meye.h
MOTORCOMM PHY DRIVER
@@ -14749,6 +14749,15 @@ S: Orphan
F: Documentation/devicetree/bindings/net/nfc/nxp,nci.yaml
F: drivers/nfc/nxp-nci
+NXP i.MX 8MP DW100 V4L2 DRIVER
+M: Xavier Roumegue <xavier.roumegue@oss.nxp.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/nxp,dw100.yaml
+F: Documentation/userspace-api/media/drivers/dw100.rst
+F: drivers/media/platform/nxp/dw100/
+F: include/uapi/linux/dw100.h
+
NXP i.MX 8QXP/8QM JPEG V4L2 DRIVER
M: Mirela Rabulea <mirela.rabulea@nxp.com>
R: NXP Linux Team <linux-imx@nxp.com>
@@ -18004,8 +18013,7 @@ M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
-F: drivers/media/common/saa7146/
-F: drivers/media/pci/saa7146/
+F: drivers/staging/media/deprecated/saa7146/
F: include/media/drv-intf/saa7146*
SAFESETID SECURITY MODULE
@@ -20428,6 +20436,7 @@ W: https://linuxtv.org
Q: http://patchwork.linuxtv.org/project/linux-media/list/
T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
F: drivers/media/platform/ti/davinci/
+F: drivers/staging/media/deprecated/vpfe_capture/
F: include/media/davinci/
TI ENHANCED QUADRATURE ENCODER PULSE (eQEP) DRIVER
@@ -20568,7 +20577,7 @@ S: Odd fixes
W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
F: Documentation/admin-guide/media/tm6000*
-F: drivers/media/usb/tm6000/
+F: drivers/staging/media/deprecated/tm6000/
TMIO/SDHI MMC DRIVER
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
@@ -20668,9 +20677,10 @@ F: include/linux/toshiba.h
F: include/uapi/linux/toshiba.h
TOSHIBA TC358743 DRIVER
-M: Mats Randgaard <matrandg@cisco.com>
+M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
L: linux-media@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/tc358743.txt
F: drivers/media/i2c/tc358743*
F: include/media/i2c/tc358743.h
@@ -21326,7 +21336,7 @@ S: Maintained
W: http://royale.zerezo.com/zr364xx/
T: git git://linuxtv.org/media_tree.git
F: Documentation/admin-guide/media/zr364xx*
-F: drivers/media/usb/zr364xx/
+F: drivers/staging/media/deprecated/zr364xx/
USER-MODE LINUX (UML)
M: Richard Weinberger <richard@nod.at>
diff --git a/drivers/media/cec/platform/sti/stih-cec.c b/drivers/media/cec/platform/sti/stih-cec.c
index abf8e8bcbb34..4edbdd09535d 100644
--- a/drivers/media/cec/platform/sti/stih-cec.c
+++ b/drivers/media/cec/platform/sti/stih-cec.c
@@ -256,8 +256,8 @@ static void stih_rx_done(struct stih_cec *cec, u32 status)
if (!msg.len)
return;
- if (msg.len > 16)
- msg.len = 16;
+ if (msg.len > CEC_MAX_MSG_SIZE)
+ msg.len = CEC_MAX_MSG_SIZE;
for (i = 0; i < msg.len; i++)
msg.msg[i] = readl(cec->regs + CEC_RX_DATA_BASE + i);
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index a2ae71270054..852b7d92fbdd 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -22,7 +22,6 @@ config VIDEO_TVEEPROM
depends on I2C
source "drivers/media/common/b2c2/Kconfig"
-source "drivers/media/common/saa7146/Kconfig"
source "drivers/media/common/siano/Kconfig"
source "drivers/media/common/v4l2-tpg/Kconfig"
source "drivers/media/common/videobuf2/Kconfig"
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index ad0b1e95fb12..d78a0df15478 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-y += b2c2/ saa7146/ siano/ v4l2-tpg/ videobuf2/
+obj-y += b2c2/ siano/ v4l2-tpg/ videobuf2/
# Please keep it alphabetically sorted by Kconfig name
# (e. g. LC_ALL=C sort Makefile)
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
index b203c1e26353..ab9697f3b5f1 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -398,7 +398,7 @@ static void init_buffer_cache_hints(struct vb2_queue *q, struct vb2_buffer *vb)
}
/*
- * __vb2_queue_alloc() - allocate videobuf buffer structures and (for MMAP type)
+ * __vb2_queue_alloc() - allocate vb2 buffer structures and (for MMAP type)
* video buffer memory for all buffers/planes on the queue and initializes the
* queue
*
@@ -417,7 +417,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
VB2_MAX_FRAME - q->num_buffers);
for (buffer = 0; buffer < num_buffers; ++buffer) {
- /* Allocate videobuf buffer structures */
+ /* Allocate vb2 buffer structures */
vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
if (!vb) {
dprintk(q, 1, "memory alloc for buffer struct failed\n");
@@ -599,7 +599,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
}
#endif
- /* Free videobuf buffers */
+ /* Free vb2 buffers */
for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
++buffer) {
kfree(q->bufs[buffer]);
@@ -1949,7 +1949,7 @@ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
if (pb)
call_void_bufop(q, fill_user_buffer, vb, pb);
- /* Remove from videobuf queue */
+ /* Remove from vb2 queue */
list_del(&vb->queued_entry);
q->queued_count--;
@@ -1978,7 +1978,7 @@ EXPORT_SYMBOL_GPL(vb2_core_dqbuf);
* __vb2_queue_cancel() - cancel and stop (pause) streaming
*
* Removes all queued buffers from driver's queue and all buffers queued by
- * userspace from videobuf's queue. Returns to state after reqbufs.
+ * userspace from vb2's queue. Returns to state after reqbufs.
*/
static void __vb2_queue_cancel(struct vb2_queue *q)
{
@@ -2016,7 +2016,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
q->uses_qbuf = 0;
/*
- * Remove all buffers from videobuf's list...
+ * Remove all buffers from vb2's list...
*/
INIT_LIST_HEAD(&q->queued_list);
/*
@@ -2139,7 +2139,7 @@ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type)
/*
* Cancel will pause streaming and remove all buffers from the driver
- * and videobuf, effectively returning control over them to userspace.
+ * and vb2, effectively returning control over them to userspace.
*
* Note that we do this even if q->streaming == 0: if you prepare or
* queue buffers, and then call streamoff without ever having called
diff --git a/drivers/media/common/videobuf2/videobuf2-dvb.c b/drivers/media/common/videobuf2/videobuf2-dvb.c
index 9d571c9d31e9..8c15bcd07eef 100644
--- a/drivers/media/common/videobuf2/videobuf2-dvb.c
+++ b/drivers/media/common/videobuf2/videobuf2-dvb.c
@@ -3,8 +3,8 @@
*
* some helper function for simple DVB cards which simply DMA the
* complete transport stream and let the computer sort everything else
- * (i.e. we are using the software demux, ...). Also uses the
- * video-buf to manage DMA buffers.
+ * (i.e. we are using the software demux, ...). Also uses vb2
+ * to manage DMA buffers.
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
*/
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index f26cb8586bd4..1f5d235a8441 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -268,7 +268,7 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b
/*
* Single-planar buffers do not use planes array,
* so fill in relevant v4l2_buffer struct fields instead.
- * In videobuf we use our internal V4l2_planes struct for
+ * In vb2 we use our internal V4l2_planes struct for
* single-planar buffers as well, for simplicity.
*
* If bytesused == 0 for the output buffer, then fall back
@@ -625,19 +625,6 @@ static const struct vb2_buf_ops v4l2_buf_ops = {
.copy_timestamp = __copy_timestamp,
};
-int vb2_find_timestamp(const struct vb2_queue *q, u64 timestamp,
- unsigned int start_idx)
-{
- unsigned int i;
-
- for (i = start_idx; i < q->num_buffers; i++)
- if (q->bufs[i]->copied_timestamp &&
- q->bufs[i]->timestamp == timestamp)
- return i;
- return -1;
-}
-EXPORT_SYMBOL_GPL(vb2_find_timestamp);
-
struct vb2_buffer *vb2_find_buffer(struct vb2_queue *q, u64 timestamp)
{
unsigned int i;
@@ -652,7 +639,7 @@ EXPORT_SYMBOL_GPL(vb2_find_buffer);
/*
* vb2_querybuf() - query video buffer information
- * @q: videobuf queue
+ * @q: vb2 queue
* @b: buffer struct passed from userspace to vidioc_querybuf handler
* in driver
*
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index d67f2dd997d0..fe19d127abb3 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -3212,7 +3212,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
case CT_DEMOD_STEP_6: /* (36) if there is an input (diversity) */
if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
- /* if there is a diversity fe in input and this fe is has not already failed : wait here until this this fe has succedeed or failed */
+ /* if there is a diversity fe in input and this fe is has not already failed : wait here until this fe has succeeded or failed */
if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
*tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failed also, break the current one */
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index 9430295a8175..47d83e0a470c 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -3516,7 +3516,7 @@ static int set_dvbt_standard(struct drxk_state *state,
status = write16(state, IQM_AF_CLP_LEN__A, 0);
if (status < 0)
goto error;
- /* window size for for sense pre-SAW detection */
+ /* window size for sense pre-SAW detection */
status = write16(state, IQM_AF_SNS_LEN__A, 0);
if (status < 0)
goto error;
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c
index 6a4f2997d6f5..05f71d169726 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -245,7 +245,7 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
if (unlikely(fbuf == NULL)) {
dev->vb_full++;
dev_notice_ratelimited(&pdev->dev,
- "videobuf is full, %d packets dropped\n",
+ "video buffer is full, %d packets dropped\n",
dev->vb_full);
goto skip;
}
diff --git a/drivers/media/dvb-frontends/tda1002x.h b/drivers/media/dvb-frontends/tda1002x.h
index 60a0952c1bca..00491bea9975 100644
--- a/drivers/media/dvb-frontends/tda1002x.h
+++ b/drivers/media/dvb-frontends/tda1002x.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module
- used on the the Siemens DVB-C cards
+ used on the Siemens DVB-C cards
Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c
index d1d206ebdedd..0b3f6999515e 100644
--- a/drivers/media/dvb-frontends/tda10048.c
+++ b/drivers/media/dvb-frontends/tda10048.c
@@ -1118,7 +1118,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
state->pll_pfactor = 0;
}
- /* Establish any defaults the the user didn't pass */
+ /* Establish any defaults the user didn't pass */
tda10048_establish_defaults(&state->frontend);
/* Set the xtal and freq defaults */
diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
index 49aca579576a..0d5ce69f12e7 100644
--- a/drivers/media/i2c/adv7511-v4l2.c
+++ b/drivers/media/i2c/adv7511-v4l2.c
@@ -943,8 +943,8 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
v4l2_dbg(1, debug, sd, "%s: cec msg len %d\n", __func__,
msg.len);
- if (msg.len > 16)
- msg.len = 16;
+ if (msg.len > CEC_MAX_MSG_SIZE)
+ msg.len = CEC_MAX_MSG_SIZE;
if (msg.len) {
u8 i;
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 5988a4fa0c46..bda0c547ce44 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -2047,8 +2047,8 @@ static void adv76xx_cec_isr(struct v4l2_subdev *sd, bool *handled)
struct cec_msg msg;
msg.len = cec_read(sd, 0x25) & 0x1f;
- if (msg.len > 16)
- msg.len = 16;
+ if (msg.len > CEC_MAX_MSG_SIZE)
+ msg.len = CEC_MAX_MSG_SIZE;
if (msg.len) {
u8 i;
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index a8dd92948df0..7731cc1887e6 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -2215,8 +2215,8 @@ static void adv7842_cec_isr(struct v4l2_subdev *sd, bool *handled)
struct cec_msg msg;
msg.len = cec_read(sd, 0x25) & 0x1f;
- if (msg.len > 16)
- msg.len = 16;
+ if (msg.len > CEC_MAX_MSG_SIZE)
+ msg.len = CEC_MAX_MSG_SIZE;
if (msg.len) {
u8 i;
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index 9d7d1d149f1a..8cef9656c612 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -196,7 +196,7 @@ static u32 clock_divider_to_resolution(u16 divider)
{
/*
* Resolution is the duration of 1 tick of the readable portion of
- * of the pulse width counter as read from the FIFO. The two lsb's are
+ * the pulse width counter as read from the FIFO. The two lsb's are
* not readable, hence the << 2. This function returns ns.
*/
return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000,
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index d99eedbdf011..200841c1f5cf 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -964,6 +964,8 @@ static void tc358743_cec_handler(struct v4l2_subdev *sd, u16 intstatus,
v = i2c_rd32(sd, CECRCTR);
msg.len = v & 0x1f;
+ if (msg.len > CEC_MAX_MSG_SIZE)
+ msg.len = CEC_MAX_MSG_SIZE;
for (i = 0; i < msg.len; i++) {
v = i2c_rd32(sd, CECRBUF1 + i * 4);
msg.msg[i] = v & 0xff;
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index 1224d908713a..dff0b450f387 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -13,12 +13,12 @@ if MEDIA_PCI_SUPPORT
if MEDIA_CAMERA_SUPPORT
comment "Media capture support"
-source "drivers/media/pci/meye/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/sta2x11/Kconfig"
source "drivers/media/pci/tw5864/Kconfig"
source "drivers/media/pci/tw68/Kconfig"
source "drivers/media/pci/tw686x/Kconfig"
+source "drivers/media/pci/zoran/Kconfig"
endif
@@ -27,7 +27,6 @@ if MEDIA_ANALOG_TV_SUPPORT
source "drivers/media/pci/dt3155/Kconfig"
source "drivers/media/pci/ivtv/Kconfig"
-source "drivers/media/pci/saa7146/Kconfig"
endif
@@ -58,7 +57,6 @@ source "drivers/media/pci/pluto2/Kconfig"
source "drivers/media/pci/pt1/Kconfig"
source "drivers/media/pci/pt3/Kconfig"
source "drivers/media/pci/smipcie/Kconfig"
-source "drivers/media/pci/ttpci/Kconfig"
endif
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 551169a3e434..8f887a8a7f17 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -5,8 +5,7 @@
# Please keep it alphabetically sorted by directory
# (e. g. LC_ALL=C sort Makefile)
-obj-y += ttpci/ \
- b2c2/ \
+obj-y += b2c2/ \
pluto2/ \
dm1105/ \
pt1/ \
@@ -14,7 +13,6 @@ obj-y += ttpci/ \
mantis/ \
ngene/ \
ddbridge/ \
- saa7146/ \
smipcie/ \
netup_unidvb/ \
intel/
@@ -32,10 +30,10 @@ obj-$(CONFIG_VIDEO_CX25821) += cx25821/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_DT3155) += dt3155/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
-obj-$(CONFIG_VIDEO_MEYE) += meye/
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
obj-$(CONFIG_VIDEO_TW5864) += tw5864/
obj-$(CONFIG_VIDEO_TW686X) += tw686x/
obj-$(CONFIG_VIDEO_TW68) += tw68/
+obj-$(CONFIG_VIDEO_ZORAN) += zoran/
diff --git a/drivers/media/pci/cx18/cx18-av-audio.c b/drivers/media/pci/cx18/cx18-av-audio.c
index 833baa934448..78e05df9a7ba 100644
--- a/drivers/media/pci/cx18/cx18-av-audio.c
+++ b/drivers/media/pci/cx18/cx18-av-audio.c
@@ -50,7 +50,7 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
*
* Many thanks to Jeff Campbell and Mike Bradley for their extensive
* investigation, experimentation, testing, and suggested solutions of
- * of audio/video sync problems with SVideo and CVBS captures.
+ * audio/video sync problems with SVideo and CVBS captures.
*/
if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
diff --git a/drivers/media/pci/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c
index fdac310d7477..1b038b2802bf 100644
--- a/drivers/media/pci/cx18/cx18-firmware.c
+++ b/drivers/media/pci/cx18/cx18-firmware.c
@@ -248,7 +248,7 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
*
* Many thanks to Jeff Campbell and Mike Bradley for their extensive
* investigation, experimentation, testing, and suggested solutions of
- * of audio/video sync problems with SVideo and CVBS captures.
+ * audio/video sync problems with SVideo and CVBS captures.
*/
/* the fast clock is at 200/245 MHz */
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index a07b18f2034e..9232a966bcab 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -2086,6 +2086,9 @@ static struct {
/* 0x1419 is the PCI ID for the IOMMU found on 15h (Models 10h-1fh) family
*/
{ PCI_VENDOR_ID_AMD, 0x1419 },
+ /* 0x1631 is the PCI ID for the IOMMU found on Renoir/Cezanne
+ */
+ { PCI_VENDOR_ID_AMD, 0x1631 },
/* 0x5a23 is the PCI ID for the IOMMU found on RD890S/RD990
*/
{ PCI_VENDOR_ID_ATI, 0x5a23 },
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index ddfd2eb37484..222d04421468 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -235,7 +235,7 @@ static u32 clock_divider_to_resolution(u16 divider)
{
/*
* Resolution is the duration of 1 tick of the readable portion of
- * of the pulse width counter as read from the FIFO. The two lsb's are
+ * the pulse width counter as read from the FIFO. The two lsb's are
* not readable, hence the << 2. This function returns ns.
*/
return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000,
diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c
index f1e1fc1cb4bd..e378f3b215c7 100644
--- a/drivers/media/pci/cx88/cx88-dsp.c
+++ b/drivers/media/pci/cx88/cx88-dsp.c
@@ -24,7 +24,7 @@
/*
* We calculate the baseband frequencies of the carrier and the pilot tones
- * based on the the sampling rate of the audio rds fifo.
+ * based on the sampling rate of the audio rds fifo.
*/
#define FREQ_A2_CARRIER baseband_freq(54687.5, 2689.36, 0.0)
diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c
index a075788c64d4..469aeaa725ad 100644
--- a/drivers/media/pci/cx88/cx88-vbi.c
+++ b/drivers/media/pci/cx88/cx88-vbi.c
@@ -144,11 +144,10 @@ static int buffer_prepare(struct vb2_buffer *vb)
return -EINVAL;
vb2_set_plane_payload(vb, 0, size);
- cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
- 0, VBI_LINE_LENGTH * lines,
- VBI_LINE_LENGTH, 0,
- lines);
- return 0;
+ return cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
+ 0, VBI_LINE_LENGTH * lines,
+ VBI_LINE_LENGTH, 0,
+ lines);
}
static void buffer_finish(struct vb2_buffer *vb)
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index d3729be89252..b509c2a03852 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -431,6 +431,7 @@ static int queue_setup(struct vb2_queue *q,
static int buffer_prepare(struct vb2_buffer *vb)
{
+ int ret;
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
struct cx88_core *core = dev->core;
@@ -445,35 +446,35 @@ static int buffer_prepare(struct vb2_buffer *vb)
switch (core->field) {
case V4L2_FIELD_TOP:
- cx88_risc_buffer(dev->pci, &buf->risc,
- sgt->sgl, 0, UNSET,
- buf->bpl, 0, core->height);
+ ret = cx88_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, 0, UNSET,
+ buf->bpl, 0, core->height);
break;
case V4L2_FIELD_BOTTOM:
- cx88_risc_buffer(dev->pci, &buf->risc,
- sgt->sgl, UNSET, 0,
- buf->bpl, 0, core->height);
+ ret = cx88_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, UNSET, 0,
+ buf->bpl, 0, core->height);
break;
case V4L2_FIELD_SEQ_TB:
- cx88_risc_buffer(dev->pci, &buf->risc,
- sgt->sgl,
- 0, buf->bpl * (core->height >> 1),
- buf->bpl, 0,
- core->height >> 1);
+ ret = cx88_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ 0, buf->bpl * (core->height >> 1),
+ buf->bpl, 0,
+ core->height >> 1);
break;
case V4L2_FIELD_SEQ_BT:
- cx88_risc_buffer(dev->pci, &buf->risc,
- sgt->sgl,
- buf->bpl * (core->height >> 1), 0,
- buf->bpl, 0,
- core->height >> 1);
+ ret = cx88_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl,
+ buf->bpl * (core->height >> 1), 0,
+ buf->bpl, 0,
+ core->height >> 1);
break;
case V4L2_FIELD_INTERLACED:
default:
- cx88_risc_buffer(dev->pci, &buf->risc,
- sgt->sgl, 0, buf->bpl,
- buf->bpl, buf->bpl,
- core->height >> 1);
+ ret = cx88_risc_buffer(dev->pci, &buf->risc,
+ sgt->sgl, 0, buf->bpl,
+ buf->bpl, buf->bpl,
+ core->height >> 1);
break;
}
dprintk(2,
@@ -481,7 +482,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
buf, buf->vb.vb2_buf.index, __func__,
core->width, core->height, dev->fmt->depth, dev->fmt->fourcc,
(unsigned long)buf->risc.dma);
- return 0;
+ return ret;
}
static void buffer_finish(struct vb2_buffer *vb)
diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
index e79e8a5a744a..4ba10c34a16a 100644
--- a/drivers/media/pci/ivtv/ivtv-yuv.c
+++ b/drivers/media/pci/ivtv/ivtv-yuv.c
@@ -538,7 +538,7 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *f)
reg_2964 = (reg_2964 << 16) + reg_2964 + (reg_2964 * 46 / 94);
/* Okay, we've wasted time working out the correct value,
- but if we use it, it fouls the the window alignment.
+ but if we use it, it fouls the window alignment.
Fudge it to what we want... */
reg_2964 = 0x00010001 + ((reg_2964 & 0x0000FFFF) - (reg_2964 >> 16));
reg_2968 = 0x00010001 + ((reg_2968 & 0x0000FFFF) - (reg_2968 >> 16));
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
index 3d296f1998a1..d1d7da84cd9d 100644
--- a/drivers/media/pci/ngene/ngene.h
+++ b/drivers/media/pci/ngene/ngene.h
@@ -596,43 +596,6 @@ struct mychip {
int capture_source[MIXER_ADDR_LAST + 1][2];
};
-#ifdef NGENE_V4L
-struct ngene_overlay {
- int tvnorm;
- struct v4l2_rect w;
- enum v4l2_field field;
- struct v4l2_clip *clips;
- int nclips;
- int setup_ok;
-};
-
-struct ngene_tvnorm {
- int v4l2_id;
- char *name;
- u16 swidth, sheight; /* scaled standard width, height */
- int tuner_norm;
- int soundstd;
-};
-
-struct ngene_vopen {
- struct ngene_channel *ch;
- enum v4l2_priority prio;
- int width;
- int height;
- int depth;
- struct videobuf_queue vbuf_q;
- struct videobuf_queue vbi;
- int fourcc;
- int picxcount;
- int resources;
- enum v4l2_buf_type type;
- const struct ngene_format *fmt;
-
- const struct ngene_format *ovfmt;
- struct ngene_overlay ov;
-};
-#endif
-
struct ngene_channel {
struct device device;
struct i2c_adapter i2c_adapter;
@@ -709,18 +672,6 @@ struct ngene_channel {
int tvnorm_num;
int tvnorm;
-#ifdef NGENE_V4L
- int videousers;
- struct v4l2_prio_state prio;
- struct ngene_vopen init;
- int resources;
- struct v4l2_framebuffer fbuf;
- struct ngene_buffer *screen; /* overlay */
- struct list_head capture; /* video capture queue */
- spinlock_t s_lock;
- struct semaphore reslock;
-#endif
-
int running;
int tsin_offset;
@@ -863,35 +814,6 @@ struct ngene_info {
int (*switch_ctrl)(struct ngene_channel *, int, int);
};
-#ifdef NGENE_V4L
-struct ngene_format {
- char *name;
- int fourcc; /* video4linux 2 */
- int btformat; /* BT848_COLOR_FMT_* */
- int format;
- int btswap; /* BT848_COLOR_CTL_* */
- int depth; /* bit/pixel */
- int flags;
- int hshift, vshift; /* for planar modes */
- int palette;
-};
-
-#define RESOURCE_OVERLAY 1
-#define RESOURCE_VIDEO 2
-#define RESOURCE_VBI 4
-
-struct ngene_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
-
- /* ngene specific */
- const struct ngene_format *fmt;
- int tvnorm;
- int btformat;
- int btswap;
-};
-#endif
-
/* Provided by ngene-core.c */
int ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id);
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index 7973ae42873a..d5f32e3ff544 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -626,7 +626,7 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id)
portf = &dev->ports[SAA7164_PORT_VBI2];
/* Check that the hardware is accessible. If the status bytes are
- * 0xFF then the device is not accessible, the the IRQ belongs
+ * 0xFF then the device is not accessible, the IRQ belongs
* to another driver.
* 4 x u32 interrupt registers.
*/
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index 80d20e2a2099..0adf3d80f248 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -1020,7 +1020,7 @@ static int solo_g_parm(struct file *file, void *priv,
cp->timeperframe.numerator = solo_enc->interval;
cp->timeperframe.denominator = solo_enc->solo_dev->fps;
cp->capturemode = 0;
- /* XXX: Shouldn't we be able to get/set this from videobuf? */
+ /* XXX: Shouldn't we be able to get/set this from vb2? */
cp->readbuffers = 2;
return 0;
diff --git a/drivers/staging/media/zoran/Kconfig b/drivers/media/pci/zoran/Kconfig
index 3fb3e27e04a8..3fb3e27e04a8 100644
--- a/drivers/staging/media/zoran/Kconfig
+++ b/drivers/media/pci/zoran/Kconfig
diff --git a/drivers/staging/media/zoran/Makefile b/drivers/media/pci/zoran/Makefile
index 9603bac0195c..9603bac0195c 100644
--- a/drivers/staging/media/zoran/Makefile
+++ b/drivers/media/pci/zoran/Makefile
diff --git a/drivers/staging/media/zoran/videocodec.c b/drivers/media/pci/zoran/videocodec.c
index a0c8bde5ec11..8efc5e06b0f7 100644
--- a/drivers/staging/media/zoran/videocodec.c
+++ b/drivers/media/pci/zoran/videocodec.c
@@ -92,9 +92,8 @@ struct videocodec *videocodec_attach(struct videocodec_master *master)
h->attached += 1;
return codec;
- } else {
- kfree(codec);
}
+ kfree(codec);
}
h = h->next;
}
@@ -255,8 +254,8 @@ int videocodec_debugfs_show(struct seq_file *m)
struct codec_list *h = codeclist_top;
struct attached_list *a;
- seq_printf(m, "<S>lave or attached <M>aster name type flags magic ");
- seq_printf(m, "(connected as)\n");
+ seq_puts(m, "<S>lave or attached <M>aster name type flags magic ");
+ seq_puts(m, "(connected as)\n");
while (h) {
seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n",
diff --git a/drivers/staging/media/zoran/videocodec.h b/drivers/media/pci/zoran/videocodec.h
index 5e6057edd339..6b69f69667f9 100644
--- a/drivers/staging/media/zoran/videocodec.h
+++ b/drivers/media/pci/zoran/videocodec.h
@@ -12,109 +12,109 @@
/* general description */
/* =================== */
-/* Should ease the (re-)usage of drivers supporting cards with (different)
- video codecs. The codecs register to this module their functionality,
- and the processors (masters) can attach to them if they fit.
-
- The codecs are typically have a "strong" binding to their master - so I
- don't think it makes sense to have a full blown interfacing as with e.g.
- i2c. If you have an other opinion, let's discuss & implement it :-)))
-
- Usage:
-
- The slave has just to setup the videocodec structure and use two functions:
- videocodec_register(codecdata);
- videocodec_unregister(codecdata);
- The best is just calling them at module (de-)initialisation.
-
- The master sets up the structure videocodec_master and calls:
- codecdata=videocodec_attach(master_codecdata);
- videocodec_detach(codecdata);
-
- The slave is called during attach/detach via functions setup previously
- during register. At that time, the master_data pointer is set up
- and the slave can access any io registers of the master device (in the case
- the slave is bound to it). Otherwise it doesn't need this functions and
- therfor they may not be initialized.
-
- The other functions are just for convenience, as they are for sure used by
- most/all of the codecs. The last ones may be omitted, too.
-
- See the structure declaration below for more information and which data has
- to be set up for the master and the slave.
-
- ----------------------------------------------------------------------------
- The master should have "knowledge" of the slave and vice versa. So the data
- structures sent to/from slave via set_data/get_data set_image/get_image are
- device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
- ----------------------------------------------------------------------------
-*/
+/*
+ * Should ease the (re-)usage of drivers supporting cards with (different)
+ * video codecs. The codecs register to this module their functionality,
+ * and the processors (masters) can attach to them if they fit.
+ *
+ * The codecs are typically have a "strong" binding to their master - so I
+ * don't think it makes sense to have a full blown interfacing as with e.g.
+ * i2c. If you have an other opinion, let's discuss & implement it :-)))
+ *
+ * Usage:
+ *
+ * The slave has just to setup the videocodec structure and use two functions:
+ * videocodec_register(codecdata);
+ * videocodec_unregister(codecdata);
+ * The best is just calling them at module (de-)initialisation.
+ *
+ * The master sets up the structure videocodec_master and calls:
+ * codecdata=videocodec_attach(master_codecdata);
+ * videocodec_detach(codecdata);
+ *
+ * The slave is called during attach/detach via functions setup previously
+ * during register. At that time, the master_data pointer is set up
+ * and the slave can access any io registers of the master device (in the case
+ * the slave is bound to it). Otherwise it doesn't need this functions and
+ * therefor they may not be initialized.
+ *
+ * The other functions are just for convenience, as they are for sure used by
+ * most/all of the codecs. The last ones may be omitted, too.
+ *
+ * See the structure declaration below for more information and which data has
+ * to be set up for the master and the slave.
+ *
+ * ----------------------------------------------------------------------------
+ * The master should have "knowledge" of the slave and vice versa. So the data
+ * structures sent to/from slave via set_data/get_data set_image/get_image are
+ * device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
+ * ----------------------------------------------------------------------------
+ */
/* ========================================== */
/* description of the videocodec_io structure */
/* ========================================== */
/*
- ==== master setup ====
- name -> name of the device structure for reference and debugging
- master_data -> data ref. for the master (e.g. the zr36055,57,67)
- readreg -> ref. to read-fn from register (setup by master, used by slave)
- writereg -> ref. to write-fn to register (setup by master, used by slave)
- this two functions do the lowlevel I/O job
-
- ==== slave functionality setup ====
- slave_data -> data ref. for the slave (e.g. the zr36050,60)
- check -> fn-ref. checks availability of an device, returns -EIO on failure or
- the type on success
- this makes espcecially sense if a driver module supports more than
- one codec which may be quite similar to access, nevertheless it
- is good for a first functionality check
-
- -- main functions you always need for compression/decompression --
-
- set_mode -> this fn-ref. resets the entire codec, and sets up the mode
- with the last defined norm/size (or device default if not
- available) - it returns 0 if the mode is possible
- set_size -> this fn-ref. sets the norm and image size for
- compression/decompression (returns 0 on success)
- the norm param is defined in videodev2.h (V4L2_STD_*)
-
- additional setup may be available, too - but the codec should work with
- some default values even without this
-
- set_data -> sets device-specific data (tables, quality etc.)
- get_data -> query device-specific data (tables, quality etc.)
-
- if the device delivers interrupts, they may be setup/handled here
- setup_interrupt -> codec irq setup (not needed for 36050/60)
- handle_interrupt -> codec irq handling (not needed for 36050/60)
-
- if the device delivers pictures, they may be handled here
- put_image -> puts image data to the codec (not needed for 36050/60)
- get_image -> gets image data from the codec (not needed for 36050/60)
- the calls include frame numbers and flags (even/odd/...)
- if needed and a flag which allows blocking until its ready
-*/
+ * ==== master setup ====
+ * name -> name of the device structure for reference and debugging
+ * master_data -> data ref. for the master (e.g. the zr36055,57,67)
+ * readreg -> ref. to read-fn from register (setup by master, used by slave)
+ * writereg -> ref. to write-fn to register (setup by master, used by slave)
+ * this two functions do the lowlevel I/O job
+ *
+ * ==== slave functionality setup ====
+ * slave_data -> data ref. for the slave (e.g. the zr36050,60)
+ * check -> fn-ref. checks availability of an device, returns -EIO on failure or
+ * the type on success
+ * this makes espcecially sense if a driver module supports more than
+ * one codec which may be quite similar to access, nevertheless it
+ * is good for a first functionality check
+ *
+ * -- main functions you always need for compression/decompression --
+ *
+ * set_mode -> this fn-ref. resets the entire codec, and sets up the mode
+ * with the last defined norm/size (or device default if not
+ * available) - it returns 0 if the mode is possible
+ * set_size -> this fn-ref. sets the norm and image size for
+ * compression/decompression (returns 0 on success)
+ * the norm param is defined in videodev2.h (V4L2_STD_*)
+ *
+ * additional setup may be available, too - but the codec should work with
+ * some default values even without this
+ *
+ * set_data -> sets device-specific data (tables, quality etc.)
+ * get_data -> query device-specific data (tables, quality etc.)
+ *
+ * if the device delivers interrupts, they may be setup/handled here
+ * setup_interrupt -> codec irq setup (not needed for 36050/60)
+ * handle_interrupt -> codec irq handling (not needed for 36050/60)
+
+ * if the device delivers pictures, they may be handled here
+ * put_image -> puts image data to the codec (not needed for 36050/60)
+ * get_image -> gets image data from the codec (not needed for 36050/60)
+ * the calls include frame numbers and flags (even/odd/...)
+ * if needed and a flag which allows blocking until its ready
+ */
/* ============== */
/* user interface */
/* ============== */
/*
- Currently there is only a information display planned, as the layer
- is not visible for the user space at all.
-
- Information is available via procfs. The current entry is "/proc/videocodecs"
- but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
-
-A example for such an output is:
-
-<S>lave or attached <M>aster name type flags magic (connected as)
-S zr36050 0002 0000d001 00000000 (TEMPLATE)
-M zr36055[0] 0001 0000c001 00000000 (zr36050[0])
-M zr36055[1] 0001 0000c001 00000000 (zr36050[1])
-
-*/
+ * Currently there is only a information display planned, as the layer
+ * is not visible for the user space at all.
+ *
+ * Information is available via procfs. The current entry is "/proc/videocodecs"
+ * but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
+ *
+ * A example for such an output is:
+ *
+ * <S>lave or attached <M>aster name type flags magic (connected as)
+ * S zr36050 0002 0000d001 00000000 (TEMPLATE)
+ * M zr36055[0] 0001 0000c001 00000000 (zr36050[0])
+ * M zr36055[1] 0001 0000c001 00000000 (zr36050[1])
+ */
/* =============================================== */
/* special defines for the videocodec_io structure */
@@ -293,15 +293,15 @@ struct videocodec_master {
// * master structure needs to be kmalloc'ed before calling attach
// and free'd after calling detach
// * returns pointer on success, NULL on failure
-extern struct videocodec *videocodec_attach(struct videocodec_master *);
+struct videocodec *videocodec_attach(struct videocodec_master *master);
// * 0 on success, <0 (errno) on failure
-extern int videocodec_detach(struct videocodec *);
+int videocodec_detach(struct videocodec *codec);
/* register and unregister commands for the slaves */
// * 0 on success, <0 (errno) on failure
-extern int videocodec_register(const struct videocodec *);
+int videocodec_register(const struct videocodec *codec);
// * 0 on success, <0 (errno) on failure
-extern int videocodec_unregister(const struct videocodec *);
+int videocodec_unregister(const struct videocodec *codec);
/* the other calls are directly done via the videocodec structure! */
diff --git a/drivers/staging/media/zoran/zoran.h b/drivers/media/pci/zoran/zoran.h
index 05227e5298f6..56340553b282 100644
--- a/drivers/staging/media/zoran/zoran.h
+++ b/drivers/media/pci/zoran/zoran.h
@@ -140,11 +140,16 @@ struct zoran_v4l_settings {
/* jpg-capture/-playback settings */
struct zoran_jpg_settings {
- int decimation; /* this bit is used to set everything to default */
- int hor_dcm, ver_dcm, tmp_dcm; /* capture decimation settings (tmp_dcm=1 means both fields) */
- int field_per_buff, odd_even; /* field-settings (odd_even=1 (+tmp_dcm=1) means top-field-first) */
- int img_x, img_y, img_width, img_height; /* crop settings (subframe capture) */
- struct v4l2_jpegcompression jpg_comp; /* JPEG-specific capture settings */
+ /* this bit is used to set everything to default */
+ int decimation;
+ /* capture decimation settings (tmp_dcm=1 means both fields) */
+ int hor_dcm, ver_dcm, tmp_dcm;
+ /* field-settings (odd_even=1 (+tmp_dcm=1) means top-field-first) */
+ int field_per_buff, odd_even;
+ /* crop settings (subframe capture) */
+ int img_x, img_y, img_width, img_height;
+ /* JPEG-specific capture settings */
+ struct v4l2_jpegcompression jpg_comp;
};
struct zoran;
@@ -248,7 +253,8 @@ struct zoran {
unsigned long vbseq;
/* zr36057's code buffer table */
- __le32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
+ /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
+ __le32 *stat_com;
/* Additional stuff for testing */
unsigned int ghost_int;
@@ -292,14 +298,16 @@ static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
return container_of(v4l2_dev, struct zoran, v4l2_dev);
}
-/* There was something called _ALPHA_BUZ that used the PCI address instead of
- * the kernel iomapped address for btread/btwrite. */
+/*
+ * There was something called _ALPHA_BUZ that used the PCI address instead of
+ * the kernel iomapped address for btread/btwrite.
+ */
#define btwrite(dat, adr) writel((dat), zr->zr36057_mem + (adr))
#define btread(adr) readl(zr->zr36057_mem + (adr))
-#define btand(dat, adr) btwrite((dat) & btread(adr), adr)
-#define btor(dat, adr) btwrite((dat) | btread(adr), adr)
-#define btaor(dat, mask, adr) btwrite((dat) | ((mask) & btread(adr)), adr)
+#define btand(dat, adr) btwrite((dat) & btread(adr), (adr))
+#define btor(dat, adr) btwrite((dat) | btread(adr), (adr))
+#define btaor(dat, mask, adr) btwrite((dat) | ((mask) & btread(adr)), (adr))
#endif
diff --git a/drivers/staging/media/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index 26f978a1cc72..3975fc1b2ee3 100644
--- a/drivers/staging/media/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -172,8 +172,6 @@ void zr36016_write(struct videocodec *codec, u16 reg, u32 val)
static void dc10_init(struct zoran *zr)
{
- pci_dbg(zr->pci_dev, "%s\n", __func__);
-
/* Pixel clock selection */
GPIO(zr, 4, 0);
GPIO(zr, 5, 1);
@@ -183,13 +181,10 @@ static void dc10_init(struct zoran *zr)
static void dc10plus_init(struct zoran *zr)
{
- pci_dbg(zr->pci_dev, "%s\n", __func__);
}
static void buz_init(struct zoran *zr)
{
- pci_dbg(zr->pci_dev, "%s\n", __func__);
-
/* some stuff from Iomega */
pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
@@ -198,8 +193,6 @@ static void buz_init(struct zoran *zr)
static void lml33_init(struct zoran *zr)
{
- pci_dbg(zr->pci_dev, "%s\n", __func__);
-
GPIO(zr, 2, 1); // Set Composite input/output
}
@@ -334,10 +327,6 @@ static void videocodec_exit(struct zoran *zr)
codec_exit(zr, zr->card.video_vfe);
}
-// struct tvnorm {
-// u16 wt, wa, h_start, h_sync_start, ht, ha, v_start;
-// };
-
static const struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
static const struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
static const struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
@@ -619,7 +608,10 @@ static struct card_info zoran_cards[NUM_CARDS] = {
}, {
.type = AVS6EYES,
.name = "6-Eyes",
-/* AverMedia chose not to brand the 6-Eyes. Thus it can't be autodetected, and requires card=x. */
+ /*
+ * AverMedia chose not to brand the 6-Eyes. Thus it can't be
+ * autodetected, and requires card=x.
+ */
.i2c_decoder = "ks0127",
.addrs_decoder = ks0127_addrs,
.i2c_encoder = "bt866",
@@ -764,7 +756,9 @@ int zoran_check_jpg_settings(struct zoran *zr,
case 4:
if (zr->card.type == DC10_NEW) {
- pci_dbg(zr->pci_dev, "%s - HDec by 4 is not supported on the DC10\n", __func__);
+ pci_dbg(zr->pci_dev,
+ "%s - HDec by 4 is not supported on the DC10\n",
+ __func__);
err0++;
break;
}
@@ -882,12 +876,7 @@ static int zoran_init_video_device(struct zoran *zr, struct video_device *video_
video_dev->device_caps = V4L2_CAP_STREAMING | dir;
strscpy(video_dev->name, ZR_DEVNAME(zr), sizeof(video_dev->name));
- /*
- * It's not a mem2mem device, but you can both capture and output from one and the same
- * device. This should really be split up into two device nodes, but that's a job for
- * another day.
- */
- video_dev->vfl_dir = VFL_DIR_M2M;
+ video_dev->vfl_dir = VFL_DIR_RX;
zoran_queue_init(zr, &zr->vq, V4L2_BUF_TYPE_VIDEO_CAPTURE);
err = video_register_device(video_dev, VFL_TYPE_VIDEO, video_nr[zr->id]);
@@ -1019,7 +1008,9 @@ static int zr36057_init(struct zoran *zr)
zr->timing = zr->card.tvn[ZR_NORM_SECAM];
}
if (!zr->timing) {
- pci_warn(zr->pci_dev, "%s - default TV standard not supported by hardware. PAL will be used.\n", __func__);
+ pci_warn(zr->pci_dev,
+ "%s - default TV standard not supported by hardware. PAL will be used.\n",
+ __func__);
zr->norm = V4L2_STD_PAL;
zr->timing = zr->card.tvn[ZR_NORM_PAL];
}
@@ -1038,9 +1029,9 @@ static int zr36057_init(struct zoran *zr)
zr->stat_com = dma_alloc_coherent(&zr->pci_dev->dev,
BUZ_NUM_STAT_COM * sizeof(u32),
&zr->p_sc, GFP_KERNEL);
- if (!zr->stat_com) {
+ if (!zr->stat_com)
return -ENOMEM;
- }
+
for (j = 0; j < BUZ_NUM_STAT_COM; j++)
zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
@@ -1066,9 +1057,11 @@ static int zr36057_init(struct zoran *zr)
return 0;
exit_statcomb:
- dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2, zr->stat_comb, zr->p_scb);
+ dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2,
+ zr->stat_comb, zr->p_scb);
exit_statcom:
- dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32), zr->stat_com, zr->p_sc);
+ dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32),
+ zr->stat_com, zr->p_sc);
return err;
}
@@ -1099,8 +1092,10 @@ static void zoran_remove(struct pci_dev *pdev)
btwrite(0, ZR36057_SPGPPCR);
pci_free_irq(zr->pci_dev, 0, zr);
/* unmap and free memory */
- dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32), zr->stat_com, zr->p_sc);
- dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2, zr->stat_comb, zr->p_scb);
+ dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32),
+ zr->stat_com, zr->p_sc);
+ dma_free_coherent(&zr->pci_dev->dev, BUZ_NUM_STAT_COM * sizeof(u32) * 2,
+ zr->stat_comb, zr->p_scb);
pci_release_regions(pdev);
pci_disable_device(zr->pci_dev);
zoran_exit_video_devices(zr);
@@ -1299,7 +1294,8 @@ static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_err(pdev, "Unknown card, try specifying card=X module parameter\n");
goto zr_unreg;
}
- pci_info(zr->pci_dev, "%s() - card %s detected\n", __func__, zoran_cards[card_num].name);
+ pci_info(zr->pci_dev, "%s() - card %s detected\n", __func__,
+ zoran_cards[card_num].name);
} else {
card_num = card[nr];
if (card_num >= NUM_CARDS || card_num < 0) {
@@ -1324,7 +1320,8 @@ static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto zr_unreg;
- zr->zr36057_mem = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+ zr->zr36057_mem = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
if (!zr->zr36057_mem) {
pci_err(pdev, "%s() - ioremap failed\n", __func__);
goto zr_pci_release;
@@ -1348,7 +1345,8 @@ static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
&latency);
need_latency = zr->revision > 1 ? 32 : 48;
if (latency != need_latency) {
- pci_info(zr->pci_dev, "Changing PCI latency from %d to %d\n", latency, need_latency);
+ pci_info(zr->pci_dev, "Changing PCI latency from %d to %d\n",
+ latency, need_latency);
pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, need_latency);
}
diff --git a/drivers/staging/media/zoran/zoran_card.h b/drivers/media/pci/zoran/zoran_card.h
index 8e0d634cb30f..518cb426b446 100644
--- a/drivers/staging/media/zoran/zoran_card.h
+++ b/drivers/media/pci/zoran/zoran_card.h
@@ -19,11 +19,10 @@ extern int zr36067_debug;
extern const struct video_device zoran_template;
-extern int zoran_check_jpg_settings(struct zoran *zr,
- struct zoran_jpg_settings *settings,
- int try);
-extern void zoran_open_init_params(struct zoran *zr);
-extern void zoran_vdev_release(struct video_device *vdev);
+int zoran_check_jpg_settings(struct zoran *zr,
+ struct zoran_jpg_settings *settings, int try);
+void zoran_open_init_params(struct zoran *zr);
+void zoran_vdev_release(struct video_device *vdev);
void zr36016_write(struct videocodec *codec, u16 reg, u32 val);
diff --git a/drivers/staging/media/zoran/zoran_device.c b/drivers/media/pci/zoran/zoran_device.c
index 2470889a58fa..31f049b55529 100644
--- a/drivers/staging/media/zoran/zoran_device.c
+++ b/drivers/media/pci/zoran/zoran_device.c
@@ -50,7 +50,6 @@ static bool lml33dpath; /* default = 0
module_param(lml33dpath, bool, 0644);
MODULE_PARM_DESC(lml33dpath, "Use digital path capture mode (on LML33 cards)");
-int zr_set_buf(struct zoran *zr);
/*
* initialize video front end
*/
@@ -108,7 +107,6 @@ int post_office_wait(struct zoran *zr)
{
u32 por;
-// while (((por = btread(ZR36057_POR)) & (ZR36057_POR_PO_PEN | ZR36057_POR_PO_TIME)) == ZR36057_POR_PO_PEN) {
while ((por = btread(ZR36057_POR)) & ZR36057_POR_PO_PEN) {
/* wait for something to happen */
/* TODO add timeout */
@@ -155,10 +153,12 @@ void jpeg_codec_sleep(struct zoran *zr, int sleep)
{
GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep);
if (!sleep) {
- pci_dbg(zr->pci_dev, "%s() - wake GPIO=0x%08x\n", __func__, btread(ZR36057_GPPGCR1));
- udelay(500);
+ pci_dbg(zr->pci_dev, "%s() - wake GPIO=0x%08x\n",
+ __func__, btread(ZR36057_GPPGCR1));
+ usleep_range(500, 1000);
} else {
- pci_dbg(zr->pci_dev, "%s() - sleep GPIO=0x%08x\n", __func__, btread(ZR36057_GPPGCR1));
+ pci_dbg(zr->pci_dev, "%s() - sleep GPIO=0x%08x\n",
+ __func__, btread(ZR36057_GPPGCR1));
udelay(2);
}
}
@@ -284,7 +284,8 @@ static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height,
vcrop1 = (tvn->ha / 2 - he) / 2;
vcrop2 = tvn->ha / 2 - he - vcrop1;
v_start = tvn->v_start;
- v_end = v_start + tvn->ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP
+ // FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP
+ v_end = v_start + tvn->ha / 2; // - 1;
v_start += vcrop1;
v_end -= vcrop2;
reg = ((v_start & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_START)
@@ -298,10 +299,12 @@ static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height,
reg |= (hor_dcm << ZR36057_VFESPFR_HOR_DCM);
reg |= (ver_dcm << ZR36057_VFESPFR_VER_DCM);
reg |= (disp_mode << ZR36057_VFESPFR_DISP_MODE);
- /* RJ: I don't know, why the following has to be the opposite
+ /*
+ * RJ: I don't know, why the following has to be the opposite
* of the corresponding ZR36060 setting, but only this way
- * we get the correct colors when uncompressing to the screen */
- //reg |= ZR36057_VFESPFR_VCLK_POL; /**/
+ * we get the correct colors when uncompressing to the screen
+ */
+ //reg |= ZR36057_VFESPFR_VCLK_POL;
/* RJ: Don't know if that is needed for NTSC also */
if (!(zr->norm & V4L2_STD_NTSC))
reg |= ZR36057_VFESPFR_EXT_FL; // NEEDED!!!!!!! Wolfgang
@@ -342,7 +345,7 @@ void zr36057_set_memgrab(struct zoran *zr, int mode)
* will be stuck at 1 until capturing is turned back on.
*/
if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SNAP_SHOT)
- pci_warn(zr->pci_dev, "zr36057_set_memgrab(1) with SnapShot on!?\n");
+ pci_warn(zr->pci_dev, "%s(1) with SnapShot on!?\n", __func__);
/* switch on VSync interrupts */
btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts
@@ -595,11 +598,9 @@ void jpeg_start(struct zoran *zr)
/* enable the Go generation */
btor(ZR36057_JMC_GO_EN, ZR36057_JMC);
- udelay(30);
+ usleep_range(30, 100);
set_frame(zr, 1); // /FRAME
-
- pci_dbg(zr->pci_dev, "jpeg_start\n");
}
void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode)
@@ -803,8 +804,10 @@ static void zoran_reap_stat_com(struct zoran *zr)
unsigned int size = 0;
u32 fcnt;
- /* In motion decompress we don't have a hardware frame counter,
- * we just count the interrupts here */
+ /*
+ * In motion decompress we don't have a hardware frame counter,
+ * we just count the interrupts here
+ */
if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
zr->jpg_seq_num++;
@@ -938,9 +941,9 @@ void zoran_init_hardware(struct zoran *zr)
void zr36057_restart(struct zoran *zr)
{
btwrite(0, ZR36057_SPGPPCR);
- udelay(1000);
+ usleep_range(1000, 2000);
btor(ZR36057_SPGPPCR_SOFT_RESET, ZR36057_SPGPPCR);
- udelay(1000);
+ usleep_range(1000, 2000);
/* assert P_Reset */
btwrite(0, ZR36057_JPC);
diff --git a/drivers/media/pci/zoran/zoran_device.h b/drivers/media/pci/zoran/zoran_device.h
new file mode 100644
index 000000000000..34fd5cc914eb
--- /dev/null
+++ b/drivers/media/pci/zoran/zoran_device.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Zoran zr36057/zr36067 PCI controller driver, for the
+ * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
+ * Media Labs LML33/LML33R10.
+ *
+ * This part handles card-specific data and detection
+ *
+ * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+ */
+
+#ifndef __ZORAN_DEVICE_H__
+#define __ZORAN_DEVICE_H__
+
+/* general purpose I/O */
+void GPIO(struct zoran *zr, int bit, unsigned int value);
+
+/* codec (or actually: guest bus) access */
+int post_office_wait(struct zoran *zr);
+int post_office_write(struct zoran *zr, unsigned int guest, unsigned int reg,
+ unsigned int value);
+int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg);
+
+void jpeg_codec_sleep(struct zoran *zr, int sleep);
+int jpeg_codec_reset(struct zoran *zr);
+
+/* zr360x7 access to raw capture */
+void zr36057_overlay(struct zoran *zr, int on);
+void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count);
+void zr36057_set_memgrab(struct zoran *zr, int mode);
+int wait_grab_pending(struct zoran *zr);
+
+/* interrupts */
+void print_interrupts(struct zoran *zr);
+void clear_interrupt_counters(struct zoran *zr);
+irqreturn_t zoran_irq(int irq, void *dev_id);
+
+/* JPEG codec access */
+void jpeg_start(struct zoran *zr);
+void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode);
+void zoran_feed_stat_com(struct zoran *zr);
+
+/* general */
+void zoran_set_pci_master(struct zoran *zr, int set_master);
+void zoran_init_hardware(struct zoran *zr);
+void zr36057_restart(struct zoran *zr);
+
+extern const struct zoran_format zoran_formats[];
+
+extern int v4l_bufsize;
+extern int jpg_bufsize;
+extern int pass_through;
+
+/* i2c */
+#define decoder_call(zr, o, f, args...) \
+ v4l2_subdev_call((zr)->decoder, o, f, ##args)
+#define encoder_call(zr, o, f, args...) \
+ v4l2_subdev_call((zr)->encoder, o, f, ##args)
+
+#endif /* __ZORAN_DEVICE_H__ */
diff --git a/drivers/staging/media/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index 4304b7e21709..fa672cc8bc67 100644
--- a/drivers/staging/media/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -203,7 +203,6 @@ static int zoran_v4l_set_format(struct zoran *zr, int width, int height,
static int zoran_set_norm(struct zoran *zr, v4l2_std_id norm)
{
-
if (!(norm & zr->card.norms)) {
pci_dbg(zr->pci_dev, "%s - unsupported norm %llx\n", __func__, norm);
return -EINVAL;
@@ -287,17 +286,6 @@ static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
}
-#if 0
-/* TODO: output does not work yet */
-static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
- struct v4l2_fmtdesc *f)
-{
- struct zoran *zr = video_drvdata(file);
-
- return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
-}
-#endif
-
static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
struct v4l2_format *fmt)
{
@@ -430,8 +418,10 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
fmt->fmt.pix.field = V4L2_FIELD_TOP;
bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8);
- v4l_bound_align_image(&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2,
- &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0);
+ v4l_bound_align_image(&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH,
+ bpp == 2 ? 1 : 2,
+ &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT,
+ 0, 0);
fmt->fmt.pix.bytesperline = fmt->fmt.pix.width * bpp;
fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height;
return 0;
@@ -627,38 +617,6 @@ static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
return res;
}
-#if 0
-/* TODO: output does not work yet */
-static int zoran_enum_output(struct file *file, void *__fh,
- struct v4l2_output *outp)
-{
- if (outp->index != 0)
- return -EINVAL;
-
- outp->index = 0;
- outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
- outp->std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
- outp->capabilities = V4L2_OUT_CAP_STD;
- strscpy(outp->name, "Autodetect", sizeof(outp->name));
-
- return 0;
-}
-static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
-{
- *output = 0;
-
- return 0;
-}
-
-static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
-{
- if (output != 0)
- return -EINVAL;
-
- return 0;
-}
-#endif
-
/* cropping (sub-frame capture) */
static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selection *sel)
{
@@ -746,9 +704,6 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
.vidioc_enum_input = zoran_enum_input,
.vidioc_g_input = zoran_g_input,
.vidioc_s_input = zoran_s_input,
-/* .vidioc_enum_output = zoran_enum_output,
- .vidioc_g_output = zoran_g_output,
- .vidioc_s_output = zoran_s_output,*/
.vidioc_g_std = zoran_g_std,
.vidioc_s_std = zoran_s_std,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
@@ -760,13 +715,9 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
.vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
-/* .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,*/
.vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
-/* .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out,*/
.vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
-/* .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out,*/
.vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
-/* .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,*/
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
@@ -1013,7 +964,7 @@ int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir)
vq->dev = &zr->pci_dev->dev;
vq->type = dir;
- vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ | VB2_WRITE;
+ vq->io_modes = VB2_DMABUF | VB2_MMAP;
vq->drv_priv = zr;
vq->buf_struct_size = sizeof(struct zr_buffer);
vq->ops = &zr_video_qops;
diff --git a/drivers/staging/media/zoran/zr36016.c b/drivers/media/pci/zoran/zr36016.c
index 0e0532537a3e..4b328ad6083f 100644
--- a/drivers/staging/media/zoran/zr36016.c
+++ b/drivers/media/pci/zoran/zr36016.c
@@ -15,18 +15,19 @@
/* codec io API */
#include "videocodec.h"
-/* it doesn't make sense to have more than 20 or so,
- just to prevent some unwanted loops */
+/*
+ * it doesn't make sense to have more than 20 or so,
+ * just to prevent some unwanted loops
+ */
#define MAX_CODECS 20
/* amount of chips attached via this driver */
static int zr36016_codecs;
-/* =========================================================================
- Local hardware I/O functions:
-
- read/write via codec layer (registers are located in the master device)
- ========================================================================= */
+/*
+ * Local hardware I/O functions: read/write via codec layer
+ * (registers are located in the master device)
+ */
/* read and write functions */
static u8 zr36016_read(struct zr36016 *ptr, u16 reg)
@@ -58,9 +59,12 @@ static void zr36016_write(struct zr36016 *ptr, u16 reg, u8 value)
zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name);
}
-/* indirect read and write functions */
-/* the 016 supports auto-addr-increment, but
- * writing it all time cost not much and is safer... */
+/*
+ * indirect read and write functions
+ *
+ * the 016 supports auto-addr-increment, but
+ * writing it all time cost not much and is safer...
+ */
static u8 zr36016_readi(struct zr36016 *ptr, u16 reg)
{
u8 value = 0;
@@ -68,8 +72,8 @@ static u8 zr36016_readi(struct zr36016 *ptr, u16 reg)
/* just in case something is wrong... */
if ((ptr->codec->master_data->writereg) && (ptr->codec->master_data->readreg)) {
- ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
- value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF; // DATA
+ ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F);
+ value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF;
} else {
zrdev_err(zr, "%s: invalid I/O setup, nothing read (i)!\n", ptr->name);
}
@@ -88,18 +92,14 @@ static void zr36016_writei(struct zr36016 *ptr, u16 reg, u8 value)
/* just in case something is wrong... */
if (ptr->codec->master_data->writereg) {
- ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
- ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF); // DATA
+ ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F);
+ ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF);
} else {
zrdev_err(zr, "%s: invalid I/O setup, nothing written (i)!\n", ptr->name);
}
}
-/* =========================================================================
- Local helper function:
-
- version read
- ========================================================================= */
+/* Local helper function: version read */
/* version kept in datastructure */
static u8 zr36016_read_version(struct zr36016 *ptr)
@@ -108,11 +108,10 @@ static u8 zr36016_read_version(struct zr36016 *ptr)
return ptr->version;
}
-/* =========================================================================
- Local helper function:
-
- basic test of "connectivity", writes/reads to/from PAX-Lo register
- ========================================================================= */
+/*
+ * Local helper function: basic test of "connectivity", writes/reads
+ * to/from PAX-Lo register
+ */
static int zr36016_basic_test(struct zr36016 *ptr)
{
@@ -150,36 +149,7 @@ static int zr36016_basic_test(struct zr36016 *ptr)
return 0; /* looks good! */
}
-/* =========================================================================
- Local helper function:
-
- simple loop for pushing the init datasets - NO USE --
- ========================================================================= */
-
-#if 0
-static int zr36016_pushit(struct zr36016 *ptr,
- u16 startreg,
- u16 len,
- const char *data)
-{
- struct zoran *zr = videocodec_to_zoran(ptr->codec);
- int i = 0;
-
- zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n",
- ptr->name, startreg, len);
- while (i < len) {
- zr36016_writei(ptr, startreg++, data[i++]);
- }
-
- return i;
-}
-#endif
-
-/* =========================================================================
- Basic datasets & init:
-
- //TODO//
- ========================================================================= */
+/* Basic datasets & init */
static void zr36016_init(struct zr36016 *ptr)
{
@@ -213,14 +183,16 @@ static void zr36016_init(struct zr36016 *ptr)
zr36016_write(ptr, ZR016_GOSTOP, 1);
}
-/* =========================================================================
- CODEC API FUNCTIONS
-
- this functions are accessed by the master via the API structure
- ========================================================================= */
+/*
+ * CODEC API FUNCTIONS
+ *
+ * These functions are accessed by the master via the API structure
+ */
-/* set compression/expansion mode and launches codec -
- this should be the last call from the master before starting processing */
+/*
+ * set compression/expansion mode and launches codec -
+ * this should be the last call from the master before starting processing
+ */
static int zr36016_set_mode(struct videocodec *codec, int mode)
{
struct zr36016 *ptr = (struct zr36016 *)codec->data;
@@ -249,22 +221,28 @@ static int zr36016_set_video(struct videocodec *codec, const struct tvnorm *norm
cap->x, cap->y, cap->width, cap->height,
cap->decimation);
- /* if () return -EINVAL;
+ /*
+ * if () return -EINVAL;
* trust the master driver that it knows what it does - so
- * we allow invalid startx/y for now ... */
+ * we allow invalid startx/y for now ...
+ */
ptr->width = cap->width;
ptr->height = cap->height;
- /* (Ronald) This is ugly. zoran_device.c, line 387
+ /*
+ * (Ronald) This is ugly. zoran_device.c, line 387
* already mentions what happens if h_start is even
* (blue faces, etc., cr/cb inversed). There's probably
* some good reason why h_start is 0 instead of 1, so I'm
* leaving it to this for now, but really... This can be
- * done a lot simpler */
+ * done a lot simpler
+ */
ptr->xoff = (norm->h_start ? norm->h_start : 1) + cap->x;
- /* Something to note here (I don't understand it), setting
+ /*
+ * Something to note here (I don't understand it), setting
* v_start too high will cause the codec to 'not work'. I
* really don't get it. values of 16 (v_start) already break
- * it here. Just '0' seems to work. More testing needed! */
+ * it here. Just '0' seems to work. More testing needed!
+ */
ptr->yoff = norm->v_start + cap->y;
/* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */
ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1;
@@ -319,11 +297,11 @@ static int zr36016_control(struct videocodec *codec, int type, int size, void *d
return size;
}
-/* =========================================================================
- Exit and unregister function:
-
- Deinitializes Zoran's JPEG processor
- ========================================================================= */
+/*
+ * Exit and unregister function:
+ *
+ * Deinitializes Zoran's JPEG processor
+ */
static int zr36016_unset(struct videocodec *codec)
{
@@ -344,14 +322,14 @@ static int zr36016_unset(struct videocodec *codec)
return -EFAULT;
}
-/* =========================================================================
- Setup and registry function:
-
- Initializes Zoran's JPEG processor
-
- Also sets pixel size, average code size, mode (compr./decompr.)
- (the given size is determined by the processor with the video interface)
- ========================================================================= */
+/*
+ * Setup and registry function:
+ *
+ * Initializes Zoran's JPEG processor
+ *
+ * Also sets pixel size, average code size, mode (compr./decompr.)
+ * (the given size is determined by the processor with the video interface)
+ */
static int zr36016_setup(struct videocodec *codec)
{
@@ -410,9 +388,7 @@ static const struct videocodec zr36016_codec = {
/* others are not used */
};
-/* =========================================================================
- HOOK IN DRIVER AS KERNEL MODULE
- ========================================================================= */
+/* HOOK IN DRIVER AS KERNEL MODULE */
int zr36016_init_module(void)
{
diff --git a/drivers/staging/media/zoran/zr36016.h b/drivers/media/pci/zoran/zr36016.h
index 04afba35669d..04afba35669d 100644
--- a/drivers/staging/media/zoran/zr36016.h
+++ b/drivers/media/pci/zoran/zr36016.h
diff --git a/drivers/staging/media/zoran/zr36050.c b/drivers/media/pci/zoran/zr36050.c
index 6a7ef28d996c..b07d7e5c1b4a 100644
--- a/drivers/staging/media/zoran/zr36050.c
+++ b/drivers/media/pci/zoran/zr36050.c
@@ -22,18 +22,20 @@
/* codec io API */
#include "videocodec.h"
-/* it doesn't make sense to have more than 20 or so,
- just to prevent some unwanted loops */
+/*
+ * it doesn't make sense to have more than 20 or so,
+ * just to prevent some unwanted loops
+ */
#define MAX_CODECS 20
/* amount of chips attached via this driver */
static int zr36050_codecs;
-/* =========================================================================
- Local hardware I/O functions:
-
- read/write via codec layer (registers are located in the master device)
- ========================================================================= */
+/*
+ * Local hardware I/O functions:
+ *
+ * read/write via codec layer (registers are located in the master device)
+ */
/* read and write functions */
static u8 zr36050_read(struct zr36050 *ptr, u16 reg)
@@ -66,12 +68,6 @@ static void zr36050_write(struct zr36050 *ptr, u16 reg, u8 value)
ptr->name);
}
-/* =========================================================================
- Local helper function:
-
- status read
- ========================================================================= */
-
/* status is kept in datastructure */
static u8 zr36050_read_status1(struct zr36050 *ptr)
{
@@ -81,12 +77,6 @@ static u8 zr36050_read_status1(struct zr36050 *ptr)
return ptr->status1;
}
-/* =========================================================================
- Local helper function:
-
- scale factor read
- ========================================================================= */
-
/* scale factor is kept in datastructure */
static u16 zr36050_read_scalefactor(struct zr36050 *ptr)
{
@@ -98,11 +88,11 @@ static u16 zr36050_read_scalefactor(struct zr36050 *ptr)
return ptr->scalefact;
}
-/* =========================================================================
- Local helper function:
-
- wait if codec is ready to proceed (end of processing) or time is over
- ========================================================================= */
+/*
+ * Local helper function:
+ *
+ * wait if codec is ready to proceed (end of processing) or time is over
+ */
static void zr36050_wait_end(struct zr36050 *ptr)
{
@@ -120,11 +110,10 @@ static void zr36050_wait_end(struct zr36050 *ptr)
}
}
-/* =========================================================================
- Local helper function:
-
- basic test of "connectivity", writes/reads to/from memory the SOF marker
- ========================================================================= */
+/*
+ * Local helper function: basic test of "connectivity", writes/reads
+ * to/from memory the SOF marker
+ */
static int zr36050_basic_test(struct zr36050 *ptr)
{
@@ -160,11 +149,7 @@ static int zr36050_basic_test(struct zr36050 *ptr)
return 0; /* looks good! */
}
-/* =========================================================================
- Local helper function:
-
- simple loop for pushing the init datasets
- ========================================================================= */
+/* Local helper function: simple loop for pushing the init datasets */
static int zr36050_pushit(struct zr36050 *ptr, u16 startreg, u16 len, const char *data)
{
@@ -179,16 +164,16 @@ static int zr36050_pushit(struct zr36050 *ptr, u16 startreg, u16 len, const char
return i;
}
-/* =========================================================================
- Basic datasets:
-
- jpeg baseline setup data (you find it on lots places in internet, or just
- extract it from any regular .jpg image...)
-
- Could be variable, but until it's not needed it they are just fixed to save
- memory. Otherwise expand zr36050 structure with arrays, push the values to
- it and initialize from there, as e.g. the linux zr36057/60 driver does it.
- ========================================================================= */
+/*
+ * Basic datasets:
+ *
+ * jpeg baseline setup data (you find it on lots places in internet, or just
+ * extract it from any regular .jpg image...)
+ *
+ * Could be variable, but until it's not needed it they are just fixed to save
+ * memory. Otherwise expand zr36050 structure with arrays, push the values to
+ * it and initialize from there, as e.g. the linux zr36057/60 driver does it.
+ */
static const char zr36050_dqt[0x86] = {
0xff, 0xdb, //Marker: DQT
@@ -281,18 +266,19 @@ static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
-/* =========================================================================
- Local helper functions:
-
- calculation and setup of parameter-dependent JPEG baseline segments
- (needed for compression only)
- ========================================================================= */
+/*
+ * Local helper functions:
+ *
+ * calculation and setup of parameter-dependent JPEG baseline segments
+ * (needed for compression only)
+ */
/* ------------------------------------------------------------------------- */
-/* SOF (start of frame) segment depends on width, height and sampling ratio
- of each color component */
-
+/*
+ * SOF (start of frame) segment depends on width, height and sampling ratio
+ * of each color component
+ */
static int zr36050_set_sof(struct zr36050 *ptr)
{
struct zoran *zr = videocodec_to_zoran(ptr->codec);
@@ -313,7 +299,8 @@ static int zr36050_set_sof(struct zr36050 *ptr)
sof_data[9] = NO_OF_COMPONENTS;
for (i = 0; i < NO_OF_COMPONENTS; i++) {
sof_data[10 + (i * 3)] = i; // index identifier
- sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios
+ sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
+ (ptr->v_samp_ratio[i]); // sampling ratios
sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
}
return zr36050_pushit(ptr, ZR050_SOF_IDX,
@@ -322,8 +309,10 @@ static int zr36050_set_sof(struct zr36050 *ptr)
/* ------------------------------------------------------------------------- */
-/* SOS (start of scan) segment depends on the used scan components
- of each color component */
+/*
+ * SOS (start of scan) segment depends on the used scan components
+ * of each color component
+ */
static int zr36050_set_sos(struct zr36050 *ptr)
{
@@ -368,14 +357,14 @@ static int zr36050_set_dri(struct zr36050 *ptr)
return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
}
-/* =========================================================================
- Setup function:
-
- Setup compression/decompression of Zoran's JPEG processor
- ( see also zoran 36050 manual )
-
- ... sorry for the spaghetti code ...
- ========================================================================= */
+/*
+ * Setup function:
+ *
+ * Setup compression/decompression of Zoran's JPEG processor
+ * ( see also zoran 36050 manual )
+ *
+ * ... sorry for the spaghetti code ...
+ */
static void zr36050_init(struct zr36050 *ptr)
{
int sum = 0;
@@ -411,8 +400,10 @@ static void zr36050_init(struct zr36050 *ptr)
sum += zr36050_set_sos(ptr);
sum += zr36050_set_dri(ptr);
- /* setup the fixed jpeg tables - maybe variable, though -
- * (see table init section above) */
+ /*
+ * setup the fixed jpeg tables - maybe variable, though -
+ * (see table init section above)
+ */
zrdev_dbg(zr, "%s: write DQT, DHT, APP\n", ptr->name);
sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
sizeof(zr36050_dqt), zr36050_dqt);
@@ -522,14 +513,16 @@ static void zr36050_init(struct zr36050 *ptr)
zr36050_read(ptr, 0);
}
-/* =========================================================================
- CODEC API FUNCTIONS
-
- this functions are accessed by the master via the API structure
- ========================================================================= */
+/*
+ * CODEC API FUNCTIONS
+ *
+ * this functions are accessed by the master via the API structure
+ */
-/* set compression/expansion mode and launches codec -
- this should be the last call from the master before starting processing */
+/*
+ * set compression/expansion mode and launches codec -
+ * this should be the last call from the master before starting processing
+ */
static int zr36050_set_mode(struct videocodec *codec, int mode)
{
struct zr36050 *ptr = (struct zr36050 *)codec->data;
@@ -558,9 +551,10 @@ static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm
ptr->name, norm->h_start, norm->v_start,
cap->x, cap->y, cap->width, cap->height,
cap->decimation, cap->quality);
- /* if () return -EINVAL;
+ /*
* trust the master driver that it knows what it does - so
- * we allow invalid startx/y and norm for now ... */
+ * we allow invalid startx/y and norm for now ...
+ */
ptr->width = cap->width / (cap->decimation & 0xff);
ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
@@ -579,8 +573,10 @@ static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm
ptr->real_code_vol = size >> 3; /* in bytes */
- /* Set max_block_vol here (previously in zr36050_init, moved
- * here for consistency with zr36060 code */
+ /*
+ * Set max_block_vol here (previously in zr36050_init, moved
+ * here for consistency with zr36060 code
+ */
zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
return 0;
@@ -637,8 +633,6 @@ static int zr36050_control(struct videocodec *codec, int type, int size, void *d
if (size != sizeof(int))
return -EFAULT;
ptr->total_code_vol = *ival;
- /* (Kieran Morrissey)
- * code copied from zr36060.c to ensure proper bitrate */
ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
break;
@@ -701,11 +695,7 @@ static int zr36050_control(struct videocodec *codec, int type, int size, void *d
return size;
}
-/* =========================================================================
- Exit and unregister function:
-
- Deinitializes Zoran's JPEG processor
- ========================================================================= */
+/* Exit and unregister function: Deinitializes Zoran's JPEG processor */
static int zr36050_unset(struct videocodec *codec)
{
@@ -727,14 +717,14 @@ static int zr36050_unset(struct videocodec *codec)
return -EFAULT;
}
-/* =========================================================================
- Setup and registry function:
-
- Initializes Zoran's JPEG processor
-
- Also sets pixel size, average code size, mode (compr./decompr.)
- (the given size is determined by the processor with the video interface)
- ========================================================================= */
+/*
+ * Setup and registry function:
+ *
+ * Initializes Zoran's JPEG processor
+ *
+ * Also sets pixel size, average code size, mode (compr./decompr.)
+ * (the given size is determined by the processor with the video interface)
+ */
static int zr36050_setup(struct videocodec *codec)
{
@@ -771,8 +761,8 @@ static int zr36050_setup(struct videocodec *codec)
memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
- ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
- * (what is the difference?) */
+ /* 0 or 1 - fixed file size flag (what is the difference?) */
+ ptr->bitrate_ctrl = 0;
ptr->mode = CODEC_DO_COMPRESSION;
ptr->width = 384;
ptr->height = 288;
@@ -809,9 +799,7 @@ static const struct videocodec zr36050_codec = {
// others are not used
};
-/* =========================================================================
- HOOK IN DRIVER AS KERNEL MODULE
- ========================================================================= */
+/* HOOK IN DRIVER AS KERNEL MODULE */
int zr36050_init_module(void)
{
diff --git a/drivers/staging/media/zoran/zr36050.h b/drivers/media/pci/zoran/zr36050.h
index f9b58f4c77b9..f9b58f4c77b9 100644
--- a/drivers/staging/media/zoran/zr36050.h
+++ b/drivers/media/pci/zoran/zr36050.h
diff --git a/drivers/staging/media/zoran/zr36057.h b/drivers/media/pci/zoran/zr36057.h
index a2a75fd9f535..45d8afc62b37 100644
--- a/drivers/staging/media/zoran/zr36057.h
+++ b/drivers/media/pci/zoran/zr36057.h
@@ -11,117 +11,117 @@
/* Zoran ZR36057 registers */
#define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */
-#define ZR36057_VFEHCR_HS_POL BIT(30)
-#define ZR36057_VFEHCR_H_START 10
+#define ZR36057_VFEHCR_HS_POL BIT(30)
+#define ZR36057_VFEHCR_H_START 10
#define ZR36057_VFEHCR_H_END 0
#define ZR36057_VFEHCR_HMASK 0x3ff
#define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */
-#define ZR36057_VFEVCR_VS_POL BIT(30)
-#define ZR36057_VFEVCR_V_START 10
+#define ZR36057_VFEVCR_VS_POL BIT(30)
+#define ZR36057_VFEVCR_V_START 10
#define ZR36057_VFEVCR_V_END 0
#define ZR36057_VFEVCR_VMASK 0x3ff
#define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */
-#define ZR36057_VFESPFR_EXT_FL BIT(26)
-#define ZR36057_VFESPFR_TOP_FIELD BIT(25)
-#define ZR36057_VFESPFR_VCLK_POL BIT(24)
-#define ZR36057_VFESPFR_H_FILTER 21
-#define ZR36057_VFESPFR_HOR_DCM 14
-#define ZR36057_VFESPFR_VER_DCM 8
-#define ZR36057_VFESPFR_DISP_MODE 6
+#define ZR36057_VFESPFR_EXT_FL BIT(26)
+#define ZR36057_VFESPFR_TOP_FIELD BIT(25)
+#define ZR36057_VFESPFR_VCLK_POL BIT(24)
+#define ZR36057_VFESPFR_H_FILTER 21
+#define ZR36057_VFESPFR_HOR_DCM 14
+#define ZR36057_VFESPFR_VER_DCM 8
+#define ZR36057_VFESPFR_DISP_MODE 6
#define ZR36057_VFESPFR_YUV422 (0 << 3)
#define ZR36057_VFESPFR_RGB888 (1 << 3)
#define ZR36057_VFESPFR_RGB565 (2 << 3)
#define ZR36057_VFESPFR_RGB555 (3 << 3)
-#define ZR36057_VFESPFR_ERR_DIF (1 << 2)
-#define ZR36057_VFESPFR_PACK24 (1 << 1)
-#define ZR36057_VFESPFR_LITTLE_ENDIAN (1 << 0)
+#define ZR36057_VFESPFR_ERR_DIF BIT(2)
+#define ZR36057_VFESPFR_PACK24 BIT(1)
+#define ZR36057_VFESPFR_LITTLE_ENDIAN BIT(0)
#define ZR36057_VDTR 0x00c /* Video Display "Top" Register */
#define ZR36057_VDBR 0x010 /* Video Display "Bottom" Register */
#define ZR36057_VSSFGR 0x014 /* Video Stride, Status, and Frame Grab Register */
-#define ZR36057_VSSFGR_DISP_STRIDE 16
-#define ZR36057_VSSFGR_VID_OVF BIT(8)
-#define ZR36057_VSSFGR_SNAP_SHOT BIT(1)
-#define ZR36057_VSSFGR_FRAME_GRAB BIT(0)
+#define ZR36057_VSSFGR_DISP_STRIDE 16
+#define ZR36057_VSSFGR_VID_OVF BIT(8)
+#define ZR36057_VSSFGR_SNAP_SHOT BIT(1)
+#define ZR36057_VSSFGR_FRAME_GRAB BIT(0)
#define ZR36057_VDCR 0x018 /* Video Display Configuration Register */
-#define ZR36057_VDCR_VID_EN BIT(31)
-#define ZR36057_VDCR_MIN_PIX 24
-#define ZR36057_VDCR_TRITON BIT(24)
-#define ZR36057_VDCR_VID_WIN_HT 12
-#define ZR36057_VDCR_VID_WIN_WID 0
+#define ZR36057_VDCR_VID_EN BIT(31)
+#define ZR36057_VDCR_MIN_PIX 24
+#define ZR36057_VDCR_TRITON BIT(24)
+#define ZR36057_VDCR_VID_WIN_HT 12
+#define ZR36057_VDCR_VID_WIN_WID 0
#define ZR36057_MMTR 0x01c /* Masking Map "Top" Register */
#define ZR36057_MMBR 0x020 /* Masking Map "Bottom" Register */
#define ZR36057_OCR 0x024 /* Overlay Control Register */
-#define ZR36057_OCR_OVL_ENABLE BIT(15)
-#define ZR36057_OCR_MASK_STRIDE 0
+#define ZR36057_OCR_OVL_ENABLE BIT(15)
+#define ZR36057_OCR_MASK_STRIDE 0
#define ZR36057_SPGPPCR 0x028 /* System, PCI, and General Purpose Pins Control Register */
-#define ZR36057_SPGPPCR_SOFT_RESET BIT(24)
+#define ZR36057_SPGPPCR_SOFT_RESET BIT(24)
#define ZR36057_GPPGCR1 0x02c /* General Purpose Pins and GuestBus Control Register (1) */
#define ZR36057_MCSAR 0x030 /* MPEG Code Source Address Register */
#define ZR36057_MCTCR 0x034 /* MPEG Code Transfer Control Register */
-#define ZR36057_MCTCR_COD_TIME BIT(30)
-#define ZR36057_MCTCR_C_EMPTY BIT(29)
-#define ZR36057_MCTCR_C_FLUSH BIT(28)
+#define ZR36057_MCTCR_COD_TIME BIT(30)
+#define ZR36057_MCTCR_C_EMPTY BIT(29)
+#define ZR36057_MCTCR_C_FLUSH BIT(28)
#define ZR36057_MCTCR_COD_GUEST_ID 20
#define ZR36057_MCTCR_COD_GUEST_REG 16
#define ZR36057_MCMPR 0x038 /* MPEG Code Memory Pointer Register */
#define ZR36057_ISR 0x03c /* Interrupt Status Register */
-#define ZR36057_ISR_GIRQ1 BIT(30)
-#define ZR36057_ISR_GIRQ0 BIT(29)
-#define ZR36057_ISR_COD_REP_IRQ BIT(28)
-#define ZR36057_ISR_JPEG_REP_IRQ BIT(27)
+#define ZR36057_ISR_GIRQ1 BIT(30)
+#define ZR36057_ISR_GIRQ0 BIT(29)
+#define ZR36057_ISR_COD_REP_IRQ BIT(28)
+#define ZR36057_ISR_JPEG_REP_IRQ BIT(27)
#define ZR36057_ICR 0x040 /* Interrupt Control Register */
-#define ZR36057_ICR_GIRQ1 BIT(30)
-#define ZR36057_ICR_GIRQ0 BIT(29)
-#define ZR36057_ICR_COD_REP_IRQ BIT(28)
-#define ZR36057_ICR_JPEG_REP_IRQ BIT(27)
-#define ZR36057_ICR_INT_PIN_EN BIT(24)
+#define ZR36057_ICR_GIRQ1 BIT(30)
+#define ZR36057_ICR_GIRQ0 BIT(29)
+#define ZR36057_ICR_COD_REP_IRQ BIT(28)
+#define ZR36057_ICR_JPEG_REP_IRQ BIT(27)
+#define ZR36057_ICR_INT_PIN_EN BIT(24)
#define ZR36057_I2CBR 0x044 /* I2C Bus Register */
-#define ZR36057_I2CBR_SDA BIT(1)
-#define ZR36057_I2CBR_SCL BIT(0)
+#define ZR36057_I2CBR_SDA BIT(1)
+#define ZR36057_I2CBR_SCL BIT(0)
#define ZR36057_JMC 0x100 /* JPEG Mode and Control */
-#define ZR36057_JMC_JPG BIT(31)
-#define ZR36057_JMC_JPG_EXP_MODE (0 << 29)
-#define ZR36057_JMC_JPG_CMP_MODE BIT(29)
-#define ZR36057_JMC_MJPG_EXP_MODE (2 << 29)
-#define ZR36057_JMC_MJPG_CMP_MODE (3 << 29)
-#define ZR36057_JMC_RTBUSY_FB BIT(6)
-#define ZR36057_JMC_GO_EN BIT(5)
-#define ZR36057_JMC_SYNC_MSTR BIT(4)
-#define ZR36057_JMC_FLD_PER_BUFF BIT(3)
-#define ZR36057_JMC_VFIFO_FB BIT(2)
-#define ZR36057_JMC_CFIFO_FB BIT(1)
-#define ZR36057_JMC_STLL_LIT_ENDIAN BIT(0)
+#define ZR36057_JMC_JPG BIT(31)
+#define ZR36057_JMC_JPG_EXP_MODE (0 << 29)
+#define ZR36057_JMC_JPG_CMP_MODE BIT(29)
+#define ZR36057_JMC_MJPG_EXP_MODE (2 << 29)
+#define ZR36057_JMC_MJPG_CMP_MODE (3 << 29)
+#define ZR36057_JMC_RTBUSY_FB BIT(6)
+#define ZR36057_JMC_GO_EN BIT(5)
+#define ZR36057_JMC_SYNC_MSTR BIT(4)
+#define ZR36057_JMC_FLD_PER_BUFF BIT(3)
+#define ZR36057_JMC_VFIFO_FB BIT(2)
+#define ZR36057_JMC_CFIFO_FB BIT(1)
+#define ZR36057_JMC_STLL_LIT_ENDIAN BIT(0)
#define ZR36057_JPC 0x104 /* JPEG Process Control */
-#define ZR36057_JPC_P_RESET BIT(7)
-#define ZR36057_JPC_COD_TRNS_EN BIT(5)
-#define ZR36057_JPC_ACTIVE BIT(0)
+#define ZR36057_JPC_P_RESET BIT(7)
+#define ZR36057_JPC_COD_TRNS_EN BIT(5)
+#define ZR36057_JPC_ACTIVE BIT(0)
#define ZR36057_VSP 0x108 /* Vertical Sync Parameters */
-#define ZR36057_VSP_VSYNC_SIZE 16
-#define ZR36057_VSP_FRM_TOT 0
+#define ZR36057_VSP_VSYNC_SIZE 16
+#define ZR36057_VSP_FRM_TOT 0
#define ZR36057_HSP 0x10c /* Horizontal Sync Parameters */
-#define ZR36057_HSP_HSYNC_START 16
-#define ZR36057_HSP_LINE_TOT 0
+#define ZR36057_HSP_HSYNC_START 16
+#define ZR36057_HSP_LINE_TOT 0
#define ZR36057_FHAP 0x110 /* Field Horizontal Active Portion */
#define ZR36057_FHAP_NAX 16
@@ -132,22 +132,22 @@
#define ZR36057_FVAP_PAY 0
#define ZR36057_FPP 0x118 /* Field Process Parameters */
-#define ZR36057_FPP_ODD_EVEN BIT(0)
+#define ZR36057_FPP_ODD_EVEN BIT(0)
#define ZR36057_JCBA 0x11c /* JPEG Code Base Address */
#define ZR36057_JCFT 0x120 /* JPEG Code FIFO Threshold */
#define ZR36057_JCGI 0x124 /* JPEG Codec Guest ID */
-#define ZR36057_JCGI_JPE_GUEST_ID 4
-#define ZR36057_JCGI_JPE_GUEST_REG 0
+#define ZR36057_JCGI_JPE_GUEST_ID 4
+#define ZR36057_JCGI_JPE_GUEST_REG 0
#define ZR36057_GCR2 0x12c /* GuestBus Control Register (2) */
#define ZR36057_POR 0x200 /* Post Office Register */
-#define ZR36057_POR_PO_PEN BIT(25)
-#define ZR36057_POR_PO_TIME BIT(24)
-#define ZR36057_POR_PO_DIR BIT(23)
+#define ZR36057_POR_PO_PEN BIT(25)
+#define ZR36057_POR_PO_TIME BIT(24)
+#define ZR36057_POR_PO_DIR BIT(23)
#define ZR36057_STR 0x300 /* "Still" Transfer Register */
diff --git a/drivers/staging/media/zoran/zr36060.c b/drivers/media/pci/zoran/zr36060.c
index 7798016f1f96..75fd167603dc 100644
--- a/drivers/staging/media/zoran/zr36060.c
+++ b/drivers/media/pci/zoran/zr36060.c
@@ -243,7 +243,10 @@ static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
-/* SOF (start of frame) segment depends on width, height and sampling ratio of each color component */
+/*
+ * SOF (start of frame) segment depends on width, height and sampling ratio
+ * of each color component
+ */
static int zr36060_set_sof(struct zr36060 *ptr)
{
struct zoran *zr = videocodec_to_zoran(ptr->codec);
@@ -555,8 +558,6 @@ static int zr36060_set_video(struct videocodec *codec, const struct tvnorm *norm
reg = 6 - 1; /* VsyncSize */
zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
- //reg = 30 - 1; /* HsyncSize */
-///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68);
reg = 68;
zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
diff --git a/drivers/staging/media/zoran/zr36060.h b/drivers/media/pci/zoran/zr36060.h
index fbf5429534ac..75c88677a4bd 100644
--- a/drivers/staging/media/zoran/zr36060.h
+++ b/drivers/media/pci/zoran/zr36060.h
@@ -124,78 +124,78 @@ struct zr36060 {
/* ZR36060 LOAD register bits */
-#define ZR060_LOAD_LOAD BIT(7)
-#define ZR060_LOAD_SYNC_RST BIT(0)
+#define ZR060_LOAD_LOAD BIT(7)
+#define ZR060_LOAD_SYNC_RST BIT(0)
/* ZR36060 Code FIFO Status register bits */
-#define ZR060_CFSR_BUSY BIT(7)
-#define ZR060_CFSR_C_BUSY BIT(2)
+#define ZR060_CFSR_BUSY BIT(7)
+#define ZR060_CFSR_C_BUSY BIT(2)
#define ZR060_CFSR_CFIFO (3 << 0)
/* ZR36060 Code Interface register */
-#define ZR060_CIR_CODE16 BIT(7)
-#define ZR060_CIR_ENDIAN BIT(6)
-#define ZR060_CIR_CFIS BIT(2)
-#define ZR060_CIR_CODE_MSTR BIT(0)
+#define ZR060_CIR_CODE16 BIT(7)
+#define ZR060_CIR_ENDIAN BIT(6)
+#define ZR060_CIR_CFIS BIT(2)
+#define ZR060_CIR_CODE_MSTR BIT(0)
/* ZR36060 Codec Mode register */
-#define ZR060_CMR_COMP BIT(7)
-#define ZR060_CMR_ATP BIT(6)
-#define ZR060_CMR_PASS2 BIT(5)
-#define ZR060_CMR_TLM BIT(4)
-#define ZR060_CMR_BRB BIT(2)
-#define ZR060_CMR_FSF BIT(1)
+#define ZR060_CMR_COMP BIT(7)
+#define ZR060_CMR_ATP BIT(6)
+#define ZR060_CMR_PASS2 BIT(5)
+#define ZR060_CMR_TLM BIT(4)
+#define ZR060_CMR_BRB BIT(2)
+#define ZR060_CMR_FSF BIT(1)
/* ZR36060 Markers Enable register */
-#define ZR060_MER_APP BIT(7)
-#define ZR060_MER_COM BIT(6)
-#define ZR060_MER_DRI BIT(5)
-#define ZR060_MER_DQT BIT(4)
-#define ZR060_MER_DHT BIT(3)
+#define ZR060_MER_APP BIT(7)
+#define ZR060_MER_COM BIT(6)
+#define ZR060_MER_DRI BIT(5)
+#define ZR060_MER_DQT BIT(4)
+#define ZR060_MER_DHT BIT(3)
/* ZR36060 Interrupt Mask register */
-#define ZR060_IMR_EOAV BIT(3)
-#define ZR060_IMR_EOI BIT(2)
-#define ZR060_IMR_END BIT(1)
-#define ZR060_IMR_DATA_ERR BIT(0)
+#define ZR060_IMR_EOAV BIT(3)
+#define ZR060_IMR_EOI BIT(2)
+#define ZR060_IMR_END BIT(1)
+#define ZR060_IMR_DATA_ERR BIT(0)
/* ZR36060 Interrupt Status register */
#define ZR060_ISR_PRO_CNT (3 << 6)
-#define ZR060_ISR_EOAV BIT(3)
-#define ZR060_ISR_EOI BIT(2)
-#define ZR060_ISR_END BIT(1)
-#define ZR060_ISR_DATA_ERR BIT(0)
+#define ZR060_ISR_EOAV BIT(3)
+#define ZR060_ISR_EOI BIT(2)
+#define ZR060_ISR_END BIT(1)
+#define ZR060_ISR_DATA_ERR BIT(0)
/* ZR36060 Video Control register */
-#define ZR060_VCR_VIDEO8 BIT(7)
-#define ZR060_VCR_RANGE BIT(6)
-#define ZR060_VCR_FI_DET BIT(3)
-#define ZR060_VCR_FI_VEDGE BIT(2)
-#define ZR060_VCR_FI_EXT BIT(1)
-#define ZR060_VCR_SYNC_MSTR BIT(0)
+#define ZR060_VCR_VIDEO8 BIT(7)
+#define ZR060_VCR_RANGE BIT(6)
+#define ZR060_VCR_FI_DET BIT(3)
+#define ZR060_VCR_FI_VEDGE BIT(2)
+#define ZR060_VCR_FI_EXT BIT(1)
+#define ZR060_VCR_SYNC_MSTR BIT(0)
/* ZR36060 Video Polarity register */
-#define ZR060_VPR_VCLK_POL BIT(7)
-#define ZR060_VPR_P_VAL_POL BIT(6)
-#define ZR060_VPR_POE_POL BIT(5)
-#define ZR060_VPR_S_IMG_POL BIT(4)
-#define ZR060_VPR_BL_POL BIT(3)
-#define ZR060_VPR_FI_POL BIT(2)
-#define ZR060_VPR_HS_POL BIT(1)
-#define ZR060_VPR_VS_POL BIT(0)
+#define ZR060_VPR_VCLK_POL BIT(7)
+#define ZR060_VPR_P_VAL_POL BIT(6)
+#define ZR060_VPR_POE_POL BIT(5)
+#define ZR060_VPR_S_IMG_POL BIT(4)
+#define ZR060_VPR_BL_POL BIT(3)
+#define ZR060_VPR_FI_POL BIT(2)
+#define ZR060_VPR_HS_POL BIT(1)
+#define ZR060_VPR_VS_POL BIT(0)
/* ZR36060 Scaling register */
-#define ZR060_SR_V_SCALE BIT(2)
-#define ZR060_SR_H_SCALE2 BIT(0)
+#define ZR060_SR_V_SCALE BIT(2)
+#define ZR060_SR_H_SCALE2 BIT(0)
#define ZR060_SR_H_SCALE4 (2 << 0)
int zr36060_init_module(void);
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index f1056ceaf5a8..a9334263fa9b 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -81,6 +81,7 @@ source "drivers/media/platform/samsung/Kconfig"
source "drivers/media/platform/st/Kconfig"
source "drivers/media/platform/sunxi/Kconfig"
source "drivers/media/platform/ti/Kconfig"
+source "drivers/media/platform/verisilicon/Kconfig"
source "drivers/media/platform/via/Kconfig"
source "drivers/media/platform/xilinx/Kconfig"
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index a881e97bae95..a91f42024273 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -24,6 +24,7 @@ obj-y += samsung/
obj-y += st/
obj-y += sunxi/
obj-y += ti/
+obj-y += verisilicon/
obj-y += via/
obj-y += xilinx/
diff --git a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
index 5e7b319f300d..142d421a8d76 100644
--- a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
+++ b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
@@ -1030,7 +1030,6 @@ static int ge2d_remove(struct platform_device *pdev)
video_unregister_device(ge2d->vfd);
v4l2_m2m_release(ge2d->m2m_dev);
- video_device_release(ge2d->vfd);
v4l2_device_unregister(&ge2d->v4l2_dev);
clk_disable_unprepare(ge2d->clk);
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
index 9e64041cc1c1..feb75dc204de 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -808,14 +808,6 @@ static void vdec_init_fmt(struct vpu_inst *inst)
inst->cap_format.field = V4L2_FIELD_NONE;
else
inst->cap_format.field = V4L2_FIELD_SEQ_TB;
- if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
- vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
- if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
- vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
- if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
- vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
- if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
- vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
}
static void vdec_init_crop(struct vpu_inst *inst)
@@ -1555,6 +1547,14 @@ static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i
vdec->codec_info.frame_rate.numerator,
vdec->codec_info.frame_rate.denominator);
break;
+ case 9:
+ num = scnprintf(str, size, "colorspace: %d, %d, %d, %d (%d)\n",
+ vdec->codec_info.color_primaries,
+ vdec->codec_info.transfer_chars,
+ vdec->codec_info.matrix_coeffs,
+ vdec->codec_info.full_range,
+ vdec->codec_info.vui_present);
+ break;
default:
break;
}
diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
index 461524dd1e44..37212f087fdd 100644
--- a/drivers/media/platform/amphion/venc.c
+++ b/drivers/media/platform/amphion/venc.c
@@ -644,7 +644,7 @@ static int venc_ctrl_init(struct vpu_inst *inst)
BITRATE_DEFAULT_PEAK);
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
+ V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 8000, 1, 30);
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
index f914de6ed81e..beac0309ca8d 100644
--- a/drivers/media/platform/amphion/vpu.h
+++ b/drivers/media/platform/amphion/vpu.h
@@ -119,7 +119,6 @@ struct vpu_mbox {
enum vpu_core_state {
VPU_CORE_DEINIT = 0,
VPU_CORE_ACTIVE,
- VPU_CORE_SNAPSHOT,
VPU_CORE_HANG
};
diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c
index 73faa50d2865..f9ec1753f7c8 100644
--- a/drivers/media/platform/amphion/vpu_core.c
+++ b/drivers/media/platform/amphion/vpu_core.c
@@ -89,7 +89,7 @@ static int vpu_core_boot_done(struct vpu_core *core)
core->supported_instance_count = min(core->supported_instance_count, count);
}
core->fw_version = fw_version;
- core->state = VPU_CORE_ACTIVE;
+ vpu_core_set_state(core, VPU_CORE_ACTIVE);
return 0;
}
@@ -172,10 +172,26 @@ int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf)
return __vpu_alloc_dma(core->dev, buf);
}
-static void vpu_core_check_hang(struct vpu_core *core)
+void vpu_core_set_state(struct vpu_core *core, enum vpu_core_state state)
{
- if (core->hang_mask)
- core->state = VPU_CORE_HANG;
+ if (state != core->state)
+ vpu_trace(core->dev, "vpu core state change from %d to %d\n", core->state, state);
+ core->state = state;
+ if (core->state == VPU_CORE_DEINIT)
+ core->hang_mask = 0;
+}
+
+static void vpu_core_update_state(struct vpu_core *core)
+{
+ if (!vpu_iface_get_power_state(core)) {
+ if (core->request_count)
+ vpu_core_set_state(core, VPU_CORE_HANG);
+ else
+ vpu_core_set_state(core, VPU_CORE_DEINIT);
+
+ } else if (core->state == VPU_CORE_ACTIVE && core->hang_mask) {
+ vpu_core_set_state(core, VPU_CORE_HANG);
+ }
}
static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type)
@@ -188,11 +204,13 @@ static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 ty
dev_dbg(c->dev, "instance_mask = 0x%lx, state = %d\n", c->instance_mask, c->state);
if (c->type != type)
continue;
+ mutex_lock(&c->lock);
+ vpu_core_update_state(c);
+ mutex_unlock(&c->lock);
if (c->state == VPU_CORE_DEINIT) {
core = c;
break;
}
- vpu_core_check_hang(c);
if (c->state != VPU_CORE_ACTIVE)
continue;
if (c->request_count < request_count) {
@@ -409,6 +427,12 @@ int vpu_inst_register(struct vpu_inst *inst)
}
mutex_lock(&core->lock);
+ if (core->state != VPU_CORE_ACTIVE) {
+ dev_err(core->dev, "vpu core is not active, state = %d\n", core->state);
+ ret = -EINVAL;
+ goto exit;
+ }
+
if (inst->id >= 0 && inst->id < core->supported_instance_count)
goto exit;
@@ -450,7 +474,7 @@ int vpu_inst_unregister(struct vpu_inst *inst)
vpu_core_release_instance(core, inst->id);
inst->id = VPU_INST_NULL_ID;
}
- vpu_core_check_hang(core);
+ vpu_core_update_state(core);
if (core->state == VPU_CORE_HANG && !core->instance_mask) {
int err;
@@ -459,7 +483,7 @@ int vpu_inst_unregister(struct vpu_inst *inst)
err = vpu_core_sw_reset(core);
mutex_lock(&core->lock);
if (!err) {
- core->state = VPU_CORE_ACTIVE;
+ vpu_core_set_state(core, VPU_CORE_ACTIVE);
core->hang_mask = 0;
}
}
@@ -609,7 +633,7 @@ static int vpu_core_probe(struct platform_device *pdev)
mutex_init(&core->cmd_lock);
init_completion(&core->cmp);
init_waitqueue_head(&core->ack_wq);
- core->state = VPU_CORE_DEINIT;
+ vpu_core_set_state(core, VPU_CORE_DEINIT);
core->res = of_device_get_match_data(dev);
if (!core->res)
@@ -758,33 +782,18 @@ static int __maybe_unused vpu_core_resume(struct device *dev)
mutex_lock(&core->lock);
pm_runtime_resume_and_get(dev);
vpu_core_get_vpu(core);
- if (core->state != VPU_CORE_SNAPSHOT)
- goto exit;
- if (!vpu_iface_get_power_state(core)) {
- if (!list_empty(&core->instances)) {
+ if (core->request_count) {
+ if (!vpu_iface_get_power_state(core))
ret = vpu_core_boot(core, false);
- if (ret) {
- dev_err(core->dev, "%s boot fail\n", __func__);
- core->state = VPU_CORE_DEINIT;
- goto exit;
- }
- } else {
- core->state = VPU_CORE_DEINIT;
- }
- } else {
- if (!list_empty(&core->instances)) {
+ else
ret = vpu_core_sw_reset(core);
- if (ret) {
- dev_err(core->dev, "%s sw_reset fail\n", __func__);
- core->state = VPU_CORE_HANG;
- goto exit;
- }
+ if (ret) {
+ dev_err(core->dev, "resume fail\n");
+ vpu_core_set_state(core, VPU_CORE_HANG);
}
- core->state = VPU_CORE_ACTIVE;
}
-
-exit:
+ vpu_core_update_state(core);
pm_runtime_put_sync(dev);
mutex_unlock(&core->lock);
@@ -798,18 +807,11 @@ static int __maybe_unused vpu_core_suspend(struct device *dev)
int ret = 0;
mutex_lock(&core->lock);
- if (core->state == VPU_CORE_ACTIVE) {
- if (!list_empty(&core->instances)) {
- ret = vpu_core_snapshot(core);
- if (ret) {
- mutex_unlock(&core->lock);
- return ret;
- }
- }
-
- core->state = VPU_CORE_SNAPSHOT;
- }
+ if (core->request_count)
+ ret = vpu_core_snapshot(core);
mutex_unlock(&core->lock);
+ if (ret)
+ return ret;
vpu_core_cancel_work(core);
diff --git a/drivers/media/platform/amphion/vpu_core.h b/drivers/media/platform/amphion/vpu_core.h
index 00a662997da4..65b562642603 100644
--- a/drivers/media/platform/amphion/vpu_core.h
+++ b/drivers/media/platform/amphion/vpu_core.h
@@ -11,5 +11,6 @@ u32 csr_readl(struct vpu_core *core, u32 reg);
int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf);
void vpu_free_dma(struct vpu_buffer *buf);
struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index);
+void vpu_core_set_state(struct vpu_core *core, enum vpu_core_state state);
#endif
diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
index f72c8a506b22..260f1c4b8f8d 100644
--- a/drivers/media/platform/amphion/vpu_dbg.c
+++ b/drivers/media/platform/amphion/vpu_dbg.c
@@ -15,6 +15,7 @@
#include <linux/debugfs.h>
#include "vpu.h"
#include "vpu_defs.h"
+#include "vpu_core.h"
#include "vpu_helpers.h"
#include "vpu_cmds.h"
#include "vpu_rpc.h"
@@ -233,6 +234,10 @@ static int vpu_dbg_core(struct seq_file *s, void *data)
if (seq_write(s, str, num))
return 0;
+ num = scnprintf(str, sizeof(str), "power %s\n",
+ vpu_iface_get_power_state(core) ? "on" : "off");
+ if (seq_write(s, str, num))
+ return 0;
num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
if (seq_write(s, str, num))
return 0;
@@ -346,10 +351,10 @@ static ssize_t vpu_dbg_core_write(struct file *file,
pm_runtime_resume_and_get(core->dev);
mutex_lock(&core->lock);
- if (core->state != VPU_CORE_DEINIT && !core->instance_mask) {
+ if (vpu_iface_get_power_state(core) && !core->request_count) {
dev_info(core->dev, "reset\n");
if (!vpu_core_sw_reset(core)) {
- core->state = VPU_CORE_ACTIVE;
+ vpu_core_set_state(core, VPU_CORE_ACTIVE);
core->hang_mask = 0;
}
}
diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
index f4a488bf9880..51e0702f9ae1 100644
--- a/drivers/media/platform/amphion/vpu_malone.c
+++ b/drivers/media/platform/amphion/vpu_malone.c
@@ -1293,7 +1293,7 @@ static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode)
vbuf = to_vb2_v4l2_buffer(scode->vb);
data = vb2_plane_vaddr(scode->vb, 0);
- if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf))
+ if (scode->inst->total_input_count == 0 || vpu_vb_is_codecconfig(vbuf))
return 0;
if (MALONE_VC1_CONTAIN_NAL(*data))
return 0;
diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c
index 35145e3348f0..54270d6b6f50 100644
--- a/drivers/media/platform/intel/pxa_camera.c
+++ b/drivers/media/platform/intel/pxa_camera.c
@@ -854,7 +854,7 @@ fail:
return -ENOMEM;
}
-static void pxa_videobuf_set_actdma(struct pxa_camera_dev *pcdev,
+static void pxa_video_buf_set_actdma(struct pxa_camera_dev *pcdev,
struct pxa_buffer *buf)
{
buf->active_dma = DMA_Y;
@@ -973,7 +973,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
* stopped. This means the tailed buffer would never be transferred by DMA.
* This function restarts the capture for this corner case, where :
* - DADR() == DADDR_STOP
- * - a videobuffer is queued on the pcdev->capture list
+ * - a video buffer is queued on the pcdev->capture list
*
* Please check the "DMA hot chaining timeslice issue" in
* Documentation/driver-api/media/drivers/pxa_camera.rst
@@ -1163,7 +1163,7 @@ static void pxa_camera_eof(struct tasklet_struct *t)
pcdev->active = list_first_entry(&pcdev->capture,
struct pxa_buffer, queue);
buf = pcdev->active;
- pxa_videobuf_set_actdma(pcdev, buf);
+ pxa_video_buf_set_actdma(pcdev, buf);
pxa_dma_start_channels(pcdev);
}
@@ -1416,7 +1416,7 @@ static int pxac_vb2_prepare(struct vb2_buffer *vb)
* the actual buffer is yours
*/
buf->inwork = 0;
- pxa_videobuf_set_actdma(pcdev, buf);
+ pxa_video_buf_set_actdma(pcdev, buf);
return ret;
}
diff --git a/drivers/media/platform/marvell/mcam-core.h b/drivers/media/platform/marvell/mcam-core.h
index f324d808d737..51e66db45af6 100644
--- a/drivers/media/platform/marvell/mcam-core.h
+++ b/drivers/media/platform/marvell/mcam-core.h
@@ -32,7 +32,7 @@
#if !defined(MCAM_MODE_VMALLOC) && !defined(MCAM_MODE_DMA_CONTIG) && \
!defined(MCAM_MODE_DMA_SG)
-#error One of the videobuf buffer modes must be selected in the config
+#error One of the vb2 buffer modes must be selected in the config
#endif
diff --git a/drivers/media/platform/mediatek/Kconfig b/drivers/media/platform/mediatek/Kconfig
index af47d9888552..84104e2cd024 100644
--- a/drivers/media/platform/mediatek/Kconfig
+++ b/drivers/media/platform/mediatek/Kconfig
@@ -6,3 +6,4 @@ source "drivers/media/platform/mediatek/jpeg/Kconfig"
source "drivers/media/platform/mediatek/mdp/Kconfig"
source "drivers/media/platform/mediatek/vcodec/Kconfig"
source "drivers/media/platform/mediatek/vpu/Kconfig"
+source "drivers/media/platform/mediatek/mdp3/Kconfig"
diff --git a/drivers/media/platform/mediatek/Makefile b/drivers/media/platform/mediatek/Makefile
index d3850a13f128..38e6ba917fe5 100644
--- a/drivers/media/platform/mediatek/Makefile
+++ b/drivers/media/platform/mediatek/Makefile
@@ -3,3 +3,4 @@ obj-y += jpeg/
obj-y += mdp/
obj-y += vcodec/
obj-y += vpu/
+obj-y += mdp3/
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 87685a62a5c2..3071b61946c3 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1414,7 +1414,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
video_unregister_device(jpeg->vdev);
- video_device_release(jpeg->vdev);
v4l2_m2m_release(jpeg->m2m_dev);
v4l2_device_unregister(&jpeg->v4l2_dev);
diff --git a/drivers/media/platform/mediatek/mdp3/Kconfig b/drivers/media/platform/mediatek/mdp3/Kconfig
new file mode 100644
index 000000000000..50ae07b75b5f
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/Kconfig
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_MEDIATEK_MDP3
+ tristate "MediaTek MDP v3 driver"
+ depends on MTK_IOMMU || COMPILE_TEST
+ depends on VIDEO_DEV
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ depends on HAS_DMA
+ depends on REMOTEPROC
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ select MTK_MMSYS
+ select VIDEO_MEDIATEK_VPU
+ select MTK_CMDQ
+ select MTK_SCP
+ default n
+ help
+ It is a v4l2 driver and present in MediaTek MT8183 SoC.
+ The driver supports scaling and color space conversion.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mtk-mdp3.
diff --git a/drivers/media/platform/mediatek/mdp3/Makefile b/drivers/media/platform/mediatek/mdp3/Makefile
new file mode 100644
index 000000000000..63e6c87e480b
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+mtk-mdp3-y += mtk-mdp3-core.o mtk-mdp3-vpu.o mtk-mdp3-regs.o
+mtk-mdp3-y += mtk-mdp3-m2m.o
+mtk-mdp3-y += mtk-mdp3-comp.o mtk-mdp3-cmdq.o
+
+obj-$(CONFIG_VIDEO_MEDIATEK_MDP3) += mtk-mdp3.o
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_ccorr.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_ccorr.h
new file mode 100644
index 000000000000..3b2c6531c194
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_ccorr.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_CCORR_H__
+#define __MDP_REG_CCORR_H__
+
+#define MDP_CCORR_EN 0x000
+#define MDP_CCORR_CFG 0x020
+#define MDP_CCORR_SIZE 0x030
+
+/* MASK */
+#define MDP_CCORR_EN_MASK 0x00000001
+#define MDP_CCORR_CFG_MASK 0x70001317
+#define MDP_CCORR_SIZE_MASK 0x1fff1fff
+
+#endif // __MDP_REG_CCORR_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h
new file mode 100644
index 000000000000..be4065e252d3
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_rdma.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_RDMA_H__
+#define __MDP_REG_RDMA_H__
+
+#define MDP_RDMA_EN 0x000
+#define MDP_RDMA_RESET 0x008
+#define MDP_RDMA_CON 0x020
+#define MDP_RDMA_GMCIF_CON 0x028
+#define MDP_RDMA_SRC_CON 0x030
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE 0x060
+#define MDP_RDMA_MF_BKGD_SIZE_IN_PXL 0x068
+#define MDP_RDMA_MF_SRC_SIZE 0x070
+#define MDP_RDMA_MF_CLIP_SIZE 0x078
+#define MDP_RDMA_MF_OFFSET_1 0x080
+#define MDP_RDMA_SF_BKGD_SIZE_IN_BYTE 0x090
+#define MDP_RDMA_SRC_END_0 0x100
+#define MDP_RDMA_SRC_END_1 0x108
+#define MDP_RDMA_SRC_END_2 0x110
+#define MDP_RDMA_SRC_OFFSET_0 0x118
+#define MDP_RDMA_SRC_OFFSET_1 0x120
+#define MDP_RDMA_SRC_OFFSET_2 0x128
+#define MDP_RDMA_SRC_OFFSET_0_P 0x148
+#define MDP_RDMA_TRANSFORM_0 0x200
+#define MDP_RDMA_RESV_DUMMY_0 0x2a0
+#define MDP_RDMA_MON_STA_1 0x408
+#define MDP_RDMA_SRC_BASE_0 0xf00
+#define MDP_RDMA_SRC_BASE_1 0xf08
+#define MDP_RDMA_SRC_BASE_2 0xf10
+#define MDP_RDMA_UFO_DEC_LENGTH_BASE_Y 0xf20
+#define MDP_RDMA_UFO_DEC_LENGTH_BASE_C 0xf28
+
+/* MASK */
+#define MDP_RDMA_EN_MASK 0x00000001
+#define MDP_RDMA_RESET_MASK 0x00000001
+#define MDP_RDMA_CON_MASK 0x00001110
+#define MDP_RDMA_GMCIF_CON_MASK 0xfffb3771
+#define MDP_RDMA_SRC_CON_MASK 0xf3ffffff
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE_MASK 0x001fffff
+#define MDP_RDMA_MF_BKGD_SIZE_IN_PXL_MASK 0x001fffff
+#define MDP_RDMA_MF_SRC_SIZE_MASK 0x1fff1fff
+#define MDP_RDMA_MF_CLIP_SIZE_MASK 0x1fff1fff
+#define MDP_RDMA_MF_OFFSET_1_MASK 0x003f001f
+#define MDP_RDMA_SF_BKGD_SIZE_IN_BYTE_MASK 0x001fffff
+#define MDP_RDMA_SRC_END_0_MASK 0xffffffff
+#define MDP_RDMA_SRC_END_1_MASK 0xffffffff
+#define MDP_RDMA_SRC_END_2_MASK 0xffffffff
+#define MDP_RDMA_SRC_OFFSET_0_MASK 0xffffffff
+#define MDP_RDMA_SRC_OFFSET_1_MASK 0xffffffff
+#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_RESV_DUMMY_0_MASK 0xffffffff
+#define MDP_RDMA_MON_STA_1_MASK 0xffffffff
+#define MDP_RDMA_SRC_BASE_0_MASK 0xffffffff
+#define MDP_RDMA_SRC_BASE_1_MASK 0xffffffff
+#define MDP_RDMA_SRC_BASE_2_MASK 0xffffffff
+#define MDP_RDMA_UFO_DEC_LENGTH_BASE_Y_MASK 0xffffffff
+#define MDP_RDMA_UFO_DEC_LENGTH_BASE_C_MASK 0xffffffff
+
+#endif // __MDP_REG_RDMA_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h
new file mode 100644
index 000000000000..484f6d60641f
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_rsz.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_RSZ_H__
+#define __MDP_REG_RSZ_H__
+
+#define PRZ_ENABLE 0x000
+#define PRZ_CONTROL_1 0x004
+#define PRZ_CONTROL_2 0x008
+#define PRZ_INPUT_IMAGE 0x010
+#define PRZ_OUTPUT_IMAGE 0x014
+#define PRZ_HORIZONTAL_COEFF_STEP 0x018
+#define PRZ_VERTICAL_COEFF_STEP 0x01c
+#define PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET 0x020
+#define PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET 0x024
+#define PRZ_LUMA_VERTICAL_INTEGER_OFFSET 0x028
+#define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET 0x02c
+#define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET 0x030
+#define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET 0x034
+
+/* MASK */
+#define PRZ_ENABLE_MASK 0x00010001
+#define PRZ_CONTROL_1_MASK 0xfffffff3
+#define PRZ_CONTROL_2_MASK 0x0ffffaff
+#define PRZ_INPUT_IMAGE_MASK 0xffffffff
+#define PRZ_OUTPUT_IMAGE_MASK 0xffffffff
+#define PRZ_HORIZONTAL_COEFF_STEP_MASK 0x007fffff
+#define PRZ_VERTICAL_COEFF_STEP_MASK 0x007fffff
+#define PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET_MASK 0x0000ffff
+#define PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET_MASK 0x001fffff
+#define PRZ_LUMA_VERTICAL_INTEGER_OFFSET_MASK 0x0000ffff
+#define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET_MASK 0x001fffff
+#define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET_MASK 0x0000ffff
+#define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET_MASK 0x001fffff
+
+#endif // __MDP_REG_RSZ_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_wdma.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_wdma.h
new file mode 100644
index 000000000000..0280e91c09e4
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_wdma.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_WDMA_H__
+#define __MDP_REG_WDMA_H__
+
+#define WDMA_EN 0x008
+#define WDMA_RST 0x00c
+#define WDMA_CFG 0x014
+#define WDMA_SRC_SIZE 0x018
+#define WDMA_CLIP_SIZE 0x01c
+#define WDMA_CLIP_COORD 0x020
+#define WDMA_DST_W_IN_BYTE 0x028
+#define WDMA_ALPHA 0x02c
+#define WDMA_BUF_CON2 0x03c
+#define WDMA_DST_UV_PITCH 0x078
+#define WDMA_DST_ADDR_OFFSET 0x080
+#define WDMA_DST_U_ADDR_OFFSET 0x084
+#define WDMA_DST_V_ADDR_OFFSET 0x088
+#define WDMA_FLOW_CTRL_DBG 0x0a0
+#define WDMA_DST_ADDR 0xf00
+#define WDMA_DST_U_ADDR 0xf04
+#define WDMA_DST_V_ADDR 0xf08
+
+/* MASK */
+#define WDMA_EN_MASK 0x00000001
+#define WDMA_RST_MASK 0x00000001
+#define WDMA_CFG_MASK 0xff03bff0
+#define WDMA_SRC_SIZE_MASK 0x3fff3fff
+#define WDMA_CLIP_SIZE_MASK 0x3fff3fff
+#define WDMA_CLIP_COORD_MASK 0x3fff3fff
+#define WDMA_DST_W_IN_BYTE_MASK 0x0000ffff
+#define WDMA_ALPHA_MASK 0x800000ff
+#define WDMA_BUF_CON2_MASK 0xffffffff
+#define WDMA_DST_UV_PITCH_MASK 0x0000ffff
+#define WDMA_DST_ADDR_OFFSET_MASK 0x0fffffff
+#define WDMA_DST_U_ADDR_OFFSET_MASK 0x0fffffff
+#define WDMA_DST_V_ADDR_OFFSET_MASK 0x0fffffff
+#define WDMA_FLOW_CTRL_DBG_MASK 0x0000f3ff
+#define WDMA_DST_ADDR_MASK 0xffffffff
+#define WDMA_DST_U_ADDR_MASK 0xffffffff
+#define WDMA_DST_V_ADDR_MASK 0xffffffff
+
+#endif // __MDP_REG_WDMA_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h b/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h
new file mode 100644
index 000000000000..6d3ff0e2b672
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mdp_reg_wrot.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MDP_REG_WROT_H__
+#define __MDP_REG_WROT_H__
+
+#define VIDO_CTRL 0x000
+#define VIDO_MAIN_BUF_SIZE 0x008
+#define VIDO_SOFT_RST 0x010
+#define VIDO_SOFT_RST_STAT 0x014
+#define VIDO_CROP_OFST 0x020
+#define VIDO_TAR_SIZE 0x024
+#define VIDO_OFST_ADDR 0x02c
+#define VIDO_STRIDE 0x030
+#define VIDO_OFST_ADDR_C 0x038
+#define VIDO_STRIDE_C 0x03c
+#define VIDO_DITHER 0x054
+#define VIDO_STRIDE_V 0x06c
+#define VIDO_OFST_ADDR_V 0x068
+#define VIDO_RSV_1 0x070
+#define VIDO_IN_SIZE 0x078
+#define VIDO_ROT_EN 0x07c
+#define VIDO_FIFO_TEST 0x080
+#define VIDO_MAT_CTRL 0x084
+#define VIDO_BASE_ADDR 0xf00
+#define VIDO_BASE_ADDR_C 0xf04
+#define VIDO_BASE_ADDR_V 0xf08
+
+/* MASK */
+#define VIDO_CTRL_MASK 0xf530711f
+#define VIDO_MAIN_BUF_SIZE_MASK 0x1fff7f77
+#define VIDO_SOFT_RST_MASK 0x00000001
+#define VIDO_SOFT_RST_STAT_MASK 0x00000001
+#define VIDO_TAR_SIZE_MASK 0x1fff1fff
+#define VIDO_CROP_OFST_MASK 0x1fff1fff
+#define VIDO_OFST_ADDR_MASK 0x0fffffff
+#define VIDO_STRIDE_MASK 0x0000ffff
+#define VIDO_OFST_ADDR_C_MASK 0x0fffffff
+#define VIDO_STRIDE_C_MASK 0x0000ffff
+#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_IN_SIZE_MASK 0x1fff1fff
+#define VIDO_ROT_EN_MASK 0x00000001
+#define VIDO_FIFO_TEST_MASK 0x00000fff
+#define VIDO_MAT_CTRL_MASK 0x000000f3
+#define VIDO_BASE_ADDR_MASK 0xffffffff
+#define VIDO_BASE_ADDR_C_MASK 0xffffffff
+#define VIDO_BASE_ADDR_V_MASK 0xffffffff
+
+#endif // __MDP_REG_WROT_H__
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h
new file mode 100644
index 000000000000..3e66ebaee2da
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h
@@ -0,0 +1,290 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Holmes Chiou <holmes.chiou@mediatek.com>
+ * Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MTK_IMG_IPI_H__
+#define __MTK_IMG_IPI_H__
+
+#include <linux/types.h>
+
+/*
+ * ISP-MDP generic input information
+ * MD5 of the target SCP blob:
+ * 6da52bdcf4bf76a0983b313e1d4745d6
+ */
+
+#define IMG_MAX_HW_INPUTS 3
+
+#define IMG_MAX_HW_OUTPUTS 4
+
+#define IMG_MAX_PLANES 3
+
+#define IMG_IPI_INIT 1
+#define IMG_IPI_DEINIT 2
+#define IMG_IPI_FRAME 3
+#define IMG_IPI_DEBUG 4
+
+struct img_timeval {
+ u32 tv_sec;
+ u32 tv_usec;
+} __packed;
+
+struct img_addr {
+ u64 va; /* Used for Linux OS access */
+ u32 pa; /* Used for CM4 access */
+ u32 iova; /* Used for IOMMU HW access */
+} __packed;
+
+struct tuning_addr {
+ u64 present;
+ u32 pa; /* Used for CM4 access */
+ u32 iova; /* Used for IOMMU HW access */
+} __packed;
+
+struct img_sw_addr {
+ u64 va; /* Used for APMCU access */
+ u32 pa; /* Used for CM4 access */
+} __packed;
+
+struct img_plane_format {
+ u32 size;
+ u16 stride;
+} __packed;
+
+struct img_pix_format {
+ u16 width;
+ u16 height;
+ u32 colorformat; /* enum mdp_color */
+ u16 ycbcr_prof; /* enum mdp_ycbcr_profile */
+ struct img_plane_format plane_fmt[IMG_MAX_PLANES];
+} __packed;
+
+struct img_image_buffer {
+ struct img_pix_format format;
+ u32 iova[IMG_MAX_PLANES];
+ /* enum mdp_buffer_usage, FD or advanced ISP usages */
+ u32 usage;
+} __packed;
+
+#define IMG_SUBPIXEL_SHIFT 20
+
+struct img_crop {
+ s16 left;
+ s16 top;
+ u16 width;
+ u16 height;
+ u32 left_subpix;
+ u32 top_subpix;
+ u32 width_subpix;
+ u32 height_subpix;
+} __packed;
+
+#define IMG_CTRL_FLAG_HFLIP BIT(0)
+#define IMG_CTRL_FLAG_DITHER BIT(1)
+#define IMG_CTRL_FLAG_SHARPNESS BIT(4)
+#define IMG_CTRL_FLAG_HDR BIT(5)
+#define IMG_CTRL_FLAG_DRE BIT(6)
+
+struct img_input {
+ struct img_image_buffer buffer;
+ u16 flags; /* HDR, DRE, dither */
+} __packed;
+
+struct img_output {
+ struct img_image_buffer buffer;
+ struct img_crop crop;
+ s16 rotation;
+ u16 flags; /* H-flip, sharpness, dither */
+} __packed;
+
+struct img_ipi_frameparam {
+ u32 index;
+ u32 frame_no;
+ struct img_timeval timestamp;
+ u8 type; /* enum mdp_stream_type */
+ u8 state;
+ u8 num_inputs;
+ u8 num_outputs;
+ u64 drv_data;
+ struct img_input inputs[IMG_MAX_HW_INPUTS];
+ struct img_output outputs[IMG_MAX_HW_OUTPUTS];
+ struct tuning_addr tuning_data;
+ struct img_addr subfrm_data;
+ struct img_sw_addr config_data;
+ struct img_sw_addr self_data;
+} __packed;
+
+struct img_sw_buffer {
+ u64 handle; /* Used for APMCU access */
+ u32 scp_addr; /* Used for CM4 access */
+} __packed;
+
+struct img_ipi_param {
+ u8 usage;
+ struct img_sw_buffer frm_param;
+} __packed;
+
+struct img_frameparam {
+ struct list_head list_entry;
+ struct img_ipi_frameparam frameparam;
+};
+
+/* ISP-MDP generic output information */
+
+struct img_comp_frame {
+ u32 output_disable:1;
+ u32 bypass:1;
+ u16 in_width;
+ u16 in_height;
+ u16 out_width;
+ u16 out_height;
+ struct img_crop crop;
+ u16 in_total_width;
+ u16 out_total_width;
+} __packed;
+
+struct img_region {
+ s16 left;
+ s16 right;
+ s16 top;
+ s16 bottom;
+} __packed;
+
+struct img_offset {
+ s16 left;
+ s16 top;
+ u32 left_subpix;
+ u32 top_subpix;
+} __packed;
+
+struct img_comp_subfrm {
+ u32 tile_disable:1;
+ struct img_region in;
+ struct img_region out;
+ struct img_offset luma;
+ struct img_offset chroma;
+ s16 out_vertical; /* Output vertical index */
+ s16 out_horizontal; /* Output horizontal index */
+} __packed;
+
+#define IMG_MAX_SUBFRAMES 14
+
+struct mdp_rdma_subfrm {
+ u32 offset[IMG_MAX_PLANES];
+ u32 offset_0_p;
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+} __packed;
+
+struct mdp_rdma_data {
+ u32 src_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;
+ struct mdp_rdma_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_rsz_subfrm {
+ u32 control2;
+ u32 src;
+ u32 clip;
+} __packed;
+
+struct mdp_rsz_data {
+ u32 coeff_step_x;
+ u32 coeff_step_y;
+ u32 control1;
+ u32 control2;
+ struct mdp_rsz_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_wrot_subfrm {
+ u32 offset[IMG_MAX_PLANES];
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+ u32 main_buf;
+} __packed;
+
+struct mdp_wrot_data {
+ u32 iova[IMG_MAX_PLANES];
+ u32 control;
+ u32 stride[IMG_MAX_PLANES];
+ u32 mat_ctrl;
+ u32 fifo_test;
+ u32 filter;
+ struct mdp_wrot_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_wdma_subfrm {
+ u32 offset[IMG_MAX_PLANES];
+ u32 src;
+ u32 clip;
+ u32 clip_ofst;
+} __packed;
+
+struct mdp_wdma_data {
+ u32 wdma_cfg;
+ u32 iova[IMG_MAX_PLANES];
+ u32 w_in_byte;
+ u32 uv_stride;
+ struct mdp_wdma_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct isp_data {
+ u64 dl_flags; /* 1 << (enum mdp_comp_type) */
+ u32 smxi_iova[4];
+ u32 cq_idx;
+ u32 cq_iova;
+ u32 tpipe_iova[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct img_compparam {
+ u16 type; /* enum mdp_comp_type */
+ u16 id; /* enum mtk_mdp_comp_id */
+ u32 input;
+ u32 outputs[IMG_MAX_HW_OUTPUTS];
+ u32 num_outputs;
+ struct img_comp_frame frame;
+ struct img_comp_subfrm subfrms[IMG_MAX_SUBFRAMES];
+ u32 num_subfrms;
+ union {
+ struct mdp_rdma_data rdma;
+ struct mdp_rsz_data rsz;
+ struct mdp_wrot_data wrot;
+ struct mdp_wdma_data wdma;
+ struct isp_data isp;
+ };
+} __packed;
+
+#define IMG_MAX_COMPONENTS 20
+
+struct img_mux {
+ u32 reg;
+ u32 value;
+ u32 subsys_id;
+};
+
+struct img_mmsys_ctrl {
+ struct img_mux sets[IMG_MAX_COMPONENTS * 2];
+ u32 num_sets;
+};
+
+struct img_config {
+ struct img_compparam components[IMG_MAX_COMPONENTS];
+ u32 num_components;
+ struct img_mmsys_ctrl ctrls[IMG_MAX_SUBFRAMES];
+ u32 num_subfrms;
+} __packed;
+
+#endif /* __MTK_IMG_IPI_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
new file mode 100644
index 000000000000..29f6c1cd3de7
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -0,0 +1,466 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#include <linux/mailbox_controller.h>
+#include <linux/platform_device.h>
+#include "mtk-mdp3-cmdq.h"
+#include "mtk-mdp3-comp.h"
+#include "mtk-mdp3-core.h"
+#include "mtk-mdp3-m2m.h"
+
+#define MDP_PATH_MAX_COMPS IMG_MAX_COMPONENTS
+
+struct mdp_path {
+ struct mdp_dev *mdp_dev;
+ struct mdp_comp_ctx comps[MDP_PATH_MAX_COMPS];
+ u32 num_comps;
+ const struct img_config *config;
+ const struct img_ipi_frameparam *param;
+ const struct v4l2_rect *composes[IMG_MAX_HW_OUTPUTS];
+ struct v4l2_rect bounds[IMG_MAX_HW_OUTPUTS];
+};
+
+#define has_op(ctx, op) \
+ ((ctx)->comp->ops && (ctx)->comp->ops->op)
+ #define call_op(ctx, op, ...) \
+ (has_op(ctx, op) ? (ctx)->comp->ops->op(ctx, ##__VA_ARGS__) : 0)
+
+static bool is_output_disabled(const struct img_compparam *param, u32 count)
+{
+ return (count < param->num_subfrms) ?
+ (param->frame.output_disable ||
+ param->subfrms[count].tile_disable) :
+ true;
+}
+
+static int mdp_path_subfrm_require(const struct mdp_path *path,
+ struct mdp_cmdq_cmd *cmd,
+ s32 *mutex_id, u32 count)
+{
+ const struct img_config *config = path->config;
+ 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;
+
+ /* Decide which mutex to use based on the current pipeline */
+ switch (path->comps[0].comp->id) {
+ case MDP_COMP_RDMA0:
+ *mutex_id = MDP_PIPE_RDMA0;
+ break;
+ case MDP_COMP_ISP_IMGI:
+ *mutex_id = MDP_PIPE_IMGI;
+ break;
+ case MDP_COMP_WPEI:
+ *mutex_id = MDP_PIPE_WPEI;
+ break;
+ case MDP_COMP_WPEI2:
+ *mutex_id = MDP_PIPE_WPEI2;
+ break;
+ default:
+ dev_err(dev, "Unknown pipeline and no mutex is assigned");
+ return -EINVAL;
+ }
+
+ /* Set mutex mod */
+ for (index = 0; index < config->num_components; index++) {
+ ctx = &path->comps[index];
+ if (is_output_disabled(ctx->param, count))
+ continue;
+ id = ctx->comp->id;
+ mtk_mutex_write_mod(mutex[*mutex_id],
+ data->mdp_mutex_table_idx[id], false);
+ }
+
+ mtk_mutex_write_sof(mutex[*mutex_id],
+ 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)
+{
+ const struct img_config *config = path->config;
+ const struct mdp_comp_ctx *ctx;
+ struct device *dev = &path->mdp_dev->pdev->dev;
+ struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
+ int index;
+ s32 event;
+
+ if (-1 == *mutex_id) {
+ dev_err(dev, "Incorrect mutex id");
+ return -EINVAL;
+ }
+
+ /* Wait WROT SRAM shared to DISP RDMA */
+ /* Clear SOF event for each engine */
+ for (index = 0; index < config->num_components; index++) {
+ ctx = &path->comps[index];
+ if (is_output_disabled(ctx->param, count))
+ continue;
+ event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
+ if (event != MDP_GCE_NO_EVENT)
+ MM_REG_CLEAR(cmd, event);
+ }
+
+ /* Enable the mutex */
+ mtk_mutex_enable_by_cmdq(mutex[*mutex_id], (void *)&cmd->pkt);
+
+ /* Wait SOF events and clear mutex modules (optional) */
+ for (index = 0; index < config->num_components; index++) {
+ ctx = &path->comps[index];
+ if (is_output_disabled(ctx->param, count))
+ continue;
+ event = ctx->comp->gce_event[MDP_GCE_EVENT_SOF];
+ if (event != MDP_GCE_NO_EVENT)
+ MM_REG_WAIT(cmd, event);
+ }
+
+ return 0;
+}
+
+static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
+{
+ const struct img_config *config = path->config;
+ int index, ret;
+
+ if (config->num_components < 1)
+ return -EINVAL;
+
+ for (index = 0; index < config->num_components; index++) {
+ ret = mdp_comp_ctx_config(mdp, &path->comps[index],
+ &config->components[index],
+ path->param);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
+ struct mdp_path *path, u32 count)
+{
+ const struct img_config *config = path->config;
+ const struct img_mmsys_ctrl *ctrl = &config->ctrls[count];
+ const struct img_mux *set;
+ struct mdp_comp_ctx *ctx;
+ s32 mutex_id;
+ int index, ret;
+
+ /* Acquire components */
+ ret = mdp_path_subfrm_require(path, cmd, &mutex_id, count);
+ if (ret)
+ return ret;
+ /* Enable mux settings */
+ for (index = 0; index < ctrl->num_sets; index++) {
+ set = &ctrl->sets[index];
+ cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
+ set->value, 0xFFFFFFFF);
+ }
+ /* Config sub-frame information */
+ for (index = (config->num_components - 1); index >= 0; index--) {
+ ctx = &path->comps[index];
+ if (is_output_disabled(ctx->param, count))
+ continue;
+ ret = call_op(ctx, config_subfrm, cmd, count);
+ if (ret)
+ return ret;
+ }
+ /* Run components */
+ ret = mdp_path_subfrm_run(path, cmd, &mutex_id, count);
+ if (ret)
+ return ret;
+ /* Wait components done */
+ for (index = 0; index < config->num_components; index++) {
+ ctx = &path->comps[index];
+ if (is_output_disabled(ctx->param, count))
+ continue;
+ ret = call_op(ctx, wait_comp_event, cmd);
+ if (ret)
+ return ret;
+ }
+ /* Advance to the next sub-frame */
+ for (index = 0; index < config->num_components; index++) {
+ ctx = &path->comps[index];
+ ret = call_op(ctx, advance_subfrm, cmd, count);
+ if (ret)
+ return ret;
+ }
+ /* Disable mux settings */
+ for (index = 0; index < ctrl->num_sets; index++) {
+ set = &ctrl->sets[index];
+ cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg,
+ 0, 0xFFFFFFFF);
+ }
+
+ return 0;
+}
+
+static int mdp_path_config(struct mdp_dev *mdp, struct mdp_cmdq_cmd *cmd,
+ struct mdp_path *path)
+{
+ const struct img_config *config = path->config;
+ struct mdp_comp_ctx *ctx;
+ int index, count, ret;
+
+ /* Config path frame */
+ /* Reset components */
+ for (index = 0; index < config->num_components; index++) {
+ ctx = &path->comps[index];
+ ret = call_op(ctx, init_comp, cmd);
+ if (ret)
+ return ret;
+ }
+ /* Config frame mode */
+ for (index = 0; index < config->num_components; index++) {
+ const struct v4l2_rect *compose =
+ path->composes[ctx->param->outputs[0]];
+
+ ctx = &path->comps[index];
+ ret = call_op(ctx, config_frame, cmd, compose);
+ if (ret)
+ return ret;
+ }
+
+ /* Config path sub-frames */
+ for (count = 0; count < config->num_subfrms; count++) {
+ ret = mdp_path_config_subfrm(cmd, path, count);
+ if (ret)
+ return ret;
+ }
+ /* Post processing information */
+ for (index = 0; index < config->num_components; index++) {
+ ctx = &path->comps[index];
+ ret = call_op(ctx, post_process, cmd);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
+ size_t size)
+{
+ struct device *dev;
+ dma_addr_t dma_addr;
+
+ pkt->va_base = kzalloc(size, GFP_KERNEL);
+ if (!pkt->va_base) {
+ kfree(pkt);
+ return -ENOMEM;
+ }
+ pkt->buf_size = size;
+ pkt->cl = (void *)client;
+
+ dev = client->chan->mbox->dev;
+ dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, dma_addr)) {
+ dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+ kfree(pkt->va_base);
+ return -ENOMEM;
+ }
+
+ pkt->pa_base = dma_addr;
+
+ return 0;
+}
+
+static void mdp_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+{
+ struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
+
+ dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
+ DMA_TO_DEVICE);
+ kfree(pkt->va_base);
+ pkt->va_base = NULL;
+}
+
+static void mdp_auto_release_work(struct work_struct *work)
+{
+ struct mdp_cmdq_cmd *cmd;
+ struct mdp_dev *mdp;
+
+ cmd = container_of(work, struct mdp_cmdq_cmd, auto_release_work);
+ mdp = cmd->mdp;
+
+ mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+ mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
+ cmd->num_comps);
+
+ atomic_dec(&mdp->job_count);
+ wake_up(&mdp->callback_wq);
+
+ mdp_cmdq_pkt_destroy(&cmd->pkt);
+ kfree(cmd->comps);
+ cmd->comps = NULL;
+ kfree(cmd);
+ cmd = NULL;
+}
+
+static void mdp_handle_cmdq_callback(struct mbox_client *cl, void *mssg)
+{
+ struct mdp_cmdq_cmd *cmd;
+ struct cmdq_cb_data *data;
+ struct mdp_dev *mdp;
+ struct device *dev;
+
+ if (!mssg) {
+ pr_info("%s:no callback data\n", __func__);
+ return;
+ }
+
+ data = (struct cmdq_cb_data *)mssg;
+ cmd = container_of(data->pkt, struct mdp_cmdq_cmd, pkt);
+ 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)) {
+ dev_err(dev, "%s:queue_work fail!\n", __func__);
+ mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+ mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
+ cmd->num_comps);
+
+ atomic_dec(&mdp->job_count);
+ wake_up(&mdp->callback_wq);
+
+ mdp_cmdq_pkt_destroy(&cmd->pkt);
+ kfree(cmd->comps);
+ cmd->comps = NULL;
+ kfree(cmd);
+ cmd = NULL;
+ }
+}
+
+int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
+{
+ struct mdp_path *path = NULL;
+ struct mdp_cmdq_cmd *cmd = NULL;
+ struct mdp_comp *comps = NULL;
+ struct device *dev = &mdp->pdev->dev;
+ int i, ret;
+
+ atomic_inc(&mdp->job_count);
+ if (atomic_read(&mdp->suspended)) {
+ atomic_dec(&mdp->job_count);
+ return -ECANCELED;
+ }
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd) {
+ ret = -ENOMEM;
+ goto err_cmdq_data;
+ }
+
+ if (mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K)) {
+ ret = -ENOMEM;
+ goto err_cmdq_data;
+ }
+
+ comps = kcalloc(param->config->num_components, sizeof(*comps),
+ GFP_KERNEL);
+ if (!comps) {
+ ret = -ENOMEM;
+ goto err_cmdq_data;
+ }
+
+ path = kzalloc(sizeof(*path), GFP_KERNEL);
+ if (!path) {
+ ret = -ENOMEM;
+ goto err_cmdq_data;
+ }
+
+ path->mdp_dev = mdp;
+ path->config = param->config;
+ path->param = param->param;
+ for (i = 0; i < param->param->num_outputs; i++) {
+ path->bounds[i].left = 0;
+ path->bounds[i].top = 0;
+ path->bounds[i].width =
+ param->param->outputs[i].buffer.format.width;
+ path->bounds[i].height =
+ param->param->outputs[i].buffer.format.height;
+ path->composes[i] = param->composes[i] ?
+ param->composes[i] : &path->bounds[i];
+ }
+
+ ret = mdp_path_ctx_init(mdp, path);
+ if (ret) {
+ dev_err(dev, "mdp_path_ctx_init error\n");
+ goto err_cmdq_data;
+ }
+
+ mtk_mutex_prepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+
+ ret = mdp_path_config(mdp, cmd, path);
+ if (ret) {
+ dev_err(dev, "mdp_path_config error\n");
+ goto err_cmdq_data;
+ }
+ cmdq_pkt_finalize(&cmd->pkt);
+
+ for (i = 0; i < param->config->num_components; i++)
+ memcpy(&comps[i], path->comps[i].comp,
+ sizeof(struct mdp_comp));
+
+ mdp->cmdq_clt->client.rx_callback = mdp_handle_cmdq_callback;
+ cmd->mdp = mdp;
+ cmd->user_cmdq_cb = param->cmdq_cb;
+ cmd->user_cb_data = param->cb_data;
+ cmd->comps = comps;
+ cmd->num_comps = param->config->num_components;
+ cmd->mdp_ctx = param->mdp_ctx;
+
+ ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps);
+ if (ret) {
+ dev_err(dev, "comp %d failed to enable clock!\n", ret);
+ goto err_clock_off;
+ }
+
+ 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;
+
+err_clock_off:
+ mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+ mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
+ cmd->num_comps);
+err_cmdq_data:
+ kfree(path);
+ atomic_dec(&mdp->job_count);
+ wake_up(&mdp->callback_wq);
+ if (cmd->pkt.buf_size > 0)
+ mdp_cmdq_pkt_destroy(&cmd->pkt);
+ kfree(comps);
+ kfree(cmd);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mdp_cmdq_send);
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h
new file mode 100644
index 000000000000..43475b862ddb
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MTK_MDP3_CMDQ_H__
+#define __MTK_MDP3_CMDQ_H__
+
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+#include "mtk-img-ipi.h"
+
+struct platform_device *mdp_get_plat_device(struct platform_device *pdev);
+
+struct mdp_cmdq_param {
+ struct img_config *config;
+ struct img_ipi_frameparam *param;
+ const struct v4l2_rect *composes[IMG_MAX_HW_OUTPUTS];
+
+ void (*cmdq_cb)(struct cmdq_cb_data data);
+ void *cb_data;
+ void *mdp_ctx;
+};
+
+struct mdp_cmdq_cmd {
+ struct work_struct auto_release_work;
+ struct cmdq_pkt pkt;
+ s32 *event;
+ struct mdp_dev *mdp;
+ void (*user_cmdq_cb)(struct cmdq_cb_data data);
+ void *user_cb_data;
+ struct mdp_comp *comps;
+ void *mdp_ctx;
+ u8 num_comps;
+};
+
+struct mdp_dev;
+
+int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param);
+
+#endif /* __MTK_MDP3_CMDQ_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
new file mode 100644
index 000000000000..e62abf3587bf
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
@@ -0,0 +1,1033 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/pm_runtime.h>
+#include "mtk-mdp3-comp.h"
+#include "mtk-mdp3-core.h"
+#include "mtk-mdp3-regs.h"
+
+#include "mdp_reg_rdma.h"
+#include "mdp_reg_ccorr.h"
+#include "mdp_reg_rsz.h"
+#include "mdp_reg_wrot.h"
+#include "mdp_reg_wdma.h"
+
+static u32 mdp_comp_alias_id[MDP_COMP_TYPE_COUNT];
+
+static inline const struct mdp_platform_config *
+__get_plat_cfg(const struct mdp_comp_ctx *ctx)
+{
+ if (!ctx)
+ return NULL;
+
+ return ctx->comp->mdp_dev->mdp_data->mdp_cfg;
+}
+
+static s64 get_comp_flag(const struct mdp_comp_ctx *ctx)
+{
+ const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+
+ if (mdp_cfg && mdp_cfg->rdma_rsz1_sram_sharing)
+ if (ctx->comp->id == MDP_COMP_RDMA0)
+ return BIT(MDP_COMP_RDMA0) | BIT(MDP_COMP_RSZ1);
+
+ return BIT(ctx->comp->id);
+}
+
+static int init_rdma(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;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
+ struct mdp_comp *prz1 = ctx->comp->mdp_dev->comp[MDP_COMP_RSZ1];
+
+ /* Disable RSZ1 */
+ if (ctx->comp->id == MDP_COMP_RDMA0 && prz1)
+ MM_REG_WRITE(cmd, subsys_id, prz1->reg_base, PRZ_ENABLE,
+ 0x0, BIT(0));
+ }
+
+ /* Reset RDMA */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0));
+ MM_REG_POLL(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8));
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0));
+ return 0;
+}
+
+static int config_rdma_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ const struct mdp_rdma_data *rdma = &ctx->param->rdma;
+ const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+ u32 colorformat = ctx->input->buffer.format.colorformat;
+ bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
+ bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
+ if (block10bit)
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7);
+ else
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7);
+ }
+
+ /* Setup smi control */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON,
+ (7 << 4) + //burst type to 8
+ (1 << 16), //enable pre-ultra
+ 0x00030071);
+
+ /* Setup source frame info */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, rdma->src_ctrl,
+ 0x03C8FE0F);
+
+ if (mdp_cfg)
+ if (mdp_cfg->rdma_support_10bit && en_ufo) {
+ /* Setup source buffer base */
+ MM_REG_WRITE(cmd, subsys_id,
+ base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y,
+ rdma->ufo_dec_y, 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id,
+ base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C,
+ rdma->ufo_dec_c, 0xFFFFFFFF);
+ /* Set 10bit source frame pitch */
+ if (block10bit)
+ MM_REG_WRITE(cmd, subsys_id,
+ base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL,
+ rdma->mf_bkgd_in_pxl, 0x001FFFFF);
+ }
+
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, rdma->control,
+ 0x1110);
+ /* Setup source buffer base */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, rdma->iova[0],
+ 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, rdma->iova[1],
+ 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, rdma->iova[2],
+ 0xFFFFFFFF);
+ /* Setup source buffer end */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0,
+ rdma->iova_end[0], 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1,
+ rdma->iova_end[1], 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2,
+ rdma->iova_end[2], 0xFFFFFFFF);
+ /* Setup source frame pitch */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
+ rdma->mf_bkgd, 0x001FFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE,
+ rdma->sf_bkgd, 0x001FFFFF);
+ /* Setup color transform */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0,
+ rdma->transform, 0x0F110000);
+
+ return 0;
+}
+
+static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ const struct mdp_rdma_subfrm *subfrm = &ctx->param->rdma.subfrms[index];
+ const struct img_comp_subfrm *csf = &ctx->param->subfrms[index];
+ const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+ u32 colorformat = ctx->input->buffer.format.colorformat;
+ bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
+ bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ /* Enable RDMA */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0));
+
+ /* Set Y pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0,
+ subfrm->offset[0], 0xFFFFFFFF);
+
+ /* Set 10bit UFO mode */
+ if (mdp_cfg)
+ if (mdp_cfg->rdma_support_10bit && block10bit && en_ufo)
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_RDMA_SRC_OFFSET_0_P,
+ subfrm->offset_0_p, 0xFFFFFFFF);
+
+ /* Set U pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1,
+ subfrm->offset[1], 0xFFFFFFFF);
+ /* Set V pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2,
+ subfrm->offset[2], 0xFFFFFFFF);
+ /* Set source size */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, subfrm->src,
+ 0x1FFF1FFF);
+ /* Set target size */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE,
+ subfrm->clip, 0x1FFF1FFF);
+ /* Set crop offset */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1,
+ subfrm->clip_ofst, 0x003F001F);
+
+ if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only)
+ if ((csf->in.right - csf->in.left + 1) > 320)
+ MM_REG_WRITE(cmd, subsys_id, base,
+ MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2));
+
+ return 0;
+}
+
+static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd)
+{
+ 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");
+
+ /* Disable RDMA */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
+ return 0;
+}
+
+static const struct mdp_comp_ops rdma_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_rdma,
+ .config_frame = config_rdma_frame,
+ .config_subfrm = config_rdma_subfrm,
+ .wait_comp_event = wait_rdma_event,
+};
+
+static int init_rsz(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;
+
+ /* Reset RSZ */
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16));
+ 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));
+ return 0;
+}
+
+static int config_rsz_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ const struct mdp_rsz_data *rsz = &ctx->param->rsz;
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ if (ctx->param->frame.bypass) {
+ /* Disable RSZ */
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0));
+ return 0;
+ }
+
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, rsz->control1,
+ 0x03FFFDF3);
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, rsz->control2,
+ 0x0FFFC290);
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP,
+ rsz->coeff_step_x, 0x007FFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP,
+ rsz->coeff_step_y, 0x007FFFFF);
+ return 0;
+}
+
+static int config_rsz_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ const struct mdp_rsz_subfrm *subfrm = &ctx->param->rsz.subfrms[index];
+ const struct img_comp_subfrm *csf = &ctx->param->subfrms[index];
+ 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;
+
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, subfrm->control2,
+ 0x00003800);
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, subfrm->src,
+ 0xFFFFFFFF);
+
+ if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample)
+ if ((csf->in.right - csf->in.left + 1) <= 16)
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1,
+ BIT(27), BIT(27));
+
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET,
+ csf->luma.left, 0xFFFF);
+ MM_REG_WRITE(cmd, subsys_id,
+ base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET,
+ csf->luma.left_subpix, 0x1FFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET,
+ csf->luma.top, 0xFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET,
+ csf->luma.top_subpix, 0x1FFFFF);
+ MM_REG_WRITE(cmd, subsys_id,
+ base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET,
+ csf->chroma.left, 0xFFFF);
+ MM_REG_WRITE(cmd, subsys_id,
+ base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET,
+ csf->chroma.left_subpix, 0x1FFFFF);
+
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, subfrm->clip,
+ 0xFFFFFFFF);
+
+ return 0;
+}
+
+static int advance_rsz_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+
+ if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample) {
+ const struct img_comp_subfrm *csf = &ctx->param->subfrms[index];
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ if ((csf->in.right - csf->in.left + 1) <= 16)
+ MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0,
+ BIT(27));
+ }
+
+ return 0;
+}
+
+static const struct mdp_comp_ops rsz_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_rsz,
+ .config_frame = config_rsz_frame,
+ .config_subfrm = config_rsz_subfrm,
+ .advance_subfrm = advance_rsz_subfrm,
+};
+
+static int init_wrot(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;
+
+ /* 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));
+ 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;
+}
+
+static int config_wrot_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ const struct mdp_wrot_data *wrot = &ctx->param->wrot;
+ 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;
+
+ /* Write frame base address */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, wrot->iova[0],
+ 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, wrot->iova[1],
+ 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, wrot->iova[2],
+ 0xFFFFFFFF);
+ /* Write frame related registers */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, wrot->control,
+ 0xF131510F);
+ /* Write frame Y pitch */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, wrot->stride[0],
+ 0x0000FFFF);
+ /* Write frame UV pitch */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, wrot->stride[1],
+ 0xFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, wrot->stride[2],
+ 0xFFFF);
+ /* Write matrix control */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, wrot->mat_ctrl, 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 (wrot->fifo_test != 0)
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST,
+ wrot->fifo_test, 0xFFF);
+ /* Filter enable */
+ if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
+ wrot->filter, 0x77);
+
+ return 0;
+}
+
+static int config_wrot_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ const struct mdp_wrot_subfrm *subfrm = &ctx->param->wrot.subfrms[index];
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ /* Write Y pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR,
+ subfrm->offset[0], 0x0FFFFFFF);
+ /* Write U pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C,
+ subfrm->offset[1], 0x0FFFFFFF);
+ /* Write V pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V,
+ subfrm->offset[2], 0x0FFFFFFF);
+ /* Write source size */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, subfrm->src,
+ 0x1FFF1FFF);
+ /* Write target size */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, subfrm->clip,
+ 0x1FFF1FFF);
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, subfrm->clip_ofst,
+ 0x1FFF1FFF);
+
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
+ subfrm->main_buf, 0x1FFF7F00);
+
+ /* Enable WROT */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0));
+
+ return 0;
+}
+
+static int wait_wrot_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 WROT1_DONE event\n");
+
+ if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0,
+ 0x77);
+
+ /* Disable WROT */
+ MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0));
+
+ return 0;
+}
+
+static const struct mdp_comp_ops wrot_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_wrot,
+ .config_frame = config_wrot_frame,
+ .config_subfrm = config_wrot_subfrm,
+ .wait_comp_event = wait_wrot_event,
+};
+
+static int init_wdma(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;
+
+ /* Reset WDMA */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0));
+ MM_REG_POLL(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0));
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0));
+ return 0;
+}
+
+static int config_wdma_frame(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose)
+{
+ const struct mdp_wdma_data *wdma = &ctx->param->wdma;
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050,
+ 0xFFFFFFFF);
+
+ /* Setup frame information */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_CFG, wdma->wdma_cfg,
+ 0x0F01B8F0);
+ /* Setup frame base address */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, wdma->iova[0],
+ 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, wdma->iova[1],
+ 0xFFFFFFFF);
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, wdma->iova[2],
+ 0xFFFFFFFF);
+ /* Setup Y pitch */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE,
+ wdma->w_in_byte, 0x0000FFFF);
+ /* Setup UV pitch */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_UV_PITCH,
+ wdma->uv_stride, 0x0000FFFF);
+ /* Set the fixed ALPHA as 0xFF */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF,
+ 0x800000FF);
+
+ return 0;
+}
+
+static int config_wdma_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ const struct mdp_wdma_subfrm *subfrm = &ctx->param->wdma.subfrms[index];
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+
+ /* Write Y pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET,
+ subfrm->offset[0], 0x0FFFFFFF);
+ /* Write U pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET,
+ subfrm->offset[1], 0x0FFFFFFF);
+ /* Write V pixel offset */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET,
+ subfrm->offset[2], 0x0FFFFFFF);
+ /* Write source size */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_SRC_SIZE, subfrm->src,
+ 0x3FFF3FFF);
+ /* Write target size */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_SIZE, subfrm->clip,
+ 0x3FFF3FFF);
+ /* Write clip offset */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_COORD, subfrm->clip_ofst,
+ 0x3FFF3FFF);
+
+ /* Enable WDMA */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0));
+
+ return 0;
+}
+
+static int wait_wdma_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;
+
+ MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]);
+ /* Disable WDMA */
+ MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0));
+ return 0;
+}
+
+static const struct mdp_comp_ops wdma_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_wdma,
+ .config_frame = config_wdma_frame,
+ .config_subfrm = config_wdma_subfrm,
+ .wait_comp_event = wait_wdma_event,
+};
+
+static int init_ccorr(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;
+
+ /* CCORR enable */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0));
+ /* Relay mode */
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0));
+ return 0;
+}
+
+static int config_ccorr_subfrm(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index)
+{
+ const struct img_comp_subfrm *csf = &ctx->param->subfrms[index];
+ phys_addr_t base = ctx->comp->reg_base;
+ u8 subsys_id = ctx->comp->subsys_id;
+ u32 hsize, vsize;
+
+ hsize = csf->in.right - csf->in.left + 1;
+ vsize = csf->in.bottom - csf->in.top + 1;
+ MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_SIZE,
+ (hsize << 16) + (vsize << 0), 0x1FFF1FFF);
+ return 0;
+}
+
+static const struct mdp_comp_ops ccorr_ops = {
+ .get_comp_flag = get_comp_flag,
+ .init_comp = init_ccorr,
+ .config_subfrm = config_ccorr_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_CCORR] = &ccorr_ops,
+};
+
+struct mdp_comp_match {
+ enum mdp_comp_type type;
+ u32 alias_id;
+};
+
+static const struct mdp_comp_match mdp_comp_matches[MDP_MAX_COMP_COUNT] = {
+ [MDP_COMP_WPEI] = { MDP_COMP_TYPE_WPEI, 0 },
+ [MDP_COMP_WPEO] = { MDP_COMP_TYPE_EXTO, 2 },
+ [MDP_COMP_WPEI2] = { MDP_COMP_TYPE_WPEI, 1 },
+ [MDP_COMP_WPEO2] = { MDP_COMP_TYPE_EXTO, 3 },
+ [MDP_COMP_ISP_IMGI] = { MDP_COMP_TYPE_IMGI, 0 },
+ [MDP_COMP_ISP_IMGO] = { MDP_COMP_TYPE_EXTO, 0 },
+ [MDP_COMP_ISP_IMG2O] = { MDP_COMP_TYPE_EXTO, 1 },
+
+ [MDP_COMP_CAMIN] = { MDP_COMP_TYPE_DL_PATH, 0 },
+ [MDP_COMP_CAMIN2] = { MDP_COMP_TYPE_DL_PATH, 1 },
+ [MDP_COMP_RDMA0] = { MDP_COMP_TYPE_RDMA, 0 },
+ [MDP_COMP_CCORR0] = { MDP_COMP_TYPE_CCORR, 0 },
+ [MDP_COMP_RSZ0] = { MDP_COMP_TYPE_RSZ, 0 },
+ [MDP_COMP_RSZ1] = { MDP_COMP_TYPE_RSZ, 1 },
+ [MDP_COMP_PATH0_SOUT] = { MDP_COMP_TYPE_PATH, 0 },
+ [MDP_COMP_PATH1_SOUT] = { MDP_COMP_TYPE_PATH, 1 },
+ [MDP_COMP_WROT0] = { MDP_COMP_TYPE_WROT, 0 },
+ [MDP_COMP_WDMA] = { MDP_COMP_TYPE_WDMA, 0 },
+};
+
+static const struct of_device_id mdp_comp_dt_ids[] = {
+ {
+ .compatible = "mediatek,mt8183-mdp3-rdma",
+ .data = (void *)MDP_COMP_TYPE_RDMA,
+ }, {
+ .compatible = "mediatek,mt8183-mdp3-ccorr",
+ .data = (void *)MDP_COMP_TYPE_CCORR,
+ }, {
+ .compatible = "mediatek,mt8183-mdp3-rsz",
+ .data = (void *)MDP_COMP_TYPE_RSZ,
+ }, {
+ .compatible = "mediatek,mt8183-mdp3-wrot",
+ .data = (void *)MDP_COMP_TYPE_WROT,
+ }, {
+ .compatible = "mediatek,mt8183-mdp3-wdma",
+ .data = (void *)MDP_COMP_TYPE_WDMA,
+ },
+ {}
+};
+
+static const struct of_device_id mdp_sub_comp_dt_ids[] = {
+ {
+ .compatible = "mediatek,mt8183-mdp3-wdma",
+ .data = (void *)MDP_COMP_TYPE_PATH,
+ }, {
+ .compatible = "mediatek,mt8183-mdp3-wrot",
+ .data = (void *)MDP_COMP_TYPE_PATH,
+ },
+ {}
+};
+
+/* Used to describe the item order in MDP property */
+struct mdp_comp_info {
+ u32 clk_num;
+ u32 clk_ofst;
+ u32 dts_reg_ofst;
+};
+
+static const struct mdp_comp_info mdp_comp_dt_info[MDP_MAX_COMP_COUNT] = {
+ [MDP_COMP_RDMA0] = {2, 0, 0},
+ [MDP_COMP_RSZ0] = {1, 0, 0},
+ [MDP_COMP_WROT0] = {1, 0, 0},
+ [MDP_COMP_WDMA] = {1, 0, 0},
+ [MDP_COMP_CCORR0] = {1, 0, 0},
+};
+
+static inline bool is_dma_capable(const enum mdp_comp_type type)
+{
+ return (type == MDP_COMP_TYPE_RDMA ||
+ type == MDP_COMP_TYPE_WROT ||
+ type == MDP_COMP_TYPE_WDMA);
+}
+
+static inline bool is_bypass_gce_event(const enum mdp_comp_type type)
+{
+ /*
+ * Subcomponent PATH is only used for the direction of data flow and
+ * dose not need to wait for GCE event.
+ */
+ return (type == MDP_COMP_TYPE_PATH);
+}
+
+static int mdp_comp_get_id(enum mdp_comp_type type, int alias_id)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mdp_comp_matches); i++)
+ if (mdp_comp_matches[i].type == type &&
+ mdp_comp_matches[i].alias_id == alias_id)
+ return i;
+ return -ENODEV;
+}
+
+int mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
+{
+ int i, ret;
+
+ if (comp->comp_dev) {
+ ret = pm_runtime_get_sync(comp->comp_dev);
+ if (ret < 0) {
+ dev_err(dev,
+ "Failed to get power, err %d. type:%d id:%d\n",
+ ret, comp->type, comp->id);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(comp->clks); i++) {
+ if (IS_ERR_OR_NULL(comp->clks[i]))
+ continue;
+ ret = clk_prepare_enable(comp->clks[i]);
+ if (ret) {
+ dev_err(dev,
+ "Failed to enable clk %d. type:%d id:%d\n",
+ i, comp->type, comp->id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+void mdp_comp_clock_off(struct device *dev, struct mdp_comp *comp)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(comp->clks); i++) {
+ if (IS_ERR_OR_NULL(comp->clks[i]))
+ continue;
+ clk_disable_unprepare(comp->clks[i]);
+ }
+
+ if (comp->comp_dev)
+ pm_runtime_put(comp->comp_dev);
+}
+
+int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ if (mdp_comp_clock_on(dev, &comps[i]) != 0)
+ return ++i;
+
+ return 0;
+}
+
+void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ mdp_comp_clock_off(dev, &comps[i]);
+}
+
+static int mdp_get_subsys_id(struct device *dev, struct device_node *node,
+ struct mdp_comp *comp)
+{
+ struct platform_device *comp_pdev;
+ struct cmdq_client_reg cmdq_reg;
+ int ret = 0;
+ int index = 0;
+
+ if (!dev || !node || !comp)
+ return -EINVAL;
+
+ comp_pdev = of_find_device_by_node(node);
+
+ if (!comp_pdev) {
+ dev_err(dev, "get comp_pdev fail! comp id=%d type=%d\n",
+ comp->id, comp->type);
+ return -ENODEV;
+ }
+
+ index = mdp_comp_dt_info[comp->id].dts_reg_ofst;
+ ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index);
+ if (ret != 0) {
+ dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n");
+ return -EINVAL;
+ }
+
+ comp->subsys_id = cmdq_reg.subsys;
+ dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys);
+
+ return 0;
+}
+
+static void __mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
+ struct mdp_comp *comp)
+{
+ struct resource res;
+ phys_addr_t base;
+ int index = mdp_comp_dt_info[comp->id].dts_reg_ofst;
+
+ if (of_address_to_resource(node, index, &res) < 0)
+ base = 0L;
+ else
+ base = res.start;
+
+ comp->mdp_dev = mdp;
+ comp->regs = of_iomap(node, 0);
+ comp->reg_base = base;
+}
+
+static int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
+ struct mdp_comp *comp, enum mtk_mdp_comp_id id)
+{
+ struct device *dev = &mdp->pdev->dev;
+ int clk_num;
+ int clk_ofst;
+ int i;
+ s32 event;
+
+ if (id < 0 || id >= MDP_MAX_COMP_COUNT) {
+ dev_err(dev, "Invalid component id %d\n", id);
+ return -EINVAL;
+ }
+
+ comp->id = id;
+ comp->type = mdp_comp_matches[id].type;
+ comp->alias_id = mdp_comp_matches[id].alias_id;
+ comp->ops = mdp_comp_ops[comp->type];
+ __mdp_comp_init(mdp, node, comp);
+
+ clk_num = mdp_comp_dt_info[id].clk_num;
+ clk_ofst = mdp_comp_dt_info[id].clk_ofst;
+
+ for (i = 0; i < clk_num; i++) {
+ comp->clks[i] = of_clk_get(node, i + clk_ofst);
+ if (IS_ERR(comp->clks[i]))
+ break;
+ }
+
+ mdp_get_subsys_id(dev, node, comp);
+
+ /* Set GCE SOF event */
+ if (is_bypass_gce_event(comp->type) ||
+ of_property_read_u32_index(node, "mediatek,gce-events",
+ MDP_GCE_EVENT_SOF, &event))
+ event = MDP_GCE_NO_EVENT;
+
+ comp->gce_event[MDP_GCE_EVENT_SOF] = event;
+
+ /* Set GCE EOF event */
+ if (is_dma_capable(comp->type)) {
+ if (of_property_read_u32_index(node, "mediatek,gce-events",
+ MDP_GCE_EVENT_EOF, &event)) {
+ dev_err(dev, "Component id %d has no EOF\n", id);
+ return -EINVAL;
+ }
+ } else {
+ event = MDP_GCE_NO_EVENT;
+ }
+
+ comp->gce_event[MDP_GCE_EVENT_EOF] = event;
+
+ return 0;
+}
+
+static void mdp_comp_deinit(struct mdp_comp *comp)
+{
+ if (!comp)
+ return;
+
+ if (comp->regs)
+ iounmap(comp->regs);
+}
+
+static struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
+ struct device_node *node,
+ enum mtk_mdp_comp_id id)
+{
+ struct device *dev = &mdp->pdev->dev;
+ struct mdp_comp *comp;
+ int ret;
+
+ if (mdp->comp[id])
+ return ERR_PTR(-EEXIST);
+
+ comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+ if (!comp)
+ return ERR_PTR(-ENOMEM);
+
+ ret = mdp_comp_init(mdp, node, comp, id);
+ if (ret) {
+ kfree(comp);
+ return ERR_PTR(ret);
+ }
+ mdp->comp[id] = comp;
+ mdp->comp[id]->mdp_dev = mdp;
+
+ dev_dbg(dev, "%s type:%d alias:%d id:%d base:%#x regs:%p\n",
+ dev->of_node->name, comp->type, comp->alias_id, id,
+ (u32)comp->reg_base, comp->regs);
+ return comp;
+}
+
+static int mdp_comp_sub_create(struct mdp_dev *mdp)
+{
+ struct device *dev = &mdp->pdev->dev;
+ struct device_node *node, *parent;
+
+ parent = dev->of_node->parent;
+
+ for_each_child_of_node(parent, node) {
+ const struct of_device_id *of_id;
+ enum mdp_comp_type type;
+ int id, alias_id;
+ struct mdp_comp *comp;
+
+ of_id = of_match_node(mdp_sub_comp_dt_ids, node);
+ if (!of_id)
+ continue;
+ if (!of_device_is_available(node)) {
+ dev_dbg(dev, "Skipping disabled sub comp. %pOF\n",
+ node);
+ continue;
+ }
+
+ type = (enum mdp_comp_type)(uintptr_t)of_id->data;
+ alias_id = mdp_comp_alias_id[type];
+ id = mdp_comp_get_id(type, alias_id);
+ if (id < 0) {
+ dev_err(dev,
+ "Fail to get sub comp. id: type %d alias %d\n",
+ type, alias_id);
+ return -EINVAL;
+ }
+ mdp_comp_alias_id[type]++;
+
+ comp = mdp_comp_create(mdp, node, id);
+ if (IS_ERR(comp))
+ return PTR_ERR(comp);
+ }
+
+ return 0;
+}
+
+void mdp_comp_destroy(struct mdp_dev *mdp)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) {
+ if (mdp->comp[i]) {
+ pm_runtime_disable(mdp->comp[i]->comp_dev);
+ mdp_comp_deinit(mdp->comp[i]);
+ kfree(mdp->comp[i]);
+ mdp->comp[i] = NULL;
+ }
+ }
+}
+
+int mdp_comp_config(struct mdp_dev *mdp)
+{
+ struct device *dev = &mdp->pdev->dev;
+ struct device_node *node, *parent;
+ struct platform_device *pdev;
+ int ret;
+
+ memset(mdp_comp_alias_id, 0, sizeof(mdp_comp_alias_id));
+
+ parent = dev->of_node->parent;
+ /* Iterate over sibling MDP function blocks */
+ for_each_child_of_node(parent, node) {
+ const struct of_device_id *of_id;
+ enum mdp_comp_type type;
+ int id, alias_id;
+ struct mdp_comp *comp;
+
+ of_id = of_match_node(mdp_comp_dt_ids, node);
+ if (!of_id)
+ continue;
+
+ if (!of_device_is_available(node)) {
+ dev_dbg(dev, "Skipping disabled component %pOF\n",
+ node);
+ continue;
+ }
+
+ type = (enum mdp_comp_type)(uintptr_t)of_id->data;
+ alias_id = mdp_comp_alias_id[type];
+ id = mdp_comp_get_id(type, alias_id);
+ if (id < 0) {
+ dev_err(dev,
+ "Fail to get component id: type %d alias %d\n",
+ type, alias_id);
+ continue;
+ }
+ mdp_comp_alias_id[type]++;
+
+ comp = mdp_comp_create(mdp, node, id);
+ if (IS_ERR(comp)) {
+ ret = PTR_ERR(comp);
+ goto err_init_comps;
+ }
+
+ /* Only DMA capable components need the pm control */
+ comp->comp_dev = NULL;
+ if (!is_dma_capable(comp->type))
+ continue;
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev) {
+ dev_warn(dev, "can't find platform device of node:%s\n",
+ node->name);
+ return -ENODEV;
+ }
+
+ comp->comp_dev = &pdev->dev;
+ pm_runtime_enable(comp->comp_dev);
+ }
+
+ ret = mdp_comp_sub_create(mdp);
+ if (ret)
+ goto err_init_comps;
+
+ return 0;
+
+err_init_comps:
+ mdp_comp_destroy(mdp);
+ return ret;
+}
+
+int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
+ const struct img_compparam *param,
+ const struct img_ipi_frameparam *frame)
+{
+ struct device *dev = &mdp->pdev->dev;
+ int i;
+
+ if (param->type < 0 || param->type >= MDP_MAX_COMP_COUNT) {
+ dev_err(dev, "Invalid component id %d", param->type);
+ return -EINVAL;
+ }
+
+ ctx->comp = mdp->comp[param->type];
+ if (!ctx->comp) {
+ dev_err(dev, "Uninit component id %d", param->type);
+ return -EINVAL;
+ }
+
+ ctx->param = param;
+ ctx->input = &frame->inputs[param->input];
+ for (i = 0; i < param->num_outputs; i++)
+ ctx->outputs[i] = &frame->outputs[param->outputs[i]];
+ return 0;
+}
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
new file mode 100644
index 000000000000..dc48f55ac4f7
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MTK_MDP3_COMP_H__
+#define __MTK_MDP3_COMP_H__
+
+#include "mtk-mdp3-cmdq.h"
+
+#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask, ...) \
+ cmdq_pkt_write_mask(&((cmd)->pkt), id, \
+ (base) + (ofst), (val), (mask), ##__VA_ARGS__)
+
+#define MM_REG_WRITE(cmd, id, base, ofst, val, mask, ...) \
+do { \
+ typeof(mask) (m) = (mask); \
+ MM_REG_WRITE_MASK(cmd, id, base, ofst, val, \
+ (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \
+ (0xffffffff) : (m), ##__VA_ARGS__); \
+} while (0)
+
+#define MM_REG_WAIT(cmd, evt) \
+do { \
+ typeof(cmd) (c) = (cmd); \
+ typeof(evt) (e) = (evt); \
+ cmdq_pkt_wfe(&((c)->pkt), (e), true); \
+} while (0)
+
+#define MM_REG_WAIT_NO_CLEAR(cmd, evt) \
+do { \
+ typeof(cmd) (c) = (cmd); \
+ typeof(evt) (e) = (evt); \
+ cmdq_pkt_wfe(&((c)->pkt), (e), false); \
+} while (0)
+
+#define MM_REG_CLEAR(cmd, evt) \
+do { \
+ typeof(cmd) (c) = (cmd); \
+ typeof(evt) (e) = (evt); \
+ cmdq_pkt_clear_event(&((c)->pkt), (e)); \
+} while (0)
+
+#define MM_REG_SET_EVENT(cmd, evt) \
+do { \
+ typeof(cmd) (c) = (cmd); \
+ typeof(evt) (e) = (evt); \
+ cmdq_pkt_set_event(&((c)->pkt), (e)); \
+} while (0)
+
+#define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask, ...) \
+do { \
+ typeof(_mask) (_m) = (_mask); \
+ cmdq_pkt_poll_mask(&((cmd)->pkt), id, \
+ (base) + (ofst), (val), (_m), ##__VA_ARGS__); \
+} while (0)
+
+#define MM_REG_POLL(cmd, id, base, ofst, val, mask, ...) \
+do { \
+ typeof(mask) (m) = (mask); \
+ MM_REG_POLL_MASK((cmd), id, base, ofst, val, \
+ (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \
+ (0xffffffff) : (m), ##__VA_ARGS__); \
+} while (0)
+
+enum mtk_mdp_comp_id {
+ MDP_COMP_NONE = -1, /* Invalid engine */
+
+ /* ISP */
+ MDP_COMP_WPEI = 0,
+ MDP_COMP_WPEO, /* 1 */
+ MDP_COMP_WPEI2, /* 2 */
+ MDP_COMP_WPEO2, /* 3 */
+ MDP_COMP_ISP_IMGI, /* 4 */
+ MDP_COMP_ISP_IMGO, /* 5 */
+ MDP_COMP_ISP_IMG2O, /* 6 */
+
+ /* IPU */
+ MDP_COMP_IPUI, /* 7 */
+ MDP_COMP_IPUO, /* 8 */
+
+ /* MDP */
+ 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_MAX_COMP_COUNT /* ALWAYS keep at the end */
+};
+
+enum mdp_comp_type {
+ MDP_COMP_TYPE_INVALID = 0,
+
+ MDP_COMP_TYPE_RDMA,
+ MDP_COMP_TYPE_RSZ,
+ MDP_COMP_TYPE_WROT,
+ MDP_COMP_TYPE_WDMA,
+ MDP_COMP_TYPE_PATH,
+
+ MDP_COMP_TYPE_TDSHP,
+ MDP_COMP_TYPE_COLOR,
+ MDP_COMP_TYPE_DRE,
+ MDP_COMP_TYPE_CCORR,
+ MDP_COMP_TYPE_HDR,
+
+ 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_COUNT /* ALWAYS keep at the end */
+};
+
+#define MDP_GCE_NO_EVENT (-1)
+enum {
+ MDP_GCE_EVENT_SOF = 0,
+ MDP_GCE_EVENT_EOF = 1,
+ MDP_GCE_EVENT_MAX,
+};
+
+struct mdp_comp_ops;
+
+struct mdp_comp {
+ struct mdp_dev *mdp_dev;
+ void __iomem *regs;
+ phys_addr_t reg_base;
+ u8 subsys_id;
+ struct clk *clks[6];
+ struct device *comp_dev;
+ enum mdp_comp_type type;
+ enum mtk_mdp_comp_id id;
+ u32 alias_id;
+ s32 gce_event[MDP_GCE_EVENT_MAX];
+ const struct mdp_comp_ops *ops;
+};
+
+struct mdp_comp_ctx {
+ struct mdp_comp *comp;
+ const struct img_compparam *param;
+ const struct img_input *input;
+ const struct img_output *outputs[IMG_MAX_HW_OUTPUTS];
+};
+
+struct mdp_comp_ops {
+ s64 (*get_comp_flag)(const struct mdp_comp_ctx *ctx);
+ int (*init_comp)(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd);
+ int (*config_frame)(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd,
+ const struct v4l2_rect *compose);
+ int (*config_subfrm)(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index);
+ int (*wait_comp_event)(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd);
+ int (*advance_subfrm)(struct mdp_comp_ctx *ctx,
+ struct mdp_cmdq_cmd *cmd, u32 index);
+ int (*post_process)(struct mdp_comp_ctx *ctx, struct mdp_cmdq_cmd *cmd);
+};
+
+struct mdp_dev;
+
+int mdp_comp_config(struct mdp_dev *mdp);
+void mdp_comp_destroy(struct mdp_dev *mdp);
+int mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp);
+void mdp_comp_clock_off(struct device *dev, struct mdp_comp *comp);
+int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num);
+void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num);
+int mdp_comp_ctx_config(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
+ const struct img_compparam *param,
+ const struct img_ipi_frameparam *frame);
+
+#endif /* __MTK_MDP3_COMP_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
new file mode 100644
index 000000000000..cde59579b7ae
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/remoteproc.h>
+#include <linux/remoteproc/mtk_scp.h>
+#include <media/videobuf2-dma-contig.h>
+#include "mtk-mdp3-core.h"
+#include "mtk-mdp3-m2m.h"
+
+static const struct mdp_platform_config mt8183_plat_cfg = {
+ .rdma_support_10bit = true,
+ .rdma_rsz1_sram_sharing = true,
+ .rdma_upsample_repeat_only = true,
+ .rsz_disable_dcm_small_sample = false,
+ .wrot_filter_constraint = false,
+};
+
+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 u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = {
+ [MDP_COMP_RDMA0] = MUTEX_MOD_IDX_MDP_RDMA0,
+ [MDP_COMP_RSZ0] = MUTEX_MOD_IDX_MDP_RSZ0,
+ [MDP_COMP_RSZ1] = MUTEX_MOD_IDX_MDP_RSZ1,
+ [MDP_COMP_TDSHP0] = MUTEX_MOD_IDX_MDP_TDSHP0,
+ [MDP_COMP_WROT0] = MUTEX_MOD_IDX_MDP_WROT0,
+ [MDP_COMP_WDMA] = MUTEX_MOD_IDX_MDP_WDMA,
+ [MDP_COMP_AAL0] = MUTEX_MOD_IDX_MDP_AAL0,
+ [MDP_COMP_CCORR0] = MUTEX_MOD_IDX_MDP_CCORR0,
+};
+
+static const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
+ .mdp_probe_infra = mt8183_mdp_probe_infra,
+ .mdp_cfg = &mt8183_plat_cfg,
+ .mdp_mutex_table_idx = mt8183_mutex_idx,
+};
+
+static const struct of_device_id mdp_of_ids[] = {
+ { .compatible = "mediatek,mt8183-mdp3-rdma",
+ .data = &mt8183_mdp_driver_data,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mdp_of_ids);
+
+static struct platform_device *__get_pdev_by_id(struct platform_device *pdev,
+ enum mdp_infra_id id)
+{
+ struct device_node *node;
+ struct platform_device *mdp_pdev = NULL;
+ const struct mtk_mdp_driver_data *mdp_data;
+ const char *compat;
+
+ if (!pdev)
+ return NULL;
+
+ if (id < MDP_INFRA_MMSYS || id >= MDP_INFRA_MAX) {
+ dev_err(&pdev->dev, "Illegal infra id %d\n", id);
+ return NULL;
+ }
+
+ mdp_data = of_device_get_match_data(&pdev->dev);
+ if (!mdp_data) {
+ dev_err(&pdev->dev, "have no driver data to find node\n");
+ return NULL;
+ }
+ compat = mdp_data->mdp_probe_infra[id].compatible;
+
+ node = of_find_compatible_node(NULL, NULL, compat);
+ if (WARN_ON(!node)) {
+ dev_err(&pdev->dev, "find node from id %d failed\n", id);
+ return NULL;
+ }
+
+ mdp_pdev = of_find_device_by_node(node);
+ of_node_put(node);
+ if (WARN_ON(!mdp_pdev)) {
+ dev_err(&pdev->dev, "find pdev from id %d failed\n", id);
+ return NULL;
+ }
+
+ return mdp_pdev;
+}
+
+struct platform_device *mdp_get_plat_device(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *mdp_node;
+ struct platform_device *mdp_pdev;
+
+ mdp_node = of_parse_phandle(dev->of_node, MDP_PHANDLE_NAME, 0);
+ if (!mdp_node) {
+ dev_err(dev, "can't get node %s\n", MDP_PHANDLE_NAME);
+ return NULL;
+ }
+
+ mdp_pdev = of_find_device_by_node(mdp_node);
+ of_node_put(mdp_node);
+
+ return mdp_pdev;
+}
+EXPORT_SYMBOL_GPL(mdp_get_plat_device);
+
+int mdp_vpu_get_locked(struct mdp_dev *mdp)
+{
+ int ret = 0;
+
+ if (mdp->vpu_count++ == 0) {
+ ret = rproc_boot(mdp->rproc_handle);
+ if (ret) {
+ dev_err(&mdp->pdev->dev,
+ "vpu_load_firmware failed %d\n", ret);
+ goto err_load_vpu;
+ }
+ ret = mdp_vpu_register(mdp);
+ if (ret) {
+ dev_err(&mdp->pdev->dev,
+ "mdp_vpu register failed %d\n", ret);
+ goto err_reg_vpu;
+ }
+ ret = mdp_vpu_dev_init(&mdp->vpu, mdp->scp, &mdp->vpu_lock);
+ if (ret) {
+ dev_err(&mdp->pdev->dev,
+ "mdp_vpu device init failed %d\n", ret);
+ goto err_init_vpu;
+ }
+ }
+ return 0;
+
+err_init_vpu:
+ mdp_vpu_unregister(mdp);
+err_reg_vpu:
+err_load_vpu:
+ mdp->vpu_count--;
+ return ret;
+}
+
+void mdp_vpu_put_locked(struct mdp_dev *mdp)
+{
+ if (--mdp->vpu_count == 0) {
+ mdp_vpu_dev_deinit(&mdp->vpu);
+ mdp_vpu_unregister(mdp);
+ }
+}
+
+void mdp_video_device_release(struct video_device *vdev)
+{
+ struct mdp_dev *mdp = (struct mdp_dev *)video_get_drvdata(vdev);
+ int i;
+
+ scp_put(mdp->scp);
+
+ destroy_workqueue(mdp->job_wq);
+ destroy_workqueue(mdp->clock_wq);
+
+ pm_runtime_disable(&mdp->pdev->dev);
+
+ 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]);
+
+ mdp_vpu_shared_mem_free(&mdp->vpu);
+ v4l2_m2m_release(mdp->m2m_dev);
+ kfree(mdp);
+}
+
+static int mdp_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mdp_dev *mdp;
+ struct platform_device *mm_pdev;
+ int ret, i;
+
+ mdp = kzalloc(sizeof(*mdp), GFP_KERNEL);
+ if (!mdp) {
+ ret = -ENOMEM;
+ goto err_return;
+ }
+
+ 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_return;
+ }
+ mdp->mdp_mmsys = &mm_pdev->dev;
+
+ mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MUTEX);
+ if (WARN_ON(!mm_pdev)) {
+ ret = -ENODEV;
+ goto err_return;
+ }
+ for (i = 0; i < MDP_PIPE_MAX; i++) {
+ mdp->mdp_mutex[i] = mtk_mutex_get(&mm_pdev->dev);
+ if (!mdp->mdp_mutex[i]) {
+ ret = -ENODEV;
+ goto err_return;
+ }
+ }
+
+ ret = mdp_comp_config(mdp);
+ if (ret) {
+ dev_err(dev, "Failed to config mdp components\n");
+ goto err_return;
+ }
+
+ mdp->job_wq = alloc_workqueue(MDP_MODULE_NAME, WQ_FREEZABLE, 0);
+ if (!mdp->job_wq) {
+ dev_err(dev, "Unable to create job workqueue\n");
+ ret = -ENOMEM;
+ goto err_deinit_comp;
+ }
+
+ mdp->clock_wq = alloc_workqueue(MDP_MODULE_NAME "-clock", WQ_FREEZABLE,
+ 0);
+ if (!mdp->clock_wq) {
+ dev_err(dev, "Unable to create clock workqueue\n");
+ ret = -ENOMEM;
+ goto err_destroy_job_wq;
+ }
+
+ mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_SCP);
+ if (WARN_ON(!mm_pdev)) {
+ dev_err(&pdev->dev, "Could not get scp device\n");
+ ret = -ENODEV;
+ goto err_destroy_clock_wq;
+ }
+ mdp->scp = platform_get_drvdata(mm_pdev);
+ mdp->rproc_handle = scp_get_rproc(mdp->scp);
+ dev_dbg(&pdev->dev, "MDP rproc_handle: %pK", mdp->rproc_handle);
+
+ 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;
+ }
+
+ init_waitqueue_head(&mdp->callback_wq);
+ ida_init(&mdp->mdp_ida);
+ platform_set_drvdata(pdev, mdp);
+
+ vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
+
+ ret = v4l2_device_register(dev, &mdp->v4l2_dev);
+ if (ret) {
+ dev_err(dev, "Failed to register v4l2 device\n");
+ ret = -EINVAL;
+ goto err_mbox_destroy;
+ }
+
+ ret = mdp_m2m_device_register(mdp);
+ if (ret) {
+ v4l2_err(&mdp->v4l2_dev, "Failed to register m2m device\n");
+ goto err_unregister_device;
+ }
+
+ 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:
+ scp_put(mdp->scp);
+err_destroy_clock_wq:
+ destroy_workqueue(mdp->clock_wq);
+err_destroy_job_wq:
+ destroy_workqueue(mdp->job_wq);
+err_deinit_comp:
+ mdp_comp_destroy(mdp);
+err_return:
+ for (i = 0; i < MDP_PIPE_MAX; i++)
+ mtk_mutex_put(mdp->mdp_mutex[i]);
+ kfree(mdp);
+ dev_dbg(dev, "Errno %d\n", ret);
+ return ret;
+}
+
+static int mdp_remove(struct platform_device *pdev)
+{
+ struct mdp_dev *mdp = platform_get_drvdata(pdev);
+
+ v4l2_device_unregister(&mdp->v4l2_dev);
+
+ dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
+ return 0;
+}
+
+static int __maybe_unused mdp_suspend(struct device *dev)
+{
+ struct mdp_dev *mdp = dev_get_drvdata(dev);
+ int ret;
+
+ atomic_set(&mdp->suspended, 1);
+
+ if (atomic_read(&mdp->job_count)) {
+ ret = wait_event_timeout(mdp->callback_wq,
+ !atomic_read(&mdp->job_count),
+ 2 * HZ);
+ if (ret == 0) {
+ dev_err(dev,
+ "%s:flushed cmdq task incomplete, count=%d\n",
+ __func__, atomic_read(&mdp->job_count));
+ return -EBUSY;
+ }
+ }
+
+ return 0;
+}
+
+static int __maybe_unused mdp_resume(struct device *dev)
+{
+ struct mdp_dev *mdp = dev_get_drvdata(dev);
+
+ atomic_set(&mdp->suspended, 0);
+
+ return 0;
+}
+
+static const struct dev_pm_ops mdp_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(mdp_suspend, mdp_resume)
+};
+
+static struct platform_driver mdp_driver = {
+ .probe = mdp_probe,
+ .remove = mdp_remove,
+ .driver = {
+ .name = MDP_MODULE_NAME,
+ .pm = &mdp_pm_ops,
+ .of_match_table = of_match_ptr(mdp_of_ids),
+ },
+};
+
+module_platform_driver(mdp_driver);
+
+MODULE_AUTHOR("Ping-Hsun Wu <ping-hsun.wu@mediatek.com>");
+MODULE_DESCRIPTION("MediaTek image processor 3 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
new file mode 100644
index 000000000000..2ef5fbc4f25a
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MTK_MDP3_CORE_H__
+#define __MTK_MDP3_CORE_H__
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-mem2mem.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-mutex.h>
+#include "mtk-mdp3-comp.h"
+#include "mtk-mdp3-vpu.h"
+
+#define MDP_MODULE_NAME "mtk-mdp3"
+#define MDP_DEVICE_NAME "MediaTek MDP3"
+#define MDP_PHANDLE_NAME "mediatek,mdp3"
+
+enum mdp_infra_id {
+ MDP_INFRA_MMSYS,
+ MDP_INFRA_MUTEX,
+ MDP_INFRA_SCP,
+ MDP_INFRA_MAX
+};
+
+enum mdp_buffer_usage {
+ MDP_BUFFER_USAGE_HW_READ,
+ MDP_BUFFER_USAGE_MDP,
+ MDP_BUFFER_USAGE_MDP2,
+ MDP_BUFFER_USAGE_ISP,
+ MDP_BUFFER_USAGE_WPE,
+};
+
+struct mdp_platform_config {
+ bool rdma_support_10bit;
+ bool rdma_rsz1_sram_sharing;
+ bool rdma_upsample_repeat_only;
+ bool rsz_disable_dcm_small_sample;
+ bool wrot_filter_constraint;
+};
+
+/* indicate which mutex is used by each pipepline */
+enum mdp_pipe_id {
+ MDP_PIPE_RDMA0,
+ MDP_PIPE_IMGI,
+ MDP_PIPE_WPEI,
+ MDP_PIPE_WPEI2,
+ MDP_PIPE_MAX
+};
+
+struct mtk_mdp_driver_data {
+ const struct of_device_id *mdp_probe_infra;
+ const struct mdp_platform_config *mdp_cfg;
+ const u32 *mdp_mutex_table_idx;
+};
+
+struct mdp_dev {
+ struct platform_device *pdev;
+ struct device *mdp_mmsys;
+ struct mtk_mutex *mdp_mutex[MDP_PIPE_MAX];
+ struct mdp_comp *comp[MDP_MAX_COMP_COUNT];
+ const struct mtk_mdp_driver_data *mdp_data;
+
+ struct workqueue_struct *job_wq;
+ struct workqueue_struct *clock_wq;
+ struct mdp_vpu_dev vpu;
+ struct mtk_scp *scp;
+ struct rproc *rproc_handle;
+ /* synchronization protect for accessing vpu working buffer info */
+ struct mutex vpu_lock;
+ s32 vpu_count;
+ u32 id_count;
+ struct ida mdp_ida;
+ struct cmdq_client *cmdq_clt;
+ wait_queue_head_t callback_wq;
+
+ struct v4l2_device v4l2_dev;
+ struct video_device *m2m_vdev;
+ struct v4l2_m2m_dev *m2m_dev;
+ /* synchronization protect for m2m device operation */
+ struct mutex m2m_lock;
+ atomic_t suspended;
+ atomic_t job_count;
+};
+
+int mdp_vpu_get_locked(struct mdp_dev *mdp);
+void mdp_vpu_put_locked(struct mdp_dev *mdp);
+int mdp_vpu_register(struct mdp_dev *mdp);
+void mdp_vpu_unregister(struct mdp_dev *mdp);
+void mdp_video_device_release(struct video_device *vdev);
+
+#endif /* __MTK_MDP3_CORE_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
new file mode 100644
index 000000000000..5f74ea3b7a52
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c
@@ -0,0 +1,724 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#include <linux/platform_device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-dma-contig.h>
+#include "mtk-mdp3-m2m.h"
+
+static inline struct mdp_m2m_ctx *fh_to_ctx(struct v4l2_fh *fh)
+{
+ return container_of(fh, struct mdp_m2m_ctx, fh);
+}
+
+static inline struct mdp_m2m_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
+{
+ return container_of(ctrl->handler, struct mdp_m2m_ctx, ctrl_handler);
+}
+
+static inline struct mdp_frame *ctx_get_frame(struct mdp_m2m_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ return &ctx->curr_param.output;
+ else
+ return &ctx->curr_param.captures[0];
+}
+
+static inline void mdp_m2m_ctx_set_state(struct mdp_m2m_ctx *ctx, u32 state)
+{
+ atomic_or(state, &ctx->curr_param.state);
+}
+
+static inline bool mdp_m2m_ctx_is_state_set(struct mdp_m2m_ctx *ctx, u32 mask)
+{
+ return ((atomic_read(&ctx->curr_param.state) & mask) == mask);
+}
+
+static void mdp_m2m_process_done(void *priv, int vb_state)
+{
+ struct mdp_m2m_ctx *ctx = priv;
+ struct vb2_v4l2_buffer *src_vbuf, *dst_vbuf;
+
+ src_vbuf = (struct vb2_v4l2_buffer *)
+ v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ dst_vbuf = (struct vb2_v4l2_buffer *)
+ v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+ ctx->curr_param.frame_no = ctx->frame_count[MDP_M2M_SRC];
+ src_vbuf->sequence = ctx->frame_count[MDP_M2M_SRC]++;
+ dst_vbuf->sequence = ctx->frame_count[MDP_M2M_DST]++;
+ v4l2_m2m_buf_copy_metadata(src_vbuf, dst_vbuf, true);
+
+ v4l2_m2m_buf_done(src_vbuf, vb_state);
+ v4l2_m2m_buf_done(dst_vbuf, vb_state);
+ v4l2_m2m_job_finish(ctx->mdp_dev->m2m_dev, ctx->m2m_ctx);
+}
+
+static void mdp_m2m_device_run(void *priv)
+{
+ struct mdp_m2m_ctx *ctx = priv;
+ struct mdp_frame *frame;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
+ struct img_ipi_frameparam param = {};
+ struct mdp_cmdq_param task = {};
+ enum vb2_buffer_state vb_state = VB2_BUF_STATE_ERROR;
+ int ret;
+
+ if (mdp_m2m_ctx_is_state_set(ctx, MDP_M2M_CTX_ERROR)) {
+ dev_err(&ctx->mdp_dev->pdev->dev,
+ "mdp_m2m_ctx is in error state\n");
+ goto worker_end;
+ }
+
+ param.frame_no = ctx->curr_param.frame_no;
+ param.type = ctx->curr_param.type;
+ param.num_inputs = 1;
+ param.num_outputs = 1;
+
+ frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ mdp_set_src_config(&param.inputs[0], frame, &src_vb->vb2_buf);
+
+ frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ mdp_set_dst_config(&param.outputs[0], frame, &dst_vb->vb2_buf);
+
+ ret = mdp_vpu_process(&ctx->vpu, &param);
+ if (ret) {
+ dev_err(&ctx->mdp_dev->pdev->dev,
+ "VPU MDP process failed: %d\n", ret);
+ goto worker_end;
+ }
+
+ task.config = ctx->vpu.config;
+ task.param = &param;
+ task.composes[0] = &frame->compose;
+ task.cmdq_cb = NULL;
+ task.cb_data = NULL;
+ task.mdp_ctx = ctx;
+
+ ret = mdp_cmdq_send(ctx->mdp_dev, &task);
+ if (ret) {
+ dev_err(&ctx->mdp_dev->pdev->dev,
+ "CMDQ sendtask failed: %d\n", ret);
+ goto worker_end;
+ }
+
+ return;
+
+worker_end:
+ mdp_m2m_process_done(ctx, vb_state);
+}
+
+static int mdp_m2m_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct mdp_m2m_ctx *ctx = vb2_get_drv_priv(q);
+ struct mdp_frame *capture;
+ struct vb2_queue *vq;
+ int ret;
+ bool out_streaming, cap_streaming;
+
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
+ ctx->frame_count[MDP_M2M_SRC] = 0;
+
+ if (V4L2_TYPE_IS_CAPTURE(q->type))
+ ctx->frame_count[MDP_M2M_DST] = 0;
+
+ capture = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ vq = v4l2_m2m_get_src_vq(ctx->m2m_ctx);
+ out_streaming = vb2_is_streaming(vq);
+ vq = v4l2_m2m_get_dst_vq(ctx->m2m_ctx);
+ cap_streaming = vb2_is_streaming(vq);
+
+ /* Check to see if scaling ratio is within supported range */
+ if ((V4L2_TYPE_IS_OUTPUT(q->type) && cap_streaming) ||
+ (V4L2_TYPE_IS_CAPTURE(q->type) && out_streaming)) {
+ ret = mdp_check_scaling_ratio(&capture->crop.c,
+ &capture->compose,
+ capture->rotation,
+ ctx->curr_param.limit);
+ if (ret) {
+ dev_err(&ctx->mdp_dev->pdev->dev,
+ "Out of scaling range\n");
+ return ret;
+ }
+ }
+
+ if (!mdp_m2m_ctx_is_state_set(ctx, MDP_VPU_INIT)) {
+ ret = mdp_vpu_get_locked(ctx->mdp_dev);
+ if (ret)
+ return ret;
+
+ ret = mdp_vpu_ctx_init(&ctx->vpu, &ctx->mdp_dev->vpu,
+ MDP_DEV_M2M);
+ if (ret) {
+ dev_err(&ctx->mdp_dev->pdev->dev,
+ "VPU init failed %d\n", ret);
+ return -EINVAL;
+ }
+ mdp_m2m_ctx_set_state(ctx, MDP_VPU_INIT);
+ }
+
+ return 0;
+}
+
+static struct vb2_v4l2_buffer *mdp_m2m_buf_remove(struct mdp_m2m_ctx *ctx,
+ unsigned int type)
+{
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ return (struct vb2_v4l2_buffer *)
+ v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ else
+ return (struct vb2_v4l2_buffer *)
+ v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+}
+
+static void mdp_m2m_stop_streaming(struct vb2_queue *q)
+{
+ struct mdp_m2m_ctx *ctx = vb2_get_drv_priv(q);
+ struct vb2_v4l2_buffer *vb;
+
+ vb = mdp_m2m_buf_remove(ctx, q->type);
+ while (vb) {
+ v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+ vb = mdp_m2m_buf_remove(ctx, q->type);
+ }
+}
+
+static int mdp_m2m_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers,
+ unsigned int *num_planes, unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ struct mdp_m2m_ctx *ctx = vb2_get_drv_priv(q);
+ struct v4l2_pix_format_mplane *pix_mp;
+ u32 i;
+
+ pix_mp = &ctx_get_frame(ctx, q->type)->format.fmt.pix_mp;
+
+ /* from VIDIOC_CREATE_BUFS */
+ if (*num_planes) {
+ if (*num_planes != pix_mp->num_planes)
+ return -EINVAL;
+ for (i = 0; i < pix_mp->num_planes; ++i)
+ if (sizes[i] < pix_mp->plane_fmt[i].sizeimage)
+ return -EINVAL;
+ } else {/* from VIDIOC_REQBUFS */
+ *num_planes = pix_mp->num_planes;
+ for (i = 0; i < pix_mp->num_planes; ++i)
+ sizes[i] = pix_mp->plane_fmt[i].sizeimage;
+ }
+
+ return 0;
+}
+
+static int mdp_m2m_buf_prepare(struct vb2_buffer *vb)
+{
+ struct mdp_m2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct v4l2_pix_format_mplane *pix_mp;
+ struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb);
+ u32 i;
+
+ v4l2_buf->field = V4L2_FIELD_NONE;
+
+ if (V4L2_TYPE_IS_CAPTURE(vb->type)) {
+ pix_mp = &ctx_get_frame(ctx, vb->type)->format.fmt.pix_mp;
+ for (i = 0; i < pix_mp->num_planes; ++i) {
+ vb2_set_plane_payload(vb, i,
+ pix_mp->plane_fmt[i].sizeimage);
+ }
+ }
+ return 0;
+}
+
+static int mdp_m2m_buf_out_validate(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb);
+
+ v4l2_buf->field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static void mdp_m2m_buf_queue(struct vb2_buffer *vb)
+{
+ struct mdp_m2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb);
+
+ v4l2_buf->field = V4L2_FIELD_NONE;
+
+ v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
+}
+
+static const struct vb2_ops mdp_m2m_qops = {
+ .queue_setup = mdp_m2m_queue_setup,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .buf_prepare = mdp_m2m_buf_prepare,
+ .start_streaming = mdp_m2m_start_streaming,
+ .stop_streaming = mdp_m2m_stop_streaming,
+ .buf_queue = mdp_m2m_buf_queue,
+ .buf_out_validate = mdp_m2m_buf_out_validate,
+};
+
+static int mdp_m2m_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ strscpy(cap->driver, MDP_MODULE_NAME, sizeof(cap->driver));
+ strscpy(cap->card, MDP_DEVICE_NAME, sizeof(cap->card));
+
+ return 0;
+}
+
+static int mdp_m2m_enum_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_fmtdesc *f)
+{
+ return mdp_enum_fmt_mplane(f);
+}
+
+static int mdp_m2m_g_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_frame *frame;
+ struct v4l2_pix_format_mplane *pix_mp;
+
+ frame = ctx_get_frame(ctx, f->type);
+ *f = frame->format;
+ pix_mp = &f->fmt.pix_mp;
+ pix_mp->colorspace = ctx->curr_param.colorspace;
+ pix_mp->xfer_func = ctx->curr_param.xfer_func;
+ pix_mp->ycbcr_enc = ctx->curr_param.ycbcr_enc;
+ pix_mp->quantization = ctx->curr_param.quant;
+
+ return 0;
+}
+
+static int mdp_m2m_s_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_frame *frame = ctx_get_frame(ctx, f->type);
+ struct mdp_frame *capture;
+ const struct mdp_format *fmt;
+ struct vb2_queue *vq;
+
+ fmt = mdp_try_fmt_mplane(f, &ctx->curr_param, ctx->id);
+ if (!fmt)
+ return -EINVAL;
+
+ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ if (vb2_is_busy(vq))
+ return -EBUSY;
+
+ frame->format = *f;
+ frame->mdp_fmt = fmt;
+ frame->ycbcr_prof = mdp_map_ycbcr_prof_mplane(f, fmt->mdp_color);
+ frame->usage = V4L2_TYPE_IS_OUTPUT(f->type) ?
+ MDP_BUFFER_USAGE_HW_READ : MDP_BUFFER_USAGE_MDP;
+
+ capture = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+ capture->crop.c.left = 0;
+ capture->crop.c.top = 0;
+ capture->crop.c.width = f->fmt.pix_mp.width;
+ capture->crop.c.height = f->fmt.pix_mp.height;
+ ctx->curr_param.colorspace = f->fmt.pix_mp.colorspace;
+ ctx->curr_param.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
+ ctx->curr_param.quant = f->fmt.pix_mp.quantization;
+ ctx->curr_param.xfer_func = f->fmt.pix_mp.xfer_func;
+ } else {
+ capture->compose.left = 0;
+ capture->compose.top = 0;
+ capture->compose.width = f->fmt.pix_mp.width;
+ capture->compose.height = f->fmt.pix_mp.height;
+ }
+
+ return 0;
+}
+
+static int mdp_m2m_try_fmt_mplane(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+
+ if (!mdp_try_fmt_mplane(f, &ctx->curr_param, ctx->id))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mdp_m2m_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_frame *frame;
+ bool valid = false;
+
+ if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ valid = mdp_target_is_crop(s->target);
+ else if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ valid = mdp_target_is_compose(s->target);
+
+ if (!valid)
+ return -EINVAL;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ s->r = frame->crop.c;
+ return 0;
+ case V4L2_SEL_TGT_COMPOSE:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ s->r = frame->compose;
+ return 0;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ frame = ctx_get_frame(ctx, s->type);
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = frame->format.fmt.pix_mp.width;
+ s->r.height = frame->format.fmt.pix_mp.height;
+ return 0;
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ frame = ctx_get_frame(ctx, s->type);
+ s->r.left = 0;
+ s->r.top = 0;
+ s->r.width = frame->format.fmt.pix_mp.width;
+ s->r.height = frame->format.fmt.pix_mp.height;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int mdp_m2m_s_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct mdp_m2m_ctx *ctx = fh_to_ctx(fh);
+ struct mdp_frame *frame = ctx_get_frame(ctx, s->type);
+ struct mdp_frame *capture;
+ struct v4l2_rect r;
+ struct device *dev = &ctx->mdp_dev->pdev->dev;
+ bool valid = false;
+ int ret;
+
+ if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ valid = (s->target == V4L2_SEL_TGT_CROP);
+ else if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ valid = (s->target == V4L2_SEL_TGT_COMPOSE);
+
+ if (!valid) {
+ dev_dbg(dev, "[%s:%d] invalid type:%u target:%u", __func__,
+ ctx->id, s->type, s->target);
+ return -EINVAL;
+ }
+
+ ret = mdp_try_crop(ctx, &r, s, frame);
+ if (ret)
+ return ret;
+ capture = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+ if (mdp_target_is_crop(s->target))
+ capture->crop.c = r;
+ else
+ capture->compose = r;
+
+ s->r = r;
+
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops mdp_m2m_ioctl_ops = {
+ .vidioc_querycap = mdp_m2m_querycap,
+ .vidioc_enum_fmt_vid_cap = mdp_m2m_enum_fmt_mplane,
+ .vidioc_enum_fmt_vid_out = mdp_m2m_enum_fmt_mplane,
+ .vidioc_g_fmt_vid_cap_mplane = mdp_m2m_g_fmt_mplane,
+ .vidioc_g_fmt_vid_out_mplane = mdp_m2m_g_fmt_mplane,
+ .vidioc_s_fmt_vid_cap_mplane = mdp_m2m_s_fmt_mplane,
+ .vidioc_s_fmt_vid_out_mplane = mdp_m2m_s_fmt_mplane,
+ .vidioc_try_fmt_vid_cap_mplane = mdp_m2m_try_fmt_mplane,
+ .vidioc_try_fmt_vid_out_mplane = mdp_m2m_try_fmt_mplane,
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+ .vidioc_g_selection = mdp_m2m_g_selection,
+ .vidioc_s_selection = mdp_m2m_s_selection,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static int mdp_m2m_queue_init(void *priv,
+ struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct mdp_m2m_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ src_vq->ops = &mdp_m2m_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->drv_priv = ctx;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->dev = &ctx->mdp_dev->pdev->dev;
+ src_vq->lock = &ctx->ctx_lock;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ dst_vq->ops = &mdp_m2m_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->drv_priv = ctx;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->dev = &ctx->mdp_dev->pdev->dev;
+ dst_vq->lock = &ctx->ctx_lock;
+
+ return vb2_queue_init(dst_vq);
+}
+
+static int mdp_m2m_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct mdp_m2m_ctx *ctx = ctrl_to_ctx(ctrl);
+ struct mdp_frame *capture;
+
+ capture = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ switch (ctrl->id) {
+ case V4L2_CID_HFLIP:
+ capture->hflip = ctrl->val;
+ break;
+ case V4L2_CID_VFLIP:
+ capture->vflip = ctrl->val;
+ break;
+ case V4L2_CID_ROTATE:
+ capture->rotation = ctrl->val;
+ break;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops mdp_m2m_ctrl_ops = {
+ .s_ctrl = mdp_m2m_s_ctrl,
+};
+
+static int mdp_m2m_ctrls_create(struct mdp_m2m_ctx *ctx)
+{
+ v4l2_ctrl_handler_init(&ctx->ctrl_handler, MDP_MAX_CTRLS);
+ ctx->ctrls.hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &mdp_m2m_ctrl_ops, V4L2_CID_HFLIP,
+ 0, 1, 1, 0);
+ ctx->ctrls.vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &mdp_m2m_ctrl_ops, V4L2_CID_VFLIP,
+ 0, 1, 1, 0);
+ ctx->ctrls.rotate = v4l2_ctrl_new_std(&ctx->ctrl_handler,
+ &mdp_m2m_ctrl_ops,
+ V4L2_CID_ROTATE, 0, 270, 90, 0);
+
+ if (ctx->ctrl_handler.error) {
+ int err = ctx->ctrl_handler.error;
+
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ dev_err(&ctx->mdp_dev->pdev->dev,
+ "Failed to register controls\n");
+ return err;
+ }
+ return 0;
+}
+
+static int mdp_m2m_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct mdp_dev *mdp = video_get_drvdata(vdev);
+ struct mdp_m2m_ctx *ctx;
+ struct device *dev = &mdp->pdev->dev;
+ int ret;
+ struct v4l2_format default_format = {};
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ if (mutex_lock_interruptible(&mdp->m2m_lock)) {
+ ret = -ERESTARTSYS;
+ goto err_free_ctx;
+ }
+
+ ctx->id = ida_alloc(&mdp->mdp_ida, GFP_KERNEL);
+ ctx->mdp_dev = mdp;
+
+ v4l2_fh_init(&ctx->fh, vdev);
+ file->private_data = &ctx->fh;
+ ret = mdp_m2m_ctrls_create(ctx);
+ if (ret)
+ goto err_exit_fh;
+
+ /* Use separate control handler per file handle */
+ ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+ v4l2_fh_add(&ctx->fh);
+
+ mutex_init(&ctx->ctx_lock);
+ ctx->m2m_ctx = v4l2_m2m_ctx_init(mdp->m2m_dev, ctx, mdp_m2m_queue_init);
+ if (IS_ERR(ctx->m2m_ctx)) {
+ dev_err(dev, "Failed to initialize m2m context\n");
+ ret = PTR_ERR(ctx->m2m_ctx);
+ goto err_release_handler;
+ }
+ ctx->fh.m2m_ctx = ctx->m2m_ctx;
+
+ ctx->curr_param.ctx = ctx;
+ ret = mdp_frameparam_init(&ctx->curr_param);
+ if (ret) {
+ dev_err(dev, "Failed to initialize mdp parameter\n");
+ goto err_release_m2m_ctx;
+ }
+
+ mutex_unlock(&mdp->m2m_lock);
+
+ /* Default format */
+ default_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ default_format.fmt.pix_mp.width = 32;
+ default_format.fmt.pix_mp.height = 32;
+ default_format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420M;
+ mdp_m2m_s_fmt_mplane(file, &ctx->fh, &default_format);
+ default_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ mdp_m2m_s_fmt_mplane(file, &ctx->fh, &default_format);
+
+ dev_dbg(dev, "%s:[%d]", __func__, ctx->id);
+
+ return 0;
+
+err_release_m2m_ctx:
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
+err_release_handler:
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ v4l2_fh_del(&ctx->fh);
+err_exit_fh:
+ v4l2_fh_exit(&ctx->fh);
+ mutex_unlock(&mdp->m2m_lock);
+err_free_ctx:
+ kfree(ctx);
+
+ return ret;
+}
+
+static int mdp_m2m_release(struct file *file)
+{
+ struct mdp_m2m_ctx *ctx = fh_to_ctx(file->private_data);
+ struct mdp_dev *mdp = video_drvdata(file);
+ struct device *dev = &mdp->pdev->dev;
+
+ mutex_lock(&mdp->m2m_lock);
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ if (mdp_m2m_ctx_is_state_set(ctx, MDP_VPU_INIT)) {
+ mdp_vpu_ctx_deinit(&ctx->vpu);
+ mdp_vpu_put_locked(mdp);
+ }
+
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ ida_free(&mdp->mdp_ida, ctx->id);
+ mutex_unlock(&mdp->m2m_lock);
+
+ dev_dbg(dev, "%s:[%d]", __func__, ctx->id);
+ kfree(ctx);
+
+ return 0;
+}
+
+static const struct v4l2_file_operations mdp_m2m_fops = {
+ .owner = THIS_MODULE,
+ .poll = v4l2_m2m_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = v4l2_m2m_fop_mmap,
+ .open = mdp_m2m_open,
+ .release = mdp_m2m_release,
+};
+
+static const struct v4l2_m2m_ops mdp_m2m_ops = {
+ .device_run = mdp_m2m_device_run,
+};
+
+int mdp_m2m_device_register(struct mdp_dev *mdp)
+{
+ struct device *dev = &mdp->pdev->dev;
+ int ret = 0;
+
+ mdp->m2m_vdev = video_device_alloc();
+ if (!mdp->m2m_vdev) {
+ dev_err(dev, "Failed to allocate video device\n");
+ ret = -ENOMEM;
+ goto err_video_alloc;
+ }
+ mdp->m2m_vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE |
+ V4L2_CAP_STREAMING;
+ mdp->m2m_vdev->fops = &mdp_m2m_fops;
+ mdp->m2m_vdev->ioctl_ops = &mdp_m2m_ioctl_ops;
+ mdp->m2m_vdev->release = mdp_video_device_release;
+ mdp->m2m_vdev->lock = &mdp->m2m_lock;
+ mdp->m2m_vdev->vfl_dir = VFL_DIR_M2M;
+ mdp->m2m_vdev->v4l2_dev = &mdp->v4l2_dev;
+ snprintf(mdp->m2m_vdev->name, sizeof(mdp->m2m_vdev->name), "%s:m2m",
+ MDP_MODULE_NAME);
+ video_set_drvdata(mdp->m2m_vdev, mdp);
+
+ mdp->m2m_dev = v4l2_m2m_init(&mdp_m2m_ops);
+ if (IS_ERR(mdp->m2m_dev)) {
+ dev_err(dev, "Failed to initialize v4l2-m2m device\n");
+ ret = PTR_ERR(mdp->m2m_dev);
+ goto err_m2m_init;
+ }
+
+ ret = video_register_device(mdp->m2m_vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(dev, "Failed to register video device\n");
+ goto err_video_register;
+ }
+
+ v4l2_info(&mdp->v4l2_dev, "Driver registered as /dev/video%d",
+ mdp->m2m_vdev->num);
+ return 0;
+
+err_video_register:
+ v4l2_m2m_release(mdp->m2m_dev);
+err_m2m_init:
+ video_device_release(mdp->m2m_vdev);
+err_video_alloc:
+
+ return ret;
+}
+
+void mdp_m2m_device_unregister(struct mdp_dev *mdp)
+{
+ video_unregister_device(mdp->m2m_vdev);
+}
+
+void mdp_m2m_job_finish(struct mdp_m2m_ctx *ctx)
+{
+ enum vb2_buffer_state vb_state = VB2_BUF_STATE_DONE;
+
+ mdp_m2m_process_done(ctx, vb_state);
+}
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.h
new file mode 100644
index 000000000000..61ddbaf1bf13
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MTK_MDP3_M2M_H__
+#define __MTK_MDP3_M2M_H__
+
+#include <media/v4l2-ctrls.h>
+#include "mtk-mdp3-core.h"
+#include "mtk-mdp3-vpu.h"
+#include "mtk-mdp3-regs.h"
+
+#define MDP_MAX_CTRLS 10
+
+enum {
+ MDP_M2M_SRC = 0,
+ MDP_M2M_DST = 1,
+ MDP_M2M_MAX,
+};
+
+struct mdp_m2m_ctrls {
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *rotate;
+};
+
+struct mdp_m2m_ctx {
+ u32 id;
+ struct mdp_dev *mdp_dev;
+ struct v4l2_fh fh;
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct mdp_m2m_ctrls ctrls;
+ struct v4l2_m2m_ctx *m2m_ctx;
+ struct mdp_vpu_ctx vpu;
+ u32 frame_count[MDP_M2M_MAX];
+
+ struct mdp_frameparam curr_param;
+ /* synchronization protect for mdp m2m context */
+ struct mutex ctx_lock;
+};
+
+int mdp_m2m_device_register(struct mdp_dev *mdp);
+void mdp_m2m_device_unregister(struct mdp_dev *mdp);
+void mdp_m2m_job_finish(struct mdp_m2m_ctx *ctx);
+
+#endif /* __MTK_MDP3_M2M_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
new file mode 100644
index 000000000000..4e84a37ecdfc
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.c
@@ -0,0 +1,735 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#include <media/v4l2-common.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include "mtk-mdp3-core.h"
+#include "mtk-mdp3-regs.h"
+#include "mtk-mdp3-m2m.h"
+
+/*
+ * All 10-bit related formats are not added in the basic format list,
+ * please add the corresponding format settings before use.
+ */
+static const struct mdp_format mdp_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,
+ }, {
+ .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,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV24,
+ .mdp_color = MDP_COLOR_NV24,
+ .depth = { 24 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_NV42,
+ .mdp_color = MDP_COLOR_NV42,
+ .depth = { 24 },
+ .row_depth = { 8 },
+ .num_planes = 1,
+ .flags = MDP_FMT_FLAG_OUTPUT,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_MT21C,
+ .mdp_color = MDP_COLOR_420_BLK_UFO,
+ .depth = { 8, 4 },
+ .row_depth = { 8, 8 },
+ .num_planes = 2,
+ .walign = 4,
+ .halign = 5,
+ .flags = MDP_FMT_FLAG_OUTPUT,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_MM21,
+ .mdp_color = MDP_COLOR_420_BLK,
+ .depth = { 8, 4 },
+ .row_depth = { 8, 8 },
+ .num_planes = 2,
+ .walign = 4,
+ .halign = 5,
+ .flags = MDP_FMT_FLAG_OUTPUT,
+ }, {
+ .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_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,
+ }, {
+ .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,
+ }, {
+ .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,
+ }
+};
+
+static const struct mdp_limit mdp_def_limit = {
+ .out_limit = {
+ .wmin = 16,
+ .hmin = 16,
+ .wmax = 8176,
+ .hmax = 8176,
+ },
+ .cap_limit = {
+ .wmin = 2,
+ .hmin = 2,
+ .wmax = 8176,
+ .hmax = 8176,
+ },
+ .h_scale_up_max = 32,
+ .v_scale_up_max = 32,
+ .h_scale_down_max = 20,
+ .v_scale_down_max = 128,
+};
+
+static const struct mdp_format *mdp_find_fmt(u32 pixelformat, u32 type)
+{
+ u32 i, flag;
+
+ flag = V4L2_TYPE_IS_OUTPUT(type) ? MDP_FMT_FLAG_OUTPUT :
+ MDP_FMT_FLAG_CAPTURE;
+ for (i = 0; i < ARRAY_SIZE(mdp_formats); ++i) {
+ if (!(mdp_formats[i].flags & flag))
+ continue;
+ if (mdp_formats[i].pixelformat == pixelformat)
+ return &mdp_formats[i];
+ }
+ return NULL;
+}
+
+static const struct mdp_format *mdp_find_fmt_by_index(u32 index, u32 type)
+{
+ u32 i, flag, num = 0;
+
+ flag = V4L2_TYPE_IS_OUTPUT(type) ? MDP_FMT_FLAG_OUTPUT :
+ MDP_FMT_FLAG_CAPTURE;
+ for (i = 0; i < ARRAY_SIZE(mdp_formats); ++i) {
+ if (!(mdp_formats[i].flags & flag))
+ continue;
+ if (index == num)
+ return &mdp_formats[i];
+ num++;
+ }
+ return NULL;
+}
+
+enum mdp_ycbcr_profile mdp_map_ycbcr_prof_mplane(struct v4l2_format *f,
+ u32 mdp_color)
+{
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+
+ if (MDP_COLOR_IS_RGB(mdp_color))
+ return MDP_YCBCR_PROFILE_FULL_BT601;
+
+ switch (pix_mp->colorspace) {
+ case V4L2_COLORSPACE_JPEG:
+ return MDP_YCBCR_PROFILE_JPEG;
+ case V4L2_COLORSPACE_REC709:
+ case V4L2_COLORSPACE_DCI_P3:
+ if (pix_mp->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ return MDP_YCBCR_PROFILE_FULL_BT709;
+ return MDP_YCBCR_PROFILE_BT709;
+ case V4L2_COLORSPACE_BT2020:
+ if (pix_mp->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ return MDP_YCBCR_PROFILE_FULL_BT2020;
+ return MDP_YCBCR_PROFILE_BT2020;
+ default:
+ if (pix_mp->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ return MDP_YCBCR_PROFILE_FULL_BT601;
+ return MDP_YCBCR_PROFILE_BT601;
+ }
+}
+
+static void mdp_bound_align_image(u32 *w, u32 *h,
+ struct v4l2_frmsize_stepwise *s,
+ unsigned int salign)
+{
+ unsigned int org_w, org_h;
+
+ org_w = *w;
+ org_h = *h;
+ v4l_bound_align_image(w, s->min_width, s->max_width, s->step_width,
+ h, s->min_height, s->max_height, s->step_height,
+ salign);
+
+ s->min_width = org_w;
+ s->min_height = org_h;
+ v4l2_apply_frmsize_constraints(w, h, s);
+}
+
+static int mdp_clamp_align(s32 *x, int min, int max, unsigned int align)
+{
+ unsigned int mask;
+
+ if (min < 0 || max < 0)
+ return -ERANGE;
+
+ /* Bits that must be zero to be aligned */
+ mask = ~((1 << align) - 1);
+
+ min = 0 ? 0 : ((min + ~mask) & mask);
+ max = max & mask;
+ if ((unsigned int)min > (unsigned int)max)
+ return -ERANGE;
+
+ /* Clamp to aligned min and max */
+ *x = clamp(*x, min, max);
+
+ /* Round to nearest aligned value */
+ if (align)
+ *x = (*x + (1 << (align - 1))) & mask;
+ return 0;
+}
+
+int mdp_enum_fmt_mplane(struct v4l2_fmtdesc *f)
+{
+ const struct mdp_format *fmt;
+
+ fmt = mdp_find_fmt_by_index(f->index, f->type);
+ if (!fmt)
+ return -EINVAL;
+
+ f->pixelformat = fmt->pixelformat;
+ return 0;
+}
+
+const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f,
+ struct mdp_frameparam *param,
+ u32 ctx_id)
+{
+ struct device *dev = &param->ctx->mdp_dev->pdev->dev;
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ const struct mdp_format *fmt;
+ const struct mdp_pix_limit *pix_limit;
+ struct v4l2_frmsize_stepwise s;
+ u32 org_w, org_h;
+ unsigned int i;
+
+ fmt = mdp_find_fmt(pix_mp->pixelformat, f->type);
+ if (!fmt) {
+ fmt = mdp_find_fmt_by_index(0, f->type);
+ if (!fmt) {
+ dev_dbg(dev, "%d: pixelformat %c%c%c%c invalid", ctx_id,
+ (pix_mp->pixelformat & 0xff),
+ (pix_mp->pixelformat >> 8) & 0xff,
+ (pix_mp->pixelformat >> 16) & 0xff,
+ (pix_mp->pixelformat >> 24) & 0xff);
+ return NULL;
+ }
+ }
+
+ pix_mp->field = V4L2_FIELD_NONE;
+ pix_mp->flags = 0;
+ pix_mp->pixelformat = fmt->pixelformat;
+ if (V4L2_TYPE_IS_CAPTURE(f->type)) {
+ pix_mp->colorspace = param->colorspace;
+ pix_mp->xfer_func = param->xfer_func;
+ pix_mp->ycbcr_enc = param->ycbcr_enc;
+ pix_mp->quantization = param->quant;
+ }
+
+ pix_limit = V4L2_TYPE_IS_OUTPUT(f->type) ? &param->limit->out_limit :
+ &param->limit->cap_limit;
+ s.min_width = pix_limit->wmin;
+ s.max_width = pix_limit->wmax;
+ s.step_width = fmt->walign;
+ s.min_height = pix_limit->hmin;
+ s.max_height = pix_limit->hmax;
+ s.step_height = fmt->halign;
+ org_w = pix_mp->width;
+ org_h = pix_mp->height;
+
+ mdp_bound_align_image(&pix_mp->width, &pix_mp->height, &s, fmt->salign);
+ if (org_w != pix_mp->width || org_h != pix_mp->height)
+ dev_dbg(dev, "%d: size change: %ux%u to %ux%u", ctx_id,
+ org_w, org_h, pix_mp->width, pix_mp->height);
+
+ if (pix_mp->num_planes && pix_mp->num_planes != fmt->num_planes)
+ dev_dbg(dev, "%d num of planes change: %u to %u", ctx_id,
+ pix_mp->num_planes, fmt->num_planes);
+ pix_mp->num_planes = fmt->num_planes;
+
+ for (i = 0; i < pix_mp->num_planes; ++i) {
+ u32 min_bpl = (pix_mp->width * fmt->row_depth[i]) >> 3;
+ u32 max_bpl = (pix_limit->wmax * fmt->row_depth[i]) >> 3;
+ u32 bpl = pix_mp->plane_fmt[i].bytesperline;
+ u32 min_si, max_si;
+ u32 si = pix_mp->plane_fmt[i].sizeimage;
+
+ bpl = clamp(bpl, min_bpl, max_bpl);
+ pix_mp->plane_fmt[i].bytesperline = bpl;
+
+ min_si = (bpl * pix_mp->height * fmt->depth[i]) /
+ fmt->row_depth[i];
+ max_si = (bpl * s.max_height * fmt->depth[i]) /
+ fmt->row_depth[i];
+
+ si = clamp(si, min_si, max_si);
+ pix_mp->plane_fmt[i].sizeimage = si;
+
+ dev_dbg(dev, "%d: p%u, bpl:%u [%u, %u], sizeimage:%u [%u, %u]",
+ ctx_id, i, bpl, min_bpl, max_bpl, si, min_si, max_si);
+ }
+
+ return fmt;
+}
+
+static int mdp_clamp_start(s32 *x, int min, int max, unsigned int align,
+ u32 flags)
+{
+ if (flags & V4L2_SEL_FLAG_GE)
+ max = *x;
+ if (flags & V4L2_SEL_FLAG_LE)
+ min = *x;
+ return mdp_clamp_align(x, min, max, align);
+}
+
+static int mdp_clamp_end(s32 *x, int min, int max, unsigned int align,
+ u32 flags)
+{
+ if (flags & V4L2_SEL_FLAG_GE)
+ min = *x;
+ if (flags & V4L2_SEL_FLAG_LE)
+ max = *x;
+ return mdp_clamp_align(x, min, max, align);
+}
+
+int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r,
+ const struct v4l2_selection *s, struct mdp_frame *frame)
+{
+ struct device *dev = &ctx->mdp_dev->pdev->dev;
+ s32 left, top, right, bottom;
+ u32 framew, frameh, walign, halign;
+ int ret;
+
+ dev_dbg(dev, "%d target:%d, set:(%d,%d) %ux%u", ctx->id,
+ s->target, s->r.left, s->r.top, s->r.width, s->r.height);
+
+ left = s->r.left;
+ top = s->r.top;
+ right = s->r.left + s->r.width;
+ bottom = s->r.top + s->r.height;
+ framew = frame->format.fmt.pix_mp.width;
+ frameh = frame->format.fmt.pix_mp.height;
+
+ if (mdp_target_is_crop(s->target)) {
+ walign = 1;
+ halign = 1;
+ } else {
+ walign = frame->mdp_fmt->walign;
+ halign = frame->mdp_fmt->halign;
+ }
+
+ dev_dbg(dev, "%d align:%u,%u, bound:%ux%u", ctx->id,
+ walign, halign, framew, frameh);
+
+ ret = mdp_clamp_start(&left, 0, right, walign, s->flags);
+ if (ret)
+ return ret;
+ ret = mdp_clamp_start(&top, 0, bottom, halign, s->flags);
+ if (ret)
+ return ret;
+ ret = mdp_clamp_end(&right, left, framew, walign, s->flags);
+ if (ret)
+ return ret;
+ ret = mdp_clamp_end(&bottom, top, frameh, halign, s->flags);
+ if (ret)
+ return ret;
+
+ r->left = left;
+ r->top = top;
+ r->width = right - left;
+ r->height = bottom - top;
+
+ dev_dbg(dev, "%d crop:(%d,%d) %ux%u", ctx->id,
+ r->left, r->top, r->width, r->height);
+ return 0;
+}
+
+int mdp_check_scaling_ratio(const struct v4l2_rect *crop,
+ const struct v4l2_rect *compose, s32 rotation,
+ const struct mdp_limit *limit)
+{
+ u32 crop_w, crop_h, comp_w, comp_h;
+
+ crop_w = crop->width;
+ crop_h = crop->height;
+ if (90 == rotation || 270 == rotation) {
+ comp_w = compose->height;
+ comp_h = compose->width;
+ } else {
+ comp_w = compose->width;
+ comp_h = compose->height;
+ }
+
+ if ((crop_w / comp_w) > limit->h_scale_down_max ||
+ (crop_h / comp_h) > limit->v_scale_down_max ||
+ (comp_w / crop_w) > limit->h_scale_up_max ||
+ (comp_h / crop_h) > limit->v_scale_up_max)
+ return -ERANGE;
+ return 0;
+}
+
+/* Stride that is accepted by MDP HW */
+static u32 mdp_fmt_get_stride(const struct mdp_format *fmt,
+ u32 bytesperline, unsigned int plane)
+{
+ enum mdp_color c = fmt->mdp_color;
+ u32 stride;
+
+ stride = (bytesperline * MDP_COLOR_BITS_PER_PIXEL(c))
+ / fmt->row_depth[0];
+ if (plane == 0)
+ return stride;
+ if (plane < MDP_COLOR_GET_PLANE_COUNT(c)) {
+ if (MDP_COLOR_IS_BLOCK_MODE(c))
+ stride = stride / 2;
+ return stride;
+ }
+ return 0;
+}
+
+/* Stride that is accepted by MDP HW of format with contiguous planes */
+static u32 mdp_fmt_get_stride_contig(const struct mdp_format *fmt,
+ u32 pix_stride, unsigned int plane)
+{
+ enum mdp_color c = fmt->mdp_color;
+ u32 stride = pix_stride;
+
+ if (plane == 0)
+ return stride;
+ if (plane < MDP_COLOR_GET_PLANE_COUNT(c)) {
+ stride = stride >> MDP_COLOR_GET_H_SUBSAMPLE(c);
+ if (MDP_COLOR_IS_UV_COPLANE(c) && !MDP_COLOR_IS_BLOCK_MODE(c))
+ stride = stride * 2;
+ return stride;
+ }
+ return 0;
+}
+
+/* Plane size that is accepted by MDP HW */
+static u32 mdp_fmt_get_plane_size(const struct mdp_format *fmt,
+ u32 stride, u32 height, unsigned int plane)
+{
+ enum mdp_color c = fmt->mdp_color;
+ u32 bytesperline;
+
+ bytesperline = (stride * fmt->row_depth[0])
+ / MDP_COLOR_BITS_PER_PIXEL(c);
+ if (plane == 0)
+ return bytesperline * height;
+ if (plane < MDP_COLOR_GET_PLANE_COUNT(c)) {
+ height = height >> MDP_COLOR_GET_V_SUBSAMPLE(c);
+ if (MDP_COLOR_IS_BLOCK_MODE(c))
+ bytesperline = bytesperline * 2;
+ return bytesperline * height;
+ }
+ return 0;
+}
+
+static void mdp_prepare_buffer(struct img_image_buffer *b,
+ struct mdp_frame *frame, struct vb2_buffer *vb)
+{
+ struct v4l2_pix_format_mplane *pix_mp = &frame->format.fmt.pix_mp;
+ unsigned int i;
+
+ b->format.colorformat = frame->mdp_fmt->mdp_color;
+ b->format.ycbcr_prof = frame->ycbcr_prof;
+ for (i = 0; i < pix_mp->num_planes; ++i) {
+ u32 stride = mdp_fmt_get_stride(frame->mdp_fmt,
+ pix_mp->plane_fmt[i].bytesperline, i);
+
+ b->format.plane_fmt[i].stride = stride;
+ b->format.plane_fmt[i].size =
+ mdp_fmt_get_plane_size(frame->mdp_fmt, stride,
+ pix_mp->height, i);
+ b->iova[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+ }
+ for (; i < MDP_COLOR_GET_PLANE_COUNT(b->format.colorformat); ++i) {
+ u32 stride = mdp_fmt_get_stride_contig(frame->mdp_fmt,
+ b->format.plane_fmt[0].stride, i);
+
+ b->format.plane_fmt[i].stride = stride;
+ b->format.plane_fmt[i].size =
+ mdp_fmt_get_plane_size(frame->mdp_fmt, stride,
+ pix_mp->height, i);
+ b->iova[i] = b->iova[i - 1] + b->format.plane_fmt[i - 1].size;
+ }
+ b->usage = frame->usage;
+}
+
+void mdp_set_src_config(struct img_input *in,
+ struct mdp_frame *frame, struct vb2_buffer *vb)
+{
+ in->buffer.format.width = frame->format.fmt.pix_mp.width;
+ in->buffer.format.height = frame->format.fmt.pix_mp.height;
+ mdp_prepare_buffer(&in->buffer, frame, vb);
+}
+
+static u32 mdp_to_fixed(u32 *r, struct v4l2_fract *f)
+{
+ u32 q;
+
+ if (f->denominator == 0) {
+ *r = 0;
+ return 0;
+ }
+
+ q = f->numerator / f->denominator;
+ *r = div_u64(((u64)f->numerator - q * f->denominator) <<
+ IMG_SUBPIXEL_SHIFT, f->denominator);
+ return q;
+}
+
+static void mdp_set_src_crop(struct img_crop *c, struct mdp_crop *crop)
+{
+ c->left = crop->c.left
+ + mdp_to_fixed(&c->left_subpix, &crop->left_subpix);
+ c->top = crop->c.top
+ + mdp_to_fixed(&c->top_subpix, &crop->top_subpix);
+ c->width = crop->c.width
+ + mdp_to_fixed(&c->width_subpix, &crop->width_subpix);
+ c->height = crop->c.height
+ + mdp_to_fixed(&c->height_subpix, &crop->height_subpix);
+}
+
+static void mdp_set_orientation(struct img_output *out,
+ s32 rotation, bool hflip, bool vflip)
+{
+ u8 flip = 0;
+
+ if (hflip)
+ flip ^= 1;
+ if (vflip) {
+ /*
+ * A vertical flip is equivalent to
+ * a 180-degree rotation with a horizontal flip
+ */
+ rotation += 180;
+ flip ^= 1;
+ }
+
+ out->rotation = rotation % 360;
+ if (flip != 0)
+ out->flags |= IMG_CTRL_FLAG_HFLIP;
+ else
+ out->flags &= ~IMG_CTRL_FLAG_HFLIP;
+}
+
+void mdp_set_dst_config(struct img_output *out,
+ struct mdp_frame *frame, struct vb2_buffer *vb)
+{
+ out->buffer.format.width = frame->compose.width;
+ out->buffer.format.height = frame->compose.height;
+ mdp_prepare_buffer(&out->buffer, frame, vb);
+ mdp_set_src_crop(&out->crop, &frame->crop);
+ mdp_set_orientation(out, frame->rotation, frame->hflip, frame->vflip);
+}
+
+int mdp_frameparam_init(struct mdp_frameparam *param)
+{
+ struct mdp_frame *frame;
+
+ if (!param)
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&param->list);
+ param->limit = &mdp_def_limit;
+ param->type = MDP_STREAM_TYPE_BITBLT;
+
+ frame = &param->output;
+ frame->format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ frame->mdp_fmt = mdp_try_fmt_mplane(&frame->format, param, 0);
+ frame->ycbcr_prof =
+ mdp_map_ycbcr_prof_mplane(&frame->format,
+ frame->mdp_fmt->mdp_color);
+ frame->usage = MDP_BUFFER_USAGE_HW_READ;
+
+ param->num_captures = 1;
+ frame = &param->captures[0];
+ frame->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ frame->mdp_fmt = mdp_try_fmt_mplane(&frame->format, param, 0);
+ frame->ycbcr_prof =
+ mdp_map_ycbcr_prof_mplane(&frame->format,
+ frame->mdp_fmt->mdp_color);
+ frame->usage = MDP_BUFFER_USAGE_MDP;
+ frame->crop.c.width = param->output.format.fmt.pix_mp.width;
+ frame->crop.c.height = param->output.format.fmt.pix_mp.height;
+ frame->compose.width = frame->format.fmt.pix_mp.width;
+ frame->compose.height = frame->format.fmt.pix_mp.height;
+
+ return 0;
+}
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h
new file mode 100644
index 000000000000..f995e536d45f
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-regs.h
@@ -0,0 +1,373 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MTK_MDP3_REGS_H__
+#define __MTK_MDP3_REGS_H__
+
+#include <linux/videodev2.h>
+#include <media/videobuf2-core.h>
+#include "mtk-img-ipi.h"
+
+/*
+ * MDP native color code
+ * Plane count: 1, 2, 3
+ * H-subsample: 0, 1, 2
+ * V-subsample: 0, 1
+ * Color group: 0-RGB, 1-YUV, 2-raw
+ */
+#define MDP_COLOR(PACKED, LOOSE, VIDEO, PLANE, HF, VF, BITS, GROUP, SWAP, ID)\
+ (((PACKED) << 27) | ((LOOSE) << 26) | ((VIDEO) << 23) |\
+ ((PLANE) << 21) | ((HF) << 19) | ((VF) << 18) | ((BITS) << 8) |\
+ ((GROUP) << 6) | ((SWAP) << 5) | ((ID) << 0))
+
+#define MDP_COLOR_IS_10BIT_PACKED(c) ((0x08000000 & (c)) >> 27)
+#define MDP_COLOR_IS_10BIT_LOOSE(c) (((0x0c000000 & (c)) >> 26) == 1)
+#define MDP_COLOR_IS_10BIT_TILE(c) (((0x0c000000 & (c)) >> 26) == 3)
+#define MDP_COLOR_IS_UFP(c) ((0x02000000 & (c)) >> 25)
+#define MDP_COLOR_IS_INTERLACED(c) ((0x01000000 & (c)) >> 24)
+#define MDP_COLOR_IS_BLOCK_MODE(c) ((0x00800000 & (c)) >> 23)
+#define MDP_COLOR_GET_PLANE_COUNT(c) ((0x00600000 & (c)) >> 21)
+#define MDP_COLOR_GET_H_SUBSAMPLE(c) ((0x00180000 & (c)) >> 19)
+#define MDP_COLOR_GET_V_SUBSAMPLE(c) ((0x00040000 & (c)) >> 18)
+#define MDP_COLOR_BITS_PER_PIXEL(c) ((0x0003ff00 & (c)) >> 8)
+#define MDP_COLOR_GET_GROUP(c) ((0x000000c0 & (c)) >> 6)
+#define MDP_COLOR_IS_SWAPPED(c) ((0x00000020 & (c)) >> 5)
+#define MDP_COLOR_GET_UNIQUE_ID(c) ((0x0000001f & (c)) >> 0)
+#define MDP_COLOR_GET_HW_FORMAT(c) ((0x0000001f & (c)) >> 0)
+
+#define MDP_COLOR_IS_RGB(c) (MDP_COLOR_GET_GROUP(c) == 0)
+#define MDP_COLOR_IS_YUV(c) (MDP_COLOR_GET_GROUP(c) == 1)
+
+enum mdp_color {
+ MDP_COLOR_UNKNOWN = 0,
+
+ //MDP_COLOR_FULLG8,
+ MDP_COLOR_FULLG8_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 8, 2, 0, 21),
+ MDP_COLOR_FULLG8_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 8, 2, 0, 21),
+ MDP_COLOR_FULLG8_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 8, 2, 0, 21),
+ MDP_COLOR_FULLG8_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 8, 2, 0, 21),
+ MDP_COLOR_FULLG8 = MDP_COLOR_FULLG8_BGGR,
+
+ //MDP_COLOR_FULLG10,
+ MDP_COLOR_FULLG10_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2, 0, 21),
+ MDP_COLOR_FULLG10_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 10, 2, 0, 21),
+ MDP_COLOR_FULLG10_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 10, 2, 0, 21),
+ MDP_COLOR_FULLG10_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 10, 2, 0, 21),
+ MDP_COLOR_FULLG10 = MDP_COLOR_FULLG10_BGGR,
+
+ //MDP_COLOR_FULLG12,
+ MDP_COLOR_FULLG12_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 12, 2, 0, 21),
+ MDP_COLOR_FULLG12_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 12, 2, 0, 21),
+ MDP_COLOR_FULLG12_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 12, 2, 0, 21),
+ MDP_COLOR_FULLG12_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 12, 2, 0, 21),
+ MDP_COLOR_FULLG12 = MDP_COLOR_FULLG12_BGGR,
+
+ //MDP_COLOR_FULLG14,
+ MDP_COLOR_FULLG14_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 14, 2, 0, 21),
+ MDP_COLOR_FULLG14_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 14, 2, 0, 21),
+ MDP_COLOR_FULLG14_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 14, 2, 0, 21),
+ MDP_COLOR_FULLG14_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 14, 2, 0, 21),
+ MDP_COLOR_FULLG14 = MDP_COLOR_FULLG14_BGGR,
+
+ MDP_COLOR_UFO10 = MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2, 0, 24),
+
+ //MDP_COLOR_BAYER8,
+ MDP_COLOR_BAYER8_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 8, 2, 0, 20),
+ MDP_COLOR_BAYER8_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 8, 2, 0, 20),
+ MDP_COLOR_BAYER8_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 8, 2, 0, 20),
+ MDP_COLOR_BAYER8_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 8, 2, 0, 20),
+ MDP_COLOR_BAYER8 = MDP_COLOR_BAYER8_BGGR,
+
+ //MDP_COLOR_BAYER10,
+ MDP_COLOR_BAYER10_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2, 0, 20),
+ MDP_COLOR_BAYER10_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 10, 2, 0, 20),
+ MDP_COLOR_BAYER10_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 10, 2, 0, 20),
+ MDP_COLOR_BAYER10_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 10, 2, 0, 20),
+ MDP_COLOR_BAYER10 = MDP_COLOR_BAYER10_BGGR,
+
+ //MDP_COLOR_BAYER12,
+ MDP_COLOR_BAYER12_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 12, 2, 0, 20),
+ MDP_COLOR_BAYER12_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 12, 2, 0, 20),
+ MDP_COLOR_BAYER12_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 12, 2, 0, 20),
+ MDP_COLOR_BAYER12_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 12, 2, 0, 20),
+ MDP_COLOR_BAYER12 = MDP_COLOR_BAYER12_BGGR,
+
+ //MDP_COLOR_BAYER14,
+ MDP_COLOR_BAYER14_RGGB = MDP_COLOR(0, 0, 0, 1, 0, 0, 14, 2, 0, 20),
+ MDP_COLOR_BAYER14_GRBG = MDP_COLOR(0, 0, 0, 1, 0, 1, 14, 2, 0, 20),
+ MDP_COLOR_BAYER14_GBRG = MDP_COLOR(0, 0, 0, 1, 1, 0, 14, 2, 0, 20),
+ MDP_COLOR_BAYER14_BGGR = MDP_COLOR(0, 0, 0, 1, 1, 1, 14, 2, 0, 20),
+ MDP_COLOR_BAYER14 = MDP_COLOR_BAYER14_BGGR,
+
+ MDP_COLOR_RGB48 = MDP_COLOR(0, 0, 0, 1, 0, 0, 48, 0, 0, 23),
+ /* For bayer+mono raw-16 */
+ MDP_COLOR_RGB565_RAW = MDP_COLOR(0, 0, 0, 1, 0, 0, 16, 2, 0, 0),
+
+ MDP_COLOR_BAYER8_UNPAK = MDP_COLOR(0, 0, 0, 1, 0, 0, 8, 2, 0, 22),
+ MDP_COLOR_BAYER10_UNPAK = MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2, 0, 22),
+ MDP_COLOR_BAYER12_UNPAK = MDP_COLOR(0, 0, 0, 1, 0, 0, 12, 2, 0, 22),
+ MDP_COLOR_BAYER14_UNPAK = MDP_COLOR(0, 0, 0, 1, 0, 0, 14, 2, 0, 22),
+
+ /* Unified formats */
+ MDP_COLOR_GREY = MDP_COLOR(0, 0, 0, 1, 0, 0, 8, 1, 0, 7),
+
+ MDP_COLOR_RGB565 = MDP_COLOR(0, 0, 0, 1, 0, 0, 16, 0, 0, 0),
+ MDP_COLOR_BGR565 = MDP_COLOR(0, 0, 0, 1, 0, 0, 16, 0, 1, 0),
+ MDP_COLOR_RGB888 = MDP_COLOR(0, 0, 0, 1, 0, 0, 24, 0, 1, 1),
+ MDP_COLOR_BGR888 = MDP_COLOR(0, 0, 0, 1, 0, 0, 24, 0, 0, 1),
+ MDP_COLOR_RGBA8888 = MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0, 1, 2),
+ MDP_COLOR_BGRA8888 = MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0, 0, 2),
+ MDP_COLOR_ARGB8888 = MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0, 1, 3),
+ MDP_COLOR_ABGR8888 = MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0, 0, 3),
+
+ MDP_COLOR_UYVY = MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1, 0, 4),
+ MDP_COLOR_VYUY = MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1, 1, 4),
+ MDP_COLOR_YUYV = MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1, 0, 5),
+ MDP_COLOR_YVYU = MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1, 1, 5),
+
+ MDP_COLOR_I420 = MDP_COLOR(0, 0, 0, 3, 1, 1, 8, 1, 0, 8),
+ MDP_COLOR_YV12 = MDP_COLOR(0, 0, 0, 3, 1, 1, 8, 1, 1, 8),
+ MDP_COLOR_I422 = MDP_COLOR(0, 0, 0, 3, 1, 0, 8, 1, 0, 9),
+ MDP_COLOR_YV16 = MDP_COLOR(0, 0, 0, 3, 1, 0, 8, 1, 1, 9),
+ MDP_COLOR_I444 = MDP_COLOR(0, 0, 0, 3, 0, 0, 8, 1, 0, 10),
+ MDP_COLOR_YV24 = MDP_COLOR(0, 0, 0, 3, 0, 0, 8, 1, 1, 10),
+
+ MDP_COLOR_NV12 = MDP_COLOR(0, 0, 0, 2, 1, 1, 8, 1, 0, 12),
+ MDP_COLOR_NV21 = MDP_COLOR(0, 0, 0, 2, 1, 1, 8, 1, 1, 12),
+ MDP_COLOR_NV16 = MDP_COLOR(0, 0, 0, 2, 1, 0, 8, 1, 0, 13),
+ MDP_COLOR_NV61 = MDP_COLOR(0, 0, 0, 2, 1, 0, 8, 1, 1, 13),
+ MDP_COLOR_NV24 = MDP_COLOR(0, 0, 0, 2, 0, 0, 8, 1, 0, 14),
+ MDP_COLOR_NV42 = MDP_COLOR(0, 0, 0, 2, 0, 0, 8, 1, 1, 14),
+
+ /* MediaTek proprietary formats */
+ /* UFO encoded block mode */
+ MDP_COLOR_420_BLK_UFO = MDP_COLOR(0, 0, 5, 2, 1, 1, 256, 1, 0, 12),
+ /* Block mode */
+ MDP_COLOR_420_BLK = MDP_COLOR(0, 0, 1, 2, 1, 1, 256, 1, 0, 12),
+ /* Block mode + field mode */
+ MDP_COLOR_420_BLKI = MDP_COLOR(0, 0, 3, 2, 1, 1, 256, 1, 0, 12),
+ /* Block mode */
+ MDP_COLOR_422_BLK = MDP_COLOR(0, 0, 1, 1, 1, 0, 512, 1, 0, 4),
+
+ MDP_COLOR_IYU2 = MDP_COLOR(0, 0, 0, 1, 0, 0, 24, 1, 0, 25),
+ MDP_COLOR_YUV444 = MDP_COLOR(0, 0, 0, 1, 0, 0, 24, 1, 0, 30),
+
+ /* Packed 10-bit formats */
+ MDP_COLOR_RGBA1010102 = MDP_COLOR(1, 0, 0, 1, 0, 0, 32, 0, 1, 2),
+ MDP_COLOR_BGRA1010102 = MDP_COLOR(1, 0, 0, 1, 0, 0, 32, 0, 0, 2),
+ /* Packed 10-bit UYVY */
+ MDP_COLOR_UYVY_10P = MDP_COLOR(1, 0, 0, 1, 1, 0, 20, 1, 0, 4),
+ /* Packed 10-bit NV21 */
+ MDP_COLOR_NV21_10P = MDP_COLOR(1, 0, 0, 2, 1, 1, 10, 1, 1, 12),
+ /* 10-bit block mode */
+ MDP_COLOR_420_BLK_10_H = MDP_COLOR(1, 0, 1, 2, 1, 1, 320, 1, 0, 12),
+ /* 10-bit HEVC tile mode */
+ MDP_COLOR_420_BLK_10_V = MDP_COLOR(1, 1, 1, 2, 1, 1, 320, 1, 0, 12),
+ /* UFO encoded 10-bit block mode */
+ MDP_COLOR_420_BLK_U10_H = MDP_COLOR(1, 0, 5, 2, 1, 1, 320, 1, 0, 12),
+ /* UFO encoded 10-bit HEVC tile mode */
+ MDP_COLOR_420_BLK_U10_V = MDP_COLOR(1, 1, 5, 2, 1, 1, 320, 1, 0, 12),
+
+ /* Loose 10-bit formats */
+ MDP_COLOR_UYVY_10L = MDP_COLOR(0, 1, 0, 1, 1, 0, 20, 1, 0, 4),
+ MDP_COLOR_VYUY_10L = MDP_COLOR(0, 1, 0, 1, 1, 0, 20, 1, 1, 4),
+ MDP_COLOR_YUYV_10L = MDP_COLOR(0, 1, 0, 1, 1, 0, 20, 1, 0, 5),
+ MDP_COLOR_YVYU_10L = MDP_COLOR(0, 1, 0, 1, 1, 0, 20, 1, 1, 5),
+ MDP_COLOR_NV12_10L = MDP_COLOR(0, 1, 0, 2, 1, 1, 10, 1, 0, 12),
+ MDP_COLOR_NV21_10L = MDP_COLOR(0, 1, 0, 2, 1, 1, 10, 1, 1, 12),
+ MDP_COLOR_NV16_10L = MDP_COLOR(0, 1, 0, 2, 1, 0, 10, 1, 0, 13),
+ MDP_COLOR_NV61_10L = MDP_COLOR(0, 1, 0, 2, 1, 0, 10, 1, 1, 13),
+ MDP_COLOR_YV12_10L = MDP_COLOR(0, 1, 0, 3, 1, 1, 10, 1, 1, 8),
+ MDP_COLOR_I420_10L = MDP_COLOR(0, 1, 0, 3, 1, 1, 10, 1, 0, 8),
+};
+
+static inline bool MDP_COLOR_IS_UV_COPLANE(enum mdp_color c)
+{
+ return (MDP_COLOR_GET_PLANE_COUNT(c) == 2 && MDP_COLOR_IS_YUV(c));
+}
+
+/* Minimum Y stride that is accepted by MDP HW */
+static inline u32 mdp_color_get_min_y_stride(enum mdp_color c, u32 width)
+{
+ return ((MDP_COLOR_BITS_PER_PIXEL(c) * width) + 4) >> 3;
+}
+
+/* Minimum UV stride that is accepted by MDP HW */
+static inline u32 mdp_color_get_min_uv_stride(enum mdp_color c, u32 width)
+{
+ u32 min_stride;
+
+ if (MDP_COLOR_GET_PLANE_COUNT(c) == 1)
+ return 0;
+ min_stride = mdp_color_get_min_y_stride(c, width)
+ >> MDP_COLOR_GET_H_SUBSAMPLE(c);
+ if (MDP_COLOR_IS_UV_COPLANE(c) && !MDP_COLOR_IS_BLOCK_MODE(c))
+ min_stride = min_stride * 2;
+ return min_stride;
+}
+
+/* Minimum Y plane size that is necessary in buffer */
+static inline u32 mdp_color_get_min_y_size(enum mdp_color c,
+ u32 width, u32 height)
+{
+ if (MDP_COLOR_IS_BLOCK_MODE(c))
+ return ((MDP_COLOR_BITS_PER_PIXEL(c) * width) >> 8) * height;
+ return mdp_color_get_min_y_stride(c, width) * height;
+}
+
+/* Minimum UV plane size that is necessary in buffer */
+static inline u32 mdp_color_get_min_uv_size(enum mdp_color c,
+ u32 width, u32 height)
+{
+ height = height >> MDP_COLOR_GET_V_SUBSAMPLE(c);
+ if (MDP_COLOR_IS_BLOCK_MODE(c) && (MDP_COLOR_GET_PLANE_COUNT(c) > 1))
+ return ((MDP_COLOR_BITS_PER_PIXEL(c) * width) >> 8) * height;
+ return mdp_color_get_min_uv_stride(c, width) * height;
+}
+
+/* Combine colorspace, xfer_func, ycbcr_encoding, and quantization */
+enum mdp_ycbcr_profile {
+ /* V4L2_YCBCR_ENC_601 and V4L2_QUANTIZATION_LIM_RANGE */
+ MDP_YCBCR_PROFILE_BT601,
+ /* V4L2_YCBCR_ENC_709 and V4L2_QUANTIZATION_LIM_RANGE */
+ MDP_YCBCR_PROFILE_BT709,
+ /* V4L2_YCBCR_ENC_601 and V4L2_QUANTIZATION_FULL_RANGE */
+ MDP_YCBCR_PROFILE_JPEG,
+ MDP_YCBCR_PROFILE_FULL_BT601 = MDP_YCBCR_PROFILE_JPEG,
+
+ /* Colorspaces not support for capture */
+ /* V4L2_YCBCR_ENC_BT2020 and V4L2_QUANTIZATION_LIM_RANGE */
+ MDP_YCBCR_PROFILE_BT2020,
+ /* V4L2_YCBCR_ENC_709 and V4L2_QUANTIZATION_FULL_RANGE */
+ MDP_YCBCR_PROFILE_FULL_BT709,
+ /* V4L2_YCBCR_ENC_BT2020 and V4L2_QUANTIZATION_FULL_RANGE */
+ MDP_YCBCR_PROFILE_FULL_BT2020,
+};
+
+#define MDP_FMT_FLAG_OUTPUT BIT(0)
+#define MDP_FMT_FLAG_CAPTURE BIT(1)
+
+struct mdp_format {
+ u32 pixelformat;
+ u32 mdp_color;
+ u8 depth[VIDEO_MAX_PLANES];
+ u8 row_depth[VIDEO_MAX_PLANES];
+ u8 num_planes;
+ u8 walign;
+ u8 halign;
+ u8 salign;
+ u32 flags;
+};
+
+struct mdp_pix_limit {
+ u32 wmin;
+ u32 hmin;
+ u32 wmax;
+ u32 hmax;
+};
+
+struct mdp_limit {
+ struct mdp_pix_limit out_limit;
+ struct mdp_pix_limit cap_limit;
+ u32 h_scale_up_max;
+ u32 v_scale_up_max;
+ u32 h_scale_down_max;
+ u32 v_scale_down_max;
+};
+
+enum mdp_stream_type {
+ MDP_STREAM_TYPE_UNKNOWN,
+ MDP_STREAM_TYPE_BITBLT,
+ MDP_STREAM_TYPE_GPU_BITBLT,
+ MDP_STREAM_TYPE_DUAL_BITBLT,
+ MDP_STREAM_TYPE_2ND_BITBLT,
+ MDP_STREAM_TYPE_ISP_IC,
+ MDP_STREAM_TYPE_ISP_VR,
+ MDP_STREAM_TYPE_ISP_ZSD,
+ MDP_STREAM_TYPE_ISP_IP,
+ MDP_STREAM_TYPE_ISP_VSS,
+ MDP_STREAM_TYPE_ISP_ZSD_SLOW,
+ MDP_STREAM_TYPE_WPE,
+ MDP_STREAM_TYPE_WPE2,
+};
+
+struct mdp_crop {
+ struct v4l2_rect c;
+ struct v4l2_fract left_subpix;
+ struct v4l2_fract top_subpix;
+ struct v4l2_fract width_subpix;
+ struct v4l2_fract height_subpix;
+};
+
+struct mdp_frame {
+ struct v4l2_format format;
+ const struct mdp_format *mdp_fmt;
+ u32 ycbcr_prof; /* enum mdp_ycbcr_profile */
+ u32 usage; /* enum mdp_buffer_usage */
+ struct mdp_crop crop;
+ struct v4l2_rect compose;
+ s32 rotation;
+ u32 hflip:1;
+ u32 vflip:1;
+ u32 hdr:1;
+ u32 dre:1;
+ u32 sharpness:1;
+ u32 dither:1;
+};
+
+static inline bool mdp_target_is_crop(u32 target)
+{
+ return (target == V4L2_SEL_TGT_CROP) ||
+ (target == V4L2_SEL_TGT_CROP_DEFAULT) ||
+ (target == V4L2_SEL_TGT_CROP_BOUNDS);
+}
+
+static inline bool mdp_target_is_compose(u32 target)
+{
+ return (target == V4L2_SEL_TGT_COMPOSE) ||
+ (target == V4L2_SEL_TGT_COMPOSE_DEFAULT) ||
+ (target == V4L2_SEL_TGT_COMPOSE_BOUNDS);
+}
+
+#define MDP_MAX_CAPTURES IMG_MAX_HW_OUTPUTS
+
+#define MDP_VPU_INIT BIT(0)
+#define MDP_M2M_CTX_ERROR BIT(1)
+
+struct mdp_frameparam {
+ struct list_head list;
+ struct mdp_m2m_ctx *ctx;
+ atomic_t state;
+ const struct mdp_limit *limit;
+ u32 type; /* enum mdp_stream_type */
+ u32 frame_no;
+ struct mdp_frame output;
+ struct mdp_frame captures[MDP_MAX_CAPTURES];
+ u32 num_captures;
+ enum v4l2_colorspace colorspace;
+ enum v4l2_ycbcr_encoding ycbcr_enc;
+ enum v4l2_xfer_func xfer_func;
+ enum v4l2_quantization quant;
+};
+
+int mdp_enum_fmt_mplane(struct v4l2_fmtdesc *f);
+const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f,
+ struct mdp_frameparam *param,
+ u32 ctx_id);
+enum mdp_ycbcr_profile mdp_map_ycbcr_prof_mplane(struct v4l2_format *f,
+ u32 mdp_color);
+int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r,
+ const struct v4l2_selection *s, struct mdp_frame *frame);
+int mdp_check_scaling_ratio(const struct v4l2_rect *crop,
+ const struct v4l2_rect *compose, s32 rotation,
+ const struct mdp_limit *limit);
+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,
+ struct mdp_frame *frame, struct vb2_buffer *vb);
+int mdp_frameparam_init(struct mdp_frameparam *param);
+
+#endif /* __MTK_MDP3_REGS_H__ */
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
new file mode 100644
index 000000000000..9f5844385c8f
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#include <linux/remoteproc.h>
+#include <linux/remoteproc/mtk_scp.h>
+#include "mtk-mdp3-vpu.h"
+#include "mtk-mdp3-core.h"
+
+#define MDP_VPU_MESSAGE_TIMEOUT 500U
+#define vpu_alloc_size 0x600000
+
+static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
+{
+ return container_of(vpu, struct mdp_dev, vpu);
+}
+
+static int mdp_vpu_shared_mem_alloc(struct mdp_vpu_dev *vpu)
+{
+ if (vpu->work && vpu->work_addr)
+ return 0;
+
+ vpu->work = dma_alloc_coherent(scp_get_device(vpu->scp), vpu_alloc_size,
+ &vpu->work_addr, GFP_KERNEL);
+
+ if (!vpu->work)
+ return -ENOMEM;
+ else
+ return 0;
+}
+
+void mdp_vpu_shared_mem_free(struct mdp_vpu_dev *vpu)
+{
+ if (vpu->work && vpu->work_addr)
+ dma_free_coherent(scp_get_device(vpu->scp), vpu_alloc_size,
+ vpu->work, vpu->work_addr);
+}
+
+static void mdp_vpu_ipi_handle_init_ack(void *data, unsigned int len,
+ void *priv)
+{
+ struct mdp_ipi_init_msg *msg = (struct mdp_ipi_init_msg *)data;
+ struct mdp_vpu_dev *vpu =
+ (struct mdp_vpu_dev *)(unsigned long)msg->drv_data;
+
+ if (!vpu->work_size)
+ vpu->work_size = msg->work_size;
+
+ vpu->status = msg->status;
+ complete(&vpu->ipi_acked);
+}
+
+static void mdp_vpu_ipi_handle_deinit_ack(void *data, unsigned int len,
+ void *priv)
+{
+ struct mdp_ipi_deinit_msg *msg = (struct mdp_ipi_deinit_msg *)data;
+ struct mdp_vpu_dev *vpu =
+ (struct mdp_vpu_dev *)(unsigned long)msg->drv_data;
+
+ vpu->status = msg->status;
+ complete(&vpu->ipi_acked);
+}
+
+static void mdp_vpu_ipi_handle_frame_ack(void *data, unsigned int len,
+ void *priv)
+{
+ struct img_sw_addr *addr = (struct img_sw_addr *)data;
+ struct img_ipi_frameparam *param =
+ (struct img_ipi_frameparam *)(unsigned long)addr->va;
+ struct mdp_vpu_ctx *ctx =
+ (struct mdp_vpu_ctx *)(unsigned long)param->drv_data;
+
+ if (param->state) {
+ struct mdp_dev *mdp = vpu_to_mdp(ctx->vpu_dev);
+
+ dev_err(&mdp->pdev->dev, "VPU MDP failure:%d\n", param->state);
+ }
+ ctx->vpu_dev->status = param->state;
+ complete(&ctx->vpu_dev->ipi_acked);
+}
+
+int mdp_vpu_register(struct mdp_dev *mdp)
+{
+ int err;
+ struct mtk_scp *scp = mdp->scp;
+ struct device *dev = &mdp->pdev->dev;
+
+ err = scp_ipi_register(scp, SCP_IPI_MDP_INIT,
+ mdp_vpu_ipi_handle_init_ack, NULL);
+ if (err) {
+ dev_err(dev, "scp_ipi_register failed %d\n", err);
+ goto err_ipi_init;
+ }
+ err = scp_ipi_register(scp, SCP_IPI_MDP_DEINIT,
+ mdp_vpu_ipi_handle_deinit_ack, NULL);
+ if (err) {
+ dev_err(dev, "scp_ipi_register failed %d\n", err);
+ goto err_ipi_deinit;
+ }
+ err = scp_ipi_register(scp, SCP_IPI_MDP_FRAME,
+ mdp_vpu_ipi_handle_frame_ack, NULL);
+ if (err) {
+ dev_err(dev, "scp_ipi_register failed %d\n", err);
+ goto err_ipi_frame;
+ }
+ return 0;
+
+err_ipi_frame:
+ scp_ipi_unregister(scp, SCP_IPI_MDP_DEINIT);
+err_ipi_deinit:
+ scp_ipi_unregister(scp, SCP_IPI_MDP_INIT);
+err_ipi_init:
+
+ return err;
+}
+
+void mdp_vpu_unregister(struct mdp_dev *mdp)
+{
+ scp_ipi_unregister(mdp->scp, SCP_IPI_MDP_INIT);
+ scp_ipi_unregister(mdp->scp, SCP_IPI_MDP_DEINIT);
+ scp_ipi_unregister(mdp->scp, SCP_IPI_MDP_FRAME);
+}
+
+static int mdp_vpu_sendmsg(struct mdp_vpu_dev *vpu, enum scp_ipi_id id,
+ void *buf, unsigned int len)
+{
+ struct mdp_dev *mdp = vpu_to_mdp(vpu);
+ unsigned int t = MDP_VPU_MESSAGE_TIMEOUT;
+ int ret;
+
+ if (!vpu->scp) {
+ dev_dbg(&mdp->pdev->dev, "vpu scp is NULL");
+ return -EINVAL;
+ }
+ ret = scp_ipi_send(vpu->scp, id, buf, len, 2000);
+
+ if (ret) {
+ dev_err(&mdp->pdev->dev, "scp_ipi_send failed %d\n", ret);
+ return -EPERM;
+ }
+ ret = wait_for_completion_timeout(&vpu->ipi_acked,
+ msecs_to_jiffies(t));
+ if (!ret)
+ ret = -ETIME;
+ else if (vpu->status)
+ ret = -EINVAL;
+ else
+ ret = 0;
+ return ret;
+}
+
+int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
+ struct mutex *lock)
+{
+ struct mdp_ipi_init_msg msg = {
+ .drv_data = (unsigned long)vpu,
+ };
+ size_t mem_size;
+ phys_addr_t pool;
+ const size_t pool_size = sizeof(struct mdp_config_pool);
+ struct mdp_dev *mdp = vpu_to_mdp(vpu);
+ int err;
+
+ init_completion(&vpu->ipi_acked);
+ vpu->scp = scp;
+ vpu->lock = lock;
+ vpu->work_size = 0;
+ err = mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_INIT, &msg, sizeof(msg));
+ if (err)
+ goto err_work_size;
+ /* vpu work_size was set in mdp_vpu_ipi_handle_init_ack */
+
+ mem_size = vpu_alloc_size;
+ if (mdp_vpu_shared_mem_alloc(vpu)) {
+ dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
+ goto err_mem_alloc;
+ }
+
+ pool = ALIGN((uintptr_t)vpu->work + vpu->work_size, 8);
+ if (pool + pool_size - (uintptr_t)vpu->work > mem_size) {
+ dev_err(&mdp->pdev->dev,
+ "VPU memory insufficient: %zx + %zx > %zx",
+ vpu->work_size, pool_size, mem_size);
+ err = -ENOMEM;
+ goto err_mem_size;
+ }
+
+ dev_dbg(&mdp->pdev->dev,
+ "VPU work:%pK pa:%pad sz:%zx pool:%pa sz:%zx (mem sz:%zx)",
+ vpu->work, &vpu->work_addr, vpu->work_size,
+ &pool, pool_size, mem_size);
+ vpu->pool = (struct mdp_config_pool *)(uintptr_t)pool;
+ msg.work_addr = vpu->work_addr;
+ msg.work_size = vpu->work_size;
+ err = mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_INIT, &msg, sizeof(msg));
+ if (err)
+ goto err_work_size;
+
+ memset(vpu->pool, 0, sizeof(*vpu->pool));
+ return 0;
+
+err_work_size:
+ switch (vpu->status) {
+ case -MDP_IPI_EBUSY:
+ err = -EBUSY;
+ break;
+ case -MDP_IPI_ENOMEM:
+ err = -ENOSPC; /* -ENOMEM */
+ break;
+ }
+ return err;
+err_mem_size:
+err_mem_alloc:
+ return err;
+}
+
+int mdp_vpu_dev_deinit(struct mdp_vpu_dev *vpu)
+{
+ struct mdp_ipi_deinit_msg msg = {
+ .drv_data = (unsigned long)vpu,
+ .work_addr = vpu->work_addr,
+ };
+
+ return mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_DEINIT, &msg, sizeof(msg));
+}
+
+static struct img_config *mdp_config_get(struct mdp_vpu_dev *vpu,
+ enum mdp_config_id id, uint32_t *addr)
+{
+ struct img_config *config;
+
+ if (id < 0 || id >= MDP_CONFIG_POOL_SIZE)
+ return ERR_PTR(-EINVAL);
+
+ mutex_lock(vpu->lock);
+ vpu->pool->cfg_count[id]++;
+ config = &vpu->pool->configs[id];
+ *addr = vpu->work_addr + ((uintptr_t)config - (uintptr_t)vpu->work);
+ mutex_unlock(vpu->lock);
+
+ return config;
+}
+
+static int mdp_config_put(struct mdp_vpu_dev *vpu,
+ enum mdp_config_id id,
+ const struct img_config *config)
+{
+ int err = 0;
+
+ if (id < 0 || id >= MDP_CONFIG_POOL_SIZE)
+ return -EINVAL;
+ if (vpu->lock)
+ mutex_lock(vpu->lock);
+ if (!vpu->pool->cfg_count[id] || config != &vpu->pool->configs[id])
+ err = -EINVAL;
+ else
+ vpu->pool->cfg_count[id]--;
+ if (vpu->lock)
+ mutex_unlock(vpu->lock);
+ return err;
+}
+
+int mdp_vpu_ctx_init(struct mdp_vpu_ctx *ctx, struct mdp_vpu_dev *vpu,
+ enum mdp_config_id id)
+{
+ ctx->config = mdp_config_get(vpu, id, &ctx->inst_addr);
+ if (IS_ERR(ctx->config)) {
+ int err = PTR_ERR(ctx->config);
+
+ ctx->config = NULL;
+ return err;
+ }
+ ctx->config_id = id;
+ ctx->vpu_dev = vpu;
+ return 0;
+}
+
+int mdp_vpu_ctx_deinit(struct mdp_vpu_ctx *ctx)
+{
+ int err = mdp_config_put(ctx->vpu_dev, ctx->config_id, ctx->config);
+
+ ctx->config_id = 0;
+ ctx->config = NULL;
+ ctx->inst_addr = 0;
+ return err;
+}
+
+int mdp_vpu_process(struct mdp_vpu_ctx *ctx, struct img_ipi_frameparam *param)
+{
+ struct mdp_vpu_dev *vpu = ctx->vpu_dev;
+ struct mdp_dev *mdp = vpu_to_mdp(vpu);
+ struct img_sw_addr addr;
+
+ if (!ctx->vpu_dev->work || !ctx->vpu_dev->work_addr) {
+ if (mdp_vpu_shared_mem_alloc(vpu)) {
+ dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
+ return -ENOMEM;
+ }
+ }
+ memset((void *)ctx->vpu_dev->work, 0, ctx->vpu_dev->work_size);
+ memset(ctx->config, 0, sizeof(*ctx->config));
+ param->config_data.va = (unsigned long)ctx->config;
+ param->config_data.pa = ctx->inst_addr;
+ param->drv_data = (unsigned long)ctx;
+
+ memcpy((void *)ctx->vpu_dev->work, param, sizeof(*param));
+ addr.pa = ctx->vpu_dev->work_addr;
+ addr.va = (uintptr_t)ctx->vpu_dev->work;
+ return mdp_vpu_sendmsg(ctx->vpu_dev, SCP_IPI_MDP_FRAME,
+ &addr, sizeof(addr));
+}
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.h
new file mode 100644
index 000000000000..244b3a32d689
--- /dev/null
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
+ */
+
+#ifndef __MTK_MDP3_VPU_H__
+#define __MTK_MDP3_VPU_H__
+
+#include <linux/platform_device.h>
+#include "mtk-img-ipi.h"
+
+enum mdp_ipi_result {
+ MDP_IPI_SUCCESS = 0,
+ MDP_IPI_ENOMEM = 12,
+ MDP_IPI_EBUSY = 16,
+ MDP_IPI_EINVAL = 22,
+ MDP_IPI_EMINST = 24,
+ MDP_IPI_ERANGE = 34,
+ MDP_IPI_NR_ERRNO,
+
+ MDP_IPI_EOTHER = MDP_IPI_NR_ERRNO,
+ MDP_IPI_PATH_CANT_MERGE,
+ MDP_IPI_OP_FAIL,
+};
+
+struct mdp_ipi_init_msg {
+ u32 status;
+ u64 drv_data;
+ u32 work_addr; /* [in] working buffer address */
+ u32 work_size; /* [in] working buffer size */
+} __packed;
+
+struct mdp_ipi_deinit_msg {
+ u32 status;
+ u64 drv_data;
+ u32 work_addr;
+} __packed;
+
+enum mdp_config_id {
+ MDP_DEV_M2M = 0,
+ MDP_CONFIG_POOL_SIZE /* ALWAYS keep at the end */
+};
+
+struct mdp_config_pool {
+ u64 cfg_count[MDP_CONFIG_POOL_SIZE];
+ struct img_config configs[MDP_CONFIG_POOL_SIZE];
+};
+
+struct mdp_vpu_dev {
+ /* synchronization protect for accessing vpu working buffer info */
+ struct mutex *lock;
+ struct mtk_scp *scp;
+ struct completion ipi_acked;
+ void *work;
+ dma_addr_t work_addr;
+ size_t work_size;
+ struct mdp_config_pool *pool;
+ u32 status;
+};
+
+struct mdp_vpu_ctx {
+ struct mdp_vpu_dev *vpu_dev;
+ u32 config_id;
+ struct img_config *config;
+ u32 inst_addr;
+};
+
+void mdp_vpu_shared_mem_free(struct mdp_vpu_dev *vpu);
+int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
+ struct mutex *lock /* for sync */);
+int mdp_vpu_dev_deinit(struct mdp_vpu_dev *vpu);
+int mdp_vpu_ctx_init(struct mdp_vpu_ctx *ctx, struct mdp_vpu_dev *vpu,
+ enum mdp_config_id id);
+int mdp_vpu_ctx_deinit(struct mdp_vpu_ctx *ctx);
+int mdp_vpu_process(struct mdp_vpu_ctx *vpu, struct img_ipi_frameparam *param);
+
+#endif /* __MTK_MDP3_VPU_H__ */
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
index 7d194a476713..641f533c417f 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
@@ -227,6 +227,8 @@ static int mtk_vcodec_dec_get_chip_name(void *priv)
return 8195;
else if (of_device_is_compatible(dev->of_node, "mediatek,mt8186-vcodec-dec"))
return 8186;
+ else if (of_device_is_compatible(dev->of_node, "mediatek,mt8188-vcodec-dec"))
+ return 8188;
else
return 8173;
}
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
index e0b6ae9d6caa..174a6eec2f54 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
@@ -478,6 +478,10 @@ static const struct of_device_id mtk_vcodec_match[] = {
.compatible = "mediatek,mt8195-vcodec-dec",
.data = &mtk_lat_sig_core_pdata,
},
+ {
+ .compatible = "mediatek,mt8188-vcodec-dec",
+ .data = &mtk_lat_sig_core_pdata,
+ },
{},
};
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h
index ef4584a46417..9acab54fd650 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h
@@ -278,6 +278,7 @@ struct vdec_pic_info {
* @hw_id: hardware index used to identify different hardware.
*
* @msg_queue: msg queue used to store lat buffer information.
+ * @q_mutex: vb2_queue mutex.
*/
struct mtk_vcodec_ctx {
enum mtk_instance_type type;
@@ -324,6 +325,8 @@ struct mtk_vcodec_ctx {
int hw_id;
struct vdec_msg_queue msg_queue;
+
+ struct mutex q_mutex;
};
/*
@@ -401,6 +404,7 @@ struct mtk_vcodec_dec_pdata {
* @output_formats: array of supported output formats
* @num_output_formats: number of entries in output_formats
* @core_id: stand for h264 or vp8 encode index
+ * @uses_34bit: whether the encoder uses 34-bit iova
*/
struct mtk_vcodec_enc_pdata {
bool uses_ext;
@@ -411,9 +415,11 @@ struct mtk_vcodec_enc_pdata {
const struct mtk_video_fmt *output_formats;
size_t num_output_formats;
int core_id;
+ bool uses_34bit;
};
#define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
+#define MTK_ENC_IOVA_IS_34BIT(ctx) ((ctx)->dev->venc_pdata->uses_34bit)
/**
* struct mtk_vcodec_dev - driver data
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
index 25e816863597..d810a78dde51 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
@@ -225,6 +225,8 @@ static int mtk_vcodec_enc_get_chip_name(void *priv)
return 8192;
else if (of_device_is_compatible(dev->of_node, "mediatek,mt8195-vcodec-enc"))
return 8195;
+ else if (of_device_is_compatible(dev->of_node, "mediatek,mt8188-vcodec-enc"))
+ return 8188;
else
return 8173;
}
@@ -503,13 +505,13 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
f->fmt.pix.pixelformat = fmt->fourcc;
}
- ret = vidioc_try_fmt_out(ctx, f, fmt);
+ q_data->visible_width = f->fmt.pix_mp.width;
+ q_data->visible_height = f->fmt.pix_mp.height;
+ q_data->fmt = fmt;
+ ret = vidioc_try_fmt_out(ctx, f, q_data->fmt);
if (ret)
return ret;
- q_data->fmt = fmt;
- q_data->visible_width = f->fmt.pix_mp.width;
- q_data->visible_height = f->fmt.pix_mp.height;
q_data->coded_width = f->fmt.pix_mp.width;
q_data->coded_height = f->fmt.pix_mp.height;
@@ -1300,7 +1302,7 @@ void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx)
{
struct mtk_q_data *q_data;
- ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
+ ctx->m2m_ctx->q_lock = &ctx->q_mutex;
ctx->fh.m2m_ctx = ctx->m2m_ctx;
ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
INIT_WORK(&ctx->encode_work, mtk_venc_worker);
@@ -1403,7 +1405,8 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
V4L2_MPEG_VIDEO_VP8_PROFILE_0, 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
- 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+ ~(1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
if (handler->error) {
@@ -1435,7 +1438,7 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->ops = &mtk_venc_vb2_ops;
src_vq->mem_ops = &vb2_dma_contig_memops;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- src_vq->lock = &ctx->dev->dev_mutex;
+ src_vq->lock = &ctx->q_mutex;
src_vq->dev = &ctx->dev->plat_dev->dev;
ret = vb2_queue_init(src_vq);
@@ -1449,7 +1452,7 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->ops = &mtk_venc_vb2_ops;
dst_vq->mem_ops = &vb2_dma_contig_memops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- dst_vq->lock = &ctx->dev->dev_mutex;
+ dst_vq->lock = &ctx->q_mutex;
dst_vq->dev = &ctx->dev->plat_dev->dev;
return vb2_queue_init(dst_vq);
diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c
index d2f5f30582a9..9095186d5495 100644
--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc_drv.c
@@ -130,6 +130,7 @@ static int fops_vcodec_open(struct file *file)
INIT_LIST_HEAD(&ctx->list);
ctx->dev = dev;
init_waitqueue_head(&ctx->queue[0]);
+ mutex_init(&ctx->q_mutex);
ctx->type = MTK_INST_ENCODER;
ret = mtk_vcodec_enc_ctrls_setup(ctx);
@@ -403,6 +404,18 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
.core_id = VENC_SYS,
};
+static const struct mtk_vcodec_enc_pdata mt8188_pdata = {
+ .uses_ext = true,
+ .capture_formats = mtk_video_formats_capture_h264,
+ .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
+ .output_formats = mtk_video_formats_output,
+ .num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
+ .min_bitrate = 64,
+ .max_bitrate = 50000000,
+ .core_id = VENC_SYS,
+ .uses_34bit = true,
+};
+
static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
.uses_ext = true,
.capture_formats = mtk_video_formats_capture_h264,
@@ -431,6 +444,7 @@ static const struct of_device_id mtk_vcodec_enc_match[] = {
{.compatible = "mediatek,mt8173-vcodec-enc-vp8",
.data = &mt8173_vp8_pdata},
{.compatible = "mediatek,mt8183-vcodec-enc", .data = &mt8183_pdata},
+ {.compatible = "mediatek,mt8188-vcodec-enc", .data = &mt8188_pdata},
{.compatible = "mediatek,mt8192-vcodec-enc", .data = &mt8192_pdata},
{.compatible = "mediatek,mt8195-vcodec-enc", .data = &mt8195_pdata},
{},
diff --git a/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c
index 4d9b8798dffe..13c4f860fa69 100644
--- a/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mediatek/vcodec/venc/venc_h264_if.c
@@ -127,6 +127,72 @@ struct venc_h264_vsi {
struct venc_h264_vpu_buf work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
};
+/**
+ * struct venc_h264_vpu_config_ext - Structure for h264 encoder configuration
+ * AP-W/R : AP is writer/reader on this item
+ * VPU-W/R: VPU is write/reader on this item
+ * @input_fourcc: input fourcc
+ * @bitrate: target bitrate (in bps)
+ * @pic_w: picture width. Picture size is visible stream resolution, in pixels,
+ * to be used for display purposes; must be smaller or equal to buffer
+ * size.
+ * @pic_h: picture height
+ * @buf_w: buffer width. Buffer size is stream resolution in pixels aligned to
+ * hardware requirements.
+ * @buf_h: buffer height
+ * @gop_size: group of picture size (idr frame)
+ * @intra_period: intra frame period
+ * @framerate: frame rate in fps
+ * @profile: as specified in standard
+ * @level: as specified in standard
+ * @wfd: WFD mode 1:on, 0:off
+ * @max_qp: max quant parameter
+ * @min_qp: min quant parameter
+ * @reserved: reserved configs
+ */
+struct venc_h264_vpu_config_ext {
+ u32 input_fourcc;
+ u32 bitrate;
+ u32 pic_w;
+ u32 pic_h;
+ u32 buf_w;
+ u32 buf_h;
+ u32 gop_size;
+ u32 intra_period;
+ u32 framerate;
+ u32 profile;
+ u32 level;
+ u32 wfd;
+ u32 max_qp;
+ u32 min_qp;
+ u32 reserved[8];
+};
+
+/**
+ * struct venc_h264_vpu_buf_34 - Structure for 34-bit buffer information
+ * AP-W/R : AP is writer/reader on this item
+ * VPU-W/R: VPU is write/reader on this item
+ * @iova: 34-bit IO virtual address
+ * @vpua: VPU side memory addr which is used by RC_CODE
+ * @size: buffer size (in bytes)
+ */
+struct venc_h264_vpu_buf_34 {
+ u64 iova;
+ u32 vpua;
+ u32 size;
+};
+
+/**
+ * struct venc_h264_vsi_34 - Structure for VPU driver control and info share
+ * Used for 34-bit iova sharing
+ * @config: h264 encoder configuration
+ * @work_bufs: working buffer information in VPU side
+ */
+struct venc_h264_vsi_34 {
+ struct venc_h264_vpu_config_ext config;
+ struct venc_h264_vpu_buf_34 work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
+};
+
/*
* struct venc_h264_inst - h264 encoder AP driver instance
* @hw_base: h264 encoder hardware register base
@@ -140,6 +206,8 @@ struct venc_h264_vsi {
* @vpu_inst: VPU instance to exchange information between AP and VPU
* @vsi: driver structure allocated by VPU side and shared to AP side for
* control and info share
+ * @vsi_34: driver structure allocated by VPU side and shared to AP side for
+ * control and info share, used for 34-bit iova sharing.
* @ctx: context for v4l2 layer integration
*/
struct venc_h264_inst {
@@ -152,6 +220,7 @@ struct venc_h264_inst {
unsigned int prepend_hdr;
struct venc_vpu_inst vpu_inst;
struct venc_h264_vsi *vsi;
+ struct venc_h264_vsi_34 *vsi_34;
struct mtk_vcodec_ctx *ctx;
};
@@ -244,14 +313,21 @@ static void h264_enc_free_work_buf(struct venc_h264_inst *inst)
mtk_vcodec_debug_leave(inst);
}
-static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
+static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit)
{
+ struct venc_h264_vpu_buf *wb = NULL;
+ struct venc_h264_vpu_buf_34 *wb_34 = NULL;
int i;
+ u32 vpua, wb_size;
int ret = 0;
- struct venc_h264_vpu_buf *wb = inst->vsi->work_bufs;
mtk_vcodec_debug_enter(inst);
+ if (is_34bit)
+ wb_34 = inst->vsi_34->work_bufs;
+ else
+ wb = inst->vsi->work_bufs;
+
for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
/*
* This 'wb' structure is set by VPU side and shared to AP for
@@ -269,13 +345,22 @@ static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
* address and do some memcpy access to move to bitstream buffer
* assigned by v4l2 layer.
*/
- inst->work_bufs[i].size = wb[i].size;
+ if (is_34bit) {
+ inst->work_bufs[i].size = wb_34[i].size;
+ vpua = wb_34[i].vpua;
+ wb_size = wb_34[i].size;
+ } else {
+ inst->work_bufs[i].size = wb[i].size;
+ vpua = wb[i].vpua;
+ wb_size = wb[i].size;
+ }
+
if (i == VENC_H264_VPU_WORK_BUF_SKIP_FRAME) {
struct mtk_vcodec_fw *handler;
handler = inst->vpu_inst.ctx->dev->fw_handler;
inst->work_bufs[i].va =
- mtk_vcodec_fw_map_dm_addr(handler, wb[i].vpua);
+ mtk_vcodec_fw_map_dm_addr(handler, vpua);
inst->work_bufs[i].dma_addr = 0;
} else {
ret = mtk_vcodec_mem_alloc(inst->ctx,
@@ -297,12 +382,14 @@ static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
handler = inst->vpu_inst.ctx->dev->fw_handler;
tmp_va = mtk_vcodec_fw_map_dm_addr(handler,
- wb[i].vpua);
- memcpy(inst->work_bufs[i].va, tmp_va,
- wb[i].size);
+ vpua);
+ memcpy(inst->work_bufs[i].va, tmp_va, wb_size);
}
}
- wb[i].iova = inst->work_bufs[i].dma_addr;
+ if (is_34bit)
+ wb_34[i].iova = inst->work_bufs[i].dma_addr;
+ else
+ wb[i].iova = inst->work_bufs[i].dma_addr;
mtk_vcodec_debug(inst,
"work_buf[%d] va=0x%p iova=%pad size=%zu",
@@ -342,22 +429,22 @@ static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
return irq_status;
}
-static int h264_frame_type(struct venc_h264_inst *inst)
+static int h264_frame_type(unsigned int frm_cnt, unsigned int gop_size,
+ unsigned int intra_period)
{
- if ((inst->vsi->config.gop_size != 0 &&
- (inst->frm_cnt % inst->vsi->config.gop_size) == 0) ||
- (inst->frm_cnt == 0 && inst->vsi->config.gop_size == 0)) {
+ if ((gop_size != 0 && (frm_cnt % gop_size) == 0) ||
+ (frm_cnt == 0 && gop_size == 0)) {
/* IDR frame */
return VENC_H264_IDR_FRM;
- } else if ((inst->vsi->config.intra_period != 0 &&
- (inst->frm_cnt % inst->vsi->config.intra_period) == 0) ||
- (inst->frm_cnt == 0 && inst->vsi->config.intra_period == 0)) {
+ } else if ((intra_period != 0 && (frm_cnt % intra_period) == 0) ||
+ (frm_cnt == 0 && intra_period == 0)) {
/* I frame */
return VENC_H264_I_FRM;
} else {
return VENC_H264_P_FRM; /* Note: B frames are not supported */
}
}
+
static int h264_encode_sps(struct venc_h264_inst *inst,
struct mtk_vcodec_mem *bs_buf,
unsigned int *bs_size)
@@ -438,18 +525,32 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
unsigned int *bs_size)
{
int ret = 0;
+ unsigned int gop_size;
+ unsigned int intra_period;
unsigned int irq_status;
struct venc_frame_info frame_info;
+ struct mtk_vcodec_ctx *ctx = inst->ctx;
mtk_vcodec_debug_enter(inst);
mtk_vcodec_debug(inst, "frm_cnt = %d\n ", inst->frm_cnt);
+
+ if (MTK_ENC_IOVA_IS_34BIT(ctx)) {
+ gop_size = inst->vsi_34->config.gop_size;
+ intra_period = inst->vsi_34->config.intra_period;
+ } else {
+ gop_size = inst->vsi->config.gop_size;
+ intra_period = inst->vsi->config.intra_period;
+ }
frame_info.frm_count = inst->frm_cnt;
frame_info.skip_frm_count = inst->skip_frm_cnt;
- frame_info.frm_type = h264_frame_type(inst);
+ frame_info.frm_type = h264_frame_type(inst->frm_cnt, gop_size,
+ intra_period);
mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n",
frame_info.frm_count, frame_info.skip_frm_count,
frame_info.frm_type);
- ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf, bs_buf, &frame_info);
+
+ ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME,
+ frm_buf, bs_buf, &frame_info);
if (ret)
return ret;
@@ -517,7 +618,10 @@ static int h264_enc_init(struct mtk_vcodec_ctx *ctx)
ret = vpu_enc_init(&inst->vpu_inst);
- inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
+ if (MTK_ENC_IOVA_IS_34BIT(ctx))
+ inst->vsi_34 = (struct venc_h264_vsi_34 *)inst->vpu_inst.vsi;
+ else
+ inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
mtk_vcodec_debug_leave(inst);
@@ -624,31 +728,61 @@ encode_err:
return ret;
}
+static void h264_enc_set_vsi_configs(struct venc_h264_inst *inst,
+ struct venc_enc_param *enc_prm)
+{
+ inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
+ inst->vsi->config.bitrate = enc_prm->bitrate;
+ inst->vsi->config.pic_w = enc_prm->width;
+ inst->vsi->config.pic_h = enc_prm->height;
+ inst->vsi->config.buf_w = enc_prm->buf_width;
+ inst->vsi->config.buf_h = enc_prm->buf_height;
+ inst->vsi->config.gop_size = enc_prm->gop_size;
+ inst->vsi->config.framerate = enc_prm->frm_rate;
+ inst->vsi->config.intra_period = enc_prm->intra_period;
+ inst->vsi->config.profile =
+ h264_get_profile(inst, enc_prm->h264_profile);
+ inst->vsi->config.level =
+ h264_get_level(inst, enc_prm->h264_level);
+ inst->vsi->config.wfd = 0;
+}
+
+static void h264_enc_set_vsi_34_configs(struct venc_h264_inst *inst,
+ struct venc_enc_param *enc_prm)
+{
+ inst->vsi_34->config.input_fourcc = enc_prm->input_yuv_fmt;
+ inst->vsi_34->config.bitrate = enc_prm->bitrate;
+ inst->vsi_34->config.pic_w = enc_prm->width;
+ inst->vsi_34->config.pic_h = enc_prm->height;
+ inst->vsi_34->config.buf_w = enc_prm->buf_width;
+ inst->vsi_34->config.buf_h = enc_prm->buf_height;
+ inst->vsi_34->config.gop_size = enc_prm->gop_size;
+ inst->vsi_34->config.framerate = enc_prm->frm_rate;
+ inst->vsi_34->config.intra_period = enc_prm->intra_period;
+ inst->vsi_34->config.profile =
+ h264_get_profile(inst, enc_prm->h264_profile);
+ inst->vsi_34->config.level =
+ h264_get_level(inst, enc_prm->h264_level);
+ inst->vsi_34->config.wfd = 0;
+}
+
static int h264_enc_set_param(void *handle,
enum venc_set_param_type type,
struct venc_enc_param *enc_prm)
{
int ret = 0;
struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
+ struct mtk_vcodec_ctx *ctx = inst->ctx;
+ const bool is_34bit = MTK_ENC_IOVA_IS_34BIT(ctx);
mtk_vcodec_debug(inst, "->type=%d", type);
switch (type) {
case VENC_SET_PARAM_ENC:
- inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
- inst->vsi->config.bitrate = enc_prm->bitrate;
- inst->vsi->config.pic_w = enc_prm->width;
- inst->vsi->config.pic_h = enc_prm->height;
- inst->vsi->config.buf_w = enc_prm->buf_width;
- inst->vsi->config.buf_h = enc_prm->buf_height;
- inst->vsi->config.gop_size = enc_prm->gop_size;
- inst->vsi->config.framerate = enc_prm->frm_rate;
- inst->vsi->config.intra_period = enc_prm->intra_period;
- inst->vsi->config.profile =
- h264_get_profile(inst, enc_prm->h264_profile);
- inst->vsi->config.level =
- h264_get_level(inst, enc_prm->h264_level);
- inst->vsi->config.wfd = 0;
+ if (is_34bit)
+ h264_enc_set_vsi_34_configs(inst, enc_prm);
+ else
+ h264_enc_set_vsi_configs(inst, enc_prm);
ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
if (ret)
break;
@@ -656,7 +790,7 @@ static int h264_enc_set_param(void *handle,
h264_enc_free_work_buf(inst);
inst->work_buf_allocated = false;
}
- ret = h264_enc_alloc_work_buf(inst);
+ ret = h264_enc_alloc_work_buf(inst, is_34bit);
if (ret)
break;
inst->work_buf_allocated = true;
diff --git a/drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h b/drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h
index 587a2cf15b76..bb16d96a7f57 100644
--- a/drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h
+++ b/drivers/media/platform/mediatek/vcodec/venc_ipi_msg.h
@@ -101,6 +101,30 @@ struct venc_ap_ipi_msg_enc_ext {
};
/**
+ * struct venc_ap_ipi_msg_enc_ext_34 - AP to SCP extended enc cmd structure
+ * @msg_id: message id (AP_IPIMSG_XXX_ENC_ENCODE)
+ * @vpu_inst_addr: VPU encoder instance addr
+ * @bs_mode: bitstream mode for h264
+ * @reserved: for struct padding
+ * @input_addr: input frame buffer 34 bit address
+ * @bs_addr: output bitstream buffer 34 bit address
+ * @bs_size: bitstream buffer size
+ * @data_item: number of items in the data array
+ * @data: data array to store the set parameters
+ */
+struct venc_ap_ipi_msg_enc_ext_34 {
+ u32 msg_id;
+ u32 vpu_inst_addr;
+ u32 bs_mode;
+ u32 reserved;
+ u64 input_addr[3];
+ u64 bs_addr;
+ u32 bs_size;
+ u32 data_item;
+ u32 data[32];
+};
+
+/**
* struct venc_ap_ipi_msg_deinit - AP to VPU deinit cmd structure
* @msg_id: message id (AP_IPIMSG_XXX_ENC_DEINIT)
* @vpu_inst_addr: VPU encoder instance addr
diff --git a/drivers/media/platform/mediatek/vcodec/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/venc_vpu_if.c
index d3570c4c177d..09e7eaa25aab 100644
--- a/drivers/media/platform/mediatek/vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/venc_vpu_if.c
@@ -222,10 +222,11 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu,
return 0;
}
-int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_frame_info *frame_info)
+static int vpu_enc_encode_32bits(struct venc_vpu_inst *vpu,
+ unsigned int bs_mode,
+ struct venc_frm_buf *frm_buf,
+ struct mtk_vcodec_mem *bs_buf,
+ struct venc_frame_info *frame_info)
{
const bool is_ext = MTK_ENC_CTX_IS_EXT(vpu->ctx);
size_t msg_size = is_ext ?
@@ -267,6 +268,73 @@ int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
return -EINVAL;
}
+ return 0;
+}
+
+static int vpu_enc_encode_34bits(struct venc_vpu_inst *vpu,
+ unsigned int bs_mode,
+ struct venc_frm_buf *frm_buf,
+ struct mtk_vcodec_mem *bs_buf,
+ struct venc_frame_info *frame_info)
+{
+ struct venc_ap_ipi_msg_enc_ext_34 out;
+ size_t msg_size = sizeof(struct venc_ap_ipi_msg_enc_ext_34);
+
+ mtk_vcodec_debug(vpu, "bs_mode %d ->", bs_mode);
+
+ memset(&out, 0, sizeof(out));
+ out.msg_id = AP_IPIMSG_ENC_ENCODE;
+ out.vpu_inst_addr = vpu->inst_addr;
+ out.bs_mode = bs_mode;
+
+ if (frm_buf) {
+ if ((frm_buf->fb_addr[0].dma_addr % 16 == 0) &&
+ (frm_buf->fb_addr[1].dma_addr % 16 == 0) &&
+ (frm_buf->fb_addr[2].dma_addr % 16 == 0)) {
+ out.input_addr[0] = frm_buf->fb_addr[0].dma_addr;
+ out.input_addr[1] = frm_buf->fb_addr[1].dma_addr;
+ out.input_addr[2] = frm_buf->fb_addr[2].dma_addr;
+ } else {
+ mtk_vcodec_err(vpu, "dma_addr not align to 16");
+ return -EINVAL;
+ }
+ }
+ if (bs_buf) {
+ out.bs_addr = bs_buf->dma_addr;
+ out.bs_size = bs_buf->size;
+ }
+ if (frame_info) {
+ out.data_item = 3;
+ out.data[0] = frame_info->frm_count;
+ out.data[1] = frame_info->skip_frm_count;
+ out.data[2] = frame_info->frm_type;
+ }
+ if (vpu_enc_send_msg(vpu, &out, msg_size)) {
+ mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail",
+ bs_mode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
+ struct venc_frm_buf *frm_buf,
+ struct mtk_vcodec_mem *bs_buf,
+ struct venc_frame_info *frame_info)
+{
+ int ret;
+
+ if (MTK_ENC_IOVA_IS_34BIT(vpu->ctx))
+ ret = vpu_enc_encode_34bits(vpu, bs_mode,
+ frm_buf, bs_buf, frame_info);
+ else
+ ret = vpu_enc_encode_32bits(vpu, bs_mode,
+ frm_buf, bs_buf, frame_info);
+
+ if (ret)
+ return ret;
+
mtk_vcodec_debug(vpu, "bs_mode %d state %d size %d key_frm %d <-",
bs_mode, vpu->state, vpu->bs_size, vpu->is_key_frm);
diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig
index 1ac0a6e91111..5917634889b5 100644
--- a/drivers/media/platform/nxp/Kconfig
+++ b/drivers/media/platform/nxp/Kconfig
@@ -15,18 +15,6 @@ config VIDEO_IMX_MIPI_CSIS
Video4Linux2 sub-device driver for the MIPI CSI-2 CSIS receiver
v3.3/v3.6.3 found on some i.MX7 and i.MX8 SoCs.
-config VIDEO_VIU
- tristate "NXP VIU Video Driver"
- depends on V4L_PLATFORM_DRIVERS
- depends on VIDEO_DEV && (PPC_MPC512x || COMPILE_TEST) && I2C
- select VIDEOBUF_DMA_CONTIG
- help
- Support for Freescale VIU video driver. This device captures
- video data, or overlays video on DIU frame buffer.
-
- Say Y here if you want to enable VIU device on MPC5121e Rev2+.
- In doubt, say N.
-
# mem2mem drivers
config VIDEO_IMX_PXP
@@ -51,4 +39,5 @@ config VIDEO_MX2_EMMAPRP
memory to memory. Operations include resizing and format
conversion.
+source "drivers/media/platform/nxp/dw100/Kconfig"
source "drivers/media/platform/nxp/imx-jpeg/Kconfig"
diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/nxp/Makefile
index efc38c6578ce..81ab304ef31c 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
+obj-y += dw100/
obj-y += imx-jpeg/
obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
-obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
diff --git a/drivers/media/platform/nxp/dw100/Kconfig b/drivers/media/platform/nxp/dw100/Kconfig
new file mode 100644
index 000000000000..cd4531bb3110
--- /dev/null
+++ b/drivers/media/platform/nxp/dw100/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config VIDEO_DW100
+ tristate "NXP i.MX DW100 dewarper"
+ depends on V4L_MEM2MEM_DRIVERS
+ depends on VIDEO_DEV
+ depends on ARCH_MXC || COMPILE_TEST
+ select MEDIA_CONTROLLER
+ select V4L2_MEM2MEM_DEV
+ select VIDEOBUF2_DMA_CONTIG
+ help
+ DW100 is a memory-to-memory engine performing geometrical
+ transformation on source images through a programmable dewarping map.
+
+ To compile this driver as a module, choose M here: the module
+ will be called dw100.
diff --git a/drivers/media/platform/nxp/dw100/Makefile b/drivers/media/platform/nxp/dw100/Makefile
new file mode 100644
index 000000000000..49db80589e9a
--- /dev/null
+++ b/drivers/media/platform/nxp/dw100/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-$(CONFIG_VIDEO_DW100) += dw100.o
diff --git a/drivers/media/platform/nxp/dw100/dw100.c b/drivers/media/platform/nxp/dw100/dw100.c
new file mode 100644
index 000000000000..b3b057798ab6
--- /dev/null
+++ b/drivers/media/platform/nxp/dw100/dw100.c
@@ -0,0 +1,1707 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * DW100 Hardware dewarper
+ *
+ * Copyright 2022 NXP
+ * Author: Xavier Roumegue (xavier.roumegue@oss.nxp.com)
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/minmax.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include <uapi/linux/dw100.h>
+
+#include "dw100_regs.h"
+
+#define DRV_NAME "dw100"
+
+#define DW100_MIN_W 176u
+#define DW100_MIN_H 144u
+#define DW100_MAX_W 4096u
+#define DW100_MAX_H 3072u
+#define DW100_ALIGN_W 3
+#define DW100_ALIGN_H 3
+
+#define DW100_BLOCK_SIZE 16
+
+#define DW100_DEF_W 640u
+#define DW100_DEF_H 480u
+#define DW100_DEF_LUT_W (DIV_ROUND_UP(DW100_DEF_W, DW100_BLOCK_SIZE) + 1)
+#define DW100_DEF_LUT_H (DIV_ROUND_UP(DW100_DEF_H, DW100_BLOCK_SIZE) + 1)
+
+/*
+ * 16 controls have been reserved for this driver for future extension, but
+ * let's limit the related driver allocation to the effective number of controls
+ * in use.
+ */
+#define DW100_MAX_CTRLS 1
+#define DW100_CTRL_DEWARPING_MAP 0
+
+enum {
+ DW100_QUEUE_SRC = 0,
+ DW100_QUEUE_DST = 1,
+};
+
+enum {
+ DW100_FMT_CAPTURE = BIT(0),
+ DW100_FMT_OUTPUT = BIT(1),
+};
+
+struct dw100_device {
+ struct platform_device *pdev;
+ struct v4l2_m2m_dev *m2m_dev;
+ struct v4l2_device v4l2_dev;
+ struct video_device vfd;
+ struct media_device mdev;
+ /* Video device lock */
+ struct mutex vfd_mutex;
+ void __iomem *mmio;
+ struct clk_bulk_data *clks;
+ int num_clks;
+ struct dentry *debugfs_root;
+};
+
+struct dw100_q_data {
+ struct v4l2_pix_format_mplane pix_fmt;
+ unsigned int sequence;
+ const struct dw100_fmt *fmt;
+ struct v4l2_rect crop;
+};
+
+struct dw100_ctx {
+ struct v4l2_fh fh;
+ struct dw100_device *dw_dev;
+ struct v4l2_ctrl_handler hdl;
+ struct v4l2_ctrl *ctrls[DW100_MAX_CTRLS];
+ /* per context m2m queue lock */
+ struct mutex vq_mutex;
+
+ /* Look Up Table for pixel remapping */
+ unsigned int *map;
+ dma_addr_t map_dma;
+ size_t map_size;
+ unsigned int map_width;
+ unsigned int map_height;
+ bool user_map_is_set;
+
+ /* Source and destination queue data */
+ struct dw100_q_data q_data[2];
+};
+
+static const struct v4l2_frmsize_stepwise dw100_frmsize_stepwise = {
+ .min_width = DW100_MIN_W,
+ .min_height = DW100_MIN_H,
+ .max_width = DW100_MAX_W,
+ .max_height = DW100_MAX_H,
+ .step_width = 1UL << DW100_ALIGN_W,
+ .step_height = 1UL << DW100_ALIGN_H,
+};
+
+static const struct dw100_fmt {
+ u32 fourcc;
+ u32 types;
+ u32 reg_format;
+ bool reg_swap_uv;
+} formats[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV16,
+ .types = DW100_FMT_OUTPUT | DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV422_SP,
+ .reg_swap_uv = false,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV16M,
+ .types = DW100_FMT_OUTPUT | DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV422_SP,
+ .reg_swap_uv = false,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV61,
+ .types = DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV422_SP,
+ .reg_swap_uv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV61M,
+ .types = DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV422_SP,
+ .reg_swap_uv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .types = DW100_FMT_OUTPUT | DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV422_PACKED,
+ .reg_swap_uv = false,
+ }, {
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .types = DW100_FMT_OUTPUT | DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV422_PACKED,
+ .reg_swap_uv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .types = DW100_FMT_OUTPUT | DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV420_SP,
+ .reg_swap_uv = false,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV12M,
+ .types = DW100_FMT_OUTPUT | DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV420_SP,
+ .reg_swap_uv = false,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV21,
+ .types = DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV420_SP,
+ .reg_swap_uv = true,
+ }, {
+ .fourcc = V4L2_PIX_FMT_NV21M,
+ .types = DW100_FMT_CAPTURE,
+ .reg_format = DW100_DEWARP_CTRL_FORMAT_YUV420_SP,
+ .reg_swap_uv = true,
+ },
+};
+
+static inline int to_dw100_fmt_type(enum v4l2_buf_type type)
+{
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ return DW100_FMT_OUTPUT;
+ else
+ return DW100_FMT_CAPTURE;
+}
+
+static const struct dw100_fmt *dw100_find_pixel_format(u32 pixel_format,
+ int fmt_type)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
+ const struct dw100_fmt *fmt = &formats[i];
+
+ if (fmt->fourcc == pixel_format && fmt->types & fmt_type)
+ return fmt;
+ }
+
+ return NULL;
+}
+
+static const struct dw100_fmt *dw100_find_format(struct v4l2_format *f)
+{
+ return dw100_find_pixel_format(f->fmt.pix_mp.pixelformat,
+ to_dw100_fmt_type(f->type));
+}
+
+static inline u32 dw100_read(struct dw100_device *dw_dev, u32 reg)
+{
+ return readl(dw_dev->mmio + reg);
+}
+
+static inline void dw100_write(struct dw100_device *dw_dev, u32 reg, u32 val)
+{
+ writel(val, dw_dev->mmio + reg);
+}
+
+static inline int dw100_dump_regs(struct seq_file *m)
+{
+ struct dw100_device *dw_dev = m->private;
+#define __DECLARE_REG(x) { #x, x }
+ unsigned int i;
+ static const struct reg_desc {
+ const char * const name;
+ unsigned int addr;
+ } dw100_regs[] = {
+ __DECLARE_REG(DW100_DEWARP_ID),
+ __DECLARE_REG(DW100_DEWARP_CTRL),
+ __DECLARE_REG(DW100_MAP_LUT_ADDR),
+ __DECLARE_REG(DW100_MAP_LUT_SIZE),
+ __DECLARE_REG(DW100_MAP_LUT_ADDR2),
+ __DECLARE_REG(DW100_MAP_LUT_SIZE2),
+ __DECLARE_REG(DW100_SRC_IMG_Y_BASE),
+ __DECLARE_REG(DW100_SRC_IMG_UV_BASE),
+ __DECLARE_REG(DW100_SRC_IMG_SIZE),
+ __DECLARE_REG(DW100_SRC_IMG_STRIDE),
+ __DECLARE_REG(DW100_DST_IMG_Y_BASE),
+ __DECLARE_REG(DW100_DST_IMG_UV_BASE),
+ __DECLARE_REG(DW100_DST_IMG_SIZE),
+ __DECLARE_REG(DW100_DST_IMG_STRIDE),
+ __DECLARE_REG(DW100_DST_IMG_Y_SIZE1),
+ __DECLARE_REG(DW100_DST_IMG_UV_SIZE1),
+ __DECLARE_REG(DW100_SRC_IMG_Y_BASE2),
+ __DECLARE_REG(DW100_SRC_IMG_UV_BASE2),
+ __DECLARE_REG(DW100_SRC_IMG_SIZE2),
+ __DECLARE_REG(DW100_SRC_IMG_STRIDE2),
+ __DECLARE_REG(DW100_DST_IMG_Y_BASE2),
+ __DECLARE_REG(DW100_DST_IMG_UV_BASE2),
+ __DECLARE_REG(DW100_DST_IMG_SIZE2),
+ __DECLARE_REG(DW100_DST_IMG_STRIDE2),
+ __DECLARE_REG(DW100_DST_IMG_Y_SIZE2),
+ __DECLARE_REG(DW100_DST_IMG_UV_SIZE2),
+ __DECLARE_REG(DW100_SWAP_CONTROL),
+ __DECLARE_REG(DW100_VERTICAL_SPLIT_LINE),
+ __DECLARE_REG(DW100_HORIZON_SPLIT_LINE),
+ __DECLARE_REG(DW100_SCALE_FACTOR),
+ __DECLARE_REG(DW100_ROI_START),
+ __DECLARE_REG(DW100_BOUNDARY_PIXEL),
+ __DECLARE_REG(DW100_INTERRUPT_STATUS),
+ __DECLARE_REG(DW100_BUS_CTRL),
+ __DECLARE_REG(DW100_BUS_CTRL1),
+ __DECLARE_REG(DW100_BUS_TIME_OUT_CYCLE),
+ };
+
+ for (i = 0; i < ARRAY_SIZE(dw100_regs); i++)
+ seq_printf(m, "%s: %#x\n", dw100_regs[i].name,
+ dw100_read(dw_dev, dw100_regs[i].addr));
+
+ return 0;
+}
+
+static inline struct dw100_ctx *dw100_file2ctx(struct file *file)
+{
+ return container_of(file->private_data, struct dw100_ctx, fh);
+}
+
+static struct dw100_q_data *dw100_get_q_data(struct dw100_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return &ctx->q_data[DW100_QUEUE_SRC];
+ else
+ return &ctx->q_data[DW100_QUEUE_DST];
+}
+
+static u32 dw100_get_n_vertices_from_length(u32 length)
+{
+ return DIV_ROUND_UP(length, DW100_BLOCK_SIZE) + 1;
+}
+
+static u16 dw100_map_convert_to_uq12_4(u32 a)
+{
+ return (u16)((a & 0xfff) << 4);
+}
+
+static u32 dw100_map_format_coordinates(u16 xq, u16 yq)
+{
+ return (u32)((yq << 16) | xq);
+}
+
+static u32 *dw100_get_user_map(struct dw100_ctx *ctx)
+{
+ struct v4l2_ctrl *ctrl = ctx->ctrls[DW100_CTRL_DEWARPING_MAP];
+
+ return ctrl->p_cur.p_u32;
+}
+
+/*
+ * Create the dewarp map used by the hardware from the V4L2 control values which
+ * have been initialized with an identity map or set by the application.
+ */
+static int dw100_create_mapping(struct dw100_ctx *ctx)
+{
+ u32 *user_map;
+
+ if (ctx->map)
+ dma_free_coherent(&ctx->dw_dev->pdev->dev, ctx->map_size,
+ ctx->map, ctx->map_dma);
+
+ ctx->map = dma_alloc_coherent(&ctx->dw_dev->pdev->dev, ctx->map_size,
+ &ctx->map_dma, GFP_KERNEL);
+
+ if (!ctx->map)
+ return -ENOMEM;
+
+ user_map = dw100_get_user_map(ctx);
+ memcpy(ctx->map, user_map, ctx->map_size);
+
+ dev_dbg(&ctx->dw_dev->pdev->dev,
+ "%ux%u %s mapping created (d:%pad-c:%p) for stream %ux%u->%ux%u\n",
+ ctx->map_width, ctx->map_height,
+ ctx->user_map_is_set ? "user" : "identity",
+ &ctx->map_dma, ctx->map,
+ ctx->q_data[DW100_QUEUE_SRC].pix_fmt.width,
+ ctx->q_data[DW100_QUEUE_DST].pix_fmt.height,
+ ctx->q_data[DW100_QUEUE_SRC].pix_fmt.width,
+ ctx->q_data[DW100_QUEUE_DST].pix_fmt.height);
+
+ return 0;
+}
+
+static void dw100_destroy_mapping(struct dw100_ctx *ctx)
+{
+ if (ctx->map) {
+ dma_free_coherent(&ctx->dw_dev->pdev->dev, ctx->map_size,
+ ctx->map, ctx->map_dma);
+ ctx->map = NULL;
+ }
+}
+
+static int dw100_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct dw100_ctx *ctx =
+ container_of(ctrl->handler, struct dw100_ctx, hdl);
+
+ switch (ctrl->id) {
+ case V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP:
+ ctx->user_map_is_set = true;
+ break;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops dw100_ctrl_ops = {
+ .s_ctrl = dw100_s_ctrl,
+};
+
+/*
+ * Initialize the dewarping map with an identity mapping.
+ *
+ * A 16 pixels cell size grid is mapped on the destination image.
+ * The last cells width/height might be lesser than 16 if the destination image
+ * width/height is not divisible by 16. This dewarping grid map specifies the
+ * source image pixel location (x, y) on each grid intersection point.
+ * Bilinear interpolation is used to compute inner cell points locations.
+ *
+ * The coordinates are saved in UQ12.4 fixed point format.
+ */
+static void dw100_ctrl_dewarping_map_init(const struct v4l2_ctrl *ctrl,
+ u32 from_idx, u32 elems,
+ union v4l2_ctrl_ptr ptr)
+{
+ struct dw100_ctx *ctx =
+ container_of(ctrl->handler, struct dw100_ctx, hdl);
+
+ u32 sw, sh, mw, mh, idx;
+ u16 qx, qy, qdx, qdy, qsh, qsw;
+ u32 *map = ctrl->p_cur.p_u32;
+
+ sw = ctx->q_data[DW100_QUEUE_SRC].pix_fmt.width;
+ sh = ctx->q_data[DW100_QUEUE_SRC].pix_fmt.height;
+
+ mw = ctrl->dims[0];
+ mh = ctrl->dims[1];
+
+ qsw = dw100_map_convert_to_uq12_4(sw);
+ qsh = dw100_map_convert_to_uq12_4(sh);
+ qdx = qsw / (mw - 1);
+ qdy = qsh / (mh - 1);
+
+ ctx->map_width = mw;
+ ctx->map_height = mh;
+ ctx->map_size = mh * mw * sizeof(u32);
+
+ for (idx = from_idx; idx < elems; idx++) {
+ qy = min_t(u32, (idx / mw) * qdy, qsh);
+ qx = min_t(u32, (idx % mw) * qdx, qsw);
+ map[idx] = dw100_map_format_coordinates(qx, qy);
+ }
+
+ ctx->user_map_is_set = false;
+}
+
+static const struct v4l2_ctrl_type_ops dw100_ctrl_type_ops = {
+ .init = dw100_ctrl_dewarping_map_init,
+ .validate = v4l2_ctrl_type_op_validate,
+ .log = v4l2_ctrl_type_op_log,
+ .equal = v4l2_ctrl_type_op_equal,
+};
+
+static const struct v4l2_ctrl_config controls[] = {
+ [DW100_CTRL_DEWARPING_MAP] = {
+ .ops = &dw100_ctrl_ops,
+ .type_ops = &dw100_ctrl_type_ops,
+ .id = V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP,
+ .name = "Dewarping Vertex Map",
+ .type = V4L2_CTRL_TYPE_U32,
+ .min = 0x00000000,
+ .max = 0xffffffff,
+ .step = 1,
+ .def = 0,
+ .dims = { DW100_DEF_LUT_W, DW100_DEF_LUT_H },
+ },
+};
+
+static int dw100_queue_setup(struct vb2_queue *vq,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct dw100_ctx *ctx = vb2_get_drv_priv(vq);
+ const struct v4l2_pix_format_mplane *format;
+ unsigned int i;
+
+ format = &dw100_get_q_data(ctx, vq->type)->pix_fmt;
+
+ if (*nplanes) {
+ if (*nplanes != format->num_planes)
+ return -EINVAL;
+
+ for (i = 0; i < *nplanes; ++i) {
+ if (sizes[i] < format->plane_fmt[i].sizeimage)
+ return -EINVAL;
+ }
+
+ return 0;
+ }
+
+ *nplanes = format->num_planes;
+
+ for (i = 0; i < format->num_planes; ++i)
+ sizes[i] = format->plane_fmt[i].sizeimage;
+
+ return 0;
+}
+
+static int dw100_buf_prepare(struct vb2_buffer *vb)
+{
+ unsigned int i;
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct dw100_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct dw100_device *dw_dev = ctx->dw_dev;
+ const struct v4l2_pix_format_mplane *pix_fmt =
+ &dw100_get_q_data(ctx, vb->vb2_queue->type)->pix_fmt;
+
+ if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+ if (vbuf->field != V4L2_FIELD_NONE) {
+ dev_dbg(&dw_dev->pdev->dev, "%x field isn't supported\n",
+ vbuf->field);
+ return -EINVAL;
+ }
+ }
+
+ for (i = 0; i < pix_fmt->num_planes; i++) {
+ unsigned long size = pix_fmt->plane_fmt[i].sizeimage;
+
+ if (vb2_plane_size(vb, i) < size) {
+ dev_dbg(&dw_dev->pdev->dev,
+ "User buffer too small (%lu < %lu)\n",
+ vb2_plane_size(vb, i), size);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, i, size);
+ }
+
+ return 0;
+}
+
+static void dw100_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct dw100_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static void dw100_return_all_buffers(struct vb2_queue *q,
+ enum vb2_buffer_state state)
+{
+ struct dw100_ctx *ctx = vb2_get_drv_priv(q);
+ struct vb2_v4l2_buffer *vbuf;
+
+ for (;;) {
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
+ vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ else
+ vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ if (!vbuf)
+ return;
+ v4l2_m2m_buf_done(vbuf, state);
+ }
+}
+
+static int dw100_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct dw100_ctx *ctx = vb2_get_drv_priv(q);
+ struct dw100_q_data *q_data = dw100_get_q_data(ctx, q->type);
+ int ret;
+
+ q_data->sequence = 0;
+
+ ret = dw100_create_mapping(ctx);
+ if (ret)
+ goto err;
+
+ ret = pm_runtime_resume_and_get(&ctx->dw_dev->pdev->dev);
+ if (ret) {
+ dw100_destroy_mapping(ctx);
+ goto err;
+ }
+
+ return 0;
+err:
+ dw100_return_all_buffers(q, VB2_BUF_STATE_QUEUED);
+ return ret;
+}
+
+static void dw100_stop_streaming(struct vb2_queue *q)
+{
+ struct dw100_ctx *ctx = vb2_get_drv_priv(q);
+
+ dw100_return_all_buffers(q, VB2_BUF_STATE_ERROR);
+
+ pm_runtime_put_sync(&ctx->dw_dev->pdev->dev);
+
+ dw100_destroy_mapping(ctx);
+}
+
+static const struct vb2_ops dw100_qops = {
+ .queue_setup = dw100_queue_setup,
+ .buf_prepare = dw100_buf_prepare,
+ .buf_queue = dw100_buf_queue,
+ .start_streaming = dw100_start_streaming,
+ .stop_streaming = dw100_stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+};
+
+static int dw100_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct dw100_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ src_vq->drv_priv = ctx;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->ops = &dw100_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->lock = &ctx->vq_mutex;
+ src_vq->dev = ctx->dw_dev->v4l2_dev.dev;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ dst_vq->drv_priv = ctx;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->ops = &dw100_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->lock = &ctx->vq_mutex;
+ dst_vq->dev = ctx->dw_dev->v4l2_dev.dev;
+
+ return vb2_queue_init(dst_vq);
+}
+
+static int dw100_open(struct file *file)
+{
+ struct dw100_device *dw_dev = video_drvdata(file);
+ struct dw100_ctx *ctx;
+ struct v4l2_ctrl_handler *hdl;
+ struct v4l2_pix_format_mplane *pix_fmt;
+ int ret, i;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ mutex_init(&ctx->vq_mutex);
+ v4l2_fh_init(&ctx->fh, video_devdata(file));
+ file->private_data = &ctx->fh;
+ ctx->dw_dev = dw_dev;
+
+ ctx->q_data[DW100_QUEUE_SRC].fmt = &formats[0];
+
+ pix_fmt = &ctx->q_data[DW100_QUEUE_SRC].pix_fmt;
+ pix_fmt->field = V4L2_FIELD_NONE;
+ pix_fmt->colorspace = V4L2_COLORSPACE_REC709;
+ pix_fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix_fmt->colorspace);
+ pix_fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix_fmt->colorspace);
+ pix_fmt->quantization =
+ V4L2_MAP_QUANTIZATION_DEFAULT(false, pix_fmt->colorspace,
+ pix_fmt->ycbcr_enc);
+
+ v4l2_fill_pixfmt_mp(pix_fmt, formats[0].fourcc, DW100_DEF_W, DW100_DEF_H);
+
+ ctx->q_data[DW100_QUEUE_SRC].crop.top = 0;
+ ctx->q_data[DW100_QUEUE_SRC].crop.left = 0;
+ ctx->q_data[DW100_QUEUE_SRC].crop.width = DW100_DEF_W;
+ ctx->q_data[DW100_QUEUE_SRC].crop.height = DW100_DEF_H;
+
+ ctx->q_data[DW100_QUEUE_DST] = ctx->q_data[DW100_QUEUE_SRC];
+
+ hdl = &ctx->hdl;
+ v4l2_ctrl_handler_init(hdl, ARRAY_SIZE(controls));
+ for (i = 0; i < ARRAY_SIZE(controls); i++) {
+ ctx->ctrls[i] = v4l2_ctrl_new_custom(hdl, &controls[i], NULL);
+ if (hdl->error) {
+ dev_err(&ctx->dw_dev->pdev->dev,
+ "Adding control (%d) failed\n", i);
+ ret = hdl->error;
+ goto err;
+ }
+ }
+ ctx->fh.ctrl_handler = hdl;
+
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dw_dev->m2m_dev,
+ ctx, &dw100_m2m_queue_init);
+
+ if (IS_ERR(ctx->fh.m2m_ctx)) {
+ ret = PTR_ERR(ctx->fh.m2m_ctx);
+ goto err;
+ }
+
+ v4l2_fh_add(&ctx->fh);
+
+ return 0;
+
+err:
+ v4l2_ctrl_handler_free(hdl);
+ v4l2_fh_exit(&ctx->fh);
+ mutex_destroy(&ctx->vq_mutex);
+ kfree(ctx);
+
+ return ret;
+}
+
+static int dw100_release(struct file *file)
+{
+ struct dw100_ctx *ctx = dw100_file2ctx(file);
+
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ v4l2_ctrl_handler_free(&ctx->hdl);
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+ mutex_destroy(&ctx->vq_mutex);
+ kfree(ctx);
+
+ return 0;
+}
+
+static const struct v4l2_file_operations dw100_fops = {
+ .owner = THIS_MODULE,
+ .open = dw100_open,
+ .release = dw100_release,
+ .poll = v4l2_m2m_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = v4l2_m2m_fop_mmap,
+};
+
+static int dw100_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ strscpy(cap->driver, DRV_NAME, sizeof(cap->driver));
+ strscpy(cap->card, "DW100 dewarper", sizeof(cap->card));
+
+ return 0;
+}
+
+static int dw100_enum_fmt_vid(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ int i, num = 0;
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
+ if (formats[i].types & to_dw100_fmt_type(f->type)) {
+ if (num == f->index) {
+ f->pixelformat = formats[i].fourcc;
+ return 0;
+ }
+ ++num;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int dw100_enum_framesizes(struct file *file, void *priv,
+ struct v4l2_frmsizeenum *fsize)
+{
+ const struct dw100_fmt *fmt;
+
+ if (fsize->index)
+ return -EINVAL;
+
+ fmt = dw100_find_pixel_format(fsize->pixel_format,
+ DW100_FMT_OUTPUT | DW100_FMT_CAPTURE);
+ if (!fmt)
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ fsize->stepwise = dw100_frmsize_stepwise;
+
+ return 0;
+}
+
+static int dw100_g_fmt_vid(struct file *file, void *priv, struct v4l2_format *f)
+{
+ struct dw100_ctx *ctx = dw100_file2ctx(file);
+ struct vb2_queue *vq;
+ struct dw100_q_data *q_data;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = dw100_get_q_data(ctx, f->type);
+
+ f->fmt.pix_mp = q_data->pix_fmt;
+
+ return 0;
+}
+
+static int dw100_try_fmt(struct file *file, struct v4l2_format *f)
+{
+ struct dw100_ctx *ctx = dw100_file2ctx(file);
+ struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+ const struct dw100_fmt *fmt;
+
+ fmt = dw100_find_format(f);
+ if (!fmt) {
+ fmt = &formats[0];
+ pix->pixelformat = fmt->fourcc;
+ }
+
+ v4l2_apply_frmsize_constraints(&pix->width, &pix->height,
+ &dw100_frmsize_stepwise);
+
+ v4l2_fill_pixfmt_mp(pix, fmt->fourcc, pix->width, pix->height);
+
+ pix->field = V4L2_FIELD_NONE;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ if (pix->colorspace == V4L2_COLORSPACE_DEFAULT)
+ pix->colorspace = V4L2_COLORSPACE_REC709;
+ if (pix->xfer_func == V4L2_XFER_FUNC_DEFAULT)
+ pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
+ if (pix->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
+ pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
+ if (pix->quantization == V4L2_QUANTIZATION_DEFAULT)
+ pix->quantization =
+ V4L2_MAP_QUANTIZATION_DEFAULT(false,
+ pix->colorspace,
+ pix->ycbcr_enc);
+ } else {
+ /*
+ * The DW100 can't perform colorspace conversion, the colorspace
+ * on the capture queue must be identical to the output queue.
+ */
+ const struct dw100_q_data *q_data =
+ dw100_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+ pix->colorspace = q_data->pix_fmt.colorspace;
+ pix->xfer_func = q_data->pix_fmt.xfer_func;
+ pix->ycbcr_enc = q_data->pix_fmt.ycbcr_enc;
+ pix->quantization = q_data->pix_fmt.quantization;
+ }
+
+ return 0;
+}
+
+static int dw100_s_fmt(struct dw100_ctx *ctx, struct v4l2_format *f)
+{
+ struct dw100_q_data *q_data;
+ struct vb2_queue *vq;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ q_data = dw100_get_q_data(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
+
+ if (vb2_is_busy(vq)) {
+ dev_dbg(&ctx->dw_dev->pdev->dev, "%s queue busy\n", __func__);
+ return -EBUSY;
+ }
+
+ q_data->fmt = dw100_find_format(f);
+ q_data->pix_fmt = f->fmt.pix_mp;
+ q_data->crop.top = 0;
+ q_data->crop.left = 0;
+ q_data->crop.width = f->fmt.pix_mp.width;
+ q_data->crop.height = f->fmt.pix_mp.height;
+
+ /* Propagate buffers encoding */
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ struct dw100_q_data *dst_q_data =
+ dw100_get_q_data(ctx,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+ dst_q_data->pix_fmt.colorspace = q_data->pix_fmt.colorspace;
+ dst_q_data->pix_fmt.ycbcr_enc = q_data->pix_fmt.ycbcr_enc;
+ dst_q_data->pix_fmt.quantization = q_data->pix_fmt.quantization;
+ dst_q_data->pix_fmt.xfer_func = q_data->pix_fmt.xfer_func;
+ }
+
+ dev_dbg(&ctx->dw_dev->pdev->dev,
+ "Setting format for type %u, wxh: %ux%u, fmt: %p4cc\n",
+ f->type, q_data->pix_fmt.width, q_data->pix_fmt.height,
+ &q_data->pix_fmt.pixelformat);
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ int ret;
+ u32 dims[V4L2_CTRL_MAX_DIMS] = {};
+ struct v4l2_ctrl *ctrl = ctx->ctrls[DW100_CTRL_DEWARPING_MAP];
+
+ dims[0] = dw100_get_n_vertices_from_length(q_data->pix_fmt.width);
+ dims[1] = dw100_get_n_vertices_from_length(q_data->pix_fmt.height);
+
+ ret = v4l2_ctrl_modify_dimensions(ctrl, dims);
+
+ if (ret) {
+ dev_err(&ctx->dw_dev->pdev->dev,
+ "Modifying LUT dimensions failed with error %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int dw100_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return -EINVAL;
+
+ return dw100_try_fmt(file, f);
+}
+
+static int dw100_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct dw100_ctx *ctx = dw100_file2ctx(file);
+ int ret;
+
+ ret = dw100_try_fmt_vid_cap(file, priv, f);
+ if (ret)
+ return ret;
+
+ ret = dw100_s_fmt(ctx, f);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int dw100_try_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ return -EINVAL;
+
+ return dw100_try_fmt(file, f);
+}
+
+static int dw100_s_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct dw100_ctx *ctx = dw100_file2ctx(file);
+ int ret;
+
+ ret = dw100_try_fmt_vid_out(file, priv, f);
+ if (ret)
+ return ret;
+
+ ret = dw100_s_fmt(ctx, f);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int dw100_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *sel)
+{
+ struct dw100_ctx *ctx = dw100_file2ctx(file);
+ struct dw100_q_data *src_q_data;
+
+ if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ src_q_data = dw100_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.top = 0;
+ sel->r.left = 0;
+ sel->r.width = src_q_data->pix_fmt.width;
+ sel->r.height = src_q_data->pix_fmt.height;
+ break;
+ case V4L2_SEL_TGT_CROP:
+ sel->r.top = src_q_data->crop.top;
+ sel->r.left = src_q_data->crop.left;
+ sel->r.width = src_q_data->crop.width;
+ sel->r.height = src_q_data->crop.height;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int dw100_s_selection(struct file *file, void *fh,
+ struct v4l2_selection *sel)
+{
+ struct dw100_ctx *ctx = dw100_file2ctx(file);
+ struct dw100_q_data *src_q_data;
+ u32 qscalex, qscaley, qscale;
+ int x, y, w, h;
+ unsigned int wframe, hframe;
+
+ if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+
+ src_q_data = dw100_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+ dev_dbg(&ctx->dw_dev->pdev->dev,
+ ">>> Buffer Type: %u Target: %u Rect: %ux%u@%d.%d\n",
+ sel->type, sel->target,
+ sel->r.width, sel->r.height, sel->r.left, sel->r.top);
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ wframe = src_q_data->pix_fmt.width;
+ hframe = src_q_data->pix_fmt.height;
+
+ sel->r.top = clamp_t(int, sel->r.top, 0, hframe - DW100_MIN_H);
+ sel->r.left = clamp_t(int, sel->r.left, 0, wframe - DW100_MIN_W);
+ sel->r.height =
+ clamp(sel->r.height, DW100_MIN_H, hframe - sel->r.top);
+ sel->r.width =
+ clamp(sel->r.width, DW100_MIN_W, wframe - sel->r.left);
+
+ /* UQ16.16 for float operations */
+ qscalex = (sel->r.width << 16) / wframe;
+ qscaley = (sel->r.height << 16) / hframe;
+ y = sel->r.top;
+ x = sel->r.left;
+ if (qscalex == qscaley) {
+ qscale = qscalex;
+ } else {
+ switch (sel->flags) {
+ case 0:
+ qscale = (qscalex + qscaley) / 2;
+ break;
+ case V4L2_SEL_FLAG_GE:
+ qscale = max(qscaley, qscalex);
+ break;
+ case V4L2_SEL_FLAG_LE:
+ qscale = min(qscaley, qscalex);
+ break;
+ case V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE:
+ return -ERANGE;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ w = (u32)((((u64)wframe << 16) * qscale) >> 32);
+ h = (u32)((((u64)hframe << 16) * qscale) >> 32);
+ x = x + (sel->r.width - w) / 2;
+ y = y + (sel->r.height - h) / 2;
+ x = min(wframe - w, (unsigned int)max(0, x));
+ y = min(hframe - h, (unsigned int)max(0, y));
+
+ sel->r.top = y;
+ sel->r.left = x;
+ sel->r.width = w;
+ sel->r.height = h;
+
+ src_q_data->crop.top = sel->r.top;
+ src_q_data->crop.left = sel->r.left;
+ src_q_data->crop.width = sel->r.width;
+ src_q_data->crop.height = sel->r.height;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ dev_dbg(&ctx->dw_dev->pdev->dev,
+ "<<< Buffer Type: %u Target: %u Rect: %ux%u@%d.%d\n",
+ sel->type, sel->target,
+ sel->r.width, sel->r.height, sel->r.left, sel->r.top);
+
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops dw100_ioctl_ops = {
+ .vidioc_querycap = dw100_querycap,
+
+ .vidioc_enum_fmt_vid_cap = dw100_enum_fmt_vid,
+ .vidioc_enum_framesizes = dw100_enum_framesizes,
+ .vidioc_g_fmt_vid_cap_mplane = dw100_g_fmt_vid,
+ .vidioc_try_fmt_vid_cap_mplane = dw100_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap_mplane = dw100_s_fmt_vid_cap,
+
+ .vidioc_enum_fmt_vid_out = dw100_enum_fmt_vid,
+ .vidioc_g_fmt_vid_out_mplane = dw100_g_fmt_vid,
+ .vidioc_try_fmt_vid_out_mplane = dw100_try_fmt_vid_out,
+ .vidioc_s_fmt_vid_out_mplane = dw100_s_fmt_vid_out,
+
+ .vidioc_g_selection = dw100_g_selection,
+ .vidioc_s_selection = dw100_s_selection,
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
+
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static void dw100_job_finish(struct dw100_device *dw_dev, bool with_error)
+{
+ struct dw100_ctx *curr_ctx;
+ struct vb2_v4l2_buffer *src_vb, *dst_vb;
+ enum vb2_buffer_state buf_state;
+
+ curr_ctx = v4l2_m2m_get_curr_priv(dw_dev->m2m_dev);
+
+ if (!curr_ctx) {
+ dev_err(&dw_dev->pdev->dev,
+ "Instance released before the end of transaction\n");
+ return;
+ }
+
+ src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
+ dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
+
+ if (likely(!with_error))
+ buf_state = VB2_BUF_STATE_DONE;
+ else
+ buf_state = VB2_BUF_STATE_ERROR;
+
+ v4l2_m2m_buf_done(src_vb, buf_state);
+ v4l2_m2m_buf_done(dst_vb, buf_state);
+
+ dev_dbg(&dw_dev->pdev->dev, "Finishing transaction with%s error(s)\n",
+ with_error ? "" : "out");
+
+ v4l2_m2m_job_finish(dw_dev->m2m_dev, curr_ctx->fh.m2m_ctx);
+}
+
+static void dw100_hw_reset(struct dw100_device *dw_dev)
+{
+ u32 val;
+
+ val = dw100_read(dw_dev, DW100_DEWARP_CTRL);
+ val |= DW100_DEWARP_CTRL_ENABLE;
+ val |= DW100_DEWARP_CTRL_SOFT_RESET;
+ dw100_write(dw_dev, DW100_DEWARP_CTRL, val);
+ val &= ~DW100_DEWARP_CTRL_SOFT_RESET;
+ dw100_write(dw_dev, DW100_DEWARP_CTRL, val);
+}
+
+static void _dw100_hw_set_master_bus_enable(struct dw100_device *dw_dev,
+ unsigned int enable)
+{
+ u32 val;
+
+ dev_dbg(&dw_dev->pdev->dev, "%sable master bus\n",
+ enable ? "En" : "Dis");
+
+ val = dw100_read(dw_dev, DW100_BUS_CTRL);
+
+ if (enable)
+ val |= DW100_BUS_CTRL_AXI_MASTER_ENABLE;
+ else
+ val &= ~DW100_BUS_CTRL_AXI_MASTER_ENABLE;
+
+ dw100_write(dw_dev, DW100_BUS_CTRL, val);
+}
+
+static void dw100_hw_master_bus_enable(struct dw100_device *dw_dev)
+{
+ _dw100_hw_set_master_bus_enable(dw_dev, 1);
+}
+
+static void dw100_hw_master_bus_disable(struct dw100_device *dw_dev)
+{
+ _dw100_hw_set_master_bus_enable(dw_dev, 0);
+}
+
+static void dw100_hw_dewarp_start(struct dw100_device *dw_dev)
+{
+ u32 val;
+
+ val = dw100_read(dw_dev, DW100_DEWARP_CTRL);
+
+ dev_dbg(&dw_dev->pdev->dev, "Starting Hardware CTRL:0x%08x\n", val);
+ dw100_write(dw_dev, DW100_DEWARP_CTRL, val | DW100_DEWARP_CTRL_START);
+ dw100_write(dw_dev, DW100_DEWARP_CTRL, val);
+}
+
+static void dw100_hw_init_ctrl(struct dw100_device *dw_dev)
+{
+ u32 val;
+ /*
+ * Input format YUV422_SP
+ * Output format YUV422_SP
+ * No hardware handshake (SW)
+ * No automatic double src buffering (Single)
+ * No automatic double dst buffering (Single)
+ * No Black Line
+ * Prefetch image pixel traversal
+ */
+
+ val = DW100_DEWARP_CTRL_ENABLE
+ /* Valid only for auto prefetch mode*/
+ | DW100_DEWARP_CTRL_PREFETCH_THRESHOLD(32);
+
+ /*
+ * Calculation mode required to support any scaling factor,
+ * but x4 slower than traversal mode.
+ *
+ * DW100_DEWARP_CTRL_PREFETCH_MODE_TRAVERSAL
+ * DW100_DEWARP_CTRL_PREFETCH_MODE_CALCULATION
+ * DW100_DEWARP_CTRL_PREFETCH_MODE_AUTO
+ *
+ * TODO: Find heuristics requiring calculation mode
+ */
+ val |= DW100_DEWARP_CTRL_PREFETCH_MODE_CALCULATION;
+
+ dw100_write(dw_dev, DW100_DEWARP_CTRL, val);
+}
+
+static void dw100_hw_set_pixel_boundary(struct dw100_device *dw_dev)
+{
+ u32 val;
+
+ val = DW100_BOUNDARY_PIXEL_V(128)
+ | DW100_BOUNDARY_PIXEL_U(128)
+ | DW100_BOUNDARY_PIXEL_Y(0);
+
+ dw100_write(dw_dev, DW100_BOUNDARY_PIXEL, val);
+}
+
+static void dw100_hw_set_scale(struct dw100_device *dw_dev, u8 scale)
+{
+ dev_dbg(&dw_dev->pdev->dev, "Setting scale factor to %u\n", scale);
+
+ dw100_write(dw_dev, DW100_SCALE_FACTOR, scale);
+}
+
+static void dw100_hw_set_roi(struct dw100_device *dw_dev, u32 x, u32 y)
+{
+ u32 val;
+
+ dev_dbg(&dw_dev->pdev->dev, "Setting ROI region to %u.%u\n", x, y);
+
+ val = DW100_ROI_START_X(x) | DW100_ROI_START_Y(y);
+
+ dw100_write(dw_dev, DW100_ROI_START, val);
+}
+
+static void dw100_hw_set_src_crop(struct dw100_device *dw_dev,
+ const struct dw100_q_data *src_q_data,
+ const struct dw100_q_data *dst_q_data)
+{
+ const struct v4l2_rect *rect = &src_q_data->crop;
+ u32 src_scale, qscale, left_scale, top_scale;
+
+ /* HW Scale is UQ1.7 encoded */
+ src_scale = (rect->width << 7) / src_q_data->pix_fmt.width;
+ dw100_hw_set_scale(dw_dev, src_scale);
+
+ qscale = (dst_q_data->pix_fmt.width << 7) / src_q_data->pix_fmt.width;
+
+ left_scale = ((rect->left << 7) * qscale) >> 14;
+ top_scale = ((rect->top << 7) * qscale) >> 14;
+
+ dw100_hw_set_roi(dw_dev, left_scale, top_scale);
+}
+
+static void dw100_hw_set_source(struct dw100_device *dw_dev,
+ const struct dw100_q_data *q_data,
+ struct vb2_buffer *buffer)
+{
+ u32 width, height, stride, fourcc, val;
+ const struct dw100_fmt *fmt = q_data->fmt;
+ dma_addr_t addr_y = vb2_dma_contig_plane_dma_addr(buffer, 0);
+ dma_addr_t addr_uv;
+
+ width = q_data->pix_fmt.width;
+ height = q_data->pix_fmt.height;
+ stride = q_data->pix_fmt.plane_fmt[0].bytesperline;
+ fourcc = q_data->fmt->fourcc;
+
+ if (q_data->pix_fmt.num_planes == 2)
+ addr_uv = vb2_dma_contig_plane_dma_addr(buffer, 1);
+ else
+ addr_uv = addr_y + (stride * height);
+
+ dev_dbg(&dw_dev->pdev->dev,
+ "Set HW source registers for %ux%u - stride %u, pixfmt: %p4cc, dma:%pad\n",
+ width, height, stride, &fourcc, &addr_y);
+
+ /* Pixel Format */
+ val = dw100_read(dw_dev, DW100_DEWARP_CTRL);
+
+ val &= ~DW100_DEWARP_CTRL_INPUT_FORMAT_MASK;
+ val |= DW100_DEWARP_CTRL_INPUT_FORMAT(fmt->reg_format);
+
+ dw100_write(dw_dev, DW100_DEWARP_CTRL, val);
+
+ /* Swap */
+ val = dw100_read(dw_dev, DW100_SWAP_CONTROL);
+
+ val &= ~DW100_SWAP_CONTROL_SRC_MASK;
+ /*
+ * Data swapping is performed only on Y plane for source image.
+ */
+ if (fmt->reg_swap_uv &&
+ fmt->reg_format == DW100_DEWARP_CTRL_FORMAT_YUV422_PACKED)
+ val |= DW100_SWAP_CONTROL_SRC(DW100_SWAP_CONTROL_Y
+ (DW100_SWAP_CONTROL_BYTE));
+
+ dw100_write(dw_dev, DW100_SWAP_CONTROL, val);
+
+ /* Image resolution */
+ dw100_write(dw_dev, DW100_SRC_IMG_SIZE,
+ DW100_IMG_SIZE_WIDTH(width) | DW100_IMG_SIZE_HEIGHT(height));
+
+ dw100_write(dw_dev, DW100_SRC_IMG_STRIDE, stride);
+
+ /* Buffers */
+ dw100_write(dw_dev, DW100_SRC_IMG_Y_BASE, DW100_IMG_Y_BASE(addr_y));
+ dw100_write(dw_dev, DW100_SRC_IMG_UV_BASE, DW100_IMG_UV_BASE(addr_uv));
+}
+
+static void dw100_hw_set_destination(struct dw100_device *dw_dev,
+ const struct dw100_q_data *q_data,
+ const struct dw100_fmt *ifmt,
+ struct vb2_buffer *buffer)
+{
+ u32 width, height, stride, fourcc, val, size_y, size_uv;
+ const struct dw100_fmt *fmt = q_data->fmt;
+ dma_addr_t addr_y, addr_uv;
+
+ width = q_data->pix_fmt.width;
+ height = q_data->pix_fmt.height;
+ stride = q_data->pix_fmt.plane_fmt[0].bytesperline;
+ fourcc = fmt->fourcc;
+
+ addr_y = vb2_dma_contig_plane_dma_addr(buffer, 0);
+ size_y = q_data->pix_fmt.plane_fmt[0].sizeimage;
+
+ if (q_data->pix_fmt.num_planes == 2) {
+ addr_uv = vb2_dma_contig_plane_dma_addr(buffer, 1);
+ size_uv = q_data->pix_fmt.plane_fmt[1].sizeimage;
+ } else {
+ addr_uv = addr_y + ALIGN(stride * height, 16);
+ size_uv = size_y;
+ if (fmt->reg_format == DW100_DEWARP_CTRL_FORMAT_YUV420_SP)
+ size_uv /= 2;
+ }
+
+ dev_dbg(&dw_dev->pdev->dev,
+ "Set HW source registers for %ux%u - stride %u, pixfmt: %p4cc, dma:%pad\n",
+ width, height, stride, &fourcc, &addr_y);
+
+ /* Pixel Format */
+ val = dw100_read(dw_dev, DW100_DEWARP_CTRL);
+
+ val &= ~DW100_DEWARP_CTRL_OUTPUT_FORMAT_MASK;
+ val |= DW100_DEWARP_CTRL_OUTPUT_FORMAT(fmt->reg_format);
+
+ dw100_write(dw_dev, DW100_DEWARP_CTRL, val);
+
+ /* Swap */
+ val = dw100_read(dw_dev, DW100_SWAP_CONTROL);
+
+ val &= ~DW100_SWAP_CONTROL_DST_MASK;
+
+ /*
+ * Avoid to swap twice
+ */
+ if (fmt->reg_swap_uv ^
+ (ifmt->reg_swap_uv && ifmt->reg_format !=
+ DW100_DEWARP_CTRL_FORMAT_YUV422_PACKED)) {
+ if (fmt->reg_format == DW100_DEWARP_CTRL_FORMAT_YUV422_PACKED)
+ val |= DW100_SWAP_CONTROL_DST(DW100_SWAP_CONTROL_Y
+ (DW100_SWAP_CONTROL_BYTE));
+ else
+ val |= DW100_SWAP_CONTROL_DST(DW100_SWAP_CONTROL_UV
+ (DW100_SWAP_CONTROL_BYTE));
+ }
+
+ dw100_write(dw_dev, DW100_SWAP_CONTROL, val);
+
+ /* Image resolution */
+ dw100_write(dw_dev, DW100_DST_IMG_SIZE,
+ DW100_IMG_SIZE_WIDTH(width) | DW100_IMG_SIZE_HEIGHT(height));
+ dw100_write(dw_dev, DW100_DST_IMG_STRIDE, stride);
+ dw100_write(dw_dev, DW100_DST_IMG_Y_BASE, DW100_IMG_Y_BASE(addr_y));
+ dw100_write(dw_dev, DW100_DST_IMG_UV_BASE, DW100_IMG_UV_BASE(addr_uv));
+ dw100_write(dw_dev, DW100_DST_IMG_Y_SIZE1, DW100_DST_IMG_Y_SIZE(size_y));
+ dw100_write(dw_dev, DW100_DST_IMG_UV_SIZE1,
+ DW100_DST_IMG_UV_SIZE(size_uv));
+}
+
+static void dw100_hw_set_mapping(struct dw100_device *dw_dev, dma_addr_t addr,
+ u32 width, u32 height)
+{
+ dev_dbg(&dw_dev->pdev->dev,
+ "Set HW mapping registers for %ux%u addr:%pad",
+ width, height, &addr);
+
+ dw100_write(dw_dev, DW100_MAP_LUT_ADDR, DW100_MAP_LUT_ADDR_ADDR(addr));
+ dw100_write(dw_dev, DW100_MAP_LUT_SIZE, DW100_MAP_LUT_SIZE_WIDTH(width)
+ | DW100_MAP_LUT_SIZE_HEIGHT(height));
+}
+
+static void dw100_hw_clear_irq(struct dw100_device *dw_dev, unsigned int irq)
+{
+ dw100_write(dw_dev, DW100_INTERRUPT_STATUS,
+ DW100_INTERRUPT_STATUS_INT_CLEAR(irq));
+}
+
+static void dw100_hw_enable_irq(struct dw100_device *dw_dev)
+{
+ dw100_write(dw_dev, DW100_INTERRUPT_STATUS,
+ DW100_INTERRUPT_STATUS_INT_ENABLE_MASK);
+}
+
+static void dw100_hw_disable_irq(struct dw100_device *dw_dev)
+{
+ dw100_write(dw_dev, DW100_INTERRUPT_STATUS, 0);
+}
+
+static u32 dw_hw_get_pending_irqs(struct dw100_device *dw_dev)
+{
+ u32 val;
+
+ val = dw100_read(dw_dev, DW100_INTERRUPT_STATUS);
+
+ return DW100_INTERRUPT_STATUS_INT_STATUS(val);
+}
+
+static irqreturn_t dw100_irq_handler(int irq, void *dev_id)
+{
+ struct dw100_device *dw_dev = dev_id;
+ u32 pending_irqs, err_irqs, frame_done_irq;
+ bool with_error = true;
+
+ pending_irqs = dw_hw_get_pending_irqs(dw_dev);
+ frame_done_irq = pending_irqs & DW100_INTERRUPT_STATUS_INT_FRAME_DONE;
+ err_irqs = DW100_INTERRUPT_STATUS_INT_ERR_STATUS(pending_irqs);
+
+ if (frame_done_irq) {
+ dev_dbg(&dw_dev->pdev->dev, "Frame done interrupt\n");
+ with_error = false;
+ err_irqs &= ~DW100_INTERRUPT_STATUS_INT_ERR_STATUS
+ (DW100_INTERRUPT_STATUS_INT_ERR_FRAME_DONE);
+ }
+
+ if (err_irqs)
+ dev_err(&dw_dev->pdev->dev, "Interrupt error: %#x\n", err_irqs);
+
+ dw100_hw_disable_irq(dw_dev);
+ dw100_hw_master_bus_disable(dw_dev);
+ dw100_hw_clear_irq(dw_dev, pending_irqs |
+ DW100_INTERRUPT_STATUS_INT_ERR_TIME_OUT);
+
+ dw100_job_finish(dw_dev, with_error);
+
+ return IRQ_HANDLED;
+}
+
+static void dw100_start(struct dw100_ctx *ctx, struct vb2_v4l2_buffer *in_vb,
+ struct vb2_v4l2_buffer *out_vb)
+{
+ struct dw100_device *dw_dev = ctx->dw_dev;
+
+ out_vb->sequence =
+ dw100_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)->sequence++;
+ in_vb->sequence =
+ dw100_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)->sequence++;
+
+ dev_dbg(&ctx->dw_dev->pdev->dev,
+ "Starting queues %p->%p, sequence %u->%u\n",
+ v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE),
+ v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE),
+ in_vb->sequence, out_vb->sequence);
+
+ v4l2_m2m_buf_copy_metadata(in_vb, out_vb, true);
+
+ /* Now, let's deal with hardware ... */
+ dw100_hw_master_bus_disable(dw_dev);
+ dw100_hw_init_ctrl(dw_dev);
+ dw100_hw_set_pixel_boundary(dw_dev);
+ dw100_hw_set_src_crop(dw_dev, &ctx->q_data[DW100_QUEUE_SRC],
+ &ctx->q_data[DW100_QUEUE_DST]);
+ dw100_hw_set_source(dw_dev, &ctx->q_data[DW100_QUEUE_SRC],
+ &in_vb->vb2_buf);
+ dw100_hw_set_destination(dw_dev, &ctx->q_data[DW100_QUEUE_DST],
+ ctx->q_data[DW100_QUEUE_SRC].fmt,
+ &out_vb->vb2_buf);
+ dw100_hw_set_mapping(dw_dev, ctx->map_dma,
+ ctx->map_width, ctx->map_height);
+ dw100_hw_enable_irq(dw_dev);
+ dw100_hw_dewarp_start(dw_dev);
+
+ /* Enable Bus */
+ dw100_hw_master_bus_enable(dw_dev);
+}
+
+static void dw100_device_run(void *priv)
+{
+ struct dw100_ctx *ctx = priv;
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
+
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+ dw100_start(ctx, src_buf, dst_buf);
+}
+
+static const struct v4l2_m2m_ops dw100_m2m_ops = {
+ .device_run = dw100_device_run,
+};
+
+static struct video_device *dw100_init_video_device(struct dw100_device *dw_dev)
+{
+ struct video_device *vfd = &dw_dev->vfd;
+
+ vfd->vfl_dir = VFL_DIR_M2M;
+ vfd->fops = &dw100_fops;
+ vfd->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+ vfd->ioctl_ops = &dw100_ioctl_ops;
+ vfd->minor = -1;
+ vfd->release = video_device_release_empty;
+ vfd->v4l2_dev = &dw_dev->v4l2_dev;
+ vfd->lock = &dw_dev->vfd_mutex;
+
+ strscpy(vfd->name, DRV_NAME, sizeof(vfd->name));
+ mutex_init(vfd->lock);
+ video_set_drvdata(vfd, dw_dev);
+
+ return vfd;
+}
+
+static int dw100_dump_regs_show(struct seq_file *m, void *private)
+{
+ struct dw100_device *dw_dev = m->private;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(&dw_dev->pdev->dev);
+ if (ret < 0)
+ return ret;
+
+ ret = dw100_dump_regs(m);
+
+ pm_runtime_put_sync(&dw_dev->pdev->dev);
+
+ return ret;
+}
+DEFINE_SHOW_ATTRIBUTE(dw100_dump_regs);
+
+static void dw100_debugfs_init(struct dw100_device *dw_dev)
+{
+ dw_dev->debugfs_root =
+ debugfs_create_dir(dev_name(&dw_dev->pdev->dev), NULL);
+
+ debugfs_create_file("dump_regs", 0600, dw_dev->debugfs_root, dw_dev,
+ &dw100_dump_regs_fops);
+}
+
+static void dw100_debugfs_exit(struct dw100_device *dw_dev)
+{
+ debugfs_remove_recursive(dw_dev->debugfs_root);
+}
+
+static int dw100_probe(struct platform_device *pdev)
+{
+ struct dw100_device *dw_dev;
+ struct video_device *vfd;
+ struct resource *res;
+ int ret, irq;
+
+ dw_dev = devm_kzalloc(&pdev->dev, sizeof(*dw_dev), GFP_KERNEL);
+ if (!dw_dev)
+ return -ENOMEM;
+ dw_dev->pdev = pdev;
+
+ ret = devm_clk_bulk_get_all(&pdev->dev, &dw_dev->clks);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to get clocks: %d\n", ret);
+ return ret;
+ }
+ dw_dev->num_clks = ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dw_dev->mmio = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dw_dev->mmio))
+ return PTR_ERR(dw_dev->mmio);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ platform_set_drvdata(pdev, dw_dev);
+
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to resume the device: %d\n", ret);
+ goto err_pm;
+ }
+
+ pm_runtime_put_sync(&pdev->dev);
+
+ ret = devm_request_irq(&pdev->dev, irq, dw100_irq_handler, IRQF_ONESHOT,
+ dev_name(&pdev->dev), dw_dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
+ return ret;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &dw_dev->v4l2_dev);
+ if (ret)
+ goto err_pm;
+
+ vfd = dw100_init_video_device(dw_dev);
+
+ dw_dev->m2m_dev = v4l2_m2m_init(&dw100_m2m_ops);
+ if (IS_ERR(dw_dev->m2m_dev)) {
+ dev_err(&pdev->dev, "Failed to init mem2mem device\n");
+ ret = PTR_ERR(dw_dev->m2m_dev);
+ goto err_v4l2;
+ }
+
+ dw_dev->mdev.dev = &pdev->dev;
+ strscpy(dw_dev->mdev.model, "dw100", sizeof(dw_dev->mdev.model));
+ media_device_init(&dw_dev->mdev);
+ dw_dev->v4l2_dev.mdev = &dw_dev->mdev;
+
+ ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register video device\n");
+ goto err_m2m;
+ }
+
+ ret = v4l2_m2m_register_media_controller(dw_dev->m2m_dev, vfd,
+ MEDIA_ENT_F_PROC_VIDEO_SCALER);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to init mem2mem media controller\n");
+ goto error_v4l2;
+ }
+
+ ret = media_device_register(&dw_dev->mdev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register mem2mem media device\n");
+ goto error_m2m_mc;
+ }
+
+ dw100_debugfs_init(dw_dev);
+
+ dev_info(&pdev->dev,
+ "dw100 v4l2 m2m registered as /dev/video%u\n", vfd->num);
+
+ return 0;
+
+error_m2m_mc:
+ v4l2_m2m_unregister_media_controller(dw_dev->m2m_dev);
+error_v4l2:
+ video_unregister_device(vfd);
+err_m2m:
+ media_device_cleanup(&dw_dev->mdev);
+ v4l2_m2m_release(dw_dev->m2m_dev);
+err_v4l2:
+ v4l2_device_unregister(&dw_dev->v4l2_dev);
+err_pm:
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static int dw100_remove(struct platform_device *pdev)
+{
+ struct dw100_device *dw_dev = platform_get_drvdata(pdev);
+
+ dw100_debugfs_exit(dw_dev);
+
+ pm_runtime_disable(&pdev->dev);
+
+ media_device_unregister(&dw_dev->mdev);
+ v4l2_m2m_unregister_media_controller(dw_dev->m2m_dev);
+ media_device_cleanup(&dw_dev->mdev);
+
+ video_unregister_device(&dw_dev->vfd);
+ mutex_destroy(dw_dev->vfd.lock);
+ v4l2_m2m_release(dw_dev->m2m_dev);
+ v4l2_device_unregister(&dw_dev->v4l2_dev);
+
+ return 0;
+}
+
+static int __maybe_unused dw100_runtime_suspend(struct device *dev)
+{
+ struct dw100_device *dw_dev = dev_get_drvdata(dev);
+
+ clk_bulk_disable_unprepare(dw_dev->num_clks, dw_dev->clks);
+
+ return 0;
+}
+
+static int __maybe_unused dw100_runtime_resume(struct device *dev)
+{
+ int ret;
+ struct dw100_device *dw_dev = dev_get_drvdata(dev);
+
+ ret = clk_bulk_prepare_enable(dw_dev->num_clks, dw_dev->clks);
+
+ if (ret)
+ return ret;
+
+ dw100_hw_reset(dw_dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops dw100_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(dw100_runtime_suspend,
+ dw100_runtime_resume, NULL)
+};
+
+static const struct of_device_id dw100_dt_ids[] = {
+ { .compatible = "nxp,imx8mp-dw100", .data = NULL },
+ { },
+};
+MODULE_DEVICE_TABLE(of, dw100_dt_ids);
+
+static struct platform_driver dw100_driver = {
+ .probe = dw100_probe,
+ .remove = dw100_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .pm = &dw100_pm,
+ .of_match_table = dw100_dt_ids,
+ },
+};
+
+module_platform_driver(dw100_driver);
+
+MODULE_DESCRIPTION("DW100 Hardware dewarper");
+MODULE_AUTHOR("Xavier Roumegue <Xavier.Roumegue@oss.nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/nxp/dw100/dw100_regs.h b/drivers/media/platform/nxp/dw100/dw100_regs.h
new file mode 100644
index 000000000000..e85dfeff9056
--- /dev/null
+++ b/drivers/media/platform/nxp/dw100/dw100_regs.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * DW100 Hardware dewarper
+ *
+ * Copyright 2022 NXP
+ * Author: Xavier Roumegue (xavier.roumegue@oss.nxp.com)
+ */
+
+#ifndef _DW100_REGS_H_
+#define _DW100_REGS_H_
+
+/* AHB register offset */
+#define DW100_DEWARP_ID 0x00
+#define DW100_DEWARP_CTRL 0x04
+#define DW100_DEWARP_CTRL_ENABLE BIT(0)
+#define DW100_DEWARP_CTRL_START BIT(1)
+#define DW100_DEWARP_CTRL_SOFT_RESET BIT(2)
+#define DW100_DEWARP_CTRL_FORMAT_YUV422_SP 0UL
+#define DW100_DEWARP_CTRL_FORMAT_YUV422_PACKED 1UL
+#define DW100_DEWARP_CTRL_FORMAT_YUV420_SP 2UL
+#define DW100_DEWARP_CTRL_INPUT_FORMAT_MASK GENMASK(5, 4)
+#define DW100_DEWARP_CTRL_INPUT_FORMAT(x) ((x) << 4)
+#define DW100_DEWARP_CTRL_OUTPUT_FORMAT(x) ((x) << 6)
+#define DW100_DEWARP_CTRL_OUTPUT_FORMAT_MASK GENMASK(7, 6)
+#define DW100_DEWARP_CTRL_SRC_AUTO_SHADOW BIT(8)
+#define DW100_DEWARP_CTRL_HW_HANDSHAKE BIT(9)
+#define DW100_DEWARP_CTRL_DST_AUTO_SHADOW BIT(10)
+#define DW100_DEWARP_CTRL_SPLIT_LINE BIT(11)
+#define DW100_DEWARP_CTRL_PREFETCH_MODE_MASK GENMASK(17, 16)
+#define DW100_DEWARP_CTRL_PREFETCH_MODE_TRAVERSAL (0UL << 16)
+#define DW100_DEWARP_CTRL_PREFETCH_MODE_CALCULATION (1UL << 16)
+#define DW100_DEWARP_CTRL_PREFETCH_MODE_AUTO (2UL << 16)
+#define DW100_DEWARP_CTRL_PREFETCH_THRESHOLD_MASK GENMASK(24, 18)
+#define DW100_DEWARP_CTRL_PREFETCH_THRESHOLD(x) ((x) << 18)
+
+#define DW100_MAP_LUT_ADDR 0x08
+#define DW100_MAP_LUT_ADDR_ADDR(addr) (((addr) >> 4) & GENMASK(29, 0))
+#define DW100_MAP_LUT_SIZE 0x0c
+#define DW100_MAP_LUT_SIZE_WIDTH(w) (((w) & GENMASK(10, 0)) << 0)
+#define DW100_MAP_LUT_SIZE_HEIGHT(h) (((h) & GENMASK(10, 0)) << 16)
+#define DW100_SRC_IMG_Y_BASE 0x10
+#define DW100_IMG_Y_BASE(base) (((base) >> 4) & GENMASK(29, 0))
+#define DW100_SRC_IMG_UV_BASE 0x14
+#define DW100_IMG_UV_BASE(base) (((base) >> 4) & GENMASK(29, 0))
+#define DW100_SRC_IMG_SIZE 0x18
+#define DW100_IMG_SIZE_WIDTH(w) (((w) & GENMASK(12, 0)) << 0)
+#define DW100_IMG_SIZE_HEIGHT(h) (((h) & GENMASK(12, 0)) << 16)
+
+#define DW100_SRC_IMG_STRIDE 0x1c
+#define DW100_MAP_LUT_ADDR2 0x20
+#define DW100_MAP_LUT_SIZE2 0x24
+#define DW100_SRC_IMG_Y_BASE2 0x28
+#define DW100_SRC_IMG_UV_BASE2 0x2c
+#define DW100_SRC_IMG_SIZE2 0x30
+#define DW100_SRC_IMG_STRIDE2 0x34
+#define DW100_DST_IMG_Y_BASE 0x38
+#define DW100_DST_IMG_UV_BASE 0x3c
+#define DW100_DST_IMG_SIZE 0x40
+#define DW100_DST_IMG_STRIDE 0x44
+#define DW100_DST_IMG_Y_BASE2 0x48
+#define DW100_DST_IMG_UV_BASE2 0x4c
+#define DW100_DST_IMG_SIZE2 0x50
+#define DW100_DST_IMG_STRIDE2 0x54
+#define DW100_SWAP_CONTROL 0x58
+#define DW100_SWAP_CONTROL_BYTE BIT(0)
+#define DW100_SWAP_CONTROL_SHORT BIT(1)
+#define DW100_SWAP_CONTROL_WORD BIT(2)
+#define DW100_SWAP_CONTROL_LONG BIT(3)
+#define DW100_SWAP_CONTROL_Y(x) (((x) & GENMASK(3, 0)) << 0)
+#define DW100_SWAP_CONTROL_UV(x) (((x) & GENMASK(3, 0)) << 4)
+#define DW100_SWAP_CONTROL_SRC(x) (((x) & GENMASK(7, 0)) << 0)
+#define DW100_SWAP_CONTROL_DST(x) (((x) & GENMASK(7, 0)) << 8)
+#define DW100_SWAP_CONTROL_SRC2(x) (((x) & GENMASK(7, 0)) << 16)
+#define DW100_SWAP_CONTROL_DST2(x) (((x) & GENMASK(7, 0)) << 24)
+#define DW100_SWAP_CONTROL_SRC_MASK GENMASK(7, 0)
+#define DW100_SWAP_CONTROL_DST_MASK GENMASK(15, 8)
+#define DW100_SWAP_CONTROL_SRC2_MASK GENMASK(23, 16)
+#define DW100_SWAP_CONTROL_DST2_MASK GENMASK(31, 24)
+#define DW100_VERTICAL_SPLIT_LINE 0x5c
+#define DW100_HORIZON_SPLIT_LINE 0x60
+#define DW100_SCALE_FACTOR 0x64
+#define DW100_ROI_START 0x68
+#define DW100_ROI_START_X(x) (((x) & GENMASK(12, 0)) << 0)
+#define DW100_ROI_START_Y(y) (((y) & GENMASK(12, 0)) << 16)
+#define DW100_BOUNDARY_PIXEL 0x6c
+#define DW100_BOUNDARY_PIXEL_V(v) (((v) & GENMASK(7, 0)) << 0)
+#define DW100_BOUNDARY_PIXEL_U(u) (((u) & GENMASK(7, 0)) << 8)
+#define DW100_BOUNDARY_PIXEL_Y(y) (((y) & GENMASK(7, 0)) << 16)
+
+#define DW100_INTERRUPT_STATUS 0x70
+#define DW100_INTERRUPT_STATUS_INT_FRAME_DONE BIT(0)
+#define DW100_INTERRUPT_STATUS_INT_ERR_TIME_OUT BIT(1)
+#define DW100_INTERRUPT_STATUS_INT_ERR_AXI_RESP BIT(2)
+#define DW100_INTERRUPT_STATUS_INT_ERR_X BIT(3)
+#define DW100_INTERRUPT_STATUS_INT_ERR_MB_FETCH BIT(4)
+#define DW100_INTERRUPT_STATUS_INT_ERR_FRAME2 BIT(5)
+#define DW100_INTERRUPT_STATUS_INT_ERR_FRAME3 BIT(6)
+#define DW100_INTERRUPT_STATUS_INT_ERR_FRAME_DONE BIT(7)
+#define DW100_INTERRUPT_STATUS_INT_ERR_STATUS(x) (((x) >> 1) & 0x7f)
+#define DW100_INTERRUPT_STATUS_INT_STATUS(x) ((x) & 0xff)
+
+#define DW100_INTERRUPT_STATUS_INT_ENABLE_MASK GENMASK(15, 8)
+#define DW100_INTERRUPT_STATUS_INT_ENABLE(x) (((x) & GENMASK(7, 0)) << 8)
+#define DW100_INTERRUPT_STATUS_FRAME_BUSY BIT(16)
+#define DW100_INTERRUPT_STATUS_INT_CLEAR(x) (((x) & GENMASK(7, 0)) << 24)
+#define DW100_BUS_CTRL 0x74
+#define DW100_BUS_CTRL_AXI_MASTER_ENABLE BIT(31)
+#define DW100_BUS_CTRL1 0x78
+#define DW100_BUS_TIME_OUT_CYCLE 0x7c
+#define DW100_DST_IMG_Y_SIZE1 0x80
+#define DW100_DST_IMG_Y_SIZE(sz) (((sz) >> 4) & GENMASK(29, 0))
+#define DW100_DST_IMG_UV_SIZE(sz) (((sz) >> 4) & GENMASK(29, 0))
+#define DW100_DST_IMG_UV_SIZE1 0x84
+#define DW100_DST_IMG_Y_SIZE2 0x88
+#define DW100_DST_IMG_UV_SIZE2 0x8c
+
+#endif /* _DW100_REGS_H_ */
diff --git a/drivers/media/platform/renesas/vsp1/vsp1.h b/drivers/media/platform/renesas/vsp1/vsp1.h
index 37cf33c7e6ca..2f6f0c6ae555 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1.h
+++ b/drivers/media/platform/renesas/vsp1/vsp1.h
@@ -22,6 +22,7 @@
struct clk;
struct device;
struct rcar_fcp_device;
+struct reset_control;
struct vsp1_drm;
struct vsp1_entity;
@@ -54,6 +55,7 @@ struct vsp1_uif;
#define VSP1_HAS_HGT BIT(8)
#define VSP1_HAS_BRS BIT(9)
#define VSP1_HAS_EXT_DL BIT(10)
+#define VSP1_HAS_NON_ZERO_LBA BIT(11)
struct vsp1_device_info {
u32 version;
@@ -66,6 +68,7 @@ struct vsp1_device_info {
unsigned int uif_count;
unsigned int wpf_count;
unsigned int num_bru_inputs;
+ u8 soc;
bool uapi;
};
@@ -79,6 +82,7 @@ struct vsp1_device {
void __iomem *mmio;
struct rcar_fcp_device *fcp;
struct device *bus_master;
+ struct reset_control *rstc;
struct vsp1_brx *brs;
struct vsp1_brx *bru;
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_drv.c b/drivers/media/platform/renesas/vsp1/vsp1_drv.c
index 1f73c48eb738..c260d318d298 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_drv.c
@@ -16,6 +16,7 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/reset.h>
#include <linux/videodev2.h>
#include <media/rcar-fcp.h>
@@ -622,6 +623,7 @@ static int __maybe_unused vsp1_pm_runtime_suspend(struct device *dev)
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
rcar_fcp_disable(vsp1->fcp);
+ reset_control_assert(vsp1->rstc);
return 0;
}
@@ -631,13 +633,31 @@ static int __maybe_unused vsp1_pm_runtime_resume(struct device *dev)
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
int ret;
+ ret = reset_control_deassert(vsp1->rstc);
+ if (ret < 0)
+ return ret;
+
if (vsp1->info) {
+ /*
+ * On R-Car Gen2 and RZ/G1, vsp1 register access after deassert
+ * can cause lock-up. It is a special case and needs some delay
+ * to avoid this lock-up.
+ */
+ if (vsp1->info->gen == 2)
+ udelay(1);
+
ret = vsp1_device_init(vsp1);
if (ret < 0)
- return ret;
+ goto done;
}
- return rcar_fcp_enable(vsp1->fcp);
+ ret = rcar_fcp_enable(vsp1->fcp);
+
+done:
+ if (ret < 0)
+ reset_control_assert(vsp1->rstc);
+
+ return ret;
}
static const struct dev_pm_ops vsp1_pm_ops = {
@@ -768,6 +788,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
}, {
.version = VI6_IP_VERSION_MODEL_VSPD_V3,
.model = "VSP2-D",
+ .soc = VI6_IP_VERSION_SOC_V3H,
.gen = 3,
.features = VSP1_HAS_BRS | VSP1_HAS_BRU,
.lif_count = 1,
@@ -776,6 +797,17 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
.wpf_count = 1,
.num_bru_inputs = 5,
}, {
+ .version = VI6_IP_VERSION_MODEL_VSPD_V3,
+ .model = "VSP2-D",
+ .soc = VI6_IP_VERSION_SOC_V3M,
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_NON_ZERO_LBA,
+ .lif_count = 1,
+ .rpf_count = 5,
+ .uif_count = 1,
+ .wpf_count = 1,
+ .num_bru_inputs = 5,
+ }, {
.version = VI6_IP_VERSION_MODEL_VSPDL_GEN3,
.model = "VSP2-DL",
.gen = 3,
@@ -798,11 +830,55 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
},
};
+static const struct vsp1_device_info rzg2l_vsp2_device_info = {
+ .version = VI6_IP_VERSION_MODEL_VSPD_RZG2L,
+ .model = "VSP2-D",
+ .soc = VI6_IP_VERSION_SOC_RZG2L,
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_WPF_VFLIP | VSP1_HAS_EXT_DL
+ | VSP1_HAS_NON_ZERO_LBA,
+ .lif_count = 1,
+ .rpf_count = 2,
+ .wpf_count = 1,
+};
+
+static const struct vsp1_device_info *vsp1_lookup_info(struct vsp1_device *vsp1)
+{
+ const struct vsp1_device_info *info;
+ unsigned int i;
+ u32 model;
+ u32 soc;
+
+ /*
+ * Try the info stored in match data first for devices that don't have
+ * a version register.
+ */
+ info = of_device_get_match_data(vsp1->dev);
+ if (info) {
+ vsp1->version = VI6_IP_VERSION_VSP_SW | info->version | info->soc;
+ return info;
+ }
+
+ vsp1->version = vsp1_read(vsp1, VI6_IP_VERSION);
+ model = vsp1->version & VI6_IP_VERSION_MODEL_MASK;
+ soc = vsp1->version & VI6_IP_VERSION_SOC_MASK;
+
+ for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) {
+ info = &vsp1_device_infos[i];
+
+ if (model == info->version && (!info->soc || soc == info->soc))
+ return info;
+ }
+
+ dev_err(vsp1->dev, "unsupported IP version 0x%08x\n", vsp1->version);
+
+ return NULL;
+}
+
static int vsp1_probe(struct platform_device *pdev)
{
struct vsp1_device *vsp1;
struct device_node *fcp_node;
- unsigned int i;
int ret;
int irq;
@@ -825,6 +901,11 @@ static int vsp1_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
+ vsp1->rstc = devm_reset_control_get_shared(&pdev->dev, NULL);
+ if (IS_ERR(vsp1->rstc))
+ return dev_err_probe(&pdev->dev, PTR_ERR(vsp1->rstc),
+ "failed to get reset control\n");
+
/* FCP (optional). */
fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
if (fcp_node) {
@@ -853,19 +934,8 @@ static int vsp1_probe(struct platform_device *pdev)
if (ret < 0)
goto done;
- vsp1->version = vsp1_read(vsp1, VI6_IP_VERSION);
-
- for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) {
- if ((vsp1->version & VI6_IP_VERSION_MODEL_MASK) ==
- vsp1_device_infos[i].version) {
- vsp1->info = &vsp1_device_infos[i];
- break;
- }
- }
-
+ vsp1->info = vsp1_lookup_info(vsp1);
if (!vsp1->info) {
- dev_err(&pdev->dev, "unsupported IP version 0x%08x\n",
- vsp1->version);
vsp1_device_put(vsp1);
ret = -ENXIO;
goto done;
@@ -922,6 +992,7 @@ static int vsp1_remove(struct platform_device *pdev)
static const struct of_device_id vsp1_of_match[] = {
{ .compatible = "renesas,vsp1" },
{ .compatible = "renesas,vsp2" },
+ { .compatible = "renesas,r9a07g044-vsp2", .data = &rzg2l_vsp2_device_info },
{ },
};
MODULE_DEVICE_TABLE(of, vsp1_of_match);
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_lif.c b/drivers/media/platform/renesas/vsp1/vsp1_lif.c
index 6a6857ac9327..186a5730e1e3 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_lif.c
@@ -107,6 +107,7 @@ static void lif_configure_stream(struct vsp1_entity *entity,
case VI6_IP_VERSION_MODEL_VSPDL_GEN3:
case VI6_IP_VERSION_MODEL_VSPD_V3:
+ case VI6_IP_VERSION_MODEL_VSPD_RZG2L:
hbth = 0;
obth = 1500;
lbth = 0;
@@ -130,13 +131,12 @@ static void lif_configure_stream(struct vsp1_entity *entity,
VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);
/*
- * On R-Car V3M the LIF0 buffer attribute register has to be set to a
- * non-default value to guarantee proper operation (otherwise artifacts
- * may appear on the output). The value required by the manual is not
- * explained but is likely a buffer size or threshold.
+ * On R-Car V3M and RZ/G2L the LIF0 buffer attribute register has to be
+ * set to a non-default value to guarantee proper operation (otherwise
+ * artifacts may appear on the output). The value required by the
+ * manual is not explained but is likely a buffer size or threshold.
*/
- if ((entity->vsp1->version & VI6_IP_VERSION_MASK) ==
- (VI6_IP_VERSION_MODEL_VSPD_V3 | VI6_IP_VERSION_SOC_V3M))
+ if (vsp1_feature(entity->vsp1, VSP1_HAS_NON_ZERO_LBA))
vsp1_lif_write(lif, dlb, VI6_LIF_LBA,
VI6_LIF_LBA_LBA0 |
(1536 << VI6_LIF_LBA_LBA1_SHIFT));
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_regs.h b/drivers/media/platform/renesas/vsp1/vsp1_regs.h
index fae7286eb01e..8928f4c6bb55 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/renesas/vsp1/vsp1_regs.h
@@ -767,6 +767,8 @@
#define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)
#define VI6_IP_VERSION_MODEL_VSPBS_GEN3 (0x1a << 8)
#define VI6_IP_VERSION_MODEL_VSPD_V3U (0x1c << 8)
+/* RZ/G2L SoCs have no version register, So use 0x80 as the model version */
+#define VI6_IP_VERSION_MODEL_VSPD_RZG2L (0x80 << 8)
#define VI6_IP_VERSION_SOC_MASK (0xff << 0)
#define VI6_IP_VERSION_SOC_H2 (0x01 << 0)
@@ -780,6 +782,10 @@
#define VI6_IP_VERSION_SOC_M3N (0x04 << 0)
#define VI6_IP_VERSION_SOC_E3 (0x04 << 0)
#define VI6_IP_VERSION_SOC_V3U (0x05 << 0)
+/* RZ/G2L SoCs have no version register, So use 0x80 for SoC Identification */
+#define VI6_IP_VERSION_SOC_RZG2L (0x80 << 0)
+
+#define VI6_IP_VERSION_VSP_SW (0xfffe << 16) /* SW VSP version */
/* -----------------------------------------------------------------------------
* RPF CLUT Registers
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_video.c b/drivers/media/platform/renesas/vsp1/vsp1_video.c
index e8e0ee5f2277..df1606b49d77 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_video.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_video.c
@@ -305,7 +305,7 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe)
* @video: the video node
*
* This function completes the current buffer by filling its sequence number,
- * time stamp and payload size, and hands it back to the videobuf core.
+ * time stamp and payload size, and hands it back to the vb2 core.
*
* Return the next queued buffer or NULL if the queue is empty.
*/
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 2f8df74ad0fd..61b25fcf826e 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -816,7 +816,7 @@ static int rga_probe(struct platform_device *pdev)
ret = rga_parse_dt(rga);
if (ret)
- dev_err(&pdev->dev, "Unable to parse OF data\n");
+ return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n");
pm_runtime_enable(rga->dev);
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.h b/drivers/media/platform/samsung/exynos4-is/fimc-core.h
index 7a058f3e6298..2b0760add092 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.h
@@ -215,7 +215,7 @@ struct fimc_addr {
/**
* struct fimc_vid_buffer - the driver's video buffer
- * @vb: v4l videobuf buffer
+ * @vb: v4l vb2 buffer
* @list: linked list structure for buffer queue
* @addr: precalculated DMA address set
* @index: buffer index for the output DMA engine
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
index e3072d69c49f..a7704ff069d6 100644
--- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
@@ -213,6 +213,7 @@ static int fimc_is_register_subdevs(struct fimc_is *is)
if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {
of_node_put(child);
+ of_node_put(i2c_bus);
return ret;
}
index++;
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
index 761341934925..fca5c6405eec 100644
--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
@@ -323,7 +323,7 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
}
ctx->sequence++;
/* The MFC returns address of the buffer, now we have to
- * check which videobuf does it correspond to */
+ * check which vb2_buffer does it correspond to */
list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
u32 addr = (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->b->vb2_buf, 0);
@@ -1399,6 +1399,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
/* Deinit MFC if probe had failed */
err_enc_reg:
video_unregister_device(dev->vfd_dec);
+ dev->vfd_dec = NULL;
err_dec_reg:
video_device_release(dev->vfd_enc);
err_enc_alloc:
@@ -1444,8 +1445,6 @@ static int s5p_mfc_remove(struct platform_device *pdev)
video_unregister_device(dev->vfd_enc);
video_unregister_device(dev->vfd_dec);
- video_device_release(dev->vfd_enc);
- video_device_release(dev->vfd_dec);
v4l2_device_unregister(&dev->v4l2_dev);
s5p_mfc_unconfigure_dma_memory(dev);
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c
index 1d46e113d01d..74d64a20ba5b 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c
@@ -177,7 +177,7 @@ static int sun6i_video_start_streaming(struct vb2_queue *vq, unsigned int count)
/*
* CSI will lookup the next dma buffer for next frame before the
- * the current frame done IRQ triggered. This is not documented
+ * current frame done IRQ triggered. This is not documented
* but reported by Ondřej Jirman.
* The BSP code has workaround for this too. It skip to mark the
* first buffer as frame done for VB2 and pass the second buffer
diff --git a/drivers/media/platform/ti/am437x/am437x-vpfe.h b/drivers/media/platform/ti/am437x/am437x-vpfe.h
index 05ee37db0273..f8b4e917b91a 100644
--- a/drivers/media/platform/ti/am437x/am437x-vpfe.h
+++ b/drivers/media/platform/ti/am437x/am437x-vpfe.h
@@ -267,7 +267,7 @@ struct vpfe_device {
* is different from the image window
*/
struct v4l2_rect crop;
- /* Buffer queue used in video-buf */
+ /* Buffer queue used in vb2 */
struct vb2_queue buffer_queue;
/* Queue of filled frames */
struct list_head dma_queue;
diff --git a/drivers/media/platform/ti/cal/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c
index e136d70b4048..16ae52879a79 100644
--- a/drivers/media/platform/ti/cal/cal-camerarx.c
+++ b/drivers/media/platform/ti/cal/cal-camerarx.c
@@ -622,12 +622,12 @@ static inline struct cal_camerarx *to_cal_camerarx(struct v4l2_subdev *sd)
static struct v4l2_mbus_framefmt *
cal_camerarx_get_pad_format(struct cal_camerarx *phy,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
unsigned int pad, u32 which)
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_format(&phy->subdev, sd_state, pad);
+ return v4l2_subdev_get_try_format(&phy->subdev, state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &phy->formats[pad];
default:
@@ -653,7 +653,7 @@ static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable)
}
static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum *code)
{
struct cal_camerarx *phy = to_cal_camerarx(sd);
@@ -670,7 +670,7 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
goto out;
}
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ fmt = cal_camerarx_get_pad_format(phy, state,
CAL_CAMERARX_PAD_SINK,
code->which);
code->code = fmt->code;
@@ -690,7 +690,7 @@ out:
}
static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_frame_size_enum *fse)
{
struct cal_camerarx *phy = to_cal_camerarx(sd);
@@ -706,7 +706,7 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd,
if (cal_rx_pad_is_source(fse->pad)) {
struct v4l2_mbus_framefmt *fmt;
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ fmt = cal_camerarx_get_pad_format(phy, state,
CAL_CAMERARX_PAD_SINK,
fse->which);
if (fse->code != fmt->code) {
@@ -738,7 +738,7 @@ out:
}
static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
{
struct cal_camerarx *phy = to_cal_camerarx(sd);
@@ -746,7 +746,7 @@ static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
mutex_lock(&phy->mutex);
- fmt = cal_camerarx_get_pad_format(phy, sd_state, format->pad,
+ fmt = cal_camerarx_get_pad_format(phy, state, format->pad,
format->which);
format->format = *fmt;
@@ -756,7 +756,7 @@ static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
}
static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
{
struct cal_camerarx *phy = to_cal_camerarx(sd);
@@ -766,7 +766,7 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
/* No transcoding, source and sink formats must match. */
if (cal_rx_pad_is_source(format->pad))
- return cal_camerarx_sd_get_fmt(sd, sd_state, format);
+ return cal_camerarx_sd_get_fmt(sd, state, format);
/*
* Default to the first format if the requested media bus code isn't
@@ -792,12 +792,12 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
mutex_lock(&phy->mutex);
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ fmt = cal_camerarx_get_pad_format(phy, state,
CAL_CAMERARX_PAD_SINK,
format->which);
*fmt = format->format;
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ fmt = cal_camerarx_get_pad_format(phy, state,
CAL_CAMERARX_PAD_FIRST_SOURCE,
format->which);
*fmt = format->format;
@@ -808,10 +808,10 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
}
static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state)
+ struct v4l2_subdev_state *state)
{
struct v4l2_subdev_format format = {
- .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
+ .which = state ? V4L2_SUBDEV_FORMAT_TRY
: V4L2_SUBDEV_FORMAT_ACTIVE,
.pad = CAL_CAMERARX_PAD_SINK,
.format = {
@@ -826,7 +826,7 @@ static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd,
},
};
- return cal_camerarx_sd_set_fmt(sd, sd_state, &format);
+ return cal_camerarx_sd_set_fmt(sd, state, &format);
}
static const struct v4l2_subdev_video_ops cal_camerarx_video_ops = {
@@ -871,6 +871,7 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
phy->cal = cal;
phy->instance = instance;
+ spin_lock_init(&phy->vc_lock);
mutex_init(&phy->mutex);
phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
diff --git a/drivers/media/platform/ti/cal/cal-video.c b/drivers/media/platform/ti/cal/cal-video.c
index 776da0cfcdbe..21e3d0aabf70 100644
--- a/drivers/media/platform/ti/cal/cal-video.c
+++ b/drivers/media/platform/ti/cal/cal-video.c
@@ -191,7 +191,7 @@ static int cal_legacy_try_fmt_vid_cap(struct file *file, void *priv,
struct cal_ctx *ctx = video_drvdata(file);
const struct cal_format_info *fmtinfo;
struct v4l2_subdev_frame_size_enum fse;
- int ret, found;
+ int found;
fmtinfo = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
if (!fmtinfo) {
@@ -206,12 +206,13 @@ static int cal_legacy_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.field = ctx->v_fmt.fmt.pix.field;
/* check for/find a valid width/height */
- ret = 0;
found = false;
fse.pad = 0;
fse.code = fmtinfo->code;
fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
for (fse.index = 0; ; fse.index++) {
+ int ret;
+
ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_size,
NULL, &fse);
if (ret)
diff --git a/drivers/media/platform/ti/cal/cal.c b/drivers/media/platform/ti/cal/cal.c
index 425b4f4b7ed7..56b61c0583cf 100644
--- a/drivers/media/platform/ti/cal/cal.c
+++ b/drivers/media/platform/ti/cal/cal.c
@@ -543,7 +543,22 @@ void cal_ctx_unprepare(struct cal_ctx *ctx)
void cal_ctx_start(struct cal_ctx *ctx)
{
- ctx->sequence = 0;
+ struct cal_camerarx *phy = ctx->phy;
+
+ /*
+ * Reset the frame number & sequence number, but only if the
+ * virtual channel is not already in use.
+ */
+
+ spin_lock(&phy->vc_lock);
+
+ if (phy->vc_enable_count[ctx->vc]++ == 0) {
+ phy->vc_frame_number[ctx->vc] = 0;
+ phy->vc_sequence[ctx->vc] = 0;
+ }
+
+ spin_unlock(&phy->vc_lock);
+
ctx->dma.state = CAL_DMA_RUNNING;
/* Configure the CSI-2, pixel processing and write DMA contexts. */
@@ -563,8 +578,15 @@ void cal_ctx_start(struct cal_ctx *ctx)
void cal_ctx_stop(struct cal_ctx *ctx)
{
+ struct cal_camerarx *phy = ctx->phy;
long timeout;
+ WARN_ON(phy->vc_enable_count[ctx->vc] == 0);
+
+ spin_lock(&phy->vc_lock);
+ phy->vc_enable_count[ctx->vc]--;
+ spin_unlock(&phy->vc_lock);
+
/*
* Request DMA stop and wait until it completes. If completion times
* out, forcefully disable the DMA.
@@ -601,6 +623,34 @@ void cal_ctx_stop(struct cal_ctx *ctx)
* ------------------------------------------------------------------
*/
+/*
+ * Track a sequence number for each virtual channel, which is shared by
+ * all contexts using the same virtual channel. This is done using the
+ * CSI-2 frame number as a base.
+ */
+static void cal_update_seq_number(struct cal_ctx *ctx)
+{
+ struct cal_dev *cal = ctx->cal;
+ struct cal_camerarx *phy = ctx->phy;
+ u16 prev_frame_num, frame_num;
+ u8 vc = ctx->vc;
+
+ frame_num =
+ cal_read(cal, CAL_CSI2_STATUS(phy->instance, ctx->csi2_ctx)) &
+ 0xffff;
+
+ if (phy->vc_frame_number[vc] != frame_num) {
+ prev_frame_num = phy->vc_frame_number[vc];
+
+ if (prev_frame_num >= frame_num)
+ phy->vc_sequence[vc] += 1;
+ else
+ phy->vc_sequence[vc] += frame_num - prev_frame_num;
+
+ phy->vc_frame_number[vc] = frame_num;
+ }
+}
+
static inline void cal_irq_wdma_start(struct cal_ctx *ctx)
{
spin_lock(&ctx->dma.lock);
@@ -631,6 +681,8 @@ static inline void cal_irq_wdma_start(struct cal_ctx *ctx)
}
spin_unlock(&ctx->dma.lock);
+
+ cal_update_seq_number(ctx);
}
static inline void cal_irq_wdma_end(struct cal_ctx *ctx)
@@ -657,27 +709,62 @@ static inline void cal_irq_wdma_end(struct cal_ctx *ctx)
if (buf) {
buf->vb.vb2_buf.timestamp = ktime_get_ns();
buf->vb.field = ctx->v_fmt.fmt.pix.field;
- buf->vb.sequence = ctx->sequence++;
+ buf->vb.sequence = ctx->phy->vc_sequence[ctx->vc];
+
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
}
+static void cal_irq_handle_wdma(struct cal_ctx *ctx, bool start, bool end)
+{
+ /*
+ * CAL HW interrupts are inherently racy. If we get both start and end
+ * interrupts, we don't know what has happened: did the DMA for a single
+ * frame start and end, or did one frame end and a new frame start?
+ *
+ * Usually for normal pixel frames we get the interrupts separately. If
+ * we do get both, we have to guess. The assumption in the code below is
+ * that the active vertical area is larger than the blanking vertical
+ * area, and thus it is more likely that we get the end of the old frame
+ * and the start of a new frame.
+ *
+ * However, for embedded data, which is only a few lines high, we always
+ * get both interrupts. Here the assumption is that we get both for the
+ * same frame.
+ */
+ if (ctx->v_fmt.fmt.pix.height < 10) {
+ if (start)
+ cal_irq_wdma_start(ctx);
+
+ if (end)
+ cal_irq_wdma_end(ctx);
+ } else {
+ if (end)
+ cal_irq_wdma_end(ctx);
+
+ if (start)
+ cal_irq_wdma_start(ctx);
+ }
+}
+
static irqreturn_t cal_irq(int irq_cal, void *data)
{
struct cal_dev *cal = data;
- u32 status;
-
- status = cal_read(cal, CAL_HL_IRQSTATUS(0));
- if (status) {
- unsigned int i;
+ u32 status[3];
+ unsigned int i;
- cal_write(cal, CAL_HL_IRQSTATUS(0), status);
+ for (i = 0; i < 3; ++i) {
+ status[i] = cal_read(cal, CAL_HL_IRQSTATUS(i));
+ if (status[i])
+ cal_write(cal, CAL_HL_IRQSTATUS(i), status[i]);
+ }
- if (status & CAL_HL_IRQ_OCPO_ERR_MASK)
+ if (status[0]) {
+ if (status[0] & CAL_HL_IRQ_OCPO_ERR_MASK)
dev_err_ratelimited(cal->dev, "OCPO ERROR\n");
for (i = 0; i < cal->data->num_csi2_phy; ++i) {
- if (status & CAL_HL_IRQ_CIO_MASK(i)) {
+ if (status[0] & CAL_HL_IRQ_CIO_MASK(i)) {
u32 cio_stat = cal_read(cal,
CAL_CSI2_COMPLEXIO_IRQSTATUS(i));
@@ -688,7 +775,7 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
cio_stat);
}
- if (status & CAL_HL_IRQ_VC_MASK(i)) {
+ if (status[0] & CAL_HL_IRQ_VC_MASK(i)) {
u32 vc_stat = cal_read(cal, CAL_CSI2_VC_IRQSTATUS(i));
dev_err_ratelimited(cal->dev,
@@ -700,32 +787,12 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
}
}
- /* Check which DMA just finished */
- status = cal_read(cal, CAL_HL_IRQSTATUS(1));
- if (status) {
- unsigned int i;
-
- /* Clear Interrupt status */
- cal_write(cal, CAL_HL_IRQSTATUS(1), status);
-
- for (i = 0; i < cal->num_contexts; ++i) {
- if (status & CAL_HL_IRQ_WDMA_END_MASK(i))
- cal_irq_wdma_end(cal->ctx[i]);
- }
- }
-
- /* Check which DMA just started */
- status = cal_read(cal, CAL_HL_IRQSTATUS(2));
- if (status) {
- unsigned int i;
-
- /* Clear Interrupt status */
- cal_write(cal, CAL_HL_IRQSTATUS(2), status);
+ for (i = 0; i < cal->num_contexts; ++i) {
+ bool end = !!(status[1] & CAL_HL_IRQ_WDMA_END_MASK(i));
+ bool start = !!(status[2] & CAL_HL_IRQ_WDMA_START_MASK(i));
- for (i = 0; i < cal->num_contexts; ++i) {
- if (status & CAL_HL_IRQ_WDMA_START_MASK(i))
- cal_irq_wdma_start(cal->ctx[i]);
- }
+ if (start || end)
+ cal_irq_handle_wdma(cal->ctx[i], start, end);
}
return IRQ_HANDLED;
diff --git a/drivers/media/platform/ti/cal/cal.h b/drivers/media/platform/ti/cal/cal.h
index 61409ddced98..80f2c9c73c71 100644
--- a/drivers/media/platform/ti/cal/cal.h
+++ b/drivers/media/platform/ti/cal/cal.h
@@ -180,6 +180,12 @@ struct cal_camerarx {
struct media_pad pads[CAL_CAMERARX_NUM_PADS];
struct v4l2_mbus_framefmt formats[CAL_CAMERARX_NUM_PADS];
+ /* protects the vc_* fields below */
+ spinlock_t vc_lock;
+ u8 vc_enable_count[4];
+ u16 vc_frame_number[4];
+ u32 vc_sequence[4];
+
/*
* Lock for camerarx ops. Protects:
* - formats
@@ -242,7 +248,6 @@ struct cal_ctx {
const struct cal_format_info **active_fmt;
unsigned int num_active_fmt;
- unsigned int sequence;
struct vb2_queue vb_vidq;
u8 dma_ctx;
u8 cport;
diff --git a/drivers/media/platform/ti/davinci/Kconfig b/drivers/media/platform/ti/davinci/Kconfig
index c61e697aeb12..96d4bed7fe9e 100644
--- a/drivers/media/platform/ti/davinci/Kconfig
+++ b/drivers/media/platform/ti/davinci/Kconfig
@@ -32,55 +32,6 @@ config VIDEO_DAVINCI_VPIF_CAPTURE
To compile this driver as a module, choose M here. There will
be two modules called vpif.ko and vpif_capture.ko
-config VIDEO_DM6446_CCDC
- tristate "TI DM6446 CCDC video capture driver"
- depends on V4L_PLATFORM_DRIVERS
- depends on VIDEO_DEV
- depends on ARCH_DAVINCI || COMPILE_TEST
- depends on I2C
- select VIDEOBUF_DMA_CONTIG
- help
- Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
- with decoder modules such as TVP5146 over BT656 or
- sensor module such as MT9T001 over a raw interface. This
- module configures the interface and CCDC/ISIF to do
- video frame capture from slave decoders.
-
- To compile this driver as a module, choose M here. There will
- be three modules called vpfe_capture.ko, vpss.ko and dm644x_ccdc.ko
-
-config VIDEO_DM355_CCDC
- tristate "TI DM355 CCDC video capture driver"
- depends on V4L_PLATFORM_DRIVERS
- depends on VIDEO_DEV
- depends on ARCH_DAVINCI || COMPILE_TEST
- depends on I2C
- select VIDEOBUF_DMA_CONTIG
- help
- Enables DM355 CCD hw module. DM355 CCDC hw interfaces
- with decoder modules such as TVP5146 over BT656 or
- sensor module such as MT9T001 over a raw interface. This
- module configures the interface and CCDC/ISIF to do
- video frame capture from a slave decoders
-
- To compile this driver as a module, choose M here. There will
- be three modules called vpfe_capture.ko, vpss.ko and dm355_ccdc.ko
-
-config VIDEO_DM365_ISIF
- tristate "TI DM365 ISIF video capture driver"
- depends on V4L_PLATFORM_DRIVERS
- depends on VIDEO_DEV
- depends on ARCH_DAVINCI || COMPILE_TEST
- depends on I2C
- select VIDEOBUF_DMA_CONTIG
- help
- Enables ISIF hw module. This is the hardware module for
- configuring ISIF in VPFE to capture Raw Bayer RGB data from
- a image sensor or YUV data from a YUV source.
-
- To compile this driver as a module, choose M here. There will
- be three modules called vpfe_capture.ko, vpss.ko and isif.ko
-
config VIDEO_DAVINCI_VPBE_DISPLAY
tristate "TI DaVinci VPBE V4L2-Display driver"
depends on V4L_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/ti/davinci/Makefile b/drivers/media/platform/ti/davinci/Makefile
index 05c45bf371aa..b20a91653162 100644
--- a/drivers/media/platform/ti/davinci/Makefile
+++ b/drivers/media/platform/ti/davinci/Makefile
@@ -8,9 +8,5 @@ obj-$(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) += vpif.o vpif_display.o
#VPIF Capture driver
obj-$(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) += vpif.o vpif_capture.o
-# Capture: DM6446 and DM355
-obj-$(CONFIG_VIDEO_DM6446_CCDC) += vpfe_capture.o vpss.o dm644x_ccdc.o
-obj-$(CONFIG_VIDEO_DM355_CCDC) += vpfe_capture.o vpss.o dm355_ccdc.o
-obj-$(CONFIG_VIDEO_DM365_ISIF) += vpfe_capture.o vpss.o isif.o
obj-$(CONFIG_VIDEO_DAVINCI_VPBE_DISPLAY) += vpss.o vpbe.o vpbe_osd.o \
vpbe_venc.o vpbe_display.o
diff --git a/drivers/media/platform/ti/davinci/vpbe.c b/drivers/media/platform/ti/davinci/vpbe.c
index 5f0aeb744e81..509ecc84624e 100644
--- a/drivers/media/platform/ti/davinci/vpbe.c
+++ b/drivers/media/platform/ti/davinci/vpbe.c
@@ -280,7 +280,7 @@ static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
* vpbe_get_output - Get output
* @vpbe_dev: vpbe device ptr
*
- * return current vpbe output to the the index
+ * return current vpbe output to the index
*/
static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
{
diff --git a/drivers/media/platform/ti/davinci/vpif.h b/drivers/media/platform/ti/davinci/vpif.h
index 651943e3e375..52ecc2562216 100644
--- a/drivers/media/platform/ti/davinci/vpif.h
+++ b/drivers/media/platform/ti/davinci/vpif.h
@@ -322,10 +322,10 @@ static inline void channel1_intr_enable(int enable)
}
/* inline function to set buffer addresses in case of Y/C non mux mode */
-static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+static inline void ch0_set_video_buf_addr_yc_nmux(unsigned long top_strt_luma,
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
@@ -334,10 +334,10 @@ static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
}
/* inline function to set buffer addresses in VPIF registers for video data */
-static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+static inline void ch0_set_video_buf_addr(unsigned long top_strt_luma,
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
@@ -345,10 +345,10 @@ static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
}
-static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+static inline void ch1_set_video_buf_addr(unsigned long top_strt_luma,
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
@@ -538,10 +538,10 @@ static inline void channel3_clipping_enable(int enable)
}
/* inline function to set buffer addresses in case of Y/C non mux mode */
-static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+static inline void ch2_set_video_buf_addr_yc_nmux(unsigned long top_strt_luma,
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
@@ -550,10 +550,10 @@ static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
}
/* inline function to set buffer addresses in VPIF registers for video data */
-static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+static inline void ch2_set_video_buf_addr(unsigned long top_strt_luma,
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
@@ -561,10 +561,10 @@ static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
}
-static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+static inline void ch3_set_video_buf_addr(unsigned long top_strt_luma,
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
@@ -574,18 +574,18 @@ static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
/* inline function to set buffer addresses in VPIF registers for vbi data */
static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
}
static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
- unsigned long btm_strt_luma,
- unsigned long top_strt_chroma,
- unsigned long btm_strt_chroma)
+ unsigned long btm_strt_luma,
+ unsigned long top_strt_chroma,
+ unsigned long btm_strt_chroma)
{
regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
diff --git a/drivers/media/platform/ti/davinci/vpif_capture.c b/drivers/media/platform/ti/davinci/vpif_capture.c
index b91eec899eb5..580723333fcc 100644
--- a/drivers/media/platform/ti/davinci/vpif_capture.c
+++ b/drivers/media/platform/ti/davinci/vpif_capture.c
@@ -632,11 +632,11 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
common = &(ch->common[VPIF_VIDEO_INDEX]);
if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
- common->set_addr = ch1_set_videobuf_addr;
+ common->set_addr = ch1_set_video_buf_addr;
else if (2 == muxmode)
- common->set_addr = ch0_set_videobuf_addr_yc_nmux;
+ common->set_addr = ch0_set_video_buf_addr_yc_nmux;
else
- common->set_addr = ch0_set_videobuf_addr;
+ common->set_addr = ch0_set_video_buf_addr;
}
/**
diff --git a/drivers/media/platform/ti/davinci/vpif_capture.h b/drivers/media/platform/ti/davinci/vpif_capture.h
index d5951f61df47..6191056500cf 100644
--- a/drivers/media/platform/ti/davinci/vpif_capture.h
+++ b/drivers/media/platform/ti/davinci/vpif_capture.h
@@ -50,7 +50,7 @@ struct common_obj {
struct vpif_cap_buffer *next_frm;
/* Used to store pixel format */
struct v4l2_format fmt;
- /* Buffer queue used in video-buf */
+ /* Buffer queue used in vb2 */
struct vb2_queue buffer_queue;
/* Queue of filled frames */
struct list_head dma_queue;
diff --git a/drivers/media/platform/ti/davinci/vpif_display.c b/drivers/media/platform/ti/davinci/vpif_display.c
index 5d524acc995d..b2df81603f62 100644
--- a/drivers/media/platform/ti/davinci/vpif_display.c
+++ b/drivers/media/platform/ti/davinci/vpif_display.c
@@ -563,12 +563,12 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode)
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
- common->set_addr = ch3_set_videobuf_addr;
+ common->set_addr = ch3_set_video_buf_addr;
} else {
if (2 == muxmode)
- common->set_addr = ch2_set_videobuf_addr_yc_nmux;
+ common->set_addr = ch2_set_video_buf_addr_yc_nmux;
else
- common->set_addr = ch2_set_videobuf_addr;
+ common->set_addr = ch2_set_video_buf_addr;
}
}
diff --git a/drivers/media/platform/ti/davinci/vpif_display.h b/drivers/media/platform/ti/davinci/vpif_display.h
index f27474e0fc36..dae20053dd73 100644
--- a/drivers/media/platform/ti/davinci/vpif_display.h
+++ b/drivers/media/platform/ti/davinci/vpif_display.h
@@ -64,11 +64,11 @@ struct common_obj {
struct vpif_disp_buffer *next_frm; /* Pointer pointing to next
* vb2_buffer */
struct v4l2_format fmt; /* Used to store the format */
- struct vb2_queue buffer_queue; /* Buffer queue used in
- * video-buf */
+ struct vb2_queue buffer_queue; /* Buffer queue used in vb2 */
struct list_head dma_queue; /* Queue of filled frames */
- spinlock_t irqlock; /* Used in video-buf */
+ spinlock_t irqlock; /* Used for video buffer
+ * handling */
/* channel specific parameters */
struct mutex lock; /* lock used to access this
diff --git a/drivers/media/platform/ti/omap/omap_voutlib.c b/drivers/media/platform/ti/omap/omap_voutlib.c
index fdea2309ee37..0ac46458e41c 100644
--- a/drivers/media/platform/ti/omap/omap_voutlib.c
+++ b/drivers/media/platform/ti/omap/omap_voutlib.c
@@ -107,7 +107,7 @@ EXPORT_SYMBOL_GPL(omap_vout_try_window);
/* Given a new render window in new_win, adjust the window to the
* nearest supported configuration. The image cropping window in crop
* will also be adjusted if necessary. Preference is given to keeping the
- * the window as close to the requested configuration as possible. If
+ * window as close to the requested configuration as possible. If
* successful, new_win, vout->win, and crop are updated.
* Returns zero if successful, or -EINVAL if the requested preview window is
* impossible and cannot reasonably be adjusted.
diff --git a/drivers/media/platform/ti/omap3isp/isp.c b/drivers/media/platform/ti/omap3isp/isp.c
index d251736eb420..a6052df9bb19 100644
--- a/drivers/media/platform/ti/omap3isp/isp.c
+++ b/drivers/media/platform/ti/omap3isp/isp.c
@@ -1528,7 +1528,7 @@ void omap3isp_print_status(struct isp_device *isp)
* To solve this problem power management support is split into prepare/complete
* and suspend/resume operations. The pipelines are stopped in prepare() and the
* ISP clocks get disabled in suspend(). Similarly, the clocks are re-enabled in
- * resume(), and the the pipelines are restarted in complete().
+ * resume(), and the pipelines are restarted in complete().
*
* TODO: PM dependencies between the ISP and sensors are not modelled explicitly
* yet.
diff --git a/drivers/media/platform/ti/omap3isp/ispvideo.c b/drivers/media/platform/ti/omap3isp/ispvideo.c
index d7059180e80e..cc9a97d5d505 100644
--- a/drivers/media/platform/ti/omap3isp/ispvideo.c
+++ b/drivers/media/platform/ti/omap3isp/ispvideo.c
@@ -1071,7 +1071,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
* processing might be possible but requires more testing.
*
* Stream start must be delayed until buffers are available at both the input
- * and output. The pipeline must be started in the videobuf queue callback with
+ * and output. The pipeline must be started in the vb2 queue callback with
* the buffers queue spinlock held. The modules subdev set stream operation must
* not sleep.
*/
diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/media/platform/verisilicon/Kconfig
index 0172a6822ec2..e65b836b9d78 100644
--- a/drivers/staging/media/hantro/Kconfig
+++ b/drivers/media/platform/verisilicon/Kconfig
@@ -1,7 +1,11 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: GPL-2.0-only
+
+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 V4L_MEM2MEM_DRIVERS
depends on VIDEO_DEV
select MEDIA_CONTROLLER
select MEDIA_CONTROLLER_REQUEST_API
diff --git a/drivers/staging/media/hantro/Makefile b/drivers/media/platform/verisilicon/Makefile
index ebd5ede7bef7..ebd5ede7bef7 100644
--- a/drivers/staging/media/hantro/Makefile
+++ b/drivers/media/platform/verisilicon/Makefile
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/media/platform/verisilicon/hantro.h
index 2989ebc631cc..2989ebc631cc 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/media/platform/verisilicon/hantro.h
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
index 2036f72eeb4a..2036f72eeb4a 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
diff --git a/drivers/staging/media/hantro/hantro_g1.c b/drivers/media/platform/verisilicon/hantro_g1.c
index 0ab1cee62218..0ab1cee62218 100644
--- a/drivers/staging/media/hantro/hantro_g1.c
+++ b/drivers/media/platform/verisilicon/hantro_g1.c
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c
index 9de7f05eff2a..9de7f05eff2a 100644
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
+++ b/drivers/media/platform/verisilicon/hantro_g1_h264_dec.c
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c
index 9aea331e1a3c..9aea331e1a3c 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/media/platform/verisilicon/hantro_g1_mpeg2_dec.c
diff --git a/drivers/staging/media/hantro/hantro_g1_regs.h b/drivers/media/platform/verisilicon/hantro_g1_regs.h
index c623b3b0be18..c623b3b0be18 100644
--- a/drivers/staging/media/hantro/hantro_g1_regs.h
+++ b/drivers/media/platform/verisilicon/hantro_g1_regs.h
diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/media/platform/verisilicon/hantro_g1_vp8_dec.c
index 851eb67f19f5..851eb67f19f5 100644
--- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
+++ b/drivers/media/platform/verisilicon/hantro_g1_vp8_dec.c
diff --git a/drivers/staging/media/hantro/hantro_g2.c b/drivers/media/platform/verisilicon/hantro_g2.c
index ee5f14c5f8f2..ee5f14c5f8f2 100644
--- a/drivers/staging/media/hantro/hantro_g2.c
+++ b/drivers/media/platform/verisilicon/hantro_g2.c
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
index 233ecd863d5f..233ecd863d5f 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/media/platform/verisilicon/hantro_g2_regs.h
index 82606783591a..82606783591a 100644
--- a/drivers/staging/media/hantro/hantro_g2_regs.h
+++ b/drivers/media/platform/verisilicon/hantro_g2_regs.h
diff --git a/drivers/staging/media/hantro/hantro_g2_vp9_dec.c b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
index 6fc4b555517f..6fc4b555517f 100644
--- a/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
+++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
diff --git a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c b/drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c
index 12d69503d6ba..12d69503d6ba 100644
--- a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
+++ b/drivers/media/platform/verisilicon/hantro_h1_jpeg_enc.c
diff --git a/drivers/staging/media/hantro/hantro_h1_regs.h b/drivers/media/platform/verisilicon/hantro_h1_regs.h
index 30e7e7b920b5..30e7e7b920b5 100644
--- a/drivers/staging/media/hantro/hantro_h1_regs.h
+++ b/drivers/media/platform/verisilicon/hantro_h1_regs.h
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/media/platform/verisilicon/hantro_h264.c
index 4e9a0ecf5c13..4e9a0ecf5c13 100644
--- a/drivers/staging/media/hantro/hantro_h264.c
+++ b/drivers/media/platform/verisilicon/hantro_h264.c
diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/media/platform/verisilicon/hantro_hevc.c
index b990bc98164c..b990bc98164c 100644
--- a/drivers/staging/media/hantro/hantro_hevc.c
+++ b/drivers/media/platform/verisilicon/hantro_hevc.c
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h
index e83f0c523a30..e83f0c523a30 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/media/platform/verisilicon/hantro_hw.h
diff --git a/drivers/staging/media/hantro/hantro_jpeg.c b/drivers/media/platform/verisilicon/hantro_jpeg.c
index d07b1b449b61..d07b1b449b61 100644
--- a/drivers/staging/media/hantro/hantro_jpeg.c
+++ b/drivers/media/platform/verisilicon/hantro_jpeg.c
diff --git a/drivers/staging/media/hantro/hantro_jpeg.h b/drivers/media/platform/verisilicon/hantro_jpeg.h
index 0b49d0b82caa..0b49d0b82caa 100644
--- a/drivers/staging/media/hantro/hantro_jpeg.h
+++ b/drivers/media/platform/verisilicon/hantro_jpeg.h
diff --git a/drivers/staging/media/hantro/hantro_mpeg2.c b/drivers/media/platform/verisilicon/hantro_mpeg2.c
index 04e545eb0a83..04e545eb0a83 100644
--- a/drivers/staging/media/hantro/hantro_mpeg2.c
+++ b/drivers/media/platform/verisilicon/hantro_mpeg2.c
diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c
index a0928c508434..a0928c508434 100644
--- a/drivers/staging/media/hantro/hantro_postproc.c
+++ b/drivers/media/platform/verisilicon/hantro_postproc.c
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
index 2c7a805289e7..2c7a805289e7 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.c
+++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
diff --git a/drivers/staging/media/hantro/hantro_v4l2.h b/drivers/media/platform/verisilicon/hantro_v4l2.h
index 64f6f57e9d7a..64f6f57e9d7a 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.h
+++ b/drivers/media/platform/verisilicon/hantro_v4l2.h
diff --git a/drivers/staging/media/hantro/hantro_vp8.c b/drivers/media/platform/verisilicon/hantro_vp8.c
index 381bc1d3bfda..381bc1d3bfda 100644
--- a/drivers/staging/media/hantro/hantro_vp8.c
+++ b/drivers/media/platform/verisilicon/hantro_vp8.c
diff --git a/drivers/staging/media/hantro/hantro_vp9.c b/drivers/media/platform/verisilicon/hantro_vp9.c
index 566cd376c097..566cd376c097 100644
--- a/drivers/staging/media/hantro/hantro_vp9.c
+++ b/drivers/media/platform/verisilicon/hantro_vp9.c
diff --git a/drivers/staging/media/hantro/hantro_vp9.h b/drivers/media/platform/verisilicon/hantro_vp9.h
index 26b69275f098..26b69275f098 100644
--- a/drivers/staging/media/hantro/hantro_vp9.h
+++ b/drivers/media/platform/verisilicon/hantro_vp9.h
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
index 77f574fdfa77..77f574fdfa77 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_h264_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c
index 46c1a83bcc4e..46c1a83bcc4e 100644
--- a/drivers/staging/media/hantro/rockchip_vpu2_hw_h264_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_h264_dec.c
diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c
index 8395c4d48dd0..8395c4d48dd0 100644
--- a/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_jpeg_enc.c
diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_mpeg2_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c
index b66737fab46b..b66737fab46b 100644
--- a/drivers/staging/media/hantro/rockchip_vpu2_hw_mpeg2_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_mpeg2_dec.c
diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_vp8_dec.c
index d079075448c9..d079075448c9 100644
--- a/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu2_hw_vp8_dec.c
diff --git a/drivers/staging/media/hantro/rockchip_vpu2_regs.h b/drivers/media/platform/verisilicon/rockchip_vpu2_regs.h
index 49e40889545b..49e40889545b 100644
--- a/drivers/staging/media/hantro/rockchip_vpu2_regs.h
+++ b/drivers/media/platform/verisilicon/rockchip_vpu2_regs.h
diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c
index 8de6fd2e8eef..8de6fd2e8eef 100644
--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c
diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/media/platform/verisilicon/sama5d4_vdec_hw.c
index b205e2db5b04..b205e2db5b04 100644
--- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+++ b/drivers/media/platform/verisilicon/sama5d4_vdec_hw.c
diff --git a/drivers/staging/media/hantro/sunxi_vpu_hw.c b/drivers/media/platform/verisilicon/sunxi_vpu_hw.c
index 02ce8b064a8f..02ce8b064a8f 100644
--- a/drivers/staging/media/hantro/sunxi_vpu_hw.c
+++ b/drivers/media/platform/verisilicon/sunxi_vpu_hw.c
diff --git a/drivers/media/platform/xilinx/xilinx-csi2rxss.c b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
index cf8e892c47f0..29b53febc2e7 100644
--- a/drivers/media/platform/xilinx/xilinx-csi2rxss.c
+++ b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
@@ -188,6 +188,7 @@ static const u32 xcsi2dt_mbus_lut[][2] = {
{ MIPI_CSI2_DT_RAW12, MEDIA_BUS_FMT_SBGGR12_1X12 },
{ MIPI_CSI2_DT_RAW12, MEDIA_BUS_FMT_SGBRG12_1X12 },
{ MIPI_CSI2_DT_RAW12, MEDIA_BUS_FMT_SGRBG12_1X12 },
+ { MIPI_CSI2_DT_RAW12, MEDIA_BUS_FMT_Y12_1X12 },
{ MIPI_CSI2_DT_RAW16, MEDIA_BUS_FMT_SRGGB16_1X16 },
{ MIPI_CSI2_DT_RAW16, MEDIA_BUS_FMT_SBGGR16_1X16 },
{ MIPI_CSI2_DT_RAW16, MEDIA_BUS_FMT_SGBRG16_1X16 },
diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c
index a0073122798f..5b214bf7f93a 100644
--- a/drivers/media/platform/xilinx/xilinx-vip.c
+++ b/drivers/media/platform/xilinx/xilinx-vip.c
@@ -40,6 +40,8 @@ static const struct xvip_video_format xvip_video_formats[] = {
1, V4L2_PIX_FMT_SGBRG8 },
{ XVIP_VF_MONO_SENSOR, 8, "bggr", MEDIA_BUS_FMT_SBGGR8_1X8,
1, V4L2_PIX_FMT_SBGGR8 },
+ { XVIP_VF_MONO_SENSOR, 12, "mono", MEDIA_BUS_FMT_Y12_1X12,
+ 2, V4L2_PIX_FMT_Y12 },
};
/**
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index f34f8b077e03..0a16c218a50a 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -471,7 +471,7 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
{
struct device_node *ports;
struct device_node *port;
- int ret;
+ int ret = 0;
ports = of_get_child_by_name(xdev->dev->of_node, "ports");
if (ports == NULL) {
@@ -481,13 +481,14 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
for_each_child_of_node(ports, port) {
ret = xvip_graph_dma_init_one(xdev, port);
- if (ret < 0) {
+ if (ret) {
of_node_put(port);
- return ret;
+ break;
}
}
- return 0;
+ of_node_put(ports);
+ return ret;
}
static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
diff --git a/drivers/media/test-drivers/vim2m.c b/drivers/media/test-drivers/vim2m.c
index 47575490e74a..7964426bf2f7 100644
--- a/drivers/media/test-drivers/vim2m.c
+++ b/drivers/media/test-drivers/vim2m.c
@@ -2,7 +2,7 @@
/*
* A virtual v4l2-mem2mem example device.
*
- * This is a virtual device driver for testing mem-to-mem videobuf framework.
+ * This is a virtual device driver for testing mem-to-mem vb2 framework.
* It simulates a device that uses memory buffers for both source and
* destination, processes the data and issues an "irq" (simulated by a delayed
* workqueue).
diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h
index 176b72cb143b..bfcfb3515901 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.h
+++ b/drivers/media/test-drivers/vivid/vivid-core.h
@@ -35,7 +35,9 @@
#define MAX_HEIGHT 2160
/* The minimum image width/height */
#define MIN_WIDTH 16
-#define MIN_HEIGHT 16
+#define MIN_HEIGHT MIN_WIDTH
+/* Pixel Array control divider */
+#define PIXEL_ARRAY_DIV MIN_WIDTH
/* The data_offset of plane 0 for the multiplanar formats */
#define PLANE0_DATA_OFFSET 128
@@ -227,6 +229,7 @@ struct vivid_dev {
struct v4l2_ctrl *bitmask;
struct v4l2_ctrl *int_menu;
struct v4l2_ctrl *ro_int32;
+ struct v4l2_ctrl *pixel_array;
struct v4l2_ctrl *test_pattern;
struct v4l2_ctrl *colorspace;
struct v4l2_ctrl *rgb_range_cap;
diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c b/drivers/media/test-drivers/vivid/vivid-ctrls.c
index a78d676575bc..92b1a7598470 100644
--- a/drivers/media/test-drivers/vivid/vivid-ctrls.c
+++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c
@@ -35,6 +35,7 @@
#define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11)
#define VIVID_CID_RO_INTEGER (VIVID_CID_CUSTOM_BASE + 12)
#define VIVID_CID_U32_DYN_ARRAY (VIVID_CID_CUSTOM_BASE + 13)
+#define VIVID_CID_U8_PIXEL_ARRAY (VIVID_CID_CUSTOM_BASE + 14)
#define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
#define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
@@ -228,6 +229,18 @@ static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = {
.dims = { 2, 3, 4, 5 },
};
+static const struct v4l2_ctrl_config vivid_ctrl_u8_pixel_array = {
+ .ops = &vivid_user_gen_ctrl_ops,
+ .id = VIVID_CID_U8_PIXEL_ARRAY,
+ .name = "U8 Pixel Array",
+ .type = V4L2_CTRL_TYPE_U8,
+ .def = 0x80,
+ .min = 0x00,
+ .max = 0xff,
+ .step = 1,
+ .dims = { 640 / PIXEL_ARRAY_DIV, 360 / PIXEL_ARRAY_DIV },
+};
+
static const char * const vivid_ctrl_menu_strings[] = {
"Menu Item 0 (Skipped)",
"Menu Item 1",
@@ -1642,6 +1655,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_dyn_array, NULL);
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
+ dev->pixel_array = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_pixel_array, NULL);
if (dev->has_vid_cap) {
/* Image Processing Controls */
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index b9caa4b26209..86b158eeb2d8 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -381,6 +381,7 @@ static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev)
void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
{
struct v4l2_bt_timings *bt = &dev->dv_timings_cap[dev->input].bt;
+ u32 dims[V4L2_CTRL_MAX_DIMS] = {};
unsigned size;
u64 pixelclock;
@@ -459,6 +460,9 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
tpg_s_pixel_aspect(&dev->tpg, vivid_get_pixel_aspect(dev));
tpg_update_mv_step(&dev->tpg);
+ dims[0] = roundup(dev->src_rect.width, PIXEL_ARRAY_DIV);
+ dims[1] = roundup(dev->src_rect.height, PIXEL_ARRAY_DIV);
+ v4l2_ctrl_modify_dimensions(dev->pixel_array, dims);
}
/* Map the field to something that is valid for the current input */
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
index af88e0766388..813171d25ac5 100644
--- a/drivers/media/usb/Kconfig
+++ b/drivers/media/usb/Kconfig
@@ -13,13 +13,11 @@ if MEDIA_USB_SUPPORT
if MEDIA_CAMERA_SUPPORT
comment "Webcam devices"
-source "drivers/media/usb/cpia2/Kconfig"
source "drivers/media/usb/gspca/Kconfig"
source "drivers/media/usb/pwc/Kconfig"
source "drivers/media/usb/s2255/Kconfig"
source "drivers/media/usb/usbtv/Kconfig"
source "drivers/media/usb/uvc/Kconfig"
-source "drivers/media/usb/zr364xx/Kconfig"
endif
@@ -38,7 +36,6 @@ if (MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT)
source "drivers/media/usb/au0828/Kconfig"
source "drivers/media/usb/cx231xx/Kconfig"
-source "drivers/media/usb/tm6000/Kconfig"
endif
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 25fa2015b179..6d171beea20d 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -12,7 +12,6 @@ obj-y += s2255/
obj-y += siano/
obj-y += ttusb-budget/
obj-y += ttusb-dec/
-obj-y += zr364xx/
# Please keep it alphabetically sorted by Kconfig name
# (e. g. LC_ALL=C sort Makefile)
@@ -24,12 +23,10 @@ obj-$(CONFIG_USB_MSI2500) += msi2500/
obj-$(CONFIG_USB_PWC) += pwc/
obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
obj-$(CONFIG_VIDEO_AU0828) += au0828/
-obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
obj-$(CONFIG_VIDEO_GO7007) += go7007/
obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
obj-$(CONFIG_VIDEO_STK1160) += stk1160/
-obj-$(CONFIG_VIDEO_TM6000) += tm6000/
obj-$(CONFIG_VIDEO_USBTV) += usbtv/
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index 240a7cc56777..462eb8423506 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -294,7 +294,7 @@ static void airspy_urb_complete(struct urb *urb)
if (unlikely(fbuf == NULL)) {
s->vb_full++;
dev_notice_ratelimited(s->dev,
- "videobuf is full, %d packets dropped\n",
+ "video buffer is full, %d packets dropped\n",
s->vb_full);
goto skip;
}
@@ -1070,6 +1070,10 @@ static int airspy_probe(struct usb_interface *intf,
ret);
goto err_free_controls;
}
+
+ /* Free buf if success*/
+ kfree(buf);
+
dev_info(s->dev, "Registered as %s\n",
video_device_node_name(&s->vdev));
dev_notice(s->dev, "SDR API is still slightly experimental and functionality changes may follow\n");
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index c0f118563c7d..eb303e94cceb 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -384,7 +384,7 @@ static void au0828_copy_video(struct au0828_dev *dev,
}
/*
- * video-buf generic routine to get the next available buffer
+ * generic routine to get the next available buffer
*/
static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
struct au0828_buffer **buf)
@@ -459,7 +459,7 @@ static void au0828_copy_vbi(struct au0828_dev *dev,
/*
- * video-buf generic routine to get the next available VBI buffer
+ * generic routine to get the next available VBI buffer
*/
static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q,
struct au0828_buffer **buf)
diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c
index fdc8b7f7b0c1..33431d9f54c2 100644
--- a/drivers/media/usb/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c
@@ -558,7 +558,7 @@ u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
}
/*
- * video-buf generic routine to get the next available buffer
+ * generic routine to get the next available buffer
*/
static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q,
struct cx231xx_buffer **buf)
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 425e470b0fd3..e23b8ccd79d4 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -220,7 +220,7 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status)
}
/*
- * video-buf generic routine to get the next available buffer
+ * generic routine to get the next available buffer
*/
static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
struct cx231xx_buffer **buf)
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index 9c77911fcad4..df90c6c5f3b9 100644
--- a/drivers/media/usb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -786,7 +786,7 @@ static void technisat_usb2_disconnect(struct usb_interface *intf)
{
struct dvb_usb_device *dev = usb_get_intfdata(intf);
- /* work and stuff was only created when the device is is hot-state */
+ /* work and stuff was only created when the device is hot-state */
if (dev != NULL) {
struct technisat_usb2_state *state = dev->priv;
if (state != NULL)
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 8181c0e6a25b..25e0620deff1 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -440,7 +440,7 @@ static inline void finish_buffer(struct em28xx *dev,
}
/*
- * Copy picture data from USB buffer to videobuf buffer
+ * Copy picture data from USB buffer to video buffer
*/
static void em28xx_copy_video(struct em28xx *dev,
struct em28xx_buffer *buf,
@@ -521,7 +521,7 @@ static void em28xx_copy_video(struct em28xx *dev,
}
/*
- * Copy VBI data from USB buffer to videobuf buffer
+ * Copy VBI data from USB buffer to video buffer
*/
static void em28xx_copy_vbi(struct em28xx *dev,
struct em28xx_buffer *buf,
diff --git a/drivers/media/usb/gspca/finepix.c b/drivers/media/usb/gspca/finepix.c
index 66c8e5122a0a..bc6133b525e3 100644
--- a/drivers/media/usb/gspca/finepix.c
+++ b/drivers/media/usb/gspca/finepix.c
@@ -129,7 +129,7 @@ again:
* for, then it's the end of the
* frame. Sometimes the jpeg is not complete,
* but there's nothing we can do. We also end
- * here if the the jpeg ends right at the end
+ * here if the jpeg ends right at the end
* of the frame. */
gspca_frame_add(gspca_dev, LAST_PACKET,
data, len);
diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c
index 71de6b4c4e4c..5a1f2698efb7 100644
--- a/drivers/media/usb/msi2500/msi2500.c
+++ b/drivers/media/usb/msi2500/msi2500.c
@@ -411,7 +411,7 @@ static void msi2500_isoc_handler(struct urb *urb)
if (unlikely(fbuf == NULL)) {
dev->vb_full++;
dev_dbg_ratelimited(dev->dev,
- "videobuf is full, %d packets dropped\n",
+ "video buffer is full, %d packets dropped\n",
dev->vb_full);
continue;
}
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 6954584526a3..26811efe0fb5 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -80,7 +80,7 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
static int pvr2_dvb_feed_thread(void *data)
{
int stat = pvr2_dvb_feed_func(data);
- /* from videobuf-dvb.c: */
+
while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 8c208db9600b..97f312020516 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
return value;
}
-static int __uvc_ctrl_get(struct uvc_video_chain *chain,
- struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
- s32 *value)
+static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl)
{
+ u8 *data;
int ret;
- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
- return -EACCES;
+ if (ctrl->loaded)
+ return 0;
- if (!ctrl->loaded) {
- if (ctrl->entity->get_cur) {
- ret = ctrl->entity->get_cur(chain->dev,
- ctrl->entity,
- ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- } else {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
- ctrl->entity->id,
- chain->dev->intfnum,
- ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- }
- if (ret < 0)
- return ret;
+ data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
+ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
+ memset(data, 0, ctrl->info.size);
ctrl->loaded = 1;
+
+ return 0;
}
+ if (ctrl->entity->get_cur)
+ ret = ctrl->entity->get_cur(chain->dev, ctrl->entity,
+ ctrl->info.selector, data,
+ ctrl->info.size);
+ else
+ ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+ ctrl->entity->id, chain->dev->intfnum,
+ ctrl->info.selector, data,
+ ctrl->info.size);
+
+ if (ret < 0)
+ return ret;
+
+ ctrl->loaded = 1;
+
+ return ret;
+}
+
+static int __uvc_ctrl_get(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ s32 *value)
+{
+ int ret;
+
+ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
+ return -EACCES;
+
+ ret = __uvc_ctrl_load_cur(chain, ctrl);
+ if (ret < 0)
+ return ret;
+
*value = __uvc_ctrl_get_value(mapping,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
@@ -1810,21 +1830,10 @@ int uvc_ctrl_set(struct uvc_fh *handle,
* needs to be loaded from the device to perform the read-modify-write
* operation.
*/
- if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
- memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- 0, ctrl->info.size);
- } else {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
- ctrl->entity->id, chain->dev->intfnum,
- ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- if (ret < 0)
- return ret;
- }
-
- ctrl->loaded = 1;
+ if ((ctrl->info.size * 8) != mapping->size) {
+ ret = __uvc_ctrl_load_cur(chain, ctrl);
+ if (ret < 0)
+ return ret;
}
/* Backup the current value in case we need to rollback later. */
@@ -2411,10 +2420,9 @@ static void uvc_ctrl_prune_entity(struct uvc_device *dev,
static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
struct uvc_control *ctrl)
{
- const struct uvc_control_info *info = uvc_ctrls;
- const struct uvc_control_info *iend = info + ARRAY_SIZE(uvc_ctrls);
- const struct uvc_control_mapping *mapping;
- const struct uvc_control_mapping *mend;
+ const struct uvc_control_mapping *mappings;
+ unsigned int num_mappings;
+ unsigned int i;
/*
* XU controls initialization requires querying the device for control
@@ -2425,7 +2433,9 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
if (UVC_ENTITY_TYPE(ctrl->entity) == UVC_VC_EXTENSION_UNIT)
return;
- for (; info < iend; ++info) {
+ for (i = 0; i < ARRAY_SIZE(uvc_ctrls); ++i) {
+ const struct uvc_control_info *info = &uvc_ctrls[i];
+
if (uvc_entity_match_guid(ctrl->entity, info->entity) &&
ctrl->index == info->index) {
uvc_ctrl_add_info(chain->dev, ctrl, info);
@@ -2452,9 +2462,11 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
*/
if (chain->dev->info->mappings) {
bool custom = false;
- unsigned int i;
- for (i = 0; (mapping = chain->dev->info->mappings[i]); ++i) {
+ for (i = 0; chain->dev->info->mappings[i]; ++i) {
+ const struct uvc_control_mapping *mapping =
+ chain->dev->info->mappings[i];
+
if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
ctrl->info.selector == mapping->selector) {
__uvc_ctrl_add_mapping(chain, ctrl, mapping);
@@ -2467,10 +2479,9 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
}
/* Process common mappings next. */
- mapping = uvc_ctrl_mappings;
- mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings);
+ for (i = 0; i < ARRAY_SIZE(uvc_ctrl_mappings); ++i) {
+ const struct uvc_control_mapping *mapping = &uvc_ctrl_mappings[i];
- for (; mapping < mend; ++mapping) {
if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
ctrl->info.selector == mapping->selector)
__uvc_ctrl_add_mapping(chain, ctrl, mapping);
@@ -2478,14 +2489,16 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
/* Finally process version-specific mappings. */
if (chain->dev->uvc_version < 0x0150) {
- mapping = uvc_ctrl_mappings_uvc11;
- mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings_uvc11);
+ mappings = uvc_ctrl_mappings_uvc11;
+ num_mappings = ARRAY_SIZE(uvc_ctrl_mappings_uvc11);
} else {
- mapping = uvc_ctrl_mappings_uvc15;
- mend = mapping + ARRAY_SIZE(uvc_ctrl_mappings_uvc15);
+ mappings = uvc_ctrl_mappings_uvc15;
+ num_mappings = ARRAY_SIZE(uvc_ctrl_mappings_uvc15);
}
- for (; mapping < mend; ++mapping) {
+ for (i = 0; i < num_mappings; ++i) {
+ const struct uvc_control_mapping *mapping = &mappings[i];
+
if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
ctrl->info.selector == mapping->selector)
__uvc_ctrl_add_mapping(chain, ctrl, mapping);
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index d509a4a2f08e..744051b52e12 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1553,10 +1553,6 @@ static int uvc_gpio_parse(struct uvc_device *dev)
if (IS_ERR_OR_NULL(gpio_privacy))
return PTR_ERR_OR_ZERO(gpio_privacy);
- unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
- if (!unit)
- return -ENOMEM;
-
irq = gpiod_to_irq(gpio_privacy);
if (irq < 0) {
if (irq != EPROBE_DEFER)
@@ -1565,6 +1561,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)
return irq;
}
+ unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
+ if (!unit)
+ return -ENOMEM;
+
unit->gpio.gpio_privacy = gpio_privacy;
unit->gpio.irq = irq;
unit->gpio.bControlSize = 1;
@@ -3264,6 +3264,15 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) },
+ /* Sonix Technology USB 2.0 Camera */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x3277,
+ .idProduct = 0x0072,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
/* Acer EasyCamera */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 170a008f4006..d2eb9066e4dc 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1095,7 +1095,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
/*
* Synchronize to the input stream by waiting for the FID bit to be
- * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
+ * toggled when the buffer state is not UVC_BUF_STATE_ACTIVE.
* stream->last_fid is initialized to -1, so the first isochronous
* frame will always be in sync.
*
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c
index 50d012ba3c02..a8c354ad3d23 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -89,10 +89,7 @@ static int req_to_user(struct v4l2_ext_control *c,
/* Helper function: copy the initial control value back to the caller */
static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
{
- int idx;
-
- for (idx = 0; idx < ctrl->elems; idx++)
- ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
+ ctrl->type_ops->init(ctrl, 0, ctrl->elems, ctrl->p_new);
return ptr_to_user(c, ctrl, ctrl->p_new);
}
@@ -105,8 +102,8 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
ctrl->is_new = 0;
if (ctrl->is_dyn_array &&
- c->size > ctrl->p_dyn_alloc_elems * ctrl->elem_size) {
- void *old = ctrl->p_dyn;
+ c->size > ctrl->p_array_alloc_elems * ctrl->elem_size) {
+ void *old = ctrl->p_array;
void *tmp = kvzalloc(2 * c->size, GFP_KERNEL);
if (!tmp)
@@ -115,14 +112,13 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
memcpy(tmp + c->size, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size);
ctrl->p_new.p = tmp;
ctrl->p_cur.p = tmp + c->size;
- ctrl->p_dyn = tmp;
- ctrl->p_dyn_alloc_elems = c->size / ctrl->elem_size;
+ ctrl->p_array = tmp;
+ ctrl->p_array_alloc_elems = c->size / ctrl->elem_size;
kvfree(old);
}
if (ctrl->is_ptr && !ctrl->is_string) {
unsigned int elems = c->size / ctrl->elem_size;
- unsigned int idx;
if (copy_from_user(ctrl->p_new.p, c->ptr, c->size))
return -EFAULT;
@@ -130,8 +126,7 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
if (ctrl->is_dyn_array)
ctrl->new_elems = elems;
else if (ctrl->is_array)
- for (idx = elems; idx < ctrl->elems; idx++)
- ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
+ ctrl->type_ops->init(ctrl, elems, ctrl->elems, ctrl->p_new);
return 0;
}
@@ -467,7 +462,7 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
if (is_default)
ret = def_to_user(cs->controls + idx, ref->ctrl);
- else if (is_request && ref->p_req_dyn_enomem)
+ else if (is_request && ref->p_req_array_enomem)
ret = -ENOMEM;
else if (is_request && ref->p_req_valid)
ret = req_to_user(cs->controls + idx, ref);
@@ -499,12 +494,7 @@ EXPORT_SYMBOL(v4l2_g_ext_ctrls);
/* Validate a new control */
static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new)
{
- unsigned int idx;
- int err = 0;
-
- for (idx = 0; !err && idx < ctrl->new_elems; idx++)
- err = ctrl->type_ops->validate(ctrl, idx, p_new);
- return err;
+ return ctrl->type_ops->validate(ctrl, ctrl->new_elems, p_new);
}
/* Validate controls. */
@@ -989,6 +979,42 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
}
EXPORT_SYMBOL(__v4l2_ctrl_modify_range);
+int __v4l2_ctrl_modify_dimensions(struct v4l2_ctrl *ctrl,
+ u32 dims[V4L2_CTRL_MAX_DIMS])
+{
+ unsigned int elems = 1;
+ unsigned int i;
+ void *p_array;
+
+ lockdep_assert_held(ctrl->handler->lock);
+
+ if (!ctrl->is_array || ctrl->is_dyn_array)
+ return -EINVAL;
+
+ for (i = 0; i < ctrl->nr_of_dims; i++)
+ elems *= dims[i];
+ if (elems == 0)
+ return -EINVAL;
+ p_array = kvzalloc(2 * elems * ctrl->elem_size, GFP_KERNEL);
+ if (!p_array)
+ return -ENOMEM;
+ kvfree(ctrl->p_array);
+ ctrl->p_array_alloc_elems = elems;
+ ctrl->elems = elems;
+ ctrl->new_elems = elems;
+ ctrl->p_array = p_array;
+ ctrl->p_new.p = p_array;
+ ctrl->p_cur.p = p_array + elems * ctrl->elem_size;
+ for (i = 0; i < ctrl->nr_of_dims; i++)
+ ctrl->dims[i] = dims[i];
+ ctrl->type_ops->init(ctrl, 0, elems, ctrl->p_cur);
+ cur_to_new(ctrl);
+ send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_VALUE |
+ V4L2_EVENT_CTRL_CH_DIMENSIONS);
+ return 0;
+}
+EXPORT_SYMBOL(__v4l2_ctrl_modify_dimensions);
+
/* Implement VIDIOC_QUERY_EXT_CTRL */
int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)
{
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 1f85828d6694..01f00093f259 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -65,33 +65,29 @@ void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
v4l2_event_queue_fh(sev->fh, &ev);
}
-static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
- union v4l2_ctrl_ptr ptr1,
- union v4l2_ctrl_ptr ptr2)
+bool v4l2_ctrl_type_op_equal(const struct v4l2_ctrl *ctrl, u32 elems,
+ union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2)
{
+ unsigned int i;
+
switch (ctrl->type) {
case V4L2_CTRL_TYPE_BUTTON:
return false;
case V4L2_CTRL_TYPE_STRING:
- idx *= ctrl->elem_size;
- /* strings are always 0-terminated */
- return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx);
- case V4L2_CTRL_TYPE_INTEGER64:
- return ptr1.p_s64[idx] == ptr2.p_s64[idx];
- case V4L2_CTRL_TYPE_U8:
- return ptr1.p_u8[idx] == ptr2.p_u8[idx];
- case V4L2_CTRL_TYPE_U16:
- return ptr1.p_u16[idx] == ptr2.p_u16[idx];
- case V4L2_CTRL_TYPE_U32:
- return ptr1.p_u32[idx] == ptr2.p_u32[idx];
+ for (i = 0; i < elems; i++) {
+ unsigned int idx = i * ctrl->elem_size;
+
+ /* strings are always 0-terminated */
+ if (strcmp(ptr1.p_char + idx, ptr2.p_char + idx))
+ return false;
+ }
+ return true;
default:
- if (ctrl->is_int)
- return ptr1.p_s32[idx] == ptr2.p_s32[idx];
- idx *= ctrl->elem_size;
- return !memcmp(ptr1.p_const + idx, ptr2.p_const + idx,
- ctrl->elem_size);
+ return !memcmp(ptr1.p_const, ptr2.p_const,
+ elems * ctrl->elem_size);
}
}
+EXPORT_SYMBOL(v4l2_ctrl_type_op_equal);
/* Default intra MPEG-2 quantisation coefficients, from the specification. */
static const u8 mpeg2_intra_quant_matrix[64] = {
@@ -181,45 +177,76 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
}
}
-static void std_init(const struct v4l2_ctrl *ctrl, u32 idx,
- union v4l2_ctrl_ptr ptr)
+void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx,
+ u32 tot_elems, union v4l2_ctrl_ptr ptr)
{
+ unsigned int i;
+ u32 elems = tot_elems - from_idx;
+
+ if (from_idx >= tot_elems)
+ return;
+
switch (ctrl->type) {
case V4L2_CTRL_TYPE_STRING:
- idx *= ctrl->elem_size;
- memset(ptr.p_char + idx, ' ', ctrl->minimum);
- ptr.p_char[idx + ctrl->minimum] = '\0';
+ for (i = from_idx; i < tot_elems; i++) {
+ unsigned int offset = i * ctrl->elem_size;
+
+ memset(ptr.p_char + offset, ' ', ctrl->minimum);
+ ptr.p_char[offset + ctrl->minimum] = '\0';
+ }
break;
case V4L2_CTRL_TYPE_INTEGER64:
- ptr.p_s64[idx] = ctrl->default_value;
+ if (ctrl->default_value) {
+ for (i = from_idx; i < tot_elems; i++)
+ ptr.p_s64[i] = ctrl->default_value;
+ } else {
+ memset(ptr.p_s64 + from_idx, 0, elems * sizeof(s64));
+ }
break;
case V4L2_CTRL_TYPE_INTEGER:
case V4L2_CTRL_TYPE_INTEGER_MENU:
case V4L2_CTRL_TYPE_MENU:
case V4L2_CTRL_TYPE_BITMASK:
case V4L2_CTRL_TYPE_BOOLEAN:
- ptr.p_s32[idx] = ctrl->default_value;
+ if (ctrl->default_value) {
+ for (i = from_idx; i < tot_elems; i++)
+ ptr.p_s32[i] = ctrl->default_value;
+ } else {
+ memset(ptr.p_s32 + from_idx, 0, elems * sizeof(s32));
+ }
break;
case V4L2_CTRL_TYPE_BUTTON:
case V4L2_CTRL_TYPE_CTRL_CLASS:
- ptr.p_s32[idx] = 0;
+ memset(ptr.p_s32 + from_idx, 0, elems * sizeof(s32));
break;
case V4L2_CTRL_TYPE_U8:
- ptr.p_u8[idx] = ctrl->default_value;
+ memset(ptr.p_u8 + from_idx, ctrl->default_value, elems);
break;
case V4L2_CTRL_TYPE_U16:
- ptr.p_u16[idx] = ctrl->default_value;
+ if (ctrl->default_value) {
+ for (i = from_idx; i < tot_elems; i++)
+ ptr.p_u16[i] = ctrl->default_value;
+ } else {
+ memset(ptr.p_u16 + from_idx, 0, elems * sizeof(u16));
+ }
break;
case V4L2_CTRL_TYPE_U32:
- ptr.p_u32[idx] = ctrl->default_value;
+ if (ctrl->default_value) {
+ for (i = from_idx; i < tot_elems; i++)
+ ptr.p_u32[i] = ctrl->default_value;
+ } else {
+ memset(ptr.p_u32 + from_idx, 0, elems * sizeof(u32));
+ }
break;
default:
- std_init_compound(ctrl, idx, ptr);
+ for (i = from_idx; i < tot_elems; i++)
+ std_init_compound(ctrl, i, ptr);
break;
}
}
+EXPORT_SYMBOL(v4l2_ctrl_type_op_init);
-static void std_log(const struct v4l2_ctrl *ctrl)
+void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl)
{
union v4l2_ctrl_ptr ptr = ctrl->p_cur;
@@ -327,6 +354,7 @@ static void std_log(const struct v4l2_ctrl *ctrl)
break;
}
}
+EXPORT_SYMBOL(v4l2_ctrl_type_op_log);
/*
* Round towards the closest legal value. Be careful when we are
@@ -520,7 +548,8 @@ validate_vp9_frame(struct v4l2_ctrl_vp9_frame *frame)
/*
* Compound controls validation requires setting unused fields/flags to zero
- * in order to properly detect unchanged controls with std_equal's memcmp.
+ * in order to properly detect unchanged controls with v4l2_ctrl_type_op_equal's
+ * memcmp.
*/
static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
union v4l2_ctrl_ptr ptr)
@@ -895,8 +924,8 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
return 0;
}
-static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
- union v4l2_ctrl_ptr ptr)
+static int std_validate_elem(const struct v4l2_ctrl *ctrl, u32 idx,
+ union v4l2_ctrl_ptr ptr)
{
size_t len;
u64 offset;
@@ -966,11 +995,43 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
}
}
+int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, u32 elems,
+ union v4l2_ctrl_ptr ptr)
+{
+ unsigned int i;
+ int ret = 0;
+
+ switch ((u32)ctrl->type) {
+ case V4L2_CTRL_TYPE_U8:
+ if (ctrl->maximum == 0xff && ctrl->minimum == 0 && ctrl->step == 1)
+ return 0;
+ break;
+ case V4L2_CTRL_TYPE_U16:
+ if (ctrl->maximum == 0xffff && ctrl->minimum == 0 && ctrl->step == 1)
+ return 0;
+ break;
+ case V4L2_CTRL_TYPE_U32:
+ if (ctrl->maximum == 0xffffffff && ctrl->minimum == 0 && ctrl->step == 1)
+ return 0;
+ break;
+
+ case V4L2_CTRL_TYPE_BUTTON:
+ case V4L2_CTRL_TYPE_CTRL_CLASS:
+ memset(ptr.p_s32, 0, elems * sizeof(s32));
+ return 0;
+ }
+
+ for (i = 0; !ret && i < elems; i++)
+ ret = std_validate_elem(ctrl, i, ptr);
+ return ret;
+}
+EXPORT_SYMBOL(v4l2_ctrl_type_op_validate);
+
static const struct v4l2_ctrl_type_ops std_type_ops = {
- .equal = std_equal,
- .init = std_init,
- .log = std_log,
- .validate = std_validate,
+ .equal = v4l2_ctrl_type_op_equal,
+ .init = v4l2_ctrl_type_op_init,
+ .log = v4l2_ctrl_type_op_log,
+ .validate = v4l2_ctrl_type_op_validate,
};
void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
@@ -1048,23 +1109,26 @@ void cur_to_new(struct v4l2_ctrl *ctrl)
ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new, ctrl->new_elems);
}
-static bool req_alloc_dyn_array(struct v4l2_ctrl_ref *ref, u32 elems)
+static bool req_alloc_array(struct v4l2_ctrl_ref *ref, u32 elems)
{
void *tmp;
- if (elems < ref->p_req_dyn_alloc_elems)
+ if (elems == ref->p_req_array_alloc_elems)
+ return true;
+ if (ref->ctrl->is_dyn_array &&
+ elems < ref->p_req_array_alloc_elems)
return true;
tmp = kvmalloc(elems * ref->ctrl->elem_size, GFP_KERNEL);
if (!tmp) {
- ref->p_req_dyn_enomem = true;
+ ref->p_req_array_enomem = true;
return false;
}
- ref->p_req_dyn_enomem = false;
+ ref->p_req_array_enomem = false;
kvfree(ref->p_req.p);
ref->p_req.p = tmp;
- ref->p_req_dyn_alloc_elems = elems;
+ ref->p_req_array_alloc_elems = elems;
return true;
}
@@ -1077,7 +1141,7 @@ void new_to_req(struct v4l2_ctrl_ref *ref)
return;
ctrl = ref->ctrl;
- if (ctrl->is_dyn_array && !req_alloc_dyn_array(ref, ctrl->new_elems))
+ if (ctrl->is_array && !req_alloc_array(ref, ctrl->new_elems))
return;
ref->p_req_elems = ctrl->new_elems;
@@ -1094,7 +1158,7 @@ void cur_to_req(struct v4l2_ctrl_ref *ref)
return;
ctrl = ref->ctrl;
- if (ctrl->is_dyn_array && !req_alloc_dyn_array(ref, ctrl->elems))
+ if (ctrl->is_array && !req_alloc_array(ref, ctrl->elems))
return;
ref->p_req_elems = ctrl->elems;
@@ -1123,26 +1187,30 @@ int req_to_new(struct v4l2_ctrl_ref *ref)
return 0;
}
- /* Not a dynamic array, so just copy the request value */
- if (!ctrl->is_dyn_array) {
+ /* Not an array, so just copy the request value */
+ if (!ctrl->is_array) {
ptr_to_ptr(ctrl, ref->p_req, ctrl->p_new, ctrl->new_elems);
return 0;
}
/* Sanity check, should never happen */
- if (WARN_ON(!ref->p_req_dyn_alloc_elems))
+ if (WARN_ON(!ref->p_req_array_alloc_elems))
+ return -ENOMEM;
+
+ if (!ctrl->is_dyn_array &&
+ ref->p_req_elems != ctrl->p_array_alloc_elems)
return -ENOMEM;
/*
* Check if the number of elements in the request is more than the
- * elements in ctrl->p_dyn. If so, attempt to realloc ctrl->p_dyn.
- * Note that p_dyn is allocated with twice the number of elements
+ * elements in ctrl->p_array. If so, attempt to realloc ctrl->p_array.
+ * Note that p_array is allocated with twice the number of elements
* in the dynamic array since it has to store both the current and
* new value of such a control.
*/
- if (ref->p_req_elems > ctrl->p_dyn_alloc_elems) {
+ if (ref->p_req_elems > ctrl->p_array_alloc_elems) {
unsigned int sz = ref->p_req_elems * ctrl->elem_size;
- void *old = ctrl->p_dyn;
+ void *old = ctrl->p_array;
void *tmp = kvzalloc(2 * sz, GFP_KERNEL);
if (!tmp)
@@ -1151,8 +1219,8 @@ int req_to_new(struct v4l2_ctrl_ref *ref)
memcpy(tmp + sz, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size);
ctrl->p_new.p = tmp;
ctrl->p_cur.p = tmp + sz;
- ctrl->p_dyn = tmp;
- ctrl->p_dyn_alloc_elems = ref->p_req_elems;
+ ctrl->p_array = tmp;
+ ctrl->p_array_alloc_elems = ref->p_req_elems;
kvfree(old);
}
@@ -1243,7 +1311,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
/* Free all nodes */
list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
list_del(&ref->node);
- if (ref->p_req_dyn_alloc_elems)
+ if (ref->p_req_array_alloc_elems)
kvfree(ref->p_req.p);
kfree(ref);
}
@@ -1252,7 +1320,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
list_del(&ctrl->node);
list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node)
list_del(&sev->node);
- kvfree(ctrl->p_dyn);
+ kvfree(ctrl->p_array);
kvfree(ctrl);
}
kvfree(hdl->buckets);
@@ -1368,7 +1436,7 @@ int handler_new_ref(struct v4l2_ctrl_handler *hdl,
if (hdl->error)
return hdl->error;
- if (allocate_req && !ctrl->is_dyn_array)
+ if (allocate_req && !ctrl->is_array)
size_extra_req = ctrl->elems * ctrl->elem_size;
new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL);
if (!new_ref)
@@ -1442,7 +1510,6 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
unsigned elems = 1;
bool is_array;
unsigned tot_ctrl_size;
- unsigned idx;
void *data;
int err;
@@ -1584,11 +1651,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
else if (type == V4L2_CTRL_TYPE_CTRL_CLASS)
flags |= V4L2_CTRL_FLAG_READ_ONLY;
- else if (!(flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) &&
+ else if (!is_array &&
(type == V4L2_CTRL_TYPE_INTEGER64 ||
type == V4L2_CTRL_TYPE_STRING ||
- type >= V4L2_CTRL_COMPOUND_TYPES ||
- is_array))
+ type >= V4L2_CTRL_COMPOUND_TYPES))
sz_extra += 2 * tot_ctrl_size;
if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const)
@@ -1632,14 +1698,14 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
ctrl->cur.val = ctrl->val = def;
data = &ctrl[1];
- if (ctrl->is_dyn_array) {
- ctrl->p_dyn_alloc_elems = elems;
- ctrl->p_dyn = kvzalloc(2 * elems * elem_size, GFP_KERNEL);
- if (!ctrl->p_dyn) {
+ if (ctrl->is_array) {
+ ctrl->p_array_alloc_elems = elems;
+ ctrl->p_array = kvzalloc(2 * elems * elem_size, GFP_KERNEL);
+ if (!ctrl->p_array) {
kvfree(ctrl);
return NULL;
}
- data = ctrl->p_dyn;
+ data = ctrl->p_array;
}
if (!ctrl->is_int) {
@@ -1651,20 +1717,18 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
}
if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) {
- if (ctrl->is_dyn_array)
+ if (ctrl->is_array)
ctrl->p_def.p = &ctrl[1];
else
ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size;
memcpy(ctrl->p_def.p, p_def.p_const, elem_size);
}
- for (idx = 0; idx < elems; idx++) {
- ctrl->type_ops->init(ctrl, idx, ctrl->p_cur);
- ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
- }
+ ctrl->type_ops->init(ctrl, 0, elems, ctrl->p_cur);
+ cur_to_new(ctrl);
if (handler_new_ref(hdl, ctrl, NULL, false, false)) {
- kvfree(ctrl->p_dyn);
+ kvfree(ctrl->p_array);
kvfree(ctrl);
return NULL;
}
@@ -1978,7 +2042,6 @@ void update_from_auto_cluster(struct v4l2_ctrl *master)
static int cluster_changed(struct v4l2_ctrl *master)
{
bool changed = false;
- unsigned int idx;
int i;
for (i = 0; i < master->ncontrols; i++) {
@@ -2004,10 +2067,9 @@ static int cluster_changed(struct v4l2_ctrl *master)
if (ctrl->elems != ctrl->new_elems)
ctrl_changed = true;
-
- for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++)
- ctrl_changed = !ctrl->type_ops->equal(ctrl, idx,
- ctrl->p_cur, ctrl->p_new);
+ if (!ctrl_changed)
+ ctrl_changed = !ctrl->type_ops->equal(ctrl,
+ ctrl->elems, ctrl->p_cur, ctrl->p_new);
ctrl->has_changed = ctrl_changed;
changed |= ctrl->has_changed;
}
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index e70e128ccc9c..355595a0fefa 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -94,7 +94,7 @@ static int v4l2_flash_set_led_brightness(struct v4l2_flash *v4l2_flash,
* brightness <-> intensity conversion, it also must have defined
* related v4l2 control step == 1. In such a case a backward conversion
* from led brightness to v4l2 intensity is required to find out the
- * the aligned intensity value.
+ * aligned intensity value.
*/
if (has_flash_op(v4l2_flash, led_brightness_to_intensity))
ctrl->val = call_flash_op(v4l2_flash,
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index e6fd355a2e92..fddba75d9074 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1045,7 +1045,7 @@ static void v4l_sanitize_format(struct v4l2_format *fmt)
/*
* The v4l2_pix_format structure has been extended with fields that were
* not previously required to be set to zero by applications. The priv
- * field, when set to a magic value, indicates the the extended fields
+ * field, when set to a magic value, indicates that the extended fields
* are valid. Otherwise they will contain undefined values. To simplify
* the API towards drivers zero the extended fields and set the priv
* field to the magic value when the extended pixel format structure
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 837e1855f94b..be7fde1ed3ea 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Memory-to-memory device framework for Video for Linux 2 and videobuf.
+ * Memory-to-memory device framework for Video for Linux 2 and vb2.
*
- * Helper functions for devices that use videobuf buffers for both their
+ * Helper functions for devices that use vb2 buffers for both their
* source and destination.
*
* Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
@@ -21,7 +21,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
-MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
+MODULE_DESCRIPTION("Mem to mem device framework for vb2");
MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 421ce9dbf44c..d4f03b203ae5 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -22,10 +22,6 @@ if STAGING_MEDIA && MEDIA_SUPPORT
# Please keep them in alphabetic order
source "drivers/staging/media/atomisp/Kconfig"
-source "drivers/staging/media/av7110/Kconfig"
-
-source "drivers/staging/media/hantro/Kconfig"
-
source "drivers/staging/media/imx/Kconfig"
source "drivers/staging/media/ipu3/Kconfig"
@@ -38,12 +34,31 @@ source "drivers/staging/media/omap4iss/Kconfig"
source "drivers/staging/media/rkvdec/Kconfig"
-source "drivers/staging/media/stkwebcam/Kconfig"
-
source "drivers/staging/media/sunxi/Kconfig"
source "drivers/staging/media/tegra-video/Kconfig"
-source "drivers/staging/media/zoran/Kconfig"
+menuconfig STAGING_MEDIA_DEPRECATED
+ bool "Media staging drivers (DEPRECATED)"
+ default n
+ help
+ This option enables deprecated media drivers that are
+ scheduled for future removal from the kernel.
+
+ If you wish to work on these drivers to prevent their removal,
+ then contact the linux-media@vger.kernel.org mailing list.
+
+ If in doubt, say N here.
+
+if STAGING_MEDIA_DEPRECATED
+source "drivers/staging/media/deprecated/cpia2/Kconfig"
+source "drivers/staging/media/deprecated/fsl-viu/Kconfig"
+source "drivers/staging/media/deprecated/meye/Kconfig"
+source "drivers/staging/media/deprecated/saa7146/Kconfig"
+source "drivers/staging/media/deprecated/stkwebcam/Kconfig"
+source "drivers/staging/media/deprecated/tm6000/Kconfig"
+source "drivers/staging/media/deprecated/vpfe_capture/Kconfig"
+source "drivers/staging/media/deprecated/zr364xx/Kconfig"
+endif
endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 950e96f10aad..a387692b84f2 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -1,14 +1,18 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_INTEL_ATOMISP) += atomisp/
+obj-$(CONFIG_VIDEO_CPIA2) += deprecated/cpia2/
obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
obj-$(CONFIG_VIDEO_MAX96712) += max96712/
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
+obj-$(CONFIG_VIDEO_MEYE) += deprecated/meye/
obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/
-obj-$(CONFIG_VIDEO_STKWEBCAM) += stkwebcam/
+obj-$(CONFIG_VIDEO_STKWEBCAM) += deprecated/stkwebcam/
obj-$(CONFIG_VIDEO_SUNXI) += sunxi/
obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/
-obj-$(CONFIG_VIDEO_HANTRO) += hantro/
obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
-obj-$(CONFIG_VIDEO_ZORAN) += zoran/
-obj-$(CONFIG_DVB_AV7110) += av7110/
+obj-$(CONFIG_VIDEO_TM6000) += deprecated/tm6000/
+obj-$(CONFIG_VIDEO_VIU) += deprecated/fsl-viu/
+obj-$(CONFIG_USB_ZR364XX) += deprecated/zr364xx/
+obj-y += deprecated/vpfe_capture/
+obj-y += deprecated/saa7146/
diff --git a/drivers/staging/media/av7110/TODO b/drivers/staging/media/av7110/TODO
deleted file mode 100644
index 60062d8441b3..000000000000
--- a/drivers/staging/media/av7110/TODO
+++ /dev/null
@@ -1,3 +0,0 @@
-- This driver is too old and relies on a different API.
- Drop it from Kernel on a couple of versions.
-- Cleanup patches for the drivers here won't be accepted.
diff --git a/drivers/media/usb/cpia2/Kconfig b/drivers/staging/media/deprecated/cpia2/Kconfig
index da2c6862b4a2..ee3b25a759d4 100644
--- a/drivers/media/usb/cpia2/Kconfig
+++ b/drivers/staging/media/deprecated/cpia2/Kconfig
@@ -1,10 +1,13 @@
# SPDX-License-Identifier: GPL-2.0-only
config VIDEO_CPIA2
- tristate "CPiA2 Video For Linux"
+ tristate "CPiA2 Video For Linux (DEPRECATED)"
depends on USB && VIDEO_DEV
help
This is the video4linux driver for cameras based on Vision's CPiA2
(Colour Processor Interface ASIC), such as the Digital Blue QX5
Microscope. If you have one of these cameras, say Y here
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
This driver is also available as a module (cpia2).
diff --git a/drivers/media/usb/cpia2/Makefile b/drivers/staging/media/deprecated/cpia2/Makefile
index 05664141f4d7..05664141f4d7 100644
--- a/drivers/media/usb/cpia2/Makefile
+++ b/drivers/staging/media/deprecated/cpia2/Makefile
diff --git a/drivers/staging/media/deprecated/cpia2/TODO b/drivers/staging/media/deprecated/cpia2/TODO
new file mode 100644
index 000000000000..92ac8718d164
--- /dev/null
+++ b/drivers/staging/media/deprecated/cpia2/TODO
@@ -0,0 +1,6 @@
+The cpia2 driver does not use the vb2 framework for streaming
+video, instead it implements this in the driver.
+
+To prevent removal of this driver early 2023 it has to be
+converted to use vb2. Contact the linux-media@vger.kernel.org
+mailing list if you want to do this.
diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/staging/media/deprecated/cpia2/cpia2.h
index 57b7f1ea68da..57b7f1ea68da 100644
--- a/drivers/media/usb/cpia2/cpia2.h
+++ b/drivers/staging/media/deprecated/cpia2/cpia2.h
diff --git a/drivers/media/usb/cpia2/cpia2_core.c b/drivers/staging/media/deprecated/cpia2/cpia2_core.c
index b5a2d06fb356..b5a2d06fb356 100644
--- a/drivers/media/usb/cpia2/cpia2_core.c
+++ b/drivers/staging/media/deprecated/cpia2/cpia2_core.c
diff --git a/drivers/media/usb/cpia2/cpia2_registers.h b/drivers/staging/media/deprecated/cpia2/cpia2_registers.h
index 8c73812a15c9..8c73812a15c9 100644
--- a/drivers/media/usb/cpia2/cpia2_registers.h
+++ b/drivers/staging/media/deprecated/cpia2/cpia2_registers.h
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/staging/media/deprecated/cpia2/cpia2_usb.c
index cba03b286473..cba03b286473 100644
--- a/drivers/media/usb/cpia2/cpia2_usb.c
+++ b/drivers/staging/media/deprecated/cpia2/cpia2_usb.c
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/staging/media/deprecated/cpia2/cpia2_v4l.c
index 926ecfc9b64a..926ecfc9b64a 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/staging/media/deprecated/cpia2/cpia2_v4l.c
diff --git a/drivers/staging/media/deprecated/fsl-viu/Kconfig b/drivers/staging/media/deprecated/fsl-viu/Kconfig
new file mode 100644
index 000000000000..399892c69a18
--- /dev/null
+++ b/drivers/staging/media/deprecated/fsl-viu/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_VIU
+ tristate "NXP VIU Video Driver (DEPRECATED)"
+ depends on V4L_PLATFORM_DRIVERS
+ depends on VIDEO_DEV && (PPC_MPC512x || COMPILE_TEST) && I2C
+ select VIDEOBUF_DMA_CONTIG
+ help
+ Support for Freescale VIU video driver. This device captures
+ video data, or overlays video on DIU frame buffer.
+
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
+ Say Y here if you want to enable VIU device on MPC5121e Rev2+.
+ In doubt, say N.
diff --git a/drivers/staging/media/deprecated/fsl-viu/Makefile b/drivers/staging/media/deprecated/fsl-viu/Makefile
new file mode 100644
index 000000000000..931ec56ad08c
--- /dev/null
+++ b/drivers/staging/media/deprecated/fsl-viu/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
diff --git a/drivers/staging/media/deprecated/fsl-viu/TODO b/drivers/staging/media/deprecated/fsl-viu/TODO
new file mode 100644
index 000000000000..ecb30a429689
--- /dev/null
+++ b/drivers/staging/media/deprecated/fsl-viu/TODO
@@ -0,0 +1,7 @@
+This is one of the few drivers still not using the vb2
+framework, so this driver is now deprecated with the intent of
+removing it altogether by the beginning of 2023.
+
+In order to keep this driver it has to be converted to vb2.
+If someone is interested in doing this work, then contact the
+linux-media mailinglist (https://linuxtv.org/lists.php).
diff --git a/drivers/media/platform/nxp/fsl-viu.c b/drivers/staging/media/deprecated/fsl-viu/fsl-viu.c
index afc96f6db2a1..afc96f6db2a1 100644
--- a/drivers/media/platform/nxp/fsl-viu.c
+++ b/drivers/staging/media/deprecated/fsl-viu/fsl-viu.c
diff --git a/drivers/media/pci/meye/Kconfig b/drivers/staging/media/deprecated/meye/Kconfig
index 3e69b66f1a5b..f135f8568c85 100644
--- a/drivers/media/pci/meye/Kconfig
+++ b/drivers/staging/media/deprecated/meye/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config VIDEO_MEYE
- tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
+ tristate "Sony Vaio Picturebook Motion Eye Video For Linux (DEPRECATED)"
depends on PCI && VIDEO_DEV
depends on SONY_LAPTOP
depends on X86 || COMPILE_TEST
@@ -12,5 +12,8 @@ config VIDEO_MEYE
If you say Y or M here, you need to say Y or M to "Sony Laptop
Extras" in the misc device section.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
To compile this driver as a module, choose M here: the
module will be called meye.
diff --git a/drivers/media/pci/meye/Makefile b/drivers/staging/media/deprecated/meye/Makefile
index 36f1f86f0d58..36f1f86f0d58 100644
--- a/drivers/media/pci/meye/Makefile
+++ b/drivers/staging/media/deprecated/meye/Makefile
diff --git a/drivers/staging/media/deprecated/meye/TODO b/drivers/staging/media/deprecated/meye/TODO
new file mode 100644
index 000000000000..6d1d1433d5a0
--- /dev/null
+++ b/drivers/staging/media/deprecated/meye/TODO
@@ -0,0 +1,6 @@
+The meye driver does not use the vb2 framework for streaming
+video, instead it implements this in the driver.
+
+To prevent removal of this driver early 2023 it has to be
+converted to use vb2. Contact the linux-media@vger.kernel.org
+mailing list if you want to do this.
diff --git a/drivers/media/pci/meye/meye.c b/drivers/staging/media/deprecated/meye/meye.c
index 5d87efd9b95c..5d87efd9b95c 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/staging/media/deprecated/meye/meye.c
diff --git a/drivers/media/pci/meye/meye.h b/drivers/staging/media/deprecated/meye/meye.h
index 5fa6552cf93d..5fa6552cf93d 100644
--- a/drivers/media/pci/meye/meye.h
+++ b/drivers/staging/media/deprecated/meye/meye.h
diff --git a/drivers/staging/media/deprecated/saa7146/Kconfig b/drivers/staging/media/deprecated/saa7146/Kconfig
new file mode 100644
index 000000000000..54154da79f59
--- /dev/null
+++ b/drivers/staging/media/deprecated/saa7146/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+source "drivers/staging/media/deprecated/saa7146/common/Kconfig"
+source "drivers/staging/media/deprecated/saa7146/av7110/Kconfig"
+source "drivers/staging/media/deprecated/saa7146/saa7146/Kconfig"
+source "drivers/staging/media/deprecated/saa7146/ttpci/Kconfig"
diff --git a/drivers/staging/media/deprecated/saa7146/Makefile b/drivers/staging/media/deprecated/saa7146/Makefile
new file mode 100644
index 000000000000..68e7aa10c639
--- /dev/null
+++ b/drivers/staging/media/deprecated/saa7146/Makefile
@@ -0,0 +1,2 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+obj-y += common/ av7110/ saa7146/ ttpci/
diff --git a/drivers/staging/media/av7110/Kconfig b/drivers/staging/media/deprecated/saa7146/av7110/Kconfig
index 9faf9d2d4001..1571eab31926 100644
--- a/drivers/staging/media/av7110/Kconfig
+++ b/drivers/staging/media/deprecated/saa7146/av7110/Kconfig
@@ -5,7 +5,7 @@ config DVB_AV7110_IR
default DVB_AV7110
config DVB_AV7110
- tristate "AV7110 cards"
+ tristate "AV7110 cards (DEPRECATED)"
depends on DVB_CORE && PCI && I2C
select TTPCI_EEPROM
select VIDEO_SAA7146_VV
@@ -35,10 +35,13 @@ config DVB_AV7110
kernel image by adding the filename to the EXTRA_FIRMWARE
configuration option string.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
Say Y if you own such a card and want to use it.
config DVB_AV7110_OSD
- bool "AV7110 OSD support"
+ bool "AV7110 OSD support (DEPRECATED)"
depends on DVB_AV7110
default y if DVB_AV7110=y || DVB_AV7110=m
help
@@ -49,10 +52,13 @@ config DVB_AV7110_OSD
Anyway, some popular DVB software like VDR uses this OSD to render
its menus, so say Y if you want to use this software.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
All other people say N.
config DVB_BUDGET_PATCH
- tristate "AV7110 cards with Budget Patch"
+ tristate "AV7110 cards with Budget Patch (DEPRECATED)"
depends on DVB_BUDGET_CORE && I2C
depends on DVB_AV7110
select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
@@ -68,6 +74,9 @@ config DVB_BUDGET_PATCH
standard AV7110 driver prior to loading this
driver.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
Say Y if you own such a card and want to use it.
To compile this driver as a module, choose M here: the
@@ -80,7 +89,7 @@ if DVB_AV7110
# it if we drop support for AV7110, as no other driver will use it.
config DVB_SP8870
- tristate "Spase sp8870 based"
+ tristate "Spase sp8870 based (DEPRECATED)"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
@@ -91,4 +100,7 @@ config DVB_SP8870
download/extract it, and then copy it to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
endif
diff --git a/drivers/staging/media/av7110/Makefile b/drivers/staging/media/deprecated/saa7146/av7110/Makefile
index 307b267598ea..c04cd0a59109 100644
--- a/drivers/staging/media/av7110/Makefile
+++ b/drivers/staging/media/deprecated/saa7146/av7110/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_DVB_SP8870) += sp8870.o
ccflags-y += -I $(srctree)/drivers/media/dvb-frontends
ccflags-y += -I $(srctree)/drivers/media/tuners
-ccflags-y += -I $(srctree)/drivers/media/pci/ttpci
ccflags-y += -I $(srctree)/drivers/media/common
+ccflags-y += -I $(srctree)/drivers/staging/media/deprecated/saa7146/ttpci
+ccflags-y += -I $(srctree)/drivers/staging/media/deprecated/saa7146/common
diff --git a/drivers/staging/media/deprecated/saa7146/av7110/TODO b/drivers/staging/media/deprecated/saa7146/av7110/TODO
new file mode 100644
index 000000000000..38817e04bb67
--- /dev/null
+++ b/drivers/staging/media/deprecated/saa7146/av7110/TODO
@@ -0,0 +1,9 @@
+- This driver is too old and relies on a different API.
+ Drop it from Kernel on a couple of versions.
+- Cleanup patches for the drivers here won't be accepted.
+
+These drivers are now deprecated with the intent of
+removing them altogether by the beginning of 2023.
+
+If someone is interested in doing this work, then contact the
+linux-media mailinglist (https://linuxtv.org/lists.php).
diff --git a/drivers/staging/media/av7110/audio-bilingual-channel-select.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-bilingual-channel-select.rst
index 33b5363317f1..33b5363317f1 100644
--- a/drivers/staging/media/av7110/audio-bilingual-channel-select.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-bilingual-channel-select.rst
diff --git a/drivers/staging/media/av7110/audio-channel-select.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-channel-select.rst
index 74093df92a68..74093df92a68 100644
--- a/drivers/staging/media/av7110/audio-channel-select.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-channel-select.rst
diff --git a/drivers/staging/media/av7110/audio-clear-buffer.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-clear-buffer.rst
index a0ebb0278260..a0ebb0278260 100644
--- a/drivers/staging/media/av7110/audio-clear-buffer.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-clear-buffer.rst
diff --git a/drivers/staging/media/av7110/audio-continue.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-continue.rst
index a2e9850f37f2..a2e9850f37f2 100644
--- a/drivers/staging/media/av7110/audio-continue.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-continue.rst
diff --git a/drivers/staging/media/av7110/audio-fclose.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-fclose.rst
index 77857d578e83..77857d578e83 100644
--- a/drivers/staging/media/av7110/audio-fclose.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-fclose.rst
diff --git a/drivers/staging/media/av7110/audio-fopen.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-fopen.rst
index 774daaab3bad..774daaab3bad 100644
--- a/drivers/staging/media/av7110/audio-fopen.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-fopen.rst
diff --git a/drivers/staging/media/av7110/audio-fwrite.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-fwrite.rst
index 7b096ac2b6c4..7b096ac2b6c4 100644
--- a/drivers/staging/media/av7110/audio-fwrite.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-fwrite.rst
diff --git a/drivers/staging/media/av7110/audio-get-capabilities.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-get-capabilities.rst
index 6d9eb71dad17..6d9eb71dad17 100644
--- a/drivers/staging/media/av7110/audio-get-capabilities.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-get-capabilities.rst
diff --git a/drivers/staging/media/av7110/audio-get-status.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-get-status.rst
index 7ae8db2e65e9..7ae8db2e65e9 100644
--- a/drivers/staging/media/av7110/audio-get-status.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-get-status.rst
diff --git a/drivers/staging/media/av7110/audio-pause.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-pause.rst
index d37d1ddce4df..d37d1ddce4df 100644
--- a/drivers/staging/media/av7110/audio-pause.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-pause.rst
diff --git a/drivers/staging/media/av7110/audio-play.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-play.rst
index e591930b6ca7..e591930b6ca7 100644
--- a/drivers/staging/media/av7110/audio-play.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-play.rst
diff --git a/drivers/staging/media/av7110/audio-select-source.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-select-source.rst
index 6a0c0f365eb1..6a0c0f365eb1 100644
--- a/drivers/staging/media/av7110/audio-select-source.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-select-source.rst
diff --git a/drivers/staging/media/av7110/audio-set-av-sync.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-av-sync.rst
index 85a8016bf025..85a8016bf025 100644
--- a/drivers/staging/media/av7110/audio-set-av-sync.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-av-sync.rst
diff --git a/drivers/staging/media/av7110/audio-set-bypass-mode.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-bypass-mode.rst
index 80d551a2053a..80d551a2053a 100644
--- a/drivers/staging/media/av7110/audio-set-bypass-mode.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-bypass-mode.rst
diff --git a/drivers/staging/media/av7110/audio-set-id.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-id.rst
index 39ad846d412d..39ad846d412d 100644
--- a/drivers/staging/media/av7110/audio-set-id.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-id.rst
diff --git a/drivers/staging/media/av7110/audio-set-mixer.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mixer.rst
index 45dbdf4801e0..45dbdf4801e0 100644
--- a/drivers/staging/media/av7110/audio-set-mixer.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mixer.rst
diff --git a/drivers/staging/media/av7110/audio-set-mute.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mute.rst
index 987751f92967..987751f92967 100644
--- a/drivers/staging/media/av7110/audio-set-mute.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mute.rst
diff --git a/drivers/staging/media/av7110/audio-set-streamtype.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-streamtype.rst
index 77d73c74882f..77d73c74882f 100644
--- a/drivers/staging/media/av7110/audio-set-streamtype.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-set-streamtype.rst
diff --git a/drivers/staging/media/av7110/audio-stop.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio-stop.rst
index d77f786fd797..d77f786fd797 100644
--- a/drivers/staging/media/av7110/audio-stop.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio-stop.rst
diff --git a/drivers/staging/media/av7110/audio.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio.rst
index aa753336b31f..aa753336b31f 100644
--- a/drivers/staging/media/av7110/audio.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio.rst
diff --git a/drivers/staging/media/av7110/audio_data_types.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio_data_types.rst
index 4744529136a8..4744529136a8 100644
--- a/drivers/staging/media/av7110/audio_data_types.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio_data_types.rst
diff --git a/drivers/staging/media/av7110/audio_function_calls.rst b/drivers/staging/media/deprecated/saa7146/av7110/audio_function_calls.rst
index fa5ba9539caf..fa5ba9539caf 100644
--- a/drivers/staging/media/av7110/audio_function_calls.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/audio_function_calls.rst
diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110.c
index df81a9b744c2..df81a9b744c2 100644
--- a/drivers/staging/media/av7110/av7110.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110.c
diff --git a/drivers/staging/media/av7110/av7110.h b/drivers/staging/media/deprecated/saa7146/av7110/av7110.h
index 809d938ae166..9fde69b38f1c 100644
--- a/drivers/staging/media/av7110/av7110.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110.h
@@ -33,7 +33,7 @@
#include "stv0297.h"
#include "l64781.h"
-#include <media/drv-intf/saa7146_vv.h>
+#include "saa7146_vv.h"
#define ANALOG_TUNER_VES1820 1
diff --git a/drivers/staging/media/av7110/av7110_av.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c
index ab7cf496b454..0bf513c26b6b 100644
--- a/drivers/staging/media/av7110/av7110_av.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c
@@ -106,7 +106,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
int ret = 0;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
+ dprintk(2, "av7110:%p, dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
if (av7110->playing || (av7110->rec_mode & av))
return -EBUSY;
diff --git a/drivers/staging/media/av7110/av7110_av.h b/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.h
index 71bbd4391f57..71bbd4391f57 100644
--- a/drivers/staging/media/av7110/av7110_av.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.h
diff --git a/drivers/staging/media/av7110/av7110_ca.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c
index c1338e074a3d..c1338e074a3d 100644
--- a/drivers/staging/media/av7110/av7110_ca.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c
diff --git a/drivers/staging/media/av7110/av7110_ca.h b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.h
index a6e3f2955730..a6e3f2955730 100644
--- a/drivers/staging/media/av7110/av7110_ca.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.h
diff --git a/drivers/staging/media/av7110/av7110_hw.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.c
index 93ca31e38ddd..93ca31e38ddd 100644
--- a/drivers/staging/media/av7110/av7110_hw.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.c
diff --git a/drivers/staging/media/av7110/av7110_hw.h b/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.h
index 6380d8950c69..6380d8950c69 100644
--- a/drivers/staging/media/av7110/av7110_hw.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.h
diff --git a/drivers/staging/media/av7110/av7110_ipack.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.c
index 30330ed01ce8..30330ed01ce8 100644
--- a/drivers/staging/media/av7110/av7110_ipack.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.c
diff --git a/drivers/staging/media/av7110/av7110_ipack.h b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.h
index 943ec899bb93..943ec899bb93 100644
--- a/drivers/staging/media/av7110/av7110_ipack.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.h
diff --git a/drivers/staging/media/av7110/av7110_ir.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ir.c
index a851ba328e4a..a851ba328e4a 100644
--- a/drivers/staging/media/av7110/av7110_ir.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_ir.c
diff --git a/drivers/staging/media/av7110/av7110_v4l.c b/drivers/staging/media/deprecated/saa7146/av7110/av7110_v4l.c
index c89f536f699c..c89f536f699c 100644
--- a/drivers/staging/media/av7110/av7110_v4l.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/av7110_v4l.c
diff --git a/drivers/staging/media/av7110/budget-patch.c b/drivers/staging/media/deprecated/saa7146/av7110/budget-patch.c
index d173c8ade6a7..d173c8ade6a7 100644
--- a/drivers/staging/media/av7110/budget-patch.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/budget-patch.c
diff --git a/drivers/staging/media/av7110/dvb_filter.c b/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.c
index 8c2eca5dcdc9..8c2eca5dcdc9 100644
--- a/drivers/staging/media/av7110/dvb_filter.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.c
diff --git a/drivers/staging/media/av7110/dvb_filter.h b/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.h
index 67a3c6333bca..67a3c6333bca 100644
--- a/drivers/staging/media/av7110/dvb_filter.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.h
diff --git a/drivers/staging/media/av7110/sp8870.c b/drivers/staging/media/deprecated/saa7146/av7110/sp8870.c
index 9767159aeb9b..9767159aeb9b 100644
--- a/drivers/staging/media/av7110/sp8870.c
+++ b/drivers/staging/media/deprecated/saa7146/av7110/sp8870.c
diff --git a/drivers/staging/media/av7110/sp8870.h b/drivers/staging/media/deprecated/saa7146/av7110/sp8870.h
index 5eacf39f425e..5eacf39f425e 100644
--- a/drivers/staging/media/av7110/sp8870.h
+++ b/drivers/staging/media/deprecated/saa7146/av7110/sp8870.h
diff --git a/drivers/staging/media/av7110/video-clear-buffer.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-clear-buffer.rst
index a7730559bbb2..a7730559bbb2 100644
--- a/drivers/staging/media/av7110/video-clear-buffer.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-clear-buffer.rst
diff --git a/drivers/staging/media/av7110/video-command.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-command.rst
index cae9445eb3af..cae9445eb3af 100644
--- a/drivers/staging/media/av7110/video-command.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-command.rst
diff --git a/drivers/staging/media/av7110/video-continue.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-continue.rst
index bc34bf3989e4..bc34bf3989e4 100644
--- a/drivers/staging/media/av7110/video-continue.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-continue.rst
diff --git a/drivers/staging/media/av7110/video-fast-forward.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-fast-forward.rst
index e71fa8d6965b..e71fa8d6965b 100644
--- a/drivers/staging/media/av7110/video-fast-forward.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-fast-forward.rst
diff --git a/drivers/staging/media/av7110/video-fclose.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-fclose.rst
index 01d24d548439..01d24d548439 100644
--- a/drivers/staging/media/av7110/video-fclose.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-fclose.rst
diff --git a/drivers/staging/media/av7110/video-fopen.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-fopen.rst
index 1371b083e4e8..1371b083e4e8 100644
--- a/drivers/staging/media/av7110/video-fopen.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-fopen.rst
diff --git a/drivers/staging/media/av7110/video-freeze.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-freeze.rst
index 4321f257cb70..4321f257cb70 100644
--- a/drivers/staging/media/av7110/video-freeze.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-freeze.rst
diff --git a/drivers/staging/media/av7110/video-fwrite.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-fwrite.rst
index a07fd7d7a40e..a07fd7d7a40e 100644
--- a/drivers/staging/media/av7110/video-fwrite.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-fwrite.rst
diff --git a/drivers/staging/media/av7110/video-get-capabilities.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-get-capabilities.rst
index 01e09f56656c..01e09f56656c 100644
--- a/drivers/staging/media/av7110/video-get-capabilities.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-get-capabilities.rst
diff --git a/drivers/staging/media/av7110/video-get-event.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-get-event.rst
index 90382bc36cfe..90382bc36cfe 100644
--- a/drivers/staging/media/av7110/video-get-event.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-get-event.rst
diff --git a/drivers/staging/media/av7110/video-get-frame-count.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-get-frame-count.rst
index b48ac8c58a41..b48ac8c58a41 100644
--- a/drivers/staging/media/av7110/video-get-frame-count.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-get-frame-count.rst
diff --git a/drivers/staging/media/av7110/video-get-pts.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-get-pts.rst
index fedaff41be0b..fedaff41be0b 100644
--- a/drivers/staging/media/av7110/video-get-pts.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-get-pts.rst
diff --git a/drivers/staging/media/av7110/video-get-size.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-get-size.rst
index de34331c5bd1..de34331c5bd1 100644
--- a/drivers/staging/media/av7110/video-get-size.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-get-size.rst
diff --git a/drivers/staging/media/av7110/video-get-status.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-get-status.rst
index 9b86fbf411d4..9b86fbf411d4 100644
--- a/drivers/staging/media/av7110/video-get-status.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-get-status.rst
diff --git a/drivers/staging/media/av7110/video-play.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-play.rst
index 35ac8b98fdbf..35ac8b98fdbf 100644
--- a/drivers/staging/media/av7110/video-play.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-play.rst
diff --git a/drivers/staging/media/av7110/video-select-source.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-select-source.rst
index 929a20985d53..929a20985d53 100644
--- a/drivers/staging/media/av7110/video-select-source.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-select-source.rst
diff --git a/drivers/staging/media/av7110/video-set-blank.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-set-blank.rst
index 70249a6ba125..70249a6ba125 100644
--- a/drivers/staging/media/av7110/video-set-blank.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-set-blank.rst
diff --git a/drivers/staging/media/av7110/video-set-display-format.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-set-display-format.rst
index 1de4f40ae732..1de4f40ae732 100644
--- a/drivers/staging/media/av7110/video-set-display-format.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-set-display-format.rst
diff --git a/drivers/staging/media/av7110/video-set-format.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-set-format.rst
index bb64e37ae081..bb64e37ae081 100644
--- a/drivers/staging/media/av7110/video-set-format.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-set-format.rst
diff --git a/drivers/staging/media/av7110/video-set-streamtype.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-set-streamtype.rst
index 1f31c048bdbc..1f31c048bdbc 100644
--- a/drivers/staging/media/av7110/video-set-streamtype.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-set-streamtype.rst
diff --git a/drivers/staging/media/av7110/video-slowmotion.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-slowmotion.rst
index 1478fcc30cb8..1478fcc30cb8 100644
--- a/drivers/staging/media/av7110/video-slowmotion.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-slowmotion.rst
diff --git a/drivers/staging/media/av7110/video-stillpicture.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-stillpicture.rst
index d25384222a20..d25384222a20 100644
--- a/drivers/staging/media/av7110/video-stillpicture.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-stillpicture.rst
diff --git a/drivers/staging/media/av7110/video-stop.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-stop.rst
index 96f61c5b48a2..96f61c5b48a2 100644
--- a/drivers/staging/media/av7110/video-stop.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-stop.rst
diff --git a/drivers/staging/media/av7110/video-try-command.rst b/drivers/staging/media/deprecated/saa7146/av7110/video-try-command.rst
index 79bf3dfb8a32..79bf3dfb8a32 100644
--- a/drivers/staging/media/av7110/video-try-command.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video-try-command.rst
diff --git a/drivers/staging/media/av7110/video.rst b/drivers/staging/media/deprecated/saa7146/av7110/video.rst
index 808705b769a1..808705b769a1 100644
--- a/drivers/staging/media/av7110/video.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video.rst
diff --git a/drivers/staging/media/av7110/video_function_calls.rst b/drivers/staging/media/deprecated/saa7146/av7110/video_function_calls.rst
index 20a897be5dca..20a897be5dca 100644
--- a/drivers/staging/media/av7110/video_function_calls.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video_function_calls.rst
diff --git a/drivers/staging/media/av7110/video_types.rst b/drivers/staging/media/deprecated/saa7146/av7110/video_types.rst
index c4557d328b7a..c4557d328b7a 100644
--- a/drivers/staging/media/av7110/video_types.rst
+++ b/drivers/staging/media/deprecated/saa7146/av7110/video_types.rst
diff --git a/drivers/media/common/saa7146/Kconfig b/drivers/staging/media/deprecated/saa7146/common/Kconfig
index a0aa155e5d85..a0aa155e5d85 100644
--- a/drivers/media/common/saa7146/Kconfig
+++ b/drivers/staging/media/deprecated/saa7146/common/Kconfig
diff --git a/drivers/media/common/saa7146/Makefile b/drivers/staging/media/deprecated/saa7146/common/Makefile
index 2a6337feaec8..2a6337feaec8 100644
--- a/drivers/media/common/saa7146/Makefile
+++ b/drivers/staging/media/deprecated/saa7146/common/Makefile
diff --git a/include/media/drv-intf/saa7146.h b/drivers/staging/media/deprecated/saa7146/common/saa7146.h
index 71ce63c99cb4..71ce63c99cb4 100644
--- a/include/media/drv-intf/saa7146.h
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146.h
diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_core.c
index e50fa0ff7c5d..da21d346b870 100644
--- a/drivers/media/common/saa7146/saa7146_core.c
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146_core.c
@@ -8,8 +8,8 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <media/drv-intf/saa7146.h>
#include <linux/module.h>
+#include "saa7146.h"
static int saa7146_num;
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_fops.c
index e9a15de6126e..aa14698a9c54 100644
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146_fops.c
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <media/drv-intf/saa7146_vv.h>
#include <linux/module.h>
+#include "saa7146_vv.h"
/****************************************************************************/
/* resource management functions, shamelessly stolen from saa7134 driver */
diff --git a/drivers/media/common/saa7146/saa7146_hlp.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_hlp.c
index 6c9946a402ee..b1222a4cfa4a 100644
--- a/drivers/media/common/saa7146/saa7146_hlp.c
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146_hlp.c
@@ -3,7 +3,7 @@
#include <linux/kernel.h>
#include <linux/export.h>
-#include <media/drv-intf/saa7146_vv.h>
+#include "saa7146_vv.h"
static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format)
{
diff --git a/drivers/media/common/saa7146/saa7146_i2c.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_i2c.c
index df9ebe2a168c..7a33fe51775a 100644
--- a/drivers/media/common/saa7146/saa7146_i2c.c
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146_i2c.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <media/drv-intf/saa7146_vv.h>
+#include "saa7146_vv.h"
static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
{
diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_vbi.c
index bd442b984423..2d4a05d7bc5b 100644
--- a/drivers/media/common/saa7146/saa7146_vbi.c
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146_vbi.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-#include <media/drv-intf/saa7146_vv.h>
+#include "saa7146_vv.h"
static int vbi_pixel_to_capture = 720 * 2;
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_video.c
index 2296765079a4..4598a44231fa 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146_video.c
@@ -1,10 +1,10 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <media/drv-intf/saa7146_vv.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include "saa7146_vv.h"
static int max_memory = 32;
diff --git a/include/media/drv-intf/saa7146_vv.h b/drivers/staging/media/deprecated/saa7146/common/saa7146_vv.h
index 635805fb35e8..d7bd916fe3ad 100644
--- a/include/media/drv-intf/saa7146_vv.h
+++ b/drivers/staging/media/deprecated/saa7146/common/saa7146_vv.h
@@ -5,8 +5,8 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-fh.h>
-#include <media/drv-intf/saa7146.h>
#include <media/videobuf-dma-sg.h>
+#include "saa7146.h"
#define MAX_SAA7146_CAPTURE_BUFFERS 32 /* arbitrary */
#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
diff --git a/drivers/media/pci/saa7146/Kconfig b/drivers/staging/media/deprecated/saa7146/saa7146/Kconfig
index 3bbb68a0ed7b..228e8d3f8d2b 100644
--- a/drivers/media/pci/saa7146/Kconfig
+++ b/drivers/staging/media/deprecated/saa7146/saa7146/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config VIDEO_HEXIUM_GEMINI
- tristate "Hexium Gemini frame grabber"
+ tristate "Hexium Gemini frame grabber (DEPRECATED)"
depends on PCI && VIDEO_DEV && I2C
select VIDEO_SAA7146_VV
help
@@ -8,22 +8,28 @@ config VIDEO_HEXIUM_GEMINI
grabber card by Hexium. Please note that the Gemini Dual
card is *not* fully supported.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
To compile this driver as a module, choose M here: the
module will be called hexium_gemini.
config VIDEO_HEXIUM_ORION
- tristate "Hexium HV-PCI6 and Orion frame grabber"
+ tristate "Hexium HV-PCI6 and Orion frame grabber (DEPRECATED)"
depends on PCI && VIDEO_DEV && I2C
select VIDEO_SAA7146_VV
help
This is a video4linux driver for the Hexium HV-PCI6 and
Orion frame grabber cards by Hexium.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
To compile this driver as a module, choose M here: the
module will be called hexium_orion.
config VIDEO_MXB
- tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
+ tristate "Siemens-Nixdorf 'Multimedia eXtension Board' (DEPRECATED)"
depends on PCI && VIDEO_DEV && I2C
select VIDEO_SAA7146_VV
select VIDEO_TUNER
@@ -35,5 +41,8 @@ config VIDEO_MXB
This is a video4linux driver for the 'Multimedia eXtension Board'
TV card by Siemens-Nixdorf.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
To compile this driver as a module, choose M here: the
module will be called mxb.
diff --git a/drivers/media/pci/saa7146/Makefile b/drivers/staging/media/deprecated/saa7146/saa7146/Makefile
index 37c9336f83d5..37c9336f83d5 100644
--- a/drivers/media/pci/saa7146/Makefile
+++ b/drivers/staging/media/deprecated/saa7146/saa7146/Makefile
diff --git a/drivers/staging/media/deprecated/saa7146/saa7146/TODO b/drivers/staging/media/deprecated/saa7146/saa7146/TODO
new file mode 100644
index 000000000000..c9ae2ec79cea
--- /dev/null
+++ b/drivers/staging/media/deprecated/saa7146/saa7146/TODO
@@ -0,0 +1,7 @@
+The saa7146-based drivers are one of the few drivers still not using
+the vb2 framework, so these drivers are now deprecated with the intent of
+removing them altogether by the beginning of 2023.
+
+In order to keep these drivers they have to be converted to vb2.
+If someone is interested in doing this work, then contact the
+linux-media mailinglist (https://linuxtv.org/lists.php).
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/staging/media/deprecated/saa7146/saa7146/hexium_gemini.c
index 3947701cd6c7..124e82bd4507 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/staging/media/deprecated/saa7146/saa7146/hexium_gemini.c
@@ -13,9 +13,9 @@
#define DEBUG_VARIABLE debug
-#include <media/drv-intf/saa7146_vv.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include "../common/saa7146_vv.h"
static int debug;
module_param(debug, int, 0);
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/staging/media/deprecated/saa7146/saa7146/hexium_orion.c
index 2eb4bee16b71..ebd63998ac79 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/staging/media/deprecated/saa7146/saa7146/hexium_orion.c
@@ -13,9 +13,9 @@
#define DEBUG_VARIABLE debug
-#include <media/drv-intf/saa7146_vv.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include "../common/saa7146_vv.h"
static int debug;
module_param(debug, int, 0);
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/staging/media/deprecated/saa7146/saa7146/mxb.c
index 7ded8f5b05cb..3e568f952dae 100644
--- a/drivers/media/pci/saa7146/mxb.c
+++ b/drivers/staging/media/deprecated/saa7146/saa7146/mxb.c
@@ -13,13 +13,13 @@
#define DEBUG_VARIABLE debug
-#include <media/drv-intf/saa7146_vv.h>
#include <media/tuner.h>
#include <media/v4l2-common.h>
#include <media/i2c/saa7115.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include "../common/saa7146_vv.h"
#include "tea6415c.h"
#include "tea6420.h"
diff --git a/drivers/media/pci/ttpci/Kconfig b/drivers/staging/media/deprecated/saa7146/ttpci/Kconfig
index 65a6832a6b96..8c85ed58e938 100644
--- a/drivers/media/pci/ttpci/Kconfig
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config DVB_BUDGET_CORE
- tristate "SAA7146 DVB cards (aka Budget, Nova-PCI)"
+ tristate "SAA7146 DVB cards (aka Budget, Nova-PCI) (DEPRECATED)"
depends on DVB_CORE && PCI && I2C
select VIDEO_SAA7146
select TTPCI_EEPROM
@@ -10,7 +10,7 @@ config DVB_BUDGET_CORE
MPEG2 decoder.
config DVB_BUDGET
- tristate "Budget cards"
+ tristate "Budget cards (DEPRECATED)"
depends on DVB_BUDGET_CORE && I2C
select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT
@@ -30,13 +30,16 @@ config DVB_BUDGET
or Nova-PCI cards) without onboard MPEG2 decoder, and without
analog inputs or an onboard Common Interface connector.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
Say Y if you own such a card and want to use it.
To compile this driver as a module, choose M here: the
module will be called budget.
config DVB_BUDGET_CI
- tristate "Budget cards with onboard CI connector"
+ tristate "Budget cards with onboard CI connector (DEPRECATED)"
depends on DVB_BUDGET_CORE && I2C
select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
@@ -57,13 +60,16 @@ config DVB_BUDGET_CI
Note: The Common Interface is not yet supported by this driver
due to lack of information from the vendor.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
Say Y if you own such a card and want to use it.
To compile this driver as a module, choose M here: the
module will be called budget-ci.
config DVB_BUDGET_AV
- tristate "Budget cards with analog video inputs"
+ tristate "Budget cards with analog video inputs (DEPRECATED)"
depends on DVB_BUDGET_CORE && I2C
select VIDEO_SAA7146_VV
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
@@ -80,6 +86,9 @@ config DVB_BUDGET_AV
(so called Budget- or Nova-PCI cards) without onboard
MPEG2 decoder, but with one or more analog video inputs.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
Say Y if you own such a card and want to use it.
To compile this driver as a module, choose M here: the
diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/staging/media/deprecated/saa7146/ttpci/Makefile
index b0708f6e40cc..b0708f6e40cc 100644
--- a/drivers/media/pci/ttpci/Makefile
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/Makefile
diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/TODO b/drivers/staging/media/deprecated/saa7146/ttpci/TODO
new file mode 100644
index 000000000000..c9ae2ec79cea
--- /dev/null
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/TODO
@@ -0,0 +1,7 @@
+The saa7146-based drivers are one of the few drivers still not using
+the vb2 framework, so these drivers are now deprecated with the intent of
+removing them altogether by the beginning of 2023.
+
+In order to keep these drivers they have to be converted to vb2.
+If someone is interested in doing this work, then contact the
+linux-media mailinglist (https://linuxtv.org/lists.php).
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c
index 3cb83005cf09..0c61a2dec221 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c
@@ -29,7 +29,7 @@
#include "tda1004x.h"
#include "tua6100.h"
#include "dvb-pll.h"
-#include <media/drv-intf/saa7146_vv.h>
+#include "../common/saa7146_vv.h"
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-ci.c
index d59d18647371..d59d18647371 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/budget-ci.c
diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-core.c
index 5d5796f24469..5d5796f24469 100644
--- a/drivers/media/pci/ttpci/budget-core.c
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/budget-core.c
diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget.c
index a88711a3ac7f..a88711a3ac7f 100644
--- a/drivers/media/pci/ttpci/budget.c
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/budget.c
diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/staging/media/deprecated/saa7146/ttpci/budget.h
index bd87432e6cde..82cc0df492b3 100644
--- a/drivers/media/pci/ttpci/budget.h
+++ b/drivers/staging/media/deprecated/saa7146/ttpci/budget.h
@@ -13,7 +13,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
-#include <media/drv-intf/saa7146.h>
+#include "../common/saa7146.h"
extern int budget_debug;
diff --git a/drivers/staging/media/stkwebcam/Kconfig b/drivers/staging/media/deprecated/stkwebcam/Kconfig
index 4450403dff41..4450403dff41 100644
--- a/drivers/staging/media/stkwebcam/Kconfig
+++ b/drivers/staging/media/deprecated/stkwebcam/Kconfig
diff --git a/drivers/staging/media/stkwebcam/Makefile b/drivers/staging/media/deprecated/stkwebcam/Makefile
index 17ad7b6f43d0..17ad7b6f43d0 100644
--- a/drivers/staging/media/stkwebcam/Makefile
+++ b/drivers/staging/media/deprecated/stkwebcam/Makefile
diff --git a/drivers/staging/media/stkwebcam/TODO b/drivers/staging/media/deprecated/stkwebcam/TODO
index 735304a72729..735304a72729 100644
--- a/drivers/staging/media/stkwebcam/TODO
+++ b/drivers/staging/media/deprecated/stkwebcam/TODO
diff --git a/drivers/staging/media/stkwebcam/stk-sensor.c b/drivers/staging/media/deprecated/stkwebcam/stk-sensor.c
index 94aa6a27f934..94aa6a27f934 100644
--- a/drivers/staging/media/stkwebcam/stk-sensor.c
+++ b/drivers/staging/media/deprecated/stkwebcam/stk-sensor.c
diff --git a/drivers/staging/media/stkwebcam/stk-webcam.c b/drivers/staging/media/deprecated/stkwebcam/stk-webcam.c
index 787edb3d47c2..787edb3d47c2 100644
--- a/drivers/staging/media/stkwebcam/stk-webcam.c
+++ b/drivers/staging/media/deprecated/stkwebcam/stk-webcam.c
diff --git a/drivers/staging/media/stkwebcam/stk-webcam.h b/drivers/staging/media/deprecated/stkwebcam/stk-webcam.h
index 136decffe9ce..136decffe9ce 100644
--- a/drivers/staging/media/stkwebcam/stk-webcam.h
+++ b/drivers/staging/media/deprecated/stkwebcam/stk-webcam.h
diff --git a/drivers/media/usb/tm6000/Kconfig b/drivers/staging/media/deprecated/tm6000/Kconfig
index 56e977deba81..73d72e49eb28 100644
--- a/drivers/media/usb/tm6000/Kconfig
+++ b/drivers/staging/media/deprecated/tm6000/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config VIDEO_TM6000
- tristate "TV Master TM5600/6000/6010 driver"
+ tristate "TV Master TM5600/6000/6010 driver (DEPRECATED)"
depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB
select VIDEO_TUNER
select MEDIA_TUNER_XC2028
@@ -13,6 +13,9 @@ config VIDEO_TM6000
only compressed MPEG data over the usb bus, so you need
an external software decoder to watch TV on your computer.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
Say Y if you own such a device and want to use it.
config VIDEO_TM6000_ALSA
diff --git a/drivers/media/usb/tm6000/Makefile b/drivers/staging/media/deprecated/tm6000/Makefile
index 75247a02a485..75247a02a485 100644
--- a/drivers/media/usb/tm6000/Makefile
+++ b/drivers/staging/media/deprecated/tm6000/Makefile
diff --git a/drivers/staging/media/deprecated/tm6000/TODO b/drivers/staging/media/deprecated/tm6000/TODO
new file mode 100644
index 000000000000..ecb30a429689
--- /dev/null
+++ b/drivers/staging/media/deprecated/tm6000/TODO
@@ -0,0 +1,7 @@
+This is one of the few drivers still not using the vb2
+framework, so this driver is now deprecated with the intent of
+removing it altogether by the beginning of 2023.
+
+In order to keep this driver it has to be converted to vb2.
+If someone is interested in doing this work, then contact the
+linux-media mailinglist (https://linuxtv.org/lists.php).
diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/staging/media/deprecated/tm6000/tm6000-alsa.c
index a19a46770c2b..a19a46770c2b 100644
--- a/drivers/media/usb/tm6000/tm6000-alsa.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-alsa.c
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/staging/media/deprecated/tm6000/tm6000-cards.c
index 98f4a63adc2a..98f4a63adc2a 100644
--- a/drivers/media/usb/tm6000/tm6000-cards.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-cards.c
diff --git a/drivers/media/usb/tm6000/tm6000-core.c b/drivers/staging/media/deprecated/tm6000/tm6000-core.c
index 5c8cbc5d6f72..5c8cbc5d6f72 100644
--- a/drivers/media/usb/tm6000/tm6000-core.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-core.c
diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/staging/media/deprecated/tm6000/tm6000-dvb.c
index ee04973cbf93..ee04973cbf93 100644
--- a/drivers/media/usb/tm6000/tm6000-dvb.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-dvb.c
diff --git a/drivers/media/usb/tm6000/tm6000-i2c.c b/drivers/staging/media/deprecated/tm6000/tm6000-i2c.c
index 7554b93b82e6..7554b93b82e6 100644
--- a/drivers/media/usb/tm6000/tm6000-i2c.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-i2c.c
diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/staging/media/deprecated/tm6000/tm6000-input.c
index 5136e9e202f1..5136e9e202f1 100644
--- a/drivers/media/usb/tm6000/tm6000-input.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-input.c
diff --git a/drivers/media/usb/tm6000/tm6000-regs.h b/drivers/staging/media/deprecated/tm6000/tm6000-regs.h
index 6a181f2e7ef2..6a181f2e7ef2 100644
--- a/drivers/media/usb/tm6000/tm6000-regs.h
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-regs.h
diff --git a/drivers/media/usb/tm6000/tm6000-stds.c b/drivers/staging/media/deprecated/tm6000/tm6000-stds.c
index 858cb4f3a9ca..858cb4f3a9ca 100644
--- a/drivers/media/usb/tm6000/tm6000-stds.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-stds.c
diff --git a/drivers/media/usb/tm6000/tm6000-usb-isoc.h b/drivers/staging/media/deprecated/tm6000/tm6000-usb-isoc.h
index e3c6933f854d..e3c6933f854d 100644
--- a/drivers/media/usb/tm6000/tm6000-usb-isoc.h
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-usb-isoc.h
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/staging/media/deprecated/tm6000/tm6000-video.c
index d855a19551f3..e06ed21edbdd 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/staging/media/deprecated/tm6000/tm6000-video.c
@@ -916,8 +916,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL;
}
- field = f->fmt.pix.field;
-
field = V4L2_FIELD_INTERLACED;
tm6000_get_std_res(dev);
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/staging/media/deprecated/tm6000/tm6000.h
index c08c95312739..c08c95312739 100644
--- a/drivers/media/usb/tm6000/tm6000.h
+++ b/drivers/staging/media/deprecated/tm6000/tm6000.h
diff --git a/drivers/staging/media/deprecated/vpfe_capture/Kconfig b/drivers/staging/media/deprecated/vpfe_capture/Kconfig
new file mode 100644
index 000000000000..10250e7e566b
--- /dev/null
+++ b/drivers/staging/media/deprecated/vpfe_capture/Kconfig
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_DM6446_CCDC
+ tristate "TI DM6446 CCDC video capture driver"
+ depends on V4L_PLATFORM_DRIVERS
+ depends on VIDEO_DEV
+ depends on ARCH_DAVINCI || COMPILE_TEST
+ depends on I2C
+ select VIDEOBUF_DMA_CONTIG
+ help
+ Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
+ with decoder modules such as TVP5146 over BT656 or
+ sensor module such as MT9T001 over a raw interface. This
+ module configures the interface and CCDC/ISIF to do
+ video frame capture from slave decoders.
+
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
+ To compile this driver as a module, choose M here. There will
+ be two modules called vpfe_capture.ko and dm644x_ccdc.ko
+
+config VIDEO_DM355_CCDC
+ tristate "TI DM355 CCDC video capture driver"
+ depends on V4L_PLATFORM_DRIVERS
+ depends on VIDEO_DEV
+ depends on ARCH_DAVINCI || COMPILE_TEST
+ depends on I2C
+ select VIDEOBUF_DMA_CONTIG
+ help
+ Enables DM355 CCD hw module. DM355 CCDC hw interfaces
+ with decoder modules such as TVP5146 over BT656 or
+ sensor module such as MT9T001 over a raw interface. This
+ module configures the interface and CCDC/ISIF to do
+ video frame capture from a slave decoders
+
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
+ To compile this driver as a module, choose M here. There will
+ be two modules called vpfe_capture.ko and dm355_ccdc.ko
+
+config VIDEO_DM365_ISIF
+ tristate "TI DM365 ISIF video capture driver"
+ depends on V4L_PLATFORM_DRIVERS
+ depends on VIDEO_DEV
+ depends on ARCH_DAVINCI || COMPILE_TEST
+ depends on I2C
+ select VIDEOBUF_DMA_CONTIG
+ help
+ Enables ISIF hw module. This is the hardware module for
+ configuring ISIF in VPFE to capture Raw Bayer RGB data from
+ a image sensor or YUV data from a YUV source.
+
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
+ To compile this driver as a module, choose M here. There will
+ be two modules called vpfe_capture.ko and isif.ko
diff --git a/drivers/staging/media/deprecated/vpfe_capture/Makefile b/drivers/staging/media/deprecated/vpfe_capture/Makefile
new file mode 100644
index 000000000000..609e8dc09ce7
--- /dev/null
+++ b/drivers/staging/media/deprecated/vpfe_capture/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_DM6446_CCDC) += vpfe_capture.o dm644x_ccdc.o
+obj-$(CONFIG_VIDEO_DM355_CCDC) += vpfe_capture.o dm355_ccdc.o
+obj-$(CONFIG_VIDEO_DM365_ISIF) += vpfe_capture.o isif.o
diff --git a/drivers/staging/media/deprecated/vpfe_capture/TODO b/drivers/staging/media/deprecated/vpfe_capture/TODO
new file mode 100644
index 000000000000..ce654d7337af
--- /dev/null
+++ b/drivers/staging/media/deprecated/vpfe_capture/TODO
@@ -0,0 +1,7 @@
+These are one of the few drivers still not using the vb2
+framework, so these drivers are now deprecated with the intent of
+removing them altogether by the beginning of 2023.
+
+In order to keep these drivers they have to be converted to vb2.
+If someone is interested in doing this work, then contact the
+linux-media mailinglist (https://linuxtv.org/lists.php).
diff --git a/drivers/media/platform/ti/davinci/ccdc_hw_device.h b/drivers/staging/media/deprecated/vpfe_capture/ccdc_hw_device.h
index a545052a95a9..a545052a95a9 100644
--- a/drivers/media/platform/ti/davinci/ccdc_hw_device.h
+++ b/drivers/staging/media/deprecated/vpfe_capture/ccdc_hw_device.h
diff --git a/drivers/media/platform/ti/davinci/dm355_ccdc.c b/drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc.c
index 8fe55d1b972c..da8db53e9498 100644
--- a/drivers/media/platform/ti/davinci/dm355_ccdc.c
+++ b/drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc.c
@@ -22,7 +22,7 @@
#include <linux/err.h>
#include <linux/module.h>
-#include <media/davinci/dm355_ccdc.h>
+#include "dm355_ccdc.h"
#include <media/davinci/vpss.h>
#include "dm355_ccdc_regs.h"
diff --git a/include/media/davinci/dm355_ccdc.h b/drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc.h
index 1f3d00aa46d1..1f3d00aa46d1 100644
--- a/include/media/davinci/dm355_ccdc.h
+++ b/drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc.h
diff --git a/drivers/media/platform/ti/davinci/dm355_ccdc_regs.h b/drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc_regs.h
index eb381f075245..eb381f075245 100644
--- a/drivers/media/platform/ti/davinci/dm355_ccdc_regs.h
+++ b/drivers/staging/media/deprecated/vpfe_capture/dm355_ccdc_regs.h
diff --git a/drivers/media/platform/ti/davinci/dm644x_ccdc.c b/drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc.c
index e4073e99914c..4a93e5ad6415 100644
--- a/drivers/media/platform/ti/davinci/dm644x_ccdc.c
+++ b/drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc.c
@@ -24,7 +24,7 @@
#include <linux/err.h>
#include <linux/module.h>
-#include <media/davinci/dm644x_ccdc.h>
+#include "dm644x_ccdc.h"
#include <media/davinci/vpss.h>
#include "dm644x_ccdc_regs.h"
diff --git a/include/media/davinci/dm644x_ccdc.h b/drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc.h
index c20dba3d76d6..c20dba3d76d6 100644
--- a/include/media/davinci/dm644x_ccdc.h
+++ b/drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc.h
diff --git a/drivers/media/platform/ti/davinci/dm644x_ccdc_regs.h b/drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc_regs.h
index c4894f6a254e..c4894f6a254e 100644
--- a/drivers/media/platform/ti/davinci/dm644x_ccdc_regs.h
+++ b/drivers/staging/media/deprecated/vpfe_capture/dm644x_ccdc_regs.h
diff --git a/drivers/media/platform/ti/davinci/isif.c b/drivers/staging/media/deprecated/vpfe_capture/isif.c
index 69e862de014f..4059891c2824 100644
--- a/drivers/media/platform/ti/davinci/isif.c
+++ b/drivers/staging/media/deprecated/vpfe_capture/isif.c
@@ -22,7 +22,7 @@
#include <linux/err.h>
#include <linux/module.h>
-#include <media/davinci/isif.h>
+#include "isif.h"
#include <media/davinci/vpss.h>
#include "isif_regs.h"
diff --git a/include/media/davinci/isif.h b/drivers/staging/media/deprecated/vpfe_capture/isif.h
index 8369acd26e7e..8369acd26e7e 100644
--- a/include/media/davinci/isif.h
+++ b/drivers/staging/media/deprecated/vpfe_capture/isif.h
diff --git a/drivers/media/platform/ti/davinci/isif_regs.h b/drivers/staging/media/deprecated/vpfe_capture/isif_regs.h
index d68d38841ae7..d68d38841ae7 100644
--- a/drivers/media/platform/ti/davinci/isif_regs.h
+++ b/drivers/staging/media/deprecated/vpfe_capture/isif_regs.h
diff --git a/drivers/media/platform/ti/davinci/vpfe_capture.c b/drivers/staging/media/deprecated/vpfe_capture/vpfe_capture.c
index 0a2226b321d7..0a2226b321d7 100644
--- a/drivers/media/platform/ti/davinci/vpfe_capture.c
+++ b/drivers/staging/media/deprecated/vpfe_capture/vpfe_capture.c
diff --git a/drivers/media/usb/zr364xx/Kconfig b/drivers/staging/media/deprecated/zr364xx/Kconfig
index a9fb02566c4b..ea29c9d8dca2 100644
--- a/drivers/media/usb/zr364xx/Kconfig
+++ b/drivers/staging/media/deprecated/zr364xx/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config USB_ZR364XX
- tristate "USB ZR364XX Camera support"
- depends on VIDEO_DEV
+ tristate "USB ZR364XX Camera support (DEPRECATED)"
+ depends on USB && VIDEO_DEV
select VIDEOBUF_GEN
select VIDEOBUF_VMALLOC
help
@@ -10,6 +10,9 @@ config USB_ZR364XX
See <file:Documentation/admin-guide/media/zr364xx.rst> for more info
and list of supported cameras.
+ This driver is deprecated and is scheduled for removal by
+ the beginning of 2023. See the TODO file for more information.
+
To compile this driver as a module, choose M here: the
module will be called zr364xx.
diff --git a/drivers/media/usb/zr364xx/Makefile b/drivers/staging/media/deprecated/zr364xx/Makefile
index edab017d499c..edab017d499c 100644
--- a/drivers/media/usb/zr364xx/Makefile
+++ b/drivers/staging/media/deprecated/zr364xx/Makefile
diff --git a/drivers/staging/media/deprecated/zr364xx/TODO b/drivers/staging/media/deprecated/zr364xx/TODO
new file mode 100644
index 000000000000..ecb30a429689
--- /dev/null
+++ b/drivers/staging/media/deprecated/zr364xx/TODO
@@ -0,0 +1,7 @@
+This is one of the few drivers still not using the vb2
+framework, so this driver is now deprecated with the intent of
+removing it altogether by the beginning of 2023.
+
+In order to keep this driver it has to be converted to vb2.
+If someone is interested in doing this work, then contact the
+linux-media mailinglist (https://linuxtv.org/lists.php).
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/staging/media/deprecated/zr364xx/zr364xx.c
index 538a330046ec..538a330046ec 100644
--- a/drivers/media/usb/zr364xx/zr364xx.c
+++ b/drivers/staging/media/deprecated/zr364xx/zr364xx.c
diff --git a/drivers/staging/media/hantro/TODO b/drivers/staging/media/hantro/TODO
deleted file mode 100644
index 8483ff482146..000000000000
--- a/drivers/staging/media/hantro/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-The V4L controls for the HEVC CODEC are not yet part of the stable uABI,
-we are keeping this driver in staging until the HEVC uABI has been merged.
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index a0553c24cce4..cbc66ef0eda8 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -160,7 +160,7 @@
#define IMX7_CSI_VIDEO_NAME "imx-capture"
/* In bytes, per queue */
-#define IMX7_CSI_VIDEO_MEM_LIMIT SZ_64M
+#define IMX7_CSI_VIDEO_MEM_LIMIT SZ_512M
#define IMX7_CSI_VIDEO_EOF_TIMEOUT 2000
#define IMX7_CSI_DEF_MBUS_CODE MEDIA_BUS_FMT_UYVY8_2X8
diff --git a/drivers/staging/media/meson/vdec/vdec_hevc.c b/drivers/staging/media/meson/vdec/vdec_hevc.c
index 9530e580e57a..afced435c907 100644
--- a/drivers/staging/media/meson/vdec/vdec_hevc.c
+++ b/drivers/staging/media/meson/vdec/vdec_hevc.c
@@ -167,8 +167,12 @@ static int vdec_hevc_start(struct amvdec_session *sess)
clk_set_rate(core->vdec_hevc_clk, 666666666);
ret = clk_prepare_enable(core->vdec_hevc_clk);
- if (ret)
+ if (ret) {
+ if (core->platform->revision == VDEC_REVISION_G12A ||
+ core->platform->revision == VDEC_REVISION_SM1)
+ clk_disable_unprepare(core->vdec_hevcf_clk);
return ret;
+ }
if (core->platform->revision == VDEC_REVISION_SM1)
regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 9512cd3314f2..842509dcfedf 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -843,7 +843,7 @@ iss_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
* processing might be possible but requires more testing.
*
* Stream start must be delayed until buffers are available at both the input
- * and output. The pipeline must be started in the videobuf queue callback with
+ * and output. The pipeline must be started in the vb2 queue callback with
* the buffers queue spinlock held. The modules subdev set stream operation must
* not sleep.
*/
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 960a0130cd62..55c54dfdc585 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -448,6 +448,8 @@ static int cedrus_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
+ platform_set_drvdata(pdev, dev);
+
dev->vfd = cedrus_video_device;
dev->dev = &pdev->dev;
dev->pdev = pdev;
@@ -521,8 +523,6 @@ static int cedrus_probe(struct platform_device *pdev)
goto err_m2m_mc;
}
- platform_set_drvdata(pdev, dev);
-
return 0;
err_m2m_mc:
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
index 084193019350..93a2196006f7 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
@@ -237,19 +237,23 @@ static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
}
static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
- int index, unsigned int plane)
+ struct vb2_buffer *buf,
+ unsigned int plane)
{
- struct vb2_buffer *buf = NULL;
- struct vb2_queue *vq;
-
- if (index < 0)
- return 0;
+ return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
+}
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (vq)
- buf = vb2_get_buffer(vq, index);
+static inline void cedrus_write_ref_buf_addr(struct cedrus_ctx *ctx,
+ struct vb2_queue *q,
+ u64 timestamp,
+ u32 luma_reg,
+ u32 chroma_reg)
+{
+ struct cedrus_dev *dev = ctx->dev;
+ struct vb2_buffer *buf = vb2_find_buffer(q, timestamp);
- return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
+ cedrus_write(dev, luma_reg, cedrus_dst_buf_addr(ctx, buf, 0));
+ cedrus_write(dev, chroma_reg, cedrus_dst_buf_addr(ctx, buf, 1));
}
static inline struct cedrus_buffer *
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index 3b6aa78a2985..e7f7602a5ab4 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -106,11 +106,11 @@ void cedrus_device_run(void *priv)
/* Trigger decoding if setup went well, bail out otherwise. */
if (!error) {
- dev->dec_ops[ctx->current_codec]->trigger(ctx);
-
/* Start the watchdog timer. */
schedule_delayed_work(&dev->watchdog_work,
msecs_to_jiffies(2000));
+
+ dev->dec_ops[ctx->current_codec]->trigger(ctx);
} else {
v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
ctx->fh.m2m_ctx,
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
index c345e67ba9bc..a8b236cd3800 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
@@ -111,16 +111,16 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
for (i = 0; i < ARRAY_SIZE(decode->dpb); i++) {
const struct v4l2_h264_dpb_entry *dpb = &decode->dpb[i];
struct cedrus_buffer *cedrus_buf;
- int buf_idx;
+ struct vb2_buffer *buf;
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
continue;
- buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
- if (buf_idx < 0)
+ buf = vb2_find_buffer(cap_q, dpb->reference_ts);
+ if (!buf)
continue;
- cedrus_buf = vb2_to_cedrus_buffer(cap_q->bufs[buf_idx]);
+ cedrus_buf = vb2_to_cedrus_buffer(buf);
position = cedrus_buf->codec.h264.position;
used_dpbs |= BIT(position);
@@ -186,7 +186,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
const struct v4l2_h264_dpb_entry *dpb;
const struct cedrus_buffer *cedrus_buf;
unsigned int position;
- int buf_idx;
+ struct vb2_buffer *buf;
u8 dpb_idx;
dpb_idx = ref_list[i].index;
@@ -195,11 +195,11 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
continue;
- buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
- if (buf_idx < 0)
+ buf = vb2_find_buffer(cap_q, dpb->reference_ts);
+ if (!buf)
continue;
- cedrus_buf = vb2_to_cedrus_buffer(cap_q->bufs[buf_idx]);
+ cedrus_buf = vb2_to_cedrus_buffer(buf);
position = cedrus_buf->codec.h264.position;
sram_array[i] |= position << 1;
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index 687f87598f78..4952fc17f3e6 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -102,14 +102,14 @@ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
unsigned int index,
bool field_pic,
u32 pic_order_cnt[],
- int buffer_index)
+ struct vb2_buffer *buf)
{
struct cedrus_dev *dev = ctx->dev;
- dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 0);
- dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 1);
+ dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buf, 0);
+ dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buf, 1);
dma_addr_t mv_col_buf_addr[2] = {
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, 0),
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index,
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, 0),
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index,
field_pic ? 1 : 0)
};
u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
@@ -141,18 +141,18 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
unsigned int i;
for (i = 0; i < num_active_dpb_entries; i++) {
- int buffer_index = vb2_find_timestamp(vq, dpb[i].timestamp, 0);
+ struct vb2_buffer *buf = vb2_find_buffer(vq, dpb[i].timestamp);
u32 pic_order_cnt[2] = {
dpb[i].pic_order_cnt_val,
dpb[i].pic_order_cnt_val
};
- if (buffer_index < 0)
+ if (!buf)
continue;
cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
pic_order_cnt,
- buffer_index);
+ buf);
}
}
@@ -234,8 +234,9 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
cedrus_write(dev, VE_DEC_H265_TRIGGER,
VE_DEC_H265_TRIGGER_FLUSH_BITS |
VE_DEC_H265_TRIGGER_TYPE_N_BITS(tmp));
- while (cedrus_read(dev, VE_DEC_H265_STATUS) & VE_DEC_H265_STATUS_VLD_BUSY)
- udelay(1);
+
+ if (cedrus_wait_for(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_VLD_BUSY))
+ dev_err_ratelimited(dev->dev, "timed out waiting to skip bits\n");
count += tmp;
}
@@ -751,7 +752,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
cedrus_h265_frame_info_write_single(ctx, output_pic_list_index,
slice_params->pic_struct != 0,
pic_order_cnt,
- run->dst->vb2_buf.index);
+ &run->dst->vb2_buf);
cedrus_write(dev, VE_DEC_H265_OUTPUT_FRAME_IDX, output_pic_list_index);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
index 4cfc4a3c8a7f..c1128d2cd555 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
@@ -54,13 +54,9 @@ static int cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
const struct v4l2_ctrl_mpeg2_picture *pic;
const struct v4l2_ctrl_mpeg2_quantisation *quantisation;
dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr;
- dma_addr_t fwd_luma_addr, fwd_chroma_addr;
- dma_addr_t bwd_luma_addr, bwd_chroma_addr;
struct cedrus_dev *dev = ctx->dev;
struct vb2_queue *vq;
const u8 *matrix;
- int forward_idx;
- int backward_idx;
unsigned int i;
u32 reg;
@@ -123,27 +119,19 @@ static int cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
cedrus_write(dev, VE_DEC_MPEG_PICBOUNDSIZE, reg);
/* Forward and backward prediction reference buffers. */
-
vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- forward_idx = vb2_find_timestamp(vq, pic->forward_ref_ts, 0);
- fwd_luma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 0);
- fwd_chroma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 1);
-
- cedrus_write(dev, VE_DEC_MPEG_FWD_REF_LUMA_ADDR, fwd_luma_addr);
- cedrus_write(dev, VE_DEC_MPEG_FWD_REF_CHROMA_ADDR, fwd_chroma_addr);
-
- backward_idx = vb2_find_timestamp(vq, pic->backward_ref_ts, 0);
- bwd_luma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 0);
- bwd_chroma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 1);
-
- cedrus_write(dev, VE_DEC_MPEG_BWD_REF_LUMA_ADDR, bwd_luma_addr);
- cedrus_write(dev, VE_DEC_MPEG_BWD_REF_CHROMA_ADDR, bwd_chroma_addr);
+ cedrus_write_ref_buf_addr(ctx, vq, pic->forward_ref_ts,
+ VE_DEC_MPEG_FWD_REF_LUMA_ADDR,
+ VE_DEC_MPEG_FWD_REF_CHROMA_ADDR);
+ cedrus_write_ref_buf_addr(ctx, vq, pic->backward_ref_ts,
+ VE_DEC_MPEG_BWD_REF_LUMA_ADDR,
+ VE_DEC_MPEG_BWD_REF_CHROMA_ADDR);
/* Destination luma and chroma buffers. */
- dst_luma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 0);
- dst_chroma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 1);
+ dst_luma_addr = cedrus_dst_buf_addr(ctx, &run->dst->vb2_buf, 0);
+ dst_chroma_addr = cedrus_dst_buf_addr(ctx, &run->dst->vb2_buf, 1);
cedrus_write(dev, VE_DEC_MPEG_REC_LUMA, dst_luma_addr);
cedrus_write(dev, VE_DEC_MPEG_REC_CHROMA, dst_chroma_addr);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c b/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c
index 3f750d1795b6..f7714baae37d 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c
@@ -660,7 +660,6 @@ static int cedrus_vp8_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
dma_addr_t luma_addr, chroma_addr;
dma_addr_t src_buf_addr;
int header_size;
- int qindex;
u32 reg;
cedrus_engine_enable(ctx, CEDRUS_CODEC_VP8);
@@ -804,43 +803,17 @@ static int cedrus_vp8_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
reg |= VE_VP8_LF_DELTA0(slice->lf.mb_mode_delta[0]);
cedrus_write(dev, VE_VP8_MODE_LF_DELTA, reg);
- luma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 0);
- chroma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 1);
+ luma_addr = cedrus_dst_buf_addr(ctx, &run->dst->vb2_buf, 0);
+ chroma_addr = cedrus_dst_buf_addr(ctx, &run->dst->vb2_buf, 1);
cedrus_write(dev, VE_VP8_REC_LUMA, luma_addr);
cedrus_write(dev, VE_VP8_REC_CHROMA, chroma_addr);
- qindex = vb2_find_timestamp(cap_q, slice->last_frame_ts, 0);
- if (qindex >= 0) {
- luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0);
- chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1);
- cedrus_write(dev, VE_VP8_FWD_LUMA, luma_addr);
- cedrus_write(dev, VE_VP8_FWD_CHROMA, chroma_addr);
- } else {
- cedrus_write(dev, VE_VP8_FWD_LUMA, 0);
- cedrus_write(dev, VE_VP8_FWD_CHROMA, 0);
- }
-
- qindex = vb2_find_timestamp(cap_q, slice->golden_frame_ts, 0);
- if (qindex >= 0) {
- luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0);
- chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1);
- cedrus_write(dev, VE_VP8_BWD_LUMA, luma_addr);
- cedrus_write(dev, VE_VP8_BWD_CHROMA, chroma_addr);
- } else {
- cedrus_write(dev, VE_VP8_BWD_LUMA, 0);
- cedrus_write(dev, VE_VP8_BWD_CHROMA, 0);
- }
-
- qindex = vb2_find_timestamp(cap_q, slice->alt_frame_ts, 0);
- if (qindex >= 0) {
- luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0);
- chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1);
- cedrus_write(dev, VE_VP8_ALT_LUMA, luma_addr);
- cedrus_write(dev, VE_VP8_ALT_CHROMA, chroma_addr);
- } else {
- cedrus_write(dev, VE_VP8_ALT_LUMA, 0);
- cedrus_write(dev, VE_VP8_ALT_CHROMA, 0);
- }
+ cedrus_write_ref_buf_addr(ctx, cap_q, slice->last_frame_ts,
+ VE_VP8_FWD_LUMA, VE_VP8_FWD_CHROMA);
+ cedrus_write_ref_buf_addr(ctx, cap_q, slice->golden_frame_ts,
+ VE_VP8_BWD_LUMA, VE_VP8_BWD_CHROMA);
+ cedrus_write_ref_buf_addr(ctx, cap_q, slice->alt_frame_ts,
+ VE_VP8_ALT_LUMA, VE_VP8_ALT_CHROMA);
cedrus_write(dev, VE_H264_CTRL, VE_H264_CTRL_VP8 |
VE_H264_CTRL_DECODE_ERR_INT |
diff --git a/drivers/staging/media/zoran/TODO b/drivers/staging/media/zoran/TODO
deleted file mode 100644
index 6992540d3e53..000000000000
--- a/drivers/staging/media/zoran/TODO
+++ /dev/null
@@ -1,19 +0,0 @@
-
-How to test the zoran driver:
-- RAW capture
- mplayer tv:///dev/video0 -tv driver=v4l2
-
-- MJPEG capture (compression)
- mplayer tv:///dev/video0 -tv driver=v4l2:outfmt=mjpeg
- TODO: need two test for both Dcim path
-
-- MJPEG play (decompression)
- ffmpeg -i test.avi -vcodec mjpeg -an -f v4l2 /dev/video0
- Note: only recent ffmpeg has the ability of sending non-raw video via v4l2
-
- The original way of sending video was via mplayer vo_zr/vo_zr2, but it does not compile
- anymore and is a dead end (usage of some old private ffmpeg structures).
-
-TODO
-- fix the v4l compliance "TRY_FMT cannot handle an invalid pixelformat"
-- Filter JPEG data to made output work
diff --git a/drivers/staging/media/zoran/zoran_device.h b/drivers/staging/media/zoran/zoran_device.h
deleted file mode 100644
index 322b04c55d41..000000000000
--- a/drivers/staging/media/zoran/zoran_device.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Zoran zr36057/zr36067 PCI controller driver, for the
- * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
- * Media Labs LML33/LML33R10.
- *
- * This part handles card-specific data and detection
- *
- * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
- */
-
-#ifndef __ZORAN_DEVICE_H__
-#define __ZORAN_DEVICE_H__
-
-/* general purpose I/O */
-extern void GPIO(struct zoran *zr, int bit, unsigned int value);
-
-/* codec (or actually: guest bus) access */
-extern int post_office_wait(struct zoran *zr);
-extern int post_office_write(struct zoran *zr, unsigned int guest, unsigned int reg, unsigned int value);
-extern int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg);
-
-extern void jpeg_codec_sleep(struct zoran *zr, int sleep);
-extern int jpeg_codec_reset(struct zoran *zr);
-
-/* zr360x7 access to raw capture */
-extern void zr36057_overlay(struct zoran *zr, int on);
-extern void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count);
-extern void zr36057_set_memgrab(struct zoran *zr, int mode);
-extern int wait_grab_pending(struct zoran *zr);
-
-/* interrupts */
-extern void print_interrupts(struct zoran *zr);
-extern void clear_interrupt_counters(struct zoran *zr);
-extern irqreturn_t zoran_irq(int irq, void *dev_id);
-
-/* JPEG codec access */
-extern void jpeg_start(struct zoran *zr);
-extern void zr36057_enable_jpg(struct zoran *zr,
- enum zoran_codec_mode mode);
-extern void zoran_feed_stat_com(struct zoran *zr);
-
-/* general */
-extern void zoran_set_pci_master(struct zoran *zr, int set_master);
-extern void zoran_init_hardware(struct zoran *zr);
-extern void zr36057_restart(struct zoran *zr);
-
-extern const struct zoran_format zoran_formats[];
-
-extern int v4l_bufsize;
-extern int jpg_bufsize;
-extern int pass_through;
-
-/* i2c */
-#define decoder_call(zr, o, f, args...) \
- v4l2_subdev_call(zr->decoder, o, f, ##args)
-#define encoder_call(zr, o, f, args...) \
- v4l2_subdev_call(zr->encoder, o, f, ##args)
-
-#endif /* __ZORAN_DEVICE_H__ */
diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h
index 6d2a93740130..d8751ea926a2 100644
--- a/include/media/davinci/vpbe_display.h
+++ b/include/media/davinci/vpbe_display.h
@@ -69,13 +69,13 @@ struct vpbe_layer {
struct vpbe_disp_buffer *cur_frm;
/* Pointer pointing to next v4l2_buffer */
struct vpbe_disp_buffer *next_frm;
- /* videobuf specific parameters
- * Buffer queue used in video-buf
+ /* vb2 specific parameters
+ * Buffer queue used in vb2
*/
struct vb2_queue buffer_queue;
/* Queue of filled frames */
struct list_head dma_queue;
- /* Used in video-buf */
+ /* Used for video buffer handling */
spinlock_t irqlock;
/* V4l2 specific parameters */
/* Identifies video device for this layer */
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 00828a4f9404..b76a0714d425 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -128,13 +128,13 @@ struct v4l2_ctrl_ops {
* otherwise.
*/
struct v4l2_ctrl_type_ops {
- bool (*equal)(const struct v4l2_ctrl *ctrl, u32 idx,
+ bool (*equal)(const struct v4l2_ctrl *ctrl, u32 elems,
union v4l2_ctrl_ptr ptr1,
union v4l2_ctrl_ptr ptr2);
- void (*init)(const struct v4l2_ctrl *ctrl, u32 idx,
+ void (*init)(const struct v4l2_ctrl *ctrl, u32 from_idx, u32 tot_elems,
union v4l2_ctrl_ptr ptr);
void (*log)(const struct v4l2_ctrl *ctrl);
- int (*validate)(const struct v4l2_ctrl *ctrl, u32 idx,
+ int (*validate)(const struct v4l2_ctrl *ctrl, u32 elems,
union v4l2_ctrl_ptr ptr);
};
@@ -203,7 +203,7 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
* @elem_size: The size in bytes of the control.
* @new_elems: The number of elements in p_new. This is the same as @elems,
* except for dynamic arrays. In that case it is in the range of
- * 1 to @p_dyn_alloc_elems.
+ * 1 to @p_array_alloc_elems.
* @dims: The size of each dimension.
* @nr_of_dims:The number of dimensions in @dims.
* @menu_skip_mask: The control's skip mask for menu controls. This makes it
@@ -227,12 +227,11 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
* not freed when the control is deleted. Should this be needed
* then a new internal bitfield can be added to tell the framework
* to free this pointer.
- * @p_dyn: Pointer to the dynamically allocated array. Only valid if
- * @is_dyn_array is true.
- * @p_dyn_alloc_elems: The number of elements in the dynamically allocated
- * array for both the cur and new values. So @p_dyn is actually
- * sized for 2 * @p_dyn_alloc_elems * @elem_size. Only valid if
- * @is_dyn_array is true.
+ * @p_array: Pointer to the allocated array. Only valid if @is_array is true.
+ * @p_array_alloc_elems: The number of elements in the allocated
+ * array for both the cur and new values. So @p_array is actually
+ * sized for 2 * @p_array_alloc_elems * @elem_size. Only valid if
+ * @is_array is true.
* @cur: Structure to store the current value.
* @cur.val: The control's current value, if the @type is represented via
* a u32 integer (see &enum v4l2_ctrl_type).
@@ -291,8 +290,8 @@ struct v4l2_ctrl {
};
unsigned long flags;
void *priv;
- void *p_dyn;
- u32 p_dyn_alloc_elems;
+ void *p_array;
+ u32 p_array_alloc_elems;
s32 val;
struct {
s32 val;
@@ -319,15 +318,15 @@ struct v4l2_ctrl {
* from a cluster with multiple controls twice (when the first
* control of a cluster is applied, they all are).
* @p_req_valid: If set, then p_req contains the control value for the request.
- * @p_req_dyn_enomem: If set, then p_req is invalid since allocating space for
- * a dynamic array failed. Attempting to read this value shall
- * result in ENOMEM. Only valid if ctrl->is_dyn_array is true.
- * @p_req_dyn_alloc_elems: The number of elements allocated for the dynamic
- * array. Only valid if @p_req_valid and ctrl->is_dyn_array are
+ * @p_req_array_enomem: If set, then p_req is invalid since allocating space for
+ * an array failed. Attempting to read this value shall
+ * result in ENOMEM. Only valid if ctrl->is_array is true.
+ * @p_req_array_alloc_elems: The number of elements allocated for the
+ * array. Only valid if @p_req_valid and ctrl->is_array are
* true.
* @p_req_elems: The number of elements in @p_req. This is the same as
* ctrl->elems, except for dynamic arrays. In that case it is in
- * the range of 1 to @p_req_dyn_alloc_elems. Only valid if
+ * the range of 1 to @p_req_array_alloc_elems. Only valid if
* @p_req_valid is true.
* @p_req: If the control handler containing this control reference
* is bound to a media request, then this points to the
@@ -349,8 +348,8 @@ struct v4l2_ctrl_ref {
bool from_other_dev;
bool req_done;
bool p_req_valid;
- bool p_req_dyn_enomem;
- u32 p_req_dyn_alloc_elems;
+ bool p_req_array_enomem;
+ u32 p_req_array_alloc_elems;
u32 p_req_elems;
union v4l2_ctrl_ptr p_req;
};
@@ -959,6 +958,59 @@ static inline int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
}
/**
+ *__v4l2_ctrl_modify_dimensions() - Unlocked variant of v4l2_ctrl_modify_dimensions()
+ *
+ * @ctrl: The control to update.
+ * @dims: The control's new dimensions.
+ *
+ * Update the dimensions of an array control on the fly. The elements of the
+ * array are reset to their default value, even if the dimensions are
+ * unchanged.
+ *
+ * An error is returned if @dims is invalid for this control.
+ *
+ * The caller is responsible for acquiring the control handler mutex on behalf
+ * of __v4l2_ctrl_modify_dimensions().
+ *
+ * Note: calling this function when the same control is used in pending requests
+ * is untested. It should work (a request with the wrong size of the control
+ * will drop that control silently), but it will be very confusing.
+ */
+int __v4l2_ctrl_modify_dimensions(struct v4l2_ctrl *ctrl,
+ u32 dims[V4L2_CTRL_MAX_DIMS]);
+
+/**
+ * v4l2_ctrl_modify_dimensions() - Update the dimensions of an array control.
+ *
+ * @ctrl: The control to update.
+ * @dims: The control's new dimensions.
+ *
+ * Update the dimensions of an array control on the fly. The elements of the
+ * array are reset to their default value, even if the dimensions are
+ * unchanged.
+ *
+ * An error is returned if @dims is invalid for this control type.
+ *
+ * This function assumes that the control handler is not locked and will
+ * take the lock itself.
+ *
+ * Note: calling this function when the same control is used in pending requests
+ * is untested. It should work (a request with the wrong size of the control
+ * will drop that control silently), but it will be very confusing.
+ */
+static inline int v4l2_ctrl_modify_dimensions(struct v4l2_ctrl *ctrl,
+ u32 dims[V4L2_CTRL_MAX_DIMS])
+{
+ int rval;
+
+ v4l2_ctrl_lock(ctrl);
+ rval = __v4l2_ctrl_modify_dimensions(ctrl, dims);
+ v4l2_ctrl_unlock(ctrl);
+
+ return rval;
+}
+
+/**
* v4l2_ctrl_notify() - Function to set a notify callback for a control.
*
* @ctrl: The control.
@@ -1486,4 +1538,52 @@ int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd);
int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ctrl_ops,
const struct v4l2_fwnode_device_properties *p);
+
+/**
+ * v4l2_ctrl_type_op_equal - Default v4l2_ctrl_type_ops equal callback.
+ *
+ * @ctrl: The v4l2_ctrl pointer.
+ * @elems: The number of elements to compare.
+ * @ptr1: A v4l2 control value.
+ * @ptr2: A v4l2 control value.
+ *
+ * Return: true if values are equal, otherwise false.
+ */
+bool v4l2_ctrl_type_op_equal(const struct v4l2_ctrl *ctrl, u32 elems,
+ union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2);
+
+/**
+ * v4l2_ctrl_type_op_init - Default v4l2_ctrl_type_ops init callback.
+ *
+ * @ctrl: The v4l2_ctrl pointer.
+ * @from_idx: Starting element index.
+ * @elems: The number of elements to initialize.
+ * @ptr: The v4l2 control value.
+ *
+ * Return: void
+ */
+void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx,
+ u32 elems, union v4l2_ctrl_ptr ptr);
+
+/**
+ * v4l2_ctrl_type_op_log - Default v4l2_ctrl_type_ops log callback.
+ *
+ * @ctrl: The v4l2_ctrl pointer.
+ *
+ * Return: void
+ */
+void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl);
+
+/**
+ * v4l2_ctrl_type_op_validate - Default v4l2_ctrl_type_ops validate callback.
+ *
+ * @ctrl: The v4l2_ctrl pointer.
+ * @elems: The number of elements in the control.
+ * @ptr: The v4l2 control value.
+ *
+ * Return: 0 on success, a negative error code on failure.
+ */
+int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, u32 elems,
+ union v4l2_ctrl_ptr ptr);
+
#endif
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index fdbd5257e020..bb9de6a899e0 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -486,10 +486,10 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
* @vma: pointer to struct &vm_area_struct
*
* Call from driver's mmap() function. Will handle mmap() for both queues
- * seamlessly for videobuffer, which will receive normal per-queue offsets and
- * proper videobuf queue pointers. The differentiation is made outside videobuf
- * by adding a predefined offset to buffers from one of the queues and
- * subtracting it before passing it back to videobuf. Only drivers (and
+ * seamlessly for the video buffer, which will receive normal per-queue offsets
+ * and proper vb2 queue pointers. The differentiation is made outside
+ * vb2 by adding a predefined offset to buffers from one of the queues
+ * and subtracting it before passing it back to vb2. Only drivers (and
* thus applications) receive modified offsets.
*/
int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
@@ -544,7 +544,7 @@ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev);
* @m2m_dev: opaque pointer to the internal data to handle M2M context
* @drv_priv: driver's instance private data
* @queue_init: a callback for queue type-specific initialization function
- * to be used for initializing videobuf_queues
+ * to be used for initializing vb2_queues
*
* Usually called from driver's ``open()`` function.
*/
@@ -579,7 +579,7 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx);
* @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
* @vbuf: pointer to struct &vb2_v4l2_buffer
*
- * Call from videobuf_queue_ops->ops->buf_queue, videobuf_queue_ops callback.
+ * Call from vb2_queue_ops->ops->buf_queue, vb2_queue_ops callback.
*/
void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
struct vb2_v4l2_buffer *vbuf);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 5468b633b9d2..3253bd2f6fee 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -65,7 +65,7 @@ struct vb2_buffer;
* DMABUF memory types.
* @get_userptr: acquire userspace memory for a hardware operation; used for
* USERPTR memory types; vaddr is the address passed to the
- * videobuf layer when queuing a video buffer of USERPTR type;
+ * videobuf2 layer when queuing a video buffer of USERPTR type;
* should return an allocator private per-buffer structure
* associated with the buffer on success, ERR_PTR() on failure;
* the returned private structure will then be passed as @buf_priv
@@ -97,7 +97,7 @@ struct vb2_buffer;
* associated with the passed private structure or NULL if not
* available.
* @num_users: return the current number of users of a memory buffer;
- * return 1 if the videobuf layer (or actually the driver using
+ * return 1 if the videobuf2 layer (or actually the driver using
* it) is the only user.
* @mmap: setup a userspace mapping for a given memory buffer under
* the provided virtual memory region.
@@ -210,11 +210,11 @@ enum vb2_io_modes {
* enum vb2_buffer_state - current video buffer state.
* @VB2_BUF_STATE_DEQUEUED: buffer under userspace control.
* @VB2_BUF_STATE_IN_REQUEST: buffer is queued in media request.
- * @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf.
- * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver.
+ * @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf2.
+ * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf2, but not in driver.
* @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used
* in a hardware operation.
- * @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but
+ * @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf2, but
* not yet dequeued to userspace.
* @VB2_BUF_STATE_ERROR: same as above, but the operation on the buffer
* has ended with an error, which will be reported
@@ -466,7 +466,7 @@ struct vb2_buf_ops {
};
/**
- * struct vb2_queue - a videobuf queue.
+ * struct vb2_queue - a videobuf2 queue.
*
* @type: private buffer type whose content is defined by the vb2-core
* caller. For example, for V4L2, it should match
@@ -544,7 +544,7 @@ struct vb2_buf_ops {
* @mmap_lock: private mutex used when buffers are allocated/freed/mmapped
* @memory: current memory type used
* @dma_dir: DMA mapping direction.
- * @bufs: videobuf buffer structures
+ * @bufs: videobuf2 buffer structures
* @num_buffers: number of allocated/used buffers
* @queued_list: list of buffers currently queued from userspace
* @queued_count: number of buffers queued and ready for streaming.
@@ -683,7 +683,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
/**
- * vb2_buffer_done() - inform videobuf that an operation on a buffer
+ * vb2_buffer_done() - inform videobuf2 that an operation on a buffer
* is finished.
* @vb: pointer to &struct vb2_buffer to be used.
* @state: state of the buffer, as defined by &enum vb2_buffer_state.
diff --git a/include/media/videobuf2-dvb.h b/include/media/videobuf2-dvb.h
index 8605366ec87c..2d577b945637 100644
--- a/include/media/videobuf2-dvb.h
+++ b/include/media/videobuf2-dvb.h
@@ -24,7 +24,7 @@ struct vb2_dvb {
struct dvb_frontend *frontend;
struct vb2_queue dvbq;
- /* video-buf-dvb state info */
+ /* vb2-dvb state info */
struct mutex lock;
int nfeeds;
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 76e405c0b003..5a845887850b 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -63,22 +63,6 @@ struct vb2_v4l2_buffer {
container_of(vb, struct vb2_v4l2_buffer, vb2_buf)
/**
- * vb2_find_timestamp() - Find buffer with given timestamp in the queue
- *
- * @q: pointer to &struct vb2_queue with videobuf2 queue.
- * @timestamp: the timestamp to find.
- * @start_idx: the start index (usually 0) in the buffer array to start
- * searching from. Note that there may be multiple buffers
- * with the same timestamp value, so you can restart the search
- * by setting @start_idx to the previously found index + 1.
- *
- * Returns the buffer index of the buffer with the given @timestamp, or
- * -1 if no buffer with @timestamp was found.
- */
-int vb2_find_timestamp(const struct vb2_queue *q, u64 timestamp,
- unsigned int start_idx);
-
-/**
* vb2_find_buffer() - Find a buffer with given timestamp
*
* @q: pointer to &struct vb2_queue with videobuf2 queue.
diff --git a/include/uapi/linux/dw100.h b/include/uapi/linux/dw100.h
new file mode 100644
index 000000000000..3356496edd6b
--- /dev/null
+++ b/include/uapi/linux/dw100.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+/* Copyright 2022 NXP */
+
+#ifndef __UAPI_DW100_H__
+#define __UAPI_DW100_H__
+
+#include <linux/v4l2-controls.h>
+
+/*
+ * Check Documentation/userspace-api/media/drivers/dw100.rst for control details.
+ */
+#define V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP (V4L2_CID_USER_DW100_BASE + 1)
+
+#endif
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 5f46bf4a570c..b5e7d082b8ad 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -225,6 +225,12 @@ enum v4l2_colorfx {
*/
#define V4L2_CID_USER_ISL7998X_BASE (V4L2_CID_USER_BASE + 0x1180)
+/*
+ * The base for DW100 driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_DW100_BASE (V4L2_CID_USER_BASE + 0x1190)
+
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
* and the 'MPEG' part of the define is historical */
@@ -1730,7 +1736,7 @@ struct v4l2_vp8_segment {
* @sharpness_level: matches sharpness_level syntax element.
* @level: matches loop_filter_level syntax element.
* @padding: padding field. Should be zeroed by applications.
- * @flags: see V4L2_VP8_LF_FLAG_{}.
+ * @flags: see V4L2_VP8_LF_{}.
*
* This structure contains loop filter related parameters.
* See the 'mb_lf_adjustments()' part of the frame header syntax,
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 01e630f2ec78..86cae23cc446 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -502,7 +502,6 @@ struct v4l2_capability {
#define V4L2_CAP_META_CAPTURE 0x00800000 /* Is a metadata capture device */
#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
-#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
#define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */
@@ -2435,6 +2434,7 @@ struct v4l2_event_vsync {
#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0)
#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1)
#define V4L2_EVENT_CTRL_CH_RANGE (1 << 2)
+#define V4L2_EVENT_CTRL_CH_DIMENSIONS (1 << 3)
struct v4l2_event_ctrl {
__u32 changes;
@@ -2682,6 +2682,11 @@ struct v4l2_create_buffers {
#ifndef __KERNEL__
#define V4L2_PIX_FMT_HM12 V4L2_PIX_FMT_NV12_16L16
#define V4L2_PIX_FMT_SUNXI_TILED_NV12 V4L2_PIX_FMT_NV12_32L32
+/*
+ * This capability was never implemented, anyone using this cap should drop it
+ * from their code.
+ */
+#define V4L2_CAP_ASYNCIO 0x02000000
#endif
#endif /* _UAPI__LINUX_VIDEODEV2_H */