aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds2022-01-10 18:55:43 -0800
committerLinus Torvalds2022-01-10 18:55:43 -0800
commit9bcbf894b6872216ef61faf17248ec234e3db6bc (patch)
treeb1a8fd7c99a3913a9a4ef4019ca879455e22f9e9
parent75b950ef6166e4ef52e43e7ec80985c5705f7e81 (diff)
parent68b9bcc8a534cd11fe55f8bc82f948aae7d81b3c (diff)
Merge tag 'media/v5.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - New sensor driver: ov5693 - A new driver for STM32 Chrom-ART Accelerator - Added V4L2 core helper functions for VP9 codec - Hantro driver has gained support for VP9 codecs - Added support for Maxim MAX96712 Quad GMSL2 Deserializer - The staging atomisp driver has gained lots of improvements, fixes and cleanups. It now works with userptr - Lots of random driver improvements as usual * tag 'media/v5.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (397 commits) media: ipu3-cio2: Add support for instantiating i2c-clients for VCMs media: ipu3-cio2: Call cio2_bridge_init() before anything else media: ipu3-cio2: Defer probing until the PMIC is fully setup media: hantro: Add support for Allwinner H6 media: dt-bindings: allwinner: document H6 Hantro G2 binding media: hantro: Convert imx8m_vpu_g2_irq to helper media: hantro: move postproc enablement for old cores media: hantro: vp9: add support for legacy register set media: hantro: vp9: use double buffering if needed media: hantro: add support for reset lines media: hantro: Fix probe func error path media: i2c: hi846: use pm_runtime_force_suspend/resume for system suspend media: i2c: hi846: check return value of regulator_bulk_disable() media: hi556: Support device probe in non-zero ACPI D state media: ov5675: Support device probe in non-zero ACPI D state media: imx208: Support device probe in non-zero ACPI D state media: ov2740: support device probe in non-zero ACPI D state media: ov5670: Support device probe in non-zero ACPI D state media: ov8856: support device probe in non-zero ACPI D state media: ov8865: Disable only enabled regulators on error path ...
-rw-r--r--.mailmap1
-rw-r--r--Documentation/admin-guide/media/platform-cardlist.rst1
-rw-r--r--Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml1
-rw-r--r--Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml64
-rw-r--r--Documentation/devicetree/bindings/media/i2c/adv748x.txt116
-rw-r--r--Documentation/devicetree/bindings/media/i2c/adv748x.yaml212
-rw-r--r--Documentation/devicetree/bindings/media/renesas,jpu.txt25
-rw-r--r--Documentation/devicetree/bindings/media/renesas,jpu.yaml65
-rw-r--r--Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml71
-rw-r--r--Documentation/driver-api/media/drivers/index.rst1
-rw-r--r--Documentation/userspace-api/media/cec/cec-ioc-receive.rst49
-rw-r--r--Documentation/userspace-api/media/lirc.h.rst.exceptions2
-rw-r--r--Documentation/userspace-api/media/rc/lirc-dev-intro.rst8
-rw-r--r--Documentation/userspace-api/media/rc/lirc-func.rst1
-rw-r--r--Documentation/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst49
-rw-r--r--Documentation/userspace-api/media/v4l/biblio.rst10
-rw-r--r--Documentation/userspace-api/media/v4l/capture.c.rst52
-rw-r--r--Documentation/userspace-api/media/v4l/control.rst9
-rw-r--r--Documentation/userspace-api/media/v4l/dev-decoder.rst17
-rw-r--r--Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst573
-rw-r--r--Documentation/userspace-api/media/v4l/libv4l-introduction.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/pixfmt-compressed.rst15
-rw-r--r--Documentation/userspace-api/media/v4l/subdev-formats.rst2
-rw-r--r--Documentation/userspace-api/media/v4l/v4l2grab.c.rst8
-rw-r--r--Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst8
-rw-r--r--Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst12
-rw-r--r--Documentation/userspace-api/media/videodev2.h.rst.exceptions2
-rw-r--r--MAINTAINERS28
-rw-r--r--drivers/acpi/scan.c37
-rw-r--r--drivers/i2c/i2c-core-acpi.c22
-rw-r--r--drivers/media/Kconfig8
-rw-r--r--drivers/media/cec/core/cec-adap.c46
-rw-r--r--drivers/media/cec/core/cec-api.c8
-rw-r--r--drivers/media/cec/core/cec-core.c3
-rw-r--r--drivers/media/cec/core/cec-pin-priv.h1
-rw-r--r--drivers/media/cec/core/cec-pin.c32
-rw-r--r--drivers/media/common/b2c2/flexcop.c11
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c5
-rw-r--r--drivers/media/common/videobuf2/frame_vector.c15
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dma-contig.c8
-rw-r--r--drivers/media/dvb-core/dmxdev.c30
-rw-r--r--drivers/media/dvb-core/dvb_demux.c12
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c21
-rw-r--r--drivers/media/dvb-core/dvb_vb2.c4
-rw-r--r--drivers/media/dvb-core/dvbdev.c12
-rw-r--r--drivers/media/dvb-frontends/cx24113.c2
-rw-r--r--drivers/media/dvb-frontends/dib8000.c4
-rw-r--r--drivers/media/dvb-frontends/dib9000.c4
-rw-r--r--drivers/media/dvb-frontends/drxd_hard.c8
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c23
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.c6
-rw-r--r--drivers/media/dvb-frontends/s5h1411.c2
-rw-r--r--drivers/media/dvb-frontends/si2168.c43
-rw-r--r--drivers/media/dvb-frontends/si2168_priv.h2
-rw-r--r--drivers/media/dvb-frontends/si21xx.c7
-rw-r--r--drivers/media/dvb-frontends/sp887x.c4
-rw-r--r--drivers/media/dvb-frontends/stb6100.c2
-rw-r--r--drivers/media/dvb-frontends/stv0367.c6
-rw-r--r--drivers/media/i2c/Kconfig12
-rw-r--r--drivers/media/i2c/Makefile1
-rw-r--r--drivers/media/i2c/adv7511-v4l2.c22
-rw-r--r--drivers/media/i2c/adv7604.c18
-rw-r--r--drivers/media/i2c/adv7842.c10
-rw-r--r--drivers/media/i2c/ccs/ccs-core.c12
-rw-r--r--drivers/media/i2c/cx25840/cx25840-ir.c20
-rw-r--r--drivers/media/i2c/dw9768.c6
-rw-r--r--drivers/media/i2c/hi556.c70
-rw-r--r--drivers/media/i2c/hi846.c14
-rw-r--r--drivers/media/i2c/imx208.c82
-rw-r--r--drivers/media/i2c/imx274.c102
-rw-r--r--drivers/media/i2c/imx290.c2
-rw-r--r--drivers/media/i2c/imx319.c2
-rw-r--r--drivers/media/i2c/imx355.c2
-rw-r--r--drivers/media/i2c/max9286.c7
-rw-r--r--drivers/media/i2c/ov13858.c2
-rw-r--r--drivers/media/i2c/ov2740.c69
-rw-r--r--drivers/media/i2c/ov5670.c80
-rw-r--r--drivers/media/i2c/ov5675.c71
-rw-r--r--drivers/media/i2c/ov5693.c1537
-rw-r--r--drivers/media/i2c/ov8856.c162
-rw-r--r--drivers/media/i2c/ov8865.c478
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-spi.c6
-rw-r--r--drivers/media/mc/mc-entity.c22
-rw-r--r--drivers/media/pci/b2c2/flexcop-pci.c3
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c4
-rw-r--r--drivers/media/pci/cobalt/cobalt-cpld.c5
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-main.c6
-rw-r--r--drivers/media/pci/cx25821/cx25821-core.c7
-rw-r--r--drivers/media/pci/intel/ipu3/cio2-bridge.c100
-rw-r--r--drivers/media/pci/intel/ipu3/cio2-bridge.h16
-rw-r--r--drivers/media/pci/intel/ipu3/ipu3-cio2-main.c27
-rw-r--r--drivers/media/pci/ivtv/ivtv-alsa-main.c6
-rw-r--r--drivers/media/pci/ivtv/ivtvfb.c2
-rw-r--r--drivers/media/pci/pt3/pt3.c58
-rw-r--r--drivers/media/pci/saa7134/saa7134-go7007.c7
-rw-r--r--drivers/media/pci/saa7146/hexium_gemini.c7
-rw-r--r--drivers/media/pci/saa7146/hexium_orion.c8
-rw-r--r--drivers/media/pci/saa7146/mxb.c11
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c12
-rw-r--r--drivers/media/pci/tw5864/tw5864-core.c5
-rw-r--r--drivers/media/platform/Kconfig12
-rw-r--r--drivers/media/platform/Makefile1
-rw-r--r--drivers/media/platform/allegro-dvt/allegro-core.c2
-rw-r--r--drivers/media/platform/aspeed-video.c14
-rw-r--r--drivers/media/platform/coda/coda-common.c16
-rw-r--r--drivers/media/platform/coda/coda-jpeg.c21
-rw-r--r--drivers/media/platform/coda/imx-vdoa.c6
-rw-r--r--drivers/media/platform/davinci/vpbe_osd.c2
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c12
-rw-r--r--drivers/media/platform/imx-pxp.c35
-rw-r--r--drivers/media/platform/marvell-ccic/cafe-driver.c7
-rw-r--r--drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c4
-rw-r--r--drivers/media/platform/mtk-mdp/mtk_mdp_core.c2
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h1
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c6
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c1
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c208
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c6
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c10
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h45
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c8
-rw-r--r--drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c9
-rw-r--r--drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c3
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_vpu_if.c1
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_vpu_if.h1
-rw-r--r--drivers/media/platform/mtk-vpu/mtk_vpu.c4
-rw-r--r--drivers/media/platform/omap3isp/isp.c3
-rw-r--r--drivers/media/platform/omap3isp/isph3a_af.c2
-rw-r--r--drivers/media/platform/omap3isp/omap3isp.h2
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe-170.c7
-rw-r--r--drivers/media/platform/qcom/venus/core.c11
-rw-r--r--drivers/media/platform/qcom/venus/pm_helpers.c32
-rw-r--r--drivers/media/platform/rcar-vin/rcar-core.c3
-rw-r--r--drivers/media/platform/rcar-vin/rcar-csi2.c23
-rw-r--r--drivers/media/platform/rcar-vin/rcar-dma.c17
-rw-r--r--drivers/media/platform/rcar-vin/rcar-v4l2.c15
-rw-r--r--drivers/media/platform/rcar_fdp1.c7
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c2
-rw-r--r--drivers/media/platform/s3c-camif/camif-core.c2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c6
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.h2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c9
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-v4l2.c1
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c12
-rw-r--r--drivers/media/platform/sti/hva/hva-hw.c4
-rw-r--r--drivers/media/platform/stm32/Makefile2
-rw-r--r--drivers/media/platform/stm32/dma2d/dma2d-hw.c133
-rw-r--r--drivers/media/platform/stm32/dma2d/dma2d-regs.h113
-rw-r--r--drivers/media/platform/stm32/dma2d/dma2d.c739
-rw-r--r--drivers/media/platform/stm32/dma2d/dma2d.h135
-rw-r--r--drivers/media/radio/radio-si476x.c6
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c20
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c16
-rw-r--r--drivers/media/rc/Kconfig2
-rw-r--r--drivers/media/rc/igorplugusb.c4
-rw-r--r--drivers/media/rc/iguanair.c3
-rw-r--r--drivers/media/rc/ir-rx51.c16
-rw-r--r--drivers/media/rc/ir-spi.c6
-rw-r--r--drivers/media/rc/lirc_dev.c5
-rw-r--r--drivers/media/rc/mceusb.c8
-rw-r--r--drivers/media/rc/pwm-ir-tx.c18
-rw-r--r--drivers/media/rc/redrat3.c22
-rw-r--r--drivers/media/rc/streamzap.c122
-rw-r--r--drivers/media/rc/winbond-cir.c1
-rw-r--r--drivers/media/spi/cxd2880-spi.c13
-rw-r--r--drivers/media/test-drivers/vicodec/vicodec-core.c2
-rw-r--r--drivers/media/test-drivers/vidtv/vidtv_psi.c12
-rw-r--r--drivers/media/tuners/msi001.c7
-rw-r--r--drivers/media/tuners/mxl5005s.c14
-rw-r--r--drivers/media/tuners/r820t.c24
-rw-r--r--drivers/media/tuners/si2157.c307
-rw-r--r--drivers/media/tuners/si2157_priv.h44
-rw-r--r--drivers/media/tuners/tua9001.c6
-rw-r--r--drivers/media/usb/au0828/au0828-i2c.c7
-rw-r--r--drivers/media/usb/b2c2/flexcop-usb.c28
-rw-r--r--drivers/media/usb/b2c2/flexcop-usb.h12
-rw-r--r--drivers/media/usb/cpia2/cpia2_usb.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c3
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c28
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c338
-rw-r--r--drivers/media/usb/dvb-usb/m920x.c12
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c18
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c4
-rw-r--r--drivers/media/usb/go7007/go7007-driver.c2
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k83a.c13
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-encoder.c4
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.c41
-rw-r--r--drivers/media/usb/s2255/s2255drv.c4
-rw-r--r--drivers/media/usb/siano/smsusb.c4
-rw-r--r--drivers/media/usb/stk1160/stk1160-core.c4
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c4
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c13
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c6
-rw-r--r--drivers/media/usb/uvc/uvc_video.c4
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h2
-rw-r--r--drivers/media/v4l2-core/Kconfig4
-rw-r--r--drivers/media/v4l2-core/Makefile1
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-core.c180
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-defs.c20
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c5
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c21
-rw-r--r--drivers/media/v4l2-core/v4l2-vp9.c1850
-rw-r--r--drivers/platform/x86/intel/int3472/Makefile9
-rw-r--r--drivers/platform/x86/intel/int3472/clk_and_regulator.c (renamed from drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c)2
-rw-r--r--drivers/platform/x86/intel/int3472/common.c82
-rw-r--r--drivers/platform/x86/intel/int3472/common.h (renamed from drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h)6
-rw-r--r--drivers/platform/x86/intel/int3472/discrete.c (renamed from drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c)51
-rw-r--r--drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c106
-rw-r--r--drivers/platform/x86/intel/int3472/tps68470.c (renamed from drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c)92
-rw-r--r--drivers/platform/x86/intel/int3472/tps68470.h25
-rw-r--r--drivers/platform/x86/intel/int3472/tps68470_board_data.c145
-rw-r--r--drivers/staging/media/Kconfig2
-rw-r--r--drivers/staging/media/Makefile1
-rw-r--r--drivers/staging/media/atomisp/Makefile24
-rw-r--r--drivers/staging/media/atomisp/TODO191
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-gc0310.c119
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-gc2235.c121
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c130
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-ov2680.c313
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-ov2722.c118
-rw-r--r--drivers/staging/media/atomisp/i2c/gc0310.h3
-rw-r--r--drivers/staging/media/atomisp/i2c/gc2235.h3
-rw-r--r--drivers/staging/media/atomisp/i2c/ov2680.h207
-rw-r--r--drivers/staging/media/atomisp/i2c/ov2722.h3
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.c248
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.h6
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat.h2
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_compat_css20.c92
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_fops.c43
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c21
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_internal.h7
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_ioctl.c312
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_subdev.c54
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_subdev.h4
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.c33
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.h3
-rw-r--r--drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c25
-rw-r--r--drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c386
-rw-r--r--drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c3420
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c386
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c224
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c11
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_acc_types.h5
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_event_public.h17
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_configs.c321
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_configs.h119
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_params.c (renamed from drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c)23
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_params.h3
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_isp_states.c (renamed from drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c)0
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_pipe.h4
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_pipe_public.h26
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_stream.h4
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_stream_public.h19
-rw-r--r--drivers/staging/media/atomisp/pci/input_system_local.h134
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c8
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h6
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c28
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h14
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c8
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h6
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c28
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h14
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h1
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c16
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h6
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c18
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h6
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c11
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c69
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h42
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c30
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h16
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c38
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h22
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c30
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h16
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c5
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c68
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h33
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h14
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c33
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h14
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h4
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c32
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h8
-rw-r--r--drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h14
-rw-r--r--drivers/staging/media/atomisp/pci/isp2400_input_system_local.h126
-rw-r--r--drivers/staging/media/atomisp/pci/isp2401_input_system_global.h12
-rw-r--r--drivers/staging/media/atomisp/pci/isp2401_input_system_local.h26
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h3
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c513
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h24
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c116
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c11
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c3
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css.c1963
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_defs.h58
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_firmware.c16
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_firmware.h3
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_internal.h36
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_metadata.c17
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_metrics.c25
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_mipi.c197
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_mipi.h17
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_morph.c17
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_param_shading.c82
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_params.c249
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_params.h8
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_shading.c17
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_sp.c131
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_sp.h7
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_stream.c17
-rw-r--r--drivers/staging/media/atomisp/pci/system_global.h3
-rw-r--r--drivers/staging/media/hantro/Kconfig11
-rw-r--r--drivers/staging/media/hantro/Makefile10
-rw-r--r--drivers/staging/media/hantro/hantro.h50
-rw-r--r--drivers/staging/media/hantro/hantro_drv.c51
-rw-r--r--drivers/staging/media/hantro/hantro_g2.c44
-rw-r--r--drivers/staging/media/hantro/hantro_g2_hevc_dec.c92
-rw-r--r--drivers/staging/media/hantro/hantro_g2_regs.h149
-rw-r--r--drivers/staging/media/hantro/hantro_g2_vp9_dec.c1022
-rw-r--r--drivers/staging/media/hantro/hantro_h1_jpeg_enc.c7
-rw-r--r--drivers/staging/media/hantro/hantro_hevc.c79
-rw-r--r--drivers/staging/media/hantro/hantro_hw.h131
-rw-r--r--drivers/staging/media/hantro/hantro_jpeg.c31
-rw-r--r--drivers/staging/media/hantro/hantro_jpeg.h4
-rw-r--r--drivers/staging/media/hantro/hantro_postproc.c84
-rw-r--r--drivers/staging/media/hantro/hantro_v4l2.c13
-rw-r--r--drivers/staging/media/hantro/hantro_vp9.c240
-rw-r--r--drivers/staging/media/hantro/hantro_vp9.h102
-rw-r--r--drivers/staging/media/hantro/imx8m_vpu_hw.c58
-rw-r--r--drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c22
-rw-r--r--drivers/staging/media/hantro/rockchip_vpu_hw.c12
-rw-r--r--drivers/staging/media/hantro/sama5d4_vdec_hw.c3
-rw-r--r--drivers/staging/media/hantro/sunxi_vpu_hw.c86
-rw-r--r--drivers/staging/media/imx/imx-media-csc-scaler.c2
-rw-r--r--drivers/staging/media/imx/imx-media-csi.c2
-rw-r--r--drivers/staging/media/imx/imx-media-utils.c42
-rw-r--r--drivers/staging/media/imx/imx-media.h4
-rw-r--r--drivers/staging/media/imx/imx6-mipi-csi2.c9
-rw-r--r--drivers/staging/media/ipu3/include/uapi/intel-ipu3.h42
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-params.c3
-rw-r--r--drivers/staging/media/max96712/Kconfig14
-rw-r--r--drivers/staging/media/max96712/Makefile2
-rw-r--r--drivers/staging/media/max96712/max96712.c440
-rw-r--r--drivers/staging/media/meson/vdec/vdec_helpers.c10
-rw-r--r--drivers/staging/media/rkvdec/Kconfig1
-rw-r--r--drivers/staging/media/rkvdec/Makefile2
-rw-r--r--drivers/staging/media/rkvdec/rkvdec-vp9.c1072
-rw-r--r--drivers/staging/media/rkvdec/rkvdec.c43
-rw-r--r--drivers/staging/media/rkvdec/rkvdec.h12
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus.c12
-rw-r--r--drivers/staging/media/tegra-vde/vde.c147
-rw-r--r--drivers/staging/media/tegra-vde/vde.h18
-rw-r--r--include/acpi/acpi_bus.h5
-rw-r--r--include/linux/i2c.h17
-rw-r--r--include/linux/platform_data/tps68470.h35
-rw-r--r--include/media/cec.h11
-rw-r--r--include/media/dmxdev.h1
-rw-r--r--include/media/dvb_frontend.h13
-rw-r--r--include/media/rc-core.h2
-rw-r--r--include/media/v4l2-ctrls.h4
-rw-r--r--include/media/v4l2-mem2mem.h5
-rw-r--r--include/media/v4l2-vp9.h233
-rw-r--r--include/media/videobuf2-core.h9
-rw-r--r--include/uapi/linux/v4l2-controls.h288
-rw-r--r--include/uapi/linux/videodev2.h6
373 files changed, 15494 insertions, 11300 deletions
diff --git a/.mailmap b/.mailmap
index 7e3fe690b86e..a83599921b1a 100644
--- a/.mailmap
+++ b/.mailmap
@@ -44,6 +44,7 @@ Andrew Vasquez <andrew.vasquez@qlogic.com>
Andrey Konovalov <andreyknvl@gmail.com> <andreyknvl@google.com>
Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com>
+Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com>
Andy Adamson <andros@citi.umich.edu>
Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com>
Antoine Tenart <atenart@kernel.org> <antoine.tenart@free-electrons.com>
diff --git a/Documentation/admin-guide/media/platform-cardlist.rst b/Documentation/admin-guide/media/platform-cardlist.rst
index 261e7772eb3e..ac73c4166d1e 100644
--- a/Documentation/admin-guide/media/platform-cardlist.rst
+++ b/Documentation/admin-guide/media/platform-cardlist.rst
@@ -60,6 +60,7 @@ s5p-mfc Samsung S5P MFC Video Codec
sh_veu SuperH VEU mem2mem video processing
sh_vou SuperH VOU video output
stm32-dcmi STM32 Digital Camera Memory Interface (DCMI)
+stm32-dma2d STM32 Chrom-Art Accelerator Unit
sun4i-csi Allwinner A10 CMOS Sensor Interface Support
sun6i-csi Allwinner V3s Camera Sensor Interface
sun8i-di Allwinner Deinterlace
diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml
index c34303b87a5b..c3de96d10396 100644
--- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml
+++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-video-engine.yaml
@@ -20,6 +20,7 @@ properties:
- allwinner,sun8i-h3-video-engine
- allwinner,sun8i-v3s-video-engine
- allwinner,sun8i-r40-video-engine
+ - allwinner,sun20i-d1-video-engine
- allwinner,sun50i-a64-video-engine
- allwinner,sun50i-h5-video-engine
- allwinner,sun50i-h6-video-engine
diff --git a/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
new file mode 100644
index 000000000000..24d7bf21499e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/allwinner,sun50i-h6-vpu-g2.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Hantro G2 VPU codec implemented on Allwinner H6 SoC
+
+maintainers:
+ - Jernej Skrabec <jernej.skrabec@gmail.com>
+
+description:
+ Hantro G2 video decode accelerator present on Allwinner H6 SoC.
+
+properties:
+ compatible:
+ const: allwinner,sun50i-h6-vpu-g2
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Bus Clock
+ - description: Module Clock
+
+ clock-names:
+ items:
+ - const: bus
+ - const: mod
+
+ resets:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/sun50i-h6-ccu.h>
+ #include <dt-bindings/reset/sun50i-h6-ccu.h>
+
+ video-codec-g2@1c00000 {
+ compatible = "allwinner,sun50i-h6-vpu-g2";
+ reg = <0x01c00000 0x1000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_VP9>, <&ccu CLK_VP9>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_VP9>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/adv748x.txt b/Documentation/devicetree/bindings/media/i2c/adv748x.txt
deleted file mode 100644
index 4f91686e54a6..000000000000
--- a/Documentation/devicetree/bindings/media/i2c/adv748x.txt
+++ /dev/null
@@ -1,116 +0,0 @@
-* Analog Devices ADV748X video decoder with HDMI receiver
-
-The ADV7481 and ADV7482 are multi format video decoders with an integrated
-HDMI receiver. They can output CSI-2 on two independent outputs TXA and TXB
-from three input sources HDMI, analog and TTL.
-
-Required Properties:
-
- - compatible: Must contain one of the following
- - "adi,adv7481" for the ADV7481
- - "adi,adv7482" for the ADV7482
-
- - reg: I2C slave addresses
- The ADV748x has up to twelve 256-byte maps that can be accessed via the
- main I2C ports. Each map has it own I2C address and acts as a standard
- slave device on the I2C bus. The main address is mandatory, others are
- optional and remain at default values if not specified.
-
-Optional Properties:
-
- - interrupt-names: Should specify the interrupts as "intrq1", "intrq2" and/or
- "intrq3". All interrupts are optional. The "intrq3" interrupt
- is only available on the adv7481
- - interrupts: Specify the interrupt lines for the ADV748x
- - reg-names : Names of maps with programmable addresses.
- It shall contain all maps needing a non-default address.
- Possible map names are:
- "main", "dpll", "cp", "hdmi", "edid", "repeater",
- "infoframe", "cbus", "cec", "sdp", "txa", "txb"
-
-The device node must contain one 'port' child node per device input and output
-port, in accordance with the video interface bindings defined in
-Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes
-are numbered as follows.
-
- Name Type Port
- ---------------------------------------
- AIN0 sink 0
- AIN1 sink 1
- AIN2 sink 2
- AIN3 sink 3
- AIN4 sink 4
- AIN5 sink 5
- AIN6 sink 6
- AIN7 sink 7
- HDMI sink 8
- TTL sink 9
- TXA source 10
- TXB source 11
-
-The digital output port nodes, when present, shall contain at least one
-endpoint. Each of those endpoints shall contain the data-lanes property as
-described in video-interfaces.txt.
-
-Required source endpoint properties:
- - data-lanes: an array of physical data lane indexes
- The accepted value(s) for this property depends on which of the two
- sources are described. For TXA 1, 2 or 4 data lanes can be described
- while for TXB only 1 data lane is valid. See video-interfaces.txt
- for detailed description.
-
-Ports are optional if they are not connected to anything at the hardware level.
-
-Example:
-
- video-receiver@70 {
- compatible = "adi,adv7482";
- reg = <0x70 0x71 0x72 0x73 0x74 0x75
- 0x60 0x61 0x62 0x63 0x64 0x65>;
- reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater",
- "infoframe", "cbus", "cec", "sdp", "txa", "txb";
-
- #address-cells = <1>;
- #size-cells = <0>;
-
- interrupt-parent = <&gpio6>;
- interrupt-names = "intrq1", "intrq2";
- interrupts = <30 IRQ_TYPE_LEVEL_LOW>,
- <31 IRQ_TYPE_LEVEL_LOW>;
-
- port@7 {
- reg = <7>;
-
- adv7482_ain7: endpoint {
- remote-endpoint = <&cvbs_in>;
- };
- };
-
- port@8 {
- reg = <8>;
-
- adv7482_hdmi: endpoint {
- remote-endpoint = <&hdmi_in>;
- };
- };
-
- port@a {
- reg = <10>;
-
- adv7482_txa: endpoint {
- clock-lanes = <0>;
- data-lanes = <1 2 3 4>;
- remote-endpoint = <&csi40_in>;
- };
- };
-
- port@b {
- reg = <11>;
-
- adv7482_txb: endpoint {
- clock-lanes = <0>;
- data-lanes = <1>;
- remote-endpoint = <&csi20_in>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/media/i2c/adv748x.yaml b/Documentation/devicetree/bindings/media/i2c/adv748x.yaml
new file mode 100644
index 000000000000..d6353081402b
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/adv748x.yaml
@@ -0,0 +1,212 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/adv748x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices ADV748X video decoder with HDMI receiver
+
+maintainers:
+ - Kieran Bingham <kieran.bingham@ideasonboard.com>
+ - Niklas Söderlund <niklas.soderlund@ragnatech.se>
+
+description:
+ The ADV7481 and ADV7482 are multi format video decoders with an integrated
+ HDMI receiver. They can output CSI-2 on two independent outputs TXA and TXB
+ from three input sources HDMI, analog and TTL.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - adi,adv7481
+ - adi,adv7482
+
+ reg:
+ minItems: 1
+ maxItems: 12
+ description:
+ The ADV748x has up to twelve 256-byte maps that can be accessed via the
+ main I2C ports. Each map has it own I2C address and acts as a standard
+ slave device on the I2C bus. The main address is mandatory, others are
+ optional and remain at default values if not specified.
+
+ reg-names:
+ minItems: 1
+ items:
+ - const: main
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+ - enum: [ dpll, cp, hdmi, edid, repeater, infoframe, cbus, cec, sdp, txa, txb ]
+
+ interrupts: true
+
+ interrupt-names: true
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ patternProperties:
+ "^port@[0-7]$":
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input port nodes for analog inputs AIN[0-7].
+
+ properties:
+ port@8:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input port node for HDMI.
+
+ port@9:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input port node for TTL.
+
+ port@a:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Output port node, single endpoint describing the CSI-2 transmitter TXA.
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+ port@b:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Output port node, single endpoint describing the CSI-2 transmitter TXB.
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ clock-lanes:
+ maxItems: 1
+
+ data-lanes:
+ maxItems: 1
+
+ required:
+ - clock-lanes
+ - data-lanes
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: adi,adv7481
+ then:
+ properties:
+ interrupts:
+ minItems: 1
+ maxItems: 3
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 3
+ items:
+ enum: [ intrq1, intrq2, intrq3 ]
+ else:
+ properties:
+ interrupts:
+ minItems: 1
+ maxItems: 2
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 2
+ items:
+ enum: [ intrq1, intrq2 ]
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - ports
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ video-receiver@70 {
+ compatible = "adi,adv7482";
+ reg = <0x70 0x71 0x72 0x73 0x74 0x75
+ 0x60 0x61 0x62 0x63 0x64 0x65>;
+ reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater",
+ "infoframe", "cbus", "cec", "sdp", "txa", "txb";
+
+ interrupt-parent = <&gpio6>;
+ interrupts = <30 IRQ_TYPE_LEVEL_LOW>, <31 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "intrq1", "intrq2";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@7 {
+ reg = <7>;
+
+ adv7482_ain7: endpoint {
+ remote-endpoint = <&cvbs_in>;
+ };
+ };
+
+ port@8 {
+ reg = <8>;
+
+ adv7482_hdmi: endpoint {
+ remote-endpoint = <&hdmi_in>;
+ };
+ };
+
+ port@a {
+ reg = <10>;
+
+ adv7482_txa: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csi40_in>;
+ };
+ };
+
+ port@b {
+ reg = <11>;
+
+ adv7482_txb: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1>;
+ remote-endpoint = <&csi20_in>;
+ };
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/media/renesas,jpu.txt b/Documentation/devicetree/bindings/media/renesas,jpu.txt
deleted file mode 100644
index d3436e5190f9..000000000000
--- a/Documentation/devicetree/bindings/media/renesas,jpu.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-* Renesas JPEG Processing Unit
-
-The JPEG processing unit (JPU) incorporates the JPEG codec with an encoding
-and decoding function conforming to the JPEG baseline process, so that the JPU
-can encode image data and decode JPEG data quickly.
-
-Required properties:
-- compatible: "renesas,jpu-<soctype>", "renesas,rcar-gen2-jpu" as fallback.
- Examples with soctypes are:
- - "renesas,jpu-r8a7790" for R-Car H2
- - "renesas,jpu-r8a7791" for R-Car M2-W
- - "renesas,jpu-r8a7792" for R-Car V2H
- - "renesas,jpu-r8a7793" for R-Car M2-N
-
- - reg: Base address and length of the registers block for the JPU.
- - interrupts: JPU interrupt specifier.
- - clocks: A phandle + clock-specifier pair for the JPU functional clock.
-
-Example: R8A7790 (R-Car H2) JPU node
- jpeg-codec@fe980000 {
- compatible = "renesas,jpu-r8a7790", "renesas,rcar-gen2-jpu";
- reg = <0 0xfe980000 0 0x10300>;
- interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&mstp1_clks R8A7790_CLK_JPU>;
- };
diff --git a/Documentation/devicetree/bindings/media/renesas,jpu.yaml b/Documentation/devicetree/bindings/media/renesas,jpu.yaml
new file mode 100644
index 000000000000..2f55968e864f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/renesas,jpu.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/renesas,jpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas JPEG Processing Unit
+
+maintainers:
+ - Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>
+
+description:
+ The JPEG processing unit (JPU) incorporates the JPEG codec with an encoding
+ and decoding function conforming to the JPEG baseline process, so that the
+ JPU can encode image data and decode JPEG data quickly.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - renesas,jpu-r8a7790 # R-Car H2
+ - renesas,jpu-r8a7791 # R-Car M2-W
+ - renesas,jpu-r8a7792 # R-Car V2H
+ - renesas,jpu-r8a7793 # R-Car M2-N
+ - const: renesas,rcar-gen2-jpu # R-Car Gen2
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - power-domains
+ - resets
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/r8a7790-cpg-mssr.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/r8a7790-sysc.h>
+
+ jpeg-codec@fe980000 {
+ compatible = "renesas,jpu-r8a7790", "renesas,rcar-gen2-jpu";
+ reg = <0xfe980000 0x10300>;
+ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 106>;
+ power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+ resets = <&cpg 106>;
+ };
diff --git a/Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml b/Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml
new file mode 100644
index 000000000000..f97b4a246605
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/st,stm32-dma2d.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32 Chrom-Art Accelerator DMA2D binding
+
+description:
+ Chrom-ART Accelerator(DMA2D), graphical hardware accelerator
+ enabling enhanced graphical user interface with minimum CPU load
+
+ It can perform the following operations.
+
+ - Filling a part or the whole of a destination image with a specific color.
+ - Copying a part or the whole of a source image into a part or the whole of
+ a destination image.
+ - Copying a part or the whole of a source image into a part or the whole of
+ a destination image with a pixel format conversion.
+ - Blending a part and/or two complete source images with different pixel
+ format and copy the result into a part or the whole of a destination image
+ with a different color format. (TODO)
+
+
+maintainers:
+ - Dillon Min <dillon.minfei@gmail.com>
+
+properties:
+ compatible:
+ const: st,stm32-dma2d
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: dma2d
+
+ resets:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/stm32fx-clock.h>
+ #include <dt-bindings/mfd/stm32f4-rcc.h>
+ dma2d: dma2d@4002b000 {
+ compatible = "st,stm32-dma2d";
+ reg = <0x4002b000 0xc00>;
+ interrupts = <90>;
+ resets = <&rcc STM32F4_AHB1_RESET(DMA2D)>;
+ clocks = <&rcc 0 STM32F4_AHB1_CLOCK(DMA2D)>;
+ clock-names = "dma2d";
+ };
+
+...
diff --git a/Documentation/driver-api/media/drivers/index.rst b/Documentation/driver-api/media/drivers/index.rst
index 426cda633bf0..32406490557c 100644
--- a/Documentation/driver-api/media/drivers/index.rst
+++ b/Documentation/driver-api/media/drivers/index.rst
@@ -21,6 +21,7 @@ Video4Linux (V4L) drivers
pvrusb2
pxa_camera
radiotrack
+ rkisp1
saa7134-devel
sh_mobile_ceu_camera
tuners
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-receive.rst b/Documentation/userspace-api/media/cec/cec-ioc-receive.rst
index bd7f7e7235cb..364938ad34df 100644
--- a/Documentation/userspace-api/media/cec/cec-ioc-receive.rst
+++ b/Documentation/userspace-api/media/cec/cec-ioc-receive.rst
@@ -48,9 +48,12 @@ it will return -1 and set errno to the ``ETIMEDOUT`` error code.
A received message can be:
1. a message received from another CEC device (the ``sequence`` field will
- be 0).
-2. the result of an earlier non-blocking transmit (the ``sequence`` field will
- be non-zero).
+ be 0, ``tx_status`` will be 0 and ``rx_status`` will be non-zero).
+2. the transmit result of an earlier non-blocking transmit (the ``sequence``
+ field will be non-zero, ``tx_status`` will be non-zero and ``rx_status``
+ will be 0).
+3. the reply to an earlier non-blocking transmit (the ``sequence`` field will
+ be non-zero, ``tx_status`` will be 0 and ``rx_status`` will be non-zero).
To send a CEC message the application has to fill in the struct
:c:type:`cec_msg` and pass it to :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`.
@@ -64,12 +67,11 @@ idea to fully fill up the transmit queue.
If the file descriptor is in non-blocking mode then the transmit will
return 0 and the result of the transmit will be available via
-:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` once the transmit has finished
-(including waiting for a reply, if requested).
-
-The ``sequence`` field is filled in for every transmit and this can be
-checked against the received messages to find the corresponding transmit
-result.
+:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>` once the transmit has finished.
+If a non-blocking transmit also specified waiting for a reply, then
+the reply will arrive in a later message. The ``sequence`` field can
+be used to associate both transmit results and replies with the original
+transmit.
Normally calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` when the physical
address is invalid (due to e.g. a disconnect) will return ``ENONET``.
@@ -123,18 +125,17 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
- ``sequence``
- A non-zero sequence number is automatically assigned by the CEC framework
for all transmitted messages. It is used by the CEC framework when it queues
- the transmit result (when transmit was called in non-blocking mode). This
- allows the application to associate the received message with the original
- transmit.
+ the transmit result for a non-blocking transmit. This allows the application
+ to associate the received message with the original transmit.
+
+ In addition, if a non-blocking transmit will wait for a reply (ii.e. ``timeout``
+ was not 0), then the ``sequence`` field of the reply will be set to the sequence
+ value of the original transmit. This allows the application to associate the
+ received message with the original transmit.
* - __u32
- ``flags``
- Flags. See :ref:`cec-msg-flags` for a list of available flags.
* - __u8
- - ``tx_status``
- - The status bits of the transmitted message. See
- :ref:`cec-tx-status` for the possible status values. It is 0 if
- this message was received, not transmitted.
- * - __u8
- ``msg[16]``
- The message payload. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in by the
application. The driver will fill this in for :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
@@ -162,15 +163,17 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
* - __u8
- ``rx_status``
- The status bits of the received message. See
- :ref:`cec-rx-status` for the possible status values. It is 0 if
- this message was transmitted, not received, unless this is the
- reply to a transmitted message. In that case both ``rx_status``
- and ``tx_status`` are set.
+ :ref:`cec-rx-status` for the possible status values.
* - __u8
- ``tx_status``
- The status bits of the transmitted message. See
- :ref:`cec-tx-status` for the possible status values. It is 0 if
- this message was received, not transmitted.
+ :ref:`cec-tx-status` for the possible status values.
+ When calling :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` in non-blocking mode,
+ this field will be 0 if the transmit started, or non-0 if the transmit
+ result is known immediately. The latter would be the case when attempting
+ to transmit a Poll message to yourself. That results in a
+ :ref:`CEC_TX_STATUS_NACK <CEC-TX-STATUS-NACK>` without ever actually
+ transmitting the Poll message.
* - __u8
- ``tx_arb_lost_cnt``
- A counter of the number of transmit attempts that resulted in the
diff --git a/Documentation/userspace-api/media/lirc.h.rst.exceptions b/Documentation/userspace-api/media/lirc.h.rst.exceptions
index e74b73cd0e9e..ec86e82d026d 100644
--- a/Documentation/userspace-api/media/lirc.h.rst.exceptions
+++ b/Documentation/userspace-api/media/lirc.h.rst.exceptions
@@ -33,6 +33,7 @@ ignore define LIRC_CAN_SET_REC_DUTY_CYCLE
# Obsolete ioctls
ignore ioctl LIRC_GET_LENGTH
+ignore ioctl LIRC_SET_REC_TIMEOUT_REPORTS
# rc protocols
@@ -73,6 +74,7 @@ ignore define PULSE_MASK
ignore define LIRC_MODE2_SPACE
ignore define LIRC_MODE2_PULSE
+ignore define LIRC_MODE2_TIMEOUT
ignore define LIRC_VALUE_MASK
ignore define LIRC_MODE2_MASK
diff --git a/Documentation/userspace-api/media/rc/lirc-dev-intro.rst b/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
index c88973732282..9a5e5f0aae11 100644
--- a/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
+++ b/Documentation/userspace-api/media/rc/lirc-dev-intro.rst
@@ -117,11 +117,9 @@ on the following table.
``LIRC_MODE2_TIMEOUT``
- If timeout reports are enabled with
- :ref:`lirc_set_rec_timeout_reports`, when the timeout set with
- :ref:`lirc_set_rec_timeout` expires due to no IR being detected,
- this packet will be sent, with the number of microseconds with
- no IR.
+ When the timeout set with :ref:`lirc_set_rec_timeout` expires due
+ to no IR being detected, this packet will be sent, with the number
+ of microseconds with no IR.
.. _lirc-mode-pulse:
diff --git a/Documentation/userspace-api/media/rc/lirc-func.rst b/Documentation/userspace-api/media/rc/lirc-func.rst
index 793f295d3ac9..5c84888f1eca 100644
--- a/Documentation/userspace-api/media/rc/lirc-func.rst
+++ b/Documentation/userspace-api/media/rc/lirc-func.rst
@@ -22,6 +22,5 @@ LIRC Function Reference
lirc-set-rec-carrier-range
lirc-set-send-carrier
lirc-set-transmitter-mask
- lirc-set-rec-timeout-reports
lirc-set-measure-carrier-mode
lirc-set-wideband-receiver
diff --git a/Documentation/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst b/Documentation/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst
deleted file mode 100644
index aebe81012939..000000000000
--- a/Documentation/userspace-api/media/rc/lirc-set-rec-timeout-reports.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
-.. c:namespace:: RC
-
-.. _lirc_set_rec_timeout_reports:
-
-**********************************
-ioctl LIRC_SET_REC_TIMEOUT_REPORTS
-**********************************
-
-Name
-====
-
-LIRC_SET_REC_TIMEOUT_REPORTS - enable or disable timeout reports for IR receive
-
-Synopsis
-========
-
-.. c:macro:: LIRC_SET_REC_TIMEOUT_REPORTS
-
-``int ioctl(int fd, LIRC_SET_REC_TIMEOUT_REPORTS, __u32 *enable)``
-
-Arguments
-=========
-
-``fd``
- File descriptor returned by open().
-
-``enable``
- enable = 1 means enable timeout report, enable = 0 means disable timeout
- reports.
-
-Description
-===========
-
-.. _lirc-mode2-timeout:
-
-Enable or disable timeout reports for IR receive. By default, timeout reports
-should be turned off.
-
-.. note::
-
- This ioctl is only valid for :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`.
-
-Return Value
-============
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/userspace-api/media/v4l/biblio.rst b/Documentation/userspace-api/media/v4l/biblio.rst
index 7b8e6738ff9e..9cd18c153d19 100644
--- a/Documentation/userspace-api/media/v4l/biblio.rst
+++ b/Documentation/userspace-api/media/v4l/biblio.rst
@@ -417,3 +417,13 @@ VP8
:title: RFC 6386: "VP8 Data Format and Decoding Guide"
:author: J. Bankoski et al.
+
+.. _vp9:
+
+VP9
+===
+
+
+:title: VP9 Bitstream & Decoding Process Specification
+
+:author: Adrian Grange (Google), Peter de Rivaz (Argon Design), Jonathan Hunt (Argon Design)
diff --git a/Documentation/userspace-api/media/v4l/capture.c.rst b/Documentation/userspace-api/media/v4l/capture.c.rst
index ccbd52c3897f..eef6772967a1 100644
--- a/Documentation/userspace-api/media/v4l/capture.c.rst
+++ b/Documentation/userspace-api/media/v4l/capture.c.rst
@@ -56,7 +56,7 @@ file: media/v4l/capture.c
static void errno_exit(const char *s)
{
- fprintf(stderr, "%s error %d, %s\\n", s, errno, strerror(errno));
+ fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
exit(EXIT_FAILURE);
}
@@ -201,7 +201,7 @@ file: media/v4l/capture.c
}
if (0 == r) {
- fprintf(stderr, "select timeout\\n");
+ fprintf(stderr, "select timeout\n");
exit(EXIT_FAILURE);
}
@@ -307,7 +307,7 @@ file: media/v4l/capture.c
buffers = calloc(1, sizeof(*buffers));
if (!buffers) {
- fprintf(stderr, "Out of memory\\n");
+ fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
@@ -315,7 +315,7 @@ file: media/v4l/capture.c
buffers[0].start = malloc(buffer_size);
if (!buffers[0].start) {
- fprintf(stderr, "Out of memory\\n");
+ fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
}
@@ -341,7 +341,7 @@ file: media/v4l/capture.c
}
if (req.count < 2) {
- fprintf(stderr, "Insufficient buffer memory on %s\\n",
+ fprintf(stderr, "Insufficient buffer memory on %s\n",
dev_name);
exit(EXIT_FAILURE);
}
@@ -349,7 +349,7 @@ file: media/v4l/capture.c
buffers = calloc(req.count, sizeof(*buffers));
if (!buffers) {
- fprintf(stderr, "Out of memory\\n");
+ fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
@@ -401,7 +401,7 @@ file: media/v4l/capture.c
buffers = calloc(4, sizeof(*buffers));
if (!buffers) {
- fprintf(stderr, "Out of memory\\n");
+ fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
@@ -410,7 +410,7 @@ file: media/v4l/capture.c
buffers[n_buffers].start = malloc(buffer_size);
if (!buffers[n_buffers].start) {
- fprintf(stderr, "Out of memory\\n");
+ fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
}
@@ -426,7 +426,7 @@ file: media/v4l/capture.c
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
if (EINVAL == errno) {
- fprintf(stderr, "%s is no V4L2 device\\n",
+ fprintf(stderr, "%s is no V4L2 device\n",
dev_name);
exit(EXIT_FAILURE);
} else {
@@ -435,7 +435,7 @@ file: media/v4l/capture.c
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
- fprintf(stderr, "%s is no video capture device\\n",
+ fprintf(stderr, "%s is no video capture device\n",
dev_name);
exit(EXIT_FAILURE);
}
@@ -443,7 +443,7 @@ file: media/v4l/capture.c
switch (io) {
case IO_METHOD_READ:
if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
- fprintf(stderr, "%s does not support read i/o\\n",
+ fprintf(stderr, "%s does not support read i/o\n",
dev_name);
exit(EXIT_FAILURE);
}
@@ -452,7 +452,7 @@ file: media/v4l/capture.c
case IO_METHOD_MMAP:
case IO_METHOD_USERPTR:
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
- fprintf(stderr, "%s does not support streaming i/o\\n",
+ fprintf(stderr, "%s does not support streaming i/o\n",
dev_name);
exit(EXIT_FAILURE);
}
@@ -541,7 +541,7 @@ file: media/v4l/capture.c
struct stat st;
if (-1 == stat(dev_name, &st)) {
- fprintf(stderr, "Cannot identify '%s': %d, %s\\n",
+ fprintf(stderr, "Cannot identify '%s': %d, %s\n",
dev_name, errno, strerror(errno));
exit(EXIT_FAILURE);
}
@@ -554,7 +554,7 @@ file: media/v4l/capture.c
fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
if (-1 == fd) {
- fprintf(stderr, "Cannot open '%s': %d, %s\\n",
+ fprintf(stderr, "Cannot open '%s': %d, %s\n",
dev_name, errno, strerror(errno));
exit(EXIT_FAILURE);
}
@@ -563,17 +563,17 @@ file: media/v4l/capture.c
static void usage(FILE *fp, int argc, char **argv)
{
fprintf(fp,
- "Usage: %s [options]\\n\\n"
- "Version 1.3\\n"
- "Options:\\n"
- "-d | --device name Video device name [%s]n"
- "-h | --help Print this messagen"
- "-m | --mmap Use memory mapped buffers [default]n"
- "-r | --read Use read() callsn"
- "-u | --userp Use application allocated buffersn"
- "-o | --output Outputs stream to stdoutn"
- "-f | --format Force format to 640x480 YUYVn"
- "-c | --count Number of frames to grab [%i]n"
+ "Usage: %s [options]\n\n"
+ "Version 1.3\n"
+ "Options:\n"
+ "-d | --device name Video device name [%s]\n"
+ "-h | --help Print this message\n"
+ "-m | --mmap Use memory mapped buffers [default]\n"
+ "-r | --read Use read() calls\n"
+ "-u | --userp Use application allocated buffers\n"
+ "-o | --output Outputs stream to stdout\n"
+ "-f | --format Force format to 640x480 YUYV\n"
+ "-c | --count Number of frames to grab [%i]\n"
"",
argv[0], dev_name, frame_count);
}
@@ -659,6 +659,6 @@ file: media/v4l/capture.c
stop_capturing();
uninit_device();
close_device();
- fprintf(stderr, "\\n");
+ fprintf(stderr, "\n");
return 0;
}
diff --git a/Documentation/userspace-api/media/v4l/control.rst b/Documentation/userspace-api/media/v4l/control.rst
index f8d0b923da20..3eec65174260 100644
--- a/Documentation/userspace-api/media/v4l/control.rst
+++ b/Documentation/userspace-api/media/v4l/control.rst
@@ -242,8 +242,17 @@ Control IDs
* - ``V4L2_COLORFX_SET_CBCR``
- The Cb and Cr chroma components are replaced by fixed coefficients
determined by ``V4L2_CID_COLORFX_CBCR`` control.
+ * - ``V4L2_COLORFX_SET_RGB``
+ - The RGB components are replaced by the fixed RGB components determined
+ by ``V4L2_CID_COLORFX_RGB`` control.
+``V4L2_CID_COLORFX_RGB`` ``(integer)``
+ Determines the Red, Green, and Blue coefficients for
+ ``V4L2_COLORFX_SET_RGB`` color effect.
+ Bits [7:0] of the supplied 32 bit value are interpreted as Blue component,
+ bits [15:8] as Green component, bits [23:16] as Red component, and
+ bits [31:24] must be zero.
``V4L2_CID_COLORFX_CBCR`` ``(integer)``
Determines the Cb and Cr coefficients for ``V4L2_COLORFX_SET_CBCR``
diff --git a/Documentation/userspace-api/media/v4l/dev-decoder.rst b/Documentation/userspace-api/media/v4l/dev-decoder.rst
index 5b9b83feeceb..3cf2b496f2d0 100644
--- a/Documentation/userspace-api/media/v4l/dev-decoder.rst
+++ b/Documentation/userspace-api/media/v4l/dev-decoder.rst
@@ -752,6 +752,23 @@ available to dequeue. Specifically:
buffers are out-of-order compared to the ``OUTPUT`` buffers): ``CAPTURE``
timestamps will not retain the order of ``OUTPUT`` timestamps.
+.. note::
+
+ The backing memory of ``CAPTURE`` buffers that are used as reference frames
+ by the stream may be read by the hardware even after they are dequeued.
+ Consequently, the client should avoid writing into this memory while the
+ ``CAPTURE`` queue is streaming. Failure to observe this may result in
+ corruption of decoded frames.
+
+ Similarly, when using a memory type other than ``V4L2_MEMORY_MMAP``, the
+ client should make sure that each ``CAPTURE`` buffer is always queued with
+ the same backing memory for as long as the ``CAPTURE`` queue is streaming.
+ The reason for this is that V4L2 buffer indices can be used by drivers to
+ identify frames. Thus, if the backing memory of a reference frame is
+ submitted under a different buffer ID, the driver may misidentify it and
+ decode a new frame into it while it is still in use, resulting in corruption
+ of the following frames.
+
During the decoding, the decoder may initiate one of the special sequences, as
listed below. The sequences will result in the decoder returning all the
``CAPTURE`` buffers that originated from all the ``OUTPUT`` buffers processed
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
index 72f5e85b4f34..cc080c4257d0 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
@@ -1458,3 +1458,576 @@ FWHT Flags
.. raw:: latex
\normalsize
+
+.. _v4l2-codec-stateless-vp9:
+
+``V4L2_CID_STATELESS_VP9_COMPRESSED_HDR (struct)``
+ Stores VP9 probabilities updates as parsed from the current compressed frame
+ header. A value of zero in an array element means no update of the relevant
+ probability. Motion vector-related updates contain a new value or zero. All
+ other updates contain values translated with inv_map_table[] (see 6.3.5 in
+ :ref:`vp9`).
+
+.. c:type:: v4l2_ctrl_vp9_compressed_hdr
+
+.. tabularcolumns:: |p{1cm}|p{4.8cm}|p{11.4cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_vp9_compressed_hdr
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - __u8
+ - ``tx_mode``
+ - Specifies the TX mode. See :ref:`TX Mode <vp9_tx_mode>` for more details.
+ * - __u8
+ - ``tx8[2][1]``
+ - TX 8x8 probabilities delta.
+ * - __u8
+ - ``tx16[2][2]``
+ - TX 16x16 probabilities delta.
+ * - __u8
+ - ``tx32[2][3]``
+ - TX 32x32 probabilities delta.
+ * - __u8
+ - ``coef[4][2][2][6][6][3]``
+ - Coefficient probabilities delta.
+ * - __u8
+ - ``skip[3]``
+ - Skip probabilities delta.
+ * - __u8
+ - ``inter_mode[7][3]``
+ - Inter prediction mode probabilities delta.
+ * - __u8
+ - ``interp_filter[4][2]``
+ - Interpolation filter probabilities delta.
+ * - __u8
+ - ``is_inter[4]``
+ - Is inter-block probabilities delta.
+ * - __u8
+ - ``comp_mode[5]``
+ - Compound prediction mode probabilities delta.
+ * - __u8
+ - ``single_ref[5][2]``
+ - Single reference probabilities delta.
+ * - __u8
+ - ``comp_ref[5]``
+ - Compound reference probabilities delta.
+ * - __u8
+ - ``y_mode[4][9]``
+ - Y prediction mode probabilities delta.
+ * - __u8
+ - ``uv_mode[10][9]``
+ - UV prediction mode probabilities delta.
+ * - __u8
+ - ``partition[16][3]``
+ - Partition probabilities delta.
+ * - __u8
+ - ``mv.joint[3]``
+ - Motion vector joint probabilities delta.
+ * - __u8
+ - ``mv.sign[2]``
+ - Motion vector sign probabilities delta.
+ * - __u8
+ - ``mv.classes[2][10]``
+ - Motion vector class probabilities delta.
+ * - __u8
+ - ``mv.class0_bit[2]``
+ - Motion vector class0 bit probabilities delta.
+ * - __u8
+ - ``mv.bits[2][10]``
+ - Motion vector bits probabilities delta.
+ * - __u8
+ - ``mv.class0_fr[2][2][3]``
+ - Motion vector class0 fractional bit probabilities delta.
+ * - __u8
+ - ``mv.fr[2][3]``
+ - Motion vector fractional bit probabilities delta.
+ * - __u8
+ - ``mv.class0_hp[2]``
+ - Motion vector class0 high precision fractional bit probabilities delta.
+ * - __u8
+ - ``mv.hp[2]``
+ - Motion vector high precision fractional bit probabilities delta.
+
+.. _vp9_tx_mode:
+
+``TX Mode``
+
+.. tabularcolumns:: |p{6.5cm}|p{0.5cm}|p{10.3cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_TX_MODE_ONLY_4X4``
+ - 0
+ - Transform size is 4x4.
+ * - ``V4L2_VP9_TX_MODE_ALLOW_8X8``
+ - 1
+ - Transform size can be up to 8x8.
+ * - ``V4L2_VP9_TX_MODE_ALLOW_16X16``
+ - 2
+ - Transform size can be up to 16x16.
+ * - ``V4L2_VP9_TX_MODE_ALLOW_32X32``
+ - 3
+ - transform size can be up to 32x32.
+ * - ``V4L2_VP9_TX_MODE_SELECT``
+ - 4
+ - Bitstream contains the transform size for each block.
+
+See section '7.3.1 Tx mode semantics' of the :ref:`vp9` specification for more details.
+
+``V4L2_CID_STATELESS_VP9_FRAME (struct)``
+ Specifies the frame parameters for the associated VP9 frame decode request.
+ This includes the necessary parameters for configuring a stateless hardware
+ decoding pipeline for VP9. The bitstream parameters are defined according
+ to :ref:`vp9`.
+
+.. c:type:: v4l2_ctrl_vp9_frame
+
+.. raw:: latex
+
+ \small
+
+.. tabularcolumns:: |p{4.7cm}|p{5.5cm}|p{7.1cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_ctrl_vp9_frame
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - struct :c:type:`v4l2_vp9_loop_filter`
+ - ``lf``
+ - Loop filter parameters. See struct :c:type:`v4l2_vp9_loop_filter` for more details.
+ * - struct :c:type:`v4l2_vp9_quantization`
+ - ``quant``
+ - Quantization parameters. See :c:type:`v4l2_vp9_quantization` for more details.
+ * - struct :c:type:`v4l2_vp9_segmentation`
+ - ``seg``
+ - Segmentation parameters. See :c:type:`v4l2_vp9_segmentation` for more details.
+ * - __u32
+ - ``flags``
+ - Combination of V4L2_VP9_FRAME_FLAG_* flags. See :ref:`Frame Flags<vp9_frame_flags>`.
+ * - __u16
+ - ``compressed_header_size``
+ - Compressed header size in bytes.
+ * - __u16
+ - ``uncompressed_header_size``
+ - Uncompressed header size in bytes.
+ * - __u16
+ - ``frame_width_minus_1``
+ - Add 1 to get the frame width expressed in pixels. See section 7.2.3 in :ref:`vp9`.
+ * - __u16
+ - ``frame_height_minus_1``
+ - Add 1 to get the frame height expressed in pixels. See section 7.2.3 in :ref:`vp9`.
+ * - __u16
+ - ``render_width_minus_1``
+ - Add 1 to get the expected render width expressed in pixels. This is
+ not used during the decoding process but might be used by HW scalers to
+ prepare a frame that's ready for scanout. See section 7.2.4 in :ref:`vp9`.
+ * - __u16
+ - render_height_minus_1
+ - Add 1 to get the expected render height expressed in pixels. This is
+ not used during the decoding process but might be used by HW scalers to
+ prepare a frame that's ready for scanout. See section 7.2.4 in :ref:`vp9`.
+ * - __u64
+ - ``last_frame_ts``
+ - "last" reference buffer timestamp.
+ The timestamp refers to the ``timestamp`` field in
+ struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+ function to convert the struct :c:type:`timeval` in struct
+ :c:type:`v4l2_buffer` to a __u64.
+ * - __u64
+ - ``golden_frame_ts``
+ - "golden" reference buffer timestamp.
+ The timestamp refers to the ``timestamp`` field in
+ struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+ function to convert the struct :c:type:`timeval` in struct
+ :c:type:`v4l2_buffer` to a __u64.
+ * - __u64
+ - ``alt_frame_ts``
+ - "alt" reference buffer timestamp.
+ The timestamp refers to the ``timestamp`` field in
+ struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+ function to convert the struct :c:type:`timeval` in struct
+ :c:type:`v4l2_buffer` to a __u64.
+ * - __u8
+ - ``ref_frame_sign_bias``
+ - a bitfield specifying whether the sign bias is set for a given
+ reference frame. See :ref:`Reference Frame Sign Bias<vp9_ref_frame_sign_bias>`
+ for more details.
+ * - __u8
+ - ``reset_frame_context``
+ - specifies whether the frame context should be reset to default values. See
+ :ref:`Reset Frame Context<vp9_reset_frame_context>` for more details.
+ * - __u8
+ - ``frame_context_idx``
+ - Frame context that should be used/updated.
+ * - __u8
+ - ``profile``
+ - VP9 profile. Can be 0, 1, 2 or 3.
+ * - __u8
+ - ``bit_depth``
+ - Component depth in bits. Can be 8, 10 or 12. Note that not all profiles
+ support 10 and/or 12 bits depths.
+ * - __u8
+ - ``interpolation_filter``
+ - Specifies the filter selection used for performing inter prediction. See
+ :ref:`Interpolation Filter<vp9_interpolation_filter>` for more details.
+ * - __u8
+ - ``tile_cols_log2``
+ - Specifies the base 2 logarithm of the width of each tile (where the
+ width is measured in units of 8x8 blocks). Shall be less than or equal
+ to 6.
+ * - __u8
+ - ``tile_rows_log2``
+ - Specifies the base 2 logarithm of the height of each tile (where the
+ height is measured in units of 8x8 blocks).
+ * - __u8
+ - ``reference_mode``
+ - Specifies the type of inter prediction to be used. See
+ :ref:`Reference Mode<vp9_reference_mode>` for more details.
+ * - __u8
+ - ``reserved[7]``
+ - Applications and drivers must set this to zero.
+
+.. raw:: latex
+
+ \normalsize
+
+.. _vp9_frame_flags:
+
+``Frame Flags``
+
+.. tabularcolumns:: |p{10.0cm}|p{1.2cm}|p{6.1cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_FRAME_FLAG_KEY_FRAME``
+ - 0x001
+ - The frame is a key frame.
+ * - ``V4L2_VP9_FRAME_FLAG_SHOW_FRAME``
+ - 0x002
+ - The frame should be displayed.
+ * - ``V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT``
+ - 0x004
+ - The decoding should be error resilient.
+ * - ``V4L2_VP9_FRAME_FLAG_INTRA_ONLY``
+ - 0x008
+ - The frame does not reference other frames.
+ * - ``V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV``
+ - 0x010
+ - The frame can use high precision motion vectors.
+ * - ``V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX``
+ - 0x020
+ - Frame context should be updated after decoding.
+ * - ``V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE``
+ - 0x040
+ - Parallel decoding is used.
+ * - ``V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING``
+ - 0x080
+ - Vertical subsampling is enabled.
+ * - ``V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING``
+ - 0x100
+ - Horizontal subsampling is enabled.
+ * - ``V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING``
+ - 0x200
+ - The full UV range is used.
+
+.. _vp9_ref_frame_sign_bias:
+
+``Reference Frame Sign Bias``
+
+.. tabularcolumns:: |p{7.0cm}|p{1.2cm}|p{9.1cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_SIGN_BIAS_LAST``
+ - 0x1
+ - Sign bias is set for the last reference frame.
+ * - ``V4L2_VP9_SIGN_BIAS_GOLDEN``
+ - 0x2
+ - Sign bias is set for the golden reference frame.
+ * - ``V4L2_VP9_SIGN_BIAS_ALT``
+ - 0x2
+ - Sign bias is set for the alt reference frame.
+
+.. _vp9_reset_frame_context:
+
+``Reset Frame Context``
+
+.. tabularcolumns:: |p{7.0cm}|p{1.2cm}|p{9.1cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_RESET_FRAME_CTX_NONE``
+ - 0
+ - Do not reset any frame context.
+ * - ``V4L2_VP9_RESET_FRAME_CTX_SPEC``
+ - 1
+ - Reset the frame context pointed to by
+ :c:type:`v4l2_ctrl_vp9_frame`.frame_context_idx.
+ * - ``V4L2_VP9_RESET_FRAME_CTX_ALL``
+ - 2
+ - Reset all frame contexts.
+
+See section '7.2 Uncompressed header semantics' of the :ref:`vp9` specification
+for more details.
+
+.. _vp9_interpolation_filter:
+
+``Interpolation Filter``
+
+.. tabularcolumns:: |p{9.0cm}|p{1.2cm}|p{7.1cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP``
+ - 0
+ - Eight tap filter.
+ * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH``
+ - 1
+ - Eight tap smooth filter.
+ * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP``
+ - 2
+ - Eeight tap sharp filter.
+ * - ``V4L2_VP9_INTERP_FILTER_BILINEAR``
+ - 3
+ - Bilinear filter.
+ * - ``V4L2_VP9_INTERP_FILTER_SWITCHABLE``
+ - 4
+ - Filter selection is signaled at the block level.
+
+See section '7.2.7 Interpolation filter semantics' of the :ref:`vp9` specification
+for more details.
+
+.. _vp9_reference_mode:
+
+``Reference Mode``
+
+.. tabularcolumns:: |p{9.6cm}|p{0.5cm}|p{7.2cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE``
+ - 0
+ - Indicates that all the inter blocks use only a single reference frame
+ to generate motion compensated prediction.
+ * - ``V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE``
+ - 1
+ - Requires all the inter blocks to use compound mode. Single reference
+ frame prediction is not allowed.
+ * - ``V4L2_VP9_REFERENCE_MODE_SELECT``
+ - 2
+ - Allows each individual inter block to select between single and
+ compound prediction modes.
+
+See section '7.3.6 Frame reference mode semantics' of the :ref:`vp9` specification for more details.
+
+.. c:type:: v4l2_vp9_segmentation
+
+Encodes the quantization parameters. See section '7.2.10 Segmentation
+params syntax' of the :ref:`vp9` specification for more details.
+
+.. tabularcolumns:: |p{0.8cm}|p{5cm}|p{11.4cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_vp9_segmentation
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - __u8
+ - ``feature_data[8][4]``
+ - Data attached to each feature. Data entry is only valid if the feature
+ is enabled. The array shall be indexed with segment number as the first dimension
+ (0..7) and one of V4L2_VP9_SEG_* as the second dimension.
+ See :ref:`Segment Feature IDs<vp9_segment_feature>`.
+ * - __u8
+ - ``feature_enabled[8]``
+ - Bitmask defining which features are enabled in each segment. The value for each
+ segment is a combination of V4L2_VP9_SEGMENT_FEATURE_ENABLED(id) values where id is
+ one of V4L2_VP9_SEG_*. See :ref:`Segment Feature IDs<vp9_segment_feature>`.
+ * - __u8
+ - ``tree_probs[7]``
+ - Specifies the probability values to be used when decoding a Segment-ID.
+ See '5.15. Segmentation map' section of :ref:`vp9` for more details.
+ * - __u8
+ - ``pred_probs[3]``
+ - Specifies the probability values to be used when decoding a
+ Predicted-Segment-ID. See '6.4.14. Get segment id syntax'
+ section of :ref:`vp9` for more details.
+ * - __u8
+ - ``flags``
+ - Combination of V4L2_VP9_SEGMENTATION_FLAG_* flags. See
+ :ref:`Segmentation Flags<vp9_segmentation_flags>`.
+ * - __u8
+ - ``reserved[5]``
+ - Applications and drivers must set this to zero.
+
+.. _vp9_segment_feature:
+
+``Segment feature IDs``
+
+.. tabularcolumns:: |p{6.0cm}|p{1cm}|p{10.3cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_SEG_LVL_ALT_Q``
+ - 0
+ - Quantizer segment feature.
+ * - ``V4L2_VP9_SEG_LVL_ALT_L``
+ - 1
+ - Loop filter segment feature.
+ * - ``V4L2_VP9_SEG_LVL_REF_FRAME``
+ - 2
+ - Reference frame segment feature.
+ * - ``V4L2_VP9_SEG_LVL_SKIP``
+ - 3
+ - Skip segment feature.
+ * - ``V4L2_VP9_SEG_LVL_MAX``
+ - 4
+ - Number of segment features.
+
+.. _vp9_segmentation_flags:
+
+``Segmentation Flags``
+
+.. tabularcolumns:: |p{10.6cm}|p{0.8cm}|p{5.9cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_SEGMENTATION_FLAG_ENABLED``
+ - 0x01
+ - Indicates that this frame makes use of the segmentation tool.
+ * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP``
+ - 0x02
+ - Indicates that the segmentation map should be updated during the
+ decoding of this frame.
+ * - ``V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE``
+ - 0x04
+ - Indicates that the updates to the segmentation map are coded
+ relative to the existing segmentation map.
+ * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA``
+ - 0x08
+ - Indicates that new parameters are about to be specified for each
+ segment.
+ * - ``V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE``
+ - 0x10
+ - Indicates that the segmentation parameters represent the actual values
+ to be used.
+
+.. c:type:: v4l2_vp9_quantization
+
+Encodes the quantization parameters. See section '7.2.9 Quantization params
+syntax' of the VP9 specification for more details.
+
+.. tabularcolumns:: |p{0.8cm}|p{4cm}|p{12.4cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_vp9_quantization
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - __u8
+ - ``base_q_idx``
+ - Indicates the base frame qindex.
+ * - __s8
+ - ``delta_q_y_dc``
+ - Indicates the Y DC quantizer relative to base_q_idx.
+ * - __s8
+ - ``delta_q_uv_dc``
+ - Indicates the UV DC quantizer relative to base_q_idx.
+ * - __s8
+ - ``delta_q_uv_ac``
+ - Indicates the UV AC quantizer relative to base_q_idx.
+ * - __u8
+ - ``reserved[4]``
+ - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp9_loop_filter
+
+This structure contains all loop filter related parameters. See sections
+'7.2.8 Loop filter semantics' of the :ref:`vp9` specification for more details.
+
+.. tabularcolumns:: |p{0.8cm}|p{4cm}|p{12.4cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: struct v4l2_vp9_loop_filter
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - __s8
+ - ``ref_deltas[4]``
+ - Contains the adjustment needed for the filter level based on the chosen
+ reference frame.
+ * - __s8
+ - ``mode_deltas[2]``
+ - Contains the adjustment needed for the filter level based on the chosen
+ mode.
+ * - __u8
+ - ``level``
+ - Indicates the loop filter strength.
+ * - __u8
+ - ``sharpness``
+ - Indicates the sharpness level.
+ * - __u8
+ - ``flags``
+ - Combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags.
+ See :ref:`Loop Filter Flags <vp9_loop_filter_flags>`.
+ * - __u8
+ - ``reserved[7]``
+ - Applications and drivers must set this to zero.
+
+
+.. _vp9_loop_filter_flags:
+
+``Loop Filter Flags``
+
+.. tabularcolumns:: |p{9.6cm}|p{0.5cm}|p{7.2cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+ :widths: 1 1 2
+
+ * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED``
+ - 0x1
+ - When set, the filter level depends on the mode and reference frame used
+ to predict a block.
+ * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE``
+ - 0x2
+ - When set, the bitstream contains additional syntax elements that
+ specify which mode and reference frame deltas are to be updated.
diff --git a/Documentation/userspace-api/media/v4l/libv4l-introduction.rst b/Documentation/userspace-api/media/v4l/libv4l-introduction.rst
index 05690f2358ce..90215313b965 100644
--- a/Documentation/userspace-api/media/v4l/libv4l-introduction.rst
+++ b/Documentation/userspace-api/media/v4l/libv4l-introduction.rst
@@ -26,7 +26,7 @@ found in V4L2 drivers into a few common RGB and YUY formats.
It currently accepts the following V4L2 driver formats:
:ref:`V4L2_PIX_FMT_BGR24 <V4L2-PIX-FMT-BGR24>`,
-:ref:`V4L2_PIX_FMT_HM12 <V4L2-PIX-FMT-HM12>`,
+:ref:`V4L2_PIX_FMT_NV12_16L16 <V4L2-PIX-FMT-NV12-16L16>`,
:ref:`V4L2_PIX_FMT_JPEG <V4L2-PIX-FMT-JPEG>`,
:ref:`V4L2_PIX_FMT_MJPEG <V4L2-PIX-FMT-MJPEG>`,
:ref:`V4L2_PIX_FMT_MR97310A <V4L2-PIX-FMT-MR97310A>`,
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
index 0ede39907ee2..967fc803ef94 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
@@ -172,6 +172,21 @@ Compressed Formats
- VP9 compressed video frame. The encoder generates one
compressed frame per buffer, and the decoder requires one
compressed frame per buffer.
+ * .. _V4L2-PIX-FMT-VP9-FRAME:
+
+ - ``V4L2_PIX_FMT_VP9_FRAME``
+ - 'VP9F'
+ - VP9 parsed frame, including the frame header, as extracted from the container.
+ This format is adapted for stateless video decoders that implement a
+ VP9 pipeline with the :ref:`stateless_decoder`.
+ Metadata associated with the frame to decode is required to be passed
+ through the ``V4L2_CID_STATELESS_VP9_FRAME`` and
+ the ``V4L2_CID_STATELESS_VP9_COMPRESSED_HDR`` controls.
+ See the :ref:`associated Codec Control IDs <v4l2-codec-stateless-vp9>`.
+ Exactly one output and one capture buffer must be provided for use with
+ this pixel format. The output buffer must contain the appropriate number
+ of macroblocks to decode a full corresponding frame to the matching
+ capture buffer.
* .. _V4L2-PIX-FMT-HEVC:
- ``V4L2_PIX_FMT_HEVC``
diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst
index bd68588b2683..0cbc045d5df6 100644
--- a/Documentation/userspace-api/media/v4l/subdev-formats.rst
+++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst
@@ -7833,7 +7833,7 @@ The following table lists existing HSV/HSL formats.
.. raw:: latex
- \normalsize
+ \endgroup
JPEG Compressed Formats
diff --git a/Documentation/userspace-api/media/v4l/v4l2grab.c.rst b/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
index eaa0f95048e7..b38f661da733 100644
--- a/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
+++ b/Documentation/userspace-api/media/v4l/v4l2grab.c.rst
@@ -46,7 +46,7 @@ file: media/v4l/v4l2grab.c
} while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
if (r == -1) {
- fprintf(stderr, "error %d, %s\\n", errno, strerror(errno));
+ fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
@@ -80,11 +80,11 @@ file: media/v4l/v4l2grab.c
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
xioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
- printf("Libv4l didn't accept RGB24 format. Can't proceed.\\n");
+ printf("Libv4l didn't accept RGB24 format. Can't proceed.\n");
exit(EXIT_FAILURE);
}
if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
- printf("Warning: driver is sending image at %dx%d\\n",
+ printf("Warning: driver is sending image at %dx%d\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
CLEAR(req);
@@ -151,7 +151,7 @@ file: media/v4l/v4l2grab.c
perror("Cannot open image");
exit(EXIT_FAILURE);
}
- fprintf(fout, "P6\\n%d %d 255\\n",
+ fprintf(fout, "P6\n%d %d 255\n",
fmt.fmt.pix.width, fmt.fmt.pix.height);
fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
fclose(fout);
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
index fdde0ae6d521..29971a45a2d4 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
@@ -233,6 +233,14 @@ still cause this situation.
- ``p_mpeg2_quantisation``
- A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_quantisation`. Valid if this control is
of type ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION``.
+ * - struct :c:type:`v4l2_ctrl_vp9_compressed_hdr` *
+ - ``p_vp9_compressed_hdr_probs``
+ - A pointer to a struct :c:type:`v4l2_ctrl_vp9_compressed_hdr`. Valid if this
+ control is of type ``V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR``.
+ * - struct :c:type:`v4l2_ctrl_vp9_frame` *
+ - ``p_vp9_frame``
+ - A pointer to a struct :c:type:`v4l2_ctrl_vp9_frame`. Valid if this
+ control is of type ``V4L2_CTRL_TYPE_VP9_FRAME``.
* - struct :c:type:`v4l2_ctrl_hdr10_cll_info` *
- ``p_hdr10_cll``
- A pointer to a struct :c:type:`v4l2_ctrl_hdr10_cll_info`. Valid if this control is
diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
index 2f491c17dd5d..88f630252d98 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -513,6 +513,18 @@ See also the examples in :ref:`control`.
- n/a
- A struct :c:type:`v4l2_ctrl_hevc_decode_params`, containing HEVC
decoding parameters for stateless video decoders.
+ * - ``V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR``
+ - n/a
+ - n/a
+ - n/a
+ - A struct :c:type:`v4l2_ctrl_vp9_compressed_hdr`, containing VP9
+ probabilities updates for stateless video decoders.
+ * - ``V4L2_CTRL_TYPE_VP9_FRAME``
+ - n/a
+ - n/a
+ - n/a
+ - A struct :c:type:`v4l2_ctrl_vp9_frame`, containing VP9
+ frame decode parameters for stateless video decoders.
.. raw:: latex
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index eb0b1cd37abd..9cbb7a0c354a 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -149,6 +149,8 @@ replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_VP8_FRAME :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_VP9_FRAME :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HDR10_CLL_INFO :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY :c:type:`v4l2_ctrl_type`
diff --git a/MAINTAINERS b/MAINTAINERS
index a439c9d486fa..716354045657 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1140,6 +1140,7 @@ ANALOG DEVICES INC ADV748X DRIVER
M: Kieran Bingham <kieran.bingham@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/adv748x.yaml
F: drivers/media/i2c/adv748x/*
ANALOG DEVICES INC ADV7511 DRIVER
@@ -2583,7 +2584,7 @@ N: s3c64xx
N: s5pv210
ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT
-M: Andrzej Hajda <a.hajda@samsung.com>
+M: Łukasz Stelmach <l.stelmach@samsung.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
S: Maintained
@@ -2607,7 +2608,8 @@ S: Maintained
F: drivers/media/platform/s5p-jpeg/
ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
-M: Andrzej Hajda <a.hajda@samsung.com>
+M: Marek Szyprowski <m.szyprowski@samsung.com>
+M: Andrzej Hajda <andrzej.hajda@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
S: Maintained
@@ -6327,7 +6329,7 @@ F: Documentation/devicetree/bindings/display/atmel/
F: drivers/gpu/drm/atmel-hlcdc/
DRM DRIVERS FOR BRIDGE CHIPS
-M: Andrzej Hajda <a.hajda@samsung.com>
+M: Andrzej Hajda <andrzej.hajda@intel.com>
M: Neil Armstrong <narmstrong@baylibre.com>
M: Robert Foss <robert.foss@linaro.org>
R: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
@@ -11562,6 +11564,12 @@ S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
F: drivers/media/i2c/max9286.c
+MAX96712 QUAD GMSL2 DESERIALIZER DRIVER
+M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/staging/media/max96712/max96712.c
+
MAX9860 MONO AUDIO VOICE CODEC DRIVER
M: Peter Rosin <peda@axentia.se>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
@@ -14126,7 +14134,6 @@ F: drivers/media/i2c/ov5647.c
OMNIVISION OV5670 SENSOR DRIVER
M: Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
-M: Hyungwoo Yang <hyungwoo.yang@intel.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
@@ -14139,6 +14146,13 @@ S: Maintained
T: git git://linuxtv.org/media_tree.git
F: drivers/media/i2c/ov5675.c
+OMNIVISION OV5693 SENSOR DRIVER
+M: Daniel Scally <djrscally@gmail.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+T: git git://linuxtv.org/media_tree.git
+F: drivers/media/i2c/ov5693.c
+
OMNIVISION OV5695 SENSOR DRIVER
M: Shunqian Zheng <zhengsq@rock-chips.com>
L: linux-media@vger.kernel.org
@@ -16866,13 +16880,15 @@ F: Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml
F: drivers/nfc/s3fwrn5
SAMSUNG S5C73M3 CAMERA DRIVER
-M: Andrzej Hajda <a.hajda@samsung.com>
+M: Sylwester Nawrocki <s.nawrocki@samsung.com>
+M: Andrzej Hajda <andrzej.hajda@intel.com>
L: linux-media@vger.kernel.org
S: Supported
F: drivers/media/i2c/s5c73m3/*
SAMSUNG S5K5BAF CAMERA DRIVER
-M: Andrzej Hajda <a.hajda@samsung.com>
+M: Sylwester Nawrocki <s.nawrocki@samsung.com>
+M: Andrzej Hajda <andrzej.hajda@intel.com>
L: linux-media@vger.kernel.org
S: Supported
F: drivers/media/i2c/s5k5baf.c
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 2c80765670bc..89c4ae6ef3ec 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -797,6 +797,12 @@ static const char * const acpi_ignore_dep_ids[] = {
NULL
};
+/* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */
+static const char * const acpi_honor_dep_ids[] = {
+ "INT3472", /* Camera sensor PMIC / clk and regulator info */
+ NULL
+};
+
static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
{
struct acpi_device *device = NULL;
@@ -1762,8 +1768,12 @@ static void acpi_scan_dep_init(struct acpi_device *adev)
struct acpi_dep_data *dep;
list_for_each_entry(dep, &acpi_dep_list, node) {
- if (dep->consumer == adev->handle)
+ if (dep->consumer == adev->handle) {
+ if (dep->honor_dep)
+ adev->flags.honor_deps = 1;
+
adev->dep_unmet++;
+ }
}
}
@@ -1967,7 +1977,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
for (count = 0, i = 0; i < dep_devices.count; i++) {
struct acpi_device_info *info;
struct acpi_dep_data *dep;
- bool skip;
+ bool skip, honor_dep;
status = acpi_get_object_info(dep_devices.handles[i], &info);
if (ACPI_FAILURE(status)) {
@@ -1976,6 +1986,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
}
skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids);
+ honor_dep = acpi_info_matches_ids(info, acpi_honor_dep_ids);
kfree(info);
if (skip)
@@ -1989,6 +2000,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
dep->supplier = dep_devices.handles[i];
dep->consumer = handle;
+ dep->honor_dep = honor_dep;
mutex_lock(&acpi_dep_list_lock);
list_add_tail(&dep->node , &acpi_dep_list);
@@ -2155,8 +2167,8 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
register_dock_dependent_device(device, ejd);
acpi_bus_get_status(device);
- /* Skip devices that are not present. */
- if (!acpi_device_is_present(device)) {
+ /* Skip devices that are not ready for enumeration (e.g. not present) */
+ if (!acpi_dev_ready_for_enumeration(device)) {
device->flags.initialized = false;
acpi_device_clear_enumerated(device);
device->flags.power_manageable = 0;
@@ -2319,6 +2331,23 @@ void acpi_dev_clear_dependencies(struct acpi_device *supplier)
EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
/**
+ * acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration
+ * @device: Pointer to the &struct acpi_device to check
+ *
+ * Check if the device is present and has no unmet dependencies.
+ *
+ * Return true if the device is ready for enumeratino. Otherwise, return false.
+ */
+bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
+{
+ if (device->flags.honor_deps && device->dep_unmet)
+ return false;
+
+ return acpi_device_is_present(device);
+}
+EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
+
+/**
* acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
* @supplier: Pointer to the dependee device
*
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index 92c1cc07ed46..c87ce2276007 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -144,9 +144,12 @@ static int i2c_acpi_do_lookup(struct acpi_device *adev,
struct list_head resource_list;
int ret;
- if (acpi_bus_get_status(adev) || !adev->status.present)
+ if (acpi_bus_get_status(adev))
return -EINVAL;
+ if (!acpi_dev_ready_for_enumeration(adev))
+ return -ENODEV;
+
if (acpi_match_device_ids(adev, i2c_acpi_ignored_device_ids) == 0)
return -ENODEV;
@@ -473,8 +476,8 @@ struct notifier_block i2c_acpi_notifier = {
};
/**
- * i2c_acpi_new_device - Create i2c-client for the Nth I2cSerialBus resource
- * @dev: Device owning the ACPI resources to get the client from
+ * i2c_acpi_new_device_by_fwnode - Create i2c-client for the Nth I2cSerialBus resource
+ * @fwnode: fwnode with the ACPI resources to get the client from
* @index: Index of ACPI resource to get
* @info: describes the I2C device; note this is modified (addr gets set)
* Context: can sleep
@@ -490,15 +493,20 @@ struct notifier_block i2c_acpi_notifier = {
* Returns a pointer to the new i2c-client, or error pointer in case of failure.
* Specifically, -EPROBE_DEFER is returned if the adapter is not found.
*/
-struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
- struct i2c_board_info *info)
+struct i2c_client *i2c_acpi_new_device_by_fwnode(struct fwnode_handle *fwnode,
+ int index,
+ struct i2c_board_info *info)
{
- struct acpi_device *adev = ACPI_COMPANION(dev);
struct i2c_acpi_lookup lookup;
struct i2c_adapter *adapter;
+ struct acpi_device *adev;
LIST_HEAD(resource_list);
int ret;
+ adev = to_acpi_device_node(fwnode);
+ if (!adev)
+ return ERR_PTR(-ENODEV);
+
memset(&lookup, 0, sizeof(lookup));
lookup.info = info;
lookup.device_handle = acpi_device_handle(adev);
@@ -520,7 +528,7 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
return i2c_new_client_device(adapter, info);
}
-EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
+EXPORT_SYMBOL_GPL(i2c_acpi_new_device_by_fwnode);
bool i2c_acpi_waive_d0_probe(struct device *dev)
{
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index b07812657cee..f3f24c63536b 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -141,10 +141,10 @@ config MEDIA_TEST_SUPPORT
prompt "Test drivers" if MEDIA_SUPPORT_FILTER
default y if !MEDIA_SUPPORT_FILTER
help
- Those drivers should not be used on production Kernels, but
- can be useful on debug ones. It enables several dummy drivers
- that simulate a real hardware. Very useful to test userspace
- applications and to validate if the subsystem core is doesn't
+ These drivers should not be used on production kernels, but
+ can be useful on debug ones. This option enables several dummy drivers
+ that simulate real hardware. Very useful to test userspace
+ applications and to validate if the subsystem core doesn't
have regressions.
Say Y if you want to use some virtual test driver.
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
index cd9cb354dc2c..2e12331c12a9 100644
--- a/drivers/media/cec/core/cec-adap.c
+++ b/drivers/media/cec/core/cec-adap.c
@@ -161,10 +161,10 @@ static void cec_queue_event(struct cec_adapter *adap,
u64 ts = ktime_get_ns();
struct cec_fh *fh;
- mutex_lock(&adap->devnode.lock);
+ mutex_lock(&adap->devnode.lock_fhs);
list_for_each_entry(fh, &adap->devnode.fhs, list)
cec_queue_event_fh(fh, ev, ts);
- mutex_unlock(&adap->devnode.lock);
+ mutex_unlock(&adap->devnode.lock_fhs);
}
/* Notify userspace that the CEC pin changed state at the given time. */
@@ -178,11 +178,12 @@ void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
};
struct cec_fh *fh;
- mutex_lock(&adap->devnode.lock);
- list_for_each_entry(fh, &adap->devnode.fhs, list)
+ mutex_lock(&adap->devnode.lock_fhs);
+ list_for_each_entry(fh, &adap->devnode.fhs, list) {
if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
- mutex_unlock(&adap->devnode.lock);
+ }
+ mutex_unlock(&adap->devnode.lock_fhs);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event);
@@ -195,10 +196,10 @@ void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
};
struct cec_fh *fh;
- mutex_lock(&adap->devnode.lock);
+ mutex_lock(&adap->devnode.lock_fhs);
list_for_each_entry(fh, &adap->devnode.fhs, list)
cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
- mutex_unlock(&adap->devnode.lock);
+ mutex_unlock(&adap->devnode.lock_fhs);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event);
@@ -211,10 +212,10 @@ void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
};
struct cec_fh *fh;
- mutex_lock(&adap->devnode.lock);
+ mutex_lock(&adap->devnode.lock_fhs);
list_for_each_entry(fh, &adap->devnode.fhs, list)
cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
- mutex_unlock(&adap->devnode.lock);
+ mutex_unlock(&adap->devnode.lock_fhs);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_5v_event);
@@ -286,12 +287,12 @@ static void cec_queue_msg_monitor(struct cec_adapter *adap,
u32 monitor_mode = valid_la ? CEC_MODE_MONITOR :
CEC_MODE_MONITOR_ALL;
- mutex_lock(&adap->devnode.lock);
+ mutex_lock(&adap->devnode.lock_fhs);
list_for_each_entry(fh, &adap->devnode.fhs, list) {
if (fh->mode_follower >= monitor_mode)
cec_queue_msg_fh(fh, msg);
}
- mutex_unlock(&adap->devnode.lock);
+ mutex_unlock(&adap->devnode.lock_fhs);
}
/*
@@ -302,12 +303,12 @@ static void cec_queue_msg_followers(struct cec_adapter *adap,
{
struct cec_fh *fh;
- mutex_lock(&adap->devnode.lock);
+ mutex_lock(&adap->devnode.lock_fhs);
list_for_each_entry(fh, &adap->devnode.fhs, list) {
if (fh->mode_follower == CEC_MODE_FOLLOWER)
cec_queue_msg_fh(fh, msg);
}
- mutex_unlock(&adap->devnode.lock);
+ mutex_unlock(&adap->devnode.lock_fhs);
}
/* Notify userspace of an adapter state change. */
@@ -342,7 +343,7 @@ static void cec_data_completed(struct cec_data *data)
* Without that we would be referring to a closed filehandle.
*/
if (data->fh)
- list_del(&data->xfer_list);
+ list_del_init(&data->xfer_list);
if (data->blocking) {
/*
@@ -898,6 +899,8 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
if (fh)
list_add_tail(&data->xfer_list, &fh->xfer_list);
+ else
+ INIT_LIST_HEAD(&data->xfer_list);
list_add_tail(&data->list, &adap->transmit_queue);
adap->transmit_queue_sz++;
@@ -923,6 +926,10 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
/* The transmit completed (possibly with an error) */
*msg = data->msg;
+ if (WARN_ON(!list_empty(&data->list)))
+ list_del(&data->list);
+ if (WARN_ON(!list_empty(&data->xfer_list)))
+ list_del(&data->xfer_list);
kfree(data);
return 0;
}
@@ -1573,6 +1580,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
/* Disabling monitor all mode should always succeed */
if (adap->monitor_all_cnt)
WARN_ON(call_op(adap, adap_monitor_all_enable, false));
+ /* serialize adap_enable */
mutex_lock(&adap->devnode.lock);
if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
WARN_ON(adap->ops->adap_enable(adap, false));
@@ -1584,14 +1592,16 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
return;
}
+ /* serialize adap_enable */
mutex_lock(&adap->devnode.lock);
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
- if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
- adap->ops->adap_enable(adap, true)) {
- mutex_unlock(&adap->devnode.lock);
- return;
+ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) {
+ if (adap->ops->adap_enable(adap, true)) {
+ mutex_unlock(&adap->devnode.lock);
+ return;
+ }
}
if (adap->monitor_all_cnt &&
diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c
index 769e6b4cddce..d72ad48c9898 100644
--- a/drivers/media/cec/core/cec-api.c
+++ b/drivers/media/cec/core/cec-api.c
@@ -586,6 +586,7 @@ static int cec_open(struct inode *inode, struct file *filp)
return err;
}
+ /* serialize adap_enable */
mutex_lock(&devnode->lock);
if (list_empty(&devnode->fhs) &&
!adap->needs_hpd &&
@@ -624,7 +625,9 @@ static int cec_open(struct inode *inode, struct file *filp)
}
#endif
+ mutex_lock(&devnode->lock_fhs);
list_add(&fh->list, &devnode->fhs);
+ mutex_unlock(&devnode->lock_fhs);
mutex_unlock(&devnode->lock);
return 0;
@@ -653,8 +656,11 @@ static int cec_release(struct inode *inode, struct file *filp)
cec_monitor_all_cnt_dec(adap);
mutex_unlock(&adap->lock);
+ /* serialize adap_enable */
mutex_lock(&devnode->lock);
+ mutex_lock(&devnode->lock_fhs);
list_del(&fh->list);
+ mutex_unlock(&devnode->lock_fhs);
if (cec_is_registered(adap) && list_empty(&devnode->fhs) &&
!adap->needs_hpd && adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
WARN_ON(adap->ops->adap_enable(adap, false));
@@ -669,7 +675,7 @@ static int cec_release(struct inode *inode, struct file *filp)
data->blocking = false;
data->fh = NULL;
- list_del(&data->xfer_list);
+ list_del_init(&data->xfer_list);
}
mutex_unlock(&adap->lock);
while (!list_empty(&fh->msgs)) {
diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c
index 551689d371a7..ec67065d5202 100644
--- a/drivers/media/cec/core/cec-core.c
+++ b/drivers/media/cec/core/cec-core.c
@@ -169,8 +169,10 @@ static void cec_devnode_unregister(struct cec_adapter *adap)
devnode->registered = false;
devnode->unregistered = true;
+ mutex_lock(&devnode->lock_fhs);
list_for_each_entry(fh, &devnode->fhs, list)
wake_up_interruptible(&fh->wait);
+ mutex_unlock(&devnode->lock_fhs);
mutex_unlock(&devnode->lock);
@@ -272,6 +274,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
/* adap->devnode initialization */
INIT_LIST_HEAD(&adap->devnode.fhs);
+ mutex_init(&adap->devnode.lock_fhs);
mutex_init(&adap->devnode.lock);
adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
diff --git a/drivers/media/cec/core/cec-pin-priv.h b/drivers/media/cec/core/cec-pin-priv.h
index fb101f15865c..7bad5a0b7cb7 100644
--- a/drivers/media/cec/core/cec-pin-priv.h
+++ b/drivers/media/cec/core/cec-pin-priv.h
@@ -170,7 +170,6 @@ struct cec_pin {
ktime_t ts;
unsigned int wait_usecs;
u16 la_mask;
- bool enabled;
bool monitor_all;
bool rx_eom;
bool enable_irq_failed;
diff --git a/drivers/media/cec/core/cec-pin.c b/drivers/media/cec/core/cec-pin.c
index a60b6f03a6a1..21f0f749713e 100644
--- a/drivers/media/cec/core/cec-pin.c
+++ b/drivers/media/cec/core/cec-pin.c
@@ -1033,6 +1033,7 @@ static int cec_pin_thread_func(void *_adap)
{
struct cec_adapter *adap = _adap;
struct cec_pin *pin = adap->pin;
+ bool irq_enabled = false;
for (;;) {
wait_event_interruptible(pin->kthread_waitq,
@@ -1060,6 +1061,7 @@ static int cec_pin_thread_func(void *_adap)
ns_to_ktime(pin->work_rx_msg.rx_ts));
msg->len = 0;
}
+
if (pin->work_tx_status) {
unsigned int tx_status = pin->work_tx_status;
@@ -1083,27 +1085,39 @@ static int cec_pin_thread_func(void *_adap)
switch (atomic_xchg(&pin->work_irq_change,
CEC_PIN_IRQ_UNCHANGED)) {
case CEC_PIN_IRQ_DISABLE:
- pin->ops->disable_irq(adap);
+ if (irq_enabled) {
+ pin->ops->disable_irq(adap);
+ irq_enabled = false;
+ }
cec_pin_high(pin);
cec_pin_to_idle(pin);
hrtimer_start(&pin->timer, ns_to_ktime(0),
HRTIMER_MODE_REL);
break;
case CEC_PIN_IRQ_ENABLE:
+ if (irq_enabled)
+ break;
pin->enable_irq_failed = !pin->ops->enable_irq(adap);
if (pin->enable_irq_failed) {
cec_pin_to_idle(pin);
hrtimer_start(&pin->timer, ns_to_ktime(0),
HRTIMER_MODE_REL);
+ } else {
+ irq_enabled = true;
}
break;
default:
break;
}
-
if (kthread_should_stop())
break;
}
+ if (pin->ops->disable_irq && irq_enabled)
+ pin->ops->disable_irq(adap);
+ hrtimer_cancel(&pin->timer);
+ cec_pin_read(pin);
+ cec_pin_to_idle(pin);
+ pin->state = CEC_ST_OFF;
return 0;
}
@@ -1111,7 +1125,6 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
{
struct cec_pin *pin = adap->pin;
- pin->enabled = enable;
if (enable) {
atomic_set(&pin->work_pin_num_events, 0);
pin->work_pin_events_rd = pin->work_pin_events_wr = 0;
@@ -1130,13 +1143,7 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
hrtimer_start(&pin->timer, ns_to_ktime(0),
HRTIMER_MODE_REL);
} else {
- if (pin->ops->disable_irq)
- pin->ops->disable_irq(adap);
- hrtimer_cancel(&pin->timer);
kthread_stop(pin->kthread);
- cec_pin_read(pin);
- cec_pin_to_idle(pin);
- pin->state = CEC_ST_OFF;
}
return 0;
}
@@ -1157,11 +1164,8 @@ void cec_pin_start_timer(struct cec_pin *pin)
if (pin->state != CEC_ST_RX_IRQ)
return;
- atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED);
- pin->ops->disable_irq(pin->adap);
- cec_pin_high(pin);
- cec_pin_to_idle(pin);
- hrtimer_start(&pin->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
+ atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE);
+ wake_up_interruptible(&pin->kthread_waitq);
}
static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
diff --git a/drivers/media/common/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c
index cbaa61f10d5f..e7a88a2d248c 100644
--- a/drivers/media/common/b2c2/flexcop.c
+++ b/drivers/media/common/b2c2/flexcop.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop.c - main module part
@@ -15,16 +16,6 @@
* Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
* Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
* filtering)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include "flexcop.h"
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
index baf5772c52a9..e9a15de6126e 100644
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ b/drivers/media/common/saa7146/saa7146_fops.c
@@ -487,6 +487,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
if (hdl->error) {
err = hdl->error;
v4l2_ctrl_handler_free(hdl);
+ v4l2_device_unregister(&dev->v4l2_dev);
return err;
}
dev->v4l2_dev.ctrl_handler = hdl;
@@ -495,6 +496,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
if (vv == NULL) {
ERR("out of memory. aborting.\n");
v4l2_ctrl_handler_free(hdl);
+ v4l2_device_unregister(&dev->v4l2_dev);
return -ENOMEM;
}
ext_vv->vid_ops = saa7146_video_ioctl_ops;
@@ -521,7 +523,8 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
ERR("out of memory. aborting.\n");
kfree(vv);
v4l2_ctrl_handler_free(hdl);
- return -1;
+ v4l2_device_unregister(&dev->v4l2_dev);
+ return -ENOMEM;
}
saa7146_video_uops.init(dev,vv);
diff --git a/drivers/media/common/videobuf2/frame_vector.c b/drivers/media/common/videobuf2/frame_vector.c
index ce879f6f8f82..542dde9d2609 100644
--- a/drivers/media/common/videobuf2/frame_vector.c
+++ b/drivers/media/common/videobuf2/frame_vector.c
@@ -37,6 +37,7 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
+ int ret_pin_user_pages_fast = 0;
int ret = 0;
int err;
@@ -56,6 +57,7 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
vec->is_pfns = false;
goto out_unlocked;
}
+ ret_pin_user_pages_fast = ret;
mmap_read_lock(mm);
vec->got_ref = false;
@@ -71,7 +73,18 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) {
err = follow_pfn(vma, start, &nums[ret]);
if (err) {
- if (ret == 0)
+ if (ret)
+ goto out;
+ // If follow_pfn() returns -EINVAL, then this
+ // is not an IO mapping or a raw PFN mapping.
+ // In that case, return the original error from
+ // pin_user_pages_fast(). Otherwise this
+ // function would return -EINVAL when
+ // pin_user_pages_fast() returned -ENOMEM,
+ // which makes debugging hard.
+ if (err == -EINVAL && ret_pin_user_pages_fast)
+ ret = ret_pin_user_pages_fast;
+ else
ret = err;
goto out;
}
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index 556e42ba66e5..7c4096e62173 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -257,7 +257,7 @@ static void *vb2_dc_alloc(struct vb2_buffer *vb,
ret = vb2_dc_alloc_coherent(buf);
if (ret) {
- dev_err(dev, "dma alloc of size %ld failed\n", size);
+ dev_err(dev, "dma alloc of size %lu failed\n", size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
@@ -298,9 +298,9 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
vma->vm_ops->open(vma);
- pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
- __func__, (unsigned long)buf->dma_addr, vma->vm_start,
- buf->size);
+ pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %lu\n",
+ __func__, (unsigned long)buf->dma_addr, vma->vm_start,
+ buf->size);
return 0;
}
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 5d5a48475a54..f6ee678107d3 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -1,19 +1,9 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* dmxdev.c - DVB demultiplexer device
*
* Copyright (C) 2000 Ralph Metzler & Marcus Metzler
* for convergence integrated media GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#define pr_fmt(fmt) "dmxdev: " fmt
@@ -1413,7 +1403,7 @@ static const struct dvb_device dvbdev_dvr = {
};
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
{
- int i;
+ int i, ret;
if (dmxdev->demux->open(dmxdev->demux) < 0)
return -EUSERS;
@@ -1432,14 +1422,26 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
DMXDEV_STATE_FREE);
}
- dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
+ ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
DVB_DEVICE_DEMUX, dmxdev->filternum);
- dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
+ if (ret < 0)
+ goto err_register_dvbdev;
+
+ ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
+ if (ret < 0)
+ goto err_register_dvr_dvbdev;
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
return 0;
+
+err_register_dvr_dvbdev:
+ dvb_unregister_device(dmxdev->dvbdev);
+err_register_dvbdev:
+ vfree(dmxdev->filter);
+ dmxdev->filter = NULL;
+ return ret;
}
EXPORT_SYMBOL(dvb_dmxdev_init);
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
index 5fde1d38b3e3..83cc32ad7e12 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -1,20 +1,10 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* dvb_demux.c - DVB kernel demux API
*
* Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
* for convergence integrated media GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#define pr_fmt(fmt) "dvb_demux: " fmt
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 258637d762d6..48e735cdbe6b 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2554,8 +2554,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_DISEQC_SEND_BURST:
if (fe->ops.diseqc_send_burst) {
- err = fe->ops.diseqc_send_burst(fe,
- (enum fe_sec_mini_cmd)parg);
+ err = fe->ops.diseqc_send_burst(fe, (long)parg);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@@ -2563,9 +2562,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_SET_TONE:
if (fe->ops.set_tone) {
- err = fe->ops.set_tone(fe,
- (enum fe_sec_tone_mode)parg);
- fepriv->tone = (enum fe_sec_tone_mode)parg;
+ fepriv->tone = (long)parg;
+ err = fe->ops.set_tone(fe, fepriv->tone);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@@ -2573,9 +2571,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_SET_VOLTAGE:
if (fe->ops.set_voltage) {
- err = fe->ops.set_voltage(fe,
- (enum fe_sec_voltage)parg);
- fepriv->voltage = (enum fe_sec_voltage)parg;
+ fepriv->voltage = (long)parg;
+ err = fe->ops.set_voltage(fe, fepriv->voltage);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@@ -2935,7 +2932,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
else if (fe->ops.tuner_ops.sleep)
ret = fe->ops.tuner_ops.sleep(fe);
- if (fe->ops.sleep)
+ if (fe->ops.suspend)
+ ret = fe->ops.suspend(fe);
+ else if (fe->ops.sleep)
ret = fe->ops.sleep(fe);
return ret;
@@ -2951,7 +2950,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
fe->id);
fe->exit = DVB_FE_DEVICE_RESUME;
- if (fe->ops.init)
+ if (fe->ops.resume)
+ ret = fe->ops.resume(fe);
+ else if (fe->ops.init)
ret = fe->ops.init(fe);
if (fe->ops.tuner_ops.resume)
diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c
index 959d110407a4..a1bd6d9c9223 100644
--- a/drivers/media/dvb-core/dvb_vb2.c
+++ b/drivers/media/dvb-core/dvb_vb2.c
@@ -5,10 +5,6 @@
* Copyright (C) 2015 Samsung Electronics
*
* Author: jh1009.sung@samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
*/
#include <linux/err.h>
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 795d9bfaba5c..675d877a67b2 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -1,20 +1,10 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* dvbdev.c
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
* for convergence integrated media GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#define pr_fmt(fmt) "dvbdev: " fmt
diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c
index 60a9f70275f7..dd55d314bf9a 100644
--- a/drivers/media/dvb-frontends/cx24113.c
+++ b/drivers/media/dvb-frontends/cx24113.c
@@ -378,7 +378,7 @@ static void cx24113_set_nfr(struct cx24113_state *state, u16 n, s32 f, u8 r)
static int cx24113_set_frequency(struct cx24113_state *state, u32 frequency)
{
- u8 r = 1; /* or 2 */
+ u8 r;
u16 n = 6;
s32 f = 0;
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index bb02354a48b8..d67f2dd997d0 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -4473,8 +4473,10 @@ static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_ad
state->timf_default = cfg->pll->timf;
- if (dib8000_identify(&state->i2c) == 0)
+ if (dib8000_identify(&state->i2c) == 0) {
+ kfree(fe);
goto error;
+ }
dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c
index 04d92d614279..914ca820c174 100644
--- a/drivers/media/dvb-frontends/dib9000.c
+++ b/drivers/media/dvb-frontends/dib9000.c
@@ -258,7 +258,7 @@ static int dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 *b, u32
state->i2c_write_buffer[0] |= (1 << 4);
do {
- l = len < chunk_size ? len : chunk_size;
+ l = min(len, chunk_size);
state->msg[1].len = l;
state->msg[1].buf = b;
ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
@@ -342,7 +342,7 @@ static int dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *
state->i2c_write_buffer[0] |= (1 << 4);
do {
- l = len < chunk_size ? len : chunk_size;
+ l = min(len, chunk_size);
state->msg[0].len = l + 2;
memcpy(&state->i2c_write_buffer[2], buf, l);
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index a7eb81df88c2..9860cae65f1c 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -914,44 +914,36 @@ static int DownloadMicrocode(struct drxd_state *state,
u32 Address;
u16 nBlocks;
u16 BlockSize;
- u32 offset = 0;
int i, status = 0;
pSrc = (u8 *) pMCImage;
/* We're not using Flags */
/* Flags = (pSrc[0] << 8) | pSrc[1]; */
pSrc += sizeof(u16);
- offset += sizeof(u16);
nBlocks = (pSrc[0] << 8) | pSrc[1];
pSrc += sizeof(u16);
- offset += sizeof(u16);
for (i = 0; i < nBlocks; i++) {
Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
(pSrc[2] << 8) | pSrc[3];
pSrc += sizeof(u32);
- offset += sizeof(u32);
BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
pSrc += sizeof(u16);
- offset += sizeof(u16);
/* We're not using Flags */
/* u16 Flags = (pSrc[0] << 8) | pSrc[1]; */
pSrc += sizeof(u16);
- offset += sizeof(u16);
/* We're not using BlockCRC */
/* u16 BlockCRC = (pSrc[0] << 8) | pSrc[1]; */
pSrc += sizeof(u16);
- offset += sizeof(u16);
status = WriteBlock(state, Address, BlockSize,
pSrc, DRX_I2C_CLEARCRC);
if (status < 0)
break;
pSrc += BlockSize;
- offset += BlockSize;
}
return status;
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index d7fc2595f15b..9430295a8175 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -3720,7 +3720,6 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
{
u16 cmd_result = 0;
u16 transmission_params = 0;
- u16 operation_mode = 0;
u32 iqm_rc_rate_ofs = 0;
u32 bandwidth = 0;
u16 param1;
@@ -3759,10 +3758,8 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
/* mode */
switch (state->props.transmission_mode) {
case TRANSMISSION_MODE_AUTO:
- default:
- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
- fallthrough; /* try first guess DRX_FFTMODE_8K */
case TRANSMISSION_MODE_8K:
+ default:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
break;
case TRANSMISSION_MODE_2K:
@@ -3773,9 +3770,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
/* guard */
switch (state->props.guard_interval) {
default:
- case GUARD_INTERVAL_AUTO:
- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
- fallthrough; /* try first guess DRX_GUARD_1DIV4 */
+ case GUARD_INTERVAL_AUTO: /* try first guess DRX_GUARD_1DIV4 */
case GUARD_INTERVAL_1_4:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
break;
@@ -3794,11 +3789,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
switch (state->props.hierarchy) {
case HIERARCHY_AUTO:
case HIERARCHY_NONE:
- default:
- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
- /* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
- /* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
- fallthrough;
+ default: /* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
case HIERARCHY_1:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
break;
@@ -3814,9 +3805,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
/* modulation */
switch (state->props.modulation) {
case QAM_AUTO:
- default:
- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
- fallthrough; /* try first guess DRX_CONSTELLATION_QAM64 */
+ default: /* try first guess DRX_CONSTELLATION_QAM64 */
case QAM_64:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
break;
@@ -3857,9 +3846,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
/* coderate */
switch (state->props.code_rate_HP) {
case FEC_AUTO:
- default:
- operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
- fallthrough; /* try first guess DRX_CODERATE_2DIV3 */
+ default: /* try first guess DRX_CODERATE_2DIV3 */
case FEC_2_3:
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
break;
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index 02e8aa11e36e..bce0f42f3d19 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -451,7 +451,7 @@ static int m88ds3103b_select_mclk(struct m88ds3103_dev *dev)
static int m88ds3103b_set_mclk(struct m88ds3103_dev *dev, u32 mclk_khz)
{
- u8 reg11 = 0x0A, reg15, reg16, reg1D, reg1E, reg1F, tmp;
+ u8 reg15, reg16, reg1D, reg1E, reg1F, tmp;
u8 sm, f0 = 0, f1 = 0, f2 = 0, f3 = 0;
u16 pll_div_fb, N;
u32 div;
@@ -480,8 +480,6 @@ static int m88ds3103b_set_mclk(struct m88ds3103_dev *dev, u32 mclk_khz)
div /= mclk_khz;
if (dev->cfg->ts_mode == M88DS3103_TS_SERIAL) {
- reg11 |= 0x02;
-
if (div <= 32) {
N = 2;
@@ -532,8 +530,6 @@ static int m88ds3103b_set_mclk(struct m88ds3103_dev *dev, u32 mclk_khz)
else if ((f3 < 8) && (f3 != 0))
f3 = 8;
} else {
- reg11 &= ~0x02;
-
if (div <= 32) {
N = 2;
diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c
index c1334d7eb442..2563a72e98b7 100644
--- a/drivers/media/dvb-frontends/s5h1411.c
+++ b/drivers/media/dvb-frontends/s5h1411.c
@@ -150,7 +150,7 @@ static struct vsb_snr_tab {
{ 0x35b, 235, },
{ 0x353, 230, },
{ 0x349, 225, },
- { 0x340, 320, },
+ { 0x340, 220, },
{ 0x337, 215, },
{ 0x327, 210, },
{ 0x31b, 205, },
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 14b93a7d3358..196e028a6617 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -448,23 +448,10 @@ static int si2168_init(struct dvb_frontend *fe)
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, dev->firmware_name, &client->dev);
if (ret) {
- /* fallback mechanism to handle old name for Si2168 B40 fw */
- if (dev->chip_id == SI2168_CHIP_ID_B40) {
- dev->firmware_name = SI2168_B40_FIRMWARE_FALLBACK;
- ret = request_firmware(&fw, dev->firmware_name,
- &client->dev);
- }
-
- if (ret == 0) {
- dev_notice(&client->dev,
- "please install firmware file '%s'\n",
- SI2168_B40_FIRMWARE);
- } else {
- dev_err(&client->dev,
- "firmware file '%s' not found\n",
- dev->firmware_name);
- goto err_release_firmware;
- }
+ dev_err(&client->dev,
+ "firmware file '%s' not found\n",
+ dev->firmware_name);
+ goto err_release_firmware;
}
dev_info(&client->dev, "downloading firmware from file '%s'\n",
@@ -527,6 +514,7 @@ static int si2168_init(struct dvb_frontend *fe)
goto err;
dev->warm = true;
+ dev->initialized = true;
warm:
/* Init stats here to indicate which stats are supported */
c->cnr.len = 1;
@@ -548,6 +536,26 @@ err:
return ret;
}
+static int si2168_resume(struct dvb_frontend *fe)
+{
+ struct i2c_client *client = fe->demodulator_priv;
+ struct si2168_dev *dev = i2c_get_clientdata(client);
+
+ /*
+ * check whether si2168_init() has been called successfully
+ * outside of a resume cycle. Only call it (and load firmware)
+ * in this case. si2168_init() is only called during resume
+ * once the device has actually been used. Otherwise, leave the
+ * device untouched.
+ */
+ if (dev->initialized) {
+ dev_dbg(&client->dev, "previously initialized, call si2168_init()\n");
+ return si2168_init(fe);
+ }
+ dev_dbg(&client->dev, "not initialized yet, skipping init on resume\n");
+ return 0;
+}
+
static int si2168_sleep(struct dvb_frontend *fe)
{
struct i2c_client *client = fe->demodulator_priv;
@@ -657,6 +665,7 @@ static const struct dvb_frontend_ops si2168_ops = {
.init = si2168_init,
.sleep = si2168_sleep,
+ .resume = si2168_resume,
.set_frontend = si2168_set_frontend,
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index 18bea5222082..3a8976229a4a 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -18,7 +18,6 @@
#define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
#define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
#define SI2168_D60_FIRMWARE "dvb-demod-si2168-d60-01.fw"
-#define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
/* state struct */
struct si2168_dev {
@@ -37,6 +36,7 @@ struct si2168_dev {
u8 ts_mode;
unsigned int active:1;
unsigned int warm:1;
+ unsigned int initialized:1;
unsigned int ts_clock_inv:1;
unsigned int ts_clock_gapped:1;
unsigned int spectral_inversion:1;
diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c
index e31eb2c5cc4c..001b23588389 100644
--- a/drivers/media/dvb-frontends/si21xx.c
+++ b/drivers/media/dvb-frontends/si21xx.c
@@ -711,7 +711,7 @@ static int si21xx_set_frontend(struct dvb_frontend *fe)
int i;
bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
- int status;
+ int status = 0;
/* allowable sample rates for ADC in MHz */
int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
@@ -747,8 +747,6 @@ static int si21xx_set_frontend(struct dvb_frontend *fe)
rf_freq = 10 * c->frequency ;
data_rate = c->symbol_rate / 100;
- status = PASS;
-
band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
+ (data_rate * 135)) / 200;
@@ -832,6 +830,9 @@ static int si21xx_set_frontend(struct dvb_frontend *fe)
state->fs = sample_rate;/*ADC MHz*/
si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
+ if (status)
+ return -EREMOTEIO;
+
return 0;
}
diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c
index c89a91a3daf4..146e7f2dd3c5 100644
--- a/drivers/media/dvb-frontends/sp887x.c
+++ b/drivers/media/dvb-frontends/sp887x.c
@@ -140,7 +140,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware
u8 buf [BLOCKSIZE + 2];
int i;
int fw_size = fw->size;
- const unsigned char *mem = fw->data;
+ const unsigned char *mem = fw->data + 10;
dprintk("%s\n", __func__);
@@ -148,8 +148,6 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware
if (fw_size < FW_SIZE + 10)
return -ENODEV;
- mem = fw->data + 10;
-
/* soft reset */
sp887x_writereg(state, 0xf1a, 0x000);
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
index d541d6613610..698866c4f15a 100644
--- a/drivers/media/dvb-frontends/stb6100.c
+++ b/drivers/media/dvb-frontends/stb6100.c
@@ -110,7 +110,7 @@ static const struct stb6100_regmask stb6100_template[] = {
/*
* Currently unused. Some boards might need it in the future
*/
-static inline void stb6100_normalise_regs(u8 regs[])
+static __always_unused inline void stb6100_normalise_regs(u8 regs[])
{
int i;
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index 6c2b05fae1c5..95e376f23506 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -1797,11 +1797,7 @@ static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz)
static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
{
- u32 ADCClk_Hz = ExtClk_Hz;
-
- ADCClk_Hz = stv0367cab_get_mclk(fe, ExtClk_Hz);
-
- return ADCClk_Hz;
+ return stv0367cab_get_mclk(fe, ExtClk_Hz);
}
static enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index d6a5d4ca439a..69c56e24a612 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -469,6 +469,7 @@ config VIDEO_VPX3220
config VIDEO_MAX9286
tristate "Maxim MAX9286 GMSL deserializer support"
depends on I2C && I2C_MUX
+ depends on VIDEO_V4L2
depends on OF_GPIO
select V4L2_FWNODE
select VIDEO_V4L2_SUBDEV_API
@@ -1058,6 +1059,17 @@ config VIDEO_OV5675
To compile this driver as a module, choose M here: the
module will be called ov5675.
+config VIDEO_OV5693
+ tristate "OmniVision OV5693 sensor support"
+ depends on I2C && VIDEO_V4L2
+ select V4L2_FWNODE
+ help
+ This is a Video4Linux2 sensor driver for the OmniVision
+ OV5693 camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ov5693.
+
config VIDEO_OV5695
tristate "OmniVision OV5695 sensor support"
depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 4d4fe08d7a6a..b01f6cd05ee8 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
obj-$(CONFIG_VIDEO_OV5648) += ov5648.o
obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
+obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
index 41f4e749a859..8e13cae40ec5 100644
--- a/drivers/media/i2c/adv7511-v4l2.c
+++ b/drivers/media/i2c/adv7511-v4l2.c
@@ -270,28 +270,6 @@ static int adv7511_pktmem_rd(struct v4l2_subdev *sd, u8 reg)
return adv_smbus_read_byte_data(state->i2c_pktmem, reg);
}
-static int adv7511_pktmem_wr(struct v4l2_subdev *sd, u8 reg, u8 val)
-{
- struct adv7511_state *state = get_adv7511_state(sd);
- int ret;
- int i;
-
- for (i = 0; i < 3; i++) {
- ret = i2c_smbus_write_byte_data(state->i2c_pktmem, reg, val);
- if (ret == 0)
- return 0;
- }
- v4l2_err(sd, "%s: i2c write error\n", __func__);
- return ret;
-}
-
-/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
- and then the value-mask (to be OR-ed). */
-static inline void adv7511_pktmem_wr_and_or(struct v4l2_subdev *sd, u8 reg, u8 clr_mask, u8 val_mask)
-{
- adv7511_pktmem_wr(sd, reg, (adv7511_pktmem_rd(sd, reg) & clr_mask) | val_mask);
-}
-
static inline bool adv7511_have_hotplug(struct v4l2_subdev *sd)
{
return adv7511_rd(sd, 0x42) & MASK_ADV7511_HPD_DETECT;
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 44768b59a6ff..a2fa408d2d9f 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -398,14 +398,14 @@ static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask,
return io_write(sd, reg, (io_read(sd, reg) & ~mask) | val);
}
-static inline int avlink_read(struct v4l2_subdev *sd, u8 reg)
+static inline int __always_unused avlink_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv76xx_read_check(state, ADV7604_PAGE_AVLINK, reg);
}
-static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+static inline int __always_unused avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
@@ -439,14 +439,14 @@ static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg)
return adv76xx_read_check(state, ADV76XX_PAGE_INFOFRAME, reg);
}
-static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+static inline int __always_unused infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return regmap_write(state->regmap[ADV76XX_PAGE_INFOFRAME], reg, val);
}
-static inline int afe_read(struct v4l2_subdev *sd, u8 reg)
+static inline int __always_unused afe_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
@@ -479,14 +479,14 @@ static inline int rep_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8
return rep_write(sd, reg, (rep_read(sd, reg) & ~mask) | val);
}
-static inline int edid_read(struct v4l2_subdev *sd, u8 reg)
+static inline int __always_unused edid_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv76xx_read_check(state, ADV76XX_PAGE_EDID, reg);
}
-static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+static inline int __always_unused edid_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
@@ -570,7 +570,7 @@ static inline int hdmi_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8
return hdmi_write(sd, reg, (hdmi_read(sd, reg) & ~mask) | val);
}
-static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+static inline int __always_unused test_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
@@ -601,14 +601,14 @@ static inline int cp_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 v
return cp_write(sd, reg, (cp_read(sd, reg) & ~mask) | val);
}
-static inline int vdp_read(struct v4l2_subdev *sd, u8 reg)
+static inline int __always_unused vdp_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv76xx_read_check(state, ADV7604_PAGE_VDP, reg);
}
-static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+static inline int __always_unused vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 7f8acbdf0db4..9d6eed0f8281 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -256,21 +256,11 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
return &container_of(ctrl->handler, struct adv7842_state, hdl)->sd;
}
-static inline unsigned hblanking(const struct v4l2_bt_timings *t)
-{
- return V4L2_DV_BT_BLANKING_WIDTH(t);
-}
-
static inline unsigned htotal(const struct v4l2_bt_timings *t)
{
return V4L2_DV_BT_FRAME_WIDTH(t);
}
-static inline unsigned vblanking(const struct v4l2_bt_timings *t)
-{
- return V4L2_DV_BT_BLANKING_HEIGHT(t);
-}
-
static inline unsigned vtotal(const struct v4l2_bt_timings *t)
{
return V4L2_DV_BT_FRAME_HEIGHT(t);
diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c
index 5363f3bcafe3..9158d3ce45c0 100644
--- a/drivers/media/i2c/ccs/ccs-core.c
+++ b/drivers/media/i2c/ccs/ccs-core.c
@@ -2758,13 +2758,13 @@ ident_show(struct device *dev, struct device_attribute *attr, char *buf)
struct ccs_module_info *minfo = &sensor->minfo;
if (minfo->mipi_manufacturer_id)
- return snprintf(buf, PAGE_SIZE, "%4.4x%4.4x%2.2x\n",
- minfo->mipi_manufacturer_id, minfo->model_id,
- minfo->revision_number) + 1;
+ return sysfs_emit(buf, "%4.4x%4.4x%2.2x\n",
+ minfo->mipi_manufacturer_id, minfo->model_id,
+ minfo->revision_number) + 1;
else
- return snprintf(buf, PAGE_SIZE, "%2.2x%4.4x%2.2x\n",
- minfo->smia_manufacturer_id, minfo->model_id,
- minfo->revision_number) + 1;
+ return sysfs_emit(buf, "%2.2x%4.4x%2.2x\n",
+ minfo->smia_manufacturer_id, minfo->model_id,
+ minfo->revision_number) + 1;
}
static DEVICE_ATTR_RO(ident);
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index 2cf3e6a1f9e1..9d7d1d149f1a 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -136,19 +136,6 @@ static inline u16 count_to_clock_divider(unsigned int d)
return (u16) d;
}
-static inline u16 ns_to_clock_divider(unsigned int ns)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ / 1000000 * ns, 1000));
-}
-
-static inline unsigned int clock_divider_to_ns(unsigned int divider)
-{
- /* Period of the Rx or Tx clock in ns */
- return DIV_ROUND_CLOSEST((divider + 1) * 1000,
- CX25840_IR_REFCLK_FREQ / 1000000);
-}
-
static inline u16 carrier_freq_to_clock_divider(unsigned int freq)
{
return count_to_clock_divider(
@@ -160,13 +147,6 @@ static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider)
return DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ, (divider + 1) * 16);
}
-static inline u16 freq_to_clock_divider(unsigned int freq,
- unsigned int rollovers)
-{
- return count_to_clock_divider(
- DIV_ROUND_CLOSEST(CX25840_IR_REFCLK_FREQ, freq * rollovers));
-}
-
static inline unsigned int clock_divider_to_freq(unsigned int divider,
unsigned int rollovers)
{
diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
index c086580efac7..65c6acf3ced9 100644
--- a/drivers/media/i2c/dw9768.c
+++ b/drivers/media/i2c/dw9768.c
@@ -469,6 +469,11 @@ static int dw9768_probe(struct i2c_client *client)
dw9768->sd.entity.function = MEDIA_ENT_F_LENS;
+ /*
+ * Device is already turned on by i2c-core with ACPI domain PM.
+ * Attempt to turn off the device to satisfy the privacy LED concerns.
+ */
+ pm_runtime_set_active(dev);
pm_runtime_enable(dev);
if (!pm_runtime_enabled(dev)) {
ret = dw9768_runtime_resume(dev);
@@ -483,6 +488,7 @@ static int dw9768_probe(struct i2c_client *client)
dev_err(dev, "failed to register V4L2 subdev: %d", ret);
goto err_power_off;
}
+ pm_runtime_idle(dev);
return 0;
diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c
index 8db1cbedc1fd..055d1aa8410e 100644
--- a/drivers/media/i2c/hi556.c
+++ b/drivers/media/i2c/hi556.c
@@ -495,6 +495,9 @@ struct hi556 {
/* Streaming on/off */
bool streaming;
+
+ /* True if the device has been identified */
+ bool identified;
};
static u64 to_pixel_rate(u32 f_index)
@@ -757,12 +760,41 @@ static void hi556_assign_pad_format(const struct hi556_mode *mode,
fmt->field = V4L2_FIELD_NONE;
}
+static int hi556_identify_module(struct hi556 *hi556)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
+ int ret;
+ u32 val;
+
+ if (hi556->identified)
+ return 0;
+
+ ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID,
+ HI556_REG_VALUE_16BIT, &val);
+ if (ret)
+ return ret;
+
+ if (val != HI556_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ HI556_CHIP_ID, val);
+ return -ENXIO;
+ }
+
+ hi556->identified = true;
+
+ return 0;
+}
+
static int hi556_start_streaming(struct hi556 *hi556)
{
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
const struct hi556_reg_list *reg_list;
int link_freq_index, ret;
+ ret = hi556_identify_module(hi556);
+ if (ret)
+ return ret;
+
link_freq_index = hi556->cur_mode->link_freq_index;
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = hi556_write_reg_list(hi556, reg_list);
@@ -1001,26 +1033,6 @@ static const struct v4l2_subdev_internal_ops hi556_internal_ops = {
.open = hi556_open,
};
-static int hi556_identify_module(struct hi556 *hi556)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
- int ret;
- u32 val;
-
- ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID,
- HI556_REG_VALUE_16BIT, &val);
- if (ret)
- return ret;
-
- if (val != HI556_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
- HI556_CHIP_ID, val);
- return -ENXIO;
- }
-
- return 0;
-}
-
static int hi556_check_hwcfg(struct device *dev)
{
struct fwnode_handle *ep;
@@ -1106,6 +1118,7 @@ static int hi556_remove(struct i2c_client *client)
static int hi556_probe(struct i2c_client *client)
{
struct hi556 *hi556;
+ bool full_power;
int ret;
ret = hi556_check_hwcfg(&client->dev);
@@ -1120,10 +1133,14 @@ static int hi556_probe(struct i2c_client *client)
return -ENOMEM;
v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops);
- ret = hi556_identify_module(hi556);
- if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
- return ret;
+
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ ret = hi556_identify_module(hi556);
+ if (ret) {
+ dev_err(&client->dev, "failed to find sensor: %d", ret);
+ return ret;
+ }
}
mutex_init(&hi556->mutex);
@@ -1152,7 +1169,9 @@ static int hi556_probe(struct i2c_client *client)
goto probe_error_media_entity_cleanup;
}
- pm_runtime_set_active(&client->dev);
+ /* Set the device's state to active if it's in D0 state. */
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -1189,6 +1208,7 @@ static struct i2c_driver hi556_i2c_driver = {
},
.probe_new = hi556_probe,
.remove = hi556_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(hi556_i2c_driver);
diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c
index 48909faeced4..ad35c3ff3611 100644
--- a/drivers/media/i2c/hi846.c
+++ b/drivers/media/i2c/hi846.c
@@ -1656,7 +1656,7 @@ err_reg:
return ret;
}
-static void hi846_power_off(struct hi846 *hi846)
+static int hi846_power_off(struct hi846 *hi846)
{
if (hi846->rst_gpio)
gpiod_set_value_cansleep(hi846->rst_gpio, 1);
@@ -1665,7 +1665,7 @@ static void hi846_power_off(struct hi846 *hi846)
gpiod_set_value_cansleep(hi846->shutdown_gpio, 1);
clk_disable_unprepare(hi846->clock);
- regulator_bulk_disable(HI846_NUM_SUPPLIES, hi846->supplies);
+ return regulator_bulk_disable(HI846_NUM_SUPPLIES, hi846->supplies);
}
static int __maybe_unused hi846_suspend(struct device *dev)
@@ -1677,9 +1677,7 @@ static int __maybe_unused hi846_suspend(struct device *dev)
if (hi846->streaming)
hi846_stop_streaming(hi846);
- hi846_power_off(hi846);
-
- return 0;
+ return hi846_power_off(hi846);
}
static int __maybe_unused hi846_resume(struct device *dev)
@@ -2164,7 +2162,11 @@ static int hi846_remove(struct i2c_client *client)
return 0;
}
-static UNIVERSAL_DEV_PM_OPS(hi846_pm_ops, hi846_suspend, hi846_resume, NULL);
+static const struct dev_pm_ops hi846_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(hi846_suspend, hi846_resume, NULL)
+};
static const struct of_device_id hi846_of_match[] = {
{ .compatible = "hynix,hi846", },
diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c
index 6f3d9c1b5879..b9516b2f1c15 100644
--- a/drivers/media/i2c/imx208.c
+++ b/drivers/media/i2c/imx208.c
@@ -296,6 +296,9 @@ struct imx208 {
/* OTP data */
bool otp_read;
char otp_data[IMX208_OTP_SIZE];
+
+ /* True if the device has been identified */
+ bool identified;
};
static inline struct imx208 *to_imx208(struct v4l2_subdev *_sd)
@@ -619,6 +622,34 @@ static int imx208_set_pad_format(struct v4l2_subdev *sd,
return 0;
}
+static int imx208_identify_module(struct imx208 *imx208)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
+ int ret;
+ u32 val;
+
+ if (imx208->identified)
+ return 0;
+
+ ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID,
+ 2, &val);
+ if (ret) {
+ dev_err(&client->dev, "failed to read chip id %x\n",
+ IMX208_CHIP_ID);
+ return ret;
+ }
+
+ if (val != IMX208_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ IMX208_CHIP_ID, val);
+ return -EIO;
+ }
+
+ imx208->identified = true;
+
+ return 0;
+}
+
/* Start streaming */
static int imx208_start_streaming(struct imx208 *imx208)
{
@@ -626,6 +657,10 @@ static int imx208_start_streaming(struct imx208 *imx208)
const struct imx208_reg_list *reg_list;
int ret, link_freq_index;
+ ret = imx208_identify_module(imx208);
+ if (ret)
+ return ret;
+
/* Setup PLL */
link_freq_index = imx208->cur_mode->link_freq_index;
reg_list = &link_freq_configs[link_freq_index].reg_list;
@@ -752,29 +787,6 @@ error:
}
/* Verify chip ID */
-static int imx208_identify_module(struct imx208 *imx208)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
- int ret;
- u32 val;
-
- ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID,
- 2, &val);
- if (ret) {
- dev_err(&client->dev, "failed to read chip id %x\n",
- IMX208_CHIP_ID);
- return ret;
- }
-
- if (val != IMX208_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
- IMX208_CHIP_ID, val);
- return -EIO;
- }
-
- return 0;
-}
-
static const struct v4l2_subdev_video_ops imx208_video_ops = {
.s_stream = imx208_set_stream,
};
@@ -813,6 +825,10 @@ static int imx208_read_otp(struct imx208 *imx208)
goto out_unlock;
}
+ ret = imx208_identify_module(imx208);
+ if (ret)
+ goto out_pm_put;
+
/* Write register address */
msgs[0].addr = client->addr;
msgs[0].flags = 0;
@@ -831,6 +847,7 @@ static int imx208_read_otp(struct imx208 *imx208)
ret = 0;
}
+out_pm_put:
pm_runtime_put(&client->dev);
out_unlock:
@@ -961,6 +978,7 @@ static int imx208_probe(struct i2c_client *client)
{
struct imx208 *imx208;
int ret;
+ bool full_power;
u32 val = 0;
device_property_read_u32(&client->dev, "clock-frequency", &val);
@@ -978,11 +996,14 @@ static int imx208_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops);
- /* Check module identity */
- ret = imx208_identify_module(imx208);
- if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
- goto error_probe;
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ /* Check module identity */
+ ret = imx208_identify_module(imx208);
+ if (ret) {
+ dev_err(&client->dev, "failed to find sensor: %d", ret);
+ goto error_probe;
+ }
}
/* Set default mode to max resolution */
@@ -1017,7 +1038,9 @@ static int imx208_probe(struct i2c_client *client)
goto error_async_subdev;
}
- pm_runtime_set_active(&client->dev);
+ /* Set the device's state to active if it's in D0 state. */
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -1077,6 +1100,7 @@ static struct i2c_driver imx208_i2c_driver = {
},
.probe_new = imx208_probe,
.remove = imx208_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(imx208_i2c_driver);
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index 0dce92872176..2aa15b9c23cc 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -27,6 +27,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
/*
@@ -1367,6 +1368,10 @@ static int imx274_s_frame_interval(struct v4l2_subdev *sd,
int min, max, def;
int ret;
+ ret = pm_runtime_resume_and_get(&imx274->client->dev);
+ if (ret < 0)
+ return ret;
+
mutex_lock(&imx274->lock);
ret = imx274_set_frame_interval(imx274, fi->interval);
@@ -1398,6 +1403,7 @@ static int imx274_s_frame_interval(struct v4l2_subdev *sd,
unlock:
mutex_unlock(&imx274->lock);
+ pm_runtime_put(&imx274->client->dev);
return ret;
}
@@ -1457,7 +1463,7 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
goto fail;
/*
- * update frame rate & expsoure. if the last mode is different,
+ * update frame rate & exposure. if the last mode is different,
* HMAX could be changed. As the result, frame rate & exposure
* are changed.
* gain is not affected.
@@ -1494,7 +1500,7 @@ fail:
/*
* imx274_get_frame_length - Function for obtaining current frame length
* @priv: Pointer to device structure
- * @val: Pointer to obainted value
+ * @val: Pointer to obtained value
*
* frame_length = vmax x (svr + 1), in unit of hmax.
*
@@ -1904,7 +1910,21 @@ fail:
return err;
}
+static int imx274_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index > 0)
+ return -EINVAL;
+
+ /* only supported format in the driver is Raw 10 bits SRGGB */
+ code->code = MEDIA_BUS_FMT_SRGGB10_1X10;
+
+ return 0;
+}
+
static const struct v4l2_subdev_pad_ops imx274_pad_ops = {
+ .enum_mbus_code = imx274_enum_mbus_code,
.get_fmt = imx274_get_fmt,
.set_fmt = imx274_set_fmt,
.get_selection = imx274_get_selection,
@@ -1938,27 +1958,66 @@ static const struct i2c_device_id imx274_id[] = {
};
MODULE_DEVICE_TABLE(i2c, imx274_id);
+static int imx274_fwnode_parse(struct device *dev)
+{
+ struct fwnode_handle *endpoint;
+ /* Only CSI2 is supported */
+ struct v4l2_fwnode_endpoint ep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ int ret;
+
+ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
+ if (!endpoint) {
+ dev_err(dev, "Endpoint node not found\n");
+ return -EINVAL;
+ }
+
+ ret = v4l2_fwnode_endpoint_parse(endpoint, &ep);
+ fwnode_handle_put(endpoint);
+ if (ret == -ENXIO) {
+ dev_err(dev, "Unsupported bus type, should be CSI2\n");
+ return ret;
+ } else if (ret) {
+ dev_err(dev, "Parsing endpoint node failed %d\n", ret);
+ return ret;
+ }
+
+ /* Check number of data lanes, only 4 lanes supported */
+ if (ep.bus.mipi_csi2.num_data_lanes != 4) {
+ dev_err(dev, "Invalid data lanes: %d\n",
+ ep.bus.mipi_csi2.num_data_lanes);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int imx274_probe(struct i2c_client *client)
{
struct v4l2_subdev *sd;
struct stimx274 *imx274;
+ struct device *dev = &client->dev;
int ret;
/* initialize imx274 */
- imx274 = devm_kzalloc(&client->dev, sizeof(*imx274), GFP_KERNEL);
+ imx274 = devm_kzalloc(dev, sizeof(*imx274), GFP_KERNEL);
if (!imx274)
return -ENOMEM;
mutex_init(&imx274->lock);
- imx274->inck = devm_clk_get_optional(&client->dev, "inck");
+ ret = imx274_fwnode_parse(dev);
+ if (ret)
+ return ret;
+
+ imx274->inck = devm_clk_get_optional(dev, "inck");
if (IS_ERR(imx274->inck))
return PTR_ERR(imx274->inck);
- ret = imx274_regulators_get(&client->dev, imx274);
+ ret = imx274_regulators_get(dev, imx274);
if (ret) {
- dev_err(&client->dev,
- "Failed to get power regulators, err: %d\n", ret);
+ dev_err(dev, "Failed to get power regulators, err: %d\n", ret);
return ret;
}
@@ -1977,7 +2036,7 @@ static int imx274_probe(struct i2c_client *client)
/* initialize regmap */
imx274->regmap = devm_regmap_init_i2c(client, &imx274_regmap_config);
if (IS_ERR(imx274->regmap)) {
- dev_err(&client->dev,
+ dev_err(dev,
"regmap init failed: %ld\n", PTR_ERR(imx274->regmap));
ret = -ENODEV;
goto err_regmap;
@@ -1994,34 +2053,32 @@ static int imx274_probe(struct i2c_client *client)
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&sd->entity, 1, &imx274->pad);
if (ret < 0) {
- dev_err(&client->dev,
+ dev_err(dev,
"%s : media entity init Failed %d\n", __func__, ret);
goto err_regmap;
}
/* initialize sensor reset gpio */
- imx274->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ imx274->reset_gpio = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(imx274->reset_gpio)) {
if (PTR_ERR(imx274->reset_gpio) != -EPROBE_DEFER)
- dev_err(&client->dev, "Reset GPIO not setup in DT");
+ dev_err(dev, "Reset GPIO not setup in DT");
ret = PTR_ERR(imx274->reset_gpio);
goto err_me;
}
/* power on the sensor */
- ret = imx274_power_on(&client->dev);
+ ret = imx274_power_on(dev);
if (ret < 0) {
- dev_err(&client->dev,
- "%s : imx274 power on failed\n", __func__);
+ dev_err(dev, "%s : imx274 power on failed\n", __func__);
goto err_me;
}
/* initialize controls */
ret = v4l2_ctrl_handler_init(&imx274->ctrls.handler, 4);
if (ret < 0) {
- dev_err(&client->dev,
- "%s : ctrl handler init Failed\n", __func__);
+ dev_err(dev, "%s : ctrl handler init Failed\n", __func__);
goto err_power_off;
}
@@ -2064,23 +2121,22 @@ static int imx274_probe(struct i2c_client *client)
/* register subdevice */
ret = v4l2_async_register_subdev(sd);
if (ret < 0) {
- dev_err(&client->dev,
- "%s : v4l2_async_register_subdev failed %d\n",
+ dev_err(dev, "%s : v4l2_async_register_subdev failed %d\n",
__func__, ret);
goto err_ctrls;
}
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
- pm_runtime_idle(&client->dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_idle(dev);
- dev_info(&client->dev, "imx274 : imx274 probe success !\n");
+ dev_info(dev, "imx274 : imx274 probe success !\n");
return 0;
err_ctrls:
v4l2_ctrl_handler_free(&imx274->ctrls.handler);
err_power_off:
- imx274_power_off(&client->dev);
+ imx274_power_off(dev);
err_me:
media_entity_cleanup(&sd->entity);
err_regmap:
diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
index bf7a6c37ca5d..99f2a50d39a4 100644
--- a/drivers/media/i2c/imx290.c
+++ b/drivers/media/i2c/imx290.c
@@ -363,7 +363,7 @@ static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
return container_of(_sd, struct imx290, sd);
}
-static inline int imx290_read_reg(struct imx290 *imx290, u16 addr, u8 *value)
+static inline int __always_unused imx290_read_reg(struct imx290 *imx290, u16 addr, u8 *value)
{
unsigned int regval;
int ret;
diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c
index daa976858e29..a2b5a34de76b 100644
--- a/drivers/media/i2c/imx319.c
+++ b/drivers/media/i2c/imx319.c
@@ -2565,6 +2565,6 @@ module_i2c_driver(imx319_i2c_driver);
MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
-MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
+MODULE_AUTHOR("Yang, Hyungwoo");
MODULE_DESCRIPTION("Sony imx319 sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index cb51c81786bd..3922b9305978 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -1851,6 +1851,6 @@ module_i2c_driver(imx355_i2c_driver);
MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
-MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
+MODULE_AUTHOR("Yang, Hyungwoo");
MODULE_DESCRIPTION("Sony imx355 sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 7c663fd587bb..eb2b8e42335b 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -1055,7 +1055,6 @@ static int max9286_register_gpio(struct max9286_priv *priv)
gpio->label = dev_name(dev);
gpio->parent = dev;
gpio->owner = THIS_MODULE;
- gpio->of_node = dev->of_node;
gpio->ngpio = 2;
gpio->base = -1;
gpio->set = max9286_gpio_set;
@@ -1295,11 +1294,9 @@ static int max9286_probe(struct i2c_client *client)
priv->regulator = devm_regulator_get(&client->dev, "poc");
if (IS_ERR(priv->regulator)) {
- if (PTR_ERR(priv->regulator) != -EPROBE_DEFER)
- dev_err(&client->dev,
- "Unable to get PoC regulator (%ld)\n",
- PTR_ERR(priv->regulator));
ret = PTR_ERR(priv->regulator);
+ dev_err_probe(&client->dev, ret,
+ "Unable to get PoC regulator\n");
goto err_powerdown;
}
diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c
index b4d22f5d9933..d5fe67c763f7 100644
--- a/drivers/media/i2c/ov13858.c
+++ b/drivers/media/i2c/ov13858.c
@@ -1818,6 +1818,6 @@ module_i2c_driver(ov13858_i2c_driver);
MODULE_AUTHOR("Kan, Chris <chris.kan@intel.com>");
MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
-MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
+MODULE_AUTHOR("Yang, Hyungwoo");
MODULE_DESCRIPTION("Omnivision ov13858 sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
index 934c9d65cb09..bab720c7c1de 100644
--- a/drivers/media/i2c/ov2740.c
+++ b/drivers/media/i2c/ov2740.c
@@ -345,6 +345,9 @@ struct ov2740 {
/* NVM data inforamtion */
struct nvm_data *nvm;
+
+ /* True if the device has been identified */
+ bool identified;
};
static inline struct ov2740 *to_ov2740(struct v4l2_subdev *subdev)
@@ -440,6 +443,30 @@ static int ov2740_write_reg_list(struct ov2740 *ov2740,
return 0;
}
+static int ov2740_identify_module(struct ov2740 *ov2740)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
+ int ret;
+ u32 val;
+
+ if (ov2740->identified)
+ return 0;
+
+ ret = ov2740_read_reg(ov2740, OV2740_REG_CHIP_ID, 3, &val);
+ if (ret)
+ return ret;
+
+ if (val != OV2740_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ OV2740_CHIP_ID, val);
+ return -ENXIO;
+ }
+
+ ov2740->identified = true;
+
+ return 0;
+}
+
static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain)
{
int ret = 0;
@@ -724,6 +751,10 @@ static int ov2740_start_streaming(struct ov2740 *ov2740)
int link_freq_index;
int ret = 0;
+ ret = ov2740_identify_module(ov2740);
+ if (ret)
+ return ret;
+
ov2740_load_otp_data(nvm);
link_freq_index = ov2740->cur_mode->link_freq_index;
@@ -956,25 +987,6 @@ static const struct v4l2_subdev_internal_ops ov2740_internal_ops = {
.open = ov2740_open,
};
-static int ov2740_identify_module(struct ov2740 *ov2740)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
- int ret;
- u32 val;
-
- ret = ov2740_read_reg(ov2740, OV2740_REG_CHIP_ID, 3, &val);
- if (ret)
- return ret;
-
- if (val != OV2740_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
- OV2740_CHIP_ID, val);
- return -ENXIO;
- }
-
- return 0;
-}
-
static int ov2740_check_hwcfg(struct device *dev)
{
struct fwnode_handle *ep;
@@ -1137,6 +1149,7 @@ static int ov2740_probe(struct i2c_client *client)
{
struct ov2740 *ov2740;
int ret = 0;
+ bool full_power;
ret = ov2740_check_hwcfg(&client->dev);
if (ret) {
@@ -1149,6 +1162,15 @@ static int ov2740_probe(struct i2c_client *client)
if (!ov2740)
return -ENOMEM;
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ ret = ov2740_identify_module(ov2740);
+ if (ret) {
+ dev_err(&client->dev, "failed to find sensor: %d", ret);
+ return ret;
+ }
+ }
+
v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops);
ret = ov2740_identify_module(ov2740);
if (ret) {
@@ -1186,11 +1208,9 @@ static int ov2740_probe(struct i2c_client *client)
if (ret)
dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret);
- /*
- * Device is already turned on by i2c-core with ACPI domain PM.
- * Enable runtime PM and turn off the device.
- */
- pm_runtime_set_active(&client->dev);
+ /* Set the device's state to active if it's in D0 state. */
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -1225,6 +1245,7 @@ static struct i2c_driver ov2740_i2c_driver = {
},
.probe_new = ov2740_probe,
.remove = ov2740_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(ov2740_i2c_driver);
diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index 251f459ab484..02f75c18e480 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -1833,6 +1833,8 @@ struct ov5670 {
/* Streaming on/off */
bool streaming;
+ /* True if the device has been identified */
+ bool identified;
};
#define to_ov5670(_sd) container_of(_sd, struct ov5670, sd)
@@ -2273,6 +2275,32 @@ static int ov5670_get_skip_frames(struct v4l2_subdev *sd, u32 *frames)
return 0;
}
+/* Verify chip ID */
+static int ov5670_identify_module(struct ov5670 *ov5670)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
+ int ret;
+ u32 val;
+
+ if (ov5670->identified)
+ return 0;
+
+ ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID,
+ OV5670_REG_VALUE_24BIT, &val);
+ if (ret)
+ return ret;
+
+ if (val != OV5670_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ OV5670_CHIP_ID, val);
+ return -ENXIO;
+ }
+
+ ov5670->identified = true;
+
+ return 0;
+}
+
/* Prepare streaming by writing default values and customized values */
static int ov5670_start_streaming(struct ov5670 *ov5670)
{
@@ -2281,6 +2309,10 @@ static int ov5670_start_streaming(struct ov5670 *ov5670)
int link_freq_index;
int ret;
+ ret = ov5670_identify_module(ov5670);
+ if (ret)
+ return ret;
+
/* Get out of from software reset */
ret = ov5670_write_reg(ov5670, OV5670_REG_SOFTWARE_RST,
OV5670_REG_VALUE_08BIT, OV5670_SOFTWARE_RST);
@@ -2400,27 +2432,6 @@ static int __maybe_unused ov5670_resume(struct device *dev)
return 0;
}
-/* Verify chip ID */
-static int ov5670_identify_module(struct ov5670 *ov5670)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
- int ret;
- u32 val;
-
- ret = ov5670_read_reg(ov5670, OV5670_REG_CHIP_ID,
- OV5670_REG_VALUE_24BIT, &val);
- if (ret)
- return ret;
-
- if (val != OV5670_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
- OV5670_CHIP_ID, val);
- return -ENXIO;
- }
-
- return 0;
-}
-
static const struct v4l2_subdev_core_ops ov5670_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
@@ -2462,6 +2473,7 @@ static int ov5670_probe(struct i2c_client *client)
struct ov5670 *ov5670;
const char *err_msg;
u32 input_clk = 0;
+ bool full_power;
int ret;
device_property_read_u32(&client->dev, "clock-frequency", &input_clk);
@@ -2478,11 +2490,14 @@ static int ov5670_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);
- /* Check module identity */
- ret = ov5670_identify_module(ov5670);
- if (ret) {
- err_msg = "ov5670_identify_module() error";
- goto error_print;
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ /* Check module identity */
+ ret = ov5670_identify_module(ov5670);
+ if (ret) {
+ err_msg = "ov5670_identify_module() error";
+ goto error_print;
+ }
}
mutex_init(&ov5670->mutex);
@@ -2519,11 +2534,9 @@ static int ov5670_probe(struct i2c_client *client)
ov5670->streaming = false;
- /*
- * Device is already turned on by i2c-core with ACPI domain PM.
- * Enable runtime PM and turn off the device.
- */
- pm_runtime_set_active(&client->dev);
+ /* Set the device's state to active if it's in D0 state. */
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -2565,7 +2578,7 @@ static const struct dev_pm_ops ov5670_pm_ops = {
#ifdef CONFIG_ACPI
static const struct acpi_device_id ov5670_acpi_ids[] = {
- {"INT3479"},
+ { "INT3479" },
{ /* sentinel */ }
};
@@ -2580,11 +2593,12 @@ static struct i2c_driver ov5670_i2c_driver = {
},
.probe_new = ov5670_probe,
.remove = ov5670_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(ov5670_i2c_driver);
MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
-MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
+MODULE_AUTHOR("Yang, Hyungwoo");
MODULE_DESCRIPTION("Omnivision ov5670 sensor driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c
index da5850b7ad07..00925850fa7c 100644
--- a/drivers/media/i2c/ov5675.c
+++ b/drivers/media/i2c/ov5675.c
@@ -493,6 +493,9 @@ struct ov5675 {
/* Streaming on/off */
bool streaming;
+
+ /* True if the device has been identified */
+ bool identified;
};
static u64 to_pixel_rate(u32 f_index)
@@ -808,12 +811,41 @@ static void ov5675_update_pad_format(const struct ov5675_mode *mode,
fmt->field = V4L2_FIELD_NONE;
}
+static int ov5675_identify_module(struct ov5675 *ov5675)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+ int ret;
+ u32 val;
+
+ if (ov5675->identified)
+ return 0;
+
+ ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID,
+ OV5675_REG_VALUE_24BIT, &val);
+ if (ret)
+ return ret;
+
+ if (val != OV5675_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ OV5675_CHIP_ID, val);
+ return -ENXIO;
+ }
+
+ ov5675->identified = true;
+
+ return 0;
+}
+
static int ov5675_start_streaming(struct ov5675 *ov5675)
{
struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
const struct ov5675_reg_list *reg_list;
int link_freq_index, ret;
+ ret = ov5675_identify_module(ov5675);
+ if (ret)
+ return ret;
+
link_freq_index = ov5675->cur_mode->link_freq_index;
reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = ov5675_write_reg_list(ov5675, reg_list);
@@ -1048,26 +1080,6 @@ static const struct v4l2_subdev_internal_ops ov5675_internal_ops = {
.open = ov5675_open,
};
-static int ov5675_identify_module(struct ov5675 *ov5675)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
- int ret;
- u32 val;
-
- ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID,
- OV5675_REG_VALUE_24BIT, &val);
- if (ret)
- return ret;
-
- if (val != OV5675_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
- OV5675_CHIP_ID, val);
- return -ENXIO;
- }
-
- return 0;
-}
-
static int ov5675_check_hwcfg(struct device *dev)
{
struct fwnode_handle *ep;
@@ -1154,6 +1166,7 @@ static int ov5675_remove(struct i2c_client *client)
static int ov5675_probe(struct i2c_client *client)
{
struct ov5675 *ov5675;
+ bool full_power;
int ret;
ret = ov5675_check_hwcfg(&client->dev);
@@ -1168,10 +1181,14 @@ static int ov5675_probe(struct i2c_client *client)
return -ENOMEM;
v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
- ret = ov5675_identify_module(ov5675);
- if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
- return ret;
+
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ ret = ov5675_identify_module(ov5675);
+ if (ret) {
+ dev_err(&client->dev, "failed to find sensor: %d", ret);
+ return ret;
+ }
}
mutex_init(&ov5675->mutex);
@@ -1204,7 +1221,10 @@ static int ov5675_probe(struct i2c_client *client)
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
*/
- pm_runtime_set_active(&client->dev);
+
+ /* Set the device's state to active if it's in D0 state. */
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -1241,6 +1261,7 @@ static struct i2c_driver ov5675_i2c_driver = {
},
.probe_new = ov5675_probe,
.remove = ov5675_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(ov5675_i2c_driver);
diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
new file mode 100644
index 000000000000..2784fcf67f3b
--- /dev/null
+++ b/drivers/media/i2c/ov5693.c
@@ -0,0 +1,1537 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
+ *
+ * Adapted from the atomisp-ov5693 driver, with contributions from:
+ *
+ * Daniel Scally
+ * Jean-Michel Hautbois
+ * Fabian Wuthrich
+ * Tsuchiya Yuto
+ * Jordan Hand
+ * Jake Day
+ */
+
+#include <asm/unaligned.h>
+#include <linux/acpi.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+
+#define OV5693_REG_8BIT(n) ((1 << 16) | (n))
+#define OV5693_REG_16BIT(n) ((2 << 16) | (n))
+#define OV5693_REG_24BIT(n) ((3 << 16) | (n))
+#define OV5693_REG_SIZE_SHIFT 16
+#define OV5693_REG_ADDR_MASK 0xffff
+
+/* System Control */
+#define OV5693_SW_RESET_REG OV5693_REG_8BIT(0x0103)
+#define OV5693_SW_STREAM_REG OV5693_REG_8BIT(0x0100)
+#define OV5693_START_STREAMING 0x01
+#define OV5693_STOP_STREAMING 0x00
+#define OV5693_SW_RESET 0x01
+
+#define OV5693_REG_CHIP_ID OV5693_REG_16BIT(0x300a)
+/* Yes, this is right. The datasheet for the OV5693 gives its ID as 0x5690 */
+#define OV5693_CHIP_ID 0x5690
+
+/* Exposure */
+#define OV5693_EXPOSURE_CTRL_REG OV5693_REG_24BIT(0x3500)
+#define OV5693_EXPOSURE_CTRL_MASK GENMASK(19, 4)
+#define OV5693_INTEGRATION_TIME_MARGIN 8
+#define OV5693_EXPOSURE_MIN 1
+#define OV5693_EXPOSURE_STEP 1
+
+/* Analogue Gain */
+#define OV5693_GAIN_CTRL_REG OV5693_REG_16BIT(0x350a)
+#define OV5693_GAIN_CTRL_MASK GENMASK(10, 4)
+#define OV5693_GAIN_MIN 1
+#define OV5693_GAIN_MAX 127
+#define OV5693_GAIN_DEF 8
+#define OV5693_GAIN_STEP 1
+
+/* Digital Gain */
+#define OV5693_MWB_RED_GAIN_REG OV5693_REG_16BIT(0x3400)
+#define OV5693_MWB_GREEN_GAIN_REG OV5693_REG_16BIT(0x3402)
+#define OV5693_MWB_BLUE_GAIN_REG OV5693_REG_16BIT(0x3404)
+#define OV5693_MWB_GAIN_MASK GENMASK(11, 0)
+#define OV5693_MWB_GAIN_MAX 0x0fff
+#define OV5693_DIGITAL_GAIN_MIN 1
+#define OV5693_DIGITAL_GAIN_MAX 4095
+#define OV5693_DIGITAL_GAIN_DEF 1024
+#define OV5693_DIGITAL_GAIN_STEP 1
+
+/* Timing and Format */
+#define OV5693_CROP_START_X_REG OV5693_REG_16BIT(0x3800)
+#define OV5693_CROP_START_Y_REG OV5693_REG_16BIT(0x3802)
+#define OV5693_CROP_END_X_REG OV5693_REG_16BIT(0x3804)
+#define OV5693_CROP_END_Y_REG OV5693_REG_16BIT(0x3806)
+#define OV5693_OUTPUT_SIZE_X_REG OV5693_REG_16BIT(0x3808)
+#define OV5693_OUTPUT_SIZE_Y_REG OV5693_REG_16BIT(0x380a)
+
+#define OV5693_TIMING_HTS_REG OV5693_REG_16BIT(0x380c)
+#define OV5693_FIXED_PPL 2688U
+#define OV5693_TIMING_VTS_REG OV5693_REG_16BIT(0x380e)
+#define OV5693_TIMING_MAX_VTS 0xffff
+#define OV5693_TIMING_MIN_VTS 0x04
+
+#define OV5693_OFFSET_START_X_REG OV5693_REG_16BIT(0x3810)
+#define OV5693_OFFSET_START_Y_REG OV5693_REG_16BIT(0x3812)
+
+#define OV5693_SUB_INC_X_REG OV5693_REG_8BIT(0x3814)
+#define OV5693_SUB_INC_Y_REG OV5693_REG_8BIT(0x3815)
+
+#define OV5693_FORMAT1_REG OV5693_REG_8BIT(0x3820)
+#define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(6)
+#define OV5693_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1)
+#define OV5693_FORMAT1_VBIN_EN BIT(0)
+#define OV5693_FORMAT2_REG OV5693_REG_8BIT(0x3821)
+#define OV5693_FORMAT2_HDR_EN BIT(7)
+#define OV5693_FORMAT2_FLIP_HORZ_ISP_EN BIT(2)
+#define OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN BIT(1)
+#define OV5693_FORMAT2_HBIN_EN BIT(0)
+
+#define OV5693_ISP_CTRL2_REG OV5693_REG_8BIT(0x5002)
+#define OV5693_ISP_SCALE_ENABLE BIT(7)
+
+/* Pixel Array */
+#define OV5693_NATIVE_WIDTH 2624
+#define OV5693_NATIVE_HEIGHT 1956
+#define OV5693_NATIVE_START_LEFT 0
+#define OV5693_NATIVE_START_TOP 0
+#define OV5693_ACTIVE_WIDTH 2592
+#define OV5693_ACTIVE_HEIGHT 1944
+#define OV5693_ACTIVE_START_LEFT 16
+#define OV5693_ACTIVE_START_TOP 6
+#define OV5693_MIN_CROP_WIDTH 2
+#define OV5693_MIN_CROP_HEIGHT 2
+
+/* Test Pattern */
+#define OV5693_TEST_PATTERN_REG OV5693_REG_8BIT(0x5e00)
+#define OV5693_TEST_PATTERN_ENABLE BIT(7)
+#define OV5693_TEST_PATTERN_ROLLING BIT(6)
+#define OV5693_TEST_PATTERN_RANDOM 0x01
+#define OV5693_TEST_PATTERN_BARS 0x00
+
+/* System Frequencies */
+#define OV5693_XVCLK_FREQ 19200000
+#define OV5693_LINK_FREQ_419_2MHZ 419200000
+#define OV5693_PIXEL_RATE 167680000
+
+/* Miscellaneous */
+#define OV5693_NUM_SUPPLIES 2
+
+#define to_ov5693_sensor(x) container_of(x, struct ov5693_device, sd)
+
+struct ov5693_reg {
+ u32 reg;
+ u8 val;
+};
+
+struct ov5693_reg_list {
+ u32 num_regs;
+ const struct ov5693_reg *regs;
+};
+
+struct ov5693_device {
+ struct i2c_client *client;
+ struct device *dev;
+
+ /* Protect against concurrent changes to controls */
+ struct mutex lock;
+
+ struct gpio_desc *reset;
+ struct gpio_desc *powerdown;
+ struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES];
+ struct clk *clk;
+
+ struct ov5693_mode {
+ struct v4l2_rect crop;
+ struct v4l2_mbus_framefmt format;
+ bool binning_x;
+ bool binning_y;
+ unsigned int inc_x_odd;
+ unsigned int inc_y_odd;
+ unsigned int vts;
+ } mode;
+ bool streaming;
+
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+
+ struct ov5693_v4l2_ctrls {
+ struct v4l2_ctrl_handler handler;
+ struct v4l2_ctrl *link_freq;
+ struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *analogue_gain;
+ struct v4l2_ctrl *digital_gain;
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *test_pattern;
+ } ctrls;
+};
+
+static const struct ov5693_reg ov5693_global_regs[] = {
+ {OV5693_REG_8BIT(0x3016), 0xf0},
+ {OV5693_REG_8BIT(0x3017), 0xf0},
+ {OV5693_REG_8BIT(0x3018), 0xf0},
+ {OV5693_REG_8BIT(0x3022), 0x01},
+ {OV5693_REG_8BIT(0x3028), 0x44},
+ {OV5693_REG_8BIT(0x3098), 0x02},
+ {OV5693_REG_8BIT(0x3099), 0x19},
+ {OV5693_REG_8BIT(0x309a), 0x02},
+ {OV5693_REG_8BIT(0x309b), 0x01},
+ {OV5693_REG_8BIT(0x309c), 0x00},
+ {OV5693_REG_8BIT(0x30a0), 0xd2},
+ {OV5693_REG_8BIT(0x30a2), 0x01},
+ {OV5693_REG_8BIT(0x30b2), 0x00},
+ {OV5693_REG_8BIT(0x30b3), 0x83},
+ {OV5693_REG_8BIT(0x30b4), 0x03},
+ {OV5693_REG_8BIT(0x30b5), 0x04},
+ {OV5693_REG_8BIT(0x30b6), 0x01},
+ {OV5693_REG_8BIT(0x3080), 0x01},
+ {OV5693_REG_8BIT(0x3104), 0x21},
+ {OV5693_REG_8BIT(0x3106), 0x00},
+ {OV5693_REG_8BIT(0x3406), 0x01},
+ {OV5693_REG_8BIT(0x3503), 0x07},
+ {OV5693_REG_8BIT(0x350b), 0x40},
+ {OV5693_REG_8BIT(0x3601), 0x0a},
+ {OV5693_REG_8BIT(0x3602), 0x38},
+ {OV5693_REG_8BIT(0x3612), 0x80},
+ {OV5693_REG_8BIT(0x3620), 0x54},
+ {OV5693_REG_8BIT(0x3621), 0xc7},
+ {OV5693_REG_8BIT(0x3622), 0x0f},
+ {OV5693_REG_8BIT(0x3625), 0x10},
+ {OV5693_REG_8BIT(0x3630), 0x55},
+ {OV5693_REG_8BIT(0x3631), 0xf4},
+ {OV5693_REG_8BIT(0x3632), 0x00},
+ {OV5693_REG_8BIT(0x3633), 0x34},
+ {OV5693_REG_8BIT(0x3634), 0x02},
+ {OV5693_REG_8BIT(0x364d), 0x0d},
+ {OV5693_REG_8BIT(0x364f), 0xdd},
+ {OV5693_REG_8BIT(0x3660), 0x04},
+ {OV5693_REG_8BIT(0x3662), 0x10},
+ {OV5693_REG_8BIT(0x3663), 0xf1},
+ {OV5693_REG_8BIT(0x3665), 0x00},
+ {OV5693_REG_8BIT(0x3666), 0x20},
+ {OV5693_REG_8BIT(0x3667), 0x00},
+ {OV5693_REG_8BIT(0x366a), 0x80},
+ {OV5693_REG_8BIT(0x3680), 0xe0},
+ {OV5693_REG_8BIT(0x3681), 0x00},
+ {OV5693_REG_8BIT(0x3700), 0x42},
+ {OV5693_REG_8BIT(0x3701), 0x14},
+ {OV5693_REG_8BIT(0x3702), 0xa0},
+ {OV5693_REG_8BIT(0x3703), 0xd8},
+ {OV5693_REG_8BIT(0x3704), 0x78},
+ {OV5693_REG_8BIT(0x3705), 0x02},
+ {OV5693_REG_8BIT(0x370a), 0x00},
+ {OV5693_REG_8BIT(0x370b), 0x20},
+ {OV5693_REG_8BIT(0x370c), 0x0c},
+ {OV5693_REG_8BIT(0x370d), 0x11},
+ {OV5693_REG_8BIT(0x370e), 0x00},
+ {OV5693_REG_8BIT(0x370f), 0x40},
+ {OV5693_REG_8BIT(0x3710), 0x00},
+ {OV5693_REG_8BIT(0x371a), 0x1c},
+ {OV5693_REG_8BIT(0x371b), 0x05},
+ {OV5693_REG_8BIT(0x371c), 0x01},
+ {OV5693_REG_8BIT(0x371e), 0xa1},
+ {OV5693_REG_8BIT(0x371f), 0x0c},
+ {OV5693_REG_8BIT(0x3721), 0x00},
+ {OV5693_REG_8BIT(0x3724), 0x10},
+ {OV5693_REG_8BIT(0x3726), 0x00},
+ {OV5693_REG_8BIT(0x372a), 0x01},
+ {OV5693_REG_8BIT(0x3730), 0x10},
+ {OV5693_REG_8BIT(0x3738), 0x22},
+ {OV5693_REG_8BIT(0x3739), 0xe5},
+ {OV5693_REG_8BIT(0x373a), 0x50},
+ {OV5693_REG_8BIT(0x373b), 0x02},
+ {OV5693_REG_8BIT(0x373c), 0x41},
+ {OV5693_REG_8BIT(0x373f), 0x02},
+ {OV5693_REG_8BIT(0x3740), 0x42},
+ {OV5693_REG_8BIT(0x3741), 0x02},
+ {OV5693_REG_8BIT(0x3742), 0x18},
+ {OV5693_REG_8BIT(0x3743), 0x01},
+ {OV5693_REG_8BIT(0x3744), 0x02},
+ {OV5693_REG_8BIT(0x3747), 0x10},
+ {OV5693_REG_8BIT(0x374c), 0x04},
+ {OV5693_REG_8BIT(0x3751), 0xf0},
+ {OV5693_REG_8BIT(0x3752), 0x00},
+ {OV5693_REG_8BIT(0x3753), 0x00},
+ {OV5693_REG_8BIT(0x3754), 0xc0},
+ {OV5693_REG_8BIT(0x3755), 0x00},
+ {OV5693_REG_8BIT(0x3756), 0x1a},
+ {OV5693_REG_8BIT(0x3758), 0x00},
+ {OV5693_REG_8BIT(0x3759), 0x0f},
+ {OV5693_REG_8BIT(0x376b), 0x44},
+ {OV5693_REG_8BIT(0x375c), 0x04},
+ {OV5693_REG_8BIT(0x3774), 0x10},
+ {OV5693_REG_8BIT(0x3776), 0x00},
+ {OV5693_REG_8BIT(0x377f), 0x08},
+ {OV5693_REG_8BIT(0x3780), 0x22},
+ {OV5693_REG_8BIT(0x3781), 0x0c},
+ {OV5693_REG_8BIT(0x3784), 0x2c},
+ {OV5693_REG_8BIT(0x3785), 0x1e},
+ {OV5693_REG_8BIT(0x378f), 0xf5},
+ {OV5693_REG_8BIT(0x3791), 0xb0},
+ {OV5693_REG_8BIT(0x3795), 0x00},
+ {OV5693_REG_8BIT(0x3796), 0x64},
+ {OV5693_REG_8BIT(0x3797), 0x11},
+ {OV5693_REG_8BIT(0x3798), 0x30},
+ {OV5693_REG_8BIT(0x3799), 0x41},
+ {OV5693_REG_8BIT(0x379a), 0x07},
+ {OV5693_REG_8BIT(0x379b), 0xb0},
+ {OV5693_REG_8BIT(0x379c), 0x0c},
+ {OV5693_REG_8BIT(0x3a04), 0x06},
+ {OV5693_REG_8BIT(0x3a05), 0x14},
+ {OV5693_REG_8BIT(0x3e07), 0x20},
+ {OV5693_REG_8BIT(0x4000), 0x08},
+ {OV5693_REG_8BIT(0x4001), 0x04},
+ {OV5693_REG_8BIT(0x4004), 0x08},
+ {OV5693_REG_8BIT(0x4006), 0x20},
+ {OV5693_REG_8BIT(0x4008), 0x24},
+ {OV5693_REG_8BIT(0x4009), 0x10},
+ {OV5693_REG_8BIT(0x4058), 0x00},
+ {OV5693_REG_8BIT(0x4101), 0xb2},
+ {OV5693_REG_8BIT(0x4307), 0x31},
+ {OV5693_REG_8BIT(0x4511), 0x05},
+ {OV5693_REG_8BIT(0x4512), 0x01},
+ {OV5693_REG_8BIT(0x481f), 0x30},
+ {OV5693_REG_8BIT(0x4826), 0x2c},
+ {OV5693_REG_8BIT(0x4d02), 0xfd},
+ {OV5693_REG_8BIT(0x4d03), 0xf5},
+ {OV5693_REG_8BIT(0x4d04), 0x0c},
+ {OV5693_REG_8BIT(0x4d05), 0xcc},
+ {OV5693_REG_8BIT(0x4837), 0x0a},
+ {OV5693_REG_8BIT(0x5003), 0x20},
+ {OV5693_REG_8BIT(0x5013), 0x00},
+ {OV5693_REG_8BIT(0x5842), 0x01},
+ {OV5693_REG_8BIT(0x5843), 0x2b},
+ {OV5693_REG_8BIT(0x5844), 0x01},
+ {OV5693_REG_8BIT(0x5845), 0x92},
+ {OV5693_REG_8BIT(0x5846), 0x01},
+ {OV5693_REG_8BIT(0x5847), 0x8f},
+ {OV5693_REG_8BIT(0x5848), 0x01},
+ {OV5693_REG_8BIT(0x5849), 0x0c},
+ {OV5693_REG_8BIT(0x5e10), 0x0c},
+ {OV5693_REG_8BIT(0x3820), 0x00},
+ {OV5693_REG_8BIT(0x3821), 0x1e},
+ {OV5693_REG_8BIT(0x5041), 0x14}
+};
+
+static const struct ov5693_reg_list ov5693_global_setting = {
+ .num_regs = ARRAY_SIZE(ov5693_global_regs),
+ .regs = ov5693_global_regs,
+};
+
+static const struct v4l2_rect ov5693_default_crop = {
+ .left = OV5693_ACTIVE_START_LEFT,
+ .top = OV5693_ACTIVE_START_TOP,
+ .width = OV5693_ACTIVE_WIDTH,
+ .height = OV5693_ACTIVE_HEIGHT,
+};
+
+static const struct v4l2_mbus_framefmt ov5693_default_fmt = {
+ .width = OV5693_ACTIVE_WIDTH,
+ .height = OV5693_ACTIVE_HEIGHT,
+ .code = MEDIA_BUS_FMT_SBGGR10_1X10,
+};
+
+static const s64 link_freq_menu_items[] = {
+ OV5693_LINK_FREQ_419_2MHZ
+};
+
+static const char * const ov5693_supply_names[] = {
+ "avdd",
+ "dovdd",
+};
+
+static const char * const ov5693_test_pattern_menu[] = {
+ "Disabled",
+ "Random Data",
+ "Colour Bars",
+ "Colour Bars with Rolling Bar"
+};
+
+static const u8 ov5693_test_pattern_bits[] = {
+ 0,
+ OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_RANDOM,
+ OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS,
+ OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS |
+ OV5693_TEST_PATTERN_ROLLING,
+};
+
+/* I2C I/O Operations */
+
+static int ov5693_read_reg(struct ov5693_device *ov5693, u32 addr, u32 *value)
+{
+ struct i2c_client *client = ov5693->client;
+ __be16 reg;
+ u8 val[4];
+ struct i2c_msg msg[] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = (u8 *)&reg,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .buf = (u8 *)&val,
+ },
+ };
+ unsigned int len = ((addr >> OV5693_REG_SIZE_SHIFT) & 3);
+ unsigned int i;
+ int ret;
+
+ reg = cpu_to_be16(addr & OV5693_REG_ADDR_MASK);
+
+ msg[1].len = len;
+
+ ret = i2c_transfer(client->adapter, msg, 2);
+ if (ret < 0)
+ return dev_err_probe(&client->dev, ret,
+ "Failed to read register 0x%04x: %d\n",
+ addr & OV5693_REG_ADDR_MASK, ret);
+
+ *value = 0;
+ for (i = 0; i < len; ++i) {
+ *value <<= 8;
+ *value |= val[i];
+ }
+
+ return 0;
+}
+
+static void ov5693_write_reg(struct ov5693_device *ov5693, u32 addr, u32 value,
+ int *error)
+{
+ struct i2c_client *client = ov5693->client;
+ struct {
+ __be16 reg;
+ u8 val[4];
+ } __packed buf;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .buf = (u8 *)&buf,
+ };
+ unsigned int len = ((addr >> OV5693_REG_SIZE_SHIFT) & 3);
+ unsigned int i;
+ int ret;
+
+ if (*error < 0)
+ return;
+
+ buf.reg = cpu_to_be16(addr & OV5693_REG_ADDR_MASK);
+ for (i = 0; i < len; ++i) {
+ buf.val[len - i - 1] = value & 0xff;
+ value >>= 8;
+ }
+
+ msg.len = len + 2;
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to write register 0x%04x: %d\n",
+ addr & OV5693_REG_ADDR_MASK, ret);
+ *error = ret;
+ }
+}
+
+static int ov5693_write_reg_array(struct ov5693_device *ov5693,
+ const struct ov5693_reg_list *reglist)
+{
+ unsigned int i;
+ int ret = 0;
+
+ for (i = 0; i < reglist->num_regs; i++)
+ ov5693_write_reg(ov5693, reglist->regs[i].reg,
+ reglist->regs[i].val, &ret);
+
+ return ret;
+}
+
+static int ov5693_update_bits(struct ov5693_device *ov5693, u32 address,
+ u32 mask, u32 bits)
+{
+ u32 value = 0;
+ int ret;
+
+ ret = ov5693_read_reg(ov5693, address, &value);
+ if (ret)
+ return ret;
+
+ value &= ~mask;
+ value |= bits;
+
+ ov5693_write_reg(ov5693, address, value, &ret);
+
+ return ret;
+}
+
+/* V4L2 Controls Functions */
+
+static int ov5693_flip_vert_configure(struct ov5693_device *ov5693,
+ bool enable)
+{
+ u8 bits = OV5693_FORMAT1_FLIP_VERT_ISP_EN |
+ OV5693_FORMAT1_FLIP_VERT_SENSOR_EN;
+ int ret;
+
+ ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG, bits,
+ enable ? bits : 0);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ov5693_flip_horz_configure(struct ov5693_device *ov5693,
+ bool enable)
+{
+ u8 bits = OV5693_FORMAT2_FLIP_HORZ_ISP_EN |
+ OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN;
+ int ret;
+
+ ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG, bits,
+ enable ? bits : 0);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ov5693_get_exposure(struct ov5693_device *ov5693, s32 *value)
+{
+ u32 exposure;
+ int ret;
+
+ ret = ov5693_read_reg(ov5693, OV5693_EXPOSURE_CTRL_REG, &exposure);
+ if (ret)
+ return ret;
+
+ /* The lowest 4 bits are unsupported fractional bits */
+ *value = exposure >> 4;
+
+ return 0;
+}
+
+static int ov5693_exposure_configure(struct ov5693_device *ov5693,
+ u32 exposure)
+{
+ int ret = 0;
+
+ exposure = (exposure << 4) & OV5693_EXPOSURE_CTRL_MASK;
+
+ ov5693_write_reg(ov5693, OV5693_EXPOSURE_CTRL_REG, exposure, &ret);
+
+ return ret;
+}
+
+static int ov5693_get_gain(struct ov5693_device *ov5693, u32 *gain)
+{
+ u32 value;
+ int ret;
+
+ ret = ov5693_read_reg(ov5693, OV5693_GAIN_CTRL_REG, &value);
+ if (ret)
+ return ret;
+
+ /* As with exposure, the lowest 4 bits are fractional bits. */
+ *gain = value >> 4;
+
+ return ret;
+}
+
+static int ov5693_digital_gain_configure(struct ov5693_device *ov5693,
+ u32 gain)
+{
+ int ret = 0;
+
+ gain &= OV5693_MWB_GAIN_MASK;
+
+ ov5693_write_reg(ov5693, OV5693_MWB_RED_GAIN_REG, gain, &ret);
+ ov5693_write_reg(ov5693, OV5693_MWB_GREEN_GAIN_REG, gain, &ret);
+ ov5693_write_reg(ov5693, OV5693_MWB_BLUE_GAIN_REG, gain, &ret);
+
+ return ret;
+}
+
+static int ov5693_analog_gain_configure(struct ov5693_device *ov5693, u32 gain)
+{
+ int ret = 0;
+
+ gain = (gain << 4) & OV5693_GAIN_CTRL_MASK;
+
+ ov5693_write_reg(ov5693, OV5693_GAIN_CTRL_REG, gain, &ret);
+
+ return ret;
+}
+
+static int ov5693_vts_configure(struct ov5693_device *ov5693, u32 vblank)
+{
+ u16 vts = ov5693->mode.format.height + vblank;
+ int ret = 0;
+
+ ov5693_write_reg(ov5693, OV5693_TIMING_VTS_REG, vts, &ret);
+
+ return ret;
+}
+
+static int ov5693_test_pattern_configure(struct ov5693_device *ov5693, u32 idx)
+{
+ int ret = 0;
+
+ ov5693_write_reg(ov5693, OV5693_TEST_PATTERN_REG,
+ ov5693_test_pattern_bits[idx], &ret);
+
+ return ret;
+}
+
+static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ov5693_device *ov5693 =
+ container_of(ctrl->handler, struct ov5693_device, ctrls.handler);
+ int ret = 0;
+
+ /* If VBLANK is altered we need to update exposure to compensate */
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ int exposure_max;
+
+ exposure_max = ov5693->mode.format.height + ctrl->val -
+ OV5693_INTEGRATION_TIME_MARGIN;
+ __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
+ ov5693->ctrls.exposure->minimum,
+ exposure_max,
+ ov5693->ctrls.exposure->step,
+ min(ov5693->ctrls.exposure->val,
+ exposure_max));
+ }
+
+ /* Only apply changes to the controls if the device is powered up */
+ if (!pm_runtime_get_if_in_use(ov5693->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ ret = ov5693_exposure_configure(ov5693, ctrl->val);
+ break;
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = ov5693_analog_gain_configure(ov5693, ctrl->val);
+ break;
+ case V4L2_CID_DIGITAL_GAIN:
+ ret = ov5693_digital_gain_configure(ov5693, ctrl->val);
+ break;
+ case V4L2_CID_HFLIP:
+ ret = ov5693_flip_horz_configure(ov5693, !!ctrl->val);
+ break;
+ case V4L2_CID_VFLIP:
+ ret = ov5693_flip_vert_configure(ov5693, !!ctrl->val);
+ break;
+ case V4L2_CID_VBLANK:
+ ret = ov5693_vts_configure(ov5693, ctrl->val);
+ break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = ov5693_test_pattern_configure(ov5693, ctrl->val);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ pm_runtime_put(ov5693->dev);
+
+ return ret;
+}
+
+static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ov5693_device *ov5693 = container_of(ctrl->handler,
+ struct ov5693_device,
+ ctrls.handler);
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE_ABSOLUTE:
+ return ov5693_get_exposure(ov5693, &ctrl->val);
+ case V4L2_CID_AUTOGAIN:
+ return ov5693_get_gain(ov5693, &ctrl->val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ctrl_ops ov5693_ctrl_ops = {
+ .s_ctrl = ov5693_s_ctrl,
+ .g_volatile_ctrl = ov5693_g_volatile_ctrl
+};
+
+/* System Control Functions */
+
+static int ov5693_mode_configure(struct ov5693_device *ov5693)
+{
+ const struct ov5693_mode *mode = &ov5693->mode;
+ int ret = 0;
+
+ /* Crop Start X */
+ ov5693_write_reg(ov5693, OV5693_CROP_START_X_REG, mode->crop.left,
+ &ret);
+
+ /* Offset X */
+ ov5693_write_reg(ov5693, OV5693_OFFSET_START_X_REG, 0, &ret);
+
+ /* Output Size X */
+ ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_X_REG, mode->format.width,
+ &ret);
+
+ /* Crop End X */
+ ov5693_write_reg(ov5693, OV5693_CROP_END_X_REG,
+ mode->crop.left + mode->crop.width, &ret);
+
+ /* Horizontal Total Size */
+ ov5693_write_reg(ov5693, OV5693_TIMING_HTS_REG, OV5693_FIXED_PPL,
+ &ret);
+
+ /* Crop Start Y */
+ ov5693_write_reg(ov5693, OV5693_CROP_START_Y_REG, mode->crop.top,
+ &ret);
+
+ /* Offset Y */
+ ov5693_write_reg(ov5693, OV5693_OFFSET_START_Y_REG, 0, &ret);
+
+ /* Output Size Y */
+ ov5693_write_reg(ov5693, OV5693_OUTPUT_SIZE_Y_REG, mode->format.height,
+ &ret);
+
+ /* Crop End Y */
+ ov5693_write_reg(ov5693, OV5693_CROP_END_Y_REG,
+ mode->crop.top + mode->crop.height, &ret);
+
+ /* Subsample X increase */
+ ov5693_write_reg(ov5693, OV5693_SUB_INC_X_REG,
+ ((mode->inc_x_odd << 4) & 0xf0) | 0x01, &ret);
+ /* Subsample Y increase */
+ ov5693_write_reg(ov5693, OV5693_SUB_INC_Y_REG,
+ ((mode->inc_y_odd << 4) & 0xf0) | 0x01, &ret);
+
+ if (ret)
+ return ret;
+
+ /* Binning */
+ ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG,
+ OV5693_FORMAT1_VBIN_EN,
+ mode->binning_y ? OV5693_FORMAT1_VBIN_EN : 0);
+ if (ret)
+ return ret;
+
+ ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG,
+ OV5693_FORMAT2_HBIN_EN,
+ mode->binning_x ? OV5693_FORMAT2_HBIN_EN : 0);
+
+ return ret;
+}
+
+static int ov5693_enable_streaming(struct ov5693_device *ov5693, bool enable)
+{
+ int ret = 0;
+
+ ov5693_write_reg(ov5693, OV5693_SW_STREAM_REG,
+ enable ? OV5693_START_STREAMING :
+ OV5693_STOP_STREAMING, &ret);
+
+ return ret;
+}
+
+static int ov5693_sw_reset(struct ov5693_device *ov5693)
+{
+ int ret = 0;
+
+ ov5693_write_reg(ov5693, OV5693_SW_RESET_REG, OV5693_SW_RESET, &ret);
+
+ return ret;
+}
+
+static int ov5693_sensor_init(struct ov5693_device *ov5693)
+{
+ int ret;
+
+ ret = ov5693_sw_reset(ov5693);
+ if (ret)
+ return dev_err_probe(ov5693->dev, ret,
+ "software reset error\n");
+
+ ret = ov5693_write_reg_array(ov5693, &ov5693_global_setting);
+ if (ret)
+ return dev_err_probe(ov5693->dev, ret,
+ "global settings error\n");
+
+ ret = ov5693_mode_configure(ov5693);
+ if (ret)
+ return dev_err_probe(ov5693->dev, ret,
+ "mode configure error\n");
+
+ ret = ov5693_enable_streaming(ov5693, false);
+ if (ret)
+ dev_err(ov5693->dev, "stop streaming error\n");
+
+ return ret;
+}
+
+static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
+{
+ gpiod_set_value_cansleep(ov5693->reset, 1);
+ gpiod_set_value_cansleep(ov5693->powerdown, 1);
+
+ regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
+
+ clk_disable_unprepare(ov5693->clk);
+}
+
+static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
+{
+ int ret;
+
+ gpiod_set_value_cansleep(ov5693->reset, 1);
+ gpiod_set_value_cansleep(ov5693->powerdown, 1);
+
+ ret = clk_prepare_enable(ov5693->clk);
+ if (ret) {
+ dev_err(ov5693->dev, "Failed to enable clk\n");
+ goto fail_power;
+ }
+
+ ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES, ov5693->supplies);
+ if (ret) {
+ dev_err(ov5693->dev, "Failed to enable regulators\n");
+ goto fail_power;
+ }
+
+ gpiod_set_value_cansleep(ov5693->powerdown, 0);
+ gpiod_set_value_cansleep(ov5693->reset, 0);
+
+ usleep_range(5000, 7500);
+
+ return 0;
+
+fail_power:
+ ov5693_sensor_powerdown(ov5693);
+ return ret;
+}
+
+static int __maybe_unused ov5693_sensor_suspend(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+
+ ov5693_sensor_powerdown(ov5693);
+
+ return 0;
+}
+
+static int __maybe_unused ov5693_sensor_resume(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+ int ret;
+
+ mutex_lock(&ov5693->lock);
+
+ ret = ov5693_sensor_powerup(ov5693);
+ if (ret)
+ goto out_unlock;
+
+ ret = ov5693_sensor_init(ov5693);
+ if (ret) {
+ dev_err(dev, "ov5693 sensor init failure\n");
+ goto err_power;
+ }
+
+ goto out_unlock;
+
+err_power:
+ ov5693_sensor_powerdown(ov5693);
+out_unlock:
+ mutex_unlock(&ov5693->lock);
+ return ret;
+}
+
+static int ov5693_detect(struct ov5693_device *ov5693)
+{
+ int ret;
+ u32 id;
+
+ ret = ov5693_read_reg(ov5693, OV5693_REG_CHIP_ID, &id);
+ if (ret)
+ return ret;
+
+ if (id != OV5693_CHIP_ID)
+ return dev_err_probe(ov5693->dev, -ENODEV,
+ "sensor ID mismatch. Found 0x%04x\n", id);
+
+ return 0;
+}
+
+/* V4L2 Framework callbacks */
+
+static unsigned int __ov5693_calc_vts(u32 height)
+{
+ /*
+ * We need to set a sensible default VTS for whatever format height we
+ * happen to be given from set_fmt(). This function just targets
+ * an even multiple of 30fps.
+ */
+
+ unsigned int tgt_fps;
+
+ tgt_fps = rounddown(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / height, 30);
+
+ return ALIGN_DOWN(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / tgt_fps, 2);
+}
+
+static struct v4l2_mbus_framefmt *
+__ov5693_get_pad_format(struct ov5693_device *ov5693,
+ struct v4l2_subdev_state *state,
+ unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+ switch (which) {
+ case V4L2_SUBDEV_FORMAT_TRY:
+ return v4l2_subdev_get_try_format(&ov5693->sd, state, pad);
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
+ return &ov5693->mode.format;
+ default:
+ return NULL;
+ }
+}
+
+static struct v4l2_rect *
+__ov5693_get_pad_crop(struct ov5693_device *ov5693,
+ struct v4l2_subdev_state *state,
+ unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+ switch (which) {
+ case V4L2_SUBDEV_FORMAT_TRY:
+ return v4l2_subdev_get_try_crop(&ov5693->sd, state, pad);
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
+ return &ov5693->mode.crop;
+ }
+
+ return NULL;
+}
+
+static int ov5693_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *format)
+{
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+
+ format->format = ov5693->mode.format;
+
+ return 0;
+}
+
+static int ov5693_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *format)
+{
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+ const struct v4l2_rect *crop;
+ struct v4l2_mbus_framefmt *fmt;
+ unsigned int hratio, vratio;
+ unsigned int width, height;
+ unsigned int hblank;
+ int exposure_max;
+ int ret = 0;
+
+ crop = __ov5693_get_pad_crop(ov5693, state, format->pad, format->which);
+
+ /*
+ * Align to two to simplify the binning calculations below, and clamp
+ * the requested format at the crop rectangle
+ */
+ width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
+ OV5693_MIN_CROP_WIDTH, crop->width);
+ height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
+ OV5693_MIN_CROP_HEIGHT, crop->height);
+
+ /*
+ * We can only support setting either the dimensions of the crop rect
+ * or those dimensions binned (separately) by a factor of two.
+ */
+ hratio = clamp_t(unsigned int,
+ DIV_ROUND_CLOSEST(crop->width, width), 1, 2);
+ vratio = clamp_t(unsigned int,
+ DIV_ROUND_CLOSEST(crop->height, height), 1, 2);
+
+ fmt = __ov5693_get_pad_format(ov5693, state, format->pad,
+ format->which);
+
+ fmt->width = crop->width / hratio;
+ fmt->height = crop->height / vratio;
+ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
+
+ format->format = *fmt;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+ return ret;
+
+ mutex_lock(&ov5693->lock);
+
+ ov5693->mode.binning_x = hratio > 1 ? true : false;
+ ov5693->mode.inc_x_odd = hratio > 1 ? 3 : 1;
+ ov5693->mode.binning_y = vratio > 1 ? true : false;
+ ov5693->mode.inc_y_odd = vratio > 1 ? 3 : 1;
+
+ ov5693->mode.vts = __ov5693_calc_vts(fmt->height);
+
+ __v4l2_ctrl_modify_range(ov5693->ctrls.vblank,
+ OV5693_TIMING_MIN_VTS,
+ OV5693_TIMING_MAX_VTS - fmt->height,
+ 1, ov5693->mode.vts - fmt->height);
+ __v4l2_ctrl_s_ctrl(ov5693->ctrls.vblank,
+ ov5693->mode.vts - fmt->height);
+
+ hblank = OV5693_FIXED_PPL - fmt->width;
+ __v4l2_ctrl_modify_range(ov5693->ctrls.hblank, hblank, hblank, 1,
+ hblank);
+
+ exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN;
+ __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
+ ov5693->ctrls.exposure->minimum, exposure_max,
+ ov5693->ctrls.exposure->step,
+ min(ov5693->ctrls.exposure->val,
+ exposure_max));
+
+ mutex_unlock(&ov5693->lock);
+ return ret;
+}
+
+static int ov5693_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_selection *sel)
+{
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ mutex_lock(&ov5693->lock);
+ sel->r = *__ov5693_get_pad_crop(ov5693, state, sel->pad,
+ sel->which);
+ mutex_unlock(&ov5693->lock);
+ break;
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.top = 0;
+ sel->r.left = 0;
+ sel->r.width = OV5693_NATIVE_WIDTH;
+ sel->r.height = OV5693_NATIVE_HEIGHT;
+ break;
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.top = OV5693_ACTIVE_START_TOP;
+ sel->r.left = OV5693_ACTIVE_START_LEFT;
+ sel->r.width = OV5693_ACTIVE_WIDTH;
+ sel->r.height = OV5693_ACTIVE_HEIGHT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ov5693_set_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_selection *sel)
+{
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+ struct v4l2_mbus_framefmt *format;
+ struct v4l2_rect *__crop;
+ struct v4l2_rect rect;
+
+ if (sel->target != V4L2_SEL_TGT_CROP)
+ return -EINVAL;
+
+ /*
+ * Clamp the boundaries of the crop rectangle to the size of the sensor
+ * pixel array. Align to multiples of 2 to ensure Bayer pattern isn't
+ * disrupted.
+ */
+ rect.left = clamp(ALIGN(sel->r.left, 2), OV5693_NATIVE_START_LEFT,
+ OV5693_NATIVE_WIDTH);
+ rect.top = clamp(ALIGN(sel->r.top, 2), OV5693_NATIVE_START_TOP,
+ OV5693_NATIVE_HEIGHT);
+ rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
+ OV5693_MIN_CROP_WIDTH, OV5693_NATIVE_WIDTH);
+ rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
+ OV5693_MIN_CROP_HEIGHT, OV5693_NATIVE_HEIGHT);
+
+ /* Make sure the crop rectangle isn't outside the bounds of the array */
+ rect.width = min_t(unsigned int, rect.width,
+ OV5693_NATIVE_WIDTH - rect.left);
+ rect.height = min_t(unsigned int, rect.height,
+ OV5693_NATIVE_HEIGHT - rect.top);
+
+ __crop = __ov5693_get_pad_crop(ov5693, state, sel->pad, sel->which);
+
+ if (rect.width != __crop->width || rect.height != __crop->height) {
+ /*
+ * Reset the output image size if the crop rectangle size has
+ * been modified.
+ */
+ format = __ov5693_get_pad_format(ov5693, state, sel->pad,
+ sel->which);
+ format->width = rect.width;
+ format->height = rect.height;
+ }
+
+ *__crop = rect;
+ sel->r = rect;
+
+ return 0;
+}
+
+static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+ int ret;
+
+ if (enable) {
+ ret = pm_runtime_get_sync(ov5693->dev);
+ if (ret < 0)
+ goto err_power_down;
+
+ mutex_lock(&ov5693->lock);
+ ret = __v4l2_ctrl_handler_setup(&ov5693->ctrls.handler);
+ if (ret) {
+ mutex_unlock(&ov5693->lock);
+ goto err_power_down;
+ }
+
+ ret = ov5693_enable_streaming(ov5693, true);
+ mutex_unlock(&ov5693->lock);
+ } else {
+ mutex_lock(&ov5693->lock);
+ ret = ov5693_enable_streaming(ov5693, false);
+ mutex_unlock(&ov5693->lock);
+ }
+ if (ret)
+ goto err_power_down;
+
+ ov5693->streaming = !!enable;
+
+ if (!enable)
+ pm_runtime_put(ov5693->dev);
+
+ return 0;
+err_power_down:
+ pm_runtime_put_noidle(ov5693->dev);
+ return ret;
+}
+
+static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_frame_interval *interval)
+{
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+ unsigned int framesize = OV5693_FIXED_PPL * (ov5693->mode.format.height +
+ ov5693->ctrls.vblank->val);
+ unsigned int fps = DIV_ROUND_CLOSEST(OV5693_PIXEL_RATE, framesize);
+
+ interval->interval.numerator = 1;
+ interval->interval.denominator = fps;
+
+ return 0;
+}
+
+static int ov5693_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ /* Only a single mbus format is supported */
+ if (code->index > 0)
+ return -EINVAL;
+
+ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
+ return 0;
+}
+
+static int ov5693_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+ struct v4l2_rect *__crop;
+
+ if (fse->index > 1 || fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
+ return -EINVAL;
+
+ __crop = __ov5693_get_pad_crop(ov5693, state, fse->pad, fse->which);
+ if (!__crop)
+ return -EINVAL;
+
+ fse->min_width = __crop->width / (fse->index + 1);
+ fse->min_height = __crop->height / (fse->index + 1);
+ fse->max_width = fse->min_width;
+ fse->max_height = fse->min_height;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov5693_video_ops = {
+ .s_stream = ov5693_s_stream,
+ .g_frame_interval = ov5693_g_frame_interval,
+};
+
+static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
+ .enum_mbus_code = ov5693_enum_mbus_code,
+ .enum_frame_size = ov5693_enum_frame_size,
+ .get_fmt = ov5693_get_fmt,
+ .set_fmt = ov5693_set_fmt,
+ .get_selection = ov5693_get_selection,
+ .set_selection = ov5693_set_selection,
+};
+
+static const struct v4l2_subdev_ops ov5693_ops = {
+ .video = &ov5693_video_ops,
+ .pad = &ov5693_pad_ops,
+};
+
+/* Sensor and Driver Configuration Functions */
+
+static int ov5693_init_controls(struct ov5693_device *ov5693)
+{
+ const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
+ struct ov5693_v4l2_ctrls *ctrls = &ov5693->ctrls;
+ struct v4l2_fwnode_device_properties props;
+ int vblank_max, vblank_def;
+ int exposure_max;
+ int hblank;
+ int ret;
+
+ ret = v4l2_ctrl_handler_init(&ctrls->handler, 12);
+ if (ret)
+ return ret;
+
+ /* link freq */
+ ctrls->link_freq = v4l2_ctrl_new_int_menu(&ctrls->handler,
+ NULL, V4L2_CID_LINK_FREQ,
+ 0, 0, link_freq_menu_items);
+ if (ctrls->link_freq)
+ ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ /* pixel rate */
+ ctrls->pixel_rate = v4l2_ctrl_new_std(&ctrls->handler, NULL,
+ V4L2_CID_PIXEL_RATE, 0,
+ OV5693_PIXEL_RATE, 1,
+ OV5693_PIXEL_RATE);
+
+ /* Exposure */
+ exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN;
+ ctrls->exposure = v4l2_ctrl_new_std(&ctrls->handler, ops,
+ V4L2_CID_EXPOSURE,
+ OV5693_EXPOSURE_MIN, exposure_max,
+ OV5693_EXPOSURE_STEP, exposure_max);
+
+ /* Gain */
+ ctrls->analogue_gain = v4l2_ctrl_new_std(&ctrls->handler,
+ ops, V4L2_CID_ANALOGUE_GAIN,
+ OV5693_GAIN_MIN,
+ OV5693_GAIN_MAX,
+ OV5693_GAIN_STEP,
+ OV5693_GAIN_DEF);
+
+ ctrls->digital_gain = v4l2_ctrl_new_std(&ctrls->handler, ops,
+ V4L2_CID_DIGITAL_GAIN,
+ OV5693_DIGITAL_GAIN_MIN,
+ OV5693_DIGITAL_GAIN_MAX,
+ OV5693_DIGITAL_GAIN_STEP,
+ OV5693_DIGITAL_GAIN_DEF);
+
+ /* Flip */
+ ctrls->hflip = v4l2_ctrl_new_std(&ctrls->handler, ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+ ctrls->vflip = v4l2_ctrl_new_std(&ctrls->handler, ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+ hblank = OV5693_FIXED_PPL - ov5693->mode.format.width;
+ ctrls->hblank = v4l2_ctrl_new_std(&ctrls->handler, ops,
+ V4L2_CID_HBLANK, hblank,
+ hblank, 1, hblank);
+
+ if (ctrls->hblank)
+ ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ vblank_max = OV5693_TIMING_MAX_VTS - ov5693->mode.format.height;
+ vblank_def = ov5693->mode.vts - ov5693->mode.format.height;
+ ctrls->vblank = v4l2_ctrl_new_std(&ctrls->handler, ops,
+ V4L2_CID_VBLANK,
+ OV5693_TIMING_MIN_VTS,
+ vblank_max, 1, vblank_def);
+
+ ctrls->test_pattern = v4l2_ctrl_new_std_menu_items(
+ &ctrls->handler, ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(ov5693_test_pattern_menu) - 1,
+ 0, 0, ov5693_test_pattern_menu);
+
+ if (ctrls->handler.error) {
+ dev_err(ov5693->dev, "Error initialising v4l2 ctrls\n");
+ ret = ctrls->handler.error;
+ goto err_free_handler;
+ }
+
+ /* set properties from fwnode (e.g. rotation, orientation) */
+ ret = v4l2_fwnode_device_parse(ov5693->dev, &props);
+ if (ret)
+ goto err_free_handler;
+
+ ret = v4l2_ctrl_new_fwnode_properties(&ctrls->handler, ops,
+ &props);
+ if (ret)
+ goto err_free_handler;
+
+ /* Use same lock for controls as for everything else. */
+ ctrls->handler.lock = &ov5693->lock;
+ ov5693->sd.ctrl_handler = &ctrls->handler;
+
+ return 0;
+
+err_free_handler:
+ v4l2_ctrl_handler_free(&ctrls->handler);
+ return ret;
+}
+
+static int ov5693_configure_gpios(struct ov5693_device *ov5693)
+{
+ ov5693->reset = devm_gpiod_get_optional(ov5693->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(ov5693->reset)) {
+ dev_err(ov5693->dev, "Error fetching reset GPIO\n");
+ return PTR_ERR(ov5693->reset);
+ }
+
+ ov5693->powerdown = devm_gpiod_get_optional(ov5693->dev, "powerdown",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(ov5693->powerdown)) {
+ dev_err(ov5693->dev, "Error fetching powerdown GPIO\n");
+ return PTR_ERR(ov5693->powerdown);
+ }
+
+ return 0;
+}
+
+static int ov5693_get_regulators(struct ov5693_device *ov5693)
+{
+ unsigned int i;
+
+ for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
+ ov5693->supplies[i].supply = ov5693_supply_names[i];
+
+ return devm_regulator_bulk_get(ov5693->dev, OV5693_NUM_SUPPLIES,
+ ov5693->supplies);
+}
+
+static int ov5693_check_hwcfg(struct ov5693_device *ov5693)
+{
+ struct fwnode_handle *fwnode = dev_fwnode(ov5693->dev);
+ struct v4l2_fwnode_endpoint bus_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY,
+ };
+ struct fwnode_handle *endpoint;
+ unsigned int i;
+ int ret;
+
+ endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
+ if (!endpoint)
+ return -EPROBE_DEFER; /* Could be provided by cio2-bridge */
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
+ fwnode_handle_put(endpoint);
+ if (ret)
+ return ret;
+
+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
+ dev_err(ov5693->dev, "only a 2-lane CSI2 config is supported");
+ ret = -EINVAL;
+ goto out_free_bus_cfg;
+ }
+
+ if (!bus_cfg.nr_of_link_frequencies) {
+ dev_err(ov5693->dev, "no link frequencies defined\n");
+ ret = -EINVAL;
+ goto out_free_bus_cfg;
+ }
+
+ for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
+ if (bus_cfg.link_frequencies[i] == OV5693_LINK_FREQ_419_2MHZ)
+ break;
+
+ if (i == bus_cfg.nr_of_link_frequencies) {
+ dev_err(ov5693->dev, "supported link freq %ull not found\n",
+ OV5693_LINK_FREQ_419_2MHZ);
+ ret = -EINVAL;
+ goto out_free_bus_cfg;
+ }
+
+out_free_bus_cfg:
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+
+ return ret;
+}
+
+static int ov5693_probe(struct i2c_client *client)
+{
+ struct ov5693_device *ov5693;
+ u32 clk_rate;
+ int ret = 0;
+
+ ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL);
+ if (!ov5693)
+ return -ENOMEM;
+
+ ov5693->client = client;
+ ov5693->dev = &client->dev;
+
+ ret = ov5693_check_hwcfg(ov5693);
+ if (ret)
+ return ret;
+
+ mutex_init(&ov5693->lock);
+
+ v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
+
+ ov5693->clk = devm_clk_get(&client->dev, "xvclk");
+ if (IS_ERR(ov5693->clk)) {
+ dev_err(&client->dev, "Error getting clock\n");
+ return PTR_ERR(ov5693->clk);
+ }
+
+ clk_rate = clk_get_rate(ov5693->clk);
+ if (clk_rate != OV5693_XVCLK_FREQ)
+ dev_warn(&client->dev, "Found clk freq %u, expected %u\n",
+ clk_rate, OV5693_XVCLK_FREQ);
+
+ ret = ov5693_configure_gpios(ov5693);
+ if (ret)
+ return ret;
+
+ ret = ov5693_get_regulators(ov5693);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Error fetching regulators\n");
+
+ ov5693->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ ov5693->pad.flags = MEDIA_PAD_FL_SOURCE;
+ ov5693->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+ ov5693->mode.crop = ov5693_default_crop;
+ ov5693->mode.format = ov5693_default_fmt;
+ ov5693->mode.vts = __ov5693_calc_vts(ov5693->mode.format.height);
+
+ ret = ov5693_init_controls(ov5693);
+ if (ret)
+ return ret;
+
+ ret = media_entity_pads_init(&ov5693->sd.entity, 1, &ov5693->pad);
+ if (ret)
+ goto err_ctrl_handler_free;
+
+ /*
+ * We need the driver to work in the event that pm runtime is disable in
+ * the kernel, so power up and verify the chip now. In the event that
+ * runtime pm is disabled this will leave the chip on, so that streaming
+ * will work.
+ */
+
+ ret = ov5693_sensor_powerup(ov5693);
+ if (ret)
+ goto err_media_entity_cleanup;
+
+ ret = ov5693_detect(ov5693);
+ if (ret)
+ goto err_powerdown;
+
+ pm_runtime_set_active(&client->dev);
+ pm_runtime_get_noresume(&client->dev);
+ pm_runtime_enable(&client->dev);
+
+ ret = v4l2_async_register_subdev_sensor(&ov5693->sd);
+ if (ret) {
+ dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+ ret);
+ goto err_pm_runtime;
+ }
+
+ pm_runtime_set_autosuspend_delay(&client->dev, 1000);
+ pm_runtime_use_autosuspend(&client->dev);
+ pm_runtime_put_autosuspend(&client->dev);
+
+ return ret;
+
+err_pm_runtime:
+ pm_runtime_disable(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+err_powerdown:
+ ov5693_sensor_powerdown(ov5693);
+err_media_entity_cleanup:
+ media_entity_cleanup(&ov5693->sd.entity);
+err_ctrl_handler_free:
+ v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
+
+ return ret;
+}
+
+static int ov5693_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ media_entity_cleanup(&ov5693->sd.entity);
+ v4l2_ctrl_handler_free(&ov5693->ctrls.handler);
+ mutex_destroy(&ov5693->lock);
+
+ /*
+ * Disable runtime PM. In case runtime PM is disabled in the kernel,
+ * make sure to turn power off manually.
+ */
+ pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ ov5693_sensor_powerdown(ov5693);
+ pm_runtime_set_suspended(&client->dev);
+
+ return 0;
+}
+
+static const struct dev_pm_ops ov5693_pm_ops = {
+ SET_RUNTIME_PM_OPS(ov5693_sensor_suspend, ov5693_sensor_resume, NULL)
+};
+
+static const struct acpi_device_id ov5693_acpi_match[] = {
+ {"INT33BE"},
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, ov5693_acpi_match);
+
+static struct i2c_driver ov5693_driver = {
+ .driver = {
+ .name = "ov5693",
+ .acpi_match_table = ov5693_acpi_match,
+ .pm = &ov5693_pm_ops,
+ },
+ .probe_new = ov5693_probe,
+ .remove = ov5693_remove,
+};
+module_i2c_driver(ov5693_driver);
+
+MODULE_DESCRIPTION("A low-level driver for OmniVision 5693 sensors");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
index c6c6050cda1a..8785764b7a74 100644
--- a/drivers/media/i2c/ov8856.c
+++ b/drivers/media/i2c/ov8856.c
@@ -1445,6 +1445,9 @@ struct ov8856 {
const struct ov8856_lane_cfg *priv_lane;
u8 modes_size;
+
+ /* True if the device has been identified */
+ bool identified;
};
struct ov8856_lane_cfg {
@@ -1685,6 +1688,71 @@ static int ov8856_write_reg_list(struct ov8856 *ov8856,
return 0;
}
+static int ov8856_identify_module(struct ov8856 *ov8856)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
+ int ret;
+ u32 val;
+
+ if (ov8856->identified)
+ return 0;
+
+ ret = ov8856_read_reg(ov8856, OV8856_REG_CHIP_ID,
+ OV8856_REG_VALUE_24BIT, &val);
+ if (ret)
+ return ret;
+
+ if (val != OV8856_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x",
+ OV8856_CHIP_ID, val);
+ return -ENXIO;
+ }
+
+ ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
+ OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
+ if (ret)
+ return ret;
+
+ ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL,
+ OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO);
+ if (ret) {
+ dev_err(&client->dev, "failed to set otp mode");
+ return ret;
+ }
+
+ ret = ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL,
+ OV8856_REG_VALUE_08BIT,
+ OV8856_OTP_LOAD_CTRL_ENABLE);
+ if (ret) {
+ dev_err(&client->dev, "failed to enable load control");
+ return ret;
+ }
+
+ ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION,
+ OV8856_REG_VALUE_08BIT, &val);
+ if (ret) {
+ dev_err(&client->dev, "failed to read module revision");
+ return ret;
+ }
+
+ dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n",
+ val,
+ val == OV8856_2A_MODULE ? "2A" :
+ val == OV8856_1B_MODULE ? "1B" : "unknown revision",
+ client->addr);
+
+ ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
+ OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY);
+ if (ret) {
+ dev_err(&client->dev, "failed to exit streaming mode");
+ return ret;
+ }
+
+ ov8856->identified = true;
+
+ return 0;
+}
+
static int ov8856_update_digital_gain(struct ov8856 *ov8856, u32 d_gain)
{
int ret;
@@ -1969,6 +2037,10 @@ static int ov8856_start_streaming(struct ov8856 *ov8856)
const struct ov8856_reg_list *reg_list;
int link_freq_index, ret;
+ ret = ov8856_identify_module(ov8856);
+ if (ret)
+ return ret;
+
link_freq_index = ov8856->cur_mode->link_freq_index;
reg_list = &ov8856->priv_lane->link_freq_configs[link_freq_index].reg_list;
@@ -2276,65 +2348,6 @@ static const struct v4l2_subdev_internal_ops ov8856_internal_ops = {
.open = ov8856_open,
};
-static int ov8856_identify_module(struct ov8856 *ov8856)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
- int ret;
- u32 val;
-
- ret = ov8856_read_reg(ov8856, OV8856_REG_CHIP_ID,
- OV8856_REG_VALUE_24BIT, &val);
- if (ret)
- return ret;
-
- if (val != OV8856_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x",
- OV8856_CHIP_ID, val);
- return -ENXIO;
- }
-
- ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
- OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
- if (ret)
- return ret;
-
- ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL,
- OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO);
- if (ret) {
- dev_err(&client->dev, "failed to set otp mode");
- return ret;
- }
-
- ret = ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL,
- OV8856_REG_VALUE_08BIT,
- OV8856_OTP_LOAD_CTRL_ENABLE);
- if (ret) {
- dev_err(&client->dev, "failed to enable load control");
- return ret;
- }
-
- ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION,
- OV8856_REG_VALUE_08BIT, &val);
- if (ret) {
- dev_err(&client->dev, "failed to read module revision");
- return ret;
- }
-
- dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n",
- val,
- val == OV8856_2A_MODULE ? "2A" :
- val == OV8856_1B_MODULE ? "1B" : "unknown revision",
- client->addr);
-
- ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
- OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY);
- if (ret) {
- dev_err(&client->dev, "failed to exit streaming mode");
- return ret;
- }
-
- return 0;
-}
static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
{
@@ -2458,6 +2471,7 @@ static int ov8856_probe(struct i2c_client *client)
{
struct ov8856 *ov8856;
int ret;
+ bool full_power;
ov8856 = devm_kzalloc(&client->dev, sizeof(*ov8856), GFP_KERNEL);
if (!ov8856)
@@ -2472,16 +2486,19 @@ static int ov8856_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops);
- ret = __ov8856_power_on(ov8856);
- if (ret) {
- dev_err(&client->dev, "failed to power on\n");
- return ret;
- }
+ full_power = acpi_dev_state_d0(&client->dev);
+ if (full_power) {
+ ret = __ov8856_power_on(ov8856);
+ if (ret) {
+ dev_err(&client->dev, "failed to power on\n");
+ return ret;
+ }
- ret = ov8856_identify_module(ov8856);
- if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d", ret);
- goto probe_power_off;
+ ret = ov8856_identify_module(ov8856);
+ if (ret) {
+ dev_err(&client->dev, "failed to find sensor: %d", ret);
+ goto probe_power_off;
+ }
}
mutex_init(&ov8856->mutex);
@@ -2511,11 +2528,9 @@ static int ov8856_probe(struct i2c_client *client)
goto probe_error_media_entity_cleanup;
}
- /*
- * Device is already turned on by i2c-core with ACPI domain PM.
- * Enable runtime PM and turn off the device.
- */
- pm_runtime_set_active(&client->dev);
+ /* Set the device's state to active if it's in D0 state. */
+ if (full_power)
+ pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
@@ -2562,6 +2577,7 @@ static struct i2c_driver ov8856_i2c_driver = {
},
.probe_new = ov8856_probe,
.remove = ov8856_remove,
+ .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
};
module_i2c_driver(ov8856_i2c_driver);
diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index ce50f3ea87b8..d9d016cfa9ac 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/pm_runtime.h>
@@ -20,10 +21,6 @@
#include <media/v4l2-image-sizes.h>
#include <media/v4l2-mediabus.h>
-/* Clock rate */
-
-#define OV8865_EXTCLK_RATE 24000000
-
/* Register definitions */
/* System */
@@ -146,6 +143,7 @@
#define OV8865_EXPOSURE_CTRL_L_REG 0x3502
#define OV8865_EXPOSURE_CTRL_L(v) ((v) & GENMASK(7, 0))
#define OV8865_EXPOSURE_GAIN_MANUAL_REG 0x3503
+#define OV8865_INTEGRATION_TIME_MARGIN 8
#define OV8865_GAIN_CTRL_H_REG 0x3508
#define OV8865_GAIN_CTRL_H(v) (((v) & GENMASK(12, 8)) >> 8)
@@ -186,6 +184,8 @@
#define OV8865_VTS_H(v) (((v) & GENMASK(11, 8)) >> 8)
#define OV8865_VTS_L_REG 0x380f
#define OV8865_VTS_L(v) ((v) & GENMASK(7, 0))
+#define OV8865_TIMING_MAX_VTS 0xffff
+#define OV8865_TIMING_MIN_VTS 0x04
#define OV8865_OFFSET_X_H_REG 0x3810
#define OV8865_OFFSET_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
#define OV8865_OFFSET_X_L_REG 0x3811
@@ -453,6 +453,15 @@
#define OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES 2
#define OV8865_PRE_CTRL0_PATTERN_BLACK 3
+/* Pixel Array */
+
+#define OV8865_NATIVE_WIDTH 3296
+#define OV8865_NATIVE_HEIGHT 2528
+#define OV8865_ACTIVE_START_TOP 32
+#define OV8865_ACTIVE_START_LEFT 80
+#define OV8865_ACTIVE_WIDTH 3264
+#define OV8865_ACTIVE_HEIGHT 2448
+
/* Macros */
#define ov8865_subdev_sensor(s) \
@@ -566,6 +575,25 @@ struct ov8865_sclk_config {
unsigned int sclk_div;
};
+struct ov8865_pll_configs {
+ const struct ov8865_pll1_config *pll1_config;
+ const struct ov8865_pll2_config *pll2_config_native;
+ const struct ov8865_pll2_config *pll2_config_binning;
+};
+
+/* Clock rate */
+
+enum extclk_rate {
+ OV8865_19_2_MHZ,
+ OV8865_24_MHZ,
+ OV8865_NUM_SUPPORTED_RATES
+};
+
+static const unsigned long supported_extclk_rates[] = {
+ [OV8865_19_2_MHZ] = 19200000,
+ [OV8865_24_MHZ] = 24000000,
+};
+
/*
* General formulas for (array-centered) mode calculation:
* - photo_array_width = 3296
@@ -632,11 +660,7 @@ struct ov8865_mode {
unsigned int blc_anchor_right_start;
unsigned int blc_anchor_right_end;
- struct v4l2_fract frame_interval;
-
- const struct ov8865_pll1_config *pll1_config;
- const struct ov8865_pll2_config *pll2_config;
- const struct ov8865_sclk_config *sclk_config;
+ bool pll2_binning;
const struct ov8865_register_value *register_values;
unsigned int register_values_count;
@@ -652,6 +676,9 @@ struct ov8865_state {
struct ov8865_ctrls {
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *exposure;
struct v4l2_ctrl_handler handler;
};
@@ -664,6 +691,9 @@ struct ov8865_sensor {
struct regulator *avdd;
struct regulator *dvdd;
struct regulator *dovdd;
+
+ unsigned long extclk_rate;
+ const struct ov8865_pll_configs *pll_configs;
struct clk *extclk;
struct v4l2_fwnode_endpoint endpoint;
@@ -679,43 +709,70 @@ struct ov8865_sensor {
/* Static definitions */
/*
- * EXTCLK = 24 MHz
* PHY_SCLK = 720 MHz
* MIPI_PCLK = 90 MHz
*/
-static const struct ov8865_pll1_config ov8865_pll1_config_native = {
- .pll_pre_div_half = 1,
- .pll_pre_div = 0,
- .pll_mul = 30,
- .m_div = 1,
- .mipi_div = 3,
- .pclk_div = 1,
- .sys_pre_div = 1,
- .sys_div = 2,
+
+static const struct ov8865_pll1_config ov8865_pll1_config_native_19_2mhz = {
+ .pll_pre_div_half = 1,
+ .pll_pre_div = 2,
+ .pll_mul = 75,
+ .m_div = 1,
+ .mipi_div = 3,
+ .pclk_div = 1,
+ .sys_pre_div = 1,
+ .sys_div = 2,
+};
+
+static const struct ov8865_pll1_config ov8865_pll1_config_native_24mhz = {
+ .pll_pre_div_half = 1,
+ .pll_pre_div = 0,
+ .pll_mul = 30,
+ .m_div = 1,
+ .mipi_div = 3,
+ .pclk_div = 1,
+ .sys_pre_div = 1,
+ .sys_div = 2,
};
/*
- * EXTCLK = 24 MHz
* DAC_CLK = 360 MHz
* SCLK = 144 MHz
*/
-static const struct ov8865_pll2_config ov8865_pll2_config_native = {
- .pll_pre_div_half = 1,
- .pll_pre_div = 0,
- .pll_mul = 30,
- .dac_div = 2,
- .sys_pre_div = 5,
- .sys_div = 0,
+static const struct ov8865_pll2_config ov8865_pll2_config_native_19_2mhz = {
+ .pll_pre_div_half = 1,
+ .pll_pre_div = 5,
+ .pll_mul = 75,
+ .dac_div = 1,
+ .sys_pre_div = 1,
+ .sys_div = 3,
+};
+
+static const struct ov8865_pll2_config ov8865_pll2_config_native_24mhz = {
+ .pll_pre_div_half = 1,
+ .pll_pre_div = 0,
+ .pll_mul = 30,
+ .dac_div = 2,
+ .sys_pre_div = 5,
+ .sys_div = 0,
};
/*
- * EXTCLK = 24 MHz
* DAC_CLK = 360 MHz
- * SCLK = 80 MHz
+ * SCLK = 72 MHz
*/
-static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
+static const struct ov8865_pll2_config ov8865_pll2_config_binning_19_2mhz = {
+ .pll_pre_div_half = 1,
+ .pll_pre_div = 2,
+ .pll_mul = 75,
+ .dac_div = 2,
+ .sys_pre_div = 10,
+ .sys_div = 0,
+};
+
+static const struct ov8865_pll2_config ov8865_pll2_config_binning_24mhz = {
.pll_pre_div_half = 1,
.pll_pre_div = 0,
.pll_mul = 30,
@@ -724,6 +781,23 @@ static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
.sys_div = 0,
};
+static const struct ov8865_pll_configs ov8865_pll_configs_19_2mhz = {
+ .pll1_config = &ov8865_pll1_config_native_19_2mhz,
+ .pll2_config_native = &ov8865_pll2_config_native_19_2mhz,
+ .pll2_config_binning = &ov8865_pll2_config_binning_19_2mhz,
+};
+
+static const struct ov8865_pll_configs ov8865_pll_configs_24mhz = {
+ .pll1_config = &ov8865_pll1_config_native_24mhz,
+ .pll2_config_native = &ov8865_pll2_config_native_24mhz,
+ .pll2_config_binning = &ov8865_pll2_config_binning_24mhz,
+};
+
+static const struct ov8865_pll_configs *ov8865_pll_configs[] = {
+ &ov8865_pll_configs_19_2mhz,
+ &ov8865_pll_configs_24mhz,
+};
+
static const struct ov8865_sclk_config ov8865_sclk_config_native = {
.sys_sel = 1,
.sclk_sel = 0,
@@ -890,7 +964,7 @@ static const struct ov8865_mode ov8865_modes[] = {
{
/* Horizontal */
.output_size_x = 3264,
- .hts = 1944,
+ .hts = 3888,
/* Vertical */
.output_size_y = 2448,
@@ -929,13 +1003,8 @@ static const struct ov8865_mode ov8865_modes[] = {
.blc_anchor_right_start = 1984,
.blc_anchor_right_end = 2239,
- /* Frame Interval */
- .frame_interval = { 1, 30 },
-
/* PLL */
- .pll1_config = &ov8865_pll1_config_native,
- .pll2_config = &ov8865_pll2_config_native,
- .sclk_config = &ov8865_sclk_config_native,
+ .pll2_binning = false,
/* Registers */
.register_values = ov8865_register_values_native,
@@ -946,11 +1015,11 @@ static const struct ov8865_mode ov8865_modes[] = {
{
/* Horizontal */
.output_size_x = 3264,
- .hts = 2582,
+ .hts = 3888,
/* Vertical */
.output_size_y = 1836,
- .vts = 2002,
+ .vts = 2470,
.size_auto = true,
.size_auto_boundary_x = 8,
@@ -985,13 +1054,8 @@ static const struct ov8865_mode ov8865_modes[] = {
.blc_anchor_right_start = 1984,
.blc_anchor_right_end = 2239,
- /* Frame Interval */
- .frame_interval = { 1, 30 },
-
/* PLL */
- .pll1_config = &ov8865_pll1_config_native,
- .pll2_config = &ov8865_pll2_config_native,
- .sclk_config = &ov8865_sclk_config_native,
+ .pll2_binning = false,
/* Registers */
.register_values = ov8865_register_values_native,
@@ -1045,13 +1109,8 @@ static const struct ov8865_mode ov8865_modes[] = {
.blc_anchor_right_start = 992,
.blc_anchor_right_end = 1119,
- /* Frame Interval */
- .frame_interval = { 1, 30 },
-
/* PLL */
- .pll1_config = &ov8865_pll1_config_native,
- .pll2_config = &ov8865_pll2_config_binning,
- .sclk_config = &ov8865_sclk_config_native,
+ .pll2_binning = true,
/* Registers */
.register_values = ov8865_register_values_binning,
@@ -1111,13 +1170,8 @@ static const struct ov8865_mode ov8865_modes[] = {
.blc_anchor_right_start = 992,
.blc_anchor_right_end = 1119,
- /* Frame Interval */
- .frame_interval = { 1, 90 },
-
/* PLL */
- .pll1_config = &ov8865_pll1_config_native,
- .pll2_config = &ov8865_pll2_config_binning,
- .sclk_config = &ov8865_sclk_config_native,
+ .pll2_binning = true,
/* Registers */
.register_values = ov8865_register_values_binning,
@@ -1512,12 +1566,11 @@ static int ov8865_isp_configure(struct ov8865_sensor *sensor)
static unsigned long ov8865_mode_pll1_rate(struct ov8865_sensor *sensor,
const struct ov8865_mode *mode)
{
- const struct ov8865_pll1_config *config = mode->pll1_config;
- unsigned long extclk_rate;
+ const struct ov8865_pll1_config *config;
unsigned long pll1_rate;
- extclk_rate = clk_get_rate(sensor->extclk);
- pll1_rate = extclk_rate * config->pll_mul / config->pll_pre_div_half;
+ config = sensor->pll_configs->pll1_config;
+ pll1_rate = sensor->extclk_rate * config->pll_mul / config->pll_pre_div_half;
switch (config->pll_pre_div) {
case 0:
@@ -1551,10 +1604,12 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
const struct ov8865_mode *mode,
u32 mbus_code)
{
- const struct ov8865_pll1_config *config = mode->pll1_config;
+ const struct ov8865_pll1_config *config;
u8 value;
int ret;
+ config = sensor->pll_configs->pll1_config;
+
switch (mbus_code) {
case MEDIA_BUS_FMT_SBGGR10_1X10:
value = OV8865_MIPI_BIT_SEL(10);
@@ -1621,9 +1676,12 @@ static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,
const struct ov8865_mode *mode)
{
- const struct ov8865_pll2_config *config = mode->pll2_config;
+ const struct ov8865_pll2_config *config;
int ret;
+ config = mode->pll2_binning ? sensor->pll_configs->pll2_config_binning :
+ sensor->pll_configs->pll2_config_native;
+
ret = ov8865_write(sensor, OV8865_PLL_CTRL12_REG,
OV8865_PLL_CTRL12_PRE_DIV_HALF(config->pll_pre_div_half) |
OV8865_PLL_CTRL12_DAC_DIV(config->dac_div));
@@ -1657,7 +1715,7 @@ static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,
static int ov8865_mode_sclk_configure(struct ov8865_sensor *sensor,
const struct ov8865_mode *mode)
{
- const struct ov8865_sclk_config *config = mode->sclk_config;
+ const struct ov8865_sclk_config *config = &ov8865_sclk_config_native;
int ret;
ret = ov8865_write(sensor, OV8865_CLK_SEL0_REG,
@@ -2052,9 +2110,11 @@ static int ov8865_mode_configure(struct ov8865_sensor *sensor,
static unsigned long ov8865_mode_mipi_clk_rate(struct ov8865_sensor *sensor,
const struct ov8865_mode *mode)
{
- const struct ov8865_pll1_config *config = mode->pll1_config;
+ const struct ov8865_pll1_config *config;
unsigned long pll1_rate;
+ config = sensor->pll_configs->pll1_config;
+
pll1_rate = ov8865_mode_pll1_rate(sensor, mode);
return pll1_rate / config->m_div / 2;
@@ -2066,6 +2126,9 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
{
int ret;
+ /* The sensor stores exposure in units of 1/16th of a line */
+ exposure *= 16;
+
ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_HH_REG,
OV8865_EXPOSURE_CTRL_HH(exposure));
if (ret)
@@ -2082,7 +2145,7 @@ static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
/* Gain */
-static int ov8865_gain_configure(struct ov8865_sensor *sensor, u32 gain)
+static int ov8865_analog_gain_configure(struct ov8865_sensor *sensor, u32 gain)
{
int ret;
@@ -2157,6 +2220,20 @@ static int ov8865_test_pattern_configure(struct ov8865_sensor *sensor,
ov8865_test_pattern_bits[index]);
}
+/* Blanking */
+
+static int ov8865_vts_configure(struct ov8865_sensor *sensor, u32 vblank)
+{
+ u16 vts = sensor->state.mode->output_size_y + vblank;
+ int ret;
+
+ ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(vts));
+ if (ret)
+ return ret;
+
+ return ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(vts));
+}
+
/* State */
static int ov8865_state_mipi_configure(struct ov8865_sensor *sensor,
@@ -2330,27 +2407,27 @@ static int ov8865_sensor_power(struct ov8865_sensor *sensor, bool on)
if (ret) {
dev_err(sensor->dev,
"failed to enable DOVDD regulator\n");
- goto disable;
+ return ret;
}
ret = regulator_enable(sensor->avdd);
if (ret) {
dev_err(sensor->dev,
"failed to enable AVDD regulator\n");
- goto disable;
+ goto disable_dovdd;
}
ret = regulator_enable(sensor->dvdd);
if (ret) {
dev_err(sensor->dev,
"failed to enable DVDD regulator\n");
- goto disable;
+ goto disable_avdd;
}
ret = clk_prepare_enable(sensor->extclk);
if (ret) {
dev_err(sensor->dev, "failed to enable EXTCLK clock\n");
- goto disable;
+ goto disable_dvdd;
}
gpiod_set_value_cansleep(sensor->reset, 0);
@@ -2359,14 +2436,16 @@ static int ov8865_sensor_power(struct ov8865_sensor *sensor, bool on)
/* Time to enter streaming mode according to power timings. */
usleep_range(10000, 12000);
} else {
-disable:
gpiod_set_value_cansleep(sensor->powerdown, 1);
gpiod_set_value_cansleep(sensor->reset, 1);
clk_disable_unprepare(sensor->extclk);
+disable_dvdd:
regulator_disable(sensor->dvdd);
+disable_avdd:
regulator_disable(sensor->avdd);
+disable_dovdd:
regulator_disable(sensor->dovdd);
}
@@ -2382,6 +2461,20 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
unsigned int index;
int ret;
+ /* If VBLANK is altered we need to update exposure to compensate */
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ int exposure_max;
+
+ exposure_max = sensor->state.mode->output_size_y + ctrl->val -
+ OV8865_INTEGRATION_TIME_MARGIN;
+ __v4l2_ctrl_modify_range(sensor->ctrls.exposure,
+ sensor->ctrls.exposure->minimum,
+ exposure_max,
+ sensor->ctrls.exposure->step,
+ min(sensor->ctrls.exposure->val,
+ exposure_max));
+ }
+
/* Wait for the sensor to be on before setting controls. */
if (pm_runtime_suspended(sensor->dev))
return 0;
@@ -2392,8 +2485,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
if (ret)
return ret;
break;
- case V4L2_CID_GAIN:
- ret = ov8865_gain_configure(sensor, ctrl->val);
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = ov8865_analog_gain_configure(sensor, ctrl->val);
if (ret)
return ret;
break;
@@ -2408,6 +2501,8 @@ static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_TEST_PATTERN:
index = (unsigned int)ctrl->val;
return ov8865_test_pattern_configure(sensor, index);
+ case V4L2_CID_VBLANK:
+ return ov8865_vts_configure(sensor, ctrl->val);
default:
return -EINVAL;
}
@@ -2424,6 +2519,10 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
struct ov8865_ctrls *ctrls = &sensor->ctrls;
struct v4l2_ctrl_handler *handler = &ctrls->handler;
const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
+ const struct ov8865_mode *mode = &ov8865_modes[0];
+ struct v4l2_fwnode_device_properties props;
+ unsigned int vblank_max, vblank_def;
+ unsigned int hblank;
int ret;
v4l2_ctrl_handler_init(handler, 32);
@@ -2433,12 +2532,13 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
/* Exposure */
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
- 512);
+ ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 2,
+ 65535, 1, 32);
/* Gain */
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 128, 8191, 128, 128);
+ v4l2_ctrl_new_std(handler, ops, V4L2_CID_ANALOGUE_GAIN, 128, 2048, 128,
+ 128);
/* White Balance */
@@ -2459,6 +2559,20 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
ARRAY_SIZE(ov8865_test_pattern_menu) - 1,
0, 0, ov8865_test_pattern_menu);
+ /* Blanking */
+ hblank = mode->hts - mode->output_size_x;
+ ctrls->hblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HBLANK, hblank,
+ hblank, 1, hblank);
+
+ if (ctrls->hblank)
+ ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;
+ vblank_def = mode->vts - mode->output_size_y;
+ ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,
+ OV8865_TIMING_MIN_VTS, vblank_max, 1,
+ vblank_def);
+
/* MIPI CSI-2 */
ctrls->link_freq =
@@ -2470,6 +2584,15 @@ static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 1,
INT_MAX, 1, 1);
+ /* set properties from fwnode (e.g. rotation, orientation) */
+ ret = v4l2_fwnode_device_parse(sensor->dev, &props);
+ if (ret)
+ goto error_ctrls;
+
+ ret = v4l2_ctrl_new_fwnode_properties(handler, ops, &props);
+ if (ret)
+ goto error_ctrls;
+
if (handler->error) {
ret = handler->error;
goto error_ctrls;
@@ -2522,11 +2645,18 @@ static int ov8865_g_frame_interval(struct v4l2_subdev *subdev,
{
struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
const struct ov8865_mode *mode;
+ unsigned int framesize;
+ unsigned int fps;
mutex_lock(&sensor->mutex);
mode = sensor->state.mode;
- interval->interval = mode->frame_interval;
+ framesize = mode->hts * (mode->output_size_y +
+ sensor->ctrls.vblank->val);
+ fps = DIV_ROUND_CLOSEST(sensor->ctrls.pixel_rate->val, framesize);
+
+ interval->interval.numerator = 1;
+ interval->interval.denominator = fps;
mutex_unlock(&sensor->mutex);
@@ -2599,7 +2729,9 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_mbus_framefmt *mbus_format = &format->format;
const struct ov8865_mode *mode;
u32 mbus_code = 0;
+ unsigned int hblank;
unsigned int index;
+ int exposure_max;
int ret = 0;
mutex_lock(&sensor->mutex);
@@ -2639,6 +2771,21 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev,
sensor->state.mbus_code != mbus_code)
ret = ov8865_state_configure(sensor, mode, mbus_code);
+ __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV8865_TIMING_MIN_VTS,
+ OV8865_TIMING_MAX_VTS - mode->output_size_y,
+ 1, mode->vts - mode->output_size_y);
+
+ hblank = mode->hts - mode->output_size_x;
+ __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,
+ hblank);
+
+ exposure_max = mode->vts - OV8865_INTEGRATION_TIME_MARGIN;
+ __v4l2_ctrl_modify_range(sensor->ctrls.exposure,
+ sensor->ctrls.exposure->minimum, exposure_max,
+ sensor->ctrls.exposure->step,
+ min(sensor->ctrls.exposure->val,
+ exposure_max));
+
complete:
mutex_unlock(&sensor->mutex);
@@ -2662,37 +2809,55 @@ static int ov8865_enum_frame_size(struct v4l2_subdev *subdev,
return 0;
}
-static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_frame_interval_enum *interval_enum)
+static void
+__ov8865_get_pad_crop(struct ov8865_sensor *sensor,
+ struct v4l2_subdev_state *state, unsigned int pad,
+ enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
{
- const struct ov8865_mode *mode = NULL;
- unsigned int mode_index;
- unsigned int interval_index;
-
- if (interval_enum->index > 0)
- return -EINVAL;
- /*
- * Multiple modes with the same dimensions may have different frame
- * intervals, so look up each relevant mode.
- */
- for (mode_index = 0, interval_index = 0;
- mode_index < ARRAY_SIZE(ov8865_modes); mode_index++) {
- mode = &ov8865_modes[mode_index];
-
- if (mode->output_size_x == interval_enum->width &&
- mode->output_size_y == interval_enum->height) {
- if (interval_index == interval_enum->index)
- break;
+ const struct ov8865_mode *mode = sensor->state.mode;
- interval_index++;
- }
+ switch (which) {
+ case V4L2_SUBDEV_FORMAT_TRY:
+ *r = *v4l2_subdev_get_try_crop(&sensor->subdev, state, pad);
+ break;
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
+ r->height = mode->output_size_y;
+ r->width = mode->output_size_x;
+ r->top = (OV8865_NATIVE_HEIGHT - mode->output_size_y) / 2;
+ r->left = (OV8865_NATIVE_WIDTH - mode->output_size_x) / 2;
+ break;
}
+}
- if (mode_index == ARRAY_SIZE(ov8865_modes))
- return -EINVAL;
+static int ov8865_get_selection(struct v4l2_subdev *subdev,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_selection *sel)
+{
+ struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
- interval_enum->interval = mode->frame_interval;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ mutex_lock(&sensor->mutex);
+ __ov8865_get_pad_crop(sensor, state, sel->pad,
+ sel->which, &sel->r);
+ mutex_unlock(&sensor->mutex);
+ break;
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.top = 0;
+ sel->r.left = 0;
+ sel->r.width = OV8865_NATIVE_WIDTH;
+ sel->r.height = OV8865_NATIVE_HEIGHT;
+ break;
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.top = OV8865_ACTIVE_START_TOP;
+ sel->r.left = OV8865_ACTIVE_START_LEFT;
+ sel->r.width = OV8865_ACTIVE_WIDTH;
+ sel->r.height = OV8865_ACTIVE_HEIGHT;
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
@@ -2702,7 +2867,8 @@ static const struct v4l2_subdev_pad_ops ov8865_subdev_pad_ops = {
.get_fmt = ov8865_get_fmt,
.set_fmt = ov8865_set_fmt,
.enum_frame_size = ov8865_enum_frame_size,
- .enum_frame_interval = ov8865_enum_frame_interval,
+ .get_selection = ov8865_get_selection,
+ .set_selection = ov8865_get_selection,
};
static const struct v4l2_subdev_ops ov8865_subdev_ops = {
@@ -2782,7 +2948,8 @@ static int ov8865_probe(struct i2c_client *client)
struct ov8865_sensor *sensor;
struct v4l2_subdev *subdev;
struct media_pad *pad;
- unsigned long rate;
+ unsigned int rate = 0;
+ unsigned int i;
int ret;
sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
@@ -2792,13 +2959,31 @@ static int ov8865_probe(struct i2c_client *client)
sensor->dev = dev;
sensor->i2c_client = client;
+ /* Regulators */
+
+ /* DVDD: digital core */
+ sensor->dvdd = devm_regulator_get(dev, "dvdd");
+ if (IS_ERR(sensor->dvdd))
+ return dev_err_probe(dev, PTR_ERR(sensor->dvdd),
+ "cannot get DVDD regulator\n");
+
+ /* DOVDD: digital I/O */
+ sensor->dovdd = devm_regulator_get(dev, "dovdd");
+ if (IS_ERR(sensor->dovdd))
+ return dev_err_probe(dev, PTR_ERR(sensor->dovdd),
+ "cannot get DOVDD regulator\n");
+
+ /* AVDD: analog */
+ sensor->avdd = devm_regulator_get(dev, "avdd");
+ if (IS_ERR(sensor->avdd))
+ return dev_err_probe(dev, PTR_ERR(sensor->avdd),
+ "cannot get AVDD (analog) regulator\n");
+
/* Graph Endpoint */
handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
- if (!handle) {
- dev_err(dev, "unable to find endpoint node\n");
- return -EINVAL;
- }
+ if (!handle)
+ return -EPROBE_DEFER;
sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
@@ -2824,48 +3009,54 @@ static int ov8865_probe(struct i2c_client *client)
goto error_endpoint;
}
- /* Regulators */
-
- /* DVDD: digital core */
- sensor->dvdd = devm_regulator_get(dev, "dvdd");
- if (IS_ERR(sensor->dvdd)) {
- dev_err(dev, "cannot get DVDD (digital core) regulator\n");
- ret = PTR_ERR(sensor->dvdd);
- goto error_endpoint;
- }
+ /* External Clock */
- /* DOVDD: digital I/O */
- sensor->dovdd = devm_regulator_get(dev, "dovdd");
- if (IS_ERR(sensor->dovdd)) {
- dev_err(dev, "cannot get DOVDD (digital I/O) regulator\n");
- ret = PTR_ERR(sensor->dovdd);
+ sensor->extclk = devm_clk_get(dev, NULL);
+ if (PTR_ERR(sensor->extclk) == -ENOENT) {
+ dev_info(dev, "no external clock found, continuing...\n");
+ sensor->extclk = NULL;
+ } else if (IS_ERR(sensor->extclk)) {
+ dev_err(dev, "failed to get external clock\n");
+ ret = PTR_ERR(sensor->extclk);
goto error_endpoint;
}
- /* AVDD: analog */
- sensor->avdd = devm_regulator_get(dev, "avdd");
- if (IS_ERR(sensor->avdd)) {
- dev_err(dev, "cannot get AVDD (analog) regulator\n");
- ret = PTR_ERR(sensor->avdd);
- goto error_endpoint;
+ /*
+ * We could have either a 24MHz or 19.2MHz clock rate from either dt or
+ * ACPI...but we also need to support the weird IPU3 case which will
+ * have an external clock AND a clock-frequency property. Check for the
+ * clock-frequency property and if found, set that rate if we managed
+ * to acquire a clock. This should cover the ACPI case. If the system
+ * uses devicetree then the configured rate should already be set, so
+ * we can just read it.
+ */
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
+ &rate);
+ if (!ret && sensor->extclk) {
+ ret = clk_set_rate(sensor->extclk, rate);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to set clock rate\n");
+ } else if (ret && !sensor->extclk) {
+ return dev_err_probe(dev, ret, "invalid clock config\n");
}
- /* External Clock */
+ sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
- sensor->extclk = devm_clk_get(dev, NULL);
- if (IS_ERR(sensor->extclk)) {
- dev_err(dev, "failed to get external clock\n");
- ret = PTR_ERR(sensor->extclk);
- goto error_endpoint;
+ for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
+ if (sensor->extclk_rate == supported_extclk_rates[i])
+ break;
}
- rate = clk_get_rate(sensor->extclk);
- if (rate != OV8865_EXTCLK_RATE) {
- dev_err(dev, "clock rate %lu Hz is unsupported\n", rate);
+ if (i == ARRAY_SIZE(supported_extclk_rates)) {
+ dev_err(dev, "clock rate %lu Hz is unsupported\n",
+ sensor->extclk_rate);
ret = -EINVAL;
goto error_endpoint;
}
+ sensor->pll_configs = ov8865_pll_configs[i];
+
/* Subdev, entity and pad */
subdev = &sensor->subdev;
@@ -2891,14 +3082,16 @@ static int ov8865_probe(struct i2c_client *client)
if (ret)
goto error_mutex;
+ mutex_lock(&sensor->mutex);
ret = ov8865_state_init(sensor);
+ mutex_unlock(&sensor->mutex);
if (ret)
goto error_ctrls;
/* Runtime PM */
- pm_runtime_enable(sensor->dev);
pm_runtime_set_suspended(sensor->dev);
+ pm_runtime_enable(sensor->dev);
/* V4L2 subdev register */
@@ -2946,6 +3139,12 @@ static const struct dev_pm_ops ov8865_pm_ops = {
SET_RUNTIME_PM_OPS(ov8865_suspend, ov8865_resume, NULL)
};
+static const struct acpi_device_id ov8865_acpi_match[] = {
+ {"INT347A"},
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, ov8865_acpi_match);
+
static const struct of_device_id ov8865_of_match[] = {
{ .compatible = "ovti,ov8865" },
{ }
@@ -2956,6 +3155,7 @@ static struct i2c_driver ov8865_driver = {
.driver = {
.name = "ov8865",
.of_match_table = ov8865_of_match,
+ .acpi_match_table = ov8865_acpi_match,
.pm = &ov8865_pm_ops,
},
.probe_new = ov8865_probe,
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
index c102c6bbc118..7fe61187a2f8 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
@@ -130,16 +130,10 @@ static int s5c73m3_spi_probe(struct spi_device *spi)
return 0;
}
-static int s5c73m3_spi_remove(struct spi_device *spi)
-{
- return 0;
-}
-
int s5c73m3_register_spi_driver(struct s5c73m3 *state)
{
struct spi_driver *spidrv = &state->spidrv;
- spidrv->remove = s5c73m3_spi_remove;
spidrv->probe = s5c73m3_spi_probe;
spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
spidrv->driver.of_match_table = s5c73m3_spi_ids;
diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c
index f40f41977142..b411f9796191 100644
--- a/drivers/media/mc/mc-entity.c
+++ b/drivers/media/mc/mc-entity.c
@@ -14,22 +14,6 @@
#include <media/media-entity.h>
#include <media/media-device.h>
-static inline const char *gobj_type(enum media_gobj_type type)
-{
- switch (type) {
- case MEDIA_GRAPH_ENTITY:
- return "entity";
- case MEDIA_GRAPH_PAD:
- return "pad";
- case MEDIA_GRAPH_LINK:
- return "link";
- case MEDIA_GRAPH_INTF_DEVNODE:
- return "intf-devnode";
- default:
- return "unknown";
- }
-}
-
static inline const char *intf_type(struct media_interface *intf)
{
switch (intf->type) {
@@ -64,12 +48,10 @@ __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum,
int idx_max)
{
idx_max = ALIGN(idx_max, BITS_PER_LONG);
- ent_enum->bmap = kcalloc(idx_max / BITS_PER_LONG, sizeof(long),
- GFP_KERNEL);
+ ent_enum->bmap = bitmap_zalloc(idx_max, GFP_KERNEL);
if (!ent_enum->bmap)
return -ENOMEM;
- bitmap_zero(ent_enum->bmap, idx_max);
ent_enum->idx_max = idx_max;
return 0;
@@ -78,7 +60,7 @@ EXPORT_SYMBOL_GPL(__media_entity_enum_init);
void media_entity_enum_cleanup(struct media_entity_enum *ent_enum)
{
- kfree(ent_enum->bmap);
+ bitmap_free(ent_enum->bmap);
}
EXPORT_SYMBOL_GPL(media_entity_enum_cleanup);
diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c
index 6a4c7cb0ad0f..486c8ec0fa60 100644
--- a/drivers/media/pci/b2c2/flexcop-pci.c
+++ b/drivers/media/pci/b2c2/flexcop-pci.c
@@ -185,6 +185,8 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
dma_addr_t cur_addr =
fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
+ if (cur_pos > fc_pci->dma[0].size * 2)
+ goto error;
deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
jiffies_to_usecs(jiffies - fc_pci->last_irq),
@@ -225,6 +227,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
ret = IRQ_NONE;
}
+error:
spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
return ret;
}
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 0e9df8b35ac6..8cc9bec43688 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -170,14 +170,14 @@ MODULE_VERSION(BTTV_VERSION);
/* ----------------------------------------------------------------------- */
/* sysfs */
-static ssize_t show_card(struct device *cd,
+static ssize_t card_show(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vfd = to_video_device(cd);
struct bttv *btv = video_get_drvdata(vfd);
return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
}
-static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
+static DEVICE_ATTR_RO(card);
/* ----------------------------------------------------------------------- */
/* dvb auto-load setup */
diff --git a/drivers/media/pci/cobalt/cobalt-cpld.c b/drivers/media/pci/cobalt/cobalt-cpld.c
index 3d8026483ac3..fad882459d23 100644
--- a/drivers/media/pci/cobalt/cobalt-cpld.c
+++ b/drivers/media/pci/cobalt/cobalt-cpld.c
@@ -236,7 +236,6 @@ bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out)
u8 n1, hsdiv;
u8 regs[6];
int found = 0;
- u16 clock_ctrl;
int retries = 3;
for (i = 0; i < ARRAY_SIZE(multipliers); i++) {
@@ -260,9 +259,7 @@ bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out)
hsdiv = multipliers[i_best].hsdiv - 4;
rfreq = div_u64(dco << 28, f_xtal);
- clock_ctrl = cpld_read(cobalt, SI570_CLOCK_CTRL);
- clock_ctrl |= S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL;
- clock_ctrl |= S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN;
+ cpld_read(cobalt, SI570_CLOCK_CTRL);
regs[0] = (hsdiv << 5) | (n1 >> 2);
regs[1] = ((n1 & 0x3) << 6) | (rfreq >> 32);
diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c
index 9a82e68303b6..9dc361886284 100644
--- a/drivers/media/pci/cx18/cx18-alsa-main.c
+++ b/drivers/media/pci/cx18/cx18-alsa-main.c
@@ -51,12 +51,6 @@ struct snd_cx18_card *to_snd_cx18_card(struct v4l2_device *v4l2_dev)
return to_cx18(v4l2_dev)->alsa;
}
-static inline
-struct snd_cx18_card *p_to_snd_cx18_card(struct v4l2_device **v4l2_dev)
-{
- return container_of(v4l2_dev, struct snd_cx18_card, v4l2_dev);
-}
-
static void snd_cx18_card_free(struct snd_cx18_card *cxsc)
{
if (cxsc == NULL)
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c
index 40c10ca94def..3078a39f0b95 100644
--- a/drivers/media/pci/cx25821/cx25821-core.c
+++ b/drivers/media/pci/cx25821/cx25821-core.c
@@ -337,13 +337,6 @@ static int cx25821_risc_decode(u32 risc)
return incr[risc >> 28] ? incr[risc >> 28] : 1;
}
-static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
-{
- struct cx25821_i2c *bus = i2c_adap->algo_data;
- struct cx25821_dev *dev = bus->dev;
- return cx_read(bus->reg_stat) & 0x01;
-}
-
static void cx25821_registers_init(struct cx25821_dev *dev)
{
u32 tmp;
diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
index 67c467d3c81f..7ccb7b6eaa82 100644
--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
+++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
@@ -3,6 +3,7 @@
#include <linux/acpi.h>
#include <linux/device.h>
+#include <linux/i2c.h>
#include <linux/pci.h>
#include <linux/property.h>
#include <media/v4l2-fwnode.h>
@@ -21,7 +22,9 @@
*/
static const struct cio2_sensor_config cio2_supported_sensors[] = {
/* Omnivision OV5693 */
- CIO2_SENSOR_CONFIG("INT33BE", 0),
+ CIO2_SENSOR_CONFIG("INT33BE", 1, 419200000),
+ /* Omnivision OV8865 */
+ CIO2_SENSOR_CONFIG("INT347A", 1, 360000000),
/* Omnivision OV2680 */
CIO2_SENSOR_CONFIG("OVTI2680", 0),
};
@@ -36,6 +39,18 @@ static const struct cio2_property_names prop_names = {
.link_frequencies = "link-frequencies",
};
+static const char * const cio2_vcm_types[] = {
+ "ad5823",
+ "dw9714",
+ "ad5816",
+ "dw9719",
+ "dw9718",
+ "dw9806b",
+ "wv517s",
+ "lc898122xa",
+ "lc898212axb",
+};
+
static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
void *data, u32 size)
{
@@ -132,6 +147,12 @@ static void cio2_bridge_create_fwnode_properties(
sensor->dev_properties[2] = PROPERTY_ENTRY_U32(
sensor->prop_names.orientation,
orientation);
+ if (sensor->ssdb.vcmtype) {
+ sensor->vcm_ref[0] =
+ SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_VCM]);
+ sensor->dev_properties[3] =
+ PROPERTY_ENTRY_REF_ARRAY("lens-focus", sensor->vcm_ref);
+ }
sensor->ep_properties[0] = PROPERTY_ENTRY_U32(
sensor->prop_names.bus_type,
@@ -193,6 +214,33 @@ static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
sensor->node_names.endpoint,
&nodes[SWNODE_CIO2_PORT],
sensor->cio2_properties);
+ if (sensor->ssdb.vcmtype)
+ nodes[SWNODE_VCM] =
+ NODE_VCM(cio2_vcm_types[sensor->ssdb.vcmtype - 1]);
+}
+
+static void cio2_bridge_instantiate_vcm_i2c_client(struct cio2_sensor *sensor)
+{
+ struct i2c_board_info board_info = { };
+ char name[16];
+
+ if (!sensor->ssdb.vcmtype)
+ return;
+
+ snprintf(name, sizeof(name), "%s-VCM", acpi_dev_name(sensor->adev));
+ board_info.dev_name = name;
+ strscpy(board_info.type, cio2_vcm_types[sensor->ssdb.vcmtype - 1],
+ ARRAY_SIZE(board_info.type));
+ board_info.swnode = &sensor->swnodes[SWNODE_VCM];
+
+ sensor->vcm_i2c_client =
+ i2c_acpi_new_device_by_fwnode(acpi_fwnode_handle(sensor->adev),
+ 1, &board_info);
+ if (IS_ERR(sensor->vcm_i2c_client)) {
+ dev_warn(&sensor->adev->dev, "Error instantiation VCM i2c-client: %ld\n",
+ PTR_ERR(sensor->vcm_i2c_client));
+ sensor->vcm_i2c_client = NULL;
+ }
}
static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
@@ -205,6 +253,7 @@ static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
software_node_unregister_nodes(sensor->swnodes);
ACPI_FREE(sensor->pld);
acpi_dev_put(sensor->adev);
+ i2c_unregister_device(sensor->vcm_i2c_client);
}
}
@@ -237,9 +286,17 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
if (ret)
goto err_put_adev;
+ if (sensor->ssdb.vcmtype > ARRAY_SIZE(cio2_vcm_types)) {
+ dev_warn(&adev->dev, "Unknown VCM type %d\n",
+ sensor->ssdb.vcmtype);
+ sensor->ssdb.vcmtype = 0;
+ }
+
status = acpi_get_physical_device_location(adev->handle, &sensor->pld);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
+ ret = -ENODEV;
goto err_put_adev;
+ }
if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
dev_err(&adev->dev,
@@ -265,6 +322,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
sensor->adev = acpi_dev_get(adev);
adev->fwnode.secondary = fwnode;
+ cio2_bridge_instantiate_vcm_i2c_client(sensor);
+
dev_info(&cio2->dev, "Found supported sensor %s\n",
acpi_dev_name(adev));
@@ -304,6 +363,40 @@ err_unregister_sensors:
return ret;
}
+/*
+ * The VCM cannot be probed until the PMIC is completely setup. We cannot rely
+ * on -EPROBE_DEFER for this, since the consumer<->supplier relations between
+ * the VCM and regulators/clks are not described in ACPI, instead they are
+ * passed as board-data to the PMIC drivers. Since -PROBE_DEFER does not work
+ * for the clks/regulators the VCM i2c-clients must not be instantiated until
+ * the PMIC is fully setup.
+ *
+ * The sensor/VCM ACPI device has an ACPI _DEP on the PMIC, check this using the
+ * acpi_dev_ready_for_enumeration() helper, like the i2c-core-acpi code does
+ * for the sensors.
+ */
+static int cio2_bridge_sensors_are_ready(void)
+{
+ struct acpi_device *adev;
+ bool ready = true;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(cio2_supported_sensors); i++) {
+ const struct cio2_sensor_config *cfg =
+ &cio2_supported_sensors[i];
+
+ for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
+ if (!adev->status.enabled)
+ continue;
+
+ if (!acpi_dev_ready_for_enumeration(adev))
+ ready = false;
+ }
+ }
+
+ return ready;
+}
+
int cio2_bridge_init(struct pci_dev *cio2)
{
struct device *dev = &cio2->dev;
@@ -312,6 +405,9 @@ int cio2_bridge_init(struct pci_dev *cio2)
unsigned int i;
int ret;
+ if (!cio2_bridge_sensors_are_ready())
+ return -EPROBE_DEFER;
+
bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
if (!bridge)
return -ENOMEM;
diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
index 202c7d494f7a..4418cbd08208 100644
--- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
+++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
@@ -8,6 +8,8 @@
#include "ipu3-cio2.h"
+struct i2c_client;
+
#define CIO2_HID "INT343E"
#define CIO2_MAX_LANES 4
#define MAX_NUM_LINK_FREQS 3
@@ -42,12 +44,19 @@
.properties = _PROPS, \
}
+#define NODE_VCM(_TYPE) \
+ (const struct software_node) { \
+ .name = _TYPE, \
+ }
+
enum cio2_sensor_swnodes {
SWNODE_SENSOR_HID,
SWNODE_SENSOR_PORT,
SWNODE_SENSOR_ENDPOINT,
SWNODE_CIO2_PORT,
SWNODE_CIO2_ENDPOINT,
+ /* Must be last because it is optional / maybe empty */
+ SWNODE_VCM,
SWNODE_COUNT
};
@@ -106,8 +115,10 @@ struct cio2_sensor_config {
struct cio2_sensor {
char name[ACPI_ID_LEN];
struct acpi_device *adev;
+ struct i2c_client *vcm_i2c_client;
- struct software_node swnodes[6];
+ /* SWNODE_COUNT + 1 for terminating empty node */
+ struct software_node swnodes[SWNODE_COUNT + 1];
struct cio2_node_names node_names;
struct cio2_sensor_ssdb ssdb;
@@ -115,10 +126,11 @@ struct cio2_sensor {
struct cio2_property_names prop_names;
struct property_entry ep_properties[5];
- struct property_entry dev_properties[4];
+ struct property_entry dev_properties[5];
struct property_entry cio2_properties[3];
struct software_node_ref_args local_ref[1];
struct software_node_ref_args remote_ref[1];
+ struct software_node_ref_args vcm_ref[1];
};
struct cio2_bridge {
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
index 356ea966cf8d..0e9b0503b62a 100644
--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
@@ -1713,11 +1713,6 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
struct cio2_device *cio2;
int r;
- cio2 = devm_kzalloc(dev, sizeof(*cio2), GFP_KERNEL);
- if (!cio2)
- return -ENOMEM;
- cio2->pci_dev = pci_dev;
-
/*
* On some platforms no connections to sensors are defined in firmware,
* if the device has no endpoints then we can try to build those as
@@ -1735,6 +1730,11 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
return r;
}
+ cio2 = devm_kzalloc(dev, sizeof(*cio2), GFP_KERNEL);
+ if (!cio2)
+ return -ENOMEM;
+ cio2->pci_dev = pci_dev;
+
r = pcim_enable_device(pci_dev);
if (r) {
dev_err(dev, "failed to enable device (%d)\n", r);
@@ -1966,12 +1966,19 @@ static int __maybe_unused cio2_suspend(struct device *dev)
struct pci_dev *pci_dev = to_pci_dev(dev);
struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
struct cio2_queue *q = cio2->cur_queue;
+ int r;
dev_dbg(dev, "cio2 suspend\n");
if (!cio2->streaming)
return 0;
/* Stop stream */
+ r = v4l2_subdev_call(q->sensor, video, s_stream, 0);
+ if (r) {
+ dev_err(dev, "failed to stop sensor streaming\n");
+ return r;
+ }
+
cio2_hw_exit(cio2, q);
synchronize_irq(pci_dev->irq);
@@ -2005,8 +2012,16 @@ static int __maybe_unused cio2_resume(struct device *dev)
}
r = cio2_hw_init(cio2, q);
- if (r)
+ if (r) {
dev_err(dev, "fail to init cio2 hw\n");
+ return r;
+ }
+
+ r = v4l2_subdev_call(q->sensor, video, s_stream, 1);
+ if (r) {
+ dev_err(dev, "fail to start sensor streaming\n");
+ cio2_hw_exit(cio2, q);
+ }
return r;
}
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c
index 4cefdb2e4d40..9e13a7128a53 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-main.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c
@@ -48,12 +48,6 @@ struct snd_ivtv_card *to_snd_ivtv_card(struct v4l2_device *v4l2_dev)
return to_ivtv(v4l2_dev)->alsa;
}
-static inline
-struct snd_ivtv_card *p_to_snd_ivtv_card(struct v4l2_device **v4l2_dev)
-{
- return container_of(v4l2_dev, struct snd_ivtv_card, v4l2_dev);
-}
-
static void snd_ivtv_card_free(struct snd_ivtv_card *itvsc)
{
if (itvsc == NULL)
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 2c43ebf83966..00ac94d4ab19 100644
--- a/drivers/media/pci/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
@@ -42,7 +42,7 @@
/* card parameters */
static int ivtvfb_card_id = -1;
-static int ivtvfb_debug = 0;
+static int ivtvfb_debug;
static bool ivtvfb_force_pat = IS_ENABLED(CONFIG_VIDEO_FB_IVTV_FORCE_PAT);
static bool osd_laced;
static int osd_depth;
diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c
index c0bc86793355..0d51bdf01f43 100644
--- a/drivers/media/pci/pt3/pt3.c
+++ b/drivers/media/pci/pt3/pt3.c
@@ -685,12 +685,6 @@ static void pt3_remove(struct pci_dev *pdev)
for (i = PT3_NUM_FE - 1; i >= 0; i--)
pt3_cleanup_adapter(pt3, i);
i2c_del_adapter(&pt3->i2c_adap);
- kfree(pt3->i2c_buf);
- pci_iounmap(pt3->pdev, pt3->regs[0]);
- pci_iounmap(pt3->pdev, pt3->regs[1]);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- kfree(pt3);
}
static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -704,14 +698,14 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_read_config_byte(pdev, PCI_REVISION_ID, &rev) || rev != 1)
return -ENODEV;
- ret = pci_enable_device(pdev);
+ ret = pcim_enable_device(pdev);
if (ret < 0)
return -ENODEV;
pci_set_master(pdev);
- ret = pci_request_regions(pdev, DRV_NAME);
+ ret = pcim_iomap_regions(pdev, BIT(0) | BIT(2), DRV_NAME);
if (ret < 0)
- goto err_disable_device;
+ return ret;
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if (ret == 0)
@@ -722,42 +716,32 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
else {
dev_err(&pdev->dev, "Failed to set DMA mask\n");
- goto err_release_regions;
+ return ret;
}
dev_info(&pdev->dev, "Use 32bit DMA\n");
}
- pt3 = kzalloc(sizeof(*pt3), GFP_KERNEL);
- if (!pt3) {
- ret = -ENOMEM;
- goto err_release_regions;
- }
+ pt3 = devm_kzalloc(&pdev->dev, sizeof(*pt3), GFP_KERNEL);
+ if (!pt3)
+ return -ENOMEM;
pci_set_drvdata(pdev, pt3);
pt3->pdev = pdev;
mutex_init(&pt3->lock);
- pt3->regs[0] = pci_ioremap_bar(pdev, 0);
- pt3->regs[1] = pci_ioremap_bar(pdev, 2);
- if (pt3->regs[0] == NULL || pt3->regs[1] == NULL) {
- dev_err(&pdev->dev, "Failed to ioremap\n");
- ret = -ENOMEM;
- goto err_kfree;
- }
+ pt3->regs[0] = pcim_iomap_table(pdev)[0];
+ pt3->regs[1] = pcim_iomap_table(pdev)[2];
ver = ioread32(pt3->regs[0] + REG_VERSION);
if ((ver >> 16) != 0x0301) {
dev_warn(&pdev->dev, "PT%d, I/F-ver.:%d not supported\n",
ver >> 24, (ver & 0x00ff0000) >> 16);
- ret = -ENODEV;
- goto err_iounmap;
+ return -ENODEV;
}
pt3->num_bufs = clamp_val(num_bufs, MIN_DATA_BUFS, MAX_DATA_BUFS);
- pt3->i2c_buf = kmalloc(sizeof(*pt3->i2c_buf), GFP_KERNEL);
- if (pt3->i2c_buf == NULL) {
- ret = -ENOMEM;
- goto err_iounmap;
- }
+ pt3->i2c_buf = devm_kmalloc(&pdev->dev, sizeof(*pt3->i2c_buf), GFP_KERNEL);
+ if (!pt3->i2c_buf)
+ return -ENOMEM;
i2c = &pt3->i2c_adap;
i2c->owner = THIS_MODULE;
i2c->algo = &pt3_i2c_algo;
@@ -767,7 +751,7 @@ static int pt3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i2c_set_adapdata(i2c, pt3);
ret = i2c_add_adapter(i2c);
if (ret < 0)
- goto err_i2cbuf;
+ return ret;
for (i = 0; i < PT3_NUM_FE; i++) {
ret = pt3_alloc_adapter(pt3, i);
@@ -799,21 +783,7 @@ err_cleanup_adapters:
while (i >= 0)
pt3_cleanup_adapter(pt3, i--);
i2c_del_adapter(i2c);
-err_i2cbuf:
- kfree(pt3->i2c_buf);
-err_iounmap:
- if (pt3->regs[0])
- pci_iounmap(pdev, pt3->regs[0]);
- if (pt3->regs[1])
- pci_iounmap(pdev, pt3->regs[1]);
-err_kfree:
- kfree(pt3);
-err_release_regions:
- pci_release_regions(pdev);
-err_disable_device:
- pci_disable_device(pdev);
return ret;
-
}
static const struct pci_device_id pt3_id_table[] = {
diff --git a/drivers/media/pci/saa7134/saa7134-go7007.c b/drivers/media/pci/saa7134/saa7134-go7007.c
index f319edb39c0e..da83893ffee9 100644
--- a/drivers/media/pci/saa7134/saa7134-go7007.c
+++ b/drivers/media/pci/saa7134/saa7134-go7007.c
@@ -56,11 +56,6 @@ struct saa7134_go7007 {
dma_addr_t bottom_dma;
};
-static inline struct saa7134_go7007 *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa7134_go7007, sd);
-}
-
static const struct go7007_board_info board_voyager = {
.flags = 0,
.sensor_flags = GO7007_SENSOR_656 |
@@ -385,7 +380,7 @@ MODULE_FIRMWARE("go7007/go7007tv.bin");
static int saa7134_go7007_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
#if 0
- struct saa7134_go7007 *saa = to_state(sd);
+ struct saa7134_go7007 *saa = container_of(sd, struct saa7134_go7007, sd);
struct saa7134_dev *dev = saa->dev;
return saa7134_s_std_internal(dev, NULL, norm);
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index 2214c74bbbf1..3947701cd6c7 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
@@ -284,7 +284,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
hexium_set_input(hexium, 0);
hexium->cur_input = 0;
- saa7146_vv_init(dev, &vv_data);
+ ret = saa7146_vv_init(dev, &vv_data);
+ if (ret) {
+ i2c_del_adapter(&hexium->i2c_adapter);
+ kfree(hexium);
+ return ret;
+ }
vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index 39d14c179d22..2eb4bee16b71 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
@@ -355,10 +355,16 @@ static struct saa7146_ext_vv vv_data;
static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
{
struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int ret;
DEB_EE("\n");
- saa7146_vv_init(dev, &vv_data);
+ ret = saa7146_vv_init(dev, &vv_data);
+ if (ret) {
+ pr_err("Error in saa7146_vv_init()\n");
+ return ret;
+ }
+
vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c
index 73fc901ecf3d..7ded8f5b05cb 100644
--- a/drivers/media/pci/saa7146/mxb.c
+++ b/drivers/media/pci/saa7146/mxb.c
@@ -340,7 +340,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
struct tuner_setup tun_setup;
v4l2_std_id std = V4L2_STD_PAL_BG;
- int i = 0, err = 0;
+ int i, err = 0;
/* mute audio on tea6420s */
tea6420_route(mxb, 6);
@@ -349,7 +349,6 @@ static int mxb_init_done(struct saa7146_dev* dev)
saa7111a_call(mxb, video, s_std, std);
/* select tuner-output on saa7111a */
- i = 0;
saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
SAA7111_FMT_CCIR, 0);
@@ -683,10 +682,16 @@ static struct saa7146_ext_vv vv_data;
static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
{
struct mxb *mxb;
+ int ret;
DEB_EE("dev:%p\n", dev);
- saa7146_vv_init(dev, &vv_data);
+ ret = saa7146_vv_init(dev, &vv_data);
+ if (ret) {
+ ERR("Error in saa7146_vv_init()");
+ return ret;
+ }
+
if (mxb_probe(dev)) {
saa7146_vv_release(dev);
return -1;
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index 0abcad4e84fa..7766cadb73ea 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -391,12 +391,12 @@ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip,
}
/* Extract values from VOP header - VE_STATUSxx */
-static inline int vop_interlaced(const vop_header *vh)
+static inline __always_unused int vop_interlaced(const vop_header *vh)
{
return (__le32_to_cpu((*vh)[0]) >> 30) & 1;
}
-static inline u8 vop_channel(const vop_header *vh)
+static inline __always_unused u8 vop_channel(const vop_header *vh)
{
return (__le32_to_cpu((*vh)[0]) >> 24) & 0x1F;
}
@@ -411,12 +411,12 @@ static inline u32 vop_mpeg_size(const vop_header *vh)
return __le32_to_cpu((*vh)[0]) & 0xFFFFF;
}
-static inline u8 vop_hsize(const vop_header *vh)
+static inline u8 __always_unused vop_hsize(const vop_header *vh)
{
return (__le32_to_cpu((*vh)[1]) >> 8) & 0xFF;
}
-static inline u8 vop_vsize(const vop_header *vh)
+static inline u8 __always_unused vop_vsize(const vop_header *vh)
{
return __le32_to_cpu((*vh)[1]) & 0xFF;
}
@@ -436,12 +436,12 @@ static inline u32 vop_jpeg_size(const vop_header *vh)
return __le32_to_cpu((*vh)[4]) & 0xFFFFF;
}
-static inline u32 vop_sec(const vop_header *vh)
+static inline u32 __always_unused vop_sec(const vop_header *vh)
{
return __le32_to_cpu((*vh)[5]);
}
-static inline u32 vop_usec(const vop_header *vh)
+static inline __always_unused u32 vop_usec(const vop_header *vh)
{
return __le32_to_cpu((*vh)[6]);
}
diff --git a/drivers/media/pci/tw5864/tw5864-core.c b/drivers/media/pci/tw5864/tw5864-core.c
index 23d3cae54a5d..5cae73e6fb9c 100644
--- a/drivers/media/pci/tw5864/tw5864-core.c
+++ b/drivers/media/pci/tw5864/tw5864-core.c
@@ -333,11 +333,10 @@ static void tw5864_finidev(struct pci_dev *pci_dev)
/* release resources */
iounmap(dev->mmio);
- release_mem_region(pci_resource_start(pci_dev, 0),
- pci_resource_len(pci_dev, 0));
+ pci_release_regions(pci_dev);
+ pci_disable_device(pci_dev);
v4l2_device_unregister(&dev->v4l2_dev);
- devm_kfree(&pci_dev->dev, dev);
}
static struct pci_driver tw5864_pci_driver = {
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index cf4adc64c953..9fbdba0fd1e7 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -492,6 +492,18 @@ config VIDEO_STI_DELTA_DRIVER
endif # VIDEO_STI_DELTA
+config VIDEO_STM32_DMA2D
+ tristate "STM32 Chrom-Art Accelerator (DMA2D)"
+ depends on VIDEO_DEV && VIDEO_V4L2
+ depends on ARCH_STM32 || COMPILE_TEST
+ select VIDEOBUF2_DMA_CONTIG
+ select V4L2_MEM2MEM_DEV
+ help
+ Enables DMA2D hardware support on stm32.
+
+ The STM32 DMA2D is a memory-to-memory engine for pixel conversion
+ and specialized DMA dedicated to image manipulation.
+
config VIDEO_RENESAS_FDP1
tristate "Renesas Fine Display Processor"
depends on VIDEO_DEV && VIDEO_V4L2
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index a148553babfc..19bcbced7382 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/
obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel/
obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32/
+obj-$(CONFIG_VIDEO_STM32_DMA2D) += stm32/
obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/
diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c
index c8156da33043..4a3d06c70e34 100644
--- a/drivers/media/platform/allegro-dvt/allegro-core.c
+++ b/drivers/media/platform/allegro-dvt/allegro-core.c
@@ -2815,7 +2815,7 @@ static void allegro_buf_queue(struct vb2_buffer *vb)
unsigned int i;
for (i = 0; i < vb->num_planes; i++)
- vb->planes[i].bytesused = 0;
+ vb2_set_plane_payload(vb, i, 0);
vbuf->field = V4L2_FIELD_NONE;
vbuf->sequence = channel->csequence++;
diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index cad3f97515ae..7a24daf7165a 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -539,6 +539,10 @@ static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
aspeed_video_update(video, VE_INTERRUPT_CTRL, 0,
VE_INTERRUPT_MODE_DETECT);
+ /* Disable mode detect in order to re-trigger */
+ aspeed_video_update(video, VE_SEQ_CTRL,
+ VE_SEQ_CTRL_TRIG_MODE_DET, 0);
+
/* Trigger mode detect */
aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET);
}
@@ -591,6 +595,8 @@ static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
set_bit(VIDEO_RES_CHANGE, &video->flags);
clear_bit(VIDEO_FRAME_INPRG, &video->flags);
+ video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL;
+
aspeed_video_off(video);
aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR);
@@ -824,10 +830,6 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
return;
}
- /* Disable mode detect in order to re-trigger */
- aspeed_video_update(video, VE_SEQ_CTRL,
- VE_SEQ_CTRL_TRIG_MODE_DET, 0);
-
aspeed_video_check_and_set_polarity(video);
aspeed_video_enable_mode_detect(video);
@@ -1375,7 +1377,6 @@ static void aspeed_video_resolution_work(struct work_struct *work)
struct delayed_work *dwork = to_delayed_work(work);
struct aspeed_video *video = container_of(dwork, struct aspeed_video,
res_work);
- u32 input_status = video->v4l2_input_status;
aspeed_video_on(video);
@@ -1388,8 +1389,7 @@ static void aspeed_video_resolution_work(struct work_struct *work)
aspeed_video_get_resolution(video);
if (video->detected_timings.width != video->active_timings.width ||
- video->detected_timings.height != video->active_timings.height ||
- input_status != video->v4l2_input_status) {
+ video->detected_timings.height != video->active_timings.height) {
static const struct v4l2_event ev = {
.type = V4L2_EVENT_SOURCE_CHANGE,
.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 0e312b0842d7..3cd47ba26357 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -43,7 +43,7 @@
#define CODA_NAME "coda"
#define CODADX6_MAX_INSTANCES 4
-#define CODA_MAX_FORMATS 4
+#define CODA_MAX_FORMATS 5
#define CODA_ISRAM_SIZE (2048 * 2)
@@ -247,6 +247,7 @@ static const struct coda_video_device coda9_jpeg_encoder = {
V4L2_PIX_FMT_YUV420,
V4L2_PIX_FMT_YVU420,
V4L2_PIX_FMT_YUV422P,
+ V4L2_PIX_FMT_GREY,
},
.dst_formats = {
V4L2_PIX_FMT_JPEG,
@@ -626,6 +627,11 @@ static int coda_try_fmt(struct coda_ctx *ctx, const struct coda_codec *codec,
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
f->fmt.pix.height * 2;
break;
+ case V4L2_PIX_FMT_GREY:
+ /* keep 16 pixel alignment of 8-bit pixel data */
+ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16);
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
+ break;
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_H264:
case V4L2_PIX_FMT_MPEG4:
@@ -1537,11 +1543,13 @@ static void coda_pic_run_work(struct work_struct *work)
if (!wait_for_completion_timeout(&ctx->completion,
msecs_to_jiffies(1000))) {
- dev_err(dev->dev, "CODA PIC_RUN timeout\n");
+ if (ctx->use_bit) {
+ dev_err(dev->dev, "CODA PIC_RUN timeout\n");
- ctx->hold = true;
+ ctx->hold = true;
- coda_hw_reset(ctx);
+ coda_hw_reset(ctx);
+ }
if (ctx->ops->run_timeout)
ctx->ops->run_timeout(ctx);
diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c
index b11cfbe166dd..a72f4655e5ad 100644
--- a/drivers/media/platform/coda/coda-jpeg.c
+++ b/drivers/media/platform/coda/coda-jpeg.c
@@ -1127,7 +1127,8 @@ static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx)
coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
- coda_write(dev, 0, CODA9_REG_JPEG_BBC_STRM_CTRL);
+ coda_write(dev, BIT(31) | ((end_addr - start_addr - header_len) / 256),
+ CODA9_REG_JPEG_BBC_STRM_CTRL);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
@@ -1257,6 +1258,23 @@ static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
coda_hw_reset(ctx);
}
+static void coda9_jpeg_encode_timeout(struct coda_ctx *ctx)
+{
+ struct coda_dev *dev = ctx->dev;
+ u32 end_addr, wr_ptr;
+
+ /* Handle missing BBC overflow interrupt via timeout */
+ end_addr = coda_read(dev, CODA9_REG_JPEG_BBC_END_ADDR);
+ wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
+ if (wr_ptr >= end_addr - 256) {
+ v4l2_err(&dev->v4l2_dev, "JPEG too large for capture buffer\n");
+ coda9_jpeg_finish_encode(ctx);
+ return;
+ }
+
+ coda_hw_reset(ctx);
+}
+
static void coda9_jpeg_release(struct coda_ctx *ctx)
{
int i;
@@ -1276,6 +1294,7 @@ const struct coda_context_ops coda9_jpeg_encode_ops = {
.start_streaming = coda9_jpeg_start_encoding,
.prepare_run = coda9_jpeg_prepare_encode,
.finish_run = coda9_jpeg_finish_encode,
+ .run_timeout = coda9_jpeg_encode_timeout,
.release = coda9_jpeg_release,
};
diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c
index 6996d4571e36..00643f37b3e6 100644
--- a/drivers/media/platform/coda/imx-vdoa.c
+++ b/drivers/media/platform/coda/imx-vdoa.c
@@ -287,7 +287,11 @@ static int vdoa_probe(struct platform_device *pdev)
struct resource *res;
int ret;
- dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "DMA enable failed\n");
+ return ret;
+ }
vdoa = devm_kzalloc(&pdev->dev, sizeof(*vdoa), GFP_KERNEL);
if (!vdoa)
diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
index 91b571a0ac2c..32f7ef547c82 100644
--- a/drivers/media/platform/davinci/vpbe_osd.c
+++ b/drivers/media/platform/davinci/vpbe_osd.c
@@ -45,7 +45,7 @@ static const struct platform_device_id vpbe_osd_devtype[] = {
MODULE_DEVICE_TABLE(platform, vpbe_osd_devtype);
/* register access routines */
-static inline u32 osd_read(struct osd_state *sd, u32 offset)
+static inline u32 __always_unused osd_read(struct osd_state *sd, u32 offset)
{
struct osd_state *osd = sd;
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index ae92e2c206d0..8fe55374c5a3 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -619,17 +619,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
}
/**
- * vpif_get_default_field() - Get default field type based on interface
- * @iface: ptr to vpif interface
- */
-static inline enum v4l2_field vpif_get_default_field(
- struct vpif_interface *iface)
-{
- return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
- V4L2_FIELD_INTERLACED;
-}
-
-/**
* vpif_config_addr() - function to configure buffer address in vpif
* @ch: channel ptr
* @muxmode: channel mux mode
@@ -1478,7 +1467,6 @@ probe_out:
for (k = 0; k < j; k++) {
/* Get the pointer to the channel object */
ch = vpif_obj.dev[k];
- common = &ch->common[k];
/* Unregister video device */
video_unregister_device(&ch->video_dev);
}
diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c
index 723b096fedd1..689ae5e6ac62 100644
--- a/drivers/media/platform/imx-pxp.c
+++ b/drivers/media/platform/imx-pxp.c
@@ -211,6 +211,7 @@ struct pxp_ctx {
/* Processing mode */
int mode;
u8 alpha_component;
+ u8 rotation;
enum v4l2_colorspace colorspace;
enum v4l2_xfer_func xfer_func;
@@ -767,14 +768,20 @@ static int pxp_start(struct pxp_ctx *ctx, struct vb2_v4l2_buffer *in_vb,
V4L2_BUF_FLAG_BFRAME |
V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
- /* Rotation disabled, 8x8 block size */
+ /* 8x8 block size */
ctrl = BF_PXP_CTRL_VFLIP0(!!(ctx->mode & MEM2MEM_VFLIP)) |
- BF_PXP_CTRL_HFLIP0(!!(ctx->mode & MEM2MEM_HFLIP));
+ BF_PXP_CTRL_HFLIP0(!!(ctx->mode & MEM2MEM_HFLIP)) |
+ BF_PXP_CTRL_ROTATE0(ctx->rotation);
/* Always write alpha value as V4L2_CID_ALPHA_COMPONENT */
out_ctrl = BF_PXP_OUT_CTRL_ALPHA(ctx->alpha_component) |
BF_PXP_OUT_CTRL_ALPHA_OUTPUT(1) |
pxp_v4l2_pix_fmt_to_out_format(dst_fourcc);
out_buf = p_out;
+
+ if (ctx->rotation == BV_PXP_CTRL_ROTATE0__ROT_90 ||
+ ctx->rotation == BV_PXP_CTRL_ROTATE0__ROT_270)
+ swap(dst_width, dst_height);
+
switch (dst_fourcc) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
@@ -1297,6 +1304,21 @@ static int pxp_s_fmt_vid_out(struct file *file, void *priv,
return 0;
}
+static u8 pxp_degrees_to_rot_mode(u32 degrees)
+{
+ switch (degrees) {
+ case 90:
+ return BV_PXP_CTRL_ROTATE0__ROT_90;
+ case 180:
+ return BV_PXP_CTRL_ROTATE0__ROT_180;
+ case 270:
+ return BV_PXP_CTRL_ROTATE0__ROT_270;
+ case 0:
+ default:
+ return BV_PXP_CTRL_ROTATE0__ROT_0;
+ }
+}
+
static int pxp_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct pxp_ctx *ctx =
@@ -1317,6 +1339,10 @@ static int pxp_s_ctrl(struct v4l2_ctrl *ctrl)
ctx->mode &= ~MEM2MEM_VFLIP;
break;
+ case V4L2_CID_ROTATE:
+ ctx->rotation = pxp_degrees_to_rot_mode(ctrl->val);
+ break;
+
case V4L2_CID_ALPHA_COMPONENT:
ctx->alpha_component = ctrl->val;
break;
@@ -1524,6 +1550,7 @@ static int pxp_open(struct file *file)
v4l2_ctrl_handler_init(hdl, 4);
v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_ROTATE, 0, 270, 90, 0);
v4l2_ctrl_new_std(hdl, &pxp_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
0, 255, 1, 255);
if (hdl->error) {
@@ -1659,6 +1686,8 @@ static int pxp_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
+ spin_lock_init(&dev->irqlock);
+
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, pxp_irq_handler,
IRQF_ONESHOT, dev_name(&pdev->dev), dev);
if (ret < 0) {
@@ -1676,8 +1705,6 @@ static int pxp_probe(struct platform_device *pdev)
goto err_clk;
}
- spin_lock_init(&dev->irqlock);
-
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret)
goto err_clk;
diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index b61b9d9551af..03dcf8bf705e 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -139,13 +139,6 @@ struct cafe_camera {
*/
#define CAFE_SMBUS_TIMEOUT (HZ) /* generous */
-static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
-{
- struct mcam_camera *m = container_of(dev, struct mcam_camera, v4l2_dev);
- return container_of(m, struct cafe_camera, mcam);
-}
-
-
static int cafe_smbus_write_done(struct mcam_camera *mcam)
{
unsigned long flags;
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index af994b9913a6..f332beb06d51 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -1361,10 +1361,8 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
}
jpeg_irq = platform_get_irq(pdev, 0);
- if (jpeg_irq < 0) {
- dev_err(&pdev->dev, "Failed to get jpeg_irq %d.\n", jpeg_irq);
+ if (jpeg_irq < 0)
return jpeg_irq;
- }
ret = devm_request_irq(&pdev->dev, jpeg_irq,
jpeg->variant->irq_handler, 0, pdev->name, jpeg);
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..3d38793aaa25 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -148,7 +148,7 @@ static int mtk_mdp_probe(struct platform_device *pdev)
continue;
}
- comp_type = (enum mtk_mdp_comp_type)of_id->data;
+ comp_type = (uintptr_t)of_id->data;
comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
if (!comp) {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 46783516b84a..e08886a600a3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -11,6 +11,7 @@
#include <media/videobuf2-core.h>
#include <media/v4l2-mem2mem.h>
+#define VCODEC_DEC_ALIGNED_64 64
#define VCODEC_CAPABILITY_4K_DISABLED 0x10
#define VCODEC_DEC_4K_CODED_WIDTH 4096U
#define VCODEC_DEC_4K_CODED_HEIGHT 2304U
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index e6e6a8203eeb..40c39e1e596b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -28,9 +28,6 @@
#define VDEC_IRQ_CLR 0x10
#define VDEC_IRQ_CFG_REG 0xa4
-module_param(mtk_v4l2_dbg_level, int, 0644);
-module_param(mtk_vcodec_dbg, bool, 0644);
-
/* Wake up context wait_queue */
static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
{
@@ -358,6 +355,8 @@ err_media_reg:
if (dev->vdec_pdata->uses_stateless_api)
v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
err_reg_cont:
+ if (dev->vdec_pdata->uses_stateless_api)
+ media_device_cleanup(&dev->mdev_dec);
destroy_workqueue(dev->decode_workqueue);
err_event_workq:
v4l2_m2m_release(dev->m2m_dev_dec);
@@ -390,7 +389,6 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
{
struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
- flush_workqueue(dev->decode_workqueue);
destroy_workqueue(dev->decode_workqueue);
if (media_devnode_is_registered(dev->mdev_dec.devnode)) {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 8f4a1f0a0769..3d9f47555884 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -133,7 +133,6 @@ static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
struct vdec_fb *pfb = &framebuf->frame_buffer;
struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
- pfb = &framebuf->frame_buffer;
pfb->base_y.va = NULL;
pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 7457451ebff0..ffb046eec610 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -104,6 +104,13 @@ static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl)
p->gop_size = ctrl->val;
ctx->param_change |= MTK_ENCODE_PARAM_GOP_SIZE;
break;
+ case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
+ /*
+ * FIXME - what vp8 profiles are actually supported?
+ * The ctrl is added (with only profile 0 supported) for now.
+ */
+ mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_VP8_PROFILE val = %d", ctrl->val);
+ break;
case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME");
p->force_intra = 1;
@@ -257,87 +264,82 @@ static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx,
return &ctx->q_data[MTK_Q_DATA_DST];
}
+static void vidioc_try_fmt_cap(struct v4l2_format *f)
+{
+ f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+ f->fmt.pix_mp.num_planes = 1;
+ f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+ f->fmt.pix_mp.flags = 0;
+}
+
/* V4L2 specification suggests the driver corrects the format struct if any of
* the dimensions is unsupported
*/
-static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
- const struct mtk_video_fmt *fmt)
+static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
+ const struct mtk_video_fmt *fmt)
{
struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
+ int tmp_w, tmp_h;
+ unsigned int max_width, max_height;
pix_fmt_mp->field = V4L2_FIELD_NONE;
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- pix_fmt_mp->num_planes = 1;
- pix_fmt_mp->plane_fmt[0].bytesperline = 0;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- int tmp_w, tmp_h;
- unsigned int max_width, max_height;
-
- if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE) {
- max_width = MTK_VENC_4K_MAX_W;
- max_height = MTK_VENC_4K_MAX_H;
- } else {
- max_width = MTK_VENC_HD_MAX_W;
- max_height = MTK_VENC_HD_MAX_H;
- }
+ if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE) {
+ max_width = MTK_VENC_4K_MAX_W;
+ max_height = MTK_VENC_4K_MAX_H;
+ } else {
+ max_width = MTK_VENC_HD_MAX_W;
+ max_height = MTK_VENC_HD_MAX_H;
+ }
- pix_fmt_mp->height = clamp(pix_fmt_mp->height,
- MTK_VENC_MIN_H,
- max_height);
- pix_fmt_mp->width = clamp(pix_fmt_mp->width,
- MTK_VENC_MIN_W,
- max_width);
+ pix_fmt_mp->height = clamp(pix_fmt_mp->height, MTK_VENC_MIN_H, max_height);
+ pix_fmt_mp->width = clamp(pix_fmt_mp->width, MTK_VENC_MIN_W, max_width);
- /* find next closer width align 16, heign align 32, size align
- * 64 rectangle
- */
- tmp_w = pix_fmt_mp->width;
- tmp_h = pix_fmt_mp->height;
- v4l_bound_align_image(&pix_fmt_mp->width,
- MTK_VENC_MIN_W,
- max_width, 4,
- &pix_fmt_mp->height,
- MTK_VENC_MIN_H,
- max_height, 5, 6);
-
- if (pix_fmt_mp->width < tmp_w &&
- (pix_fmt_mp->width + 16) <= max_width)
- pix_fmt_mp->width += 16;
- if (pix_fmt_mp->height < tmp_h &&
- (pix_fmt_mp->height + 32) <= max_height)
- pix_fmt_mp->height += 32;
-
- mtk_v4l2_debug(0,
- "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d %d",
- tmp_w, tmp_h, pix_fmt_mp->width,
- pix_fmt_mp->height,
- pix_fmt_mp->plane_fmt[0].sizeimage,
- pix_fmt_mp->plane_fmt[1].sizeimage);
-
- pix_fmt_mp->num_planes = fmt->num_planes;
- pix_fmt_mp->plane_fmt[0].sizeimage =
- pix_fmt_mp->width * pix_fmt_mp->height +
- ((ALIGN(pix_fmt_mp->width, 16) * 2) * 16);
- pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
-
- if (pix_fmt_mp->num_planes == 2) {
- pix_fmt_mp->plane_fmt[1].sizeimage =
- (pix_fmt_mp->width * pix_fmt_mp->height) / 2 +
- (ALIGN(pix_fmt_mp->width, 16) * 16);
- pix_fmt_mp->plane_fmt[2].sizeimage = 0;
- pix_fmt_mp->plane_fmt[1].bytesperline =
- pix_fmt_mp->width;
- pix_fmt_mp->plane_fmt[2].bytesperline = 0;
- } else if (pix_fmt_mp->num_planes == 3) {
- pix_fmt_mp->plane_fmt[1].sizeimage =
- pix_fmt_mp->plane_fmt[2].sizeimage =
- (pix_fmt_mp->width * pix_fmt_mp->height) / 4 +
- ((ALIGN(pix_fmt_mp->width, 16) / 2) * 16);
- pix_fmt_mp->plane_fmt[1].bytesperline =
- pix_fmt_mp->plane_fmt[2].bytesperline =
- pix_fmt_mp->width / 2;
- }
+ /* find next closer width align 16, heign align 32, size align
+ * 64 rectangle
+ */
+ tmp_w = pix_fmt_mp->width;
+ tmp_h = pix_fmt_mp->height;
+ v4l_bound_align_image(&pix_fmt_mp->width,
+ MTK_VENC_MIN_W,
+ max_width, 4,
+ &pix_fmt_mp->height,
+ MTK_VENC_MIN_H,
+ max_height, 5, 6);
+
+ if (pix_fmt_mp->width < tmp_w && (pix_fmt_mp->width + 16) <= max_width)
+ pix_fmt_mp->width += 16;
+ if (pix_fmt_mp->height < tmp_h && (pix_fmt_mp->height + 32) <= max_height)
+ pix_fmt_mp->height += 32;
+
+ mtk_v4l2_debug(0, "before resize w=%d, h=%d, after resize w=%d, h=%d, sizeimage=%d %d",
+ tmp_w, tmp_h, pix_fmt_mp->width,
+ pix_fmt_mp->height,
+ pix_fmt_mp->plane_fmt[0].sizeimage,
+ pix_fmt_mp->plane_fmt[1].sizeimage);
+
+ pix_fmt_mp->num_planes = fmt->num_planes;
+ pix_fmt_mp->plane_fmt[0].sizeimage =
+ pix_fmt_mp->width * pix_fmt_mp->height +
+ ((ALIGN(pix_fmt_mp->width, 16) * 2) * 16);
+ pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
+
+ if (pix_fmt_mp->num_planes == 2) {
+ pix_fmt_mp->plane_fmt[1].sizeimage =
+ (pix_fmt_mp->width * pix_fmt_mp->height) / 2 +
+ (ALIGN(pix_fmt_mp->width, 16) * 16);
+ pix_fmt_mp->plane_fmt[2].sizeimage = 0;
+ pix_fmt_mp->plane_fmt[1].bytesperline =
+ pix_fmt_mp->width;
+ pix_fmt_mp->plane_fmt[2].bytesperline = 0;
+ } else if (pix_fmt_mp->num_planes == 3) {
+ pix_fmt_mp->plane_fmt[1].sizeimage =
+ pix_fmt_mp->plane_fmt[2].sizeimage =
+ (pix_fmt_mp->width * pix_fmt_mp->height) / 4 +
+ ((ALIGN(pix_fmt_mp->width, 16) / 2) * 16);
+ pix_fmt_mp->plane_fmt[1].bytesperline =
+ pix_fmt_mp->plane_fmt[2].bytesperline =
+ pix_fmt_mp->width / 2;
}
pix_fmt_mp->flags = 0;
@@ -398,7 +400,7 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
struct vb2_queue *vq;
- struct mtk_q_data *q_data;
+ struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
int i, ret;
const struct mtk_video_fmt *fmt;
@@ -413,12 +415,6 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
return -EBUSY;
}
- q_data = mtk_venc_get_q_data(ctx, f->type);
- if (!q_data) {
- mtk_v4l2_err("fail to get q data");
- return -EINVAL;
- }
-
fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
if (!fmt) {
fmt = &ctx->dev->venc_pdata->capture_formats[0];
@@ -426,9 +422,7 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
}
q_data->fmt = fmt;
- ret = vidioc_try_fmt(ctx, f, q_data->fmt);
- if (ret)
- return ret;
+ vidioc_try_fmt_cap(f);
q_data->coded_width = f->fmt.pix_mp.width;
q_data->coded_height = f->fmt.pix_mp.height;
@@ -461,7 +455,7 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
struct vb2_queue *vq;
- struct mtk_q_data *q_data;
+ struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
int ret, i;
const struct mtk_video_fmt *fmt;
@@ -476,19 +470,13 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
return -EBUSY;
}
- q_data = mtk_venc_get_q_data(ctx, f->type);
- if (!q_data) {
- mtk_v4l2_err("fail to get q data");
- return -EINVAL;
- }
-
fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
if (!fmt) {
fmt = &ctx->dev->venc_pdata->output_formats[0];
f->fmt.pix.pixelformat = fmt->fourcc;
}
- ret = vidioc_try_fmt(ctx, f, fmt);
+ ret = vidioc_try_fmt_out(ctx, f, fmt);
if (ret)
return ret;
@@ -521,14 +509,13 @@ static int vidioc_venc_g_fmt(struct file *file, void *priv,
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
struct vb2_queue *vq;
- struct mtk_q_data *q_data;
+ struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
int i;
vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
if (!vq)
return -EINVAL;
- q_data = mtk_venc_get_q_data(ctx, f->type);
pix->width = q_data->coded_width;
pix->height = q_data->coded_height;
@@ -566,7 +553,9 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
f->fmt.pix_mp.quantization = ctx->quantization;
f->fmt.pix_mp.xfer_func = ctx->xfer_func;
- return vidioc_try_fmt(ctx, f, fmt);
+ vidioc_try_fmt_cap(f);
+
+ return 0;
}
static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
@@ -588,22 +577,18 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
}
- return vidioc_try_fmt(ctx, f, fmt);
+ return vidioc_try_fmt_out(ctx, f, fmt);
}
static int vidioc_venc_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct mtk_q_data *q_data;
+ struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
- q_data = mtk_venc_get_q_data(ctx, s->type);
- if (!q_data)
- return -EINVAL;
-
switch (s->target) {
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_BOUNDS:
@@ -629,15 +614,11 @@ static int vidioc_venc_s_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct mtk_q_data *q_data;
+ struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
- q_data = mtk_venc_get_q_data(ctx, s->type);
- if (!q_data)
- return -EINVAL;
-
switch (s->target) {
case V4L2_SEL_TGT_CROP:
/* Only support crop from (0,0) */
@@ -804,11 +785,9 @@ static int vb2ops_venc_queue_setup(struct vb2_queue *vq,
struct device *alloc_devs[])
{
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
- struct mtk_q_data *q_data;
+ struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vq->type);
unsigned int i;
- q_data = mtk_venc_get_q_data(ctx, vq->type);
-
if (q_data == NULL)
return -EINVAL;
@@ -828,11 +807,9 @@ static int vb2ops_venc_queue_setup(struct vb2_queue *vq,
static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb)
{
struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct mtk_q_data *q_data;
+ struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type);
int i;
- q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type);
-
for (i = 0; i < q_data->fmt->num_planes; i++) {
if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
@@ -959,7 +936,7 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
- dst_buf->vb2_buf.planes[0].bytesused = 0;
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
}
/* STREAMOFF on the CAPTURE queue completes any ongoing flush */
@@ -1068,7 +1045,7 @@ static int mtk_venc_encode_header(void *priv)
NULL, &bs_buf, &enc_result);
if (ret) {
- dst_buf->vb2_buf.planes[0].bytesused = 0;
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
ctx->state = MTK_STATE_ABORT;
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
mtk_v4l2_err("venc_if_encode failed=%d", ret);
@@ -1083,7 +1060,7 @@ static int mtk_venc_encode_header(void *priv)
}
ctx->state = MTK_STATE_HEADER;
- dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size;
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
return 0;
@@ -1232,12 +1209,12 @@ static void mtk_venc_worker(struct work_struct *work)
if (ret) {
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
- dst_buf->vb2_buf.planes[0].bytesused = 0;
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
mtk_v4l2_err("venc_if_encode failed=%d", ret);
} else {
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
- dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size;
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
enc_result.bs_size);
@@ -1395,6 +1372,9 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL,
h264_max_level,
0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+ v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
+ V4L2_MPEG_VIDEO_VP8_PROFILE_0, 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
+
if (handler->error) {
mtk_v4l2_err("Init control handler fail %d",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index eed67394cf46..aeaecb8d416e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -23,9 +23,6 @@
#include "mtk_vcodec_util.h"
#include "mtk_vcodec_fw.h"
-module_param(mtk_v4l2_dbg_level, int, S_IRUGO | S_IWUSR);
-module_param(mtk_vcodec_dbg, bool, S_IRUGO | S_IWUSR);
-
static const struct mtk_video_fmt mtk_video_formats_output[] = {
{
.fourcc = V4L2_PIX_FMT_NV12M,
@@ -214,11 +211,11 @@ static int fops_vcodec_release(struct file *file)
mtk_v4l2_debug(1, "[%d] encoder", ctx->id);
mutex_lock(&dev->dev_mutex);
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
mtk_vcodec_enc_release(ctx);
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
list_del_init(&ctx->list);
kfree(ctx);
@@ -461,7 +458,6 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
mtk_v4l2_debug_enter();
- flush_workqueue(dev->encode_workqueue);
destroy_workqueue(dev->encode_workqueue);
if (dev->m2m_dev_enc)
v4l2_m2m_release(dev->m2m_dev_enc);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index ac5973b6735f..5bac820a47fc 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -10,16 +10,6 @@
#include "mtk_vcodec_drv.h"
#include "mtk_vcodec_util.h"
-/* For encoder, this will enable logs in venc/*/
-bool mtk_vcodec_dbg;
-EXPORT_SYMBOL(mtk_vcodec_dbg);
-
-/* The log level of v4l2 encoder or decoder driver.
- * That is, files under mtk-vcodec/.
- */
-int mtk_v4l2_dbg_level;
-EXPORT_SYMBOL(mtk_v4l2_dbg_level);
-
void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
unsigned int reg_idx)
{
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index b999d7b84ed1..87c3d6d4bfa7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -25,54 +25,29 @@ struct mtk_vcodec_fb {
struct mtk_vcodec_ctx;
struct mtk_vcodec_dev;
-extern int mtk_v4l2_dbg_level;
-extern bool mtk_vcodec_dbg;
-
+#undef pr_fmt
+#define pr_fmt(fmt) "%s(),%d: " fmt, __func__, __LINE__
#define mtk_v4l2_err(fmt, args...) \
- pr_err("[MTK_V4L2][ERROR] %s:%d: " fmt "\n", __func__, __LINE__, \
- ##args)
-
-#define mtk_vcodec_err(h, fmt, args...) \
- pr_err("[MTK_VCODEC][ERROR][%d]: %s() " fmt "\n", \
- ((struct mtk_vcodec_ctx *)h->ctx)->id, __func__, ##args)
+ pr_err("[MTK_V4L2][ERROR] " fmt "\n", ##args)
+#define mtk_vcodec_err(h, fmt, args...) \
+ pr_err("[MTK_VCODEC][ERROR][%d]: " fmt "\n", \
+ ((struct mtk_vcodec_ctx *)(h)->ctx)->id, ##args)
-#if defined(DEBUG)
-#define mtk_v4l2_debug(level, fmt, args...) \
- do { \
- if (mtk_v4l2_dbg_level >= level) \
- pr_info("[MTK_V4L2] level=%d %s(),%d: " fmt "\n",\
- level, __func__, __LINE__, ##args); \
- } while (0)
+#define mtk_v4l2_debug(level, fmt, args...) pr_debug(fmt, ##args)
#define mtk_v4l2_debug_enter() mtk_v4l2_debug(3, "+")
#define mtk_v4l2_debug_leave() mtk_v4l2_debug(3, "-")
-#define mtk_vcodec_debug(h, fmt, args...) \
- do { \
- if (mtk_vcodec_dbg) \
- pr_info("[MTK_VCODEC][%d]: %s() " fmt "\n", \
- ((struct mtk_vcodec_ctx *)h->ctx)->id, \
- __func__, ##args); \
- } while (0)
+#define mtk_vcodec_debug(h, fmt, args...) \
+ pr_debug("[MTK_VCODEC][%d]: " fmt "\n", \
+ ((struct mtk_vcodec_ctx *)(h)->ctx)->id, ##args)
#define mtk_vcodec_debug_enter(h) mtk_vcodec_debug(h, "+")
#define mtk_vcodec_debug_leave(h) mtk_vcodec_debug(h, "-")
-#else
-
-#define mtk_v4l2_debug(level, fmt, args...) {}
-#define mtk_v4l2_debug_enter() {}
-#define mtk_v4l2_debug_leave() {}
-
-#define mtk_vcodec_debug(h, fmt, args...) {}
-#define mtk_vcodec_debug_enter(h) {}
-#define mtk_vcodec_debug_leave(h) {}
-
-#endif
-
void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
unsigned int reg_idx);
int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 946c23088308..fada4d146703 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -527,7 +527,7 @@ static int alloc_mv_buf(struct vdec_h264_slice_inst *inst,
struct mtk_vcodec_mem *mem = NULL;
unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
- mtk_v4l2_debug(3, "size = 0x%lx", buf_sz);
+ mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
for (i = 0; i < H264_MAX_MV_NUM; i++) {
mem = &inst->mv_buf[i];
if (mem->va)
@@ -562,8 +562,8 @@ static void get_pic_info(struct vdec_h264_slice_inst *inst,
{
struct mtk_vcodec_ctx *ctx = inst->ctx;
- ctx->picinfo.buf_w = (ctx->picinfo.pic_w + 15) & 0xFFFFFFF0;
- ctx->picinfo.buf_h = (ctx->picinfo.pic_h + 31) & 0xFFFFFFE0;
+ ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, VCODEC_DEC_ALIGNED_64);
+ ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, VCODEC_DEC_ALIGNED_64);
ctx->picinfo.fb_sz[0] = ctx->picinfo.buf_w * ctx->picinfo.buf_h;
ctx->picinfo.fb_sz[1] = ctx->picinfo.fb_sz[0] >> 1;
inst->vsi_ctx.dec.cap_num_planes =
@@ -637,7 +637,7 @@ static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx)
if (err)
goto error_deinit;
- mtk_vcodec_debug(inst, "struct size = %d,%d,%d,%d\n",
+ mtk_vcodec_debug(inst, "struct size = %zu,%zu,%zu,%zu\n",
sizeof(struct mtk_h264_sps_param),
sizeof(struct mtk_h264_pps_param),
sizeof(struct mtk_h264_dec_slice_param),
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index b6a4f2074fa5..bf03888a824f 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -367,8 +367,7 @@ static int h264_encode_sps(struct venc_h264_inst *inst,
mtk_vcodec_debug_enter(inst);
- ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL,
- bs_buf, bs_size, NULL);
+ ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL, bs_buf, NULL);
if (ret)
return ret;
@@ -394,8 +393,7 @@ static int h264_encode_pps(struct venc_h264_inst *inst,
mtk_vcodec_debug_enter(inst);
- ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL,
- bs_buf, bs_size, NULL);
+ ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL, bs_buf, NULL);
if (ret)
return ret;
@@ -451,8 +449,7 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
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, bs_size, &frame_info);
+ ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf, bs_buf, &frame_info);
if (ret)
return ret;
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 8267a9c4fd25..6b66957d5192 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -302,8 +302,7 @@ static int vp8_enc_encode_frame(struct venc_vp8_inst *inst,
mtk_vcodec_debug(inst, "->frm_cnt=%d", inst->frm_cnt);
- ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, bs_size,
- NULL);
+ ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, NULL);
if (ret)
return ret;
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
index be6d8790a41e..e7899d8a3e4e 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
@@ -225,7 +225,6 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu,
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,
- unsigned int *bs_size,
struct venc_frame_info *frame_info)
{
const bool is_ext = MTK_ENC_CTX_IS_EXT(vpu->ctx);
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
index f9be9cab7ff7..f83bc1b3f2bf 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
@@ -45,7 +45,6 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu,
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,
- unsigned int *bs_size,
struct venc_frame_info *frame_info);
int vpu_enc_deinit(struct venc_vpu_inst *vpu);
diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c
index 7f1647da0ade..7bd715fc844d 100644
--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
+++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
@@ -964,10 +964,8 @@ static int mtk_vpu_remove(struct platform_device *pdev)
#ifdef CONFIG_DEBUG_FS
debugfs_remove(vpu_debugfs);
#endif
- if (vpu->wdt.wq) {
- flush_workqueue(vpu->wdt.wq);
+ if (vpu->wdt.wq)
destroy_workqueue(vpu->wdt.wq);
- }
vpu_free_ext_mem(vpu, P_FW);
vpu_free_ext_mem(vpu, D_FW);
mutex_destroy(&vpu->vpu_mutex);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 6de377ce281d..4c937f3f323e 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -476,7 +476,8 @@ void omap3isp_hist_dma_done(struct isp_device *isp)
}
}
-static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus)
+static inline void __maybe_unused isp_isr_dbg(struct isp_device *isp,
+ u32 irqstatus)
{
static const char *name[] = {
"CSIA_IRQ",
diff --git a/drivers/media/platform/omap3isp/isph3a_af.c b/drivers/media/platform/omap3isp/isph3a_af.c
index a65cfdfa9637..de7b116d0122 100644
--- a/drivers/media/platform/omap3isp/isph3a_af.c
+++ b/drivers/media/platform/omap3isp/isph3a_af.c
@@ -21,7 +21,7 @@
#include "ispstat.h"
#define IS_OUT_OF_BOUNDS(value, min, max) \
- (((value) < (min)) || ((value) > (max)))
+ ((((unsigned int)value) < (min)) || (((unsigned int)value) > (max)))
static void h3a_af_setup_regs(struct ispstat *af, void *priv)
{
diff --git a/drivers/media/platform/omap3isp/omap3isp.h b/drivers/media/platform/omap3isp/omap3isp.h
index 214f94c46a9d..4a003c8263ed 100644
--- a/drivers/media/platform/omap3isp/omap3isp.h
+++ b/drivers/media/platform/omap3isp/omap3isp.h
@@ -95,6 +95,8 @@ struct isp_csiphy_lanes_cfg {
* ISP_CCP2_PHY_DATA_CLOCK - Data/clock physical layer
* ISP_CCP2_PHY_DATA_STROBE - Data/strobe physical layer
* @vpclk_div: Video port output clock control
+ * @vp_clk_pol: Video port output clock polarity
+ * @lanecfg: CCP2/CSI2 lane configuration
*/
struct isp_ccp2_cfg {
unsigned int strobe_clk_pol:1;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
index 5c083d70d495..f524af712a84 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -191,13 +191,6 @@ static u32 vfe_hw_version(struct vfe_device *vfe)
return hw_version;
}
-static inline void vfe_reg_clr(struct vfe_device *vfe, u32 reg, u32 clr_bits)
-{
- u32 bits = readl_relaxed(vfe->base + reg);
-
- writel_relaxed(bits & ~clr_bits, vfe->base + reg);
-}
-
static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
{
u32 bits = readl_relaxed(vfe->base + reg);
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index f5fa81896012..877eca125803 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -350,11 +350,11 @@ static int venus_probe(struct platform_device *pdev)
ret = venus_firmware_init(core);
if (ret)
- goto err_runtime_disable;
+ goto err_of_depopulate;
ret = venus_boot(core);
if (ret)
- goto err_runtime_disable;
+ goto err_firmware_deinit;
ret = hfi_core_resume(core, true);
if (ret)
@@ -386,6 +386,10 @@ err_dev_unregister:
v4l2_device_unregister(&core->v4l2_dev);
err_venus_shutdown:
venus_shutdown(core);
+err_firmware_deinit:
+ venus_firmware_deinit(core);
+err_of_depopulate:
+ of_platform_depopulate(dev);
err_runtime_disable:
pm_runtime_put_noidle(dev);
pm_runtime_set_suspended(dev);
@@ -473,7 +477,8 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
err_video_path:
icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
err_cpucfg_path:
- pm_ops->core_power(core, POWER_ON);
+ if (pm_ops->core_power)
+ pm_ops->core_power(core, POWER_ON);
return ret;
}
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
index cedc664ba755..cb48c5ff3dee 100644
--- a/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -163,14 +163,12 @@ static u32 load_per_type(struct venus_core *core, u32 session_type)
struct venus_inst *inst = NULL;
u32 mbs_per_sec = 0;
- mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
if (inst->session_type != session_type)
continue;
mbs_per_sec += load_per_instance(inst);
}
- mutex_unlock(&core->lock);
return mbs_per_sec;
}
@@ -219,14 +217,12 @@ static int load_scale_bw(struct venus_core *core)
struct venus_inst *inst = NULL;
u32 mbs_per_sec, avg, peak, total_avg = 0, total_peak = 0;
- mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
mbs_per_sec = load_per_instance(inst);
mbs_to_bw(inst, mbs_per_sec, &avg, &peak);
total_avg += avg;
total_peak += peak;
}
- mutex_unlock(&core->lock);
/*
* keep minimum bandwidth vote for "video-mem" path,
@@ -253,8 +249,9 @@ static int load_scale_v1(struct venus_inst *inst)
struct device *dev = core->dev;
u32 mbs_per_sec;
unsigned int i;
- int ret;
+ int ret = 0;
+ mutex_lock(&core->lock);
mbs_per_sec = load_per_type(core, VIDC_SESSION_TYPE_ENC) +
load_per_type(core, VIDC_SESSION_TYPE_DEC);
@@ -279,17 +276,19 @@ set_freq:
if (ret) {
dev_err(dev, "failed to set clock rate %lu (%d)\n",
freq, ret);
- return ret;
+ goto exit;
}
ret = load_scale_bw(core);
if (ret) {
dev_err(dev, "failed to set bandwidth (%d)\n",
ret);
- return ret;
+ goto exit;
}
- return 0;
+exit:
+ mutex_unlock(&core->lock);
+ return ret;
}
static int core_get_v1(struct venus_core *core)
@@ -587,8 +586,8 @@ min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load, bool lo
if (inst->session_type == VIDC_SESSION_TYPE_DEC)
vpp_freq = inst_pos->clk_data.vpp_freq;
else if (inst->session_type == VIDC_SESSION_TYPE_ENC)
- vpp_freq = low_power ? inst_pos->clk_data.vpp_freq :
- inst_pos->clk_data.low_power_freq;
+ vpp_freq = low_power ? inst_pos->clk_data.low_power_freq :
+ inst_pos->clk_data.vpp_freq;
else
continue;
@@ -1116,13 +1115,13 @@ static int load_scale_v4(struct venus_inst *inst)
struct device *dev = core->dev;
unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
unsigned long filled_len = 0;
- int i, ret;
+ int i, ret = 0;
for (i = 0; i < inst->num_input_bufs; i++)
filled_len = max(filled_len, inst->payloads[i]);
if (inst->session_type == VIDC_SESSION_TYPE_DEC && !filled_len)
- return 0;
+ return ret;
freq = calculate_inst_freq(inst, filled_len);
inst->clk_data.freq = freq;
@@ -1138,7 +1137,6 @@ static int load_scale_v4(struct venus_inst *inst)
freq_core2 += inst->clk_data.freq;
}
}
- mutex_unlock(&core->lock);
freq = max(freq_core1, freq_core2);
@@ -1163,17 +1161,19 @@ set_freq:
if (ret) {
dev_err(dev, "failed to set clock rate %lu (%d)\n",
freq, ret);
- return ret;
+ goto exit;
}
ret = load_scale_bw(core);
if (ret) {
dev_err(dev, "failed to set bandwidth (%d)\n",
ret);
- return ret;
+ goto exit;
}
- return 0;
+exit:
+ mutex_unlock(&core->lock);
+ return ret;
}
static const struct venus_pm_ops pm_ops_v4 = {
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 1d92cc8ede8f..0186ae235113 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -349,12 +349,10 @@ out:
static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
{
- mutex_lock(&vin->group->lock);
if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
v4l2_async_nf_unregister(&vin->group->notifier);
v4l2_async_nf_cleanup(&vin->group->notifier);
}
- mutex_unlock(&vin->group->lock);
}
static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port,
@@ -1620,6 +1618,7 @@ static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume);
static struct platform_driver rcar_vin_driver = {
.driver = {
.name = "rcar-vin",
+ .suppress_bind_attrs = true,
.pm = &rvin_pm_ops,
.of_match_table = rvin_of_id_table,
},
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c
index 11848d0c4a55..8c939cb3073d 100644
--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
+++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
@@ -542,16 +542,27 @@ static int rcsi2_wait_phy_start(struct rcar_csi2 *priv,
static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps)
{
const struct rcsi2_mbps_reg *hsfreq;
+ const struct rcsi2_mbps_reg *hsfreq_prev = NULL;
- for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++)
+ if (mbps < priv->info->hsfreqrange->mbps)
+ dev_warn(priv->dev, "%u Mbps less than min PHY speed %u Mbps",
+ mbps, priv->info->hsfreqrange->mbps);
+
+ for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++) {
if (hsfreq->mbps >= mbps)
break;
+ hsfreq_prev = hsfreq;
+ }
if (!hsfreq->mbps) {
dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps);
return -ERANGE;
}
+ if (hsfreq_prev &&
+ ((mbps - hsfreq_prev->mbps) <= (hsfreq->mbps - mbps)))
+ hsfreq = hsfreq_prev;
+
rcsi2_write(priv, PHYPLL_REG, PHYPLL_HSFREQRANGE(hsfreq->reg));
return 0;
@@ -1097,10 +1108,17 @@ static int rcsi2_phtw_write_mbps(struct rcar_csi2 *priv, unsigned int mbps,
const struct rcsi2_mbps_reg *values, u16 code)
{
const struct rcsi2_mbps_reg *value;
+ const struct rcsi2_mbps_reg *prev_value = NULL;
- for (value = values; value->mbps; value++)
+ for (value = values; value->mbps; value++) {
if (value->mbps >= mbps)
break;
+ prev_value = value;
+ }
+
+ if (prev_value &&
+ ((mbps - prev_value->mbps) <= (value->mbps - mbps)))
+ value = prev_value;
if (!value->mbps) {
dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps);
@@ -1498,6 +1516,7 @@ static struct platform_driver rcar_csi2_pdrv = {
.probe = rcsi2_probe,
.driver = {
.name = "rcar-csi2",
+ .suppress_bind_attrs = true,
.of_match_table = rcar_csi2_of_table,
},
};
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 25ead9333d00..8136bc75e7c4 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -111,6 +111,9 @@
#define VNIE_FIE (1 << 4)
#define VNIE_EFE (1 << 1)
+/* Video n Interrupt Status Register bits */
+#define VNINTS_FIS (1 << 4)
+
/* Video n Data Mode Register bits */
#define VNDMR_A8BIT(n) (((n) & 0xff) << 24)
#define VNDMR_A8BIT_MASK (0xff << 24)
@@ -1005,6 +1008,10 @@ static irqreturn_t rvin_irq(int irq, void *data)
rvin_ack_interrupt(vin);
handled = 1;
+ /* Nothing to do if nothing was captured. */
+ if (!(int_status & VNINTS_FIS))
+ goto done;
+
/* Nothing to do if capture status is 'STOPPED' */
if (vin->state == STOPPED) {
vin_dbg(vin, "IRQ while state stopped\n");
@@ -1371,6 +1378,16 @@ void rvin_stop_streaming(struct rvin_dev *vin)
spin_unlock_irqrestore(&vin->qlock, flags);
+ /* If something went wrong, free buffers with an error. */
+ if (!buffersFreed) {
+ return_unused_buffers(vin, VB2_BUF_STATE_ERROR);
+ for (i = 0; i < HW_BUFFER_NUM; i++) {
+ if (vin->buf_hw[i].buffer)
+ vb2_buffer_done(&vin->buf_hw[i].buffer->vb2_buf,
+ VB2_BUF_STATE_ERROR);
+ }
+ }
+
rvin_set_stream(vin, 0);
/* disable interrupts */
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index a5bfa76fdac6..2e60b9fce03b 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -179,20 +179,27 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
break;
}
- /* HW limit width to a multiple of 32 (2^5) for NV12/16 else 2 (2^1) */
+ /* Hardware limits width alignment based on format. */
switch (pix->pixelformat) {
+ /* Multiple of 32 (2^5) for NV12/16. */
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV16:
walign = 5;
break;
- default:
+ /* Multiple of 2 (2^1) for YUV. */
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
walign = 1;
break;
+ /* No multiple for RGB. */
+ default:
+ walign = 0;
+ break;
}
/* Limit to VIN capabilities */
- v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign,
- &pix->height, 4, vin->info->max_height, 2, 0);
+ v4l_bound_align_image(&pix->width, 5, vin->info->max_width, walign,
+ &pix->height, 2, vin->info->max_height, 0, 0);
pix->bytesperline = rvin_format_bytesperline(vin, pix);
pix->sizeimage = rvin_format_sizeimage(pix);
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c
index 19de3c19bcca..37ecf489d112 100644
--- a/drivers/media/platform/rcar_fdp1.c
+++ b/drivers/media/platform/rcar_fdp1.c
@@ -2287,11 +2287,10 @@ static int fdp1_probe(struct platform_device *pdev)
return PTR_ERR(fdp1->regs);
/* Interrupt service routine registration */
- fdp1->irq = ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
- dev_err(&pdev->dev, "cannot find IRQ\n");
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
return ret;
- }
+ fdp1->irq = ret;
ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0,
dev_name(&pdev->dev), fdp1);
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 50b166c49a03..3f5cfa7eb937 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -462,7 +462,7 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
{
struct rkisp1_debug *debug = &rkisp1->debug;
- debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL);
+ debug->debugfs_dir = debugfs_create_dir(dev_name(rkisp1->dev), NULL);
debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
&debug->data_loss);
debugfs_create_ulong("outform_size_err", 0444, debug->debugfs_dir,
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index 32892ab359ee..6e8ef86566b7 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -291,7 +291,6 @@ static void camif_unregister_media_entities(struct camif_dev *camif)
{
camif_unregister_video_nodes(camif);
camif_unregister_sensor(camif);
- s3c_camif_unregister_subdev(camif);
}
/*
@@ -520,6 +519,7 @@ static int s3c_camif_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
camif_clk_put(camif);
+ s3c_camif_unregister_subdev(camif);
pdata->gpio_put();
return 0;
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index ebdfd24e9cd5..a8d9159d5ed8 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2425,17 +2425,17 @@ static int s5p_jpeg_job_ready(void *priv)
return 1;
}
-static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
+static const struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
.device_run = s5p_jpeg_device_run,
.job_ready = s5p_jpeg_job_ready,
};
-static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
+static const struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
.device_run = exynos3250_jpeg_device_run,
.job_ready = s5p_jpeg_job_ready,
};
-static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
+static const struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
.device_run = exynos4_jpeg_device_run,
.job_ready = s5p_jpeg_job_ready,
};
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index 8473a019bb5f..4a5fb1b15455 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -142,7 +142,7 @@ struct s5p_jpeg_variant {
unsigned int hw3250_compat:1;
unsigned int htbl_reinit:1;
unsigned int hw_ex4_compat:1;
- struct v4l2_m2m_ops *m2m_ops;
+ const struct v4l2_m2m_ops *m2m_ops;
irqreturn_t (*jpeg_irq)(int irq, void *priv);
const char *clk_names[JPEG_MAX_CLOCKS];
int num_clocks;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index fc85e4e2d020..f6732f031e96 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1185,7 +1185,6 @@ static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev)
{
struct device *dev = &mfc_dev->plat_dev->dev;
unsigned long mem_size = SZ_4M;
- unsigned int bitmap_size;
if (IS_ENABLED(CONFIG_DMA_CMA) || exynos_is_iommu_available(dev))
mem_size = SZ_8M;
@@ -1193,16 +1192,14 @@ static int s5p_mfc_configure_common_memory(struct s5p_mfc_dev *mfc_dev)
if (mfc_mem_size)
mem_size = memparse(mfc_mem_size, NULL);
- bitmap_size = BITS_TO_LONGS(mem_size >> PAGE_SHIFT) * sizeof(long);
-
- mfc_dev->mem_bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ mfc_dev->mem_bitmap = bitmap_zalloc(mem_size >> PAGE_SHIFT, GFP_KERNEL);
if (!mfc_dev->mem_bitmap)
return -ENOMEM;
mfc_dev->mem_virt = dma_alloc_coherent(dev, mem_size,
&mfc_dev->mem_base, GFP_KERNEL);
if (!mfc_dev->mem_virt) {
- kfree(mfc_dev->mem_bitmap);
+ bitmap_free(mfc_dev->mem_bitmap);
dev_err(dev, "failed to preallocate %ld MiB for the firmware and context buffers\n",
(mem_size / SZ_1M));
return -ENOMEM;
@@ -1241,7 +1238,7 @@ static void s5p_mfc_unconfigure_common_memory(struct s5p_mfc_dev *mfc_dev)
dma_free_coherent(dev, mfc_dev->mem_size, mfc_dev->mem_virt,
mfc_dev->mem_base);
- kfree(mfc_dev->mem_bitmap);
+ bitmap_free(mfc_dev->mem_bitmap);
vb2_dma_contig_clear_max_seg_size(dev);
}
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index 7d467f2ba072..01ce7b711774 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -1394,6 +1394,7 @@ err_filter:
err_pm:
pm_runtime_put(dev);
err_remove:
+ pm_runtime_disable(dev);
bdisp_debugfs_remove(bdisp);
v4l2_device_unregister(&bdisp->v4l2_dev);
err_clk:
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 02dc78bd7fab..7bb1384e4bad 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -925,17 +925,12 @@ static int c8sectpfe_remove(struct platform_device *pdev)
static int configure_channels(struct c8sectpfei *fei)
{
int index = 0, ret;
- struct channel_info *tsin;
struct device_node *child, *np = fei->dev->of_node;
/* iterate round each tsin and configure memdma descriptor and IB hw */
for_each_child_of_node(np, child) {
-
- tsin = fei->channel_data[index];
-
ret = configure_memdma_and_inputblock(fei,
fei->channel_data[index]);
-
if (ret) {
dev_err(fei->dev,
"configure_memdma_and_inputblock failed\n");
@@ -947,10 +942,9 @@ static int configure_channels(struct c8sectpfei *fei)
return 0;
err_unmap:
- for (index = 0; index < fei->tsin_count; index++) {
- tsin = fei->channel_data[index];
- free_input_block(fei, tsin);
- }
+ while (--index >= 0)
+ free_input_block(fei, fei->channel_data[index]);
+
return ret;
}
diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c
index 15e8f83b1b56..fe4ea2e7f37e 100644
--- a/drivers/media/platform/sti/hva/hva-hw.c
+++ b/drivers/media/platform/sti/hva/hva-hw.c
@@ -385,7 +385,7 @@ int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva)
ret = pm_runtime_resume_and_get(dev);
if (ret < 0) {
dev_err(dev, "%s failed to set PM\n", HVA_PREFIX);
- goto err_clk;
+ goto err_disable;
}
/* check IP hardware version */
@@ -403,6 +403,8 @@ int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva)
err_pm:
pm_runtime_put(dev);
+err_disable:
+ pm_runtime_disable(dev);
err_clk:
if (hva->clk)
clk_unprepare(hva->clk);
diff --git a/drivers/media/platform/stm32/Makefile b/drivers/media/platform/stm32/Makefile
index 48b36db2c2e2..896ef98a73ab 100644
--- a/drivers/media/platform/stm32/Makefile
+++ b/drivers/media/platform/stm32/Makefile
@@ -1,2 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o
+stm32-dma2d-objs := dma2d/dma2d.o dma2d/dma2d-hw.o
+obj-$(CONFIG_VIDEO_STM32_DMA2D) += stm32-dma2d.o
diff --git a/drivers/media/platform/stm32/dma2d/dma2d-hw.c b/drivers/media/platform/stm32/dma2d/dma2d-hw.c
new file mode 100644
index 000000000000..ea4cc84d8a39
--- /dev/null
+++ b/drivers/media/platform/stm32/dma2d/dma2d-hw.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * ST stm32 Chrom-Art - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2021 Dillon Min
+ * Dillon Min, <dillon.minfei@gmail.com>
+ *
+ * based on s5p-g2d
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ */
+
+#include <linux/io.h>
+
+#include "dma2d.h"
+#include "dma2d-regs.h"
+
+static inline u32 reg_read(void __iomem *base, u32 reg)
+{
+ return readl_relaxed(base + reg);
+}
+
+static inline void reg_write(void __iomem *base, u32 reg, u32 val)
+{
+ writel_relaxed(val, base + reg);
+}
+
+static inline void reg_update_bits(void __iomem *base, u32 reg, u32 mask,
+ u32 val)
+{
+ reg_write(base, reg, (reg_read(base, reg) & ~mask) | val);
+}
+
+void dma2d_start(struct dma2d_dev *d)
+{
+ reg_update_bits(d->regs, DMA2D_CR_REG, CR_START, CR_START);
+}
+
+u32 dma2d_get_int(struct dma2d_dev *d)
+{
+ return reg_read(d->regs, DMA2D_ISR_REG);
+}
+
+void dma2d_clear_int(struct dma2d_dev *d)
+{
+ u32 isr_val = reg_read(d->regs, DMA2D_ISR_REG);
+
+ reg_write(d->regs, DMA2D_IFCR_REG, isr_val & 0x003f);
+}
+
+void dma2d_config_common(struct dma2d_dev *d, enum dma2d_op_mode op_mode,
+ u16 width, u16 height)
+{
+ reg_update_bits(d->regs, DMA2D_CR_REG, CR_MODE_MASK,
+ op_mode << CR_MODE_SHIFT);
+
+ reg_write(d->regs, DMA2D_NLR_REG, (width << 16) | height);
+}
+
+void dma2d_config_out(struct dma2d_dev *d, struct dma2d_frame *frm,
+ dma_addr_t o_addr)
+{
+ reg_update_bits(d->regs, DMA2D_CR_REG, CR_CEIE, CR_CEIE);
+ reg_update_bits(d->regs, DMA2D_CR_REG, CR_CTCIE, CR_CTCIE);
+ reg_update_bits(d->regs, DMA2D_CR_REG, CR_CAEIE, CR_CAEIE);
+ reg_update_bits(d->regs, DMA2D_CR_REG, CR_TCIE, CR_TCIE);
+ reg_update_bits(d->regs, DMA2D_CR_REG, CR_TEIE, CR_TEIE);
+
+ if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
+ frm->fmt->cmode <= CM_MODE_ARGB4444)
+ reg_update_bits(d->regs, DMA2D_OPFCCR_REG, OPFCCR_CM_MASK,
+ frm->fmt->cmode);
+
+ reg_write(d->regs, DMA2D_OMAR_REG, o_addr);
+
+ reg_write(d->regs, DMA2D_OCOLR_REG,
+ (frm->a_rgb[3] << 24) |
+ (frm->a_rgb[2] << 16) |
+ (frm->a_rgb[1] << 8) |
+ frm->a_rgb[0]);
+
+ reg_update_bits(d->regs, DMA2D_OOR_REG, OOR_LO_MASK,
+ frm->line_offset & 0x3fff);
+}
+
+void dma2d_config_fg(struct dma2d_dev *d, struct dma2d_frame *frm,
+ dma_addr_t f_addr)
+{
+ reg_write(d->regs, DMA2D_FGMAR_REG, f_addr);
+ reg_update_bits(d->regs, DMA2D_FGOR_REG, FGOR_LO_MASK,
+ frm->line_offset);
+
+ if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
+ frm->fmt->cmode <= CM_MODE_A4)
+ reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_CM_MASK,
+ frm->fmt->cmode);
+
+ reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_AM_MASK,
+ (frm->a_mode << 16) & 0x03);
+
+ reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_ALPHA_MASK,
+ frm->a_rgb[3] << 24);
+
+ reg_write(d->regs, DMA2D_FGCOLR_REG,
+ (frm->a_rgb[2] << 16) |
+ (frm->a_rgb[1] << 8) |
+ frm->a_rgb[0]);
+}
+
+void dma2d_config_bg(struct dma2d_dev *d, struct dma2d_frame *frm,
+ dma_addr_t b_addr)
+{
+ reg_write(d->regs, DMA2D_BGMAR_REG, b_addr);
+ reg_update_bits(d->regs, DMA2D_BGOR_REG, BGOR_LO_MASK,
+ frm->line_offset);
+
+ if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
+ frm->fmt->cmode <= CM_MODE_A4)
+ reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_CM_MASK,
+ frm->fmt->cmode);
+
+ reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_AM_MASK,
+ (frm->a_mode << 16) & 0x03);
+
+ reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_ALPHA_MASK,
+ frm->a_rgb[3] << 24);
+
+ reg_write(d->regs, DMA2D_BGCOLR_REG,
+ (frm->a_rgb[2] << 16) |
+ (frm->a_rgb[1] << 8) |
+ frm->a_rgb[0]);
+}
diff --git a/drivers/media/platform/stm32/dma2d/dma2d-regs.h b/drivers/media/platform/stm32/dma2d/dma2d-regs.h
new file mode 100644
index 000000000000..6444592d415b
--- /dev/null
+++ b/drivers/media/platform/stm32/dma2d/dma2d-regs.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * ST stm32 Chrom-Art - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2021 Dillon Min
+ * Dillon Min, <dillon.minfei@gmail.com>
+ *
+ * based on s5p-g2d
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ */
+
+#ifndef __DMA2D_REGS_H__
+#define __DMA2D_REGS_H__
+
+#define DMA2D_CR_REG 0x0000
+#define CR_MODE_MASK GENMASK(17, 16)
+#define CR_MODE_SHIFT 16
+#define CR_M2M 0x0000
+#define CR_M2M_PFC BIT(16)
+#define CR_M2M_BLEND BIT(17)
+#define CR_R2M (BIT(17) | BIT(16))
+#define CR_CEIE BIT(13)
+#define CR_CTCIE BIT(12)
+#define CR_CAEIE BIT(11)
+#define CR_TWIE BIT(10)
+#define CR_TCIE BIT(9)
+#define CR_TEIE BIT(8)
+#define CR_ABORT BIT(2)
+#define CR_SUSP BIT(1)
+#define CR_START BIT(0)
+
+#define DMA2D_ISR_REG 0x0004
+#define ISR_CEIF BIT(5)
+#define ISR_CTCIF BIT(4)
+#define ISR_CAEIF BIT(3)
+#define ISR_TWIF BIT(2)
+#define ISR_TCIF BIT(1)
+#define ISR_TEIF BIT(0)
+
+#define DMA2D_IFCR_REG 0x0008
+#define IFCR_CCEIF BIT(5)
+#define IFCR_CCTCIF BIT(4)
+#define IFCR_CAECIF BIT(3)
+#define IFCR_CTWIF BIT(2)
+#define IFCR_CTCIF BIT(1)
+#define IFCR_CTEIF BIT(0)
+
+#define DMA2D_FGMAR_REG 0x000c
+#define DMA2D_FGOR_REG 0x0010
+#define FGOR_LO_MASK GENMASK(13, 0)
+
+#define DMA2D_BGMAR_REG 0x0014
+#define DMA2D_BGOR_REG 0x0018
+#define BGOR_LO_MASK GENMASK(13, 0)
+
+#define DMA2D_FGPFCCR_REG 0x001c
+#define FGPFCCR_ALPHA_MASK GENMASK(31, 24)
+#define FGPFCCR_AM_MASK GENMASK(17, 16)
+#define FGPFCCR_CS_MASK GENMASK(15, 8)
+#define FGPFCCR_START BIT(5)
+#define FGPFCCR_CCM_RGB888 BIT(4)
+#define FGPFCCR_CM_MASK GENMASK(3, 0)
+
+#define DMA2D_FGCOLR_REG 0x0020
+#define FGCOLR_REG_MASK GENMASK(23, 16)
+#define FGCOLR_GREEN_MASK GENMASK(15, 8)
+#define FGCOLR_BLUE_MASK GENMASK(7, 0)
+
+#define DMA2D_BGPFCCR_REG 0x0024
+#define BGPFCCR_ALPHA_MASK GENMASK(31, 24)
+#define BGPFCCR_AM_MASK GENMASK(17, 16)
+#define BGPFCCR_CS_MASK GENMASK(15, 8)
+#define BGPFCCR_START BIT(5)
+#define BGPFCCR_CCM_RGB888 BIT(4)
+#define BGPFCCR_CM_MASK GENMASK(3, 0)
+
+#define DMA2D_BGCOLR_REG 0x0028
+#define BGCOLR_REG_MASK GENMASK(23, 16)
+#define BGCOLR_GREEN_MASK GENMASK(15, 8)
+#define BGCOLR_BLUE_MASK GENMASK(7, 0)
+
+#define DMA2D_OPFCCR_REG 0x0034
+#define OPFCCR_CM_MASK GENMASK(2, 0)
+
+#define DMA2D_OCOLR_REG 0x0038
+#define OCOLR_ALPHA_MASK GENMASK(31, 24)
+#define OCOLR_RED_MASK GENMASK(23, 16)
+#define OCOLR_GREEN_MASK GENMASK(15, 8)
+#define OCOLR_BLUE_MASK GENMASK(7, 0)
+
+#define DMA2D_OMAR_REG 0x003c
+
+#define DMA2D_OOR_REG 0x0040
+#define OOR_LO_MASK GENMASK(13, 0)
+
+#define DMA2D_NLR_REG 0x0044
+#define NLR_PL_MASK GENMASK(29, 16)
+#define NLR_NL_MASK GENMASK(15, 0)
+
+/* Hardware limits */
+#define MAX_WIDTH 2592
+#define MAX_HEIGHT 2592
+
+#define DEFAULT_WIDTH 240
+#define DEFAULT_HEIGHT 320
+#define DEFAULT_SIZE 307200
+
+#define CM_MODE_ARGB8888 0x00
+#define CM_MODE_ARGB4444 0x04
+#define CM_MODE_A4 0x0a
+#endif /* __DMA2D_REGS_H__ */
diff --git a/drivers/media/platform/stm32/dma2d/dma2d.c b/drivers/media/platform/stm32/dma2d/dma2d.c
new file mode 100644
index 000000000000..17af90d86898
--- /dev/null
+++ b/drivers/media/platform/stm32/dma2d/dma2d.c
@@ -0,0 +1,739 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * STM32 DMA2D - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2021 Dillon Min
+ * Dillon Min, <dillon.minfei@gmail.com>
+ *
+ * based on s5p-g2d
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "dma2d.h"
+#include "dma2d-regs.h"
+
+/*
+ * This V4L2 subdev m2m driver enables Chrom-Art Accelerator unit
+ * of STMicroelectronics STM32 SoC series.
+ *
+ * Currently support r2m, m2m, m2m_pfc.
+ *
+ * - r2m, Filling a part or the whole of a destination image with a specific
+ * color.
+ * - m2m, Copying a part or the whole of a source image into a part or the
+ * whole of a destination.
+ * - m2m_pfc, Copying a part or the whole of a source image into a part or the
+ * whole of a destination image with a pixel format conversion.
+ */
+
+#define fh2ctx(__fh) container_of(__fh, struct dma2d_ctx, fh)
+
+static const struct dma2d_fmt formats[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB32,
+ .cmode = DMA2D_CMODE_ARGB8888,
+ .depth = 32,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_RGB24,
+ .cmode = DMA2D_CMODE_RGB888,
+ .depth = 24,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .cmode = DMA2D_CMODE_RGB565,
+ .depth = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB555,
+ .cmode = DMA2D_CMODE_ARGB1555,
+ .depth = 16,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_ARGB444,
+ .cmode = DMA2D_CMODE_ARGB4444,
+ .depth = 16,
+ },
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static const struct dma2d_frame def_frame = {
+ .width = DEFAULT_WIDTH,
+ .height = DEFAULT_HEIGHT,
+ .line_offset = 0,
+ .a_rgb = {0x00, 0x00, 0x00, 0xff},
+ .a_mode = DMA2D_ALPHA_MODE_NO_MODIF,
+ .fmt = (struct dma2d_fmt *)&formats[0],
+ .size = DEFAULT_SIZE,
+};
+
+static struct dma2d_fmt *find_fmt(int pixelformat)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].fourcc == pixelformat)
+ return (struct dma2d_fmt *)&formats[i];
+ }
+
+ return NULL;
+}
+
+static struct dma2d_frame *get_frame(struct dma2d_ctx *ctx,
+ enum v4l2_buf_type type)
+{
+ return V4L2_TYPE_IS_OUTPUT(type) ? &ctx->cap : &ctx->out;
+}
+
+static int dma2d_queue_setup(struct vb2_queue *vq,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct dma2d_ctx *ctx = vb2_get_drv_priv(vq);
+ struct dma2d_frame *f = get_frame(ctx, vq->type);
+
+ if (*nplanes)
+ return sizes[0] < f->size ? -EINVAL : 0;
+
+ sizes[0] = f->size;
+ *nplanes = 1;
+
+ return 0;
+}
+
+static int dma2d_buf_out_validate(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+ if (vbuf->field == V4L2_FIELD_ANY)
+ vbuf->field = V4L2_FIELD_NONE;
+ if (vbuf->field != V4L2_FIELD_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int dma2d_buf_prepare(struct vb2_buffer *vb)
+{
+ struct dma2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct dma2d_frame *f = get_frame(ctx, vb->vb2_queue->type);
+
+ if (vb2_plane_size(vb, 0) < f->size)
+ return -EINVAL;
+
+ vb2_set_plane_payload(vb, 0, f->size);
+
+ return 0;
+}
+
+static void dma2d_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct dma2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
+}
+
+static int dma2d_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+ struct dma2d_ctx *ctx = vb2_get_drv_priv(q);
+ struct dma2d_frame *f = get_frame(ctx, q->type);
+
+ f->sequence = 0;
+ return 0;
+}
+
+static void dma2d_stop_streaming(struct vb2_queue *q)
+{
+ struct dma2d_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, VB2_BUF_STATE_ERROR);
+ }
+}
+
+static const struct vb2_ops dma2d_qops = {
+ .queue_setup = dma2d_queue_setup,
+ .buf_out_validate = dma2d_buf_out_validate,
+ .buf_prepare = dma2d_buf_prepare,
+ .buf_queue = dma2d_buf_queue,
+ .start_streaming = dma2d_start_streaming,
+ .stop_streaming = dma2d_stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq)
+{
+ struct dma2d_ctx *ctx = priv;
+ int ret;
+
+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ src_vq->drv_priv = ctx;
+ src_vq->ops = &dma2d_qops;
+ src_vq->mem_ops = &vb2_dma_contig_memops;
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->lock = &ctx->dev->mutex;
+ src_vq->dev = ctx->dev->v4l2_dev.dev;
+
+ ret = vb2_queue_init(src_vq);
+ if (ret)
+ return ret;
+
+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+ dst_vq->drv_priv = ctx;
+ dst_vq->ops = &dma2d_qops;
+ dst_vq->mem_ops = &vb2_dma_contig_memops;
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->lock = &ctx->dev->mutex;
+ dst_vq->dev = ctx->dev->v4l2_dev.dev;
+
+ return vb2_queue_init(dst_vq);
+}
+
+static int dma2d_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct dma2d_frame *frm;
+ struct dma2d_ctx *ctx = container_of(ctrl->handler, struct dma2d_ctx,
+ ctrl_handler);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->dev->ctrl_lock, flags);
+ switch (ctrl->id) {
+ case V4L2_CID_COLORFX:
+ if (ctrl->val == V4L2_COLORFX_SET_RGB)
+ ctx->op_mode = DMA2D_MODE_R2M;
+ else if (ctrl->val == V4L2_COLORFX_NONE)
+ ctx->op_mode = DMA2D_MODE_M2M;
+ break;
+ case V4L2_CID_COLORFX_RGB:
+ frm = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ frm->a_rgb[2] = (ctrl->val >> 16) & 0xff;
+ frm->a_rgb[1] = (ctrl->val >> 8) & 0xff;
+ frm->a_rgb[0] = (ctrl->val >> 0) & 0xff;
+ break;
+ default:
+ spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
+ return -EINVAL;
+ }
+ spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops dma2d_ctrl_ops = {
+ .s_ctrl = dma2d_s_ctrl,
+};
+
+static int dma2d_setup_ctrls(struct dma2d_ctx *ctx)
+{
+ struct v4l2_ctrl_handler *handler = &ctx->ctrl_handler;
+
+ v4l2_ctrl_handler_init(handler, 2);
+
+ v4l2_ctrl_new_std_menu(handler, &dma2d_ctrl_ops, V4L2_CID_COLORFX,
+ V4L2_COLORFX_SET_RGB, ~0x10001,
+ V4L2_COLORFX_NONE);
+
+ v4l2_ctrl_new_std(handler, &dma2d_ctrl_ops, V4L2_CID_COLORFX_RGB, 0,
+ 0xffffff, 1, 0);
+
+ return 0;
+}
+
+static int dma2d_open(struct file *file)
+{
+ struct dma2d_dev *dev = video_drvdata(file);
+ struct dma2d_ctx *ctx = NULL;
+ int ret = 0;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->dev = dev;
+ /* Set default formats */
+ ctx->cap = def_frame;
+ ctx->bg = def_frame;
+ ctx->out = def_frame;
+ ctx->op_mode = DMA2D_MODE_M2M_FPC;
+ ctx->colorspace = V4L2_COLORSPACE_REC709;
+ if (mutex_lock_interruptible(&dev->mutex)) {
+ kfree(ctx);
+ return -ERESTARTSYS;
+ }
+
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
+ if (IS_ERR(ctx->fh.m2m_ctx)) {
+ ret = PTR_ERR(ctx->fh.m2m_ctx);
+ mutex_unlock(&dev->mutex);
+ kfree(ctx);
+ return ret;
+ }
+
+ v4l2_fh_init(&ctx->fh, video_devdata(file));
+ file->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+
+ dma2d_setup_ctrls(ctx);
+
+ /* Write the default values to the ctx struct */
+ v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
+
+ ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+ mutex_unlock(&dev->mutex);
+
+ return 0;
+}
+
+static int dma2d_release(struct file *file)
+{
+ struct dma2d_dev *dev = video_drvdata(file);
+ struct dma2d_ctx *ctx = fh2ctx(file->private_data);
+
+ mutex_lock(&dev->mutex);
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+ mutex_unlock(&dev->mutex);
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+ kfree(ctx);
+
+ return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ strscpy(cap->driver, DMA2D_NAME, sizeof(cap->driver));
+ strscpy(cap->card, DMA2D_NAME, sizeof(cap->card));
+ strscpy(cap->bus_info, BUS_INFO, sizeof(cap->bus_info));
+
+ return 0;
+}
+
+static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
+{
+ if (f->index >= NUM_FORMATS)
+ return -EINVAL;
+
+ f->pixelformat = formats[f->index].fourcc;
+ return 0;
+}
+
+static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+ struct dma2d_ctx *ctx = prv;
+ struct vb2_queue *vq;
+ struct dma2d_frame *frm;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (!vq)
+ return -EINVAL;
+
+ frm = get_frame(ctx, f->type);
+ f->fmt.pix.width = frm->width;
+ f->fmt.pix.height = frm->height;
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+ f->fmt.pix.pixelformat = frm->fmt->fourcc;
+ f->fmt.pix.bytesperline = (frm->width * frm->fmt->depth) >> 3;
+ f->fmt.pix.sizeimage = frm->size;
+ f->fmt.pix.colorspace = ctx->colorspace;
+ f->fmt.pix.xfer_func = ctx->xfer_func;
+ f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
+ f->fmt.pix.quantization = ctx->quant;
+
+ return 0;
+}
+
+static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+ struct dma2d_ctx *ctx = prv;
+ struct dma2d_fmt *fmt;
+ enum v4l2_field *field;
+ u32 fourcc = f->fmt.pix.pixelformat;
+
+ fmt = find_fmt(fourcc);
+ if (!fmt) {
+ f->fmt.pix.pixelformat = formats[0].fourcc;
+ fmt = find_fmt(f->fmt.pix.pixelformat);
+ }
+
+ field = &f->fmt.pix.field;
+ if (*field == V4L2_FIELD_ANY)
+ *field = V4L2_FIELD_NONE;
+ else if (*field != V4L2_FIELD_NONE)
+ return -EINVAL;
+
+ if (f->fmt.pix.width > MAX_WIDTH)
+ f->fmt.pix.width = MAX_WIDTH;
+ if (f->fmt.pix.height > MAX_HEIGHT)
+ f->fmt.pix.height = MAX_HEIGHT;
+
+ if (f->fmt.pix.width < 1)
+ f->fmt.pix.width = 1;
+ if (f->fmt.pix.height < 1)
+ f->fmt.pix.height = 1;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && !f->fmt.pix.colorspace) {
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+ } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ f->fmt.pix.colorspace = ctx->colorspace;
+ f->fmt.pix.xfer_func = ctx->xfer_func;
+ f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
+ f->fmt.pix.quantization = ctx->quant;
+ }
+ f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
+ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
+ return 0;
+}
+
+static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+ struct dma2d_ctx *ctx = prv;
+ struct vb2_queue *vq;
+ struct dma2d_frame *frm;
+ struct dma2d_fmt *fmt;
+ int ret = 0;
+
+ /* Adjust all values accordingly to the hardware capabilities
+ * and chosen format.
+ */
+ ret = vidioc_try_fmt(file, prv, f);
+ if (ret)
+ return ret;
+
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+ if (vb2_is_busy(vq))
+ return -EBUSY;
+
+ fmt = find_fmt(f->fmt.pix.pixelformat);
+ if (!fmt)
+ return -EINVAL;
+
+ if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+ ctx->colorspace = f->fmt.pix.colorspace;
+ ctx->xfer_func = f->fmt.pix.xfer_func;
+ ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
+ ctx->quant = f->fmt.pix.quantization;
+ }
+
+ frm = get_frame(ctx, f->type);
+ frm->width = f->fmt.pix.width;
+ frm->height = f->fmt.pix.height;
+ frm->size = f->fmt.pix.sizeimage;
+ /* Reset crop settings */
+ frm->o_width = 0;
+ frm->o_height = 0;
+ frm->c_width = frm->width;
+ frm->c_height = frm->height;
+ frm->right = frm->width;
+ frm->bottom = frm->height;
+ frm->fmt = fmt;
+ frm->line_offset = 0;
+
+ return 0;
+}
+
+static void device_run(void *prv)
+{
+ struct dma2d_ctx *ctx = prv;
+ struct dma2d_dev *dev = ctx->dev;
+ struct dma2d_frame *frm_out, *frm_cap;
+ struct vb2_v4l2_buffer *src, *dst;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->ctrl_lock, flags);
+ dev->curr = ctx;
+
+ src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+ if (!dst || !src)
+ goto end;
+
+ frm_cap = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ frm_out = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ if (!frm_cap || !frm_out)
+ goto end;
+
+ src->sequence = frm_out->sequence++;
+ dst->sequence = frm_cap->sequence++;
+ v4l2_m2m_buf_copy_metadata(src, dst, true);
+
+ clk_enable(dev->gate);
+
+ dma2d_config_fg(dev, frm_out,
+ vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0));
+
+ /* TODO: add M2M_BLEND handler here */
+
+ if (ctx->op_mode != DMA2D_MODE_R2M) {
+ if (frm_out->fmt->fourcc == frm_cap->fmt->fourcc)
+ ctx->op_mode = DMA2D_MODE_M2M;
+ else
+ ctx->op_mode = DMA2D_MODE_M2M_FPC;
+ }
+
+ dma2d_config_out(dev, frm_cap,
+ vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0));
+ dma2d_config_common(dev, ctx->op_mode, frm_cap->width, frm_cap->height);
+
+ dma2d_start(dev);
+end:
+ spin_unlock_irqrestore(&dev->ctrl_lock, flags);
+}
+
+static irqreturn_t dma2d_isr(int irq, void *prv)
+{
+ struct dma2d_dev *dev = prv;
+ struct dma2d_ctx *ctx = dev->curr;
+ struct vb2_v4l2_buffer *src, *dst;
+ u32 s = dma2d_get_int(dev);
+
+ dma2d_clear_int(dev);
+ if (s & ISR_TCIF || s == 0) {
+ clk_disable(dev->gate);
+
+ WARN_ON(!ctx);
+
+ src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+
+ WARN_ON(!dst);
+ WARN_ON(!src);
+
+ v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
+ v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
+ v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
+
+ dev->curr = NULL;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static const struct v4l2_file_operations dma2d_fops = {
+ .owner = THIS_MODULE,
+ .open = dma2d_open,
+ .release = dma2d_release,
+ .poll = v4l2_m2m_fop_poll,
+ .unlocked_ioctl = video_ioctl2,
+ .mmap = v4l2_m2m_fop_mmap,
+#ifndef CONFIG_MMU
+ .get_unmapped_area = v4l2_m2m_get_unmapped_area,
+#endif
+};
+
+static const struct v4l2_ioctl_ops dma2d_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt,
+
+ .vidioc_enum_fmt_vid_out = vidioc_enum_fmt,
+ .vidioc_g_fmt_vid_out = vidioc_g_fmt,
+ .vidioc_try_fmt_vid_out = vidioc_try_fmt,
+ .vidioc_s_fmt_vid_out = vidioc_s_fmt,
+
+ .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 const struct video_device dma2d_videodev = {
+ .name = DMA2D_NAME,
+ .fops = &dma2d_fops,
+ .ioctl_ops = &dma2d_ioctl_ops,
+ .minor = -1,
+ .release = video_device_release,
+ .vfl_dir = VFL_DIR_M2M,
+};
+
+static const struct v4l2_m2m_ops dma2d_m2m_ops = {
+ .device_run = device_run,
+};
+
+static const struct of_device_id stm32_dma2d_match[];
+
+static int dma2d_probe(struct platform_device *pdev)
+{
+ struct dma2d_dev *dev;
+ struct video_device *vfd;
+ struct resource *res;
+ int ret = 0;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ spin_lock_init(&dev->ctrl_lock);
+ mutex_init(&dev->mutex);
+ atomic_set(&dev->num_inst, 0);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ dev->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dev->regs))
+ return PTR_ERR(dev->regs);
+
+ dev->gate = clk_get(&pdev->dev, "dma2d");
+ if (IS_ERR(dev->gate)) {
+ dev_err(&pdev->dev, "failed to get dma2d clock gate\n");
+ ret = -ENXIO;
+ return ret;
+ }
+
+ ret = clk_prepare(dev->gate);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to prepare dma2d clock gate\n");
+ goto put_clk_gate;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to find IRQ\n");
+ ret = -ENXIO;
+ goto unprep_clk_gate;
+ }
+
+ dev->irq = res->start;
+
+ ret = devm_request_irq(&pdev->dev, dev->irq, dma2d_isr,
+ 0, pdev->name, dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to install IRQ\n");
+ goto unprep_clk_gate;
+ }
+
+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+ if (ret)
+ goto unprep_clk_gate;
+
+ vfd = video_device_alloc();
+ if (!vfd) {
+ v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
+ ret = -ENOMEM;
+ goto unreg_v4l2_dev;
+ }
+
+ *vfd = dma2d_videodev;
+ vfd->lock = &dev->mutex;
+ vfd->v4l2_dev = &dev->v4l2_dev;
+ vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
+
+ platform_set_drvdata(pdev, dev);
+ dev->m2m_dev = v4l2_m2m_init(&dma2d_m2m_ops);
+ if (IS_ERR(dev->m2m_dev)) {
+ v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
+ ret = PTR_ERR(dev->m2m_dev);
+ goto rel_vdev;
+ }
+
+ ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+ goto free_m2m;
+ }
+
+ video_set_drvdata(vfd, dev);
+ dev->vfd = vfd;
+ v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
+ vfd->num);
+ return 0;
+
+free_m2m:
+ v4l2_m2m_release(dev->m2m_dev);
+rel_vdev:
+ video_device_release(vfd);
+unreg_v4l2_dev:
+ v4l2_device_unregister(&dev->v4l2_dev);
+unprep_clk_gate:
+ clk_unprepare(dev->gate);
+put_clk_gate:
+ clk_put(dev->gate);
+
+ return ret;
+}
+
+static int dma2d_remove(struct platform_device *pdev)
+{
+ struct dma2d_dev *dev = platform_get_drvdata(pdev);
+
+ v4l2_info(&dev->v4l2_dev, "Removing " DMA2D_NAME);
+ v4l2_m2m_release(dev->m2m_dev);
+ video_unregister_device(dev->vfd);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+ clk_unprepare(dev->gate);
+ clk_put(dev->gate);
+
+ return 0;
+}
+
+static const struct of_device_id stm32_dma2d_match[] = {
+ {
+ .compatible = "st,stm32-dma2d",
+ .data = NULL,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, stm32_dma2d_match);
+
+static struct platform_driver dma2d_pdrv = {
+ .probe = dma2d_probe,
+ .remove = dma2d_remove,
+ .driver = {
+ .name = DMA2D_NAME,
+ .of_match_table = stm32_dma2d_match,
+ },
+};
+
+module_platform_driver(dma2d_pdrv);
+
+MODULE_AUTHOR("Dillon Min <dillon.minfei@gmail.com>");
+MODULE_DESCRIPTION("STM32 Chrom-Art Accelerator DMA2D driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/stm32/dma2d/dma2d.h b/drivers/media/platform/stm32/dma2d/dma2d.h
new file mode 100644
index 000000000000..3f03a7ca9ee3
--- /dev/null
+++ b/drivers/media/platform/stm32/dma2d/dma2d.h
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * ST stm32 DMA2D - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2021 Dillon Min
+ * Dillon Min, <dillon.minfei@gmail.com>
+ *
+ * based on s5p-g2d
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ */
+
+#ifndef __DMA2D_H__
+#define __DMA2D_H__
+
+#include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define DMA2D_NAME "stm-dma2d"
+#define BUS_INFO "platform:stm-dma2d"
+enum dma2d_op_mode {
+ DMA2D_MODE_M2M,
+ DMA2D_MODE_M2M_FPC,
+ DMA2D_MODE_M2M_BLEND,
+ DMA2D_MODE_R2M
+};
+
+enum dma2d_cmode {
+ /* output pfc cmode from ARGB888 to ARGB4444 */
+ DMA2D_CMODE_ARGB8888,
+ DMA2D_CMODE_RGB888,
+ DMA2D_CMODE_RGB565,
+ DMA2D_CMODE_ARGB1555,
+ DMA2D_CMODE_ARGB4444,
+ /* bg or fg pfc cmode from L8 to A4 */
+ DMA2D_CMODE_L8,
+ DMA2D_CMODE_AL44,
+ DMA2D_CMODE_AL88,
+ DMA2D_CMODE_L4,
+ DMA2D_CMODE_A8,
+ DMA2D_CMODE_A4
+};
+
+enum dma2d_alpha_mode {
+ DMA2D_ALPHA_MODE_NO_MODIF,
+ DMA2D_ALPHA_MODE_REPLACE,
+ DMA2D_ALPHA_MODE_COMBINE
+};
+
+struct dma2d_fmt {
+ u32 fourcc;
+ int depth;
+ enum dma2d_cmode cmode;
+};
+
+struct dma2d_frame {
+ /* Original dimensions */
+ u32 width;
+ u32 height;
+ /* Crop size */
+ u32 c_width;
+ u32 c_height;
+ /* Offset */
+ u32 o_width;
+ u32 o_height;
+ u32 bottom;
+ u32 right;
+ u16 line_offset;
+ /* Image format */
+ struct dma2d_fmt *fmt;
+ /* [0]: blue
+ * [1]: green
+ * [2]: red
+ * [3]: alpha
+ */
+ u8 a_rgb[4];
+ /*
+ * AM[1:0] of DMA2D_FGPFCCR
+ */
+ enum dma2d_alpha_mode a_mode;
+ u32 size;
+ unsigned int sequence;
+};
+
+struct dma2d_ctx {
+ struct v4l2_fh fh;
+ struct dma2d_dev *dev;
+ struct dma2d_frame cap;
+ struct dma2d_frame out;
+ struct dma2d_frame bg;
+ /* fb_buf always point to bg address */
+ struct v4l2_framebuffer fb_buf;
+ /*
+ * MODE[17:16] of DMA2D_CR
+ */
+ enum dma2d_op_mode op_mode;
+ struct v4l2_ctrl_handler ctrl_handler;
+ enum v4l2_colorspace colorspace;
+ enum v4l2_ycbcr_encoding ycbcr_enc;
+ enum v4l2_xfer_func xfer_func;
+ enum v4l2_quantization quant;
+};
+
+struct dma2d_dev {
+ struct v4l2_device v4l2_dev;
+ struct v4l2_m2m_dev *m2m_dev;
+ struct video_device *vfd;
+ /* for device open/close etc */
+ struct mutex mutex;
+ /* to avoid the conflict with device running and user setting
+ * at the same time
+ */
+ spinlock_t ctrl_lock;
+ atomic_t num_inst;
+ void __iomem *regs;
+ struct clk *gate;
+ struct dma2d_ctx *curr;
+ int irq;
+};
+
+void dma2d_start(struct dma2d_dev *d);
+u32 dma2d_get_int(struct dma2d_dev *d);
+void dma2d_clear_int(struct dma2d_dev *d);
+void dma2d_config_out(struct dma2d_dev *d, struct dma2d_frame *frm,
+ dma_addr_t o_addr);
+void dma2d_config_fg(struct dma2d_dev *d, struct dma2d_frame *frm,
+ dma_addr_t f_addr);
+void dma2d_config_bg(struct dma2d_dev *d, struct dma2d_frame *frm,
+ dma_addr_t b_addr);
+void dma2d_config_common(struct dma2d_dev *d, enum dma2d_op_mode op_mode,
+ u16 width, u16 height);
+
+#endif /* __DMA2D_H__ */
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index b39a68f83c5f..0bf99e1cd1d8 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -313,12 +313,6 @@ struct si476x_radio {
};
static inline struct si476x_radio *
-v4l2_dev_to_radio(struct v4l2_device *d)
-{
- return container_of(d, struct si476x_radio, v4l2dev);
-}
-
-static inline struct si476x_radio *
v4l2_ctrl_handler_to_radio(struct v4l2_ctrl_handler *d)
{
return container_of(d, struct si476x_radio, ctrl_handler);
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index a972c0705ac7..59b3d77e282d 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -334,7 +334,6 @@ static int si470x_i2c_probe(struct i2c_client *client)
{
struct si470x_device *radio;
int retval = 0;
- unsigned char version_warning = 0;
/* private data allocation and initialization */
radio = devm_kzalloc(&client->dev, sizeof(*radio), GFP_KERNEL);
@@ -368,7 +367,7 @@ static int si470x_i2c_probe(struct i2c_client *client)
if (radio->hdl.error) {
retval = radio->hdl.error;
dev_err(&client->dev, "couldn't register control\n");
- goto err_dev;
+ goto err_all;
}
/* video device initialization */
@@ -410,20 +409,10 @@ static int si470x_i2c_probe(struct i2c_client *client)
radio->registers[DEVICEID], radio->registers[SI_CHIPID]);
if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
dev_warn(&client->dev,
- "This driver is known to work with firmware version %hu,\n",
- RADIO_FW_VERSION);
- dev_warn(&client->dev,
- "but the device has firmware version %hu.\n",
+ "This driver is known to work with firmware version %u, but the device has firmware version %u.\n"
+ "If you have some trouble using this driver, please report to V4L ML at linux-media@vger.kernel.org\n",
+ RADIO_FW_VERSION,
radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE);
- version_warning = 1;
- }
-
- /* give out version warning */
- if (version_warning == 1) {
- dev_warn(&client->dev,
- "If you have some trouble using this driver,\n");
- dev_warn(&client->dev,
- "please report to V4L ML at linux-media@vger.kernel.org\n");
}
/* set initial frequency */
@@ -463,7 +452,6 @@ static int si470x_i2c_probe(struct i2c_client *client)
return 0;
err_all:
v4l2_ctrl_handler_free(&radio->hdl);
-err_dev:
v4l2_device_unregister(&radio->v4l2_dev);
err_initial:
return retval;
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index 3f8634a46573..6b2768623c88 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -681,10 +681,8 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
radio->registers[DEVICEID], radio->registers[SI_CHIPID]);
if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
dev_warn(&intf->dev,
- "This driver is known to work with firmware version %hu,\n",
- RADIO_FW_VERSION);
- dev_warn(&intf->dev,
- "but the device has firmware version %hu.\n",
+ "This driver is known to work with firmware version %u, but the device has firmware version %u.\n",
+ RADIO_FW_VERSION,
radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE);
version_warning = 1;
}
@@ -698,10 +696,8 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
radio->software_version, radio->hardware_version);
if (radio->hardware_version < RADIO_HW_VERSION) {
dev_warn(&intf->dev,
- "This driver is known to work with hardware version %hu,\n",
- RADIO_HW_VERSION);
- dev_warn(&intf->dev,
- "but the device has hardware version %hu.\n",
+ "This driver is known to work with hardware version %u, but the device has hardware version %u.\n",
+ RADIO_HW_VERSION,
radio->hardware_version);
version_warning = 1;
}
@@ -709,9 +705,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
/* give out version warning */
if (version_warning == 1) {
dev_warn(&intf->dev,
- "If you have some trouble using this driver,\n");
- dev_warn(&intf->dev,
- "please report to V4L ML at linux-media@vger.kernel.org\n");
+ "If you have some trouble using this driver, please report to V4L ML at linux-media@vger.kernel.org\n");
}
/* set led to connect state */
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 9506baf3c4c1..c111af820ae4 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -175,7 +175,7 @@ config IR_ENE
config IR_HIX5HD2
tristate "Hisilicon hix5hd2 IR remote control"
- depends on OF || COMPILE_TEST
+ depends on (OF && HAS_IOMEM) || COMPILE_TEST
help
Say Y here if you want to use hisilicon hix5hd2 remote control.
To compile this driver as a module, choose M here: the module will be
diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
index effaa5751d6c..3e9988ee785f 100644
--- a/drivers/media/rc/igorplugusb.c
+++ b/drivers/media/rc/igorplugusb.c
@@ -64,9 +64,11 @@ static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len)
if (start >= len) {
dev_err(ir->dev, "receive overflow invalid: %u", overflow);
} else {
- if (overflow > 0)
+ if (overflow > 0) {
dev_warn(ir->dev, "receive overflow, at least %u lost",
overflow);
+ ir_raw_event_reset(ir->rc);
+ }
do {
rawir.duration = ir->buf_in[i] * 85;
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 84949baf9f6b..f8d080e41f4c 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -262,9 +262,6 @@ static int iguanair_receiver(struct iguanair *ir, bool enable)
ir->packet->header.direction = DIR_OUT;
ir->packet->header.cmd = enable ? CMD_RECEIVER_ON : CMD_RECEIVER_OFF;
- if (enable)
- ir_raw_event_reset(ir->rc);
-
return iguanair_send(ir, sizeof(ir->packet->header));
}
diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c
index a0d9c02a7588..a3b145183260 100644
--- a/drivers/media/rc/ir-rx51.c
+++ b/drivers/media/rc/ir-rx51.c
@@ -19,6 +19,7 @@
struct ir_rx51 {
struct rc_dev *rcdev;
struct pwm_device *pwm;
+ struct pwm_state state;
struct hrtimer timer;
struct device *dev;
wait_queue_head_t wqueue;
@@ -32,22 +33,20 @@ struct ir_rx51 {
static inline void ir_rx51_on(struct ir_rx51 *ir_rx51)
{
- pwm_enable(ir_rx51->pwm);
+ ir_rx51->state.enabled = true;
+ pwm_apply_state(ir_rx51->pwm, &ir_rx51->state);
}
static inline void ir_rx51_off(struct ir_rx51 *ir_rx51)
{
- pwm_disable(ir_rx51->pwm);
+ ir_rx51->state.enabled = false;
+ pwm_apply_state(ir_rx51->pwm, &ir_rx51->state);
}
static int init_timing_params(struct ir_rx51 *ir_rx51)
{
- struct pwm_device *pwm = ir_rx51->pwm;
- int duty, period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, ir_rx51->freq);
-
- duty = DIV_ROUND_CLOSEST(ir_rx51->duty_cycle * period, 100);
-
- pwm_config(pwm, duty, period);
+ ir_rx51->state.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, ir_rx51->freq);
+ pwm_set_relative_duty_cycle(&ir_rx51->state, ir_rx51->duty_cycle, 100);
return 0;
}
@@ -242,6 +241,7 @@ static int ir_rx51_probe(struct platform_device *dev)
/* Use default, in case userspace does not set the carrier */
ir_rx51.freq = DIV_ROUND_CLOSEST_ULL(pwm_get_period(pwm), NSEC_PER_SEC);
+ pwm_init_state(pwm, &ir_rx51.state);
pwm_put(pwm);
hrtimer_init(&ir_rx51.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c
index c58f2d38a458..51aa55a84bb5 100644
--- a/drivers/media/rc/ir-spi.c
+++ b/drivers/media/rc/ir-spi.c
@@ -152,11 +152,6 @@ static int ir_spi_probe(struct spi_device *spi)
return devm_rc_register_device(&spi->dev, idata->rc);
}
-static int ir_spi_remove(struct spi_device *spi)
-{
- return 0;
-}
-
static const struct of_device_id ir_spi_of_match[] = {
{ .compatible = "ir-spi-led" },
{},
@@ -165,7 +160,6 @@ MODULE_DEVICE_TABLE(of, ir_spi_of_match);
static struct spi_driver ir_spi_driver = {
.probe = ir_spi_probe,
- .remove = ir_spi_remove,
.driver = {
.name = IR_SPI_DRIVER_NAME,
.of_match_table = ir_spi_of_match,
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 7f591ff5269d..c7c5157725f8 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -102,8 +102,6 @@ void lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
spin_lock_irqsave(&dev->lirc_fh_lock, flags);
list_for_each_entry(fh, &dev->lirc_fh, list) {
- if (LIRC_IS_TIMEOUT(sample) && !fh->send_timeout_reports)
- continue;
if (kfifo_put(&fh->rawir, sample))
wake_up_poll(&fh->wait_poll, EPOLLIN | EPOLLRDNORM);
}
@@ -166,7 +164,6 @@ static int lirc_open(struct inode *inode, struct file *file)
fh->send_mode = LIRC_MODE_PULSE;
fh->rc = dev;
- fh->send_timeout_reports = true;
if (dev->driver_type == RC_DRIVER_SCANCODE)
fh->rec_mode = LIRC_MODE_SCANCODE;
@@ -570,8 +567,6 @@ static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case LIRC_SET_REC_TIMEOUT_REPORTS:
if (dev->driver_type != RC_DRIVER_IR_RAW)
ret = -ENOTTY;
- else
- fh->send_timeout_reports = !!val;
break;
default:
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index d09bee82c04c..2dc810f5a73f 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1430,7 +1430,7 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
*/
ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
- data, USB_CTRL_MSG_SZ, HZ * 3);
+ data, USB_CTRL_MSG_SZ, 3000);
dev_dbg(dev, "set address - ret = %d", ret);
dev_dbg(dev, "set address - data[0] = %d, data[1] = %d",
data[0], data[1]);
@@ -1438,20 +1438,20 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
/* set feature: bit rate 38400 bps */
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
- 0xc04e, 0x0000, NULL, 0, HZ * 3);
+ 0xc04e, 0x0000, NULL, 0, 3000);
dev_dbg(dev, "set feature - ret = %d", ret);
/* bRequest 4: set char length to 8 bits */
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
4, USB_TYPE_VENDOR,
- 0x0808, 0x0000, NULL, 0, HZ * 3);
+ 0x0808, 0x0000, NULL, 0, 3000);
dev_dbg(dev, "set char length - retB = %d", ret);
/* bRequest 2: set handshaking to use DTR/DSR */
ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
2, USB_TYPE_VENDOR,
- 0x0000, 0x0100, NULL, 0, HZ * 3);
+ 0x0000, 0x0100, NULL, 0, 3000);
dev_dbg(dev, "set handshake - retC = %d", ret);
/* device resume */
diff --git a/drivers/media/rc/pwm-ir-tx.c b/drivers/media/rc/pwm-ir-tx.c
index 4bc28d2c9cc9..105a9c24f1e3 100644
--- a/drivers/media/rc/pwm-ir-tx.c
+++ b/drivers/media/rc/pwm-ir-tx.c
@@ -53,22 +53,21 @@ static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
{
struct pwm_ir *pwm_ir = dev->priv;
struct pwm_device *pwm = pwm_ir->pwm;
- int i, duty, period;
+ struct pwm_state state;
+ int i;
ktime_t edge;
long delta;
- period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, pwm_ir->carrier);
- duty = DIV_ROUND_CLOSEST(pwm_ir->duty_cycle * period, 100);
+ pwm_init_state(pwm, &state);
- pwm_config(pwm, duty, period);
+ state.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, pwm_ir->carrier);
+ pwm_set_relative_duty_cycle(&state, pwm_ir->duty_cycle, 100);
edge = ktime_get();
for (i = 0; i < count; i++) {
- if (i % 2) // space
- pwm_disable(pwm);
- else
- pwm_enable(pwm);
+ state.enabled = !(i % 2);
+ pwm_apply_state(pwm, &state);
edge = ktime_add_us(edge, txbuf[i]);
delta = ktime_us_delta(edge, ktime_get());
@@ -76,7 +75,8 @@ static int pwm_ir_tx(struct rc_dev *dev, unsigned int *txbuf,
usleep_range(delta, delta + 10);
}
- pwm_disable(pwm);
+ state.enabled = false;
+ pwm_apply_state(pwm, &state);
return count;
}
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index ac85464864b9..cb22316b3f00 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -404,7 +404,7 @@ static int redrat3_send_cmd(int cmd, struct redrat3_dev *rr3)
udev = rr3->udev;
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0x0000, 0x0000, data, sizeof(u8), HZ * 10);
+ 0x0000, 0x0000, data, sizeof(u8), 10000);
if (res < 0) {
dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d",
@@ -480,7 +480,7 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3)
pipe = usb_rcvctrlpipe(rr3->udev, 0);
ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5);
+ RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, 5000);
if (ret != len)
dev_warn(rr3->dev, "Failed to read timeout from hardware\n");
else {
@@ -510,7 +510,7 @@ static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutus)
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
RR3_IR_IO_SIG_TIMEOUT, 0, timeout, sizeof(*timeout),
- HZ * 25);
+ 25000);
dev_dbg(dev, "set ir parm timeout %d ret 0x%02x\n",
be32_to_cpu(*timeout), ret);
@@ -542,32 +542,32 @@ static void redrat3_reset(struct redrat3_dev *rr3)
*val = 0x01;
rc = usb_control_msg(udev, rxpipe, RR3_RESET,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25);
+ RR3_CPUCS_REG_ADDR, 0, val, len, 25000);
dev_dbg(dev, "reset returned 0x%02x\n", rc);
*val = length_fuzz;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25);
+ RR3_IR_IO_LENGTH_FUZZ, 0, val, len, 25000);
dev_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc);
*val = (65536 - (minimum_pause * 2000)) / 256;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_MIN_PAUSE, 0, val, len, HZ * 25);
+ RR3_IR_IO_MIN_PAUSE, 0, val, len, 25000);
dev_dbg(dev, "set ir parm min pause %d rc 0x%02x\n", *val, rc);
*val = periods_measure_carrier;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_PERIODS_MF, 0, val, len, HZ * 25);
+ RR3_IR_IO_PERIODS_MF, 0, val, len, 25000);
dev_dbg(dev, "set ir parm periods measure carrier %d rc 0x%02x", *val,
rc);
*val = RR3_DRIVER_MAXLENS;
rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25);
+ RR3_IR_IO_MAX_LENGTHS, 0, val, len, 25000);
dev_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc);
kfree(val);
@@ -585,7 +585,7 @@ static void redrat3_get_firmware_rev(struct redrat3_dev *rr3)
rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0),
RR3_FW_VERSION,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5);
+ 0, 0, buffer, RR3_FW_VERSION_LEN, 5000);
if (rc >= 0)
dev_info(rr3->dev, "Firmware rev: %s", buffer);
@@ -825,14 +825,14 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress);
ret = usb_bulk_msg(rr3->udev, pipe, irdata,
- sendbuf_len, &ret_len, 10 * HZ);
+ sendbuf_len, &ret_len, 10000);
dev_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret);
/* now tell the hardware to transmit what we sent it */
pipe = usb_rcvctrlpipe(rr3->udev, 0);
ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, 0, irdata, 2, HZ * 10);
+ 0, 0, irdata, 2, 10000);
if (ret < 0)
dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index 1cc5ebb85b6c..16ba85d7c090 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -21,12 +21,10 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/ktime.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <media/rc-core.h>
-#define DRIVER_VERSION "1.61"
#define DRIVER_NAME "streamzap"
#define DRIVER_DESC "Streamzap Remote Control driver"
@@ -67,9 +65,6 @@ struct streamzap_ir {
struct device *dev;
/* usb */
- struct usb_device *usbdev;
- struct usb_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
struct urb *urb_in;
/* buffer & dma */
@@ -79,16 +74,7 @@ struct streamzap_ir {
/* track what state we're in */
enum StreamzapDecoderState decoder_state;
- /* tracks whether we are currently receiving some signal */
- bool idle;
- /* sum of signal lengths received since signal start */
- unsigned long sum;
- /* start time of signal; necessary for gap tracking */
- ktime_t signal_last;
- ktime_t signal_start;
- bool timeout_enabled;
-
- char name[128];
+
char phys[64];
};
@@ -121,37 +107,11 @@ static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
static void sz_push_full_pulse(struct streamzap_ir *sz,
unsigned char value)
{
- struct ir_raw_event rawir = {};
-
- if (sz->idle) {
- int delta;
-
- sz->signal_last = sz->signal_start;
- sz->signal_start = ktime_get_real();
-
- delta = ktime_us_delta(sz->signal_start, sz->signal_last);
- rawir.pulse = false;
- if (delta > (15 * USEC_PER_SEC)) {
- /* really long time */
- rawir.duration = IR_MAX_DURATION;
- } else {
- rawir.duration = delta;
- rawir.duration -= sz->sum;
- rawir.duration = (rawir.duration > IR_MAX_DURATION) ?
- IR_MAX_DURATION : rawir.duration;
- }
- sz_push(sz, rawir);
+ struct ir_raw_event rawir = {
+ .pulse = true,
+ .duration = value * SZ_RESOLUTION + SZ_RESOLUTION / 2,
+ };
- sz->idle = false;
- sz->sum = 0;
- }
-
- rawir.pulse = true;
- rawir.duration = ((int) value) * SZ_RESOLUTION;
- rawir.duration += SZ_RESOLUTION / 2;
- sz->sum += rawir.duration;
- rawir.duration = (rawir.duration > IR_MAX_DURATION) ?
- IR_MAX_DURATION : rawir.duration;
sz_push(sz, rawir);
}
@@ -164,12 +124,11 @@ static void sz_push_half_pulse(struct streamzap_ir *sz,
static void sz_push_full_space(struct streamzap_ir *sz,
unsigned char value)
{
- struct ir_raw_event rawir = {};
+ struct ir_raw_event rawir = {
+ .pulse = false,
+ .duration = value * SZ_RESOLUTION + SZ_RESOLUTION / 2,
+ };
- rawir.pulse = false;
- rawir.duration = ((int) value) * SZ_RESOLUTION;
- rawir.duration += SZ_RESOLUTION / 2;
- sz->sum += rawir.duration;
sz_push(sz, rawir);
}
@@ -241,11 +200,7 @@ static void streamzap_callback(struct urb *urb)
.pulse = false,
.duration = sz->rdev->timeout
};
- sz->idle = true;
- if (sz->timeout_enabled)
- sz_push(sz, rawir);
- ir_raw_event_handle(sz->rdev);
- ir_raw_event_reset(sz->rdev);
+ sz_push(sz, rawir);
} else {
sz_push_full_space(sz, sz->buf_in[i]);
}
@@ -267,27 +222,23 @@ static void streamzap_callback(struct urb *urb)
usb_submit_urb(urb, GFP_ATOMIC);
}
-static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
+static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz,
+ struct usb_device *usbdev)
{
struct rc_dev *rdev;
struct device *dev = sz->dev;
int ret;
rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
- if (!rdev) {
- dev_err(dev, "remote dev allocation failed\n");
+ if (!rdev)
goto out;
- }
- snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared Receiver (%04x:%04x)",
- le16_to_cpu(sz->usbdev->descriptor.idVendor),
- le16_to_cpu(sz->usbdev->descriptor.idProduct));
- usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
+ usb_make_path(usbdev, sz->phys, sizeof(sz->phys));
strlcat(sz->phys, "/input0", sizeof(sz->phys));
- rdev->device_name = sz->name;
+ rdev->device_name = "Streamzap PC Remote Infrared Receiver";
rdev->input_phys = sz->phys;
- usb_to_input_id(sz->usbdev, &rdev->input_id);
+ usb_to_input_id(usbdev, &rdev->input_id);
rdev->dev.parent = dev;
rdev->priv = sz;
rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
@@ -319,9 +270,9 @@ static int streamzap_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *usbdev = interface_to_usbdev(intf);
+ struct usb_endpoint_descriptor *endpoint;
struct usb_host_interface *iface_host;
struct streamzap_ir *sz = NULL;
- char buf[63], name[128] = "";
int retval = -ENOMEM;
int pipe, maxp;
@@ -330,9 +281,6 @@ static int streamzap_probe(struct usb_interface *intf,
if (!sz)
return -ENOMEM;
- sz->usbdev = usbdev;
- sz->interface = intf;
-
/* Check to ensure endpoint information matches requirements */
iface_host = intf->cur_altsetting;
@@ -343,22 +291,22 @@ static int streamzap_probe(struct usb_interface *intf,
goto free_sz;
}
- sz->endpoint = &(iface_host->endpoint[0].desc);
- if (!usb_endpoint_dir_in(sz->endpoint)) {
+ endpoint = &iface_host->endpoint[0].desc;
+ if (!usb_endpoint_dir_in(endpoint)) {
dev_err(&intf->dev, "%s: endpoint doesn't match input device 02%02x\n",
- __func__, sz->endpoint->bEndpointAddress);
+ __func__, endpoint->bEndpointAddress);
retval = -ENODEV;
goto free_sz;
}
- if (!usb_endpoint_xfer_int(sz->endpoint)) {
+ if (!usb_endpoint_xfer_int(endpoint)) {
dev_err(&intf->dev, "%s: endpoint attributes don't match xfer 02%02x\n",
- __func__, sz->endpoint->bmAttributes);
+ __func__, endpoint->bmAttributes);
retval = -ENODEV;
goto free_sz;
}
- pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress);
+ pipe = usb_rcvintpipe(usbdev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe));
if (maxp == 0) {
@@ -380,25 +328,12 @@ static int streamzap_probe(struct usb_interface *intf,
sz->dev = &intf->dev;
sz->buf_in_len = maxp;
- if (usbdev->descriptor.iManufacturer
- && usb_string(usbdev, usbdev->descriptor.iManufacturer,
- buf, sizeof(buf)) > 0)
- strscpy(name, buf, sizeof(name));
-
- if (usbdev->descriptor.iProduct
- && usb_string(usbdev, usbdev->descriptor.iProduct,
- buf, sizeof(buf)) > 0)
- snprintf(name + strlen(name), sizeof(name) - strlen(name),
- " %s", buf);
-
- sz->rdev = streamzap_init_rc_dev(sz);
+ sz->rdev = streamzap_init_rc_dev(sz, usbdev);
if (!sz->rdev)
goto rc_dev_fail;
- sz->idle = true;
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
- sz->timeout_enabled = true;
sz->rdev->timeout = SZ_TIMEOUT * SZ_RESOLUTION;
#if 0
/* not yet supported, depends on patches from maxim */
@@ -407,12 +342,9 @@ static int streamzap_probe(struct usb_interface *intf,
sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION;
#endif
- sz->signal_start = ktime_get_real();
-
/* Complete final initialisations */
usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in,
- maxp, (usb_complete_t)streamzap_callback,
- sz, sz->endpoint->bInterval);
+ maxp, streamzap_callback, sz, endpoint->bInterval);
sz->urb_in->transfer_dma = sz->dma_in;
sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -421,9 +353,6 @@ static int streamzap_probe(struct usb_interface *intf,
if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
dev_err(sz->dev, "urb submit failed\n");
- dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
- usbdev->bus->busnum, usbdev->devnum);
-
return 0;
rc_dev_fail:
@@ -456,7 +385,6 @@ static void streamzap_disconnect(struct usb_interface *interface)
if (!sz)
return;
- sz->usbdev = NULL;
rc_unregister_device(sz->rdev);
usb_kill_urb(sz->urb_in);
usb_free_urb(sz->urb_in);
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index aed23ca0fa6c..94efb035d21b 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -997,7 +997,6 @@ wbcir_resume(struct pnp_dev *device)
struct wbcir_data *data = pnp_get_drvdata(device);
wbcir_init_hw(data);
- ir_raw_event_reset(data->dev);
enable_irq(data->irq);
led_classdev_resume(&data->led);
diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c
index 506f52c1af10..6f2a66bc87fb 100644
--- a/drivers/media/spi/cxd2880-spi.c
+++ b/drivers/media/spi/cxd2880-spi.c
@@ -628,19 +628,8 @@ fail_regulator:
static int
cxd2880_spi_remove(struct spi_device *spi)
{
- struct cxd2880_dvb_spi *dvb_spi;
+ struct cxd2880_dvb_spi *dvb_spi = spi_get_drvdata(spi);
- if (!spi) {
- pr_err("invalid arg\n");
- return -EINVAL;
- }
-
- dvb_spi = spi_get_drvdata(spi);
-
- if (!dvb_spi) {
- pr_err("failed\n");
- return -EINVAL;
- }
dvb_spi->demux.dmx.remove_frontend(&dvb_spi->demux.dmx,
&dvb_spi->dmx_fe);
dvb_dmxdev_release(&dvb_spi->dmxdev);
diff --git a/drivers/media/test-drivers/vicodec/vicodec-core.c b/drivers/media/test-drivers/vicodec/vicodec-core.c
index 33f1c893c1b6..be43f7d32df9 100644
--- a/drivers/media/test-drivers/vicodec/vicodec-core.c
+++ b/drivers/media/test-drivers/vicodec/vicodec-core.c
@@ -1443,7 +1443,7 @@ static void vicodec_buf_queue(struct vb2_buffer *vb)
unsigned int i;
for (i = 0; i < vb->num_planes; i++)
- vb->planes[i].bytesused = 0;
+ vb2_set_plane_payload(vb, i, 0);
vbuf->field = V4L2_FIELD_NONE;
vbuf->sequence =
diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c
index c11ac8dca73d..a5875380ef40 100644
--- a/drivers/media/test-drivers/vidtv/vidtv_psi.c
+++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c
@@ -94,34 +94,28 @@ static void vidtv_psi_update_version_num(struct vidtv_psi_table_header *h)
static u16 vidtv_psi_get_sec_len(struct vidtv_psi_table_header *h)
{
u16 mask;
- u16 ret;
mask = GENMASK(11, 0);
- ret = be16_to_cpu(h->bitfield) & mask;
- return ret;
+ return be16_to_cpu(h->bitfield) & mask;
}
u16 vidtv_psi_get_pat_program_pid(struct vidtv_psi_table_pat_program *p)
{
u16 mask;
- u16 ret;
mask = GENMASK(12, 0);
- ret = be16_to_cpu(p->bitfield) & mask;
- return ret;
+ return be16_to_cpu(p->bitfield) & mask;
}
u16 vidtv_psi_pmt_stream_get_elem_pid(struct vidtv_psi_table_pmt_stream *s)
{
u16 mask;
- u16 ret;
mask = GENMASK(12, 0);
- ret = be16_to_cpu(s->bitfield) & mask;
- return ret;
+ return be16_to_cpu(s->bitfield) & mask;
}
static void vidtv_psi_set_desc_loop_len(__be16 *bitfield, u16 new_len,
diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c
index 78e6fd600d8e..44247049a319 100644
--- a/drivers/media/tuners/msi001.c
+++ b/drivers/media/tuners/msi001.c
@@ -442,6 +442,13 @@ static int msi001_probe(struct spi_device *spi)
V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000);
+ if (dev->hdl.error) {
+ ret = dev->hdl.error;
+ dev_err(&spi->dev, "Could not initialize controls\n");
+ /* control init failed, free handler */
+ goto err_ctrl_handler_free;
+ }
+
v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false);
dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1);
diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
index f6e82a8e7d37..ab4c43df9d18 100644
--- a/drivers/media/tuners/mxl5005s.c
+++ b/drivers/media/tuners/mxl5005s.c
@@ -3414,9 +3414,8 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
u32 value, u16 controlGroup)
{
struct mxl5005s_state *state = fe->tuner_priv;
- u16 i, j, k;
+ u16 i, j;
u32 highLimit;
- u32 ctrlVal;
if (controlGroup == 1) /* Initial Control */ {
@@ -3432,9 +3431,6 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
(u8)(state->Init_Ctrl[i].bit[j]),
(u8)((value>>j) & 0x01));
}
- ctrlVal = 0;
- for (k = 0; k < state->Init_Ctrl[i].size; k++)
- ctrlVal += state->Init_Ctrl[i].val[k] * (1 << k);
} else
return -1;
}
@@ -3454,9 +3450,6 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
(u8)(state->CH_Ctrl[i].bit[j]),
(u8)((value>>j) & 0x01));
}
- ctrlVal = 0;
- for (k = 0; k < state->CH_Ctrl[i].size; k++)
- ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
} else
return -1;
}
@@ -3477,11 +3470,6 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
(u8)(state->MXL_Ctrl[i].bit[j]),
(u8)((value>>j) & 0x01));
}
- ctrlVal = 0;
- for (k = 0; k < state->MXL_Ctrl[i].size; k++)
- ctrlVal += state->
- MXL_Ctrl[i].val[k] *
- (1 << k);
} else
return -1;
}
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index aed2f130ec74..b9a7590aeec6 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -326,6 +326,26 @@ static int r820t_xtal_capacitor[][2] = {
{ 0x10, XTAL_HIGH_CAP_0P },
};
+static const char *r820t_chip_enum_to_str(enum r820t_chip chip)
+{
+ switch (chip) {
+ case CHIP_R820T:
+ return "R820T";
+ case CHIP_R620D:
+ return "R620D";
+ case CHIP_R828D:
+ return "R828D";
+ case CHIP_R828:
+ return "R828";
+ case CHIP_R828S:
+ return "R828S";
+ case CHIP_R820C:
+ return "R820C";
+ default:
+ return "<unknown>";
+ }
+}
+
/*
* I2C read/write code and shadow registers logic
*/
@@ -2355,7 +2375,9 @@ struct dvb_frontend *r820t_attach(struct dvb_frontend *fe,
if (rc < 0)
goto err;
- tuner_info("Rafael Micro r820t successfully identified\n");
+ tuner_info(
+ "Rafael Micro r820t successfully identified, chip type: %s\n",
+ r820t_chip_enum_to_str(cfg->rafael_chip));
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index fefb2625f655..481c5c3b577d 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -76,21 +76,156 @@ err_mutex_unlock:
return ret;
}
-static int si2157_init(struct dvb_frontend *fe)
+static const struct si2157_tuner_info si2157_tuners[] = {
+ { SI2141, false, 0x60, SI2141_60_FIRMWARE, SI2141_A10_FIRMWARE },
+ { SI2141, false, 0x61, SI2141_61_FIRMWARE, SI2141_A10_FIRMWARE },
+ { SI2146, false, 0x11, SI2146_11_FIRMWARE, NULL },
+ { SI2147, false, 0x50, SI2147_50_FIRMWARE, NULL },
+ { SI2148, true, 0x32, SI2148_32_FIRMWARE, SI2158_A20_FIRMWARE },
+ { SI2148, true, 0x33, SI2148_33_FIRMWARE, SI2158_A20_FIRMWARE },
+ { SI2157, false, 0x50, SI2157_50_FIRMWARE, SI2157_A30_FIRMWARE },
+ { SI2158, false, 0x50, SI2158_50_FIRMWARE, SI2158_A20_FIRMWARE },
+ { SI2158, false, 0x51, SI2158_51_FIRMWARE, SI2158_A20_FIRMWARE },
+ { SI2177, false, 0x50, SI2177_50_FIRMWARE, SI2157_A30_FIRMWARE },
+};
+
+static int si2157_load_firmware(struct dvb_frontend *fe,
+ const char *fw_name)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ const struct firmware *fw;
+ int ret, len, remaining;
+ struct si2157_cmd cmd;
+
+ /* request the firmware, this will block and timeout */
+ ret = firmware_request_nowarn(&fw, fw_name, &client->dev);
+ if (ret)
+ return ret;
+
+ /* firmware should be n chunks of 17 bytes */
+ if (fw->size % 17 != 0) {
+ dev_err(&client->dev, "firmware file '%s' is invalid\n",
+ fw_name);
+ ret = -EINVAL;
+ goto err_release_firmware;
+ }
+
+ dev_info(&client->dev, "downloading firmware from file '%s'\n",
+ fw_name);
+
+ for (remaining = fw->size; remaining > 0; remaining -= 17) {
+ len = fw->data[fw->size - remaining];
+ if (len > SI2157_ARGLEN) {
+ dev_err(&client->dev, "Bad firmware length\n");
+ ret = -EINVAL;
+ goto err_release_firmware;
+ }
+ memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
+ cmd.wlen = len;
+ cmd.rlen = 1;
+ ret = si2157_cmd_execute(client, &cmd);
+ if (ret) {
+ dev_err(&client->dev, "firmware download failed %d\n",
+ ret);
+ goto err_release_firmware;
+ }
+ }
+
+err_release_firmware:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int si2157_find_and_load_firmware(struct dvb_frontend *fe)
{
struct i2c_client *client = fe->tuner_priv;
struct si2157_dev *dev = i2c_get_clientdata(client);
+ const char *fw_alt_name = NULL;
+ unsigned char part_id, rom_id;
+ const char *fw_name = NULL;
+ struct si2157_cmd cmd;
+ bool required = true;
+ int ret, i;
+
+ if (dev->dont_load_firmware) {
+ dev_info(&client->dev,
+ "device is buggy, skipping firmware download\n");
+ return 0;
+ }
+
+ /* query chip revision */
+ memcpy(cmd.args, "\x02", 1);
+ cmd.wlen = 1;
+ cmd.rlen = 13;
+ ret = si2157_cmd_execute(client, &cmd);
+ if (ret)
+ return ret;
+
+ part_id = cmd.args[2];
+ rom_id = cmd.args[12];
+
+ for (i = 0; i < ARRAY_SIZE(si2157_tuners); i++) {
+ if (si2157_tuners[i].part_id != part_id)
+ continue;
+ required = si2157_tuners[i].required;
+ fw_alt_name = si2157_tuners[i].fw_alt_name;
+
+ /* Both part and rom ID match */
+ if (si2157_tuners[i].rom_id == rom_id) {
+ fw_name = si2157_tuners[i].fw_name;
+ break;
+ }
+ }
+
+ if (!fw_name && !fw_alt_name) {
+ dev_err(&client->dev,
+ "unknown chip version Si21%d-%c%c%c ROM 0x%02x\n",
+ part_id, cmd.args[1], cmd.args[3], cmd.args[4], rom_id);
+ return -EINVAL;
+ }
+
+ /* Update the part id based on device's report */
+ dev->part_id = part_id;
+
+ dev_info(&client->dev,
+ "found a 'Silicon Labs Si21%d-%c%c%c ROM 0x%02x'\n",
+ part_id, cmd.args[1], cmd.args[3], cmd.args[4], rom_id);
+
+ if (fw_name)
+ ret = si2157_load_firmware(fe, fw_name);
+ else
+ ret = -ENOENT;
+
+ /* Try alternate name, if any */
+ if (ret == -ENOENT && fw_alt_name)
+ ret = si2157_load_firmware(fe, fw_alt_name);
+
+ if (ret == -ENOENT) {
+ if (!required) {
+ dev_info(&client->dev, "Using ROM firmware.\n");
+ return 0;
+ }
+ dev_err(&client->dev, "Can't continue without a firmware.\n");
+ } else if (ret < 0) {
+ dev_err(&client->dev, "error %d when loading firmware\n", ret);
+ }
+ return ret;
+}
+
+static int si2157_init(struct dvb_frontend *fe)
+{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret, len, remaining;
+ struct i2c_client *client = fe->tuner_priv;
+ struct si2157_dev *dev = i2c_get_clientdata(client);
+ unsigned int xtal_trim;
struct si2157_cmd cmd;
- const struct firmware *fw;
- const char *fw_name;
- unsigned int chip_id, xtal_trim;
+ int ret;
dev_dbg(&client->dev, "\n");
/* Try to get Xtal trim property, to verify tuner still running */
- memcpy(cmd.args, "\x15\x00\x04\x02", 4);
+ memcpy(cmd.args, "\x15\x00\x02\x04", 4);
cmd.wlen = 4;
cmd.rlen = 4;
ret = si2157_cmd_execute(client, &cmd);
@@ -103,10 +238,12 @@ static int si2157_init(struct dvb_frontend *fe)
dev->if_frequency = 0; /* we no longer know current tuner state */
/* power up */
- if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
+ if (dev->part_id == SI2146) {
+ /* clock_mode = XTAL, clock_freq = 24MHz */
memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
cmd.wlen = 9;
- } else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+ } else if (dev->part_id == SI2141) {
+ /* clock_mode: XTAL, xout enabled */
memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
cmd.wlen = 10;
} else {
@@ -115,11 +252,11 @@ static int si2157_init(struct dvb_frontend *fe)
}
cmd.rlen = 1;
ret = si2157_cmd_execute(client, &cmd);
- if (ret && (dev->chiptype != SI2157_CHIPTYPE_SI2141 || ret != -EAGAIN))
+ if (ret && (dev->part_id != SI2141 || ret != -EAGAIN))
goto err;
- /* Si2141 needs a second command before it answers the revision query */
- if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
+ /* Si2141 needs a wake up command */
+ if (dev->part_id == SI2141) {
memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x00\x01", 7);
cmd.wlen = 7;
ret = si2157_cmd_execute(client, &cmd);
@@ -127,100 +264,11 @@ static int si2157_init(struct dvb_frontend *fe)
goto err;
}
- if (dev->dont_load_firmware) {
- dev_info(&client->dev, "device is buggy, skipping firmware download\n");
- goto skip_fw_download;
- }
-
- /* query chip revision */
- memcpy(cmd.args, "\x02", 1);
- cmd.wlen = 1;
- cmd.rlen = 13;
- ret = si2157_cmd_execute(client, &cmd);
- if (ret)
+ /* Try to load the firmware */
+ ret = si2157_find_and_load_firmware(fe);
+ if (ret < 0)
goto err;
- chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
- cmd.args[4] << 0;
-
- #define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
- #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
- #define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
- #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
- #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
- #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
- #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
-
- switch (chip_id) {
- case SI2158_A20:
- case SI2148_A20:
- fw_name = SI2158_A20_FIRMWARE;
- break;
- case SI2141_A10:
- fw_name = SI2141_A10_FIRMWARE;
- break;
- case SI2177_A30:
- fw_name = SI2157_A30_FIRMWARE;
- break;
- case SI2157_A30:
- case SI2147_A30:
- case SI2146_A10:
- fw_name = NULL;
- break;
- default:
- dev_err(&client->dev, "unknown chip version Si21%d-%c%c%c\n",
- cmd.args[2], cmd.args[1],
- cmd.args[3], cmd.args[4]);
- ret = -EINVAL;
- goto err;
- }
-
- dev_info(&client->dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n",
- cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
-
- if (fw_name == NULL)
- goto skip_fw_download;
-
- /* request the firmware, this will block and timeout */
- ret = request_firmware(&fw, fw_name, &client->dev);
- if (ret) {
- dev_err(&client->dev, "firmware file '%s' not found\n",
- fw_name);
- goto err;
- }
-
- /* firmware should be n chunks of 17 bytes */
- if (fw->size % 17 != 0) {
- dev_err(&client->dev, "firmware file '%s' is invalid\n",
- fw_name);
- ret = -EINVAL;
- goto err_release_firmware;
- }
-
- dev_info(&client->dev, "downloading firmware from file '%s'\n",
- fw_name);
-
- for (remaining = fw->size; remaining > 0; remaining -= 17) {
- len = fw->data[fw->size - remaining];
- if (len > SI2157_ARGLEN) {
- dev_err(&client->dev, "Bad firmware length\n");
- ret = -EINVAL;
- goto err_release_firmware;
- }
- memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
- cmd.wlen = len;
- cmd.rlen = 1;
- ret = si2157_cmd_execute(client, &cmd);
- if (ret) {
- dev_err(&client->dev, "firmware download failed %d\n",
- ret);
- goto err_release_firmware;
- }
- }
-
- release_firmware(fw);
-
-skip_fw_download:
/* reboot the tuner with new firmware? */
memcpy(cmd.args, "\x01\x01", 2);
cmd.wlen = 2;
@@ -270,8 +318,7 @@ warm:
dev->active = true;
return 0;
-err_release_firmware:
- release_firmware(fw);
+
err:
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
@@ -411,8 +458,12 @@ static int si2157_set_params(struct dvb_frontend *fe)
goto err;
}
+ if (SUPPORTS_1700KHz(dev) && c->bandwidth_hz <= 1700000)
+ bandwidth = 0x09;
if (c->bandwidth_hz <= 6000000)
bandwidth = 0x06;
+ if (SUPPORTS_1700KHz(dev) && c->bandwidth_hz <= 6100000)
+ bandwidth = 0x10;
else if (c->bandwidth_hz <= 7000000)
bandwidth = 0x07;
else if (c->bandwidth_hz <= 8000000)
@@ -436,6 +487,12 @@ static int si2157_set_params(struct dvb_frontend *fe)
case SYS_DVBC_ANNEX_A:
delivery_system = 0x30;
break;
+ case SYS_ISDBT:
+ delivery_system = 0x40;
+ break;
+ case SYS_DTMB:
+ delivery_system = 0x60;
+ break;
default:
ret = -EINVAL;
goto err;
@@ -451,7 +508,8 @@ static int si2157_set_params(struct dvb_frontend *fe)
if (ret)
goto err;
- if (dev->chiptype == SI2157_CHIPTYPE_SI2146)
+ /* On SI2146, set DTV AGC source to DLIF_AGC_3DB */
+ if (dev->part_id == SI2146)
memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6);
else
memcpy(cmd.args, "\x14\x00\x02\x07\x00\x00", 6);
@@ -518,9 +576,9 @@ static int si2157_set_analog_params(struct dvb_frontend *fe,
u8 color = 0; /* 0=NTSC/PAL, 0x10=SECAM */
u8 invert_analog = 1; /* analog tuner spectrum; 0=normal, 1=inverted */
- if (dev->chiptype != SI2157_CHIPTYPE_SI2157) {
- dev_info(&client->dev, "Analog tuning not supported for chiptype=%u\n",
- dev->chiptype);
+ if (!SUPPORTS_ATV_IF(dev)) {
+ dev_info(&client->dev, "Analog tuning not supported yet for Si21%d\n",
+ dev->part_id);
ret = -EINVAL;
goto err;
}
@@ -832,7 +890,7 @@ static int si2157_probe(struct i2c_client *client,
dev->inversion = cfg->inversion;
dev->dont_load_firmware = cfg->dont_load_firmware;
dev->if_port = cfg->if_port;
- dev->chiptype = (u8)id->driver_data;
+ dev->part_id = (u8)id->driver_data;
dev->if_frequency = 5000000; /* default value of property 0x0706 */
mutex_init(&dev->i2c_mutex);
INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work);
@@ -875,10 +933,8 @@ static int si2157_probe(struct i2c_client *client,
}
#endif
- dev_info(&client->dev, "Silicon Labs %s successfully attached\n",
- dev->chiptype == SI2157_CHIPTYPE_SI2141 ? "Si2141" :
- dev->chiptype == SI2157_CHIPTYPE_SI2146 ?
- "Si2146" : "Si2147/2148/2157/2158");
+ dev_info(&client->dev, "Silicon Labs Si21%d successfully attached\n",
+ dev->part_id);
return 0;
@@ -911,11 +967,16 @@ static int si2157_remove(struct i2c_client *client)
return 0;
}
+/*
+ * The part_id used here will only be used on buggy devices that don't
+ * accept firmware uploads. Non-buggy devices should just use "si2157" for
+ * all SiLabs TER tuners, as the driver should auto-detect it.
+ */
static const struct i2c_device_id si2157_id_table[] = {
- {"si2157", SI2157_CHIPTYPE_SI2157},
- {"si2146", SI2157_CHIPTYPE_SI2146},
- {"si2141", SI2157_CHIPTYPE_SI2141},
- {"si2177", SI2157_CHIPTYPE_SI2177},
+ {"si2157", SI2157},
+ {"si2146", SI2146},
+ {"si2141", SI2141},
+ {"si2177", SI2177},
{}
};
MODULE_DEVICE_TABLE(i2c, si2157_id_table);
@@ -938,3 +999,13 @@ MODULE_LICENSE("GPL");
MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
MODULE_FIRMWARE(SI2157_A30_FIRMWARE);
+MODULE_FIRMWARE(SI2141_60_FIRMWARE);
+MODULE_FIRMWARE(SI2141_61_FIRMWARE);
+MODULE_FIRMWARE(SI2146_11_FIRMWARE);
+MODULE_FIRMWARE(SI2147_50_FIRMWARE);
+MODULE_FIRMWARE(SI2148_32_FIRMWARE);
+MODULE_FIRMWARE(SI2148_33_FIRMWARE);
+MODULE_FIRMWARE(SI2157_50_FIRMWARE);
+MODULE_FIRMWARE(SI2158_50_FIRMWARE);
+MODULE_FIRMWARE(SI2158_51_FIRMWARE);
+MODULE_FIRMWARE(SI2177_50_FIRMWARE);
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index ef4796098931..8579e80f7af7 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -26,7 +26,7 @@ struct si2157_dev {
unsigned int active:1;
unsigned int inversion:1;
unsigned int dont_load_firmware:1;
- u8 chiptype;
+ u8 part_id;
u8 if_port;
u32 if_frequency;
u32 bandwidth;
@@ -41,10 +41,22 @@ struct si2157_dev {
};
-#define SI2157_CHIPTYPE_SI2157 0
-#define SI2157_CHIPTYPE_SI2146 1
-#define SI2157_CHIPTYPE_SI2141 2
-#define SI2157_CHIPTYPE_SI2177 3
+enum si2157_part_id {
+ SI2141 = 41,
+ SI2146 = 46,
+ SI2147 = 47,
+ SI2148 = 48,
+ SI2157 = 57,
+ SI2158 = 58,
+ SI2177 = 77,
+};
+
+struct si2157_tuner_info {
+ enum si2157_part_id part_id;
+ unsigned char rom_id;
+ bool required;
+ const char *fw_name, *fw_alt_name;
+};
/* firmware command struct */
#define SI2157_ARGLEN 30
@@ -54,7 +66,29 @@ struct si2157_cmd {
unsigned rlen;
};
+#define SUPPORTS_1700KHz(dev) (((dev)->part_id == SI2141) || \
+ ((dev)->part_id == SI2147) || \
+ ((dev)->part_id == SI2157) || \
+ ((dev)->part_id == SI2177))
+
+#define SUPPORTS_ATV_IF(dev) (((dev)->part_id == SI2157) || \
+ ((dev)->part_id == SI2158))
+
+/* Old firmware namespace */
#define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
#define SI2141_A10_FIRMWARE "dvb-tuner-si2141-a10-01.fw"
#define SI2157_A30_FIRMWARE "dvb-tuner-si2157-a30-01.fw"
+
+/* New firmware namespace */
+#define SI2141_60_FIRMWARE "dvb_driver_si2141_rom60.fw"
+#define SI2141_61_FIRMWARE "dvb_driver_si2141_rom61.fw"
+#define SI2146_11_FIRMWARE "dvb_driver_si2146_rom11.fw"
+#define SI2147_50_FIRMWARE "dvb_driver_si2147_rom50.fw"
+#define SI2148_32_FIRMWARE "dvb_driver_si2148_rom32.fw"
+#define SI2148_33_FIRMWARE "dvb_driver_si2148_rom33.fw"
+#define SI2157_50_FIRMWARE "dvb_driver_si2157_rom50.fw"
+#define SI2158_50_FIRMWARE "dvb_driver_si2178_rom50.fw"
+#define SI2158_51_FIRMWARE "dvb_driver_si2158_rom51.fw"
+#define SI2177_50_FIRMWARE "dvb_driver_si2177_rom50.fw"
+
#endif
diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c
index 5e3625e75620..af7d5ea1f77e 100644
--- a/drivers/media/tuners/tua9001.c
+++ b/drivers/media/tuners/tua9001.c
@@ -240,14 +240,10 @@ static int tua9001_remove(struct i2c_client *client)
DVB_FRONTEND_COMPONENT_TUNER,
TUA9001_CMD_CEN, 0);
if (ret)
- goto err_kfree;
+ dev_err(&client->dev, "Tuner disable failed (%pe)\n", ERR_PTR(ret));
}
kfree(dev);
return 0;
-err_kfree:
- kfree(dev);
- dev_dbg(&client->dev, "failed=%d\n", ret);
- return ret;
}
static const struct i2c_device_id tua9001_id_table[] = {
diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c
index 708f01ab47fa..749f90d73b5b 100644
--- a/drivers/media/usb/au0828/au0828-i2c.c
+++ b/drivers/media/usb/au0828/au0828-i2c.c
@@ -23,13 +23,6 @@ MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
#define I2C_WAIT_DELAY 25
#define I2C_WAIT_RETRY 1000
-static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap)
-{
- struct au0828_dev *dev = i2c_adap->algo_data;
- return au0828_read(dev, AU0828_I2C_STATUS_201) &
- AU0828_I2C_STATUS_NO_WRITE_ACK ? 0 : 1;
-}
-
static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap)
{
struct au0828_dev *dev = i2c_adap->algo_data;
diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c
index 5d38171b7638..7835bb0f32fc 100644
--- a/drivers/media/usb/b2c2/flexcop-usb.c
+++ b/drivers/media/usb/b2c2/flexcop-usb.c
@@ -87,7 +87,7 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
0,
fc_usb->data,
sizeof(u32),
- B2C2_WAIT_FOR_OPERATION_RDW * HZ);
+ B2C2_WAIT_FOR_OPERATION_RDW);
if (ret != sizeof(u32)) {
err("error while %s dword from %d (%d).", read ? "reading" :
@@ -155,7 +155,7 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
wIndex,
fc_usb->data,
buflen,
- nWaitTime * HZ);
+ nWaitTime);
if (ret != buflen)
ret = -EIO;
@@ -171,7 +171,7 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
return ret;
}
-#define bytes_left_to_read_on_page(paddr,buflen) \
+#define bytes_left_to_read_on_page(paddr, buflen) \
((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
@@ -179,11 +179,11 @@ static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
u32 addr, int extended, u8 *buf, u32 len)
{
- int i,ret = 0;
+ int i, ret = 0;
u16 wMax;
u32 pagechunk = 0;
- switch(req) {
+ switch (req) {
case B2C2_USB_READ_V8_MEM:
wMax = USB_MEM_READ_MAX;
break;
@@ -248,13 +248,13 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
/* DKT 020208 - add this to support special case of DiSEqC */
case USB_FUNC_I2C_CHECKWRITE:
pipe = B2C2_USB_CTRL_PIPE_OUT;
- nWaitTime = 2;
+ nWaitTime = 2000;
request_type |= USB_DIR_OUT;
break;
case USB_FUNC_I2C_READ:
case USB_FUNC_I2C_REPEATREAD:
pipe = B2C2_USB_CTRL_PIPE_IN;
- nWaitTime = 2;
+ nWaitTime = 2000;
request_type |= USB_DIR_IN;
break;
default:
@@ -281,7 +281,7 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
wIndex,
fc_usb->data,
buflen,
- nWaitTime * HZ);
+ nWaitTime);
if (ret != buflen)
ret = -EIO;
@@ -341,8 +341,8 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
b = fc_usb->tmp_buffer;
l = fc_usb->tmp_buffer_length;
} else {
- b=buffer;
- l=buffer_length;
+ b = buffer;
+ l = buffer_length;
}
while (l >= 190) {
@@ -368,7 +368,7 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
}
}
- if (l>0)
+ if (l > 0)
memcpy(fc_usb->tmp_buffer, b, l);
fc_usb->tmp_buffer_length = l;
}
@@ -399,7 +399,7 @@ static void flexcop_usb_urb_complete(struct urb *urb)
urb->iso_frame_desc[i].status = 0;
urb->iso_frame_desc[i].actual_length = 0;
}
- usb_submit_urb(urb,GFP_ATOMIC);
+ usb_submit_urb(urb, GFP_ATOMIC);
}
static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff)
@@ -413,7 +413,7 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
int i;
for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
if (fc_usb->iso_urb[i] != NULL) {
- deb_ts("unlinking/killing urb no. %d\n",i);
+ deb_ts("unlinking/killing urb no. %d\n", i);
usb_kill_urb(fc_usb->iso_urb[i]);
usb_free_urb(fc_usb->iso_urb[i]);
}
@@ -483,7 +483,7 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
err("submitting urb %d failed with %d.", i, ret);
goto urb_error;
}
- deb_ts("submitted urb no. %d.\n",i);
+ deb_ts("submitted urb no. %d.\n", i);
}
/* SRAM */
diff --git a/drivers/media/usb/b2c2/flexcop-usb.h b/drivers/media/usb/b2c2/flexcop-usb.h
index 2f230bf72252..c7cca1a5ee59 100644
--- a/drivers/media/usb/b2c2/flexcop-usb.h
+++ b/drivers/media/usb/b2c2/flexcop-usb.h
@@ -91,13 +91,13 @@ typedef enum {
UTILITY_SRAM_TESTVERIFY = 0x16,
} flexcop_usb_utility_function_t;
-#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
-#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
-#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
+#define B2C2_WAIT_FOR_OPERATION_RW 1000
+#define B2C2_WAIT_FOR_OPERATION_RDW 3000
+#define B2C2_WAIT_FOR_OPERATION_WDW 1000
-#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
-#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
-#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8READ 3000
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3000
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3000
typedef enum {
V8_MEMORY_PAGE_DVB_CI = 0x20,
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
index 76aac06f9fb8..cba03b286473 100644
--- a/drivers/media/usb/cpia2/cpia2_usb.c
+++ b/drivers/media/usb/cpia2/cpia2_usb.c
@@ -550,7 +550,7 @@ static int write_packet(struct usb_device *udev,
0, /* index */
buf, /* buffer */
size,
- HZ);
+ 1000);
kfree(buf);
return ret;
@@ -582,7 +582,7 @@ static int read_packet(struct usb_device *udev,
0, /* index */
buf, /* buffer */
size,
- HZ);
+ 1000);
if (ret >= 0)
memcpy(registers, buf, size);
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index fe4d886442a4..8a34e6c0d6a6 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -423,6 +423,9 @@ static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
mutex_unlock(&d->i2c_mutex);
+ if (ret)
+ return -EREMOTEIO;
+
return 0;
}
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 70219b3e8566..1caabb51ea47 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -583,7 +583,7 @@ out:
int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct dib0700_state *st = adap->dev->priv;
- int ret;
+ int ret, adapt_nr;
if ((onoff != 0) && (st->fw_version >= 0x10201)) {
/* for firmware later than 1.20.1,
@@ -610,26 +610,24 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
st->buf[3] = 0x00;
- deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
-
- st->channel_state &= ~0x3;
if ((adap->fe_adap[0].stream.props.endpoint != 2)
- && (adap->fe_adap[0].stream.props.endpoint != 3)) {
- deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint);
- if (onoff)
- st->channel_state |= 1 << (adap->id);
- else
- st->channel_state |= 1 << ~(adap->id);
+ && (adap->fe_adap[0].stream.props.endpoint != 3)) {
+ deb_info("the endpoint number (%i) is not correct, use the adapter id instead\n",
+ adap->fe_adap[0].stream.props.endpoint);
+ adapt_nr = adap->id;
} else {
- if (onoff)
- st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2);
- else
- st->channel_state |= 1 << (3-adap->fe_adap[0].stream.props.endpoint);
+ adapt_nr = adap->fe_adap[0].stream.props.endpoint - 2;
}
+ if (onoff)
+ st->channel_state |= 1 << adapt_nr;
+ else
+ st->channel_state &= ~(1 << adapt_nr);
+
st->buf[2] |= st->channel_state;
- deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
+ deb_info("adapter %d, streaming %s: %*ph\n",
+ adapt_nr, onoff ? "ON" : "OFF", 3, st->buf);
ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
mutex_unlock(&adap->dev->usb_mutex);
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index f0e686b05dc6..ca75ebdc10b3 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -2150,46 +2150,153 @@ static struct dvb_usb_device_properties s6x0_properties = {
}
};
-static const struct dvb_usb_device_description d1100 = {
- "Prof 1100 USB ",
- {&dw2102_table[PROF_1100], NULL},
- {NULL},
-};
+static struct dvb_usb_device_properties p1100_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .size_of_priv = sizeof(struct dw2102_state),
+ .firmware = P1100_FIRMWARE,
+ .no_reconnect = 1,
-static const struct dvb_usb_device_description d660 = {
- "TeVii S660 USB",
- {&dw2102_table[TEVII_S660], NULL},
- {NULL},
-};
+ .i2c_algo = &s6x0_i2c_algo,
+ .rc.core = {
+ .rc_interval = 150,
+ .rc_codes = RC_MAP_TBS_NEC,
+ .module_name = "dw2102",
+ .allowed_protos = RC_PROTO_BIT_NEC,
+ .rc_query = prof_rc_query,
+ },
-static const struct dvb_usb_device_description d480_1 = {
- "TeVii S480.1 USB",
- {&dw2102_table[TEVII_S480_1], NULL},
- {NULL},
+ .generic_bulk_ctrl_endpoint = 0x81,
+ .num_adapters = 1,
+ .download_firmware = dw2102_load_firmware,
+ .read_mac_address = s6x0_read_mac_address,
+ .adapter = {
+ {
+ .num_frontends = 1,
+ .fe = {{
+ .frontend_attach = stv0288_frontend_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ } },
+ }
+ },
+ .num_device_descs = 1,
+ .devices = {
+ {"Prof 1100 USB ",
+ {&dw2102_table[PROF_1100], NULL},
+ {NULL},
+ },
+ }
};
-static const struct dvb_usb_device_description d480_2 = {
- "TeVii S480.2 USB",
- {&dw2102_table[TEVII_S480_2], NULL},
- {NULL},
-};
+static struct dvb_usb_device_properties s660_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .size_of_priv = sizeof(struct dw2102_state),
+ .firmware = S660_FIRMWARE,
+ .no_reconnect = 1,
-static const struct dvb_usb_device_description d7500 = {
- "Prof 7500 USB DVB-S2",
- {&dw2102_table[PROF_7500], NULL},
- {NULL},
-};
+ .i2c_algo = &s6x0_i2c_algo,
+ .rc.core = {
+ .rc_interval = 150,
+ .rc_codes = RC_MAP_TEVII_NEC,
+ .module_name = "dw2102",
+ .allowed_protos = RC_PROTO_BIT_NEC,
+ .rc_query = dw2102_rc_query,
+ },
-static const struct dvb_usb_device_description d421 = {
- "TeVii S421 PCI",
- {&dw2102_table[TEVII_S421], NULL},
- {NULL},
+ .generic_bulk_ctrl_endpoint = 0x81,
+ .num_adapters = 1,
+ .download_firmware = dw2102_load_firmware,
+ .read_mac_address = s6x0_read_mac_address,
+ .adapter = {
+ {
+ .num_frontends = 1,
+ .fe = {{
+ .frontend_attach = ds3000_frontend_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ } },
+ }
+ },
+ .num_device_descs = 3,
+ .devices = {
+ {"TeVii S660 USB",
+ {&dw2102_table[TEVII_S660], NULL},
+ {NULL},
+ },
+ {"TeVii S480.1 USB",
+ {&dw2102_table[TEVII_S480_1], NULL},
+ {NULL},
+ },
+ {"TeVii S480.2 USB",
+ {&dw2102_table[TEVII_S480_2], NULL},
+ {NULL},
+ },
+ }
};
-static const struct dvb_usb_device_description d632 = {
- "TeVii S632 USB",
- {&dw2102_table[TEVII_S632], NULL},
- {NULL},
+static struct dvb_usb_device_properties p7500_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .size_of_priv = sizeof(struct dw2102_state),
+ .firmware = P7500_FIRMWARE,
+ .no_reconnect = 1,
+
+ .i2c_algo = &s6x0_i2c_algo,
+ .rc.core = {
+ .rc_interval = 150,
+ .rc_codes = RC_MAP_TBS_NEC,
+ .module_name = "dw2102",
+ .allowed_protos = RC_PROTO_BIT_NEC,
+ .rc_query = prof_rc_query,
+ },
+
+ .generic_bulk_ctrl_endpoint = 0x81,
+ .num_adapters = 1,
+ .download_firmware = dw2102_load_firmware,
+ .read_mac_address = s6x0_read_mac_address,
+ .adapter = {
+ {
+ .num_frontends = 1,
+ .fe = {{
+ .frontend_attach = prof_7500_frontend_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ } },
+ }
+ },
+ .num_device_descs = 1,
+ .devices = {
+ {"Prof 7500 USB DVB-S2",
+ {&dw2102_table[PROF_7500], NULL},
+ {NULL},
+ },
+ }
};
static struct dvb_usb_device_properties su3000_properties = {
@@ -2273,6 +2380,59 @@ static struct dvb_usb_device_properties su3000_properties = {
}
};
+static struct dvb_usb_device_properties s421_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .size_of_priv = sizeof(struct dw2102_state),
+ .power_ctrl = su3000_power_ctrl,
+ .num_adapters = 1,
+ .identify_state = su3000_identify_state,
+ .i2c_algo = &su3000_i2c_algo,
+
+ .rc.core = {
+ .rc_interval = 150,
+ .rc_codes = RC_MAP_SU3000,
+ .module_name = "dw2102",
+ .allowed_protos = RC_PROTO_BIT_RC5,
+ .rc_query = su3000_rc_query,
+ },
+
+ .read_mac_address = su3000_read_mac_address,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+
+ .adapter = {
+ {
+ .num_frontends = 1,
+ .fe = {{
+ .streaming_ctrl = su3000_streaming_ctrl,
+ .frontend_attach = m88rs2000_frontend_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ }
+ } },
+ }
+ },
+ .num_device_descs = 2,
+ .devices = {
+ { "TeVii S421 PCI",
+ { &dw2102_table[TEVII_S421], NULL },
+ { NULL },
+ },
+ { "TeVii S632 USB",
+ { &dw2102_table[TEVII_S632], NULL },
+ { NULL },
+ },
+ }
+};
+
static struct dvb_usb_device_properties t220_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = DEVICE_SPECIFIC,
@@ -2390,101 +2550,33 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = {
static int dw2102_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- int retval = -ENOMEM;
- struct dvb_usb_device_properties *p1100;
- struct dvb_usb_device_properties *s660;
- struct dvb_usb_device_properties *p7500;
- struct dvb_usb_device_properties *s421;
-
- p1100 = kmemdup(&s6x0_properties,
- sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
- if (!p1100)
- goto err0;
-
- /* copy default structure */
- /* fill only different fields */
- p1100->firmware = P1100_FIRMWARE;
- p1100->devices[0] = d1100;
- p1100->rc.core.rc_query = prof_rc_query;
- p1100->rc.core.rc_codes = RC_MAP_TBS_NEC;
- p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
-
- s660 = kmemdup(&s6x0_properties,
- sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
- if (!s660)
- goto err1;
-
- s660->firmware = S660_FIRMWARE;
- s660->num_device_descs = 3;
- s660->devices[0] = d660;
- s660->devices[1] = d480_1;
- s660->devices[2] = d480_2;
- s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
-
- p7500 = kmemdup(&s6x0_properties,
- sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
- if (!p7500)
- goto err2;
-
- p7500->firmware = P7500_FIRMWARE;
- p7500->devices[0] = d7500;
- p7500->rc.core.rc_query = prof_rc_query;
- p7500->rc.core.rc_codes = RC_MAP_TBS_NEC;
- p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
-
-
- s421 = kmemdup(&su3000_properties,
- sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
- if (!s421)
- goto err3;
-
- s421->num_device_descs = 2;
- s421->devices[0] = d421;
- s421->devices[1] = d632;
- s421->adapter->fe[0].frontend_attach = m88rs2000_frontend_attach;
-
- if (0 == dvb_usb_device_init(intf, &dw2102_properties,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &dw2104_properties,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &dw3101_properties,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &s6x0_properties,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, p1100,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, s660,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, p7500,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, s421,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &su3000_properties,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &t220_properties,
- THIS_MODULE, NULL, adapter_nr) ||
- 0 == dvb_usb_device_init(intf, &tt_s2_4600_properties,
- THIS_MODULE, NULL, adapter_nr)) {
-
- /* clean up copied properties */
- kfree(s421);
- kfree(p7500);
- kfree(s660);
- kfree(p1100);
+ if (!(dvb_usb_device_init(intf, &dw2102_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &dw2104_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &dw3101_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &s6x0_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &p1100_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &s660_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &p7500_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &s421_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &su3000_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &t220_properties,
+ THIS_MODULE, NULL, adapter_nr) &&
+ dvb_usb_device_init(intf, &tt_s2_4600_properties,
+ THIS_MODULE, NULL, adapter_nr))) {
return 0;
}
- retval = -ENODEV;
- kfree(s421);
-err3:
- kfree(p7500);
-err2:
- kfree(s660);
-err1:
- kfree(p1100);
-err0:
- return retval;
+ return -ENODEV;
}
static void dw2102_disconnect(struct usb_interface *intf)
diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
index 4bb5b82599a7..691e05833db1 100644
--- a/drivers/media/usb/dvb-usb/m920x.c
+++ b/drivers/media/usb/dvb-usb/m920x.c
@@ -274,6 +274,13 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
/* Should check for ack here, if we knew how. */
}
if (msg[i].flags & I2C_M_RD) {
+ char *read = kmalloc(1, GFP_KERNEL);
+ if (!read) {
+ ret = -ENOMEM;
+ kfree(read);
+ goto unlock;
+ }
+
for (j = 0; j < msg[i].len; j++) {
/* Last byte of transaction?
* Send STOP, otherwise send ACK. */
@@ -281,9 +288,12 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
0x20 | stop,
- &msg[i].buf[j], 1)) != 0)
+ read, 1)) != 0)
goto unlock;
+ msg[i].buf[j] = read[0];
}
+
+ kfree(read);
} else {
for (j = 0; j < msg[i].len; j++) {
/* Last byte of transaction? Then send STOP. */
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index b207f34af5c6..b451ce3cb169 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -3630,8 +3630,10 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
if (dev->is_audio_only) {
retval = em28xx_audio_setup(dev);
- if (retval)
- return -ENODEV;
+ if (retval) {
+ retval = -ENODEV;
+ goto err_deinit_media;
+ }
em28xx_init_extension(dev);
return 0;
@@ -3650,7 +3652,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
dev_err(&dev->intf->dev,
"%s: em28xx_i2c_register bus 0 - error [%d]!\n",
__func__, retval);
- return retval;
+ goto err_deinit_media;
}
/* register i2c bus 1 */
@@ -3666,9 +3668,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
"%s: em28xx_i2c_register bus 1 - error [%d]!\n",
__func__, retval);
- em28xx_i2c_unregister(dev, 0);
-
- return retval;
+ goto err_unreg_i2c;
}
}
@@ -3676,6 +3676,12 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
em28xx_card_setup(dev);
return 0;
+
+err_unreg_i2c:
+ em28xx_i2c_unregister(dev, 0);
+err_deinit_media:
+ em28xx_unregister_media_device(dev);
+ return retval;
}
static int em28xx_duplicate_dev(struct em28xx *dev)
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index acc0bf7dbe2b..c837cc528a33 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -89,7 +89,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
mutex_lock(&dev->ctrl_urb_lock);
ret = usb_control_msg(udev, pipe, req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0000, reg, dev->urb_buf, len, HZ);
+ 0x0000, reg, dev->urb_buf, len, 1000);
if (ret < 0) {
em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n",
pipe,
@@ -158,7 +158,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
memcpy(dev->urb_buf, buf, len);
ret = usb_control_msg(udev, pipe, req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0000, reg, dev->urb_buf, len, HZ);
+ 0x0000, reg, dev->urb_buf, len, 1000);
mutex_unlock(&dev->ctrl_urb_lock);
if (ret < 0) {
diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
index 6650eab913d8..0c24e2984304 100644
--- a/drivers/media/usb/go7007/go7007-driver.c
+++ b/drivers/media/usb/go7007/go7007-driver.c
@@ -516,7 +516,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
if (vb && vb->vb.vb2_buf.planes[0].bytesused >=
GO7007_BUF_SIZE - 3) {
v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
- vb->vb.vb2_buf.planes[0].bytesused = 0;
+ vb2_set_plane_payload(&vb->vb.vb2_buf, 0, 0);
vb->frame_offset = 0;
vb->modet_active = 0;
vb = go->active_buf = NULL;
diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
index bc4008d5d116..8ef010a87445 100644
--- a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
@@ -339,14 +339,13 @@ int s5k83a_start(struct sd *sd)
/* Create another thread, polling the GPIO ports of the camera to check
if it got rotated. This is how the windows driver does it so we have
to assume that there is no better way of accomplishing this */
- sd->rotation_thread = kthread_create(rotation_thread_function,
- sd, "rotation thread");
+ sd->rotation_thread = kthread_run(rotation_thread_function,
+ sd, "rotation thread");
if (IS_ERR(sd->rotation_thread)) {
err = PTR_ERR(sd->rotation_thread);
sd->rotation_thread = NULL;
return err;
}
- wake_up_process(sd->rotation_thread);
/* Preinit the sensor */
for (i = 0; i < ARRAY_SIZE(start_s5k83a) && !err; i++) {
@@ -408,25 +407,21 @@ static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
{
- int err;
u8 data[1];
struct sd *sd = (struct sd *) gspca_dev;
data[0] = val;
- err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
- return err;
+ return m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
}
static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
{
- int err;
u8 data[2];
struct sd *sd = (struct sd *) gspca_dev;
data[0] = 0;
data[1] = val;
- err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
- return err;
+ return m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
}
static int s5k83a_set_flip_real(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
index f6005d1296ef..c8102772344b 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c
@@ -188,8 +188,8 @@ static int pvr2_encoder_cmd(void *ctxt,
}
- LOCK_TAKE(hdw->ctl_lock); while (1) {
-
+ LOCK_TAKE(hdw->ctl_lock);
+ while (1) {
if (!hdw->state_encoder_ok) {
ret = -EIO;
break;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index d38dee1792e4..cd7b118d5929 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -1467,7 +1467,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
for (address = 0; address < fwsize; address += 0x800) {
memcpy(fw_ptr, fw_entry->data + address, 0x800);
ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
- 0, fw_ptr, 0x800, HZ);
+ 0, fw_ptr, 0x800, 1000);
}
trace_firmware("Upload done, releasing device's CPU");
@@ -1605,7 +1605,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]);
ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
- &actual_length, HZ);
+ &actual_length, 1000);
ret |= (actual_length != bcnt);
if (ret) break;
fw_done += bcnt;
@@ -1718,16 +1718,16 @@ int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
{
int ret,st;
- LOCK_TAKE(hdw->big_lock); do {
- pvr2_hdw_untrip_unlocked(hdw);
- if ((!enable_flag) != !(hdw->state_pipeline_req)) {
- hdw->state_pipeline_req = enable_flag != 0;
- pvr2_trace(PVR2_TRACE_START_STOP,
- "/*--TRACE_STREAM--*/ %s",
- enable_flag ? "enable" : "disable");
- }
- pvr2_hdw_state_sched(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
+ LOCK_TAKE(hdw->big_lock);
+ pvr2_hdw_untrip_unlocked(hdw);
+ if (!enable_flag != !hdw->state_pipeline_req) {
+ hdw->state_pipeline_req = enable_flag != 0;
+ pvr2_trace(PVR2_TRACE_START_STOP,
+ "/*--TRACE_STREAM--*/ %s",
+ enable_flag ? "enable" : "disable");
+ }
+ pvr2_hdw_state_sched(hdw);
+ LOCK_GIVE(hdw->big_lock);
if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret;
if (enable_flag) {
while ((st = hdw->master_state) != PVR2_STATE_RUN) {
@@ -3394,7 +3394,8 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
int ret;
u16 address;
unsigned int pipe;
- LOCK_TAKE(hdw->big_lock); do {
+ LOCK_TAKE(hdw->big_lock);
+ do {
if ((hdw->fw_buffer == NULL) == !enable_flag) break;
if (!enable_flag) {
@@ -3438,7 +3439,7 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
0xa0,0xc0,
address,0,
hdw->fw_buffer+address,
- 0x800,HZ);
+ 0x800,1000);
if (ret < 0) break;
}
@@ -3457,8 +3458,8 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
pvr2_trace(PVR2_TRACE_FIRMWARE,
"Done sucking down EEPROM contents");
}
-
- } while (0); LOCK_GIVE(hdw->big_lock);
+ } while (0);
+ LOCK_GIVE(hdw->big_lock);
}
@@ -3473,7 +3474,8 @@ int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
char *buf,unsigned int cnt)
{
int ret = -EINVAL;
- LOCK_TAKE(hdw->big_lock); do {
+ LOCK_TAKE(hdw->big_lock);
+ do {
if (!buf) break;
if (!cnt) break;
@@ -3498,7 +3500,8 @@ int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
"Read firmware data offs=%d cnt=%d",
offs,cnt);
ret = cnt;
- } while (0); LOCK_GIVE(hdw->big_lock);
+ } while (0);
+ LOCK_GIVE(hdw->big_lock);
return ret;
}
@@ -3977,7 +3980,7 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
/* Write the CPUCS register on the 8051. The lsb of the register
is the reset bit; a 1 asserts reset while a 0 clears it. */
pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
- ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
+ ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,1000);
if (ret < 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"cpureset_assert(%d) error=%d",val,ret);
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 3b0e4ed75d99..acf18e2251a5 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -1882,7 +1882,7 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_DIR_IN,
Value, Index, buf,
- TransferBufferLength, HZ * 5);
+ TransferBufferLength, USB_CTRL_SET_TIMEOUT);
if (r >= 0)
memcpy(TransferBuffer, buf, TransferBufferLength);
@@ -1891,7 +1891,7 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Value, Index, buf,
- TransferBufferLength, HZ * 5);
+ TransferBufferLength, USB_CTRL_SET_TIMEOUT);
}
kfree(buf);
return r;
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index df4c5dcba39c..fe9c7b3a950e 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -661,10 +661,6 @@ static const struct usb_device_id smsusb_id_table[] = {
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0x5590),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x187f, 0x0202),
- .driver_info = SMS1XXX_BOARD_SIANO_NICE },
- { USB_DEVICE(0x187f, 0x0301),
- .driver_info = SMS1XXX_BOARD_SIANO_VENICE },
{ USB_DEVICE(0x2040, 0xb900),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0xb910),
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c
index b4f8bc5db138..4e1698f78818 100644
--- a/drivers/media/usb/stk1160/stk1160-core.c
+++ b/drivers/media/usb/stk1160/stk1160-core.c
@@ -65,7 +65,7 @@ int stk1160_read_reg(struct stk1160 *dev, u16 reg, u8 *value)
return -ENOMEM;
ret = usb_control_msg(dev->udev, pipe, 0x00,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, reg, buf, sizeof(u8), HZ);
+ 0x00, reg, buf, sizeof(u8), 1000);
if (ret < 0) {
stk1160_err("read failed on reg 0x%x (%d)\n",
reg, ret);
@@ -85,7 +85,7 @@ int stk1160_write_reg(struct stk1160 *dev, u16 reg, u16 value)
ret = usb_control_msg(dev->udev, pipe, 0x01,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, reg, NULL, 0, HZ);
+ value, reg, NULL, 0, 1000);
if (ret < 0) {
stk1160_err("write failed on reg 0x%x (%d)\n",
reg, ret);
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 30bfe9069a1f..b4f6edf968bc 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1638,8 +1638,8 @@ static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,
struct v4l2_ext_controls *ctrls,
struct uvc_control *uvc_control)
{
- struct uvc_control_mapping *mapping;
- struct uvc_control *ctrl_found;
+ struct uvc_control_mapping *mapping = NULL;
+ struct uvc_control *ctrl_found = NULL;
unsigned int i;
if (!entity)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 7c007426e082..5f394d4efc21 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -256,7 +256,7 @@ static struct uvc_format_desc *uvc_format_by_guid(const u8 guid[16])
static enum v4l2_colorspace uvc_colorspace(const u8 primaries)
{
static const enum v4l2_colorspace colorprimaries[] = {
- V4L2_COLORSPACE_DEFAULT, /* Unspecified */
+ V4L2_COLORSPACE_SRGB, /* Unspecified */
V4L2_COLORSPACE_SRGB,
V4L2_COLORSPACE_470_SYSTEM_M,
V4L2_COLORSPACE_470_SYSTEM_BG,
@@ -267,7 +267,7 @@ static enum v4l2_colorspace uvc_colorspace(const u8 primaries)
if (primaries < ARRAY_SIZE(colorprimaries))
return colorprimaries[primaries];
- return V4L2_COLORSPACE_DEFAULT; /* Reserved */
+ return V4L2_COLORSPACE_SRGB; /* Reserved */
}
static enum v4l2_xfer_func uvc_xfer_func(const u8 transfer_characteristics)
@@ -769,6 +769,8 @@ static int uvc_parse_format(struct uvc_device *dev,
buflen -= buffer[0];
buffer += buffer[0];
+ } else {
+ format->colorspace = V4L2_COLORSPACE_SRGB;
}
return buffer - start;
@@ -2193,7 +2195,6 @@ int uvc_register_video_device(struct uvc_device *dev,
const struct v4l2_file_operations *fops,
const struct v4l2_ioctl_ops *ioctl_ops)
{
- const char *name;
int ret;
/* Initialize the video buffers queue. */
@@ -2222,20 +2223,16 @@ int uvc_register_video_device(struct uvc_device *dev,
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
default:
vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- name = "Video Capture";
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
- name = "Video Output";
break;
case V4L2_BUF_TYPE_META_CAPTURE:
vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
- name = "Metadata";
break;
}
- snprintf(vdev->name, sizeof(vdev->name), "%s %u", name,
- stream->header.bTerminalLink);
+ strscpy(vdev->name, dev->name, sizeof(vdev->name));
/*
* Set the driver data before calling video_register_device, otherwise
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index f4e4aff8ddf7..711556d13d03 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -44,8 +44,10 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
if (v4l2_ctrl_get_name(map->id) == NULL) {
map->name = kmemdup(xmap->name, sizeof(xmap->name),
GFP_KERNEL);
- if (!map->name)
- return -ENOMEM;
+ if (!map->name) {
+ ret = -ENOMEM;
+ goto free_map;
+ }
}
memcpy(map->entity, xmap->entity, sizeof(map->entity));
map->selector = xmap->selector;
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 9f37eaf28ce7..1b4cc934109e 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1963,6 +1963,10 @@ static int uvc_video_start_transfer(struct uvc_streaming *stream,
if (ep == NULL)
return -EIO;
+ /* Reject broken descriptors. */
+ if (usb_endpoint_maxp(&ep->desc) == 0)
+ return -EIO;
+
ret = uvc_init_video_bulk(stream, ep, gfp_flags);
}
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 2e5366143b81..143230b3275b 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -189,7 +189,7 @@
/* Maximum status buffer size in bytes of interrupt URB. */
#define UVC_MAX_STATUS_SIZE 16
-#define UVC_CTRL_CONTROL_TIMEOUT 500
+#define UVC_CTRL_CONTROL_TIMEOUT 5000
#define UVC_CTRL_STREAMING_TIMEOUT 5000
/* Maximum allowed number of control mappings per device */
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 02dc1787e953..6ee75c6c820e 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -52,6 +52,10 @@ config V4L2_JPEG_HELPER
config V4L2_H264
tristate
+# Used by drivers that need v4l2-vp9.ko
+config V4L2_VP9
+ tristate
+
# Used by drivers that need v4l2-mem2mem.ko
config V4L2_MEM2MEM_DEV
tristate
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 66a78c556c98..83fac5c746f5 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_VIDEO_TUNER) += tuner.o
obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
obj-$(CONFIG_V4L2_H264) += v4l2-h264.o
+obj-$(CONFIG_V4L2_VP9) += v4l2-vp9.o
obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 70adfc1b9c81..54abe5245dcc 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -283,6 +283,12 @@ static void std_log(const struct v4l2_ctrl *ctrl)
case V4L2_CTRL_TYPE_MPEG2_PICTURE:
pr_cont("MPEG2_PICTURE");
break;
+ case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR:
+ pr_cont("VP9_COMPRESSED_HDR");
+ break;
+ case V4L2_CTRL_TYPE_VP9_FRAME:
+ pr_cont("VP9_FRAME");
+ break;
default:
pr_cont("unknown type %d", ctrl->type);
break;
@@ -317,6 +323,168 @@ static void std_log(const struct v4l2_ctrl *ctrl)
#define zero_reserved(s) \
memset(&(s).reserved, 0, sizeof((s).reserved))
+static int
+validate_vp9_lf_params(struct v4l2_vp9_loop_filter *lf)
+{
+ unsigned int i;
+
+ if (lf->flags & ~(V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED |
+ V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE))
+ return -EINVAL;
+
+ /* That all values are in the accepted range. */
+ if (lf->level > GENMASK(5, 0))
+ return -EINVAL;
+
+ if (lf->sharpness > GENMASK(2, 0))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++)
+ if (lf->ref_deltas[i] < -63 || lf->ref_deltas[i] > 63)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++)
+ if (lf->mode_deltas[i] < -63 || lf->mode_deltas[i] > 63)
+ return -EINVAL;
+
+ zero_reserved(*lf);
+ return 0;
+}
+
+static int
+validate_vp9_quant_params(struct v4l2_vp9_quantization *quant)
+{
+ if (quant->delta_q_y_dc < -15 || quant->delta_q_y_dc > 15 ||
+ quant->delta_q_uv_dc < -15 || quant->delta_q_uv_dc > 15 ||
+ quant->delta_q_uv_ac < -15 || quant->delta_q_uv_ac > 15)
+ return -EINVAL;
+
+ zero_reserved(*quant);
+ return 0;
+}
+
+static int
+validate_vp9_seg_params(struct v4l2_vp9_segmentation *seg)
+{
+ unsigned int i, j;
+
+ if (seg->flags & ~(V4L2_VP9_SEGMENTATION_FLAG_ENABLED |
+ V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP |
+ V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE |
+ V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA |
+ V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(seg->feature_enabled); i++) {
+ if (seg->feature_enabled[i] &
+ ~V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK)
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(seg->feature_data); i++) {
+ const int range[] = { 255, 63, 3, 0 };
+
+ for (j = 0; j < ARRAY_SIZE(seg->feature_data[j]); j++) {
+ if (seg->feature_data[i][j] < -range[j] ||
+ seg->feature_data[i][j] > range[j])
+ return -EINVAL;
+ }
+ }
+
+ zero_reserved(*seg);
+ return 0;
+}
+
+static int
+validate_vp9_compressed_hdr(struct v4l2_ctrl_vp9_compressed_hdr *hdr)
+{
+ if (hdr->tx_mode > V4L2_VP9_TX_MODE_SELECT)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int
+validate_vp9_frame(struct v4l2_ctrl_vp9_frame *frame)
+{
+ int ret;
+
+ /* Make sure we're not passed invalid flags. */
+ if (frame->flags & ~(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+ V4L2_VP9_FRAME_FLAG_SHOW_FRAME |
+ V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT |
+ V4L2_VP9_FRAME_FLAG_INTRA_ONLY |
+ V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV |
+ V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX |
+ V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE |
+ V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
+ V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING |
+ V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING))
+ return -EINVAL;
+
+ if (frame->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT &&
+ frame->flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX)
+ return -EINVAL;
+
+ if (frame->profile > V4L2_VP9_PROFILE_MAX)
+ return -EINVAL;
+
+ if (frame->reset_frame_context > V4L2_VP9_RESET_FRAME_CTX_ALL)
+ return -EINVAL;
+
+ if (frame->frame_context_idx >= V4L2_VP9_NUM_FRAME_CTX)
+ return -EINVAL;
+
+ /*
+ * Profiles 0 and 1 only support 8-bit depth, profiles 2 and 3 only 10
+ * and 12 bit depths.
+ */
+ if ((frame->profile < 2 && frame->bit_depth != 8) ||
+ (frame->profile >= 2 &&
+ (frame->bit_depth != 10 && frame->bit_depth != 12)))
+ return -EINVAL;
+
+ /* Profile 0 and 2 only accept YUV 4:2:0. */
+ if ((frame->profile == 0 || frame->profile == 2) &&
+ (!(frame->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) ||
+ !(frame->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING)))
+ return -EINVAL;
+
+ /* Profile 1 and 3 only accept YUV 4:2:2, 4:4:0 and 4:4:4. */
+ if ((frame->profile == 1 || frame->profile == 3) &&
+ ((frame->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) &&
+ (frame->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING)))
+ return -EINVAL;
+
+ if (frame->interpolation_filter > V4L2_VP9_INTERP_FILTER_SWITCHABLE)
+ return -EINVAL;
+
+ /*
+ * According to the spec, tile_cols_log2 shall be less than or equal
+ * to 6.
+ */
+ if (frame->tile_cols_log2 > 6)
+ return -EINVAL;
+
+ if (frame->reference_mode > V4L2_VP9_REFERENCE_MODE_SELECT)
+ return -EINVAL;
+
+ ret = validate_vp9_lf_params(&frame->lf);
+ if (ret)
+ return ret;
+
+ ret = validate_vp9_quant_params(&frame->quant);
+ if (ret)
+ return ret;
+
+ ret = validate_vp9_seg_params(&frame->seg);
+ if (ret)
+ return ret;
+
+ zero_reserved(*frame);
+ return 0;
+}
+
/*
* Compound controls validation requires setting unused fields/flags to zero
* in order to properly detect unchanged controls with std_equal's memcmp.
@@ -690,6 +858,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
break;
+ case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR:
+ return validate_vp9_compressed_hdr(p);
+
+ case V4L2_CTRL_TYPE_VP9_FRAME:
+ return validate_vp9_frame(p);
+
case V4L2_CTRL_TYPE_AREA:
area = p;
if (!area->width || !area->height)
@@ -1255,6 +1429,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY:
elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display);
break;
+ case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR:
+ elem_size = sizeof(struct v4l2_ctrl_vp9_compressed_hdr);
+ break;
+ case V4L2_CTRL_TYPE_VP9_FRAME:
+ elem_size = sizeof(struct v4l2_ctrl_vp9_frame);
+ break;
case V4L2_CTRL_TYPE_AREA:
elem_size = sizeof(struct v4l2_area);
break;
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index ebe82b6ba6e6..54ca4e6b820b 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -785,6 +785,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers";
case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr";
+ case V4L2_CID_COLORFX_RGB: return "Color Effects, RGB";
/*
* Codec controls
@@ -1177,6 +1178,8 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_STATELESS_MPEG2_SEQUENCE: return "MPEG-2 Sequence Header";
case V4L2_CID_STATELESS_MPEG2_PICTURE: return "MPEG-2 Picture Header";
case V4L2_CID_STATELESS_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices";
+ case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR: return "VP9 Probabilities Updates";
+ case V4L2_CID_STATELESS_VP9_FRAME: return "VP9 Frame Decode Parameters";
/* Colorimetry controls */
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
@@ -1394,11 +1397,18 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
*min = *max = *step = *def = 0;
break;
case V4L2_CID_BG_COLOR:
+ case V4L2_CID_COLORFX_RGB:
*type = V4L2_CTRL_TYPE_INTEGER;
*step = 1;
*min = 0;
- /* Max is calculated as RGB888 that is 2^24 */
- *max = 0xFFFFFF;
+ /* Max is calculated as RGB888 that is 2^24 - 1 */
+ *max = 0xffffff;
+ break;
+ case V4L2_CID_COLORFX_CBCR:
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ *step = 1;
+ *min = 0;
+ *max = 0xffff;
break;
case V4L2_CID_FLASH_FAULT:
case V4L2_CID_JPEG_ACTIVE_MARKER:
@@ -1498,6 +1508,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
break;
+ case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR:
+ *type = V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR;
+ break;
+ case V4L2_CID_STATELESS_VP9_FRAME:
+ *type = V4L2_CTRL_TYPE_VP9_FRAME;
+ break;
case V4L2_CID_UNIT_CELL_SIZE:
*type = V4L2_CTRL_TYPE_AREA;
*flags |= V4L2_CTRL_FLAG_READ_ONLY;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 31d0109ce5a8..9ac557b8e146 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1413,6 +1413,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_VP8: descr = "VP8"; break;
case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break;
case V4L2_PIX_FMT_VP9: descr = "VP9"; break;
+ case V4L2_PIX_FMT_VP9_FRAME: descr = "VP9 Frame"; break;
case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */
case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break;
case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */
@@ -2090,6 +2091,7 @@ static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
+ struct video_device *vfd = video_devdata(file);
struct v4l2_streamparm *p = arg;
v4l2_std_id std;
int ret = check_fmt(file, p->type);
@@ -2101,7 +2103,8 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
return -EINVAL;
- p->parm.capture.readbuffers = 2;
+ if (vfd->device_caps & V4L2_CAP_READWRITE)
+ p->parm.capture.readbuffers = 2;
ret = ops->vidioc_g_std(file, fh, &std);
if (ret == 0)
v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index e7f4bf5bc8dd..e2654b422334 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -966,6 +966,27 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
}
EXPORT_SYMBOL(v4l2_m2m_mmap);
+#ifndef CONFIG_MMU
+unsigned long v4l2_m2m_get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags)
+{
+ struct v4l2_fh *fh = file->private_data;
+ unsigned long offset = pgoff << PAGE_SHIFT;
+ struct vb2_queue *vq;
+
+ if (offset < DST_QUEUE_OFF_BASE) {
+ vq = v4l2_m2m_get_src_vq(fh->m2m_ctx);
+ } else {
+ vq = v4l2_m2m_get_dst_vq(fh->m2m_ctx);
+ pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
+ }
+
+ return vb2_get_unmapped_area(vq, addr, len, pgoff, flags);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_get_unmapped_area);
+#endif
+
#if defined(CONFIG_MEDIA_CONTROLLER)
void v4l2_m2m_unregister_media_controller(struct v4l2_m2m_dev *m2m_dev)
{
diff --git a/drivers/media/v4l2-core/v4l2-vp9.c b/drivers/media/v4l2-core/v4l2-vp9.c
new file mode 100644
index 000000000000..859589f1fd35
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-vp9.c
@@ -0,0 +1,1850 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * V4L2 VP9 helpers.
+ *
+ * Copyright (C) 2021 Collabora, Ltd.
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+ */
+
+#include <linux/module.h>
+
+#include <media/v4l2-vp9.h>
+
+const u8 v4l2_vp9_kf_y_mode_prob[10][10][9] = {
+ {
+ /* above = dc */
+ { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, /*left = dc */
+ { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, /*left = v */
+ { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, /*left = h */
+ { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, /*left = d45 */
+ { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, /*left = d135*/
+ { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, /*left = d117*/
+ { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, /*left = d153*/
+ { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, /*left = d207*/
+ { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, /*left = d63 */
+ { 59, 67, 44, 140, 161, 202, 78, 67, 119 }, /*left = tm */
+ }, { /* above = v */
+ { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, /*left = dc */
+ { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, /*left = v */
+ { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, /*left = h */
+ { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, /*left = d45 */
+ { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, /*left = d135*/
+ { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, /*left = d117*/
+ { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, /*left = d153*/
+ { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, /*left = d207*/
+ { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, /*left = d63 */
+ { 36, 61, 116, 114, 128, 162, 80, 125, 82 }, /*left = tm */
+ }, { /* above = h */
+ { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, /*left = dc */
+ { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, /*left = v */
+ { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, /*left = h */
+ { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, /*left = d45 */
+ { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, /*left = d135*/
+ { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, /*left = d117*/
+ { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, /*left = d153*/
+ { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, /*left = d207*/
+ { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, /*left = d63 */
+ { 38, 72, 19, 168, 203, 212, 50, 50, 107 }, /*left = tm */
+ }, { /* above = d45 */
+ { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, /*left = dc */
+ { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, /*left = v */
+ { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, /*left = h */
+ { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, /*left = d45 */
+ { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, /*left = d135*/
+ { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, /*left = d117*/
+ { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, /*left = d153*/
+ { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, /*left = d207*/
+ { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, /*left = d63 */
+ { 47, 47, 43, 114, 137, 181, 100, 99, 95 }, /*left = tm */
+ }, { /* above = d135 */
+ { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, /*left = dc */
+ { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, /*left = v */
+ { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, /*left = h */
+ { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, /*left = d45 */
+ { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, /*left = d135*/
+ { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, /*left = d117*/
+ { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, /*left = d153*/
+ { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, /*left = d207*/
+ { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, /*left = d63 */
+ { 47, 54, 34, 146, 108, 203, 72, 103, 151 }, /*left = tm */
+ }, { /* above = d117 */
+ { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, /*left = dc */
+ { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, /*left = v */
+ { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, /*left = h */
+ { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, /*left = d45 */
+ { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, /*left = d135*/
+ { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, /*left = d117*/
+ { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, /*left = d153*/
+ { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, /*left = d207*/
+ { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, /*left = d63 */
+ { 38, 44, 51, 136, 74, 162, 57, 97, 121 }, /*left = tm */
+ }, { /* above = d153 */
+ { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, /*left = dc */
+ { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, /*left = v */
+ { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, /*left = h */
+ { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, /*left = d45 */
+ { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, /*left = d135*/
+ { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, /*left = d117*/
+ { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, /*left = d153*/
+ { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, /*left = d207*/
+ { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, /*left = d63 */
+ { 37, 49, 25, 129, 168, 164, 41, 54, 148 }, /*left = tm */
+ }, { /* above = d207 */
+ { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, /*left = dc */
+ { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, /*left = v */
+ { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, /*left = h */
+ { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, /*left = d45 */
+ { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, /*left = d135*/
+ { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, /*left = d117*/
+ { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, /*left = d153*/
+ { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, /*left = d207*/
+ { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, /*left = d63 */
+ { 40, 61, 26, 126, 152, 206, 61, 59, 93 }, /*left = tm */
+ }, { /* above = d63 */
+ { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, /*left = dc */
+ { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, /*left = v */
+ { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, /*left = h */
+ { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, /*left = d45 */
+ { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, /*left = d135*/
+ { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, /*left = d117*/
+ { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, /*left = d153*/
+ { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, /*left = d207*/
+ { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, /*left = d63 */
+ { 36, 38, 48, 92, 122, 165, 88, 137, 91 }, /*left = tm */
+ }, { /* above = tm */
+ { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, /*left = dc */
+ { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, /*left = v */
+ { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, /*left = h */
+ { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, /*left = d45 */
+ { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, /*left = d135*/
+ { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, /*left = d117*/
+ { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, /*left = d153*/
+ { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, /*left = d207*/
+ { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, /*left = d63 */
+ { 43, 81, 53, 140, 169, 204, 68, 84, 72 }, /*left = tm */
+ }
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_kf_y_mode_prob);
+
+const u8 v4l2_vp9_kf_partition_probs[16][3] = {
+ /* 8x8 -> 4x4 */
+ { 158, 97, 94 }, /* a/l both not split */
+ { 93, 24, 99 }, /* a split, l not split */
+ { 85, 119, 44 }, /* l split, a not split */
+ { 62, 59, 67 }, /* a/l both split */
+ /* 16x16 -> 8x8 */
+ { 149, 53, 53 }, /* a/l both not split */
+ { 94, 20, 48 }, /* a split, l not split */
+ { 83, 53, 24 }, /* l split, a not split */
+ { 52, 18, 18 }, /* a/l both split */
+ /* 32x32 -> 16x16 */
+ { 150, 40, 39 }, /* a/l both not split */
+ { 78, 12, 26 }, /* a split, l not split */
+ { 67, 33, 11 }, /* l split, a not split */
+ { 24, 7, 5 }, /* a/l both split */
+ /* 64x64 -> 32x32 */
+ { 174, 35, 49 }, /* a/l both not split */
+ { 68, 11, 27 }, /* a split, l not split */
+ { 57, 15, 9 }, /* l split, a not split */
+ { 12, 3, 3 }, /* a/l both split */
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_kf_partition_probs);
+
+const u8 v4l2_vp9_kf_uv_mode_prob[10][9] = {
+ { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, /* y = dc */
+ { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, /* y = v */
+ { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, /* y = h */
+ { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, /* y = d45 */
+ { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, /* y = d135 */
+ { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, /* y = d117 */
+ { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, /* y = d153 */
+ { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, /* y = d207 */
+ { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, /* y = d63 */
+ { 102, 19, 66, 162, 182, 122, 35, 59, 128 } /* y = tm */
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_kf_uv_mode_prob);
+
+const struct v4l2_vp9_frame_context v4l2_vp9_default_probs = {
+ .tx8 = {
+ { 100 },
+ { 66 },
+ },
+ .tx16 = {
+ { 20, 152 },
+ { 15, 101 },
+ },
+ .tx32 = {
+ { 3, 136, 37 },
+ { 5, 52, 13 },
+ },
+ .coef = {
+ { /* tx = 4x4 */
+ { /* block Type 0 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 195, 29, 183 },
+ { 84, 49, 136 },
+ { 8, 42, 71 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 31, 107, 169 },
+ { 35, 99, 159 },
+ { 17, 82, 140 },
+ { 8, 66, 114 },
+ { 2, 44, 76 },
+ { 1, 19, 32 },
+ },
+ { /* Coeff Band 2 */
+ { 40, 132, 201 },
+ { 29, 114, 187 },
+ { 13, 91, 157 },
+ { 7, 75, 127 },
+ { 3, 58, 95 },
+ { 1, 28, 47 },
+ },
+ { /* Coeff Band 3 */
+ { 69, 142, 221 },
+ { 42, 122, 201 },
+ { 15, 91, 159 },
+ { 6, 67, 121 },
+ { 1, 42, 77 },
+ { 1, 17, 31 },
+ },
+ { /* Coeff Band 4 */
+ { 102, 148, 228 },
+ { 67, 117, 204 },
+ { 17, 82, 154 },
+ { 6, 59, 114 },
+ { 2, 39, 75 },
+ { 1, 15, 29 },
+ },
+ { /* Coeff Band 5 */
+ { 156, 57, 233 },
+ { 119, 57, 212 },
+ { 58, 48, 163 },
+ { 29, 40, 124 },
+ { 12, 30, 81 },
+ { 3, 12, 31 }
+ },
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 191, 107, 226 },
+ { 124, 117, 204 },
+ { 25, 99, 155 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 29, 148, 210 },
+ { 37, 126, 194 },
+ { 8, 93, 157 },
+ { 2, 68, 118 },
+ { 1, 39, 69 },
+ { 1, 17, 33 },
+ },
+ { /* Coeff Band 2 */
+ { 41, 151, 213 },
+ { 27, 123, 193 },
+ { 3, 82, 144 },
+ { 1, 58, 105 },
+ { 1, 32, 60 },
+ { 1, 13, 26 },
+ },
+ { /* Coeff Band 3 */
+ { 59, 159, 220 },
+ { 23, 126, 198 },
+ { 4, 88, 151 },
+ { 1, 66, 114 },
+ { 1, 38, 71 },
+ { 1, 18, 34 },
+ },
+ { /* Coeff Band 4 */
+ { 114, 136, 232 },
+ { 51, 114, 207 },
+ { 11, 83, 155 },
+ { 3, 56, 105 },
+ { 1, 33, 65 },
+ { 1, 17, 34 },
+ },
+ { /* Coeff Band 5 */
+ { 149, 65, 234 },
+ { 121, 57, 215 },
+ { 61, 49, 166 },
+ { 28, 36, 114 },
+ { 12, 25, 76 },
+ { 3, 16, 42 },
+ },
+ },
+ },
+ { /* block Type 1 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 214, 49, 220 },
+ { 132, 63, 188 },
+ { 42, 65, 137 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 85, 137, 221 },
+ { 104, 131, 216 },
+ { 49, 111, 192 },
+ { 21, 87, 155 },
+ { 2, 49, 87 },
+ { 1, 16, 28 },
+ },
+ { /* Coeff Band 2 */
+ { 89, 163, 230 },
+ { 90, 137, 220 },
+ { 29, 100, 183 },
+ { 10, 70, 135 },
+ { 2, 42, 81 },
+ { 1, 17, 33 },
+ },
+ { /* Coeff Band 3 */
+ { 108, 167, 237 },
+ { 55, 133, 222 },
+ { 15, 97, 179 },
+ { 4, 72, 135 },
+ { 1, 45, 85 },
+ { 1, 19, 38 },
+ },
+ { /* Coeff Band 4 */
+ { 124, 146, 240 },
+ { 66, 124, 224 },
+ { 17, 88, 175 },
+ { 4, 58, 122 },
+ { 1, 36, 75 },
+ { 1, 18, 37 },
+ },
+ { /* Coeff Band 5 */
+ { 141, 79, 241 },
+ { 126, 70, 227 },
+ { 66, 58, 182 },
+ { 30, 44, 136 },
+ { 12, 34, 96 },
+ { 2, 20, 47 },
+ },
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 229, 99, 249 },
+ { 143, 111, 235 },
+ { 46, 109, 192 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 82, 158, 236 },
+ { 94, 146, 224 },
+ { 25, 117, 191 },
+ { 9, 87, 149 },
+ { 3, 56, 99 },
+ { 1, 33, 57 },
+ },
+ { /* Coeff Band 2 */
+ { 83, 167, 237 },
+ { 68, 145, 222 },
+ { 10, 103, 177 },
+ { 2, 72, 131 },
+ { 1, 41, 79 },
+ { 1, 20, 39 },
+ },
+ { /* Coeff Band 3 */
+ { 99, 167, 239 },
+ { 47, 141, 224 },
+ { 10, 104, 178 },
+ { 2, 73, 133 },
+ { 1, 44, 85 },
+ { 1, 22, 47 },
+ },
+ { /* Coeff Band 4 */
+ { 127, 145, 243 },
+ { 71, 129, 228 },
+ { 17, 93, 177 },
+ { 3, 61, 124 },
+ { 1, 41, 84 },
+ { 1, 21, 52 },
+ },
+ { /* Coeff Band 5 */
+ { 157, 78, 244 },
+ { 140, 72, 231 },
+ { 69, 58, 184 },
+ { 31, 44, 137 },
+ { 14, 38, 105 },
+ { 8, 23, 61 },
+ },
+ },
+ },
+ },
+ { /* tx = 8x8 */
+ { /* block Type 0 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 125, 34, 187 },
+ { 52, 41, 133 },
+ { 6, 31, 56 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 37, 109, 153 },
+ { 51, 102, 147 },
+ { 23, 87, 128 },
+ { 8, 67, 101 },
+ { 1, 41, 63 },
+ { 1, 19, 29 },
+ },
+ { /* Coeff Band 2 */
+ { 31, 154, 185 },
+ { 17, 127, 175 },
+ { 6, 96, 145 },
+ { 2, 73, 114 },
+ { 1, 51, 82 },
+ { 1, 28, 45 },
+ },
+ { /* Coeff Band 3 */
+ { 23, 163, 200 },
+ { 10, 131, 185 },
+ { 2, 93, 148 },
+ { 1, 67, 111 },
+ { 1, 41, 69 },
+ { 1, 14, 24 },
+ },
+ { /* Coeff Band 4 */
+ { 29, 176, 217 },
+ { 12, 145, 201 },
+ { 3, 101, 156 },
+ { 1, 69, 111 },
+ { 1, 39, 63 },
+ { 1, 14, 23 },
+ },
+ { /* Coeff Band 5 */
+ { 57, 192, 233 },
+ { 25, 154, 215 },
+ { 6, 109, 167 },
+ { 3, 78, 118 },
+ { 1, 48, 69 },
+ { 1, 21, 29 },
+ },
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 202, 105, 245 },
+ { 108, 106, 216 },
+ { 18, 90, 144 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 33, 172, 219 },
+ { 64, 149, 206 },
+ { 14, 117, 177 },
+ { 5, 90, 141 },
+ { 2, 61, 95 },
+ { 1, 37, 57 },
+ },
+ { /* Coeff Band 2 */
+ { 33, 179, 220 },
+ { 11, 140, 198 },
+ { 1, 89, 148 },
+ { 1, 60, 104 },
+ { 1, 33, 57 },
+ { 1, 12, 21 },
+ },
+ { /* Coeff Band 3 */
+ { 30, 181, 221 },
+ { 8, 141, 198 },
+ { 1, 87, 145 },
+ { 1, 58, 100 },
+ { 1, 31, 55 },
+ { 1, 12, 20 },
+ },
+ { /* Coeff Band 4 */
+ { 32, 186, 224 },
+ { 7, 142, 198 },
+ { 1, 86, 143 },
+ { 1, 58, 100 },
+ { 1, 31, 55 },
+ { 1, 12, 22 },
+ },
+ { /* Coeff Band 5 */
+ { 57, 192, 227 },
+ { 20, 143, 204 },
+ { 3, 96, 154 },
+ { 1, 68, 112 },
+ { 1, 42, 69 },
+ { 1, 19, 32 },
+ },
+ },
+ },
+ { /* block Type 1 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 212, 35, 215 },
+ { 113, 47, 169 },
+ { 29, 48, 105 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 74, 129, 203 },
+ { 106, 120, 203 },
+ { 49, 107, 178 },
+ { 19, 84, 144 },
+ { 4, 50, 84 },
+ { 1, 15, 25 },
+ },
+ { /* Coeff Band 2 */
+ { 71, 172, 217 },
+ { 44, 141, 209 },
+ { 15, 102, 173 },
+ { 6, 76, 133 },
+ { 2, 51, 89 },
+ { 1, 24, 42 },
+ },
+ { /* Coeff Band 3 */
+ { 64, 185, 231 },
+ { 31, 148, 216 },
+ { 8, 103, 175 },
+ { 3, 74, 131 },
+ { 1, 46, 81 },
+ { 1, 18, 30 },
+ },
+ { /* Coeff Band 4 */
+ { 65, 196, 235 },
+ { 25, 157, 221 },
+ { 5, 105, 174 },
+ { 1, 67, 120 },
+ { 1, 38, 69 },
+ { 1, 15, 30 },
+ },
+ { /* Coeff Band 5 */
+ { 65, 204, 238 },
+ { 30, 156, 224 },
+ { 7, 107, 177 },
+ { 2, 70, 124 },
+ { 1, 42, 73 },
+ { 1, 18, 34 },
+ },
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 225, 86, 251 },
+ { 144, 104, 235 },
+ { 42, 99, 181 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 85, 175, 239 },
+ { 112, 165, 229 },
+ { 29, 136, 200 },
+ { 12, 103, 162 },
+ { 6, 77, 123 },
+ { 2, 53, 84 },
+ },
+ { /* Coeff Band 2 */
+ { 75, 183, 239 },
+ { 30, 155, 221 },
+ { 3, 106, 171 },
+ { 1, 74, 128 },
+ { 1, 44, 76 },
+ { 1, 17, 28 },
+ },
+ { /* Coeff Band 3 */
+ { 73, 185, 240 },
+ { 27, 159, 222 },
+ { 2, 107, 172 },
+ { 1, 75, 127 },
+ { 1, 42, 73 },
+ { 1, 17, 29 },
+ },
+ { /* Coeff Band 4 */
+ { 62, 190, 238 },
+ { 21, 159, 222 },
+ { 2, 107, 172 },
+ { 1, 72, 122 },
+ { 1, 40, 71 },
+ { 1, 18, 32 },
+ },
+ { /* Coeff Band 5 */
+ { 61, 199, 240 },
+ { 27, 161, 226 },
+ { 4, 113, 180 },
+ { 1, 76, 129 },
+ { 1, 46, 80 },
+ { 1, 23, 41 },
+ },
+ },
+ },
+ },
+ { /* tx = 16x16 */
+ { /* block Type 0 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 7, 27, 153 },
+ { 5, 30, 95 },
+ { 1, 16, 30 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 50, 75, 127 },
+ { 57, 75, 124 },
+ { 27, 67, 108 },
+ { 10, 54, 86 },
+ { 1, 33, 52 },
+ { 1, 12, 18 },
+ },
+ { /* Coeff Band 2 */
+ { 43, 125, 151 },
+ { 26, 108, 148 },
+ { 7, 83, 122 },
+ { 2, 59, 89 },
+ { 1, 38, 60 },
+ { 1, 17, 27 },
+ },
+ { /* Coeff Band 3 */
+ { 23, 144, 163 },
+ { 13, 112, 154 },
+ { 2, 75, 117 },
+ { 1, 50, 81 },
+ { 1, 31, 51 },
+ { 1, 14, 23 },
+ },
+ { /* Coeff Band 4 */
+ { 18, 162, 185 },
+ { 6, 123, 171 },
+ { 1, 78, 125 },
+ { 1, 51, 86 },
+ { 1, 31, 54 },
+ { 1, 14, 23 },
+ },
+ { /* Coeff Band 5 */
+ { 15, 199, 227 },
+ { 3, 150, 204 },
+ { 1, 91, 146 },
+ { 1, 55, 95 },
+ { 1, 30, 53 },
+ { 1, 11, 20 },
+ }
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 19, 55, 240 },
+ { 19, 59, 196 },
+ { 3, 52, 105 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 41, 166, 207 },
+ { 104, 153, 199 },
+ { 31, 123, 181 },
+ { 14, 101, 152 },
+ { 5, 72, 106 },
+ { 1, 36, 52 },
+ },
+ { /* Coeff Band 2 */
+ { 35, 176, 211 },
+ { 12, 131, 190 },
+ { 2, 88, 144 },
+ { 1, 60, 101 },
+ { 1, 36, 60 },
+ { 1, 16, 28 },
+ },
+ { /* Coeff Band 3 */
+ { 28, 183, 213 },
+ { 8, 134, 191 },
+ { 1, 86, 142 },
+ { 1, 56, 96 },
+ { 1, 30, 53 },
+ { 1, 12, 20 },
+ },
+ { /* Coeff Band 4 */
+ { 20, 190, 215 },
+ { 4, 135, 192 },
+ { 1, 84, 139 },
+ { 1, 53, 91 },
+ { 1, 28, 49 },
+ { 1, 11, 20 },
+ },
+ { /* Coeff Band 5 */
+ { 13, 196, 216 },
+ { 2, 137, 192 },
+ { 1, 86, 143 },
+ { 1, 57, 99 },
+ { 1, 32, 56 },
+ { 1, 13, 24 },
+ },
+ },
+ },
+ { /* block Type 1 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 211, 29, 217 },
+ { 96, 47, 156 },
+ { 22, 43, 87 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 78, 120, 193 },
+ { 111, 116, 186 },
+ { 46, 102, 164 },
+ { 15, 80, 128 },
+ { 2, 49, 76 },
+ { 1, 18, 28 },
+ },
+ { /* Coeff Band 2 */
+ { 71, 161, 203 },
+ { 42, 132, 192 },
+ { 10, 98, 150 },
+ { 3, 69, 109 },
+ { 1, 44, 70 },
+ { 1, 18, 29 },
+ },
+ { /* Coeff Band 3 */
+ { 57, 186, 211 },
+ { 30, 140, 196 },
+ { 4, 93, 146 },
+ { 1, 62, 102 },
+ { 1, 38, 65 },
+ { 1, 16, 27 },
+ },
+ { /* Coeff Band 4 */
+ { 47, 199, 217 },
+ { 14, 145, 196 },
+ { 1, 88, 142 },
+ { 1, 57, 98 },
+ { 1, 36, 62 },
+ { 1, 15, 26 },
+ },
+ { /* Coeff Band 5 */
+ { 26, 219, 229 },
+ { 5, 155, 207 },
+ { 1, 94, 151 },
+ { 1, 60, 104 },
+ { 1, 36, 62 },
+ { 1, 16, 28 },
+ }
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 233, 29, 248 },
+ { 146, 47, 220 },
+ { 43, 52, 140 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 100, 163, 232 },
+ { 179, 161, 222 },
+ { 63, 142, 204 },
+ { 37, 113, 174 },
+ { 26, 89, 137 },
+ { 18, 68, 97 },
+ },
+ { /* Coeff Band 2 */
+ { 85, 181, 230 },
+ { 32, 146, 209 },
+ { 7, 100, 164 },
+ { 3, 71, 121 },
+ { 1, 45, 77 },
+ { 1, 18, 30 },
+ },
+ { /* Coeff Band 3 */
+ { 65, 187, 230 },
+ { 20, 148, 207 },
+ { 2, 97, 159 },
+ { 1, 68, 116 },
+ { 1, 40, 70 },
+ { 1, 14, 29 },
+ },
+ { /* Coeff Band 4 */
+ { 40, 194, 227 },
+ { 8, 147, 204 },
+ { 1, 94, 155 },
+ { 1, 65, 112 },
+ { 1, 39, 66 },
+ { 1, 14, 26 },
+ },
+ { /* Coeff Band 5 */
+ { 16, 208, 228 },
+ { 3, 151, 207 },
+ { 1, 98, 160 },
+ { 1, 67, 117 },
+ { 1, 41, 74 },
+ { 1, 17, 31 },
+ },
+ },
+ },
+ },
+ { /* tx = 32x32 */
+ { /* block Type 0 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 17, 38, 140 },
+ { 7, 34, 80 },
+ { 1, 17, 29 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 37, 75, 128 },
+ { 41, 76, 128 },
+ { 26, 66, 116 },
+ { 12, 52, 94 },
+ { 2, 32, 55 },
+ { 1, 10, 16 },
+ },
+ { /* Coeff Band 2 */
+ { 50, 127, 154 },
+ { 37, 109, 152 },
+ { 16, 82, 121 },
+ { 5, 59, 85 },
+ { 1, 35, 54 },
+ { 1, 13, 20 },
+ },
+ { /* Coeff Band 3 */
+ { 40, 142, 167 },
+ { 17, 110, 157 },
+ { 2, 71, 112 },
+ { 1, 44, 72 },
+ { 1, 27, 45 },
+ { 1, 11, 17 },
+ },
+ { /* Coeff Band 4 */
+ { 30, 175, 188 },
+ { 9, 124, 169 },
+ { 1, 74, 116 },
+ { 1, 48, 78 },
+ { 1, 30, 49 },
+ { 1, 11, 18 },
+ },
+ { /* Coeff Band 5 */
+ { 10, 222, 223 },
+ { 2, 150, 194 },
+ { 1, 83, 128 },
+ { 1, 48, 79 },
+ { 1, 27, 45 },
+ { 1, 11, 17 },
+ },
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 36, 41, 235 },
+ { 29, 36, 193 },
+ { 10, 27, 111 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 85, 165, 222 },
+ { 177, 162, 215 },
+ { 110, 135, 195 },
+ { 57, 113, 168 },
+ { 23, 83, 120 },
+ { 10, 49, 61 },
+ },
+ { /* Coeff Band 2 */
+ { 85, 190, 223 },
+ { 36, 139, 200 },
+ { 5, 90, 146 },
+ { 1, 60, 103 },
+ { 1, 38, 65 },
+ { 1, 18, 30 },
+ },
+ { /* Coeff Band 3 */
+ { 72, 202, 223 },
+ { 23, 141, 199 },
+ { 2, 86, 140 },
+ { 1, 56, 97 },
+ { 1, 36, 61 },
+ { 1, 16, 27 },
+ },
+ { /* Coeff Band 4 */
+ { 55, 218, 225 },
+ { 13, 145, 200 },
+ { 1, 86, 141 },
+ { 1, 57, 99 },
+ { 1, 35, 61 },
+ { 1, 13, 22 },
+ },
+ { /* Coeff Band 5 */
+ { 15, 235, 212 },
+ { 1, 132, 184 },
+ { 1, 84, 139 },
+ { 1, 57, 97 },
+ { 1, 34, 56 },
+ { 1, 14, 23 },
+ },
+ },
+ },
+ { /* block Type 1 */
+ { /* Intra */
+ { /* Coeff Band 0 */
+ { 181, 21, 201 },
+ { 61, 37, 123 },
+ { 10, 38, 71 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 47, 106, 172 },
+ { 95, 104, 173 },
+ { 42, 93, 159 },
+ { 18, 77, 131 },
+ { 4, 50, 81 },
+ { 1, 17, 23 },
+ },
+ { /* Coeff Band 2 */
+ { 62, 147, 199 },
+ { 44, 130, 189 },
+ { 28, 102, 154 },
+ { 18, 75, 115 },
+ { 2, 44, 65 },
+ { 1, 12, 19 },
+ },
+ { /* Coeff Band 3 */
+ { 55, 153, 210 },
+ { 24, 130, 194 },
+ { 3, 93, 146 },
+ { 1, 61, 97 },
+ { 1, 31, 50 },
+ { 1, 10, 16 },
+ },
+ { /* Coeff Band 4 */
+ { 49, 186, 223 },
+ { 17, 148, 204 },
+ { 1, 96, 142 },
+ { 1, 53, 83 },
+ { 1, 26, 44 },
+ { 1, 11, 17 },
+ },
+ { /* Coeff Band 5 */
+ { 13, 217, 212 },
+ { 2, 136, 180 },
+ { 1, 78, 124 },
+ { 1, 50, 83 },
+ { 1, 29, 49 },
+ { 1, 14, 23 },
+ },
+ },
+ { /* Inter */
+ { /* Coeff Band 0 */
+ { 197, 13, 247 },
+ { 82, 17, 222 },
+ { 25, 17, 162 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ },
+ { /* Coeff Band 1 */
+ { 126, 186, 247 },
+ { 234, 191, 243 },
+ { 176, 177, 234 },
+ { 104, 158, 220 },
+ { 66, 128, 186 },
+ { 55, 90, 137 },
+ },
+ { /* Coeff Band 2 */
+ { 111, 197, 242 },
+ { 46, 158, 219 },
+ { 9, 104, 171 },
+ { 2, 65, 125 },
+ { 1, 44, 80 },
+ { 1, 17, 91 },
+ },
+ { /* Coeff Band 3 */
+ { 104, 208, 245 },
+ { 39, 168, 224 },
+ { 3, 109, 162 },
+ { 1, 79, 124 },
+ { 1, 50, 102 },
+ { 1, 43, 102 },
+ },
+ { /* Coeff Band 4 */
+ { 84, 220, 246 },
+ { 31, 177, 231 },
+ { 2, 115, 180 },
+ { 1, 79, 134 },
+ { 1, 55, 77 },
+ { 1, 60, 79 },
+ },
+ { /* Coeff Band 5 */
+ { 43, 243, 240 },
+ { 8, 180, 217 },
+ { 1, 115, 166 },
+ { 1, 84, 121 },
+ { 1, 51, 67 },
+ { 1, 16, 6 },
+ },
+ },
+ },
+ },
+ },
+
+ .skip = { 192, 128, 64 },
+ .inter_mode = {
+ { 2, 173, 34 },
+ { 7, 145, 85 },
+ { 7, 166, 63 },
+ { 7, 94, 66 },
+ { 8, 64, 46 },
+ { 17, 81, 31 },
+ { 25, 29, 30 },
+ },
+ .interp_filter = {
+ { 235, 162 },
+ { 36, 255 },
+ { 34, 3 },
+ { 149, 144 },
+ },
+ .is_inter = { 9, 102, 187, 225 },
+ .comp_mode = { 239, 183, 119, 96, 41 },
+ .single_ref = {
+ { 33, 16 },
+ { 77, 74 },
+ { 142, 142 },
+ { 172, 170 },
+ { 238, 247 },
+ },
+ .comp_ref = { 50, 126, 123, 221, 226 },
+ .y_mode = {
+ { 65, 32, 18, 144, 162, 194, 41, 51, 98 },
+ { 132, 68, 18, 165, 217, 196, 45, 40, 78 },
+ { 173, 80, 19, 176, 240, 193, 64, 35, 46 },
+ { 221, 135, 38, 194, 248, 121, 96, 85, 29 },
+ },
+ .uv_mode = {
+ { 120, 7, 76, 176, 208, 126, 28, 54, 103 } /* y = dc */,
+ { 48, 12, 154, 155, 139, 90, 34, 117, 119 } /* y = v */,
+ { 67, 6, 25, 204, 243, 158, 13, 21, 96 } /* y = h */,
+ { 97, 5, 44, 131, 176, 139, 48, 68, 97 } /* y = d45 */,
+ { 83, 5, 42, 156, 111, 152, 26, 49, 152 } /* y = d135 */,
+ { 80, 5, 58, 178, 74, 83, 33, 62, 145 } /* y = d117 */,
+ { 86, 5, 32, 154, 192, 168, 14, 22, 163 } /* y = d153 */,
+ { 85, 5, 32, 156, 216, 148, 19, 29, 73 } /* y = d207 */,
+ { 77, 7, 64, 116, 132, 122, 37, 126, 120 } /* y = d63 */,
+ { 101, 21, 107, 181, 192, 103, 19, 67, 125 } /* y = tm */
+ },
+ .partition = {
+ /* 8x8 -> 4x4 */
+ { 199, 122, 141 } /* a/l both not split */,
+ { 147, 63, 159 } /* a split, l not split */,
+ { 148, 133, 118 } /* l split, a not split */,
+ { 121, 104, 114 } /* a/l both split */,
+ /* 16x16 -> 8x8 */
+ { 174, 73, 87 } /* a/l both not split */,
+ { 92, 41, 83 } /* a split, l not split */,
+ { 82, 99, 50 } /* l split, a not split */,
+ { 53, 39, 39 } /* a/l both split */,
+ /* 32x32 -> 16x16 */
+ { 177, 58, 59 } /* a/l both not split */,
+ { 68, 26, 63 } /* a split, l not split */,
+ { 52, 79, 25 } /* l split, a not split */,
+ { 17, 14, 12 } /* a/l both split */,
+ /* 64x64 -> 32x32 */
+ { 222, 34, 30 } /* a/l both not split */,
+ { 72, 16, 44 } /* a split, l not split */,
+ { 58, 32, 12 } /* l split, a not split */,
+ { 10, 7, 6 } /* a/l both split */,
+ },
+
+ .mv = {
+ .joint = { 32, 64, 96 },
+ .sign = { 128, 128 },
+ .classes = {
+ { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 },
+ { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 },
+ },
+ .class0_bit = { 216, 208 },
+ .bits = {
+ { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240},
+ { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240},
+ },
+ .class0_fr = {
+ {
+ { 128, 128, 64 },
+ { 96, 112, 64 },
+ },
+ {
+ { 128, 128, 64 },
+ { 96, 112, 64 },
+ },
+ },
+ .fr = {
+ { 64, 96, 64 },
+ { 64, 96, 64 },
+ },
+ .class0_hp = { 160, 160 },
+ .hp = { 128, 128 },
+ },
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_default_probs);
+
+static u32 fastdiv(u32 dividend, u16 divisor)
+{
+#define DIV_INV(d) ((u32)(((1ULL << 32) + ((d) - 1)) / (d)))
+#define DIVS_INV(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9) \
+ DIV_INV(d0), DIV_INV(d1), DIV_INV(d2), DIV_INV(d3), \
+ DIV_INV(d4), DIV_INV(d5), DIV_INV(d6), DIV_INV(d7), \
+ DIV_INV(d8), DIV_INV(d9)
+
+ static const u32 inv[] = {
+ DIV_INV(2), DIV_INV(3), DIV_INV(4), DIV_INV(5),
+ DIV_INV(6), DIV_INV(7), DIV_INV(8), DIV_INV(9),
+ DIVS_INV(10, 11, 12, 13, 14, 15, 16, 17, 18, 19),
+ DIVS_INV(20, 21, 22, 23, 24, 25, 26, 27, 28, 29),
+ DIVS_INV(30, 31, 32, 33, 34, 35, 36, 37, 38, 39),
+ DIVS_INV(40, 41, 42, 43, 44, 45, 46, 47, 48, 49),
+ DIVS_INV(50, 51, 52, 53, 54, 55, 56, 57, 58, 59),
+ DIVS_INV(60, 61, 62, 63, 64, 65, 66, 67, 68, 69),
+ DIVS_INV(70, 71, 72, 73, 74, 75, 76, 77, 78, 79),
+ DIVS_INV(80, 81, 82, 83, 84, 85, 86, 87, 88, 89),
+ DIVS_INV(90, 91, 92, 93, 94, 95, 96, 97, 98, 99),
+ DIVS_INV(100, 101, 102, 103, 104, 105, 106, 107, 108, 109),
+ DIVS_INV(110, 111, 112, 113, 114, 115, 116, 117, 118, 119),
+ DIVS_INV(120, 121, 122, 123, 124, 125, 126, 127, 128, 129),
+ DIVS_INV(130, 131, 132, 133, 134, 135, 136, 137, 138, 139),
+ DIVS_INV(140, 141, 142, 143, 144, 145, 146, 147, 148, 149),
+ DIVS_INV(150, 151, 152, 153, 154, 155, 156, 157, 158, 159),
+ DIVS_INV(160, 161, 162, 163, 164, 165, 166, 167, 168, 169),
+ DIVS_INV(170, 171, 172, 173, 174, 175, 176, 177, 178, 179),
+ DIVS_INV(180, 181, 182, 183, 184, 185, 186, 187, 188, 189),
+ DIVS_INV(190, 191, 192, 193, 194, 195, 196, 197, 198, 199),
+ DIVS_INV(200, 201, 202, 203, 204, 205, 206, 207, 208, 209),
+ DIVS_INV(210, 211, 212, 213, 214, 215, 216, 217, 218, 219),
+ DIVS_INV(220, 221, 222, 223, 224, 225, 226, 227, 228, 229),
+ DIVS_INV(230, 231, 232, 233, 234, 235, 236, 237, 238, 239),
+ DIVS_INV(240, 241, 242, 243, 244, 245, 246, 247, 248, 249),
+ DIV_INV(250), DIV_INV(251), DIV_INV(252), DIV_INV(253),
+ DIV_INV(254), DIV_INV(255), DIV_INV(256),
+ };
+
+ if (divisor == 0)
+ return 0;
+ else if (divisor == 1)
+ return dividend;
+
+ if (WARN_ON(divisor - 2 >= ARRAY_SIZE(inv)))
+ return dividend;
+
+ return ((u64)dividend * inv[divisor - 2]) >> 32;
+}
+
+/* 6.3.6 inv_recenter_nonneg(v, m) */
+static int inv_recenter_nonneg(int v, int m)
+{
+ if (v > 2 * m)
+ return v;
+
+ if (v & 1)
+ return m - ((v + 1) >> 1);
+
+ return m + (v >> 1);
+}
+
+/*
+ * part of 6.3.5 inv_remap_prob(deltaProb, prob)
+ * delta = inv_map_table[deltaProb] done by userspace
+ */
+static int update_prob(int delta, int prob)
+{
+ if (!delta)
+ return prob;
+
+ return prob <= 128 ?
+ 1 + inv_recenter_nonneg(delta, prob - 1) :
+ 255 - inv_recenter_nonneg(delta, 255 - prob);
+}
+
+/* Counterpart to 6.3.2 tx_mode_probs() */
+static void update_tx_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(probs->tx8); i++) {
+ u8 *p8x8 = probs->tx8[i];
+ u8 *p16x16 = probs->tx16[i];
+ u8 *p32x32 = probs->tx32[i];
+ const u8 *d8x8 = deltas->tx8[i];
+ const u8 *d16x16 = deltas->tx16[i];
+ const u8 *d32x32 = deltas->tx32[i];
+
+ p8x8[0] = update_prob(d8x8[0], p8x8[0]);
+ p16x16[0] = update_prob(d16x16[0], p16x16[0]);
+ p16x16[1] = update_prob(d16x16[1], p16x16[1]);
+ p32x32[0] = update_prob(d32x32[0], p32x32[0]);
+ p32x32[1] = update_prob(d32x32[1], p32x32[1]);
+ p32x32[2] = update_prob(d32x32[2], p32x32[2]);
+ }
+}
+
+#define BAND_6(band) ((band) == 0 ? 3 : 6)
+
+static void update_coeff(const u8 deltas[6][6][3], u8 probs[6][6][3])
+{
+ int l, m, n;
+
+ for (l = 0; l < 6; l++)
+ for (m = 0; m < BAND_6(l); m++) {
+ u8 *p = probs[l][m];
+ const u8 *d = deltas[l][m];
+
+ for (n = 0; n < 3; n++)
+ p[n] = update_prob(d[n], p[n]);
+ }
+}
+
+/* Counterpart to 6.3.7 read_coef_probs() */
+static void update_coef_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ int i, j, k;
+
+ for (i = 0; i < ARRAY_SIZE(probs->coef); i++) {
+ for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++)
+ for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++)
+ update_coeff(deltas->coef[i][j][k], probs->coef[i][j][k]);
+
+ if (deltas->tx_mode == i)
+ break;
+ }
+}
+
+/* Counterpart to 6.3.8 read_skip_prob() */
+static void update_skip_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(probs->skip); i++)
+ probs->skip[i] = update_prob(deltas->skip[i], probs->skip[i]);
+}
+
+/* Counterpart to 6.3.9 read_inter_mode_probs() */
+static void update_inter_mode_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(probs->inter_mode); i++) {
+ u8 *p = probs->inter_mode[i];
+ const u8 *d = deltas->inter_mode[i];
+
+ p[0] = update_prob(d[0], p[0]);
+ p[1] = update_prob(d[1], p[1]);
+ p[2] = update_prob(d[2], p[2]);
+ }
+}
+
+/* Counterpart to 6.3.10 read_interp_filter_probs() */
+static void update_interp_filter_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(probs->interp_filter); i++) {
+ u8 *p = probs->interp_filter[i];
+ const u8 *d = deltas->interp_filter[i];
+
+ p[0] = update_prob(d[0], p[0]);
+ p[1] = update_prob(d[1], p[1]);
+ }
+}
+
+/* Counterpart to 6.3.11 read_is_inter_probs() */
+static void update_is_inter_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(probs->is_inter); i++)
+ probs->is_inter[i] = update_prob(deltas->is_inter[i], probs->is_inter[i]);
+}
+
+/* 6.3.12 frame_reference_mode() done entirely in userspace */
+
+/* Counterpart to 6.3.13 frame_reference_mode_probs() */
+static void
+update_frame_reference_mode_probs(unsigned int reference_mode,
+ struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i;
+
+ if (reference_mode == V4L2_VP9_REFERENCE_MODE_SELECT)
+ for (i = 0; i < ARRAY_SIZE(probs->comp_mode); i++)
+ probs->comp_mode[i] = update_prob(deltas->comp_mode[i],
+ probs->comp_mode[i]);
+
+ if (reference_mode != V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE)
+ for (i = 0; i < ARRAY_SIZE(probs->single_ref); i++) {
+ u8 *p = probs->single_ref[i];
+ const u8 *d = deltas->single_ref[i];
+
+ p[0] = update_prob(d[0], p[0]);
+ p[1] = update_prob(d[1], p[1]);
+ }
+
+ if (reference_mode != V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE)
+ for (i = 0; i < ARRAY_SIZE(probs->comp_ref); i++)
+ probs->comp_ref[i] = update_prob(deltas->comp_ref[i], probs->comp_ref[i]);
+}
+
+/* Counterpart to 6.3.14 read_y_mode_probs() */
+static void update_y_mode_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(probs->y_mode); i++)
+ for (j = 0; j < ARRAY_SIZE(probs->y_mode[0]); ++j)
+ probs->y_mode[i][j] =
+ update_prob(deltas->y_mode[i][j], probs->y_mode[i][j]);
+}
+
+/* Counterpart to 6.3.15 read_partition_probs() */
+static void update_partition_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas)
+{
+ int i, j;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++) {
+ u8 *p = probs->partition[i * 4 + j];
+ const u8 *d = deltas->partition[i * 4 + j];
+
+ p[0] = update_prob(d[0], p[0]);
+ p[1] = update_prob(d[1], p[1]);
+ p[2] = update_prob(d[2], p[2]);
+ }
+}
+
+static inline int update_mv_prob(int delta, int prob)
+{
+ if (!delta)
+ return prob;
+
+ return delta;
+}
+
+/* Counterpart to 6.3.16 mv_probs() */
+static void update_mv_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ u8 *p = probs->mv.joint;
+ const u8 *d = deltas->mv.joint;
+ unsigned int i, j;
+
+ p[0] = update_mv_prob(d[0], p[0]);
+ p[1] = update_mv_prob(d[1], p[1]);
+ p[2] = update_mv_prob(d[2], p[2]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->mv.sign); i++) {
+ p = probs->mv.sign;
+ d = deltas->mv.sign;
+ p[i] = update_mv_prob(d[i], p[i]);
+
+ p = probs->mv.classes[i];
+ d = deltas->mv.classes[i];
+ for (j = 0; j < ARRAY_SIZE(probs->mv.classes[0]); j++)
+ p[j] = update_mv_prob(d[j], p[j]);
+
+ p = probs->mv.class0_bit;
+ d = deltas->mv.class0_bit;
+ p[i] = update_mv_prob(d[i], p[i]);
+
+ p = probs->mv.bits[i];
+ d = deltas->mv.bits[i];
+ for (j = 0; j < ARRAY_SIZE(probs->mv.bits[0]); j++)
+ p[j] = update_mv_prob(d[j], p[j]);
+
+ for (j = 0; j < ARRAY_SIZE(probs->mv.class0_fr[0]); j++) {
+ p = probs->mv.class0_fr[i][j];
+ d = deltas->mv.class0_fr[i][j];
+
+ p[0] = update_mv_prob(d[0], p[0]);
+ p[1] = update_mv_prob(d[1], p[1]);
+ p[2] = update_mv_prob(d[2], p[2]);
+ }
+
+ p = probs->mv.fr[i];
+ d = deltas->mv.fr[i];
+ for (j = 0; j < ARRAY_SIZE(probs->mv.fr[i]); j++)
+ p[j] = update_mv_prob(d[j], p[j]);
+
+ if (dec_params->flags & V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV) {
+ p = probs->mv.class0_hp;
+ d = deltas->mv.class0_hp;
+ p[i] = update_mv_prob(d[i], p[i]);
+
+ p = probs->mv.hp;
+ d = deltas->mv.hp;
+ p[i] = update_mv_prob(d[i], p[i]);
+ }
+ }
+}
+
+/* Counterpart to 6.3 compressed_header(), but parsing has been done in userspace. */
+void v4l2_vp9_fw_update_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ if (deltas->tx_mode == V4L2_VP9_TX_MODE_SELECT)
+ update_tx_probs(probs, deltas);
+
+ update_coef_probs(probs, deltas, dec_params);
+
+ update_skip_probs(probs, deltas);
+
+ if (dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME ||
+ dec_params->flags & V4L2_VP9_FRAME_FLAG_INTRA_ONLY)
+ return;
+
+ update_inter_mode_probs(probs, deltas);
+
+ if (dec_params->interpolation_filter == V4L2_VP9_INTERP_FILTER_SWITCHABLE)
+ update_interp_filter_probs(probs, deltas);
+
+ update_is_inter_probs(probs, deltas);
+
+ update_frame_reference_mode_probs(dec_params->reference_mode, probs, deltas);
+
+ update_y_mode_probs(probs, deltas);
+
+ update_partition_probs(probs, deltas);
+
+ update_mv_probs(probs, deltas, dec_params);
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_fw_update_probs);
+
+u8 v4l2_vp9_reset_frame_ctx(const struct v4l2_ctrl_vp9_frame *dec_params,
+ struct v4l2_vp9_frame_context *frame_context)
+{
+ int i;
+
+ u8 fctx_idx = dec_params->frame_context_idx;
+
+ if (dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME ||
+ dec_params->flags & V4L2_VP9_FRAME_FLAG_INTRA_ONLY ||
+ dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) {
+ /*
+ * setup_past_independence()
+ * We do nothing here. Instead of storing default probs in some intermediate
+ * location and then copying from that location to appropriate contexts
+ * in save_probs() below, we skip that step and save default probs directly
+ * to appropriate contexts.
+ */
+ if (dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME ||
+ dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT ||
+ dec_params->reset_frame_context == V4L2_VP9_RESET_FRAME_CTX_ALL)
+ for (i = 0; i < 4; ++i)
+ /* save_probs(i) */
+ memcpy(&frame_context[i], &v4l2_vp9_default_probs,
+ sizeof(v4l2_vp9_default_probs));
+ else if (dec_params->reset_frame_context == V4L2_VP9_RESET_FRAME_CTX_SPEC)
+ /* save_probs(fctx_idx) */
+ memcpy(&frame_context[fctx_idx], &v4l2_vp9_default_probs,
+ sizeof(v4l2_vp9_default_probs));
+ fctx_idx = 0;
+ }
+
+ return fctx_idx;
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_reset_frame_ctx);
+
+/* 8.4.1 Merge prob process */
+static u8 merge_prob(u8 pre_prob, u32 ct0, u32 ct1, u16 count_sat, u32 max_update_factor)
+{
+ u32 den, prob, count, factor;
+
+ den = ct0 + ct1;
+ if (!den) {
+ /*
+ * prob = 128, count = 0, update_factor = 0
+ * Round2's argument: pre_prob * 256
+ * (pre_prob * 256 + 128) >> 8 == pre_prob
+ */
+ return pre_prob;
+ }
+
+ prob = clamp(((ct0 << 8) + (den >> 1)) / den, (u32)1, (u32)255);
+ count = min_t(u32, den, count_sat);
+ factor = fastdiv(max_update_factor * count, count_sat);
+
+ /*
+ * Round2(pre_prob * (256 - factor) + prob * factor, 8)
+ * Round2(pre_prob * 256 + (prob - pre_prob) * factor, 8)
+ * (pre_prob * 256 >> 8) + (((prob - pre_prob) * factor + 128) >> 8)
+ */
+ return pre_prob + (((prob - pre_prob) * factor + 128) >> 8);
+}
+
+static inline u8 noncoef_merge_prob(u8 pre_prob, u32 ct0, u32 ct1)
+{
+ return merge_prob(pre_prob, ct0, ct1, 20, 128);
+}
+
+/* 8.4.2 Merge probs process */
+/*
+ * merge_probs() is a recursive function in the spec. We avoid recursion in the kernel.
+ * That said, the "tree" parameter of merge_probs() controls how deep the recursion goes.
+ * It turns out that in all cases the recursive calls boil down to a short-ish series
+ * of merge_prob() invocations (note no "s").
+ *
+ * Variant A
+ * ---------
+ * merge_probs(small_token_tree, 2):
+ * merge_prob(p[1], c[0], c[1] + c[2])
+ * merge_prob(p[2], c[1], c[2])
+ *
+ * Variant B
+ * ---------
+ * merge_probs(binary_tree, 0) or
+ * merge_probs(tx_size_8_tree, 0):
+ * merge_prob(p[0], c[0], c[1])
+ *
+ * Variant C
+ * ---------
+ * merge_probs(inter_mode_tree, 0):
+ * merge_prob(p[0], c[2], c[1] + c[0] + c[3])
+ * merge_prob(p[1], c[0], c[1] + c[3])
+ * merge_prob(p[2], c[1], c[3])
+ *
+ * Variant D
+ * ---------
+ * merge_probs(intra_mode_tree, 0):
+ * merge_prob(p[0], c[0], c[1] + ... + c[9])
+ * merge_prob(p[1], c[9], c[1] + ... + c[8])
+ * merge_prob(p[2], c[1], c[2] + ... + c[8])
+ * merge_prob(p[3], c[2] + c[4] + c[5], c[3] + c[8] + c[6] + c[7])
+ * merge_prob(p[4], c[2], c[4] + c[5])
+ * merge_prob(p[5], c[4], c[5])
+ * merge_prob(p[6], c[3], c[8] + c[6] + c[7])
+ * merge_prob(p[7], c[8], c[6] + c[7])
+ * merge_prob(p[8], c[6], c[7])
+ *
+ * Variant E
+ * ---------
+ * merge_probs(partition_tree, 0) or
+ * merge_probs(tx_size_32_tree, 0) or
+ * merge_probs(mv_joint_tree, 0) or
+ * merge_probs(mv_fr_tree, 0):
+ * merge_prob(p[0], c[0], c[1] + c[2] + c[3])
+ * merge_prob(p[1], c[1], c[2] + c[3])
+ * merge_prob(p[2], c[2], c[3])
+ *
+ * Variant F
+ * ---------
+ * merge_probs(interp_filter_tree, 0) or
+ * merge_probs(tx_size_16_tree, 0):
+ * merge_prob(p[0], c[0], c[1] + c[2])
+ * merge_prob(p[1], c[1], c[2])
+ *
+ * Variant G
+ * ---------
+ * merge_probs(mv_class_tree, 0):
+ * merge_prob(p[0], c[0], c[1] + ... + c[10])
+ * merge_prob(p[1], c[1], c[2] + ... + c[10])
+ * merge_prob(p[2], c[2] + c[3], c[4] + ... + c[10])
+ * merge_prob(p[3], c[2], c[3])
+ * merge_prob(p[4], c[4] + c[5], c[6] + ... + c[10])
+ * merge_prob(p[5], c[4], c[5])
+ * merge_prob(p[6], c[6], c[7] + ... + c[10])
+ * merge_prob(p[7], c[7] + c[8], c[9] + c[10])
+ * merge_prob(p[8], c[7], c[8])
+ * merge_prob(p[9], c[9], [10])
+ */
+
+static inline void merge_probs_variant_a(u8 *p, const u32 *c, u16 count_sat, u32 update_factor)
+{
+ p[1] = merge_prob(p[1], c[0], c[1] + c[2], count_sat, update_factor);
+ p[2] = merge_prob(p[2], c[1], c[2], count_sat, update_factor);
+}
+
+static inline void merge_probs_variant_b(u8 *p, const u32 *c, u16 count_sat, u32 update_factor)
+{
+ p[0] = merge_prob(p[0], c[0], c[1], count_sat, update_factor);
+}
+
+static inline void merge_probs_variant_c(u8 *p, const u32 *c)
+{
+ p[0] = noncoef_merge_prob(p[0], c[2], c[1] + c[0] + c[3]);
+ p[1] = noncoef_merge_prob(p[1], c[0], c[1] + c[3]);
+ p[2] = noncoef_merge_prob(p[2], c[1], c[3]);
+}
+
+static void merge_probs_variant_d(u8 *p, const u32 *c)
+{
+ u32 sum = 0, s2;
+
+ sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
+
+ p[0] = noncoef_merge_prob(p[0], c[0], sum);
+ sum -= c[9];
+ p[1] = noncoef_merge_prob(p[1], c[9], sum);
+ sum -= c[1];
+ p[2] = noncoef_merge_prob(p[2], c[1], sum);
+ s2 = c[2] + c[4] + c[5];
+ sum -= s2;
+ p[3] = noncoef_merge_prob(p[3], s2, sum);
+ s2 -= c[2];
+ p[4] = noncoef_merge_prob(p[4], c[2], s2);
+ p[5] = noncoef_merge_prob(p[5], c[4], c[5]);
+ sum -= c[3];
+ p[6] = noncoef_merge_prob(p[6], c[3], sum);
+ sum -= c[8];
+ p[7] = noncoef_merge_prob(p[7], c[8], sum);
+ p[8] = noncoef_merge_prob(p[8], c[6], c[7]);
+}
+
+static inline void merge_probs_variant_e(u8 *p, const u32 *c)
+{
+ p[0] = noncoef_merge_prob(p[0], c[0], c[1] + c[2] + c[3]);
+ p[1] = noncoef_merge_prob(p[1], c[1], c[2] + c[3]);
+ p[2] = noncoef_merge_prob(p[2], c[2], c[3]);
+}
+
+static inline void merge_probs_variant_f(u8 *p, const u32 *c)
+{
+ p[0] = noncoef_merge_prob(p[0], c[0], c[1] + c[2]);
+ p[1] = noncoef_merge_prob(p[1], c[1], c[2]);
+}
+
+static void merge_probs_variant_g(u8 *p, const u32 *c)
+{
+ u32 sum;
+
+ sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10];
+ p[0] = noncoef_merge_prob(p[0], c[0], sum);
+ sum -= c[1];
+ p[1] = noncoef_merge_prob(p[1], c[1], sum);
+ sum -= c[2] + c[3];
+ p[2] = noncoef_merge_prob(p[2], c[2] + c[3], sum);
+ p[3] = noncoef_merge_prob(p[3], c[2], c[3]);
+ sum -= c[4] + c[5];
+ p[4] = noncoef_merge_prob(p[4], c[4] + c[5], sum);
+ p[5] = noncoef_merge_prob(p[5], c[4], c[5]);
+ sum -= c[6];
+ p[6] = noncoef_merge_prob(p[6], c[6], sum);
+ p[7] = noncoef_merge_prob(p[7], c[7] + c[8], c[9] + c[10]);
+ p[8] = noncoef_merge_prob(p[8], c[7], c[8]);
+ p[9] = noncoef_merge_prob(p[9], c[9], c[10]);
+}
+
+/* 8.4.3 Coefficient probability adaptation process */
+static inline void adapt_probs_variant_a_coef(u8 *p, const u32 *c, u32 update_factor)
+{
+ merge_probs_variant_a(p, c, 24, update_factor);
+}
+
+static inline void adapt_probs_variant_b_coef(u8 *p, const u32 *c, u32 update_factor)
+{
+ merge_probs_variant_b(p, c, 24, update_factor);
+}
+
+static void _adapt_coeff(unsigned int i, unsigned int j, unsigned int k,
+ struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_vp9_frame_symbol_counts *counts,
+ u32 uf)
+{
+ s32 l, m;
+
+ for (l = 0; l < ARRAY_SIZE(probs->coef[0][0][0]); l++) {
+ for (m = 0; m < BAND_6(l); m++) {
+ u8 *p = probs->coef[i][j][k][l][m];
+ const u32 counts_more_coefs[2] = {
+ *counts->eob[i][j][k][l][m][1],
+ *counts->eob[i][j][k][l][m][0] - *counts->eob[i][j][k][l][m][1],
+ };
+
+ adapt_probs_variant_a_coef(p, *counts->coeff[i][j][k][l][m], uf);
+ adapt_probs_variant_b_coef(p, counts_more_coefs, uf);
+ }
+ }
+}
+
+static void _adapt_coef_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_vp9_frame_symbol_counts *counts,
+ unsigned int uf)
+{
+ unsigned int i, j, k;
+
+ for (i = 0; i < ARRAY_SIZE(probs->coef); i++)
+ for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++)
+ for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++)
+ _adapt_coeff(i, j, k, probs, counts, uf);
+}
+
+void v4l2_vp9_adapt_coef_probs(struct v4l2_vp9_frame_context *probs,
+ struct v4l2_vp9_frame_symbol_counts *counts,
+ bool use_128,
+ bool frame_is_intra)
+{
+ if (frame_is_intra) {
+ _adapt_coef_probs(probs, counts, 112);
+ } else {
+ if (use_128)
+ _adapt_coef_probs(probs, counts, 128);
+ else
+ _adapt_coef_probs(probs, counts, 112);
+ }
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_adapt_coef_probs);
+
+/* 8.4.4 Non coefficient probability adaptation process, adapt_probs() */
+static inline void adapt_probs_variant_b(u8 *p, const u32 *c)
+{
+ merge_probs_variant_b(p, c, 20, 128);
+}
+
+static inline void adapt_probs_variant_c(u8 *p, const u32 *c)
+{
+ merge_probs_variant_c(p, c);
+}
+
+static inline void adapt_probs_variant_d(u8 *p, const u32 *c)
+{
+ merge_probs_variant_d(p, c);
+}
+
+static inline void adapt_probs_variant_e(u8 *p, const u32 *c)
+{
+ merge_probs_variant_e(p, c);
+}
+
+static inline void adapt_probs_variant_f(u8 *p, const u32 *c)
+{
+ merge_probs_variant_f(p, c);
+}
+
+static inline void adapt_probs_variant_g(u8 *p, const u32 *c)
+{
+ merge_probs_variant_g(p, c);
+}
+
+/* 8.4.4 Non coefficient probability adaptation process, adapt_prob() */
+static inline u8 adapt_prob(u8 prob, const u32 counts[2])
+{
+ return noncoef_merge_prob(prob, counts[0], counts[1]);
+}
+
+/* 8.4.4 Non coefficient probability adaptation process */
+void v4l2_vp9_adapt_noncoef_probs(struct v4l2_vp9_frame_context *probs,
+ struct v4l2_vp9_frame_symbol_counts *counts,
+ u8 reference_mode, u8 interpolation_filter, u8 tx_mode,
+ u32 flags)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(probs->is_inter); i++)
+ probs->is_inter[i] = adapt_prob(probs->is_inter[i], (*counts->intra_inter)[i]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->comp_mode); i++)
+ probs->comp_mode[i] = adapt_prob(probs->comp_mode[i], (*counts->comp)[i]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->comp_ref); i++)
+ probs->comp_ref[i] = adapt_prob(probs->comp_ref[i], (*counts->comp_ref)[i]);
+
+ if (reference_mode != V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE)
+ for (i = 0; i < ARRAY_SIZE(probs->single_ref); i++)
+ for (j = 0; j < ARRAY_SIZE(probs->single_ref[0]); j++)
+ probs->single_ref[i][j] = adapt_prob(probs->single_ref[i][j],
+ (*counts->single_ref)[i][j]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->inter_mode); i++)
+ adapt_probs_variant_c(probs->inter_mode[i], (*counts->mv_mode)[i]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->y_mode); i++)
+ adapt_probs_variant_d(probs->y_mode[i], (*counts->y_mode)[i]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->uv_mode); i++)
+ adapt_probs_variant_d(probs->uv_mode[i], (*counts->uv_mode)[i]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->partition); i++)
+ adapt_probs_variant_e(probs->partition[i], (*counts->partition)[i]);
+
+ for (i = 0; i < ARRAY_SIZE(probs->skip); i++)
+ probs->skip[i] = adapt_prob(probs->skip[i], (*counts->skip)[i]);
+
+ if (interpolation_filter == V4L2_VP9_INTERP_FILTER_SWITCHABLE)
+ for (i = 0; i < ARRAY_SIZE(probs->interp_filter); i++)
+ adapt_probs_variant_f(probs->interp_filter[i], (*counts->filter)[i]);
+
+ if (tx_mode == V4L2_VP9_TX_MODE_SELECT)
+ for (i = 0; i < ARRAY_SIZE(probs->tx8); i++) {
+ adapt_probs_variant_b(probs->tx8[i], (*counts->tx8p)[i]);
+ adapt_probs_variant_f(probs->tx16[i], (*counts->tx16p)[i]);
+ adapt_probs_variant_e(probs->tx32[i], (*counts->tx32p)[i]);
+ }
+
+ adapt_probs_variant_e(probs->mv.joint, *counts->mv_joint);
+
+ for (i = 0; i < ARRAY_SIZE(probs->mv.sign); i++) {
+ probs->mv.sign[i] = adapt_prob(probs->mv.sign[i], (*counts->sign)[i]);
+
+ adapt_probs_variant_g(probs->mv.classes[i], (*counts->classes)[i]);
+
+ probs->mv.class0_bit[i] = adapt_prob(probs->mv.class0_bit[i], (*counts->class0)[i]);
+
+ for (j = 0; j < ARRAY_SIZE(probs->mv.bits[0]); j++)
+ probs->mv.bits[i][j] = adapt_prob(probs->mv.bits[i][j],
+ (*counts->bits)[i][j]);
+
+ for (j = 0; j < ARRAY_SIZE(probs->mv.class0_fr[0]); j++)
+ adapt_probs_variant_e(probs->mv.class0_fr[i][j],
+ (*counts->class0_fp)[i][j]);
+
+ adapt_probs_variant_e(probs->mv.fr[i], (*counts->fp)[i]);
+
+ if (!(flags & V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV))
+ continue;
+
+ probs->mv.class0_hp[i] = adapt_prob(probs->mv.class0_hp[i],
+ (*counts->class0_hp)[i]);
+
+ probs->mv.hp[i] = adapt_prob(probs->mv.hp[i], (*counts->hp)[i]);
+ }
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_adapt_noncoef_probs);
+
+bool
+v4l2_vp9_seg_feat_enabled(const u8 *feature_enabled,
+ unsigned int feature,
+ unsigned int segid)
+{
+ u8 mask = V4L2_VP9_SEGMENT_FEATURE_ENABLED(feature);
+
+ return !!(feature_enabled[segid] & mask);
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_seg_feat_enabled);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("V4L2 VP9 Helpers");
+MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@collabora.com>");
diff --git a/drivers/platform/x86/intel/int3472/Makefile b/drivers/platform/x86/intel/int3472/Makefile
index 2362e04db18d..cfec7784c5c9 100644
--- a/drivers/platform/x86/intel/int3472/Makefile
+++ b/drivers/platform/x86/intel/int3472/Makefile
@@ -1,5 +1,4 @@
-obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472.o
-intel_skl_int3472-y := intel_skl_int3472_common.o \
- intel_skl_int3472_discrete.o \
- intel_skl_int3472_tps68470.o \
- intel_skl_int3472_clk_and_regulator.o
+obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472_discrete.o \
+ intel_skl_int3472_tps68470.o
+intel_skl_int3472_discrete-y := discrete.o clk_and_regulator.o common.o
+intel_skl_int3472_tps68470-y := tps68470.o tps68470_board_data.o common.o
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
index 1700e7557a82..1cf958983e86 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_clk_and_regulator.c
+++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
@@ -9,7 +9,7 @@
#include <linux/regulator/driver.h>
#include <linux/slab.h>
-#include "intel_skl_int3472_common.h"
+#include "common.h"
/*
* The regulators have to have .ops to be valid, but the only ops we actually
diff --git a/drivers/platform/x86/intel/int3472/common.c b/drivers/platform/x86/intel/int3472/common.c
new file mode 100644
index 000000000000..77cf058e4168
--- /dev/null
+++ b/drivers/platform/x86/intel/int3472/common.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Author: Dan Scally <djrscally@gmail.com> */
+
+#include <linux/acpi.h>
+#include <linux/slab.h>
+
+#include "common.h"
+
+union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
+{
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_handle handle = adev->handle;
+ union acpi_object *obj;
+ acpi_status status;
+
+ status = acpi_evaluate_object(handle, id, NULL, &buffer);
+ if (ACPI_FAILURE(status))
+ return ERR_PTR(-ENODEV);
+
+ obj = buffer.pointer;
+ if (!obj)
+ return ERR_PTR(-ENODEV);
+
+ if (obj->type != ACPI_TYPE_BUFFER) {
+ acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
+ kfree(obj);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return obj;
+}
+
+int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
+{
+ union acpi_object *obj;
+ int ret;
+
+ obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
+ if (IS_ERR(obj))
+ return PTR_ERR(obj);
+
+ if (obj->buffer.length > sizeof(*cldb)) {
+ acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
+ ret = -EINVAL;
+ goto out_free_obj;
+ }
+
+ memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
+ ret = 0;
+
+out_free_obj:
+ kfree(obj);
+ return ret;
+}
+
+/* sensor_adev_ret may be NULL, name_ret must not be NULL */
+int skl_int3472_get_sensor_adev_and_name(struct device *dev,
+ struct acpi_device **sensor_adev_ret,
+ const char **name_ret)
+{
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+ struct acpi_device *sensor;
+ int ret = 0;
+
+ sensor = acpi_dev_get_first_consumer_dev(adev);
+ if (!sensor) {
+ dev_err(dev, "INT3472 seems to have no dependents.\n");
+ return -ENODEV;
+ }
+
+ *name_ret = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
+ acpi_dev_name(sensor));
+ if (!*name_ret)
+ ret = -ENOMEM;
+
+ if (ret == 0 && sensor_adev_ret)
+ *sensor_adev_ret = sensor;
+ else
+ acpi_dev_put(sensor);
+
+ return ret;
+}
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h b/drivers/platform/x86/intel/int3472/common.h
index 714fde73b524..53270d19c73a 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.h
+++ b/drivers/platform/x86/intel/int3472/common.h
@@ -105,12 +105,12 @@ struct int3472_discrete_device {
struct gpiod_lookup_table gpios;
};
-int skl_int3472_discrete_probe(struct platform_device *pdev);
-int skl_int3472_discrete_remove(struct platform_device *pdev);
-int skl_int3472_tps68470_probe(struct i2c_client *client);
union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
char *id);
int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
+int skl_int3472_get_sensor_adev_and_name(struct device *dev,
+ struct acpi_device **sensor_adev_ret,
+ const char **name_ret);
int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
index e59d79c7e82f..5b514fa01a97 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -14,7 +14,7 @@
#include <linux/platform_device.h>
#include <linux/uuid.h>
-#include "intel_skl_int3472_common.h"
+#include "common.h"
/*
* 79234640-9e10-4fea-a5c1-b5aa8b19756f
@@ -332,7 +332,9 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
return 0;
}
-int skl_int3472_discrete_probe(struct platform_device *pdev)
+static int skl_int3472_discrete_remove(struct platform_device *pdev);
+
+static int skl_int3472_discrete_probe(struct platform_device *pdev)
{
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
struct int3472_discrete_device *int3472;
@@ -361,19 +363,10 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
int3472->dev = &pdev->dev;
platform_set_drvdata(pdev, int3472);
- int3472->sensor = acpi_dev_get_first_consumer_dev(adev);
- if (!int3472->sensor) {
- dev_err(&pdev->dev, "INT3472 seems to have no dependents.\n");
- return -ENODEV;
- }
-
- int3472->sensor_name = devm_kasprintf(int3472->dev, GFP_KERNEL,
- I2C_DEV_NAME_FORMAT,
- acpi_dev_name(int3472->sensor));
- if (!int3472->sensor_name) {
- ret = -ENOMEM;
- goto err_put_sensor;
- }
+ ret = skl_int3472_get_sensor_adev_and_name(&pdev->dev, &int3472->sensor,
+ &int3472->sensor_name);
+ if (ret)
+ return ret;
/*
* Initialising this list means we can call gpiod_remove_lookup_table()
@@ -387,15 +380,11 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
return ret;
}
+ acpi_dev_clear_dependencies(adev);
return 0;
-
-err_put_sensor:
- acpi_dev_put(int3472->sensor);
-
- return ret;
}
-int skl_int3472_discrete_remove(struct platform_device *pdev)
+static int skl_int3472_discrete_remove(struct platform_device *pdev)
{
struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
@@ -411,3 +400,23 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
return 0;
}
+
+static const struct acpi_device_id int3472_device_id[] = {
+ { "INT3472", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, int3472_device_id);
+
+static struct platform_driver int3472_discrete = {
+ .driver = {
+ .name = "int3472-discrete",
+ .acpi_match_table = int3472_device_id,
+ },
+ .probe = skl_int3472_discrete_probe,
+ .remove = skl_int3472_discrete_remove,
+};
+module_platform_driver(int3472_discrete);
+
+MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Discrete Device Driver");
+MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c b/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
deleted file mode 100644
index 497e74fba75f..000000000000
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_common.c
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Author: Dan Scally <djrscally@gmail.com> */
-
-#include <linux/acpi.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include "intel_skl_int3472_common.h"
-
-union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
-{
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- acpi_handle handle = adev->handle;
- union acpi_object *obj;
- acpi_status status;
-
- status = acpi_evaluate_object(handle, id, NULL, &buffer);
- if (ACPI_FAILURE(status))
- return ERR_PTR(-ENODEV);
-
- obj = buffer.pointer;
- if (!obj)
- return ERR_PTR(-ENODEV);
-
- if (obj->type != ACPI_TYPE_BUFFER) {
- acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
- kfree(obj);
- return ERR_PTR(-EINVAL);
- }
-
- return obj;
-}
-
-int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
-{
- union acpi_object *obj;
- int ret;
-
- obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
- if (IS_ERR(obj))
- return PTR_ERR(obj);
-
- if (obj->buffer.length > sizeof(*cldb)) {
- acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
- ret = -EINVAL;
- goto out_free_obj;
- }
-
- memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
- ret = 0;
-
-out_free_obj:
- kfree(obj);
- return ret;
-}
-
-static const struct acpi_device_id int3472_device_id[] = {
- { "INT3472", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(acpi, int3472_device_id);
-
-static struct platform_driver int3472_discrete = {
- .driver = {
- .name = "int3472-discrete",
- .acpi_match_table = int3472_device_id,
- },
- .probe = skl_int3472_discrete_probe,
- .remove = skl_int3472_discrete_remove,
-};
-
-static struct i2c_driver int3472_tps68470 = {
- .driver = {
- .name = "int3472-tps68470",
- .acpi_match_table = int3472_device_id,
- },
- .probe_new = skl_int3472_tps68470_probe,
-};
-
-static int skl_int3472_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&int3472_discrete);
- if (ret)
- return ret;
-
- ret = i2c_register_driver(THIS_MODULE, &int3472_tps68470);
- if (ret)
- platform_driver_unregister(&int3472_discrete);
-
- return ret;
-}
-module_init(skl_int3472_init);
-
-static void skl_int3472_exit(void)
-{
- platform_driver_unregister(&int3472_discrete);
- i2c_del_driver(&int3472_tps68470);
-}
-module_exit(skl_int3472_exit);
-
-MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Device Driver");
-MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
index c05b4cf502fe..22f61b47f9e5 100644
--- a/drivers/platform/x86/intel/int3472/intel_skl_int3472_tps68470.c
+++ b/drivers/platform/x86/intel/int3472/tps68470.c
@@ -2,27 +2,27 @@
/* Author: Dan Scally <djrscally@gmail.com> */
#include <linux/i2c.h>
+#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps68470.h>
#include <linux/platform_device.h>
+#include <linux/platform_data/tps68470.h>
#include <linux/regmap.h>
+#include <linux/string.h>
-#include "intel_skl_int3472_common.h"
+#include "common.h"
+#include "tps68470.h"
#define DESIGNED_FOR_CHROMEOS 1
#define DESIGNED_FOR_WINDOWS 2
+#define TPS68470_WIN_MFD_CELL_COUNT 3
+
static const struct mfd_cell tps68470_cros[] = {
{ .name = "tps68470-gpio" },
{ .name = "tps68470_pmic_opregion" },
};
-static const struct mfd_cell tps68470_win[] = {
- { .name = "tps68470-gpio" },
- { .name = "tps68470-clk" },
- { .name = "tps68470-regulator" },
-};
-
static const struct regmap_config tps68470_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -95,13 +95,21 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
return DESIGNED_FOR_WINDOWS;
}
-int skl_int3472_tps68470_probe(struct i2c_client *client)
+static int skl_int3472_tps68470_probe(struct i2c_client *client)
{
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
+ const struct int3472_tps68470_board_data *board_data;
+ struct tps68470_clk_platform_data clk_pdata = {};
+ struct mfd_cell *cells;
struct regmap *regmap;
int device_type;
int ret;
+ ret = skl_int3472_get_sensor_adev_and_name(&client->dev, NULL,
+ &clk_pdata.consumer_dev_name);
+ if (ret)
+ return ret;
+
regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
@@ -119,9 +127,38 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
device_type = skl_int3472_tps68470_calc_type(adev);
switch (device_type) {
case DESIGNED_FOR_WINDOWS:
+ board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
+ if (!board_data)
+ return dev_err_probe(&client->dev, -ENODEV, "No board-data found for this model\n");
+
+ cells = kcalloc(TPS68470_WIN_MFD_CELL_COUNT, sizeof(*cells), GFP_KERNEL);
+ if (!cells)
+ return -ENOMEM;
+
+ /*
+ * The order of the cells matters here! The clk must be first
+ * because the regulator depends on it. The gpios must be last,
+ * acpi_gpiochip_add() calls acpi_dev_clear_dependencies() and
+ * the clk + regulators must be ready when this happens.
+ */
+ cells[0].name = "tps68470-clk";
+ cells[0].platform_data = &clk_pdata;
+ cells[0].pdata_size = sizeof(clk_pdata);
+ cells[1].name = "tps68470-regulator";
+ cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
+ cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);
+ cells[2].name = "tps68470-gpio";
+
+ gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_table);
+
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
- tps68470_win, ARRAY_SIZE(tps68470_win),
+ cells, TPS68470_WIN_MFD_CELL_COUNT,
NULL, 0, NULL);
+ kfree(cells);
+
+ if (ret)
+ gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
+
break;
case DESIGNED_FOR_CHROMEOS:
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
@@ -133,5 +170,42 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
return device_type;
}
+ /*
+ * No acpi_dev_clear_dependencies() here, since the acpi_gpiochip_add()
+ * for the GPIO cell already does this.
+ */
+
return ret;
}
+
+static int skl_int3472_tps68470_remove(struct i2c_client *client)
+{
+ const struct int3472_tps68470_board_data *board_data;
+
+ board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
+ if (board_data)
+ gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
+
+ return 0;
+}
+
+static const struct acpi_device_id int3472_device_id[] = {
+ { "INT3472", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, int3472_device_id);
+
+static struct i2c_driver int3472_tps68470 = {
+ .driver = {
+ .name = "int3472-tps68470",
+ .acpi_match_table = int3472_device_id,
+ },
+ .probe_new = skl_int3472_tps68470_probe,
+ .remove = skl_int3472_tps68470_remove,
+};
+module_i2c_driver(int3472_tps68470);
+
+MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
+MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");
diff --git a/drivers/platform/x86/intel/int3472/tps68470.h b/drivers/platform/x86/intel/int3472/tps68470.h
new file mode 100644
index 000000000000..cfd33eb62740
--- /dev/null
+++ b/drivers/platform/x86/intel/int3472/tps68470.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TI TPS68470 PMIC platform data definition.
+ *
+ * Copyright (c) 2021 Red Hat Inc.
+ *
+ * Red Hat authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#ifndef _INTEL_SKL_INT3472_TPS68470_H
+#define _INTEL_SKL_INT3472_TPS68470_H
+
+struct gpiod_lookup_table;
+struct tps68470_regulator_platform_data;
+
+struct int3472_tps68470_board_data {
+ const char *dev_name;
+ struct gpiod_lookup_table *tps68470_gpio_lookup_table;
+ const struct tps68470_regulator_platform_data *tps68470_regulator_pdata;
+};
+
+const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name);
+
+#endif
diff --git a/drivers/platform/x86/intel/int3472/tps68470_board_data.c b/drivers/platform/x86/intel/int3472/tps68470_board_data.c
new file mode 100644
index 000000000000..faa5570f6e6b
--- /dev/null
+++ b/drivers/platform/x86/intel/int3472/tps68470_board_data.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TI TPS68470 PMIC platform data definition.
+ *
+ * Copyright (c) 2021 Dan Scally <djrscally@gmail.com>
+ * Copyright (c) 2021 Red Hat Inc.
+ *
+ * Red Hat authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/dmi.h>
+#include <linux/gpio/machine.h>
+#include <linux/platform_data/tps68470.h>
+#include <linux/regulator/machine.h>
+#include "tps68470.h"
+
+static struct regulator_consumer_supply int347a_core_consumer_supplies[] = {
+ REGULATOR_SUPPLY("dvdd", "i2c-INT347A:00"),
+};
+
+static struct regulator_consumer_supply int347a_ana_consumer_supplies[] = {
+ REGULATOR_SUPPLY("avdd", "i2c-INT347A:00"),
+};
+
+static struct regulator_consumer_supply int347a_vcm_consumer_supplies[] = {
+ REGULATOR_SUPPLY("vdd", "i2c-INT347A:00-VCM"),
+};
+
+static struct regulator_consumer_supply int347a_vsio_consumer_supplies[] = {
+ REGULATOR_SUPPLY("dovdd", "i2c-INT347A:00"),
+ REGULATOR_SUPPLY("vsio", "i2c-INT347A:00-VCM"),
+};
+
+static const struct regulator_init_data surface_go_tps68470_core_reg_init_data = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = true,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(int347a_core_consumer_supplies),
+ .consumer_supplies = int347a_core_consumer_supplies,
+};
+
+static const struct regulator_init_data surface_go_tps68470_ana_reg_init_data = {
+ .constraints = {
+ .min_uV = 2815200,
+ .max_uV = 2815200,
+ .apply_uV = true,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(int347a_ana_consumer_supplies),
+ .consumer_supplies = int347a_ana_consumer_supplies,
+};
+
+static const struct regulator_init_data surface_go_tps68470_vcm_reg_init_data = {
+ .constraints = {
+ .min_uV = 2815200,
+ .max_uV = 2815200,
+ .apply_uV = true,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(int347a_vcm_consumer_supplies),
+ .consumer_supplies = int347a_vcm_consumer_supplies,
+};
+
+/* Ensure the always-on VIO regulator has the same voltage as VSIO */
+static const struct regulator_init_data surface_go_tps68470_vio_reg_init_data = {
+ .constraints = {
+ .min_uV = 1800600,
+ .max_uV = 1800600,
+ .apply_uV = true,
+ .always_on = true,
+ },
+};
+
+static const struct regulator_init_data surface_go_tps68470_vsio_reg_init_data = {
+ .constraints = {
+ .min_uV = 1800600,
+ .max_uV = 1800600,
+ .apply_uV = true,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(int347a_vsio_consumer_supplies),
+ .consumer_supplies = int347a_vsio_consumer_supplies,
+};
+
+static const struct tps68470_regulator_platform_data surface_go_tps68470_pdata = {
+ .reg_init_data = {
+ [TPS68470_CORE] = &surface_go_tps68470_core_reg_init_data,
+ [TPS68470_ANA] = &surface_go_tps68470_ana_reg_init_data,
+ [TPS68470_VCM] = &surface_go_tps68470_vcm_reg_init_data,
+ [TPS68470_VIO] = &surface_go_tps68470_vio_reg_init_data,
+ [TPS68470_VSIO] = &surface_go_tps68470_vsio_reg_init_data,
+ },
+};
+
+static struct gpiod_lookup_table surface_go_tps68470_gpios = {
+ .dev_id = "i2c-INT347A:00",
+ .table = {
+ GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW)
+ }
+};
+
+static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {
+ .dev_name = "i2c-INT3472:05",
+ .tps68470_gpio_lookup_table = &surface_go_tps68470_gpios,
+ .tps68470_regulator_pdata = &surface_go_tps68470_pdata,
+};
+
+static const struct dmi_system_id int3472_tps68470_board_data_table[] = {
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go"),
+ },
+ .driver_data = (void *)&surface_go_tps68470_board_data,
+ },
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go 2"),
+ },
+ .driver_data = (void *)&surface_go_tps68470_board_data,
+ },
+ { }
+};
+
+const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name)
+{
+ const struct int3472_tps68470_board_data *board_data;
+ const struct dmi_system_id *match;
+
+ for (match = dmi_first_match(int3472_tps68470_board_data_table);
+ match;
+ match = dmi_first_match(match + 1)) {
+ board_data = match->driver_data;
+ if (strcmp(board_data->dev_name, dev_name) == 0)
+ return board_data;
+ }
+
+ return NULL;
+}
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index e3aaae920847..b81cfa74edb7 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -26,6 +26,8 @@ source "drivers/staging/media/hantro/Kconfig"
source "drivers/staging/media/imx/Kconfig"
+source "drivers/staging/media/max96712/Kconfig"
+
source "drivers/staging/media/meson/vdec/Kconfig"
source "drivers/staging/media/omap4iss/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 5b5afc5b03a0..7e2c86e3695d 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_INTEL_ATOMISP) += atomisp/
obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
+obj-$(CONFIG_VIDEO_MAX96712) += max96712/
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/
diff --git a/drivers/staging/media/atomisp/Makefile b/drivers/staging/media/atomisp/Makefile
index 606b7754fdfd..2485d7b3fee2 100644
--- a/drivers/staging/media/atomisp/Makefile
+++ b/drivers/staging/media/atomisp/Makefile
@@ -27,20 +27,16 @@ atomisp-objs += \
pci/sh_css_firmware.o \
pci/sh_css_host_data.o \
pci/sh_css_hrt.o \
- pci/sh_css_metadata.o \
pci/sh_css_metrics.o \
pci/sh_css_mipi.o \
pci/sh_css_mmu.o \
- pci/sh_css_morph.o \
pci/sh_css.o \
pci/sh_css_param_dvs.o \
pci/sh_css_param_shading.o \
pci/sh_css_params.o \
pci/sh_css_properties.o \
- pci/sh_css_shading.o \
pci/sh_css_sp.o \
pci/sh_css_stream_format.o \
- pci/sh_css_stream.o \
pci/sh_css_version.o \
pci/base/circbuf/src/circbuf.o \
pci/base/refcount/src/refcount.o \
@@ -53,6 +49,9 @@ atomisp-objs += \
pci/hmm/hmm.o \
pci/hmm/hmm_reserved_pool.o \
pci/ia_css_device_access.o \
+ pci/ia_css_isp_configs.o \
+ pci/ia_css_isp_states.o \
+ pci/ia_css_isp_params.o \
pci/isp/kernels/aa/aa_2/ia_css_aa2.host.o \
pci/isp/kernels/anr/anr_1.0/ia_css_anr.host.o \
pci/isp/kernels/anr/anr_2/ia_css_anr2.host.o \
@@ -154,21 +153,13 @@ atomisp-objs += \
pci/hive_isp_css_common/host/timed_ctrl.o \
pci/hive_isp_css_common/host/vmem.o \
pci/hive_isp_css_shared/host/tag.o \
- pci/system_local.o \
-
-obj-byt = \
- pci/css_2400_system/hive/ia_css_isp_configs.o \
- pci/css_2400_system/hive/ia_css_isp_params.o \
- pci/css_2400_system/hive/ia_css_isp_states.o \
+ pci/system_local.o
# These will be needed when clean merge CHT support nicely into the driver
# Keep them here handy for when we get to that point
#
obj-cht = \
- pci/css_2401_system/hive/ia_css_isp_configs.o \
- pci/css_2401_system/hive/ia_css_isp_params.o \
- pci/css_2401_system/hive/ia_css_isp_states.o \
pci/css_2401_system/host/csi_rx.o \
pci/css_2401_system/host/ibuf_ctrl.o \
pci/css_2401_system/host/isys_dma.o \
@@ -306,10 +297,8 @@ INCLUDES += \
-I$(atomisp)/pci/runtime/rmgr/interface/ \
-I$(atomisp)/pci/runtime/spctrl/interface/ \
-I$(atomisp)/pci/runtime/tagger/interface/ \
- -I$(atomisp)/pci/css_2400_system/hive/ \
-I$(atomisp)/pci/css_2401_system/ \
-I$(atomisp)/pci/css_2401_system/host/ \
- -I$(atomisp)/pci/css_2401_system/hive/ \
-I$(atomisp)/pci/css_2401_system/hrt/
DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__
@@ -324,10 +313,7 @@ ifeq ($(CONFIG_VIDEO_ATOMISP_ISP2401),y)
atomisp-objs += \
$(obj-cht) \
pci/runtime/isys/src/ibuf_ctrl_rmgr.o
-DEFINES += -DISP2401 -DISP2401_NEW_INPUT_SYSTEM -DSYSTEM_hive_isp_css_2401_system
-else
-atomisp-objs += $(obj-byt)
-DEFINES += -DISP2400 -DSYSTEM_hive_isp_css_2400_system
+DEFINES += -DISP2401
endif
ccflags-y += $(INCLUDES) $(DEFINES) -fno-common
diff --git a/drivers/staging/media/atomisp/TODO b/drivers/staging/media/atomisp/TODO
index 2d1ef9eb262a..43b842043f29 100644
--- a/drivers/staging/media/atomisp/TODO
+++ b/drivers/staging/media/atomisp/TODO
@@ -1,92 +1,161 @@
+For both Cherrytrail (CHT) and Baytrail (BHT) the driver
+requires the "candrpv_0415_20150521_0458" firmware version.
+It should be noticed that the firmware file is different,
+depending on the ISP model, so they're stored with different
+names:
+
+- for BHT: /lib/firmware/shisp_2400b0_v21.bin
+
+ Warning: The driver was not tested yet for BHT.
+
+- for CHT: /lib/firmware/shisp_2401a0_v21.bin
+
+ https://github.com/intel-aero/meta-intel-aero-base/blob/master/recipes-kernel/linux/linux-yocto/shisp_2401a0_v21.bin
+
NOTE:
=====
-While the driver probes the hardware and reports itself as a
-V4L2 driver, there are still some issues preventing it to
-stream (at least it doesn't with the standard V4L2 applications.
-Didn't test yet with some custom-made app for this driver).
-Solving the related bugs and issues preventing it to work is
-needed (items 6 and 7 from the list below).
+This driver currently doesn't work with most V4L2 applications,
+as there are still some issues with regards to implementing
+certain APIs at the standard way.
+
+Also, currently only USERPTR streaming mode is working.
+
+In order to test, it is needed to know what's the sensor's
+resolution. This can be checked with:
+
+$ v4l2-ctl --get-fmt-video
+ Format Video Capture:
+ Width/Height : 1600/1200
+ ...
+
+It is known to work with:
+
+- v4l2grab at contrib/test directory at https://git.linuxtv.org/v4l-utils.git/
+
+ The resolution should not be bigger than the max resolution
+ supported by the sensor, or it will fail. So, if the sensor
+ reports:
+
+ The driver can be tested with:
+
+ v4l2grab -f YUYV -x 1600 -y 1200 -d /dev/video2 -u
+
+- NVT at https://github.com/intel/nvt
+
+ $ ./v4l2n -o testimage_@.raw \
+ --device /dev/video2 \
+ --input 0 \
+ --exposure=30000,30000,30000,30000 \
+ --parm type=1,capturemode=CI_MODE_PREVIEW \
+ --fmt type=1,width=1600,height=1200,pixelformat=YUYV \
+ --reqbufs count=2,memory=USERPTR \
+ --parameters=wb_config.r=32768,wb_config.gr=21043,wb_config.gb=21043,wb_config.b=30863 \
+ --capture=20
+
+ As the output is in raw format, images need to be converted with:
+
+ $ for i in $(seq 0 19); do
+ name="testimage_$(printf "%03i" $i)"
+ ./raw2pnm -x$WIDTH -y$HEIGHT -f$FORMAT $name.raw $name.pnm
+ rm $name.raw
+ done
TODO
====
-1. The atomisp doesn't rely at the usual i2c stuff to discover the
- sensors. Instead, it calls a function from atomisp_gmin_platform.c.
- There are some hacks added there for it to wait for sensors to be
- probed (with a timeout of 2 seconds or so).
- This should be converted to the usual way, using V4L2 async subdev
- framework to wait for cameras to be probed;
+1. Fix support for MMAP streaming mode. This is required for most
+ V4L2 applications;
-2. Use ACPI _DSM table - DONE!
+2. Implement and/or fix V4L2 ioctls in order to allow a normal app to
+ use it;
-3. Switch the driver to use pm_runtime stuff. Right now, it probes the
- existing PMIC code and sensors call it directly.
+3. Ensure that the driver will pass v4l2-compliance tests;
-4. There's a problem at the sensor drivers: when trying to set a video
- format, the atomisp main driver calls the sensor drivers with the
- sensor turned off. This causes them to fail.
+4. Get manufacturer's authorization to redistribute the binaries for
+ the firmware files;
- The only exception is the atomisp-ov2880, which has a hack inside it
- to turn it on when VIDIOC_S_FMT is called.
+5. remove VIDEO_ATOMISP_ISP2401, making the driver to auto-detect the
+ register address differences between ISP2400 and ISP2401;
- The right fix seems to power on the sensor when a video device is
- opened (or at the first VIDIOC_ ioctl - except for VIDIOC_QUERYCAP),
- powering it down at close() syscall.
+6. Cleanup the driver code, removing the abstraction layers inside it;
- Such kind of control would need to be done inside the atomisp driver,
- not at the sensors code.
+7. The atomisp doesn't rely at the usual i2c stuff to discover the
+ sensors. Instead, it calls a function from atomisp_gmin_platform.c.
+ There are some hacks added there for it to wait for sensors to be
+ probed (with a timeout of 2 seconds or so). This should be converted
+ to the usual way, using V4L2 async subdev framework to wait for
+ cameras to be probed;
-5. There are several issues related to memory management, causing
- crashes. The atomisp splits the memory management on three separate
- regions:
+8. Switch to standard V4L2 sub-device API for sensor and lens. In
+ particular, the user space API needs to support V4L2 controls as
+ defined in the V4L2 spec and references to atomisp must be removed from
+ these drivers.
+
+9. Use LED flash API for flash LED drivers such as LM3554 (which already
+ has a LED class driver).
+
+10. Migrate the sensor drivers out of staging or re-using existing
+ drivers;
+
+11. Switch the driver to use pm_runtime stuff. Right now, it probes the
+ existing PMIC code and sensors call it directly.
+
+12. There's a problem on sensor drivers: when trying to set a video
+ format, the atomisp main driver calls the sensor drivers with the
+ sensor turned off. This causes them to fail.
+
+ This was fixed at atomisp-ov2880, which has a hack inside it
+ to turn it on when VIDIOC_S_FMT is called, but this has to be
+ cheked on other drivers as well.
+
+ The right fix seems to power on the sensor when a video device is
+ opened (or at the first VIDIOC_ ioctl - except for VIDIOC_QUERYCAP),
+ powering it down at close() syscall.
+
+ Such kind of control would need to be done inside the atomisp driver,
+ not at the sensors code.
+
+13. There are several issues related to memory management, that can
+ cause crashes and/or memory leaks. The atomisp splits the memory
+ management on three separate regions:
- dynamic pool;
- reserved pool;
- generic pool
- The code implementing it is at:
+ The code implementing it is at:
drivers/staging/media/atomisp/pci/hmm/
- It also has a separate code for managing DMA buffers at:
+ It also has a separate code for managing DMA buffers at:
drivers/staging/media/atomisp/pci/mmu/
- The code there is really dirty, ugly and probably wrong. I fixed
- one bug there already, but the best would be to just trash it and use
- something else. Maybe the code from the newer intel driver could
- serve as a model:
+ The code there is really dirty, ugly and probably wrong. I fixed
+ one bug there already, but the best would be to just trash it and use
+ something else. Maybe the code from the newer intel driver could
+ serve as a model:
drivers/staging/media/ipu3/ipu3-mmu.c
- But converting it to use something like that is painful and may
- cause some breakages.
-
-6. There is some issues at the frame receive logic, causing the
- DQBUF ioctls to fail.
-
-7. A single AtomISP driver needs to be implemented to support both
- Baytrail (BYT) and Cherrytail (CHT) platforms at the same time.
- The current driver is a mechanical and hand combined merge of the
- two using several runtime macros, plus some ifdef ISP2401 to select the
- CHT version. Yet, there are some ISP-specific headers that change the
- driver's behavior during compile time.
+ But converting it to use something like that is painful and may
+ cause some breakages.
-8. The file structure needs to get tidied up to resemble a normal Linux
- driver.
+14. The file structure needs to get tidied up to resemble a normal Linux
+ driver.
-9. Lots of the midlayer glue. unused code and abstraction needs removing.
+15. Lots of the midlayer glue. Unused code and abstraction needs removing.
-10. The AtomISP driver includes some special IOCTLS (ATOMISP_IOC_XXXX_XXXX)
+16. The AtomISP driver includes some special IOCTLS (ATOMISP_IOC_XXXX_XXXX)
and controls that require some cleanup. Some of those code may have
been removed during the cleanups. They could be needed in order to
- properly support 3A algorithms
+ properly support 3A algorithms.
Such IOCTL interface needs more documentation. The better would
be to use something close to the interface used by the IPU3 IMGU driver.
-11. The ISP code has some dependencies of the exact FW version.
+17. The ISP code has some dependencies of the exact FW version.
The version defined in pci/sh_css_firmware.c:
BYT (isp2400): "irci_stable_candrpv_0415_20150521_0458"
@@ -106,24 +175,16 @@ TODO
there are any specific things that can be done to fold in support for
multiple firmware versions.
-12. Switch to standard V4L2 sub-device API for sensor and lens. In
- particular, the user space API needs to support V4L2 controls as
- defined in the V4L2 spec and references to atomisp must be removed from
- these drivers.
-
-13. Use LED flash API for flash LED drivers such as LM3554 (which already
- has a LED class driver).
-14. Switch from videobuf1 to videobuf2. Videobuf1 is being removed!
+18. Switch from videobuf1 to videobuf2. Videobuf1 is being removed!
-15. Correct Coding Style. Please refrain sending coding style patches
+19. Correct Coding Style. Please refrain sending coding style patches
for this driver until the other work is done, as there will be a lot
of code churn until this driver becomes functional again.
-16. Fix private ioctls to not need a compat_ioctl handler for running
- 32-bit tasks. The compat code has been removed because of bugs,
- and should not be needed for modern drivers. Fixing this properly
- unfortunately means an incompatible ABI change.
+20. Remove the logic which sets up pipelines inside it, moving it to
+ libcamera and implement MC support.
+
Limitations
===========
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index 687888d643df..cbc8b1d91995 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -266,7 +266,7 @@ static int gc0310_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
{
struct gc0310_device *dev = to_gc0310_sensor(sd);
- *val = gc0310_res[dev->fmt_idx].bin_factor_x;
+ *val = dev->res->bin_factor_x;
return 0;
}
@@ -275,7 +275,7 @@ static int gc0310_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
{
struct gc0310_device *dev = to_gc0310_sensor(sd);
- *val = gc0310_res[dev->fmt_idx].bin_factor_y;
+ *val = dev->res->bin_factor_y;
return 0;
}
@@ -878,76 +878,6 @@ static int gc0310_s_power(struct v4l2_subdev *sd, int on)
return gc0310_init(sd);
}
-/*
- * distance - calculate the distance
- * @res: resolution
- * @w: width
- * @h: height
- *
- * Get the gap between resolution and w/h.
- * res->width/height smaller than w/h wouldn't be considered.
- * Returns the value of gap or -1 if fail.
- */
-#define LARGEST_ALLOWED_RATIO_MISMATCH 800
-static int distance(struct gc0310_resolution *res, u32 w, u32 h)
-{
- unsigned int w_ratio = (res->width << 13) / w;
- unsigned int h_ratio;
- int match;
-
- if (h == 0)
- return -1;
- h_ratio = (res->height << 13) / h;
- if (h_ratio == 0)
- return -1;
- match = abs(((w_ratio << 13) / h_ratio) - 8192);
-
- if ((w_ratio < 8192) || (h_ratio < 8192) ||
- (match > LARGEST_ALLOWED_RATIO_MISMATCH))
- return -1;
-
- return w_ratio + h_ratio;
-}
-
-/* Return the nearest higher resolution index */
-static int nearest_resolution_index(int w, int h)
-{
- int i;
- int idx = -1;
- int dist;
- int min_dist = INT_MAX;
- struct gc0310_resolution *tmp_res = NULL;
-
- for (i = 0; i < N_RES; i++) {
- tmp_res = &gc0310_res[i];
- dist = distance(tmp_res, w, h);
- if (dist == -1)
- continue;
- if (dist < min_dist) {
- min_dist = dist;
- idx = i;
- }
- }
-
- return idx;
-}
-
-static int get_resolution_index(int w, int h)
-{
- int i;
-
- for (i = 0; i < N_RES; i++) {
- if (w != gc0310_res[i].width)
- continue;
- if (h != gc0310_res[i].height)
- continue;
-
- return i;
- }
-
- return -1;
-}
-
/* TODO: remove it. */
static int startup(struct v4l2_subdev *sd)
{
@@ -955,7 +885,7 @@ static int startup(struct v4l2_subdev *sd)
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
- ret = gc0310_write_reg_array(client, gc0310_res[dev->fmt_idx].regs);
+ ret = gc0310_write_reg_array(client, dev->res->regs);
if (ret) {
dev_err(&client->dev, "gc0310 write register err.\n");
return ret;
@@ -972,8 +902,8 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd,
struct gc0310_device *dev = to_gc0310_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct camera_mipi_info *gc0310_info = NULL;
+ struct gc0310_resolution *res;
int ret = 0;
- int idx = 0;
if (format->pad)
return -EINVAL;
@@ -987,15 +917,16 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd,
mutex_lock(&dev->input_lock);
- idx = nearest_resolution_index(fmt->width, fmt->height);
- if (idx == -1) {
- /* return the largest resolution */
- fmt->width = gc0310_res[N_RES - 1].width;
- fmt->height = gc0310_res[N_RES - 1].height;
- } else {
- fmt->width = gc0310_res[idx].width;
- fmt->height = gc0310_res[idx].height;
- }
+ res = v4l2_find_nearest_size(gc0310_res_preview,
+ ARRAY_SIZE(gc0310_res_preview), width,
+ height, fmt->width, fmt->height);
+ if (!res)
+ res = &gc0310_res_preview[N_RES - 1];
+
+ fmt->width = res->width;
+ fmt->height = res->height;
+ dev->res = res;
+
fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
@@ -1004,23 +935,15 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd,
return 0;
}
- dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- if (dev->fmt_idx == -1) {
- dev_err(&client->dev, "get resolution fail\n");
- mutex_unlock(&dev->input_lock);
- return -EINVAL;
- }
-
dev_dbg(&client->dev, "%s: before gc0310_write_reg_array %s\n",
- __func__, gc0310_res[dev->fmt_idx].desc);
+ __func__, dev->res->desc);
ret = startup(sd);
if (ret) {
dev_err(&client->dev, "gc0310 startup err\n");
goto err;
}
- ret = gc0310_get_intg_factor(client, gc0310_info,
- &gc0310_res[dev->fmt_idx]);
+ ret = gc0310_get_intg_factor(client, gc0310_info, dev->res);
if (ret) {
dev_err(&client->dev, "failed to get integration_factor\n");
goto err;
@@ -1044,8 +967,8 @@ static int gc0310_get_fmt(struct v4l2_subdev *sd,
if (!fmt)
return -EINVAL;
- fmt->width = gc0310_res[dev->fmt_idx].width;
- fmt->height = gc0310_res[dev->fmt_idx].height;
+ fmt->width = dev->res->width;
+ fmt->height = dev->res->height;
fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
return 0;
@@ -1199,7 +1122,7 @@ static int gc0310_g_frame_interval(struct v4l2_subdev *sd,
struct gc0310_device *dev = to_gc0310_sensor(sd);
interval->interval.numerator = 1;
- interval->interval.denominator = gc0310_res[dev->fmt_idx].fps;
+ interval->interval.denominator = dev->res->fps;
return 0;
}
@@ -1237,7 +1160,7 @@ static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
struct gc0310_device *dev = to_gc0310_sensor(sd);
mutex_lock(&dev->input_lock);
- *frames = gc0310_res[dev->fmt_idx].skip_frames;
+ *frames = dev->res->skip_frames;
mutex_unlock(&dev->input_lock);
return 0;
@@ -1301,7 +1224,7 @@ static int gc0310_probe(struct i2c_client *client)
mutex_init(&dev->input_lock);
- dev->fmt_idx = 0;
+ dev->res = &gc0310_res_preview[0];
v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops);
pdata = gmin_camera_platform_data(&dev->sd,
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index 4d769590f2d3..0e6b2e6100d1 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -570,14 +570,16 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag)
static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
{
struct gc2235_device *dev = to_gc2235_sensor(sd);
- int ret = -1;
+ int ret;
if (!dev || !dev->platform_data)
return -ENODEV;
- ret |= dev->platform_data->gpio1_ctrl(sd, !flag);
+ ret = dev->platform_data->gpio1_ctrl(sd, !flag);
usleep_range(60, 90);
- return dev->platform_data->gpio0_ctrl(sd, flag);
+ ret |= dev->platform_data->gpio0_ctrl(sd, flag);
+
+ return ret;
}
static int power_up(struct v4l2_subdev *sd)
@@ -670,76 +672,6 @@ static int gc2235_s_power(struct v4l2_subdev *sd, int on)
return ret;
}
-/*
- * distance - calculate the distance
- * @res: resolution
- * @w: width
- * @h: height
- *
- * Get the gap between resolution and w/h.
- * res->width/height smaller than w/h wouldn't be considered.
- * Returns the value of gap or -1 if fail.
- */
-#define LARGEST_ALLOWED_RATIO_MISMATCH 800
-static int distance(struct gc2235_resolution *res, u32 w, u32 h)
-{
- unsigned int w_ratio = (res->width << 13) / w;
- unsigned int h_ratio;
- int match;
-
- if (h == 0)
- return -1;
- h_ratio = (res->height << 13) / h;
- if (h_ratio == 0)
- return -1;
- match = abs(((w_ratio << 13) / h_ratio) - 8192);
-
- if ((w_ratio < 8192) || (h_ratio < 8192) ||
- (match > LARGEST_ALLOWED_RATIO_MISMATCH))
- return -1;
-
- return w_ratio + h_ratio;
-}
-
-/* Return the nearest higher resolution index */
-static int nearest_resolution_index(int w, int h)
-{
- int i;
- int idx = -1;
- int dist;
- int min_dist = INT_MAX;
- struct gc2235_resolution *tmp_res = NULL;
-
- for (i = 0; i < N_RES; i++) {
- tmp_res = &gc2235_res[i];
- dist = distance(tmp_res, w, h);
- if (dist == -1)
- continue;
- if (dist < min_dist) {
- min_dist = dist;
- idx = i;
- }
- }
-
- return idx;
-}
-
-static int get_resolution_index(int w, int h)
-{
- int i;
-
- for (i = 0; i < N_RES; i++) {
- if (w != gc2235_res[i].width)
- continue;
- if (h != gc2235_res[i].height)
- continue;
-
- return i;
- }
-
- return -1;
-}
-
static int startup(struct v4l2_subdev *sd)
{
struct gc2235_device *dev = to_gc2235_sensor(sd);
@@ -758,7 +690,7 @@ static int startup(struct v4l2_subdev *sd)
gc2235_write_reg_array(client, gc2235_init_settings);
}
- ret = gc2235_write_reg_array(client, gc2235_res[dev->fmt_idx].regs);
+ ret = gc2235_write_reg_array(client, dev->res->regs);
if (ret) {
dev_err(&client->dev, "gc2235 write register err.\n");
return ret;
@@ -776,8 +708,8 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
struct gc2235_device *dev = to_gc2235_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct camera_mipi_info *gc2235_info = NULL;
+ struct gc2235_resolution *res;
int ret = 0;
- int idx;
gc2235_info = v4l2_get_subdev_hostdata(sd);
if (!gc2235_info)
@@ -786,16 +718,18 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
return -EINVAL;
if (!fmt)
return -EINVAL;
+
mutex_lock(&dev->input_lock);
- idx = nearest_resolution_index(fmt->width, fmt->height);
- if (idx == -1) {
- /* return the largest resolution */
- fmt->width = gc2235_res[N_RES - 1].width;
- fmt->height = gc2235_res[N_RES - 1].height;
- } else {
- fmt->width = gc2235_res[idx].width;
- fmt->height = gc2235_res[idx].height;
- }
+ res = v4l2_find_nearest_size(gc2235_res_preview,
+ ARRAY_SIZE(gc2235_res_preview), width,
+ height, fmt->width, fmt->height);
+ if (!res)
+ res = &gc2235_res_preview[N_RES - 1];
+
+ fmt->width = res->width;
+ fmt->height = res->height;
+ dev->res = res;
+
fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
sd_state->pads->try_fmt = *fmt;
@@ -803,13 +737,6 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
return 0;
}
- dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- if (dev->fmt_idx == -1) {
- dev_err(&client->dev, "get resolution fail\n");
- mutex_unlock(&dev->input_lock);
- return -EINVAL;
- }
-
ret = startup(sd);
if (ret) {
dev_err(&client->dev, "gc2235 startup err\n");
@@ -817,7 +744,7 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
}
ret = gc2235_get_intg_factor(client, gc2235_info,
- &gc2235_res[dev->fmt_idx]);
+ dev->res);
if (ret)
dev_err(&client->dev, "failed to get integration_factor\n");
@@ -839,8 +766,8 @@ static int gc2235_get_fmt(struct v4l2_subdev *sd,
if (!fmt)
return -EINVAL;
- fmt->width = gc2235_res[dev->fmt_idx].width;
- fmt->height = gc2235_res[dev->fmt_idx].height;
+ fmt->width = dev->res->width;
+ fmt->height = dev->res->height;
fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
return 0;
@@ -953,7 +880,7 @@ static int gc2235_g_frame_interval(struct v4l2_subdev *sd,
struct gc2235_device *dev = to_gc2235_sensor(sd);
interval->interval.numerator = 1;
- interval->interval.denominator = gc2235_res[dev->fmt_idx].fps;
+ interval->interval.denominator = dev->res->fps;
return 0;
}
@@ -991,7 +918,7 @@ static int gc2235_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
struct gc2235_device *dev = to_gc2235_sensor(sd);
mutex_lock(&dev->input_lock);
- *frames = gc2235_res[dev->fmt_idx].skip_frames;
+ *frames = dev->res->skip_frames;
mutex_unlock(&dev->input_lock);
return 0;
@@ -1055,7 +982,7 @@ static int gc2235_probe(struct i2c_client *client)
mutex_init(&dev->input_lock);
- dev->fmt_idx = 0;
+ dev->res = &gc2235_res_preview[0];
v4l2_i2c_subdev_init(&dev->sd, client, &gc2235_ops);
gcpdev = gmin_camera_platform_data(&dev->sd,
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index 49f4090856d3..00d6842c07d6 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -579,107 +579,6 @@ static int mt9m114_s_power(struct v4l2_subdev *sd, int power)
return mt9m114_init_common(sd);
}
-/*
- * distance - calculate the distance
- * @res: resolution
- * @w: width
- * @h: height
- *
- * Get the gap between resolution and w/h.
- * res->width/height smaller than w/h wouldn't be considered.
- * Returns the value of gap or -1 if fail.
- */
-#define LARGEST_ALLOWED_RATIO_MISMATCH 600
-static int distance(struct mt9m114_res_struct const *res, u32 w, u32 h)
-{
- unsigned int w_ratio;
- unsigned int h_ratio;
- int match;
-
- if (w == 0)
- return -1;
- w_ratio = (res->width << 13) / w;
- if (h == 0)
- return -1;
- h_ratio = (res->height << 13) / h;
- if (h_ratio == 0)
- return -1;
- match = abs(((w_ratio << 13) / h_ratio) - 8192);
-
- if ((w_ratio < 8192) || (h_ratio < 8192) ||
- (match > LARGEST_ALLOWED_RATIO_MISMATCH))
- return -1;
-
- return w_ratio + h_ratio;
-}
-
-/* Return the nearest higher resolution index */
-static int nearest_resolution_index(int w, int h)
-{
- int i;
- int idx = -1;
- int dist;
- int min_dist = INT_MAX;
- const struct mt9m114_res_struct *tmp_res = NULL;
-
- for (i = 0; i < ARRAY_SIZE(mt9m114_res); i++) {
- tmp_res = &mt9m114_res[i];
- dist = distance(tmp_res, w, h);
- if (dist == -1)
- continue;
- if (dist < min_dist) {
- min_dist = dist;
- idx = i;
- }
- }
-
- return idx;
-}
-
-static int mt9m114_try_res(u32 *w, u32 *h)
-{
- int idx = 0;
-
- if ((*w > MT9M114_RES_960P_SIZE_H)
- || (*h > MT9M114_RES_960P_SIZE_V)) {
- *w = MT9M114_RES_960P_SIZE_H;
- *h = MT9M114_RES_960P_SIZE_V;
- } else {
- idx = nearest_resolution_index(*w, *h);
-
- /*
- * nearest_resolution_index() doesn't return smaller
- * resolutions. If it fails, it means the requested
- * resolution is higher than wecan support. Fallback
- * to highest possible resolution in this case.
- */
- if (idx == -1)
- idx = ARRAY_SIZE(mt9m114_res) - 1;
-
- *w = mt9m114_res[idx].width;
- *h = mt9m114_res[idx].height;
- }
-
- return 0;
-}
-
-static struct mt9m114_res_struct *mt9m114_to_res(u32 w, u32 h)
-{
- int index;
-
- for (index = 0; index < N_RES; index++) {
- if ((mt9m114_res[index].width == w) &&
- (mt9m114_res[index].height == h))
- break;
- }
-
- /* No mode found */
- if (index >= N_RES)
- return NULL;
-
- return &mt9m114_res[index];
-}
-
static int mt9m114_res2size(struct v4l2_subdev *sd, int *h_size, int *v_size)
{
struct mt9m114_device *dev = to_mt9m114_sensor(sd);
@@ -829,7 +728,7 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *fmt = &format->format;
struct i2c_client *c = v4l2_get_subdevdata(sd);
struct mt9m114_device *dev = to_mt9m114_sensor(sd);
- struct mt9m114_res_struct *res_index;
+ struct mt9m114_res_struct *res;
u32 width = fmt->width;
u32 height = fmt->height;
struct camera_mipi_info *mt9m114_info = NULL;
@@ -845,20 +744,21 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
if (!mt9m114_info)
return -EINVAL;
- mt9m114_try_res(&width, &height);
+ res = v4l2_find_nearest_size(mt9m114_res,
+ ARRAY_SIZE(mt9m114_res), width,
+ height, fmt->width, fmt->height);
+ if (!res)
+ res = &mt9m114_res[N_RES - 1];
+
+ fmt->width = res->width;
+ fmt->height = res->height;
+
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
sd_state->pads->try_fmt = *fmt;
return 0;
}
- res_index = mt9m114_to_res(width, height);
-
- /* Sanity check */
- if (unlikely(!res_index)) {
- WARN_ON(1);
- return -EINVAL;
- }
- switch (res_index->res) {
+ switch (res->res) {
case MT9M114_RES_736P:
ret = mt9m114_write_reg_array(c, mt9m114_736P_init, NO_POLLING);
ret += misensor_rmw_reg(c, MISENSOR_16BIT, MISENSOR_READ_MODE,
@@ -876,7 +776,7 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
MISENSOR_R_MODE_MASK, MISENSOR_NORMAL_SET);
break;
default:
- v4l2_err(sd, "set resolution: %d failed!\n", res_index->res);
+ v4l2_err(sd, "set resolution: %d failed!\n", res->res);
return -EINVAL;
}
@@ -890,7 +790,7 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
if (mt9m114_set_suspend(sd))
return -EINVAL;
- if (dev->res != res_index->res) {
+ if (dev->res != res->res) {
int index;
/* Switch to different size */
@@ -922,7 +822,7 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
}
}
ret = mt9m114_get_intg_factor(c, mt9m114_info,
- &mt9m114_res[res_index->res]);
+ &mt9m114_res[res->res]);
if (ret) {
dev_err(&c->dev, "failed to get integration_factor\n");
return -EINVAL;
@@ -931,7 +831,7 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
* mt9m114 - we don't poll for context switch
* because it does not happen with streaming disabled.
*/
- dev->res = res_index->res;
+ dev->res = res->res;
fmt->width = width;
fmt->height = height;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 2111e4a478c1..4ba99c660681 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -48,7 +48,7 @@ static enum atomisp_bayer_order ov2680_bayer_order_mapping[] = {
/* i2c read/write stuff */
static int ov2680_read_reg(struct i2c_client *client,
- int len, u16 reg, u16 *val)
+ int len, u16 reg, u32 *val)
{
struct i2c_msg msgs[2];
u8 addr_buf[2] = { reg >> 8, reg & 0xff };
@@ -86,7 +86,7 @@ static int ov2680_write_reg(struct i2c_client *client, unsigned int len,
int ret;
if (len == 2)
- put_unaligned_be16(val << (8 * (4 - len)), buf + 2);
+ put_unaligned_be16(val, buf + 2);
else if (len == 1)
buf[2] = val;
else
@@ -147,7 +147,7 @@ static int ov2680_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
struct i2c_client *client = v4l2_get_subdevdata(sd);
dev_dbg(&client->dev, "++++ov2680_g_bin_factor_x\n");
- *val = ov2680_res[dev->fmt_idx].bin_factor_x;
+ *val = dev->res->bin_factor_x;
return 0;
}
@@ -157,7 +157,7 @@ static int ov2680_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
struct ov2680_device *dev = to_ov2680_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- *val = ov2680_res[dev->fmt_idx].bin_factor_y;
+ *val = dev->res->bin_factor_y;
dev_dbg(&client->dev, "++++ov2680_g_bin_factor_y\n");
return 0;
}
@@ -166,11 +166,9 @@ static int ov2680_get_intg_factor(struct i2c_client *client,
struct camera_mipi_info *info,
const struct ov2680_resolution *res)
{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct ov2680_device *dev = to_ov2680_sensor(sd);
struct atomisp_sensor_mode_data *buf = &info->data;
unsigned int pix_clk_freq_hz;
- u16 reg_val;
+ u32 reg_val;
int ret;
dev_dbg(&client->dev, "++++ov2680_get_intg_factor\n");
@@ -180,7 +178,6 @@ static int ov2680_get_intg_factor(struct i2c_client *client,
/* pixel clock */
pix_clk_freq_hz = res->pix_clk_freq * 1000000;
- dev->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
buf->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
/* get integration time */
@@ -254,7 +251,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
"+++++++__ov2680_set_exposure coarse_itg %d, gain %d, digitgain %d++\n",
coarse_itg, gain, digitgain);
- vts = ov2680_res[dev->fmt_idx].lines_per_frame;
+ vts = dev->res->lines_per_frame;
/* group hold */
ret = ov2680_write_reg(client, 1,
@@ -359,10 +356,17 @@ static int ov2680_set_exposure(struct v4l2_subdev *sd, int exposure,
int gain, int digitgain)
{
struct ov2680_device *dev = to_ov2680_sensor(sd);
- int ret;
+ int ret = 0;
mutex_lock(&dev->input_lock);
- ret = __ov2680_set_exposure(sd, exposure, gain, digitgain);
+
+ dev->exposure = exposure;
+ dev->gain = gain;
+ dev->digitgain = digitgain;
+
+ if (dev->power_on)
+ ret = __ov2680_set_exposure(sd, exposure, gain, digitgain);
+
mutex_unlock(&dev->input_lock);
return ret;
@@ -383,7 +387,6 @@ static long ov2680_s_exposure(struct v4l2_subdev *sd,
return -EINVAL;
}
- // EXPOSURE CONTROL DISABLED FOR INITIAL CHECKIN, TUNING DOESN'T WORK
return ov2680_set_exposure(sd, coarse_itg, analog_gain, digital_gain);
}
@@ -406,56 +409,25 @@ static long ov2680_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
static int ov2680_q_exposure(struct v4l2_subdev *sd, s32 *value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
- u16 reg_v, reg_v2;
+ u32 reg_val;
int ret;
/* get exposure */
- ret = ov2680_read_reg(client, 1,
- OV2680_EXPOSURE_L,
- &reg_v);
+ ret = ov2680_read_reg(client, 3, OV2680_EXPOSURE_H, &reg_val);
if (ret)
- goto err;
-
- ret = ov2680_read_reg(client, 1,
- OV2680_EXPOSURE_M,
- &reg_v2);
- if (ret)
- goto err;
-
- reg_v += reg_v2 << 8;
- ret = ov2680_read_reg(client, 1,
- OV2680_EXPOSURE_H,
- &reg_v2);
- if (ret)
- goto err;
-
- *value = reg_v + (((u32)reg_v2 << 16));
-err:
- return ret;
-}
+ return ret;
-static u32 ov2680_translate_bayer_order(enum atomisp_bayer_order code)
-{
- switch (code) {
- case atomisp_bayer_order_rggb:
- return MEDIA_BUS_FMT_SRGGB10_1X10;
- case atomisp_bayer_order_grbg:
- return MEDIA_BUS_FMT_SGRBG10_1X10;
- case atomisp_bayer_order_bggr:
- return MEDIA_BUS_FMT_SBGGR10_1X10;
- case atomisp_bayer_order_gbrg:
- return MEDIA_BUS_FMT_SGBRG10_1X10;
- }
+ /* Lower four bits are not part of the exposure val (always 0) */
+ *value = reg_val >> 4;
return 0;
}
static int ov2680_v_flip(struct v4l2_subdev *sd, s32 value)
{
- struct ov2680_device *dev = to_ov2680_sensor(sd);
struct camera_mipi_info *ov2680_info = NULL;
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
- u16 val;
+ u32 val;
u8 index;
dev_dbg(&client->dev, "@%s: value:%d\n", __func__, value);
@@ -476,19 +448,16 @@ static int ov2680_v_flip(struct v4l2_subdev *sd, s32 value)
ov2680_info = v4l2_get_subdev_hostdata(sd);
if (ov2680_info) {
ov2680_info->raw_bayer_order = ov2680_bayer_order_mapping[index];
- dev->format.code = ov2680_translate_bayer_order(
- ov2680_info->raw_bayer_order);
}
return ret;
}
static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value)
{
- struct ov2680_device *dev = to_ov2680_sensor(sd);
struct camera_mipi_info *ov2680_info = NULL;
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
- u16 val;
+ u32 val;
u8 index;
dev_dbg(&client->dev, "@%s: value:%d\n", __func__, value);
@@ -510,8 +479,6 @@ static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value)
ov2680_info = v4l2_get_subdev_hostdata(sd);
if (ov2680_info) {
ov2680_info->raw_bayer_order = ov2680_bayer_order_mapping[index];
- dev->format.code = ov2680_translate_bayer_order(
- ov2680_info->raw_bayer_order);
}
return ret;
}
@@ -677,25 +644,6 @@ static int ov2680_init_registers(struct v4l2_subdev *sd)
return ret;
}
-static int ov2680_init(struct v4l2_subdev *sd)
-{
- struct ov2680_device *dev = to_ov2680_sensor(sd);
-
- int ret;
-
- mutex_lock(&dev->input_lock);
-
- /* restore settings */
- ov2680_res = ov2680_res_preview;
- N_RES = N_RES_PREVIEW;
-
- ret = ov2680_init_registers(sd);
-
- mutex_unlock(&dev->input_lock);
-
- return ret;
-}
-
static int power_ctrl(struct v4l2_subdev *sd, bool flag)
{
int ret = 0;
@@ -760,6 +708,9 @@ static int power_up(struct v4l2_subdev *sd)
return -ENODEV;
}
+ if (dev->power_on)
+ return 0; /* Already on */
+
/* power control */
ret = power_ctrl(sd, 1);
if (ret)
@@ -784,8 +735,19 @@ static int power_up(struct v4l2_subdev *sd)
/* according to DS, 20ms is needed between PWDN and i2c access */
msleep(20);
+ ret = ov2680_init_registers(sd);
+ if (ret)
+ goto fail_init_registers;
+
+ ret = __ov2680_set_exposure(sd, dev->exposure, dev->gain, dev->digitgain);
+ if (ret)
+ goto fail_init_registers;
+
+ dev->power_on = true;
return 0;
+fail_init_registers:
+ dev->platform_data->flisclk_ctrl(sd, 0);
fail_clk:
gpio_ctrl(sd, 0);
fail_power:
@@ -809,6 +771,9 @@ static int power_down(struct v4l2_subdev *sd)
return -ENODEV;
}
+ if (!dev->power_on)
+ return 0; /* Already off */
+
ret = dev->platform_data->flisclk_ctrl(sd, 0);
if (ret)
dev_err(&client->dev, "flisclk failed\n");
@@ -823,94 +788,31 @@ static int power_down(struct v4l2_subdev *sd)
/* power control */
ret = power_ctrl(sd, 0);
- if (ret)
+ if (ret) {
dev_err(&client->dev, "vprog failed.\n");
+ return ret;
+ }
- return ret;
+ dev->power_on = false;
+ return 0;
}
static int ov2680_s_power(struct v4l2_subdev *sd, int on)
{
+ struct ov2680_device *dev = to_ov2680_sensor(sd);
int ret;
+ mutex_lock(&dev->input_lock);
+
if (on == 0) {
ret = power_down(sd);
} else {
ret = power_up(sd);
- if (!ret)
- return ov2680_init(sd);
}
- return ret;
-}
-
-/*
- * distance - calculate the distance
- * @res: resolution
- * @w: width
- * @h: height
- *
- * Get the gap between resolution and w/h.
- * res->width/height smaller than w/h wouldn't be considered.
- * Returns the value of gap or -1 if fail.
- */
-#define LARGEST_ALLOWED_RATIO_MISMATCH 600
-static int distance(struct ov2680_resolution *res, u32 w, u32 h)
-{
- unsigned int w_ratio = (res->width << 13) / w;
- unsigned int h_ratio;
- int match;
-
- if (h == 0)
- return -1;
- h_ratio = (res->height << 13) / h;
- if (h_ratio == 0)
- return -1;
- match = abs(((w_ratio << 13) / h_ratio) - 8192);
-
- if ((w_ratio < 8192) || (h_ratio < 8192) ||
- (match > LARGEST_ALLOWED_RATIO_MISMATCH))
- return -1;
-
- return w_ratio + h_ratio;
-}
-/* Return the nearest higher resolution index */
-static int nearest_resolution_index(int w, int h)
-{
- int i;
- int idx = -1;
- int dist;
- int min_dist = INT_MAX;
- struct ov2680_resolution *tmp_res = NULL;
-
- for (i = 0; i < N_RES; i++) {
- tmp_res = &ov2680_res[i];
- dist = distance(tmp_res, w, h);
- if (dist == -1)
- continue;
- if (dist < min_dist) {
- min_dist = dist;
- idx = i;
- }
- }
-
- return idx;
-}
-
-static int get_resolution_index(int w, int h)
-{
- int i;
-
- for (i = 0; i < N_RES; i++) {
- if (w != ov2680_res[i].width)
- continue;
- if (h != ov2680_res[i].height)
- continue;
-
- return i;
- }
+ mutex_unlock(&dev->input_lock);
- return -1;
+ return ret;
}
static int ov2680_set_fmt(struct v4l2_subdev *sd,
@@ -921,8 +823,8 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
struct ov2680_device *dev = to_ov2680_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct camera_mipi_info *ov2680_info = NULL;
- int ret = 0;
- int idx = 0;
+ struct ov2680_resolution *res;
+ int vts, ret = 0;
dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
__func__,
@@ -940,41 +842,44 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
return -EINVAL;
mutex_lock(&dev->input_lock);
- idx = nearest_resolution_index(fmt->width, fmt->height);
- if (idx == -1) {
- /* return the largest resolution */
- fmt->width = ov2680_res[N_RES - 1].width;
- fmt->height = ov2680_res[N_RES - 1].height;
- } else {
- fmt->width = ov2680_res[idx].width;
- fmt->height = ov2680_res[idx].height;
- }
+
+ res = v4l2_find_nearest_size(ov2680_res_preview,
+ ARRAY_SIZE(ov2680_res_preview), width,
+ height, fmt->width, fmt->height);
+ if (!res)
+ res = &ov2680_res_preview[N_RES_PREVIEW - 1];
+
+ fmt->width = res->width;
+ fmt->height = res->height;
+
fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
sd_state->pads->try_fmt = *fmt;
mutex_unlock(&dev->input_lock);
return 0;
}
- dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- dev_dbg(&client->dev, "%s: Resolution index: %d\n",
- __func__, dev->fmt_idx);
- if (dev->fmt_idx == -1) {
- dev_err(&client->dev, "get resolution fail\n");
- mutex_unlock(&dev->input_lock);
- return -EINVAL;
- }
- dev_dbg(&client->dev, "%s: i=%d, w=%d, h=%d\n",
- __func__, dev->fmt_idx, fmt->width, fmt->height);
- // IS IT NEEDED?
+ dev_dbg(&client->dev, "%s: %dx%d\n",
+ __func__, fmt->width, fmt->height);
+
+ /* s_power has not been called yet for std v4l2 clients (camorama) */
power_up(sd);
- ret = ov2680_write_reg_array(client, ov2680_res[dev->fmt_idx].regs);
+ ret = ov2680_write_reg_array(client, dev->res->regs);
if (ret)
dev_err(&client->dev,
"ov2680 write resolution register err: %d\n", ret);
- ret = ov2680_get_intg_factor(client, ov2680_info,
- &ov2680_res[dev->fmt_idx]);
+ vts = dev->res->lines_per_frame;
+
+ /* If necessary increase the VTS to match exposure + MARGIN */
+ if (dev->exposure > vts - OV2680_INTEGRATION_TIME_MARGIN)
+ vts = dev->exposure + OV2680_INTEGRATION_TIME_MARGIN;
+
+ ret = ov2680_write_reg(client, 2, OV2680_TIMING_VTS_H, vts);
+ if (ret)
+ dev_err(&client->dev, "ov2680 write vts err: %d\n", ret);
+
+ ret = ov2680_get_intg_factor(client, ov2680_info, res);
if (ret) {
dev_err(&client->dev, "failed to get integration factor\n");
goto err;
@@ -989,8 +894,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
if (v_flag)
ov2680_v_flip(sd, v_flag);
- v4l2_info(client, "\n%s idx %d\n", __func__, dev->fmt_idx);
-
/*
* ret = startup(sd);
* if (ret)
@@ -1014,8 +917,8 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
if (!fmt)
return -EINVAL;
- fmt->width = ov2680_res[dev->fmt_idx].width;
- fmt->height = ov2680_res[dev->fmt_idx].height;
+ fmt->width = dev->res->width;
+ fmt->height = dev->res->height;
fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
return 0;
@@ -1024,7 +927,7 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
static int ov2680_detect(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
- u16 high, low;
+ u32 high, low;
int ret;
u16 id;
u8 revision;
@@ -1072,11 +975,6 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
ret = ov2680_write_reg(client, 1, OV2680_SW_STREAM,
enable ? OV2680_START_STREAMING :
OV2680_STOP_STREAMING);
-#if 0
- /* restore settings */
- ov2680_res = ov2680_res_preview;
- N_RES = N_RES_PREVIEW;
-#endif
//otp valid at stream on state
//if(!dev->otp_data)
@@ -1101,16 +999,6 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
(struct camera_sensor_platform_data *)platform_data;
mutex_lock(&dev->input_lock);
- /*
- * power off the module, then power on it in future
- * as first power on by board may not fulfill the
- * power on sequqence needed by the module
- */
- ret = power_down(sd);
- if (ret) {
- dev_err(&client->dev, "ov2680 power-off err.\n");
- goto fail_power_off;
- }
ret = power_up(sd);
if (ret) {
@@ -1144,7 +1032,6 @@ fail_csi_cfg:
fail_power_on:
power_down(sd);
dev_err(&client->dev, "sensor power-gating failed\n");
-fail_power_off:
mutex_unlock(&dev->input_lock);
return ret;
}
@@ -1155,7 +1042,7 @@ static int ov2680_g_frame_interval(struct v4l2_subdev *sd,
struct ov2680_device *dev = to_ov2680_sensor(sd);
interval->interval.numerator = 1;
- interval->interval.denominator = ov2680_res[dev->fmt_idx].fps;
+ interval->interval.denominator = dev->res->fps;
return 0;
}
@@ -1177,13 +1064,33 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd,
{
int index = fse->index;
- if (index >= N_RES)
+ if (index >= N_RES_PREVIEW)
return -EINVAL;
- fse->min_width = ov2680_res[index].width;
- fse->min_height = ov2680_res[index].height;
- fse->max_width = ov2680_res[index].width;
- fse->max_height = ov2680_res[index].height;
+ fse->min_width = ov2680_res_preview[index].width;
+ fse->min_height = ov2680_res_preview[index].height;
+ fse->max_width = ov2680_res_preview[index].width;
+ fse->max_height = ov2680_res_preview[index].height;
+
+ return 0;
+}
+
+static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ struct v4l2_fract fract;
+
+ if (fie->index >= N_RES_PREVIEW ||
+ fie->width > ov2680_res_preview[0].width ||
+ fie->height > ov2680_res_preview[0].height ||
+ fie->which > V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
+ fract.denominator = ov2680_res_preview[fie->index].fps;
+ fract.numerator = 1;
+
+ fie->interval = fract;
return 0;
}
@@ -1193,7 +1100,7 @@ static int ov2680_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
struct ov2680_device *dev = to_ov2680_sensor(sd);
mutex_lock(&dev->input_lock);
- *frames = ov2680_res[dev->fmt_idx].skip_frames;
+ *frames = dev->res->skip_frames;
mutex_unlock(&dev->input_lock);
return 0;
@@ -1216,6 +1123,7 @@ static const struct v4l2_subdev_core_ops ov2680_core_ops = {
static const struct v4l2_subdev_pad_ops ov2680_pad_ops = {
.enum_mbus_code = ov2680_enum_mbus_code,
.enum_frame_size = ov2680_enum_frame_size,
+ .enum_frame_interval = ov2680_enum_frame_interval,
.get_fmt = ov2680_get_fmt,
.set_fmt = ov2680_set_fmt,
};
@@ -1257,7 +1165,9 @@ static int ov2680_probe(struct i2c_client *client)
mutex_init(&dev->input_lock);
- dev->fmt_idx = 0;
+ dev->res = &ov2680_res_preview[0];
+ dev->exposure = dev->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
+ dev->gain = 250; /* 0-2047 */
v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
pdata = gmin_camera_platform_data(&dev->sd,
@@ -1278,7 +1188,6 @@ static int ov2680_probe(struct i2c_client *client)
dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
dev->pad.flags = MEDIA_PAD_FL_SOURCE;
- dev->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret =
v4l2_ctrl_handler_init(&dev->ctrl_handler,
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index 90d0871a78a3..da98094d7094 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -557,7 +557,7 @@ static int ov2722_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
ret = ov2722_g_fnumber_range(&dev->sd, &ctrl->val);
break;
case V4L2_CID_LINK_FREQ:
- val = ov2722_res[dev->fmt_idx].mipi_freq;
+ val = dev->res->mipi_freq;
if (val == 0)
return -EINVAL;
@@ -782,76 +782,6 @@ static int ov2722_s_power(struct v4l2_subdev *sd, int on)
return ret;
}
-/*
- * distance - calculate the distance
- * @res: resolution
- * @w: width
- * @h: height
- *
- * Get the gap between resolution and w/h.
- * res->width/height smaller than w/h wouldn't be considered.
- * Returns the value of gap or -1 if fail.
- */
-#define LARGEST_ALLOWED_RATIO_MISMATCH 800
-static int distance(struct ov2722_resolution *res, u32 w, u32 h)
-{
- unsigned int w_ratio = (res->width << 13) / w;
- unsigned int h_ratio;
- int match;
-
- if (h == 0)
- return -1;
- h_ratio = (res->height << 13) / h;
- if (h_ratio == 0)
- return -1;
- match = abs(((w_ratio << 13) / h_ratio) - 8192);
-
- if ((w_ratio < 8192) || (h_ratio < 8192) ||
- (match > LARGEST_ALLOWED_RATIO_MISMATCH))
- return -1;
-
- return w_ratio + h_ratio;
-}
-
-/* Return the nearest higher resolution index */
-static int nearest_resolution_index(int w, int h)
-{
- int i;
- int idx = -1;
- int dist;
- int min_dist = INT_MAX;
- struct ov2722_resolution *tmp_res = NULL;
-
- for (i = 0; i < N_RES; i++) {
- tmp_res = &ov2722_res[i];
- dist = distance(tmp_res, w, h);
- if (dist == -1)
- continue;
- if (dist < min_dist) {
- min_dist = dist;
- idx = i;
- }
- }
-
- return idx;
-}
-
-static int get_resolution_index(int w, int h)
-{
- int i;
-
- for (i = 0; i < N_RES; i++) {
- if (w != ov2722_res[i].width)
- continue;
- if (h != ov2722_res[i].height)
- continue;
-
- return i;
- }
-
- return -1;
-}
-
/* TODO: remove it. */
static int startup(struct v4l2_subdev *sd)
{
@@ -866,7 +796,7 @@ static int startup(struct v4l2_subdev *sd)
return ret;
}
- ret = ov2722_write_reg_array(client, ov2722_res[dev->fmt_idx].regs);
+ ret = ov2722_write_reg_array(client, dev->res->regs);
if (ret) {
dev_err(&client->dev, "ov2722 write register err.\n");
return ret;
@@ -882,9 +812,9 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *fmt = &format->format;
struct ov2722_device *dev = to_ov2722_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ov2722_resolution *res;
struct camera_mipi_info *ov2722_info = NULL;
int ret = 0;
- int idx;
if (format->pad)
return -EINVAL;
@@ -895,15 +825,16 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
return -EINVAL;
mutex_lock(&dev->input_lock);
- idx = nearest_resolution_index(fmt->width, fmt->height);
- if (idx == -1) {
- /* return the largest resolution */
- fmt->width = ov2722_res[N_RES - 1].width;
- fmt->height = ov2722_res[N_RES - 1].height;
- } else {
- fmt->width = ov2722_res[idx].width;
- fmt->height = ov2722_res[idx].height;
- }
+ res = v4l2_find_nearest_size(ov2722_res_preview,
+ ARRAY_SIZE(ov2722_res_preview), width,
+ height, fmt->width, fmt->height);
+ if (!res)
+ res = &ov2722_res_preview[N_RES - 1];
+
+ fmt->width = res->width;
+ fmt->height = res->height;
+ dev->res = res;
+
fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
sd_state->pads->try_fmt = *fmt;
@@ -911,15 +842,9 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
return 0;
}
- dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
- if (dev->fmt_idx == -1) {
- dev_err(&client->dev, "get resolution fail\n");
- mutex_unlock(&dev->input_lock);
- return -EINVAL;
- }
- dev->pixels_per_line = ov2722_res[dev->fmt_idx].pixels_per_line;
- dev->lines_per_frame = ov2722_res[dev->fmt_idx].lines_per_frame;
+ dev->pixels_per_line = dev->res->pixels_per_line;
+ dev->lines_per_frame = dev->res->lines_per_frame;
ret = startup(sd);
if (ret) {
@@ -950,8 +875,7 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
}
}
- ret = ov2722_get_intg_factor(client, ov2722_info,
- &ov2722_res[dev->fmt_idx]);
+ ret = ov2722_get_intg_factor(client, ov2722_info, dev->res);
if (ret)
dev_err(&client->dev, "failed to get integration_factor\n");
@@ -972,8 +896,8 @@ static int ov2722_get_fmt(struct v4l2_subdev *sd,
if (!fmt)
return -EINVAL;
- fmt->width = ov2722_res[dev->fmt_idx].width;
- fmt->height = ov2722_res[dev->fmt_idx].height;
+ fmt->width = dev->res->width;
+ fmt->height = dev->res->height;
fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
return 0;
@@ -1098,7 +1022,7 @@ static int ov2722_g_frame_interval(struct v4l2_subdev *sd,
struct ov2722_device *dev = to_ov2722_sensor(sd);
interval->interval.numerator = 1;
- interval->interval.denominator = ov2722_res[dev->fmt_idx].fps;
+ interval->interval.denominator = dev->res->fps;
return 0;
}
@@ -1136,7 +1060,7 @@ static int ov2722_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
struct ov2722_device *dev = to_ov2722_sensor(sd);
mutex_lock(&dev->input_lock);
- *frames = ov2722_res[dev->fmt_idx].skip_frames;
+ *frames = dev->res->skip_frames;
mutex_unlock(&dev->input_lock);
return 0;
@@ -1220,7 +1144,7 @@ static int ov2722_probe(struct i2c_client *client)
mutex_init(&dev->input_lock);
- dev->fmt_idx = 0;
+ dev->res = &ov2722_res_preview[0];
v4l2_i2c_subdev_init(&dev->sd, client, &ov2722_ops);
ovpdev = gmin_camera_platform_data(&dev->sd,
diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
index 2fe3de115083..db643ebc3909 100644
--- a/drivers/staging/media/atomisp/i2c/gc0310.h
+++ b/drivers/staging/media/atomisp/i2c/gc0310.h
@@ -150,8 +150,7 @@ struct gc0310_device {
struct camera_sensor_platform_data *platform_data;
int vt_pix_clk_freq_mhz;
- int fmt_idx;
- u8 res;
+ struct gc0310_resolution *res;
u8 type;
};
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
index ba5db1230033..806be5dff7a5 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -158,11 +158,10 @@ struct gc2235_device {
struct v4l2_mbus_framefmt format;
struct mutex input_lock;
struct v4l2_ctrl_handler ctrl_handler;
+ struct gc2235_resolution *res;
struct camera_sensor_platform_data *platform_data;
int vt_pix_clk_freq_mhz;
- int fmt_idx;
- u8 res;
u8 type;
};
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 874115f35fca..4e351196fe34 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -141,7 +141,6 @@ struct regval_list {
};
struct ov2680_resolution {
- u8 *desc;
const struct ov2680_reg *regs;
int res;
int width;
@@ -154,7 +153,6 @@ struct ov2680_resolution {
u8 bin_factor_x;
u8 bin_factor_y;
u8 bin_mode;
- bool used;
};
struct ov2680_format {
@@ -169,15 +167,14 @@ struct ov2680_format {
struct ov2680_device {
struct v4l2_subdev sd;
struct media_pad pad;
- struct v4l2_mbus_framefmt format;
struct mutex input_lock;
struct v4l2_ctrl_handler ctrl_handler;
+ struct ov2680_resolution *res;
struct camera_sensor_platform_data *platform_data;
- int vt_pix_clk_freq_mhz;
- int fmt_idx;
- int run_mode;
- u8 res;
- u8 type;
+ bool power_on;
+ u16 exposure;
+ u16 gain;
+ u16 digitgain;
};
/**
@@ -283,14 +280,11 @@ static struct ov2680_reg const ov2680_global_setting[] = {
{}
};
-#if 0 /* None of the definitions below are used currently */
/*
* 176x144 30fps VBlanking 1lane 10Bit (binning)
*/
static struct ov2680_reg const ov2680_QCIF_30fps[] = {
{0x3086, 0x01},
- {0x3501, 0x24},
- {0x3502, 0x40},
{0x370a, 0x23},
{0x3801, 0xa0},
{0x3802, 0x00},
@@ -305,8 +299,6 @@ static struct ov2680_reg const ov2680_QCIF_30fps[] = {
{0x380b, 0xa0},
{0x380c, 0x06},
{0x380d, 0xb0},
- {0x380e, 0x02},
- {0x380f, 0x84},
{0x3810, 0x00},
{0x3811, 0x04},
{0x3812, 0x00},
@@ -334,8 +326,6 @@ static struct ov2680_reg const ov2680_QCIF_30fps[] = {
*/
static struct ov2680_reg const ov2680_CIF_30fps[] = {
{0x3086, 0x01},
- {0x3501, 0x24},
- {0x3502, 0x40},
{0x370a, 0x23},
{0x3801, 0xa0},
{0x3802, 0x00},
@@ -350,8 +340,6 @@ static struct ov2680_reg const ov2680_CIF_30fps[] = {
{0x380b, 0x30},
{0x380c, 0x06},
{0x380d, 0xb0},
- {0x380e, 0x02},
- {0x380f, 0x84},
{0x3810, 0x00},
{0x3811, 0x04},
{0x3812, 0x00},
@@ -377,8 +365,6 @@ static struct ov2680_reg const ov2680_CIF_30fps[] = {
*/
static struct ov2680_reg const ov2680_QVGA_30fps[] = {
{0x3086, 0x01},
- {0x3501, 0x24},
- {0x3502, 0x40},
{0x370a, 0x23},
{0x3801, 0xa0},
{0x3802, 0x00},
@@ -393,8 +379,6 @@ static struct ov2680_reg const ov2680_QVGA_30fps[] = {
{0x380b, 0x00},
{0x380c, 0x06},
{0x380d, 0xb0},
- {0x380e, 0x02},
- {0x380f, 0x84},
{0x3810, 0x00},
{0x3811, 0x04},
{0x3812, 0x00},
@@ -420,8 +404,6 @@ static struct ov2680_reg const ov2680_QVGA_30fps[] = {
*/
static struct ov2680_reg const ov2680_656x496_30fps[] = {
{0x3086, 0x01},
- {0x3501, 0x24},
- {0x3502, 0x40},
{0x370a, 0x23},
{0x3801, 0xa0},
{0x3802, 0x00},
@@ -436,8 +418,6 @@ static struct ov2680_reg const ov2680_656x496_30fps[] = {
{0x380b, 0xf0},
{0x380c, 0x06},
{0x380d, 0xb0},
- {0x380e, 0x02},
- {0x380f, 0x84},
{0x3810, 0x00},
{0x3811, 0x04},
{0x3812, 0x00},
@@ -459,12 +439,10 @@ static struct ov2680_reg const ov2680_656x496_30fps[] = {
};
/*
- * 800x600 30fps VBlanking 1lane 10Bit (binning)
+ * 720x592 30fps VBlanking 1lane 10Bit (binning)
*/
static struct ov2680_reg const ov2680_720x592_30fps[] = {
{0x3086, 0x01},
- {0x3501, 0x26},
- {0x3502, 0x40},
{0x370a, 0x23},
{0x3801, 0x00}, // X_ADDR_START;
{0x3802, 0x00},
@@ -479,8 +457,6 @@ static struct ov2680_reg const ov2680_720x592_30fps[] = {
{0x380b, 0x50}, // Y_OUTPUT_SIZE;
{0x380c, 0x06},
{0x380d, 0xac}, // HTS;
- {0x380e, 0x02},
- {0x380f, 0x84}, // VTS;
{0x3810, 0x00},
{0x3811, 0x00},
{0x3812, 0x00},
@@ -508,8 +484,6 @@ static struct ov2680_reg const ov2680_720x592_30fps[] = {
*/
static struct ov2680_reg const ov2680_800x600_30fps[] = {
{0x3086, 0x01},
- {0x3501, 0x26},
- {0x3502, 0x40},
{0x370a, 0x23},
{0x3801, 0x00},
{0x3802, 0x00},
@@ -524,8 +498,6 @@ static struct ov2680_reg const ov2680_800x600_30fps[] = {
{0x380b, 0x58},
{0x380c, 0x06},
{0x380d, 0xac},
- {0x380e, 0x02},
- {0x380f, 0x84},
{0x3810, 0x00},
{0x3811, 0x00},
{0x3812, 0x00},
@@ -551,8 +523,6 @@ static struct ov2680_reg const ov2680_800x600_30fps[] = {
*/
static struct ov2680_reg const ov2680_720p_30fps[] = {
{0x3086, 0x00},
- {0x3501, 0x48},
- {0x3502, 0xe0},
{0x370a, 0x21},
{0x3801, 0xa0},
{0x3802, 0x00},
@@ -567,8 +537,6 @@ static struct ov2680_reg const ov2680_720p_30fps[] = {
{0x380b, 0xe0},
{0x380c, 0x06},
{0x380d, 0xa8},
- {0x380e, 0x05},
- {0x380f, 0x0e},
{0x3810, 0x00},
{0x3811, 0x08},
{0x3812, 0x00},
@@ -594,8 +562,6 @@ static struct ov2680_reg const ov2680_720p_30fps[] = {
*/
static struct ov2680_reg const ov2680_1296x976_30fps[] = {
{0x3086, 0x00},
- {0x3501, 0x48},
- {0x3502, 0xe0},
{0x370a, 0x21},
{0x3801, 0xa0},
{0x3802, 0x00},
@@ -610,8 +576,6 @@ static struct ov2680_reg const ov2680_1296x976_30fps[] = {
{0x380b, 0xd0},
{0x380c, 0x06},
{0x380d, 0xa8},
- {0x380e, 0x05},
- {0x380f, 0x0e},
{0x3810, 0x00},
{0x3811, 0x08},
{0x3812, 0x00},
@@ -637,8 +601,6 @@ static struct ov2680_reg const ov2680_1296x976_30fps[] = {
*/
static struct ov2680_reg const ov2680_1456x1096_30fps[] = {
{0x3086, 0x00},
- {0x3501, 0x48},
- {0x3502, 0xe0},
{0x370a, 0x21},
{0x3801, 0x90},
{0x3802, 0x00},
@@ -653,8 +615,6 @@ static struct ov2680_reg const ov2680_1456x1096_30fps[] = {
{0x380b, 0x48},
{0x380c, 0x06},
{0x380d, 0xa8},
- {0x380e, 0x05},
- {0x380f, 0x0e},
{0x3810, 0x00},
{0x3811, 0x08},
{0x3812, 0x00},
@@ -674,7 +634,6 @@ static struct ov2680_reg const ov2680_1456x1096_30fps[] = {
// {0x5090, 0x0c},
{}
};
-#endif
/*
*1616x916 30fps VBlanking 1lane 10bit
@@ -682,8 +641,6 @@ static struct ov2680_reg const ov2680_1456x1096_30fps[] = {
static struct ov2680_reg const ov2680_1616x916_30fps[] = {
{0x3086, 0x00},
- {0x3501, 0x48},
- {0x3502, 0xe0},
{0x370a, 0x21},
{0x3801, 0x00},
{0x3802, 0x00},
@@ -698,8 +655,6 @@ static struct ov2680_reg const ov2680_1616x916_30fps[] = {
{0x380b, 0x94},
{0x380c, 0x06},
{0x380d, 0xa8},
- {0x380e, 0x05},
- {0x380f, 0x0e},
{0x3810, 0x00},
{0x3811, 0x00},
{0x3812, 0x00},
@@ -721,13 +676,10 @@ static struct ov2680_reg const ov2680_1616x916_30fps[] = {
};
/*
- * 1612x1212 30fps VBlanking 1lane 10Bit
+ * 1616x1082 30fps VBlanking 1lane 10Bit
*/
-#if 0
static struct ov2680_reg const ov2680_1616x1082_30fps[] = {
{0x3086, 0x00},
- {0x3501, 0x48},
- {0x3502, 0xe0},
{0x370a, 0x21},
{0x3801, 0x00},
{0x3802, 0x00},
@@ -742,8 +694,6 @@ static struct ov2680_reg const ov2680_1616x1082_30fps[] = {
{0x380b, 0x3a},
{0x380c, 0x06},
{0x380d, 0xa8},
- {0x380e, 0x05},
- {0x380f, 0x0e},
{0x3810, 0x00},
{0x3811, 0x00},
{0x3812, 0x00},
@@ -763,14 +713,12 @@ static struct ov2680_reg const ov2680_1616x1082_30fps[] = {
{0x5081, 0x41},
{}
};
-#endif
+
/*
* 1616x1216 30fps VBlanking 1lane 10Bit
*/
static struct ov2680_reg const ov2680_1616x1216_30fps[] = {
{0x3086, 0x00},
- {0x3501, 0x48},
- {0x3502, 0xe0},
{0x370a, 0x21},
{0x3801, 0x00},
{0x3802, 0x00},
@@ -785,8 +733,6 @@ static struct ov2680_reg const ov2680_1616x1216_30fps[] = {
{0x380b, 0xc0},//c0},
{0x380c, 0x06},
{0x380d, 0xa8},
- {0x380e, 0x05},
- {0x380f, 0x0e},
{0x3810, 0x00},
{0x3811, 0x00},
{0x3812, 0x00},
@@ -809,12 +755,10 @@ static struct ov2680_reg const ov2680_1616x1216_30fps[] = {
static struct ov2680_resolution ov2680_res_preview[] = {
{
- .desc = "ov2680_1616x1216_30fps",
.width = 1616,
.height = 1216,
.pix_clk_freq = 66,
.fps = 30,
- .used = 0,
.pixels_per_line = 1698,//1704,
.lines_per_frame = 1294,
.bin_factor_x = 0,
@@ -824,12 +768,23 @@ static struct ov2680_resolution ov2680_res_preview[] = {
.regs = ov2680_1616x1216_30fps,
},
{
- .desc = "ov2680_1616x916_30fps",
+ .width = 1616,
+ .height = 1082,
+ .pix_clk_freq = 66,
+ .fps = 30,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_1616x1082_30fps,
+ },
+ {
.width = 1616,
.height = 916,
.fps = 30,
.pix_clk_freq = 66,
- .used = 0,
.pixels_per_line = 1698,//1704,
.lines_per_frame = 1294,
.bin_factor_x = 0,
@@ -838,11 +793,125 @@ static struct ov2680_resolution ov2680_res_preview[] = {
.skip_frames = 3,
.regs = ov2680_1616x916_30fps,
},
+ {
+ .width = 1456,
+ .height = 1096,
+ .fps = 30,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_1456x1096_30fps,
+ },
+ {
+ .width = 1296,
+ .height = 976,
+ .fps = 30,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_1296x976_30fps,
+ },
+ {
+ .width = 1280,
+ .height = 720,
+ .fps = 60,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_720p_30fps,
+ },
+ {
+ .width = 800,
+ .height = 600,
+ .fps = 60,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_800x600_30fps,
+ },
+ {
+ .width = 720,
+ .height = 592,
+ .fps = 60,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_720x592_30fps,
+ },
+ {
+ .width = 656,
+ .height = 496,
+ .fps = 60,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_656x496_30fps,
+ },
+ {
+ .width = 336,
+ .height = 256,
+ .fps = 60,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_QVGA_30fps,
+ },
+ {
+ .width = 352,
+ .height = 288,
+ .fps = 60,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_CIF_30fps,
+ },
+ {
+ .width = 176,
+ .height = 144,
+ .fps = 60,
+ .pix_clk_freq = 66,
+ .pixels_per_line = 1698,//1704,
+ .lines_per_frame = 1294,
+ .bin_factor_x = 0,
+ .bin_factor_y = 0,
+ .bin_mode = 0,
+ .skip_frames = 3,
+ .regs = ov2680_QCIF_30fps,
+ },
};
#define N_RES_PREVIEW (ARRAY_SIZE(ov2680_res_preview))
-static struct ov2680_resolution *ov2680_res = ov2680_res_preview;
-static unsigned long N_RES = N_RES_PREVIEW;
-
#endif
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
index 7b0debb6c53d..d6e2510bc01c 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -201,14 +201,13 @@ struct ov2722_device {
struct media_pad pad;
struct v4l2_mbus_framefmt format;
struct mutex input_lock;
+ struct ov2722_resolution *res;
struct camera_sensor_platform_data *platform_data;
int vt_pix_clk_freq_mhz;
- int fmt_idx;
int run_mode;
u16 pixels_per_line;
u16 lines_per_frame;
- u8 res;
u8 type;
struct v4l2_ctrl_handler ctrl_handler;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 366161cff560..97d5a528969b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -857,7 +857,8 @@ static struct atomisp_video_pipe *__atomisp_get_pipe(
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
/* For online video or SDV video pipe. */
if (css_pipe_id == IA_CSS_PIPE_ID_VIDEO ||
- css_pipe_id == IA_CSS_PIPE_ID_COPY) {
+ css_pipe_id == IA_CSS_PIPE_ID_COPY ||
+ css_pipe_id == IA_CSS_PIPE_ID_YUVPP) {
if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
return &asd->video_out_video_capture;
return &asd->video_out_preview;
@@ -865,7 +866,8 @@ static struct atomisp_video_pipe *__atomisp_get_pipe(
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
/* For online preview or ZSL preview pipe. */
if (css_pipe_id == IA_CSS_PIPE_ID_PREVIEW ||
- css_pipe_id == IA_CSS_PIPE_ID_COPY)
+ css_pipe_id == IA_CSS_PIPE_ID_COPY ||
+ css_pipe_id == IA_CSS_PIPE_ID_YUVPP)
return &asd->video_out_preview;
}
/* For capture pipe. */
@@ -1046,13 +1048,8 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error,
asd->pending_capture_request--;
- if (IS_ISP2401)
- asd->re_trigger_capture = false;
-
dev_dbg(isp->dev, "Trigger capture again for new buffer. err=%d\n",
err);
- } else if (IS_ISP2401) {
- asd->re_trigger_capture = true;
}
break;
case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:
@@ -1474,7 +1471,7 @@ void atomisp_wdt_work(struct work_struct *work)
wdt_work);
int i;
unsigned int pipe_wdt_cnt[MAX_STREAM_NUM][4] = { {0} };
- bool css_recover = false;
+ bool css_recover = true;
rt_mutex_lock(&isp->mutex);
if (!atomisp_streaming_count(isp)) {
@@ -1487,12 +1484,7 @@ void atomisp_wdt_work(struct work_struct *work)
dev_err(isp->dev, "timeout %d of %d\n",
atomic_read(&isp->wdt_count) + 1,
ATOMISP_ISP_MAX_TIMEOUT_COUNT);
-
- if (atomic_inc_return(&isp->wdt_count) < ATOMISP_ISP_MAX_TIMEOUT_COUNT)
- css_recover = true;
} else {
- css_recover = true;
-
for (i = 0; i < isp->num_of_streams; i++) {
struct atomisp_sub_device *asd = &isp->asd[i];
@@ -1715,6 +1707,12 @@ void atomisp_wdt_refresh_pipe(struct atomisp_video_pipe *pipe,
{
unsigned long next;
+ if (!pipe->asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, pipe->vdev.name);
+ return;
+ }
+
if (delay != ATOMISP_WDT_KEEP_CURRENT_DELAY)
pipe->wdt_duration = delay;
@@ -1777,6 +1775,12 @@ void atomisp_wdt_refresh(struct atomisp_sub_device *asd, unsigned int delay)
/* ISP2401 */
void atomisp_wdt_stop_pipe(struct atomisp_video_pipe *pipe, bool sync)
{
+ if (!pipe->asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, pipe->vdev.name);
+ return;
+ }
+
if (!atomisp_is_wdt_running(pipe))
return;
@@ -1869,7 +1873,7 @@ irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr)
/*
* The standard CSS2.0 API tells the following calling sequence of
* dequeue ready buffers:
- * while (ia_css_dequeue_event(...)) {
+ * while (ia_css_dequeue_psys_event(...)) {
* switch (event.type) {
* ...
* ia_css_pipe_dequeue_buffer()
@@ -1920,22 +1924,6 @@ out:
}
/*
- * utils for buffer allocation/free
- */
-
-int atomisp_get_frame_pgnr(struct atomisp_device *isp,
- const struct ia_css_frame *frame, u32 *p_pgnr)
-{
- if (!frame) {
- dev_err(isp->dev, "%s: NULL frame pointer ERROR.\n", __func__);
- return -EINVAL;
- }
-
- *p_pgnr = DIV_ROUND_UP(frame->data_bytes, PAGE_SIZE);
- return 0;
-}
-
-/*
* Get internal fmt according to V4L2 fmt
*/
static enum ia_css_frame_format
@@ -1968,9 +1956,11 @@ v4l2_fmt_to_sh_fmt(u32 fmt)
return IA_CSS_FRAME_FORMAT_RGBA888;
case V4L2_PIX_FMT_RGB565:
return IA_CSS_FRAME_FORMAT_RGB565;
+#if 0
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_CUSTOM_M10MO_RAW:
return IA_CSS_FRAME_FORMAT_BINARY_8;
+#endif
case V4L2_PIX_FMT_SBGGR16:
case V4L2_PIX_FMT_SBGGR10:
case V4L2_PIX_FMT_SGBRG10:
@@ -2022,7 +2012,7 @@ static int raw_output_format_match_input(u32 input, u32 output)
return -EINVAL;
}
-static u32 get_pixel_depth(u32 pixelformat)
+u32 atomisp_get_pixel_depth(u32 pixelformat)
{
switch (pixelformat) {
case V4L2_PIX_FMT_YUV420:
@@ -3619,18 +3609,10 @@ int atomisp_cp_lsc_table(struct atomisp_sub_device *asd,
}
/* Shading table size per color */
- if (!IS_ISP2401) {
- if (st->width > ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
- st->height > ISP2400_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR) {
- dev_err(asd->isp->dev, "shading table w/h validate failed!");
- return -EINVAL;
- }
- } else {
- if (st->width > ISP2401_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
- st->height > ISP2401_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR) {
- dev_err(asd->isp->dev, "shading table w/h validate failed!");
- return -EINVAL;
- }
+ if (st->width > SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
+ st->height > SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR) {
+ dev_err(asd->isp->dev, "shading table w/h validate failed!");
+ return -EINVAL;
}
shading_table = atomisp_css_shading_table_alloc(st->width, st->height);
@@ -4109,6 +4091,12 @@ void atomisp_handle_parameter_and_buffer(struct atomisp_video_pipe *pipe)
unsigned long irqflags;
bool need_to_enqueue_buffer = false;
+ if (!asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, pipe->vdev.name);
+ return;
+ }
+
if (atomisp_is_vf_pipe(pipe))
return;
@@ -4196,6 +4184,12 @@ int atomisp_set_parameters(struct video_device *vdev,
struct atomisp_css_params *css_param = &asd->params.css_param;
int ret;
+ if (!asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
dev_err(asd->isp->dev, "%s: internal error!\n", __func__);
return -EINVAL;
@@ -4792,15 +4786,6 @@ int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
return 0;
}
-int atomisp_get_fmt(struct video_device *vdev, struct v4l2_format *f)
-{
- struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
-
- f->fmt.pix = pipe->pix;
-
- return 0;
-}
-
static void __atomisp_update_stream_env(struct atomisp_sub_device *asd,
u16 stream_index, struct atomisp_input_stream_info *stream_info)
{
@@ -4857,6 +4842,12 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f,
int source_pad = atomisp_subdev_source_pad(vdev);
int ret;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (!isp->inputs[asd->input_curr].camera)
return -EINVAL;
@@ -4943,7 +4934,7 @@ atomisp_try_fmt_file(struct atomisp_device *isp, struct v4l2_format *f)
return -EINVAL;
}
- depth = get_pixel_depth(pixelformat);
+ depth = atomisp_get_pixel_depth(pixelformat);
if (field == V4L2_FIELD_ANY) {
field = V4L2_FIELD_NONE;
@@ -5133,11 +5124,11 @@ static int css_input_resolution_changed(struct atomisp_sub_device *asd,
dev_dbg(asd->isp->dev, "css_input_resolution_changed to %ux%u\n",
ffmt->width, ffmt->height);
-#if defined(ISP2401_NEW_INPUT_SYSTEM)
- atomisp_css_input_set_two_pixels_per_clock(asd, false);
-#else
- atomisp_css_input_set_two_pixels_per_clock(asd, true);
-#endif
+ if (IS_ISP2401)
+ atomisp_css_input_set_two_pixels_per_clock(asd, false);
+ else
+ atomisp_css_input_set_two_pixels_per_clock(asd, true);
+
if (asd->continuous_mode->val) {
/* Note for all checks: ffmt includes pad_w+pad_h */
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO ||
@@ -5194,10 +5185,17 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
int (*configure_pp_input)(struct atomisp_sub_device *asd,
unsigned int width, unsigned int height) =
configure_pp_input_nop;
- u16 stream_index = atomisp_source_pad_to_stream_id(asd, source_pad);
+ u16 stream_index;
const struct atomisp_in_fmt_conv *fc;
int ret, i;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+ stream_index = atomisp_source_pad_to_stream_id(asd, source_pad);
+
v4l2_fh_init(&fh.vfh, vdev);
isp_sink_crop = atomisp_subdev_get_rect(
@@ -5417,9 +5415,9 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev,
else
ret = get_frame_info(asd, output_info);
if (ret) {
- dev_err(isp->dev, "get_frame_info %ux%u (padded to %u)\n",
- pix->width, pix->height, pix->bytesperline);
- return -EINVAL;
+ dev_err(isp->dev, "__get_frame_info %ux%u (padded to %u) returned %d\n",
+ pix->width, pix->height, pix->bytesperline, ret);
+ return ret;
}
atomisp_update_grid_info(asd, pipe_id, source_pad);
@@ -5465,9 +5463,14 @@ static void atomisp_get_dis_envelop(struct atomisp_sub_device *asd,
static void atomisp_check_copy_mode(struct atomisp_sub_device *asd,
int source_pad, struct v4l2_pix_format *f)
{
-#if defined(ISP2401_NEW_INPUT_SYSTEM)
struct v4l2_mbus_framefmt *sink, *src;
+ if (!IS_ISP2401) {
+ /* Only used for the new input system */
+ asd->copy_mode = false;
+ return;
+ }
+
sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SINK);
src = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
@@ -5481,8 +5484,6 @@ static void atomisp_check_copy_mode(struct atomisp_sub_device *asd,
sensor[asd->sensor_curr].stream_num > 1)))
asd->copy_mode = true;
else
-#endif
- /* Only used for the new input system */
asd->copy_mode = false;
dev_dbg(asd->isp->dev, "copy_mode: %d\n", asd->copy_mode);
@@ -5493,7 +5494,8 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev,
unsigned int padding_w, unsigned int padding_h,
unsigned int dvs_env_w, unsigned int dvs_env_h)
{
- struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
+ struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
+ struct atomisp_sub_device *asd = pipe->asd;
const struct atomisp_format_bridge *format;
struct v4l2_subdev_pad_config pad_cfg;
struct v4l2_subdev_state pad_state = {
@@ -5504,7 +5506,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev,
};
struct v4l2_mbus_framefmt *ffmt = &vformat.format;
struct v4l2_mbus_framefmt *req_ffmt;
- struct atomisp_device *isp = asd->isp;
+ struct atomisp_device *isp;
struct atomisp_input_stream_info *stream_info =
(struct atomisp_input_stream_info *)ffmt->reserved;
u16 stream_index = ATOMISP_INPUT_STREAM_GENERAL;
@@ -5512,6 +5514,14 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev,
struct v4l2_subdev_fh fh;
int ret;
+ if (!asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
+ isp = asd->isp;
+
v4l2_fh_init(&fh.vfh, vdev);
stream_index = atomisp_source_pad_to_stream_id(asd, source_pad);
@@ -5540,6 +5550,10 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev,
pad, set_fmt, &pad_state, &vformat);
if (ret)
return ret;
+
+ dev_dbg(isp->dev, "video dis: sensor width: %d, height: %d\n",
+ ffmt->width, ffmt->height);
+
if (ffmt->width < req_ffmt->width ||
ffmt->height < req_ffmt->height) {
req_ffmt->height -= dvs_env_h;
@@ -5550,8 +5564,6 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev,
asd->params.video_dis_en = false;
}
}
- dev_dbg(isp->dev, "sensor width: %d, height: %d\n",
- ffmt->width, ffmt->height);
vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
set_fmt, NULL, &vformat);
@@ -5590,18 +5602,28 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
const struct atomisp_format_bridge *format_bridge;
const struct atomisp_format_bridge *snr_format_bridge;
struct ia_css_frame_info output_info, raw_output_info;
- struct v4l2_pix_format snr_fmt = f->fmt.pix;
- struct v4l2_pix_format backup_fmt = snr_fmt, s_fmt;
+ struct v4l2_pix_format snr_fmt;
+ struct v4l2_pix_format backup_fmt, s_fmt;
unsigned int dvs_env_w = 0, dvs_env_h = 0;
unsigned int padding_w = pad_w, padding_h = pad_h;
bool res_overflow = false, crop_needs_override = false;
struct v4l2_mbus_framefmt *isp_sink_fmt;
struct v4l2_mbus_framefmt isp_source_fmt = {0};
+ struct v4l2_subdev_format vformat = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ struct v4l2_mbus_framefmt *ffmt = &vformat.format;
struct v4l2_rect isp_sink_crop;
u16 source_pad = atomisp_subdev_source_pad(vdev);
struct v4l2_subdev_fh fh;
int ret;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (source_pad >= ATOMISP_SUBDEV_PADS_NUM)
return -EINVAL;
@@ -5621,9 +5643,38 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
if (!format_bridge)
return -EINVAL;
+ /* Currently, raw formats are broken!!! */
+
+ if (format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+
+ format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+ if (!format_bridge)
+ return -EINVAL;
+ }
pipe->sh_fmt = format_bridge->sh_fmt;
pipe->pix.pixelformat = f->fmt.pix.pixelformat;
+ /* Ensure that the resolution is equal or below the maximum supported */
+
+ vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ v4l2_fill_mbus_format(ffmt, &f->fmt.pix, format_bridge->mbus_code);
+ ffmt->height += padding_h;
+ ffmt->width += padding_w;
+
+ ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
+ set_fmt, NULL, &vformat);
+ if (ret)
+ return ret;
+
+ f->fmt.pix.width = ffmt->width - padding_w;
+ f->fmt.pix.height = ffmt->height - padding_h;
+
+ snr_fmt = f->fmt.pix;
+ backup_fmt = snr_fmt;
+
+ /**********************************************************************/
+
if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VF ||
(source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW
&& asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)) {
@@ -5945,7 +5996,7 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
* which appears to be related by a hardware
* performance limitation. It's unclear why this
* particular code triggers the issue. */
- if (!IS_ISP2401 || crop_needs_override) {
+ if (crop_needs_override) {
if (isp_sink_crop.width * main_compose.height >
isp_sink_crop.height * main_compose.width) {
sink_crop.height = isp_sink_crop.height;
@@ -5987,6 +6038,14 @@ done:
pipe->pix.width = f->fmt.pix.width;
pipe->pix.height = f->fmt.pix.height;
pipe->pix.pixelformat = f->fmt.pix.pixelformat;
+ /*
+ * FIXME: do we need to setup this differently, depending on the
+ * sensor or the pipeline?
+ */
+ pipe->pix.colorspace = V4L2_COLORSPACE_REC709;
+ pipe->pix.ycbcr_enc = V4L2_YCBCR_ENC_709;
+ pipe->pix.xfer_func = V4L2_XFER_FUNC_709;
+
if (format_bridge->planar) {
pipe->pix.bytesperline = output_info.padded_width;
pipe->pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
@@ -6021,6 +6080,15 @@ done:
else
isp->need_gfx_throttle = true;
+ /* Report the needed sizes */
+ f->fmt.pix.sizeimage = pipe->pix.sizeimage;
+ f->fmt.pix.bytesperline = pipe->pix.bytesperline;
+
+ dev_dbg(isp->dev, "%s: %dx%d, image size: %d, %d bytes per line\n",
+ __func__,
+ f->fmt.pix.width, f->fmt.pix.height,
+ f->fmt.pix.sizeimage, f->fmt.pix.bytesperline);
+
return 0;
}
@@ -6034,6 +6102,12 @@ int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f)
struct v4l2_subdev_fh fh;
int ret;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
v4l2_fh_init(&fh.vfh, vdev);
dev_dbg(isp->dev, "setting fmt %ux%u 0x%x for file inject\n",
@@ -6092,15 +6166,9 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
}
/* Shading table size per color */
- if (!IS_ISP2401) {
- if (user_shading_table->width > ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
- user_shading_table->height > ISP2400_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR)
- return -EINVAL;
- } else {
- if (user_shading_table->width > ISP2401_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
- user_shading_table->height > ISP2401_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR)
- return -EINVAL;
- }
+ if (user_shading_table->width > SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR ||
+ user_shading_table->height > SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR)
+ return -EINVAL;
shading_table = atomisp_css_shading_table_alloc(
user_shading_table->width, user_shading_table->height);
@@ -6359,6 +6427,12 @@ bool atomisp_is_vf_pipe(struct atomisp_video_pipe *pipe)
{
struct atomisp_sub_device *asd = pipe->asd;
+ if (!asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, pipe->vdev.name);
+ return false;
+ }
+
if (pipe == &asd->video_out_vf)
return true;
@@ -6572,6 +6646,12 @@ static int atomisp_get_pipe_id(struct atomisp_video_pipe *pipe)
{
struct atomisp_sub_device *asd = pipe->asd;
+ if (!asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, pipe->vdev.name);
+ return -EINVAL;
+ }
+
if (ATOMISP_USE_YUVPP(asd)) {
return IA_CSS_PIPE_ID_YUVPP;
} else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
@@ -6609,6 +6689,12 @@ int atomisp_get_invalid_frame_num(struct video_device *vdev,
struct ia_css_pipe_info p_info;
int ret;
+ if (!asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (asd->isp->inputs[asd->input_curr].camera_caps->
sensor[asd->sensor_curr].stream_num > 1) {
/* External ISP */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
index e8bdd264d31b..ebc729468f87 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
@@ -74,8 +74,6 @@ irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr);
const struct atomisp_format_bridge *get_atomisp_format_bridge_from_mbus(
u32 mbus_code);
bool atomisp_is_mbuscode_raw(uint32_t code);
-int atomisp_get_frame_pgnr(struct atomisp_device *isp,
- const struct ia_css_frame *frame, u32 *p_pgnr);
void atomisp_delayed_init_work(struct work_struct *work);
/* Get internal fmt according to V4L2 fmt */
@@ -266,8 +264,6 @@ int atomisp_compare_grid(struct atomisp_sub_device *asd,
int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
struct atomisp_sensor_mode_data *config);
-int atomisp_get_fmt(struct video_device *vdev, struct v4l2_format *f);
-
/* This function looks up the closest available resolution. */
int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f,
bool *res_overflow);
@@ -341,6 +337,8 @@ enum atomisp_metadata_type
atomisp_get_metadata_type(struct atomisp_sub_device *asd,
enum ia_css_pipe_id pipe_id);
+u32 atomisp_get_pixel_depth(u32 pixelformat);
+
/* Function for HAL to inject a fake event to wake up poll thread */
int atomisp_inject_a_fake_event(struct atomisp_sub_device *asd, int *event);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat.h b/drivers/staging/media/atomisp/pci/atomisp_compat.h
index c16eaf3d126f..64c1bf0943e6 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat.h
@@ -133,8 +133,6 @@ void atomisp_css_get_dis_statistics(struct atomisp_sub_device *asd,
struct atomisp_css_buffer *isp_css_buffer,
struct ia_css_isp_dvs_statistics_map *dvs_map);
-int atomisp_css_dequeue_event(struct atomisp_css_event *current_event);
-
void atomisp_css_temp_pipe_to_pipe_id(struct atomisp_sub_device *asd,
struct atomisp_css_event *current_event);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
index 99a632f33d2d..1173be0e72b0 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
@@ -611,15 +611,6 @@ static void __apply_additional_pipe_config(
if (stream_env->pipe_configs[pipe_id].
default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW)
stream_env->pipe_configs[pipe_id].enable_dz = false;
-
- if (IS_ISP2401) {
- /* the isp default to use ISP2.2 and the camera hal will
- * control whether use isp2.7 */
- if (asd->select_isp_version->val == ATOMISP_CSS_ISP_PIPE_VERSION_2_7)
- stream_env->pipe_configs[pipe_id].isp_pipe_version = SH_CSS_ISP_PIPE_VERSION_2_7;
- else
- stream_env->pipe_configs[pipe_id].isp_pipe_version = SH_CSS_ISP_PIPE_VERSION_2_2;
- }
break;
case IA_CSS_PIPE_ID_VIDEO:
/* enable reduced pipe to have binary
@@ -972,7 +963,7 @@ int atomisp_css_irq_translate(struct atomisp_device *isp,
void atomisp_css_rx_get_irq_info(enum mipi_port_id port,
unsigned int *infos)
{
-#ifndef ISP2401_NEW_INPUT_SYSTEM
+#ifndef IS_ISP2401
ia_css_isys_rx_get_irq_info(port, infos);
#else
*infos = 0;
@@ -982,7 +973,7 @@ void atomisp_css_rx_get_irq_info(enum mipi_port_id port,
void atomisp_css_rx_clear_irq_info(enum mipi_port_id port,
unsigned int infos)
{
-#ifndef ISP2401_NEW_INPUT_SYSTEM
+#ifndef IS_ISP2401
ia_css_isys_rx_clear_irq_info(port, infos);
#endif
}
@@ -1633,14 +1624,6 @@ void atomisp_css_get_dis_statistics(struct atomisp_sub_device *asd,
}
}
-int atomisp_css_dequeue_event(struct atomisp_css_event *current_event)
-{
- if (ia_css_dequeue_event(&current_event->event))
- return -EINVAL;
-
- return 0;
-}
-
void atomisp_css_temp_pipe_to_pipe_id(struct atomisp_sub_device *asd,
struct atomisp_css_event *current_event)
{
@@ -2657,41 +2640,50 @@ static int __get_frame_info(struct atomisp_sub_device *asd,
if (__destroy_pipes(asd, true))
dev_warn(isp->dev, "destroy pipe failed.\n");
- if (__create_pipes(asd))
+ if (__create_pipes(asd)) {
+ dev_err(isp->dev, "can't create pipes\n");
return -EINVAL;
+ }
- if (__create_streams(asd))
+ if (__create_streams(asd)) {
+ dev_err(isp->dev, "can't create streams\n");
goto stream_err;
+ }
- ret = ia_css_pipe_get_info(
- asd->stream_env[stream_index]
- .pipes[pipe_id], &p_info);
- if (!ret) {
- switch (type) {
- case ATOMISP_CSS_VF_FRAME:
- *info = p_info.vf_output_info[0];
- dev_dbg(isp->dev, "getting vf frame info.\n");
- break;
- case ATOMISP_CSS_SECOND_VF_FRAME:
- *info = p_info.vf_output_info[1];
- dev_dbg(isp->dev, "getting second vf frame info.\n");
- break;
- case ATOMISP_CSS_OUTPUT_FRAME:
- *info = p_info.output_info[0];
- dev_dbg(isp->dev, "getting main frame info.\n");
- break;
- case ATOMISP_CSS_SECOND_OUTPUT_FRAME:
- *info = p_info.output_info[1];
- dev_dbg(isp->dev, "getting second main frame info.\n");
- break;
- case ATOMISP_CSS_RAW_FRAME:
- *info = p_info.raw_output_info;
- dev_dbg(isp->dev, "getting raw frame info.\n");
- }
- dev_dbg(isp->dev, "get frame info: w=%d, h=%d, num_invalid_frames %d.\n",
- info->res.width, info->res.height, p_info.num_invalid_frames);
- return 0;
+ ret = ia_css_pipe_get_info(asd->stream_env[stream_index].pipes[pipe_id],
+ &p_info);
+ if (ret) {
+ dev_err(isp->dev, "can't get info from pipe\n");
+ goto stream_err;
+ }
+
+ switch (type) {
+ case ATOMISP_CSS_VF_FRAME:
+ *info = p_info.vf_output_info[0];
+ dev_dbg(isp->dev, "getting vf frame info.\n");
+ break;
+ case ATOMISP_CSS_SECOND_VF_FRAME:
+ *info = p_info.vf_output_info[1];
+ dev_dbg(isp->dev, "getting second vf frame info.\n");
+ break;
+ case ATOMISP_CSS_OUTPUT_FRAME:
+ *info = p_info.output_info[0];
+ dev_dbg(isp->dev, "getting main frame info.\n");
+ break;
+ case ATOMISP_CSS_SECOND_OUTPUT_FRAME:
+ *info = p_info.output_info[1];
+ dev_dbg(isp->dev, "getting second main frame info.\n");
+ break;
+ default:
+ case ATOMISP_CSS_RAW_FRAME:
+ *info = p_info.raw_output_info;
+ dev_dbg(isp->dev, "getting raw frame info.\n");
+ break;
}
+ dev_dbg(isp->dev, "get frame info: w=%d, h=%d, num_invalid_frames %d.\n",
+ info->res.width, info->res.height, p_info.num_invalid_frames);
+
+ return 0;
stream_err:
__destroy_pipes(asd, true);
@@ -4111,7 +4103,7 @@ int atomisp_css_isr_thread(struct atomisp_device *isp,
bool reset_wdt_timer[MAX_STREAM_NUM] = {false};
int i;
- while (!atomisp_css_dequeue_event(&current_event)) {
+ while (!ia_css_dequeue_psys_event(&current_event.event)) {
if (current_event.event.type ==
IA_CSS_EVENT_TYPE_FW_ASSERT) {
/*
diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index f82bf082aa79..be6a74d5ac19 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -464,13 +464,11 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
}
-#ifdef ISP2401_NEW_INPUT_SYSTEM
- if (asd->copy_mode) {
+ if (IS_ISP2401 && asd->copy_mode) {
css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
css_preview_pipe_id = IA_CSS_PIPE_ID_COPY;
css_video_pipe_id = IA_CSS_PIPE_ID_COPY;
}
-#endif
if (asd->yuvpp_mode) {
capture_pipe = &asd->video_out_capture;
@@ -772,6 +770,30 @@ static int atomisp_open(struct file *file)
dev_dbg(isp->dev, "open device %s\n", vdev->name);
+ /*
+ * Ensure that if we are still loading we block. Once the loading
+ * is over we can proceed. We can't blindly hold the lock until
+ * that occurs as if the load fails we'll deadlock the unload
+ */
+ rt_mutex_lock(&isp->loading);
+ /*
+ * FIXME: revisit this with a better check once the code structure
+ * is cleaned up a bit more
+ */
+ ret = v4l2_fh_open(file);
+ if (ret) {
+ dev_err(isp->dev,
+ "%s: v4l2_fh_open() returned error %d\n",
+ __func__, ret);
+ rt_mutex_unlock(&isp->loading);
+ return ret;
+ }
+ if (!isp->ready) {
+ rt_mutex_unlock(&isp->loading);
+ return -ENXIO;
+ }
+ rt_mutex_unlock(&isp->loading);
+
rt_mutex_lock(&isp->mutex);
acc_node = !strcmp(vdev->name, "ATOMISP ISP ACC");
@@ -877,6 +899,11 @@ done:
else
pipe->users++;
rt_mutex_unlock(&isp->mutex);
+
+ /* Ensure that a mode is set */
+ if (!acc_node)
+ v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode);
+
return 0;
css_error:
@@ -1025,7 +1052,7 @@ done:
rt_mutex_unlock(&isp->mutex);
mutex_unlock(&isp->streamoff_mutex);
- return 0;
+ return v4l2_fh_release(file);
}
/*
@@ -1067,7 +1094,7 @@ static int frame_mmap(struct atomisp_device *isp,
host_virt = vma->vm_start;
isp_virt = frame->data;
- atomisp_get_frame_pgnr(isp, frame, &pgnr);
+ pgnr = DIV_ROUND_UP(frame->data_bytes, PAGE_SIZE);
if (do_isp_mm_remap(isp, vma, isp_virt, host_virt, pgnr))
return -EAGAIN;
@@ -1171,6 +1198,12 @@ static int atomisp_mmap(struct file *file, struct vm_area_struct *vma)
u32 origin_size, new_size;
int ret;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (!(vma->vm_flags & (VM_WRITE | VM_READ)))
return -EACCES;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
index d8c9e31314b2..1cc581074ba7 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
@@ -321,6 +321,18 @@ static struct gmin_cfg_var i8880_vars[] = {
{},
};
+/*
+ * Surface 3 does not describe CsiPort/CsiLanes in both DSDT and EFI.
+ */
+static struct gmin_cfg_var surface3_vars[] = {
+ {"APTA0330:00_CsiPort", "0"},
+ {"APTA0330:00_CsiLanes", "2"},
+
+ {"OVTI8835:00_CsiPort", "1"},
+ {"OVTI8835:00_CsiLanes", "4"},
+ {},
+};
+
static const struct dmi_system_id gmin_vars[] = {
{
.ident = "BYT-T FFD8",
@@ -358,6 +370,13 @@ static const struct dmi_system_id gmin_vars[] = {
},
.driver_data = i8880_vars,
},
+ {
+ .ident = "Surface 3",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "Surface 3"),
+ },
+ .driver_data = surface3_vars,
+ },
{}
};
@@ -481,7 +500,7 @@ fail:
static u8 gmin_get_pmic_id_and_addr(struct device *dev)
{
- struct i2c_client *power;
+ struct i2c_client *power = NULL;
static u8 pmic_i2c_addr;
if (pmic_id)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h
index c01db10bb735..f71ab1ee6e19 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h
@@ -247,6 +247,13 @@ struct atomisp_device {
* structures and css API calls. */
struct rt_mutex mutex;
/*
+ * This mutex ensures that we don't allow an open to succeed while
+ * the initialization process is incomplete
+ */
+ struct rt_mutex loading;
+ /* Set once the ISP is ready to allow opens */
+ bool ready;
+ /*
* Serialise streamoff: mutex is dropped during streamoff to
* cancel the watchdog queue. MUST be acquired BEFORE
* "mutex".
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index c8a625667e81..8fd470efd658 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -492,23 +492,22 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = {
.mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE,
.sh_fmt = IA_CSS_FRAME_FORMAT_RGB565,
.description = "16 RGB 5-6-5"
+#if 0
}, {
.pixelformat = V4L2_PIX_FMT_JPEG,
.depth = 8,
.mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
.sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
.description = "JPEG"
- },
-#if 0
- {
+ }, {
/* This is a custom format being used by M10MO to send the RAW data */
.pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
.depth = 8,
.mbus_code = V4L2_MBUS_FMT_CUSTOM_M10MO_RAW,
.sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
.description = "Custom RAW for M10MO"
- },
#endif
+ },
};
const struct atomisp_format_bridge *
@@ -646,6 +645,12 @@ static int atomisp_g_input(struct file *file, void *fh, unsigned int *input)
struct atomisp_device *isp = video_get_drvdata(vdev);
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
rt_mutex_lock(&isp->mutex);
*input = asd->input_curr;
rt_mutex_unlock(&isp->mutex);
@@ -665,6 +670,12 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
struct v4l2_subdev *motor;
int ret;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
rt_mutex_lock(&isp->mutex);
if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) {
dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt);
@@ -755,24 +766,91 @@ error:
return ret;
}
+static int atomisp_enum_framesizes(struct file *file, void *priv,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct atomisp_device *isp = video_get_drvdata(vdev);
+ struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
+ struct v4l2_subdev_frame_size_enum fse = {
+ .index = fsize->index,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ int ret;
+
+ ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
+ pad, enum_frame_size, NULL, &fse);
+ if (ret)
+ return ret;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = fse.max_width - pad_w;
+ fsize->discrete.height = fse.max_height - pad_h;
+
+ return 0;
+}
+
+static int atomisp_enum_frameintervals(struct file *file, void *priv,
+ struct v4l2_frmivalenum *fival)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct atomisp_device *isp = video_get_drvdata(vdev);
+ struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
+ struct v4l2_subdev_frame_interval_enum fie = {
+ .code = atomisp_in_fmt_conv[0].code,
+ .index = fival->index,
+ .width = fival->width,
+ .height = fival->height,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ int ret;
+
+ ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
+ pad, enum_frame_interval, NULL,
+ &fie);
+ if (ret)
+ return ret;
+
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete = fie.interval;
+
+ return ret;
+}
+
static int atomisp_enum_fmt_cap(struct file *file, void *fh,
struct v4l2_fmtdesc *f)
{
struct video_device *vdev = video_devdata(file);
struct atomisp_device *isp = video_get_drvdata(vdev);
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
- struct v4l2_subdev_mbus_code_enum code = { 0 };
+ struct v4l2_subdev_mbus_code_enum code = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ const struct atomisp_format_bridge *format;
+ struct v4l2_subdev *camera;
unsigned int i, fi = 0;
int rval;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
+ camera = isp->inputs[asd->input_curr].camera;
+ if(!camera) {
+ dev_err(isp->dev, "%s(): camera is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
rt_mutex_lock(&isp->mutex);
- rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
- enum_mbus_code, NULL, &code);
+
+ rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code);
if (rval == -ENOIOCTLCMD) {
dev_warn(isp->dev,
- "enum_mbus_code pad op not supported. Please fix your sensor driver!\n");
- // rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
- // video, enum_mbus_fmt, 0, &code.code);
+ "enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n",
+ camera->name);
}
rt_mutex_unlock(&isp->mutex);
@@ -780,15 +858,15 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
return rval;
for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
- const struct atomisp_format_bridge *format =
- &atomisp_output_fmts[i];
+ format = &atomisp_output_fmts[i];
/*
* Is the atomisp-supported format is valid for the
* sensor (configuration)? If not, skip it.
+ *
+ * FIXME: fix the pipeline to allow sensor format too.
*/
- if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW
- && format->mbus_code != code.code)
+ if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW)
continue;
/* Found a match. Now let's pick f->index'th one. */
@@ -806,20 +884,6 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
return -EINVAL;
}
-static int atomisp_g_fmt_cap(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct video_device *vdev = video_devdata(file);
- struct atomisp_device *isp = video_get_drvdata(vdev);
-
- int ret;
-
- rt_mutex_lock(&isp->mutex);
- ret = atomisp_get_fmt(vdev, f);
- rt_mutex_unlock(&isp->mutex);
- return ret;
-}
-
static int atomisp_g_fmt_file(struct file *file, void *fh,
struct v4l2_format *f)
{
@@ -834,6 +898,72 @@ static int atomisp_g_fmt_file(struct file *file, void *fh,
return 0;
}
+static int atomisp_adjust_fmt(struct v4l2_format *f)
+{
+ const struct atomisp_format_bridge *format_bridge;
+ u32 padded_width;
+
+ format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+
+ padded_width = f->fmt.pix.width + pad_w;
+
+ if (format_bridge->planar) {
+ f->fmt.pix.bytesperline = padded_width;
+ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
+ DIV_ROUND_UP(format_bridge->depth *
+ padded_width, 8));
+ } else {
+ f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth *
+ padded_width, 8);
+ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
+ }
+
+ if (f->fmt.pix.field == V4L2_FIELD_ANY)
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+
+ format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+ if (!format_bridge)
+ return -EINVAL;
+
+ /* Currently, raw formats are broken!!! */
+ if (format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+
+ format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+ if (!format_bridge)
+ return -EINVAL;
+ }
+
+ padded_width = f->fmt.pix.width + pad_w;
+
+ if (format_bridge->planar) {
+ f->fmt.pix.bytesperline = padded_width;
+ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
+ DIV_ROUND_UP(format_bridge->depth *
+ padded_width, 8));
+ } else {
+ f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth *
+ padded_width, 8);
+ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
+ }
+
+ if (f->fmt.pix.field == V4L2_FIELD_ANY)
+ f->fmt.pix.field = V4L2_FIELD_NONE;
+
+ /*
+ * FIXME: do we need to setup this differently, depending on the
+ * sensor or the pipeline?
+ */
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+ f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_709;
+ f->fmt.pix.xfer_func = V4L2_XFER_FUNC_709;
+
+ f->fmt.pix.width -= pad_w;
+ f->fmt.pix.height -= pad_h;
+
+ return 0;
+}
+
/* This function looks up the closest available resolution. */
static int atomisp_try_fmt_cap(struct file *file, void *fh,
struct v4l2_format *f)
@@ -845,7 +975,35 @@ static int atomisp_try_fmt_cap(struct file *file, void *fh,
rt_mutex_lock(&isp->mutex);
ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL);
rt_mutex_unlock(&isp->mutex);
- return ret;
+
+ if (ret)
+ return ret;
+
+ return atomisp_adjust_fmt(f);
+}
+
+static int atomisp_g_fmt_cap(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct atomisp_device *isp = video_get_drvdata(vdev);
+ struct atomisp_video_pipe *pipe;
+
+ rt_mutex_lock(&isp->mutex);
+ pipe = atomisp_to_video_pipe(vdev);
+ rt_mutex_unlock(&isp->mutex);
+
+ f->fmt.pix = pipe->pix;
+
+ /* If s_fmt was issued, just return whatever is was previouly set */
+ if (f->fmt.pix.sizeimage)
+ return 0;
+
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ f->fmt.pix.width = 10000;
+ f->fmt.pix.height = 10000;
+
+ return atomisp_try_fmt_cap(file, fh, f);
}
static int atomisp_s_fmt_cap(struct file *file, void *fh,
@@ -1024,9 +1182,16 @@ int __atomisp_reqbufs(struct file *file, void *fh,
struct ia_css_frame *frame;
struct videobuf_vmalloc_memory *vm_mem;
u16 source_pad = atomisp_subdev_source_pad(vdev);
- u16 stream_id = atomisp_source_pad_to_stream_id(asd, source_pad);
+ u16 stream_id;
int ret = 0, i = 0;
+ if (!asd) {
+ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+ stream_id = atomisp_source_pad_to_stream_id(asd, source_pad);
+
if (req->count == 0) {
mutex_lock(&pipe->capq.vb_lock);
if (!list_empty(&pipe->capq.stream))
@@ -1154,6 +1319,12 @@ static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
u32 pgnr;
int ret = 0;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
rt_mutex_lock(&isp->mutex);
if (isp->isp_fatal_error) {
ret = -EIO;
@@ -1287,25 +1458,8 @@ done:
pipe->capq.streaming &&
!asd->enable_raw_buffer_lock->val &&
asd->params.offline_parm.num_captures == 1) {
- if (!IS_ISP2401) {
asd->pending_capture_request++;
dev_dbg(isp->dev, "Add one pending capture request.\n");
- } else {
- if (asd->re_trigger_capture) {
- ret = atomisp_css_offline_capture_configure(asd,
- asd->params.offline_parm.num_captures,
- asd->params.offline_parm.skip_frames,
- asd->params.offline_parm.offset);
- asd->re_trigger_capture = false;
- dev_dbg(isp->dev, "%s Trigger capture again ret=%d\n",
- __func__, ret);
-
- } else {
- asd->pending_capture_request++;
- asd->re_trigger_capture = false;
- dev_dbg(isp->dev, "Add one pending capture request.\n");
- }
- }
}
rt_mutex_unlock(&isp->mutex);
@@ -1389,6 +1543,12 @@ static int atomisp_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
struct atomisp_device *isp = video_get_drvdata(vdev);
int ret = 0;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
rt_mutex_lock(&isp->mutex);
if (isp->isp_fatal_error) {
@@ -1640,6 +1800,12 @@ static int atomisp_streamon(struct file *file, void *fh,
int ret = 0;
unsigned long irqflags;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
dev_dbg(isp->dev, "Start stream on pad %d for asd%d\n",
atomisp_subdev_source_pad(vdev), asd->index);
@@ -1686,8 +1852,6 @@ static int atomisp_streamon(struct file *file, void *fh,
/* Reset pending capture request count. */
asd->pending_capture_request = 0;
- if (IS_ISP2401)
- asd->re_trigger_capture = false;
if ((atomisp_subdev_streaming_count(asd) > sensor_start_stream) &&
(!isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl)) {
@@ -1901,6 +2065,12 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
unsigned long flags;
bool first_streamoff = false;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
dev_dbg(isp->dev, "Stop stream on pad %d for asd%d\n",
atomisp_subdev_source_pad(vdev), asd->index);
@@ -2150,6 +2320,12 @@ static int atomisp_g_ctrl(struct file *file, void *fh,
struct atomisp_device *isp = video_get_drvdata(vdev);
int i, ret = -EINVAL;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
for (i = 0; i < ctrls_num; i++) {
if (ci_v4l2_controls[i].id == control->id) {
ret = 0;
@@ -2229,6 +2405,12 @@ static int atomisp_s_ctrl(struct file *file, void *fh,
struct atomisp_device *isp = video_get_drvdata(vdev);
int i, ret = -EINVAL;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
for (i = 0; i < ctrls_num; i++) {
if (ci_v4l2_controls[i].id == control->id) {
ret = 0;
@@ -2310,6 +2492,12 @@ static int atomisp_queryctl(struct file *file, void *fh,
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
struct atomisp_device *isp = video_get_drvdata(vdev);
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
switch (qc->id) {
case V4L2_CID_FOCUS_ABSOLUTE:
case V4L2_CID_FOCUS_RELATIVE:
@@ -2355,6 +2543,12 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
int i;
int ret = 0;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (!IS_ISP2401)
motor = isp->inputs[asd->input_curr].motor;
else
@@ -2466,6 +2660,12 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
int i;
int ret = 0;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (!IS_ISP2401)
motor = isp->inputs[asd->input_curr].motor;
else
@@ -2591,6 +2791,12 @@ static int atomisp_g_parm(struct file *file, void *fh,
struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
struct atomisp_device *isp = video_get_drvdata(vdev);
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
dev_err(isp->dev, "unsupported v4l2 buf type\n");
return -EINVAL;
@@ -2613,6 +2819,12 @@ static int atomisp_s_parm(struct file *file, void *fh,
int rval;
int fps;
+ if (!asd) {
+ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
+ __func__, vdev->name);
+ return -EINVAL;
+ }
+
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
dev_err(isp->dev, "unsupported v4l2 buf type\n");
return -EINVAL;
@@ -3035,6 +3247,8 @@ const struct v4l2_ioctl_ops atomisp_ioctl_ops = {
.vidioc_g_ctrl = atomisp_g_ctrl,
.vidioc_s_ext_ctrls = atomisp_s_ext_ctrls,
.vidioc_g_ext_ctrls = atomisp_g_ext_ctrls,
+ .vidioc_enum_framesizes = atomisp_enum_framesizes,
+ .vidioc_enum_frameintervals = atomisp_enum_frameintervals,
.vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap,
.vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap,
.vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap,
diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
index 12f22ad007c7..1807cfa786a7 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
@@ -1058,24 +1058,6 @@ static const struct v4l2_ctrl_config ctrl_depth_mode = {
.def = 0,
};
-/*
- * Control for selectting ISP version
- *
- * When enabled, that means ISP version will be used ISP2.7. when disable, the
- * isp will default to use ISP2.2.
- * Note: Make sure set this configuration before creating stream.
- */
-static const struct v4l2_ctrl_config ctrl_select_isp_version = {
- .ops = &ctrl_ops,
- .id = V4L2_CID_ATOMISP_SELECT_ISP_VERSION,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Select Isp version",
- .min = 0,
- .max = 1,
- .step = 1,
- .def = 0,
-};
-
static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type)
{
@@ -1164,23 +1146,28 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
atomisp_init_acc_pipe(asd, &asd->video_acc);
- ret = atomisp_video_init(&asd->video_in, "MEMORY");
+ ret = atomisp_video_init(&asd->video_in, "MEMORY",
+ ATOMISP_RUN_MODE_SDV);
if (ret < 0)
return ret;
- ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE");
+ ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE",
+ ATOMISP_RUN_MODE_STILL_CAPTURE);
if (ret < 0)
return ret;
- ret = atomisp_video_init(&asd->video_out_vf, "VIEWFINDER");
+ ret = atomisp_video_init(&asd->video_out_vf, "VIEWFINDER",
+ ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE);
if (ret < 0)
return ret;
- ret = atomisp_video_init(&asd->video_out_preview, "PREVIEW");
+ ret = atomisp_video_init(&asd->video_out_preview, "PREVIEW",
+ ATOMISP_RUN_MODE_PREVIEW);
if (ret < 0)
return ret;
- ret = atomisp_video_init(&asd->video_out_video_capture, "VIDEO");
+ ret = atomisp_video_init(&asd->video_out_video_capture, "VIDEO",
+ ATOMISP_RUN_MODE_VIDEO);
if (ret < 0)
return ret;
@@ -1218,11 +1205,6 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
v4l2_ctrl_new_custom(&asd->ctrl_handler,
&ctrl_disable_dz,
NULL);
- if (IS_ISP2401) {
- asd->select_isp_version = v4l2_ctrl_new_custom(&asd->ctrl_handler,
- &ctrl_select_isp_version,
- NULL);
- }
/* Make controls visible on subdev as well. */
asd->subdev.ctrl_handler = &asd->ctrl_handler;
@@ -1351,6 +1333,14 @@ int atomisp_subdev_register_entities(struct atomisp_sub_device *asd,
if (ret < 0)
goto error;
+ asd->video_out_preview.vdev.v4l2_dev = vdev;
+ asd->video_out_preview.vdev.device_caps = device_caps |
+ V4L2_CAP_VIDEO_OUTPUT;
+ ret = video_register_device(&asd->video_out_preview.vdev,
+ VFL_TYPE_VIDEO, -1);
+ if (ret < 0)
+ goto error;
+
asd->video_out_capture.vdev.v4l2_dev = vdev;
asd->video_out_capture.vdev.device_caps = device_caps |
V4L2_CAP_VIDEO_OUTPUT;
@@ -1366,13 +1356,7 @@ int atomisp_subdev_register_entities(struct atomisp_sub_device *asd,
VFL_TYPE_VIDEO, -1);
if (ret < 0)
goto error;
- asd->video_out_preview.vdev.v4l2_dev = vdev;
- asd->video_out_preview.vdev.device_caps = device_caps |
- V4L2_CAP_VIDEO_OUTPUT;
- ret = video_register_device(&asd->video_out_preview.vdev,
- VFL_TYPE_VIDEO, -1);
- if (ret < 0)
- goto error;
+
asd->video_out_video_capture.vdev.v4l2_dev = vdev;
asd->video_out_video_capture.vdev.device_caps = device_caps |
V4L2_CAP_VIDEO_OUTPUT;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
index d6fcfab6352d..7d731f1fee72 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
@@ -81,6 +81,9 @@ struct atomisp_video_pipe {
/* the link list to store per_frame parameters */
struct list_head per_frame_params;
+ /* Store here the initial run mode */
+ unsigned int default_run_mode;
+
unsigned int buffers_in_css;
/* irq_lock is used to protect video buffer state change operations and
@@ -316,7 +319,6 @@ struct atomisp_sub_device {
/* ISP2401 */
struct v4l2_ctrl *ion_dev_fd;
- struct v4l2_ctrl *select_isp_version;
struct v4l2_ctrl *disable_dz;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index 1e324f1f656e..1b240891a6e2 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -447,7 +447,8 @@ const struct atomisp_dfs_config dfs_config_cht_soc = {
.dfs_table_size = ARRAY_SIZE(dfs_rules_cht_soc),
};
-int atomisp_video_init(struct atomisp_video_pipe *video, const char *name)
+int atomisp_video_init(struct atomisp_video_pipe *video, const char *name,
+ unsigned int run_mode)
{
int ret;
const char *direction;
@@ -478,6 +479,7 @@ int atomisp_video_init(struct atomisp_video_pipe *video, const char *name)
"ATOMISP ISP %s %s", name, direction);
video->vdev.release = video_device_release_empty;
video_set_drvdata(&video->vdev, video->isp);
+ video->default_run_mode = run_mode;
return 0;
}
@@ -711,15 +713,15 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
dev_dbg(isp->dev, "IUNIT power-%s.\n", enable ? "on" : "off");
- /*WA:Enable DVFS*/
+ /* WA for P-Unit, if DVFS enabled, ISP timeout observed */
if (IS_CHT && enable)
- punit_ddr_dvfs_enable(true);
+ punit_ddr_dvfs_enable(false);
/*
* FIXME:WA for ECS28A, with this sleep, CTS
* android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceAbort
* PASS, no impact on other platforms
- */
+ */
if (IS_BYT && enable)
msleep(10);
@@ -727,7 +729,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0,
val, MRFLD_ISPSSPM0_ISPSSC_MASK);
- /*WA:Enable DVFS*/
+ /* WA:Enable DVFS */
if (IS_CHT && !enable)
punit_ddr_dvfs_enable(true);
@@ -1182,6 +1184,7 @@ static void atomisp_unregister_entities(struct atomisp_device *isp)
v4l2_device_unregister(&isp->v4l2_dev);
media_device_unregister(&isp->media_dev);
+ media_device_cleanup(&isp->media_dev);
}
static int atomisp_register_entities(struct atomisp_device *isp)
@@ -1566,6 +1569,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
dev_dbg(&pdev->dev, "atomisp mmio base: %p\n", isp->base);
rt_mutex_init(&isp->mutex);
+ rt_mutex_init(&isp->loading);
mutex_init(&isp->streamoff_mutex);
spin_lock_init(&isp->lock);
@@ -1633,12 +1637,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
pdev->d3cold_delay = 0;
break;
case ATOMISP_PCI_DEVICE_SOC_ANN:
- isp->media_dev.hw_revision = (
-#ifdef ISP2401_NEW_INPUT_SYSTEM
- ATOMISP_HW_REVISION_ISP2401
-#else
- ATOMISP_HW_REVISION_ISP2401_LEGACY
-#endif
+ isp->media_dev.hw_revision = ( ATOMISP_HW_REVISION_ISP2401
<< ATOMISP_HW_REVISION_SHIFT);
isp->media_dev.hw_revision |= pdev->revision < 2 ?
ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0;
@@ -1646,12 +1645,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
isp->hpll_freq = HPLL_FREQ_1600MHZ;
break;
case ATOMISP_PCI_DEVICE_SOC_CHT:
- isp->media_dev.hw_revision = (
-#ifdef ISP2401_NEW_INPUT_SYSTEM
- ATOMISP_HW_REVISION_ISP2401
-#else
- ATOMISP_HW_REVISION_ISP2401_LEGACY
-#endif
+ isp->media_dev.hw_revision = ( ATOMISP_HW_REVISION_ISP2401
<< ATOMISP_HW_REVISION_SHIFT);
isp->media_dev.hw_revision |= pdev->revision < 2 ?
ATOMISP_HW_STEPPING_A0 : ATOMISP_HW_STEPPING_B0;
@@ -1748,6 +1742,8 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, csi_afe_trim);
}
+ rt_mutex_lock(&isp->loading);
+
err = atomisp_initialize_modules(isp);
if (err < 0) {
dev_err(&pdev->dev, "atomisp_initialize_modules (%d)\n", err);
@@ -1805,6 +1801,8 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
release_firmware(isp->firmware);
isp->firmware = NULL;
isp->css_env.isp_css_fw.data = NULL;
+ isp->ready = true;
+ rt_mutex_unlock(&isp->loading);
atomisp_drvfs_init(isp);
@@ -1824,6 +1822,7 @@ wdt_work_queue_fail:
register_entities_fail:
atomisp_uninitialize_modules(isp);
initialize_modules_fail:
+ rt_mutex_unlock(&isp->loading);
cpu_latency_qos_remove_request(&isp->pm_qos);
atomisp_msi_irq_uninit(isp);
pci_free_irq_vectors(pdev);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.h b/drivers/staging/media/atomisp/pci/atomisp_v4l2.h
index 81bb356b8172..72611b8286a4 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.h
@@ -27,7 +27,8 @@ struct v4l2_device;
struct atomisp_device;
struct firmware;
-int atomisp_video_init(struct atomisp_video_pipe *video, const char *name);
+int atomisp_video_init(struct atomisp_video_pipe *video, const char *name,
+ unsigned int run_mode);
void atomisp_acc_init(struct atomisp_acc_pipe *video, const char *name);
void atomisp_video_unregister(struct atomisp_video_pipe *video);
void atomisp_acc_unregister(struct atomisp_acc_pipe *video);
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c
index f20c9b02fbe0..7dd0e4a53c8b 100644
--- a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c
+++ b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c
@@ -58,7 +58,6 @@ static void pipe_binarydesc_get_offline(
descr->enable_dz = true;
descr->enable_xnr = false;
descr->enable_dpc = false;
- descr->enable_luma_only = false;
descr->enable_tnr = false;
descr->enable_capture_pp_bli = false;
descr->enable_fractional_ds = false;
@@ -390,8 +389,6 @@ int ia_css_pipe_get_video_binarydesc(
pipe->extra_config.enable_fractional_ds;
video_descr->enable_dpc =
pipe->config.enable_dpc;
- video_descr->enable_luma_only =
- pipe->config.enable_luma_only;
video_descr->enable_tnr =
pipe->config.enable_tnr;
@@ -574,11 +571,9 @@ void ia_css_pipe_get_primary_binarydesc(
in_info->res = pipe->config.input_effective_res;
in_info->padded_width = in_info->res.width;
-#if !defined(HAS_NO_PACKED_RAW_PIXELS)
if (pipe->stream->config.pack_raw_pixels)
in_info->format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
else
-#endif
in_info->format = IA_CSS_FRAME_FORMAT_RAW;
in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe);
@@ -600,24 +595,15 @@ void ia_css_pipe_get_primary_binarydesc(
prim_descr->isp_pipe_version = pipe->config.isp_pipe_version;
prim_descr->enable_fractional_ds =
pipe->extra_config.enable_fractional_ds;
- prim_descr->enable_luma_only =
- pipe->config.enable_luma_only;
/* We have both striped and non-striped primary binaries,
* if continuous viewfinder is required, then we must select
* a striped one. Otherwise we prefer to use a non-striped
* since it has better performance. */
if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1)
prim_descr->striped = false;
- else if (!IS_ISP2401) {
+ else
prim_descr->striped = prim_descr->continuous &&
(!pipe->stream->stop_copy_preview || !pipe->stream->disable_cont_vf);
- } else {
- prim_descr->striped = prim_descr->continuous && !pipe->stream->disable_cont_vf;
-
- if ((pipe->config.default_capture_config.enable_xnr != 0) &&
- (pipe->extra_config.enable_dvs_6axis == true))
- prim_descr->enable_xnr = true;
- }
}
IA_CSS_LEAVE_PRIVATE("");
}
@@ -849,14 +835,7 @@ void ia_css_pipe_get_ldc_binarydesc(
assert(out_info);
IA_CSS_ENTER_PRIVATE("");
- if (!IS_ISP2401) {
- *in_info = *out_info;
- } else {
- if (pipe->out_yuv_ds_input_info.res.width)
- *in_info = pipe->out_yuv_ds_input_info;
- else
- *in_info = *out_info;
- }
+ *in_info = *out_info;
in_info->format = IA_CSS_FRAME_FORMAT_YUV420;
in_info->raw_bit_depth = 0;
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c
deleted file mode 100644
index 1a021ae841fe..000000000000
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_configs.c
+++ /dev/null
@@ -1,386 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* Generated code: do not edit or commmit. */
-
-#define IA_CSS_INCLUDE_CONFIGURATIONS
-#include "ia_css_pipeline.h"
-#include "ia_css_isp_configs.h"
-#include "ia_css_debug.h"
-#include "assert_support.h"
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_iterator(
- const struct ia_css_binary *binary,
- const struct ia_css_iterator_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_iterator() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.iterator.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.iterator.offset;
- }
- if (size) {
- ia_css_iterator_config((struct sh_css_isp_iterator_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_iterator() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_copy_output(
- const struct ia_css_binary *binary,
- const struct ia_css_copy_output_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_copy_output() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.copy_output.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.copy_output.offset;
- }
- if (size) {
- ia_css_copy_output_config((struct sh_css_isp_copy_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_copy_output() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_crop(
- const struct ia_css_binary *binary,
- const struct ia_css_crop_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_crop() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.crop.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.crop.offset;
- }
- if (size) {
- ia_css_crop_config((struct sh_css_isp_crop_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_crop() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_fpn(
- const struct ia_css_binary *binary,
- const struct ia_css_fpn_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_fpn() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.fpn.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.fpn.offset;
- }
- if (size) {
- ia_css_fpn_config((struct sh_css_isp_fpn_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_fpn() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_dvs(
- const struct ia_css_binary *binary,
- const struct ia_css_dvs_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_dvs() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.dvs.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.dvs.offset;
- }
- if (size) {
- ia_css_dvs_config((struct sh_css_isp_dvs_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_dvs() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_qplane(
- const struct ia_css_binary *binary,
- const struct ia_css_qplane_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_qplane() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.qplane.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.qplane.offset;
- }
- if (size) {
- ia_css_qplane_config((struct sh_css_isp_qplane_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_qplane() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_output0(
- const struct ia_css_binary *binary,
- const struct ia_css_output0_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output0() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.output0.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.output0.offset;
- }
- if (size) {
- ia_css_output0_config((struct sh_css_isp_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output0() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_output1(
- const struct ia_css_binary *binary,
- const struct ia_css_output1_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output1() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.output1.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.output1.offset;
- }
- if (size) {
- ia_css_output1_config((struct sh_css_isp_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output1() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_output(
- const struct ia_css_binary *binary,
- const struct ia_css_output_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.output.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.output.offset;
- }
- if (size) {
- ia_css_output_config((struct sh_css_isp_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_raw(
- const struct ia_css_binary *binary,
- const struct ia_css_raw_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_raw() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.raw.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.raw.offset;
- }
- if (size) {
- ia_css_raw_config((struct sh_css_isp_raw_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_raw() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_tnr(
- const struct ia_css_binary *binary,
- const struct ia_css_tnr_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_tnr() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.tnr.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.tnr.offset;
- }
- if (size) {
- ia_css_tnr_config((struct sh_css_isp_tnr_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_tnr() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_ref(
- const struct ia_css_binary *binary,
- const struct ia_css_ref_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_ref() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.ref.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.ref.offset;
- }
- if (size) {
- ia_css_ref_config((struct sh_css_isp_ref_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_ref() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_vf(
- const struct ia_css_binary *binary,
- const struct ia_css_vf_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_vf() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.vf.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.vf.offset;
- }
- if (size) {
- ia_css_vf_config((struct sh_css_isp_vf_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_vf() leave:\n");
-}
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c b/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c
deleted file mode 100644
index b786247b322b..000000000000
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_params.c
+++ /dev/null
@@ -1,3420 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-#define IA_CSS_INCLUDE_PARAMETERS
-#include "sh_css_params.h"
-#include "isp/kernels/aa/aa_2/ia_css_aa2.host.h"
-#include "isp/kernels/anr/anr_1.0/ia_css_anr.host.h"
-#include "isp/kernels/anr/anr_2/ia_css_anr2.host.h"
-#include "isp/kernels/bh/bh_2/ia_css_bh.host.h"
-#include "isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.h"
-#include "isp/kernels/bnr/bnr2_2/ia_css_bnr2_2.host.h"
-#include "isp/kernels/cnr/cnr_2/ia_css_cnr2.host.h"
-#include "isp/kernels/crop/crop_1.0/ia_css_crop.host.h"
-#include "isp/kernels/csc/csc_1.0/ia_css_csc.host.h"
-#include "isp/kernels/ctc/ctc_1.0/ia_css_ctc.host.h"
-#include "isp/kernels/ctc/ctc1_5/ia_css_ctc1_5.host.h"
-#include "isp/kernels/ctc/ctc2/ia_css_ctc2.host.h"
-#include "isp/kernels/de/de_1.0/ia_css_de.host.h"
-#include "isp/kernels/de/de_2/ia_css_de2.host.h"
-#include "isp/kernels/dp/dp_1.0/ia_css_dp.host.h"
-#include "isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h"
-#include "isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h"
-#include "isp/kernels/gc/gc_1.0/ia_css_gc.host.h"
-#include "isp/kernels/gc/gc_2/ia_css_gc2.host.h"
-#include "isp/kernels/macc/macc_1.0/ia_css_macc.host.h"
-#include "isp/kernels/macc/macc1_5/ia_css_macc1_5.host.h"
-#include "isp/kernels/ob/ob_1.0/ia_css_ob.host.h"
-#include "isp/kernels/ob/ob2/ia_css_ob2.host.h"
-#include "isp/kernels/output/output_1.0/ia_css_output.host.h"
-#include "isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.h"
-#include "isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.h"
-#include "isp/kernels/sc/sc_1.0/ia_css_sc.host.h"
-#include "isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.h"
-#include "isp/kernels/sdis/sdis_2/ia_css_sdis2.host.h"
-#include "isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h"
-#include "isp/kernels/uds/uds_1.0/ia_css_uds_param.h"
-#include "isp/kernels/wb/wb_1.0/ia_css_wb.host.h"
-#include "isp/kernels/xnr/xnr_1.0/ia_css_xnr.host.h"
-#include "isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.h"
-#include "isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.h"
-#include "isp/kernels/ynr/ynr_2/ia_css_ynr2.host.h"
-#include "isp/kernels/fc/fc_1.0/ia_css_formats.host.h"
-#include "isp/kernels/tdf/tdf_1.0/ia_css_tdf.host.h"
-#include "isp/kernels/dpc2/ia_css_dpc2.host.h"
-#include "isp/kernels/eed1_8/ia_css_eed1_8.host.h"
-#include "isp/kernels/bnlm/ia_css_bnlm.host.h"
-#include "isp/kernels/conversion/conversion_1.0/ia_css_conversion.host.h"
-/* Generated code: do not edit or commmit. */
-
-#include "ia_css_pipeline.h"
-#include "ia_css_isp_params.h"
-#include "ia_css_debug.h"
-#include "assert_support.h"
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_aa(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.aa.size;
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.aa.offset;
-
- if (size) {
- struct sh_css_isp_aa_params *t = (struct sh_css_isp_aa_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset];
- t->strength = params->aa_config.strength;
- }
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_anr(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.anr.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.anr.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_anr() enter:\n");
-
- ia_css_anr_encode((struct sh_css_isp_anr_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->anr_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_anr() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_anr2(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vmem.anr2.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vmem.anr2.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_anr2() enter:\n");
-
- ia_css_anr2_vmem_encode((struct ia_css_isp_anr2_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VMEM].address[offset],
- &params->anr_thres,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_anr2() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_bh(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.bh.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.bh.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_bh() enter:\n");
-
- ia_css_bh_encode((struct sh_css_isp_bh_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->s3a_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_bh() leave:\n");
- }
- }
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->hmem0.bh.size;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_bh() enter:\n");
-
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_HMEM0] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_bh() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_cnr(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.cnr.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.cnr.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_cnr() enter:\n");
-
- ia_css_cnr_encode((struct sh_css_isp_cnr_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->cnr_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_cnr() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_crop(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.crop.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.crop.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_crop() enter:\n");
-
- ia_css_crop_encode((struct sh_css_isp_crop_isp_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->crop_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_crop() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_csc(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.csc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.csc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_csc() enter:\n");
-
- ia_css_csc_encode((struct sh_css_isp_csc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->cc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_csc() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_dp(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.dp.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.dp.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_dp() enter:\n");
-
- ia_css_dp_encode((struct sh_css_isp_dp_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->dp_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_dp() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_bnr(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.bnr.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.bnr.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_bnr() enter:\n");
-
- ia_css_bnr_encode((struct sh_css_isp_bnr_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->nr_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_bnr() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_de(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.de.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.de.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_de() enter:\n");
-
- ia_css_de_encode((struct sh_css_isp_de_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->de_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_de() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_ecd(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.ecd.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.ecd.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ecd() enter:\n");
-
- ia_css_ecd_encode((struct sh_css_isp_ecd_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->ecd_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ecd() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_formats(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.formats.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.formats.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_formats() enter:\n");
-
- ia_css_formats_encode((struct sh_css_isp_formats_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->formats_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_formats() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_fpn(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.fpn.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.fpn.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_fpn() enter:\n");
-
- ia_css_fpn_encode((struct sh_css_isp_fpn_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->fpn_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_fpn() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_gc(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.gc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.gc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_gc() enter:\n");
-
- ia_css_gc_encode((struct sh_css_isp_gc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->gc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_gc() leave:\n");
- }
- }
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vamem1.gc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vamem1.gc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_gc() enter:\n");
-
- ia_css_gc_vamem_encode((struct sh_css_isp_gc_vamem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VAMEM1].address[offset],
- &params->gc_table,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VAMEM1] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_gc() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_ce(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.ce.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.ce.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_ce() enter:\n");
-
- ia_css_ce_encode((struct sh_css_isp_ce_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->ce_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_ce() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_yuv2rgb(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.yuv2rgb.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.yuv2rgb.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_yuv2rgb() enter:\n");
-
- ia_css_yuv2rgb_encode((struct sh_css_isp_csc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->yuv2rgb_cc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_yuv2rgb() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_rgb2yuv(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.rgb2yuv.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.rgb2yuv.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_rgb2yuv() enter:\n");
-
- ia_css_rgb2yuv_encode((struct sh_css_isp_csc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->rgb2yuv_cc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_rgb2yuv() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_r_gamma(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vamem0.r_gamma.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vamem0.r_gamma.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_r_gamma() enter:\n");
-
- ia_css_r_gamma_vamem_encode((struct sh_css_isp_rgb_gamma_vamem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VAMEM0].address[offset],
- &params->r_gamma_table,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VAMEM0] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_r_gamma() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_g_gamma(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vamem1.g_gamma.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vamem1.g_gamma.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_g_gamma() enter:\n");
-
- ia_css_g_gamma_vamem_encode((struct sh_css_isp_rgb_gamma_vamem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VAMEM1].address[offset],
- &params->g_gamma_table,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VAMEM1] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_g_gamma() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_b_gamma(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vamem2.b_gamma.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vamem2.b_gamma.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_b_gamma() enter:\n");
-
- ia_css_b_gamma_vamem_encode((struct sh_css_isp_rgb_gamma_vamem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VAMEM2].address[offset],
- &params->b_gamma_table,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VAMEM2] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_b_gamma() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_uds(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.uds.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.uds.offset;
-
- if (size) {
- struct sh_css_sp_uds_params *p;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_uds() enter:\n");
-
- p = (struct sh_css_sp_uds_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset];
- p->crop_pos = params->uds_config.crop_pos;
- p->uds = params->uds_config.uds;
-
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_uds() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_raa(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.raa.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.raa.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_raa() enter:\n");
-
- ia_css_raa_encode((struct sh_css_isp_aa_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->raa_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_raa() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_s3a(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.s3a.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.s3a.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_s3a() enter:\n");
-
- ia_css_s3a_encode((struct sh_css_isp_s3a_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->s3a_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_s3a() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_ob(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.ob.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.ob.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_ob() enter:\n");
-
- ia_css_ob_encode((struct sh_css_isp_ob_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->ob_config,
- &params->stream_configs.ob, size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_ob() leave:\n");
- }
- }
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vmem.ob.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vmem.ob.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_ob() enter:\n");
-
- ia_css_ob_vmem_encode((struct sh_css_isp_ob_vmem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VMEM].address[offset],
- &params->ob_config,
- &params->stream_configs.ob, size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_ob() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_output(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.output.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.output.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_output() enter:\n");
-
- ia_css_output_encode((struct sh_css_isp_output_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->output_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_output() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sc(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.sc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.sc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_sc() enter:\n");
-
- ia_css_sc_encode((struct sh_css_isp_sc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->sc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_sc() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_bds(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.bds.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.bds.offset;
-
- if (size) {
- struct sh_css_isp_bds_params *p;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_bds() enter:\n");
-
- p = (struct sh_css_isp_bds_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset];
- p->baf_strength = params->bds_config.strength;
-
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_bds() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_tnr(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.tnr.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.tnr.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_tnr() enter:\n");
-
- ia_css_tnr_encode((struct sh_css_isp_tnr_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->tnr_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_tnr() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_macc(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.macc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.macc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_macc() enter:\n");
-
- ia_css_macc_encode((struct sh_css_isp_macc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->macc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_macc() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis_horicoef(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis_horicoef.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis_horicoef.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_horicoef() enter:\n");
-
- ia_css_sdis_horicoef_vmem_encode((struct sh_css_isp_sdis_hori_coef_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VMEM].address[offset],
- &params->dvs_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_horicoef() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis_vertcoef(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis_vertcoef.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis_vertcoef.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_vertcoef() enter:\n");
-
- ia_css_sdis_vertcoef_vmem_encode((struct sh_css_isp_sdis_vert_coef_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VMEM].address[offset],
- &params->dvs_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_vertcoef() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis_horiproj(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis_horiproj.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis_horiproj.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_horiproj() enter:\n");
-
- ia_css_sdis_horiproj_encode((struct sh_css_isp_sdis_hori_proj_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->dvs_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_horiproj() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis_vertproj(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis_vertproj.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis_vertproj.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_vertproj() enter:\n");
-
- ia_css_sdis_vertproj_encode((struct sh_css_isp_sdis_vert_proj_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->dvs_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis_vertproj() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis2_horicoef(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis2_horicoef.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis2_horicoef.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_horicoef() enter:\n");
-
- ia_css_sdis2_horicoef_vmem_encode((struct sh_css_isp_sdis_hori_coef_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VMEM].address[offset],
- &params->dvs2_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_horicoef() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis2_vertcoef(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis2_vertcoef.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vmem.sdis2_vertcoef.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_vertcoef() enter:\n");
-
- ia_css_sdis2_vertcoef_vmem_encode((struct sh_css_isp_sdis_vert_coef_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VMEM].address[offset],
- &params->dvs2_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_vertcoef() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis2_horiproj(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis2_horiproj.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis2_horiproj.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_horiproj() enter:\n");
-
- ia_css_sdis2_horiproj_encode((struct sh_css_isp_sdis_hori_proj_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->dvs2_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_horiproj() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_sdis2_vertproj(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis2_vertproj.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.sdis2_vertproj.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_vertproj() enter:\n");
-
- ia_css_sdis2_vertproj_encode((struct sh_css_isp_sdis_vert_proj_tbl *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->dvs2_coefs,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_sdis2_vertproj() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_wb(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.wb.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.wb.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_wb() enter:\n");
-
- ia_css_wb_encode((struct sh_css_isp_wb_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->wb_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_wb() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_nr(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.nr.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.nr.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_nr() enter:\n");
-
- ia_css_nr_encode((struct sh_css_isp_ynr_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->nr_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_nr() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_yee(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.yee.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.yee.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_yee() enter:\n");
-
- ia_css_yee_encode((struct sh_css_isp_yee_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->yee_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_yee() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_ynr(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.ynr.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.ynr.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ynr() enter:\n");
-
- ia_css_ynr_encode((struct sh_css_isp_yee2_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->ynr_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ynr() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_fc(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.fc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.fc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_fc() enter:\n");
-
- ia_css_fc_encode((struct sh_css_isp_fc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->fc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_process_fc() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_ctc(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.ctc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.ctc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ctc() enter:\n");
-
- ia_css_ctc_encode((struct sh_css_isp_ctc_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->ctc_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ctc() leave:\n");
- }
- }
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vamem0.ctc.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vamem0.ctc.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ctc() enter:\n");
-
- ia_css_ctc_vamem_encode((struct sh_css_isp_ctc_vamem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VAMEM0].address[offset],
- &params->ctc_table,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VAMEM0] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_ctc() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_xnr_table(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vamem1.xnr_table.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vamem1.xnr_table.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr_table() enter:\n");
-
- ia_css_xnr_table_vamem_encode((struct sh_css_isp_xnr_vamem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VAMEM1].address[offset],
- &params->xnr_table,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VAMEM1] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr_table() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_xnr(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.xnr.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.xnr.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr() enter:\n");
-
- ia_css_xnr_encode((struct sh_css_isp_xnr_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->xnr_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_process_function() */
-
-static void
-ia_css_process_xnr3(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params)
-{
- assert(params);
-
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.xnr3.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.xnr3.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr3() enter:\n");
-
- ia_css_xnr3_encode((struct sh_css_isp_xnr3_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->xnr3_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr3() leave:\n");
- }
- }
-}
-
-/* Code generated by genparam/gencode.c:gen_param_process_table() */
-
-void (*ia_css_kernel_process_param[IA_CSS_NUM_PARAMETER_IDS])(
- unsigned int pipe_id,
- const struct ia_css_pipeline_stage *stage,
- struct ia_css_isp_parameters *params) = {
- ia_css_process_aa,
- ia_css_process_anr,
- ia_css_process_anr2,
- ia_css_process_bh,
- ia_css_process_cnr,
- ia_css_process_crop,
- ia_css_process_csc,
- ia_css_process_dp,
- ia_css_process_bnr,
- ia_css_process_de,
- ia_css_process_ecd,
- ia_css_process_formats,
- ia_css_process_fpn,
- ia_css_process_gc,
- ia_css_process_ce,
- ia_css_process_yuv2rgb,
- ia_css_process_rgb2yuv,
- ia_css_process_r_gamma,
- ia_css_process_g_gamma,
- ia_css_process_b_gamma,
- ia_css_process_uds,
- ia_css_process_raa,
- ia_css_process_s3a,
- ia_css_process_ob,
- ia_css_process_output,
- ia_css_process_sc,
- ia_css_process_bds,
- ia_css_process_tnr,
- ia_css_process_macc,
- ia_css_process_sdis_horicoef,
- ia_css_process_sdis_vertcoef,
- ia_css_process_sdis_horiproj,
- ia_css_process_sdis_vertproj,
- ia_css_process_sdis2_horicoef,
- ia_css_process_sdis2_vertcoef,
- ia_css_process_sdis2_horiproj,
- ia_css_process_sdis2_vertproj,
- ia_css_process_wb,
- ia_css_process_nr,
- ia_css_process_yee,
- ia_css_process_ynr,
- ia_css_process_fc,
- ia_css_process_ctc,
- ia_css_process_xnr_table,
- ia_css_process_xnr,
- ia_css_process_xnr3,
-};
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_dp_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dp_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_dp_config() enter: config=%p\n",
- config);
-
- *config = params->dp_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_dp_config() leave\n");
- ia_css_dp_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_dp_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dp_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_dp_config() enter:\n");
- ia_css_dp_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dp_config = *config;
- params->config_changed[IA_CSS_DP_ID] = true;
- params->config_changed[IA_CSS_DP_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_dp_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_wb_config(const struct ia_css_isp_parameters *params,
- struct ia_css_wb_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_wb_config() enter: config=%p\n",
- config);
-
- *config = params->wb_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_wb_config() leave\n");
- ia_css_wb_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_wb_config(struct ia_css_isp_parameters *params,
- const struct ia_css_wb_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_wb_config() enter:\n");
- ia_css_wb_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->wb_config = *config;
- params->config_changed[IA_CSS_WB_ID] = true;
- params->config_changed[IA_CSS_WB_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_wb_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_tnr_config(const struct ia_css_isp_parameters *params,
- struct ia_css_tnr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_tnr_config() enter: config=%p\n",
- config);
-
- *config = params->tnr_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_tnr_config() leave\n");
- ia_css_tnr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_tnr_config(struct ia_css_isp_parameters *params,
- const struct ia_css_tnr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_tnr_config() enter:\n");
- ia_css_tnr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->tnr_config = *config;
- params->config_changed[IA_CSS_TNR_ID] = true;
- params->config_changed[IA_CSS_TNR_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_tnr_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_ob_config(const struct ia_css_isp_parameters *params,
- struct ia_css_ob_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ob_config() enter: config=%p\n",
- config);
-
- *config = params->ob_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ob_config() leave\n");
- ia_css_ob_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_ob_config(struct ia_css_isp_parameters *params,
- const struct ia_css_ob_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_ob_config() enter:\n");
- ia_css_ob_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->ob_config = *config;
- params->config_changed[IA_CSS_OB_ID] = true;
- params->config_changed[IA_CSS_OB_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_ob_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_de_config(const struct ia_css_isp_parameters *params,
- struct ia_css_de_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_de_config() enter: config=%p\n",
- config);
-
- *config = params->de_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_de_config() leave\n");
- ia_css_de_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_de_config(struct ia_css_isp_parameters *params,
- const struct ia_css_de_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_de_config() enter:\n");
- ia_css_de_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->de_config = *config;
- params->config_changed[IA_CSS_DE_ID] = true;
- params->config_changed[IA_CSS_DE_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_de_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_anr_config(const struct ia_css_isp_parameters *params,
- struct ia_css_anr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_anr_config() enter: config=%p\n",
- config);
-
- *config = params->anr_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_anr_config() leave\n");
- ia_css_anr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_anr_config(struct ia_css_isp_parameters *params,
- const struct ia_css_anr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_anr_config() enter:\n");
- ia_css_anr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->anr_config = *config;
- params->config_changed[IA_CSS_ANR_ID] = true;
- params->config_changed[IA_CSS_ANR_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_anr_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_anr2_config(const struct ia_css_isp_parameters *params,
- struct ia_css_anr_thres *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_anr2_config() enter: config=%p\n",
- config);
-
- *config = params->anr_thres;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_anr2_config() leave\n");
- ia_css_anr2_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_anr2_config(struct ia_css_isp_parameters *params,
- const struct ia_css_anr_thres *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_anr2_config() enter:\n");
- ia_css_anr2_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->anr_thres = *config;
- params->config_changed[IA_CSS_ANR2_ID] = true;
- params->config_changed[IA_CSS_ANR2_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_anr2_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_ce_config(const struct ia_css_isp_parameters *params,
- struct ia_css_ce_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ce_config() enter: config=%p\n",
- config);
-
- *config = params->ce_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ce_config() leave\n");
- ia_css_ce_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_ce_config(struct ia_css_isp_parameters *params,
- const struct ia_css_ce_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_ce_config() enter:\n");
- ia_css_ce_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->ce_config = *config;
- params->config_changed[IA_CSS_CE_ID] = true;
- params->config_changed[IA_CSS_CE_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_ce_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_ecd_config(const struct ia_css_isp_parameters *params,
- struct ia_css_ecd_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ecd_config() enter: config=%p\n",
- config);
-
- *config = params->ecd_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ecd_config() leave\n");
- ia_css_ecd_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_ecd_config(struct ia_css_isp_parameters *params,
- const struct ia_css_ecd_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_ecd_config() enter:\n");
- ia_css_ecd_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->ecd_config = *config;
- params->config_changed[IA_CSS_ECD_ID] = true;
- params->config_changed[IA_CSS_ECD_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_ecd_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_ynr_config(const struct ia_css_isp_parameters *params,
- struct ia_css_ynr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ynr_config() enter: config=%p\n",
- config);
-
- *config = params->ynr_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ynr_config() leave\n");
- ia_css_ynr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_ynr_config(struct ia_css_isp_parameters *params,
- const struct ia_css_ynr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_ynr_config() enter:\n");
- ia_css_ynr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->ynr_config = *config;
- params->config_changed[IA_CSS_YNR_ID] = true;
- params->config_changed[IA_CSS_YNR_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_ynr_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_fc_config(const struct ia_css_isp_parameters *params,
- struct ia_css_fc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_fc_config() enter: config=%p\n",
- config);
-
- *config = params->fc_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_fc_config() leave\n");
- ia_css_fc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_fc_config(struct ia_css_isp_parameters *params,
- const struct ia_css_fc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_fc_config() enter:\n");
- ia_css_fc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->fc_config = *config;
- params->config_changed[IA_CSS_FC_ID] = true;
- params->config_changed[IA_CSS_FC_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_fc_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_cnr_config(const struct ia_css_isp_parameters *params,
- struct ia_css_cnr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_cnr_config() enter: config=%p\n",
- config);
-
- *config = params->cnr_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_cnr_config() leave\n");
- ia_css_cnr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_cnr_config(struct ia_css_isp_parameters *params,
- const struct ia_css_cnr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_cnr_config() enter:\n");
- ia_css_cnr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->cnr_config = *config;
- params->config_changed[IA_CSS_CNR_ID] = true;
- params->config_changed[IA_CSS_CNR_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_cnr_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_macc_config(const struct ia_css_isp_parameters *params,
- struct ia_css_macc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_macc_config() enter: config=%p\n",
- config);
-
- *config = params->macc_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_macc_config() leave\n");
- ia_css_macc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_macc_config(struct ia_css_isp_parameters *params,
- const struct ia_css_macc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_macc_config() enter:\n");
- ia_css_macc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->macc_config = *config;
- params->config_changed[IA_CSS_MACC_ID] = true;
- params->config_changed[IA_CSS_MACC_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_macc_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_ctc_config(const struct ia_css_isp_parameters *params,
- struct ia_css_ctc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ctc_config() enter: config=%p\n",
- config);
-
- *config = params->ctc_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_ctc_config() leave\n");
- ia_css_ctc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_ctc_config(struct ia_css_isp_parameters *params,
- const struct ia_css_ctc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_ctc_config() enter:\n");
- ia_css_ctc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->ctc_config = *config;
- params->config_changed[IA_CSS_CTC_ID] = true;
- params->config_changed[IA_CSS_CTC_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_ctc_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_aa_config(const struct ia_css_isp_parameters *params,
- struct ia_css_aa_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_aa_config() enter: config=%p\n",
- config);
-
- *config = params->aa_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_aa_config() leave\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_aa_config(struct ia_css_isp_parameters *params,
- const struct ia_css_aa_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_aa_config() enter:\n");
- params->aa_config = *config;
- params->config_changed[IA_CSS_AA_ID] = true;
- params->config_changed[IA_CSS_AA_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_aa_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_yuv2rgb_config(const struct ia_css_isp_parameters *params,
- struct ia_css_cc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_yuv2rgb_config() enter: config=%p\n",
- config);
-
- *config = params->yuv2rgb_cc_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_yuv2rgb_config() leave\n");
- ia_css_yuv2rgb_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_yuv2rgb_config(struct ia_css_isp_parameters *params,
- const struct ia_css_cc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_yuv2rgb_config() enter:\n");
- ia_css_yuv2rgb_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->yuv2rgb_cc_config = *config;
- params->config_changed[IA_CSS_YUV2RGB_ID] = true;
- params->config_changed[IA_CSS_YUV2RGB_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_yuv2rgb_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_rgb2yuv_config(const struct ia_css_isp_parameters *params,
- struct ia_css_cc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_rgb2yuv_config() enter: config=%p\n",
- config);
-
- *config = params->rgb2yuv_cc_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_rgb2yuv_config() leave\n");
- ia_css_rgb2yuv_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_rgb2yuv_config(struct ia_css_isp_parameters *params,
- const struct ia_css_cc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_rgb2yuv_config() enter:\n");
- ia_css_rgb2yuv_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->rgb2yuv_cc_config = *config;
- params->config_changed[IA_CSS_RGB2YUV_ID] = true;
- params->config_changed[IA_CSS_RGB2YUV_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_rgb2yuv_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_csc_config(const struct ia_css_isp_parameters *params,
- struct ia_css_cc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_csc_config() enter: config=%p\n",
- config);
-
- *config = params->cc_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_csc_config() leave\n");
- ia_css_csc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_csc_config(struct ia_css_isp_parameters *params,
- const struct ia_css_cc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_csc_config() enter:\n");
- ia_css_csc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->cc_config = *config;
- params->config_changed[IA_CSS_CSC_ID] = true;
- params->config_changed[IA_CSS_CSC_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_csc_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_nr_config(const struct ia_css_isp_parameters *params,
- struct ia_css_nr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_nr_config() enter: config=%p\n",
- config);
-
- *config = params->nr_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_nr_config() leave\n");
- ia_css_nr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_nr_config(struct ia_css_isp_parameters *params,
- const struct ia_css_nr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_nr_config() enter:\n");
- ia_css_nr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->nr_config = *config;
- params->config_changed[IA_CSS_BNR_ID] = true;
- params->config_changed[IA_CSS_NR_ID] = true;
- params->config_changed[IA_CSS_NR_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_nr_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_gc_config(const struct ia_css_isp_parameters *params,
- struct ia_css_gc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_gc_config() enter: config=%p\n",
- config);
-
- *config = params->gc_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_gc_config() leave\n");
- ia_css_gc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_gc_config(struct ia_css_isp_parameters *params,
- const struct ia_css_gc_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_gc_config() enter:\n");
- ia_css_gc_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->gc_config = *config;
- params->config_changed[IA_CSS_GC_ID] = true;
- params->config_changed[IA_CSS_GC_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_gc_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis_horicoef_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_horicoef_config() enter: config=%p\n",
- config);
-
- *config = params->dvs_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_horicoef_config() leave\n");
- ia_css_sdis_horicoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis_horicoef_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis_horicoef_config() enter:\n");
- ia_css_sdis_horicoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs_coefs = *config;
- params->config_changed[IA_CSS_SDIS_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_HORICOEF_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis_horicoef_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis_vertcoef_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_vertcoef_config() enter: config=%p\n",
- config);
-
- *config = params->dvs_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_vertcoef_config() leave\n");
- ia_css_sdis_vertcoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis_vertcoef_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis_vertcoef_config() enter:\n");
- ia_css_sdis_vertcoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs_coefs = *config;
- params->config_changed[IA_CSS_SDIS_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTCOEF_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis_vertcoef_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis_horiproj_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_horiproj_config() enter: config=%p\n",
- config);
-
- *config = params->dvs_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_horiproj_config() leave\n");
- ia_css_sdis_horiproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis_horiproj_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis_horiproj_config() enter:\n");
- ia_css_sdis_horiproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs_coefs = *config;
- params->config_changed[IA_CSS_SDIS_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_HORIPROJ_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis_horiproj_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis_vertproj_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_vertproj_config() enter: config=%p\n",
- config);
-
- *config = params->dvs_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis_vertproj_config() leave\n");
- ia_css_sdis_vertproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis_vertproj_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis_vertproj_config() enter:\n");
- ia_css_sdis_vertproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs_coefs = *config;
- params->config_changed[IA_CSS_SDIS_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS_VERTPROJ_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis_vertproj_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis2_horicoef_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_horicoef_config() enter: config=%p\n",
- config);
-
- *config = params->dvs2_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_horicoef_config() leave\n");
- ia_css_sdis2_horicoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis2_horicoef_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis2_horicoef_config() enter:\n");
- ia_css_sdis2_horicoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs2_coefs = *config;
- params->config_changed[IA_CSS_SDIS2_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_HORICOEF_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis2_horicoef_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis2_vertcoef_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_vertcoef_config() enter: config=%p\n",
- config);
-
- *config = params->dvs2_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_vertcoef_config() leave\n");
- ia_css_sdis2_vertcoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis2_vertcoef_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis2_vertcoef_config() enter:\n");
- ia_css_sdis2_vertcoef_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs2_coefs = *config;
- params->config_changed[IA_CSS_SDIS2_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTCOEF_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis2_vertcoef_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis2_horiproj_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_horiproj_config() enter: config=%p\n",
- config);
-
- *config = params->dvs2_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_horiproj_config() leave\n");
- ia_css_sdis2_horiproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis2_horiproj_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis2_horiproj_config() enter:\n");
- ia_css_sdis2_horiproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs2_coefs = *config;
- params->config_changed[IA_CSS_SDIS2_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_HORIPROJ_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis2_horiproj_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_sdis2_vertproj_config(const struct ia_css_isp_parameters *params,
- struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_vertproj_config() enter: config=%p\n",
- config);
-
- *config = params->dvs2_coefs;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_sdis2_vertproj_config() leave\n");
- ia_css_sdis2_vertproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_sdis2_vertproj_config(struct ia_css_isp_parameters *params,
- const struct ia_css_dvs2_coefficients *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_sdis2_vertproj_config() enter:\n");
- ia_css_sdis2_vertproj_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->dvs2_coefs = *config;
- params->config_changed[IA_CSS_SDIS2_HORICOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTCOEF_ID] = true;
- params->config_changed[IA_CSS_SDIS2_HORIPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTPROJ_ID] = true;
- params->config_changed[IA_CSS_SDIS2_VERTPROJ_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_sdis2_vertproj_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_r_gamma_config(const struct ia_css_isp_parameters *params,
- struct ia_css_rgb_gamma_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_r_gamma_config() enter: config=%p\n",
- config);
-
- *config = params->r_gamma_table;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_r_gamma_config() leave\n");
- ia_css_r_gamma_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_r_gamma_config(struct ia_css_isp_parameters *params,
- const struct ia_css_rgb_gamma_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_r_gamma_config() enter:\n");
- ia_css_r_gamma_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->r_gamma_table = *config;
- params->config_changed[IA_CSS_R_GAMMA_ID] = true;
- params->config_changed[IA_CSS_R_GAMMA_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_r_gamma_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_g_gamma_config(const struct ia_css_isp_parameters *params,
- struct ia_css_rgb_gamma_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_g_gamma_config() enter: config=%p\n",
- config);
-
- *config = params->g_gamma_table;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_g_gamma_config() leave\n");
- ia_css_g_gamma_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_g_gamma_config(struct ia_css_isp_parameters *params,
- const struct ia_css_rgb_gamma_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_g_gamma_config() enter:\n");
- ia_css_g_gamma_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->g_gamma_table = *config;
- params->config_changed[IA_CSS_G_GAMMA_ID] = true;
- params->config_changed[IA_CSS_G_GAMMA_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_g_gamma_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_b_gamma_config(const struct ia_css_isp_parameters *params,
- struct ia_css_rgb_gamma_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_b_gamma_config() enter: config=%p\n",
- config);
-
- *config = params->b_gamma_table;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_b_gamma_config() leave\n");
- ia_css_b_gamma_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_b_gamma_config(struct ia_css_isp_parameters *params,
- const struct ia_css_rgb_gamma_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_b_gamma_config() enter:\n");
- ia_css_b_gamma_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->b_gamma_table = *config;
- params->config_changed[IA_CSS_B_GAMMA_ID] = true;
- params->config_changed[IA_CSS_B_GAMMA_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_b_gamma_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_xnr_table_config(const struct ia_css_isp_parameters *params,
- struct ia_css_xnr_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_xnr_table_config() enter: config=%p\n",
- config);
-
- *config = params->xnr_table;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_xnr_table_config() leave\n");
- ia_css_xnr_table_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_xnr_table_config(struct ia_css_isp_parameters *params,
- const struct ia_css_xnr_table *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_set_xnr_table_config() enter:\n");
- ia_css_xnr_table_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->xnr_table = *config;
- params->config_changed[IA_CSS_XNR_TABLE_ID] = true;
- params->config_changed[IA_CSS_XNR_TABLE_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_xnr_table_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_formats_config(const struct ia_css_isp_parameters *params,
- struct ia_css_formats_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_formats_config() enter: config=%p\n",
- config);
-
- *config = params->formats_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_formats_config() leave\n");
- ia_css_formats_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_formats_config(struct ia_css_isp_parameters *params,
- const struct ia_css_formats_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_formats_config() enter:\n");
- ia_css_formats_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->formats_config = *config;
- params->config_changed[IA_CSS_FORMATS_ID] = true;
- params->config_changed[IA_CSS_FORMATS_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_formats_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_xnr_config(const struct ia_css_isp_parameters *params,
- struct ia_css_xnr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_xnr_config() enter: config=%p\n",
- config);
-
- *config = params->xnr_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_xnr_config() leave\n");
- ia_css_xnr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_xnr_config(struct ia_css_isp_parameters *params,
- const struct ia_css_xnr_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_xnr_config() enter:\n");
- ia_css_xnr_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->xnr_config = *config;
- params->config_changed[IA_CSS_XNR_ID] = true;
- params->config_changed[IA_CSS_XNR_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_xnr_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_xnr3_config(const struct ia_css_isp_parameters *params,
- struct ia_css_xnr3_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_xnr3_config() enter: config=%p\n",
- config);
-
- *config = params->xnr3_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_xnr3_config() leave\n");
- ia_css_xnr3_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_xnr3_config(struct ia_css_isp_parameters *params,
- const struct ia_css_xnr3_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_xnr3_config() enter:\n");
- ia_css_xnr3_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->xnr3_config = *config;
- params->config_changed[IA_CSS_XNR3_ID] = true;
- params->config_changed[IA_CSS_XNR3_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_xnr3_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_s3a_config(const struct ia_css_isp_parameters *params,
- struct ia_css_3a_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_s3a_config() enter: config=%p\n",
- config);
-
- *config = params->s3a_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_s3a_config() leave\n");
- ia_css_s3a_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_s3a_config(struct ia_css_isp_parameters *params,
- const struct ia_css_3a_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_s3a_config() enter:\n");
- ia_css_s3a_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->s3a_config = *config;
- params->config_changed[IA_CSS_BH_ID] = true;
- params->config_changed[IA_CSS_S3A_ID] = true;
- params->config_changed[IA_CSS_S3A_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_s3a_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_get_function() */
-
-static void
-ia_css_get_output_config(const struct ia_css_isp_parameters *params,
- struct ia_css_output_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_output_config() enter: config=%p\n",
- config);
-
- *config = params->output_config;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_get_output_config() leave\n");
- ia_css_output_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
-}
-
-/* Code generated by genparam/gencode.c:gen_set_function() */
-
-void
-ia_css_set_output_config(struct ia_css_isp_parameters *params,
- const struct ia_css_output_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_set_output_config() enter:\n");
- ia_css_output_debug_dtrace(config, IA_CSS_DEBUG_TRACE);
- params->output_config = *config;
- params->config_changed[IA_CSS_OUTPUT_ID] = true;
- params->config_changed[IA_CSS_OUTPUT_ID] = true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_set_output_config() leave: return_void\n");
-}
-
-/* Code generated by genparam/gencode.c:gen_global_access_function() */
-
-void
-ia_css_get_configs(struct ia_css_isp_parameters *params,
- const struct ia_css_isp_config *config)
-{
- ia_css_get_dp_config(params, config->dp_config);
- ia_css_get_wb_config(params, config->wb_config);
- ia_css_get_tnr_config(params, config->tnr_config);
- ia_css_get_ob_config(params, config->ob_config);
- ia_css_get_de_config(params, config->de_config);
- ia_css_get_anr_config(params, config->anr_config);
- ia_css_get_anr2_config(params, config->anr_thres);
- ia_css_get_ce_config(params, config->ce_config);
- ia_css_get_ecd_config(params, config->ecd_config);
- ia_css_get_ynr_config(params, config->ynr_config);
- ia_css_get_fc_config(params, config->fc_config);
- ia_css_get_cnr_config(params, config->cnr_config);
- ia_css_get_macc_config(params, config->macc_config);
- ia_css_get_ctc_config(params, config->ctc_config);
- ia_css_get_aa_config(params, config->aa_config);
- ia_css_get_yuv2rgb_config(params, config->yuv2rgb_cc_config);
- ia_css_get_rgb2yuv_config(params, config->rgb2yuv_cc_config);
- ia_css_get_csc_config(params, config->cc_config);
- ia_css_get_nr_config(params, config->nr_config);
- ia_css_get_gc_config(params, config->gc_config);
- ia_css_get_sdis_horicoef_config(params, config->dvs_coefs);
- ia_css_get_sdis_vertcoef_config(params, config->dvs_coefs);
- ia_css_get_sdis_horiproj_config(params, config->dvs_coefs);
- ia_css_get_sdis_vertproj_config(params, config->dvs_coefs);
- ia_css_get_sdis2_horicoef_config(params, config->dvs2_coefs);
- ia_css_get_sdis2_vertcoef_config(params, config->dvs2_coefs);
- ia_css_get_sdis2_horiproj_config(params, config->dvs2_coefs);
- ia_css_get_sdis2_vertproj_config(params, config->dvs2_coefs);
- ia_css_get_r_gamma_config(params, config->r_gamma_table);
- ia_css_get_g_gamma_config(params, config->g_gamma_table);
- ia_css_get_b_gamma_config(params, config->b_gamma_table);
- ia_css_get_xnr_table_config(params, config->xnr_table);
- ia_css_get_formats_config(params, config->formats_config);
- ia_css_get_xnr_config(params, config->xnr_config);
- ia_css_get_xnr3_config(params, config->xnr3_config);
- ia_css_get_s3a_config(params, config->s3a_config);
- ia_css_get_output_config(params, config->output_config);
-}
-
-/* Code generated by genparam/gencode.c:gen_global_access_function() */
-
-void
-ia_css_set_configs(struct ia_css_isp_parameters *params,
- const struct ia_css_isp_config *config)
-{
- ia_css_set_dp_config(params, config->dp_config);
- ia_css_set_wb_config(params, config->wb_config);
- ia_css_set_tnr_config(params, config->tnr_config);
- ia_css_set_ob_config(params, config->ob_config);
- ia_css_set_de_config(params, config->de_config);
- ia_css_set_anr_config(params, config->anr_config);
- ia_css_set_anr2_config(params, config->anr_thres);
- ia_css_set_ce_config(params, config->ce_config);
- ia_css_set_ecd_config(params, config->ecd_config);
- ia_css_set_ynr_config(params, config->ynr_config);
- ia_css_set_fc_config(params, config->fc_config);
- ia_css_set_cnr_config(params, config->cnr_config);
- ia_css_set_macc_config(params, config->macc_config);
- ia_css_set_ctc_config(params, config->ctc_config);
- ia_css_set_aa_config(params, config->aa_config);
- ia_css_set_yuv2rgb_config(params, config->yuv2rgb_cc_config);
- ia_css_set_rgb2yuv_config(params, config->rgb2yuv_cc_config);
- ia_css_set_csc_config(params, config->cc_config);
- ia_css_set_nr_config(params, config->nr_config);
- ia_css_set_gc_config(params, config->gc_config);
- ia_css_set_sdis_horicoef_config(params, config->dvs_coefs);
- ia_css_set_sdis_vertcoef_config(params, config->dvs_coefs);
- ia_css_set_sdis_horiproj_config(params, config->dvs_coefs);
- ia_css_set_sdis_vertproj_config(params, config->dvs_coefs);
- ia_css_set_sdis2_horicoef_config(params, config->dvs2_coefs);
- ia_css_set_sdis2_vertcoef_config(params, config->dvs2_coefs);
- ia_css_set_sdis2_horiproj_config(params, config->dvs2_coefs);
- ia_css_set_sdis2_vertproj_config(params, config->dvs2_coefs);
- ia_css_set_r_gamma_config(params, config->r_gamma_table);
- ia_css_set_g_gamma_config(params, config->g_gamma_table);
- ia_css_set_b_gamma_config(params, config->b_gamma_table);
- ia_css_set_xnr_table_config(params, config->xnr_table);
- ia_css_set_formats_config(params, config->formats_config);
- ia_css_set_xnr_config(params, config->xnr_config);
- ia_css_set_xnr3_config(params, config->xnr3_config);
- ia_css_set_s3a_config(params, config->s3a_config);
- ia_css_set_output_config(params, config->output_config);
-}
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c
deleted file mode 100644
index 1a021ae841fe..000000000000
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_configs.c
+++ /dev/null
@@ -1,386 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* Generated code: do not edit or commmit. */
-
-#define IA_CSS_INCLUDE_CONFIGURATIONS
-#include "ia_css_pipeline.h"
-#include "ia_css_isp_configs.h"
-#include "ia_css_debug.h"
-#include "assert_support.h"
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_iterator(
- const struct ia_css_binary *binary,
- const struct ia_css_iterator_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_iterator() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.iterator.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.iterator.offset;
- }
- if (size) {
- ia_css_iterator_config((struct sh_css_isp_iterator_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_iterator() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_copy_output(
- const struct ia_css_binary *binary,
- const struct ia_css_copy_output_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_copy_output() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.copy_output.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.copy_output.offset;
- }
- if (size) {
- ia_css_copy_output_config((struct sh_css_isp_copy_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_copy_output() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_crop(
- const struct ia_css_binary *binary,
- const struct ia_css_crop_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_crop() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.crop.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.crop.offset;
- }
- if (size) {
- ia_css_crop_config((struct sh_css_isp_crop_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_crop() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_fpn(
- const struct ia_css_binary *binary,
- const struct ia_css_fpn_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_fpn() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.fpn.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.fpn.offset;
- }
- if (size) {
- ia_css_fpn_config((struct sh_css_isp_fpn_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_fpn() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_dvs(
- const struct ia_css_binary *binary,
- const struct ia_css_dvs_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_dvs() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.dvs.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.dvs.offset;
- }
- if (size) {
- ia_css_dvs_config((struct sh_css_isp_dvs_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_dvs() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_qplane(
- const struct ia_css_binary *binary,
- const struct ia_css_qplane_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_qplane() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.qplane.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.qplane.offset;
- }
- if (size) {
- ia_css_qplane_config((struct sh_css_isp_qplane_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_qplane() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_output0(
- const struct ia_css_binary *binary,
- const struct ia_css_output0_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output0() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.output0.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.output0.offset;
- }
- if (size) {
- ia_css_output0_config((struct sh_css_isp_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output0() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_output1(
- const struct ia_css_binary *binary,
- const struct ia_css_output1_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output1() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.output1.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.output1.offset;
- }
- if (size) {
- ia_css_output1_config((struct sh_css_isp_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output1() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_output(
- const struct ia_css_binary *binary,
- const struct ia_css_output_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.output.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.output.offset;
- }
- if (size) {
- ia_css_output_config((struct sh_css_isp_output_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_output() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_raw(
- const struct ia_css_binary *binary,
- const struct ia_css_raw_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_raw() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.raw.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.raw.offset;
- }
- if (size) {
- ia_css_raw_config((struct sh_css_isp_raw_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_raw() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_tnr(
- const struct ia_css_binary *binary,
- const struct ia_css_tnr_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_tnr() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.tnr.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.tnr.offset;
- }
- if (size) {
- ia_css_tnr_config((struct sh_css_isp_tnr_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_tnr() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_ref(
- const struct ia_css_binary *binary,
- const struct ia_css_ref_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_ref() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.ref.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.ref.offset;
- }
- if (size) {
- ia_css_ref_config((struct sh_css_isp_ref_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_ref() leave:\n");
-}
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_vf(
- const struct ia_css_binary *binary,
- const struct ia_css_vf_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_vf() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.vf.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.vf.offset;
- }
- if (size) {
- ia_css_vf_config((struct sh_css_isp_vf_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_vf() leave:\n");
-}
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c b/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c
deleted file mode 100644
index 514ffe0303cb..000000000000
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_states.c
+++ /dev/null
@@ -1,224 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* Generated code: do not edit or commmit. */
-
-#include "ia_css_pipeline.h"
-#include "ia_css_isp_states.h"
-#include "ia_css_debug.h"
-#include "assert_support.h"
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_aa_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_aa_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->vmem.aa.size;
- unsigned int offset = binary->info->mem_offsets.offsets.state->vmem.aa.offset;
-
- if (size)
- memset(&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
- 0, size);
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_aa_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_cnr_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_cnr_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->vmem.cnr.size;
-
- unsigned int offset = binary->info->mem_offsets.offsets.state->vmem.cnr.offset;
-
- if (size) {
- ia_css_init_cnr_state(
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
- size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_cnr_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_cnr2_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_cnr2_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->vmem.cnr2.size;
-
- unsigned int offset = binary->info->mem_offsets.offsets.state->vmem.cnr2.offset;
-
- if (size) {
- ia_css_init_cnr2_state(
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
- size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_cnr2_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_dp_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_dp_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->vmem.dp.size;
-
- unsigned int offset = binary->info->mem_offsets.offsets.state->vmem.dp.offset;
-
- if (size) {
- ia_css_init_dp_state(
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
- size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_dp_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_de_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_de_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->vmem.de.size;
-
- unsigned int offset = binary->info->mem_offsets.offsets.state->vmem.de.offset;
-
- if (size) {
- ia_css_init_de_state(
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
- size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_de_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_tnr_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_tnr_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->dmem.tnr.size;
-
- unsigned int offset = binary->info->mem_offsets.offsets.state->dmem.tnr.offset;
-
- if (size) {
- ia_css_init_tnr_state((struct sh_css_isp_tnr_dmem_state *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_DMEM].address[offset],
- size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_tnr_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_ref_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_ref_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->dmem.ref.size;
-
- unsigned int offset = binary->info->mem_offsets.offsets.state->dmem.ref.offset;
-
- if (size) {
- ia_css_init_ref_state((struct sh_css_isp_ref_dmem_state *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_DMEM].address[offset],
- size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_ref_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_init_function() */
-
-static void
-ia_css_initialize_ynr_state(
- const struct ia_css_binary *binary)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_ynr_state() enter:\n");
-
- {
- unsigned int size = binary->info->mem_offsets.offsets.state->vmem.ynr.size;
-
- unsigned int offset = binary->info->mem_offsets.offsets.state->vmem.ynr.offset;
-
- if (size) {
- ia_css_init_ynr_state(
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
- size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_initialize_ynr_state() leave:\n");
-}
-
-/* Code generated by genparam/genstate.c:gen_state_init_table() */
-
-void (*ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(
- const struct ia_css_binary *binary) = {
- ia_css_initialize_aa_state,
- ia_css_initialize_cnr_state,
- ia_css_initialize_cnr2_state,
- ia_css_initialize_dp_state,
- ia_css_initialize_de_state,
- ia_css_initialize_tnr_state,
- ia_css_initialize_ref_state,
- ia_css_initialize_ynr_state,
-};
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c
index 8ed1cffc5384..25e082d6a94a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/gdc.c
@@ -28,10 +28,6 @@ static inline void gdc_reg_store(
const unsigned int reg,
const hrt_data value);
-static inline hrt_data gdc_reg_load(
- const gdc_ID_t ID,
- const unsigned int reg);
-
#ifndef __INLINE_GDC__
#include "gdc_private.h"
#endif /* __INLINE_GDC__ */
@@ -117,10 +113,3 @@ static inline void gdc_reg_store(
ia_css_device_store_uint32(GDC_BASE[ID] + reg * sizeof(hrt_data), value);
return;
}
-
-static inline hrt_data gdc_reg_load(
- const gdc_ID_t ID,
- const unsigned int reg)
-{
- return ia_css_device_load_uint32(GDC_BASE[ID] + reg * sizeof(hrt_data));
-}
diff --git a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
index 36583ab12e3f..d0ce2f8ba653 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_acc_types.h
@@ -222,11 +222,6 @@ struct ia_css_binary_info {
struct ia_css_isp_param_isp_segments mem_initializers;
/* MW: Packing (related) bools in an integer ?? */
struct {
- /* ISP2401 */
- u8 luma_only;
- u8 input_yuv;
- u8 input_raw;
-
u8 reduced_pipe;
u8 vf_veceven;
u8 dis;
diff --git a/drivers/staging/media/atomisp/pci/ia_css_event_public.h b/drivers/staging/media/atomisp/pci/ia_css_event_public.h
index 08ea801dd5ac..76219d741d2e 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_event_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_event_public.h
@@ -157,21 +157,6 @@ struct ia_css_event {
int
ia_css_dequeue_psys_event(struct ia_css_event *event);
-/* @brief Dequeue an event from the CSS system.
- *
- * @param[out] event Pointer to the event struct which will be filled by
- * this function if an event is available.
- * @return -ENODATA if no events are
- * available or
- * 0 otherwise.
- *
- * deprecated{Use ia_css_dequeue_psys_event instead}.
- * Unless the isys event queue is explicitly enabled, this function will
- * dequeue both isys (EOF) and psys events (all others).
- */
-int
-ia_css_dequeue_event(struct ia_css_event *event);
-
/* @brief Dequeue an ISYS event from the CSS system.
*
* @param[out] event Pointer to the event struct which will be filled by
@@ -182,7 +167,7 @@ ia_css_dequeue_event(struct ia_css_event *event);
*
* This function dequeues an event from the ISYS event queue. The queue is
* between host and the CSS system.
- * Unlike the ia_css_dequeue_event() function, this function can be called
+ * Unlike the ia_css_dequeue_psys_event() function, this function can be called
* directly from an interrupt service routine (ISR) and it is safe to call
* this function in parallel with other CSS API functions (but only one
* call to this function should be in flight at any point in time).
diff --git a/drivers/staging/media/atomisp/pci/ia_css_isp_configs.c b/drivers/staging/media/atomisp/pci/ia_css_isp_configs.c
new file mode 100644
index 000000000000..d28a76a68e43
--- /dev/null
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_configs.c
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Support for Intel Camera Imaging ISP subsystem.
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+/* Generated code: do not edit or commmit. */
+
+#define IA_CSS_INCLUDE_CONFIGURATIONS
+#include "ia_css_pipeline.h"
+#include "ia_css_isp_configs.h"
+#include "ia_css_debug.h"
+#include "assert_support.h"
+
+int ia_css_configure_iterator(const struct ia_css_binary *binary,
+ const struct ia_css_iterator_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.iterator.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.iterator.offset;
+
+ ia_css_iterator_config((struct sh_css_isp_iterator_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_copy_output(const struct ia_css_binary *binary,
+ const struct ia_css_copy_output_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.copy_output.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.copy_output.offset;
+
+ ia_css_copy_output_config((struct sh_css_isp_copy_output_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+/* Code generated by genparam/genconfig.c:gen_configure_function() */
+
+int ia_css_configure_crop(const struct ia_css_binary *binary,
+ const struct ia_css_crop_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.crop.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.crop.offset;
+
+ ia_css_crop_config((struct sh_css_isp_crop_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_fpn(const struct ia_css_binary *binary,
+ const struct ia_css_fpn_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.fpn.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.fpn.offset;
+ ia_css_fpn_config((struct sh_css_isp_fpn_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_dvs(const struct ia_css_binary *binary,
+ const struct ia_css_dvs_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.dvs.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.dvs.offset;
+ ia_css_dvs_config((struct sh_css_isp_dvs_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_qplane(const struct ia_css_binary *binary,
+ const struct ia_css_qplane_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.qplane.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.qplane.offset;
+ ia_css_qplane_config((struct sh_css_isp_qplane_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+
+ return 0;
+}
+
+int ia_css_configure_output0(const struct ia_css_binary *binary,
+ const struct ia_css_output0_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.output0.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.output0.offset;
+
+ ia_css_output0_config((struct sh_css_isp_output_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_output1(const struct ia_css_binary *binary,
+ const struct ia_css_output1_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.output1.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.output1.offset;
+
+ ia_css_output1_config((struct sh_css_isp_output_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_output(const struct ia_css_binary *binary,
+ const struct ia_css_output_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.output.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.output.offset;
+
+ ia_css_output_config((struct sh_css_isp_output_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_raw(const struct ia_css_binary *binary,
+ const struct ia_css_raw_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.raw.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.raw.offset;
+
+ ia_css_raw_config((struct sh_css_isp_raw_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_tnr(const struct ia_css_binary *binary,
+ const struct ia_css_tnr_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.tnr.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.tnr.offset;
+
+ ia_css_tnr_config((struct sh_css_isp_tnr_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_ref(const struct ia_css_binary *binary,
+ const struct ia_css_ref_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.ref.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.ref.offset;
+
+ ia_css_ref_config((struct sh_css_isp_ref_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
+
+int ia_css_configure_vf(const struct ia_css_binary *binary,
+ const struct ia_css_vf_configuration *config_dmem)
+{
+ unsigned int offset = 0;
+ unsigned int size = 0;
+
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "%s:\n", __func__);
+
+ if (!binary->info->mem_offsets.offsets.config)
+ return 0;
+
+ size = binary->info->mem_offsets.offsets.config->dmem.vf.size;
+ if (!size)
+ return 0;
+
+ offset = binary->info->mem_offsets.offsets.config->dmem.vf.offset;
+
+ ia_css_vf_config((struct sh_css_isp_vf_isp_config *)
+ &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
+ config_dmem, size);
+ return 0;
+}
diff --git a/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h b/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h
index 1abb2fd6a913..fffcfc871bd2 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_configs.h
@@ -23,22 +23,15 @@
#include "isp/kernels/raw/raw_1.0/ia_css_raw.host.h"
#include "isp/kernels/ref/ref_1.0/ia_css_ref.host.h"
#include "isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.h"
-
-/* ISP2401 */
-#include "isp/kernels/sc/sc_1.0/ia_css_sc.host.h"
-
#include "isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h"
#include "isp/kernels/vf/vf_1.0/ia_css_vf.host.h"
#include "isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.h"
#include "isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h"
-#endif /* IA_CSS_INCLUDE_CONFIGURATIONS */
-/* Generated code: do not edit or commmit. */
+#endif
#ifndef _IA_CSS_ISP_CONFIG_H
#define _IA_CSS_ISP_CONFIG_H
-/* Code generated by genparam/gencode.c:gen_param_enum() */
-
enum ia_css_configuration_ids {
IA_CSS_ITERATOR_CONFIG_ID,
IA_CSS_COPY_OUTPUT_CONFIG_ID,
@@ -60,8 +53,6 @@ enum ia_css_configuration_ids {
IA_CSS_NUM_CONFIGURATION_IDS
};
-/* Code generated by genparam/gencode.c:gen_param_offsets() */
-
struct ia_css_config_memory_offsets {
struct {
struct ia_css_isp_parameter iterator;
@@ -73,10 +64,6 @@ struct ia_css_config_memory_offsets {
struct ia_css_isp_parameter output0;
struct ia_css_isp_parameter output1;
struct ia_css_isp_parameter output;
-
- /* ISP2401 */
- struct ia_css_isp_parameter sc;
-
struct ia_css_isp_parameter raw;
struct ia_css_isp_parameter tnr;
struct ia_css_isp_parameter ref;
@@ -88,96 +75,44 @@ struct ia_css_config_memory_offsets {
#include "ia_css_stream.h" /* struct ia_css_stream */
#include "ia_css_binary.h" /* struct ia_css_binary */
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_iterator(
- const struct ia_css_binary *binary,
- const struct ia_css_iterator_configuration *config_dmem);
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_copy_output(
- const struct ia_css_binary *binary,
- const struct ia_css_copy_output_configuration *config_dmem);
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_crop(
- const struct ia_css_binary *binary,
- const struct ia_css_crop_configuration *config_dmem);
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_fpn(
- const struct ia_css_binary *binary,
- const struct ia_css_fpn_configuration *config_dmem);
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_dvs(
- const struct ia_css_binary *binary,
- const struct ia_css_dvs_configuration *config_dmem);
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_qplane(
- const struct ia_css_binary *binary,
- const struct ia_css_qplane_configuration *config_dmem);
-
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-void
-ia_css_configure_output0(
- const struct ia_css_binary *binary,
- const struct ia_css_output0_configuration *config_dmem);
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
+int ia_css_configure_iterator(const struct ia_css_binary *binary,
+ const struct ia_css_iterator_configuration *config_dmem);
-void
-ia_css_configure_output1(
- const struct ia_css_binary *binary,
- const struct ia_css_output1_configuration *config_dmem);
+int ia_css_configure_copy_output(const struct ia_css_binary *binary,
+ const struct ia_css_copy_output_configuration *config_dmem);
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
+int ia_css_configure_crop(const struct ia_css_binary *binary,
+ const struct ia_css_crop_configuration *config_dmem);
-void
-ia_css_configure_output(
- const struct ia_css_binary *binary,
- const struct ia_css_output_configuration *config_dmem);
+int ia_css_configure_fpn(const struct ia_css_binary *binary,
+ const struct ia_css_fpn_configuration *config_dmem);
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
+int ia_css_configure_dvs(const struct ia_css_binary *binary,
+ const struct ia_css_dvs_configuration *config_dmem);
-void
-ia_css_configure_raw(
- const struct ia_css_binary *binary,
- const struct ia_css_raw_configuration *config_dmem);
+int ia_css_configure_qplane(const struct ia_css_binary *binary,
+ const struct ia_css_qplane_configuration *config_dmem);
+int ia_css_configure_output0(const struct ia_css_binary *binary,
+ const struct ia_css_output0_configuration *config_dmem);
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
+int ia_css_configure_output1(const struct ia_css_binary *binary,
+ const struct ia_css_output1_configuration *config_dmem);
-void
-ia_css_configure_tnr(
- const struct ia_css_binary *binary,
- const struct ia_css_tnr_configuration *config_dmem);
+int ia_css_configure_output(const struct ia_css_binary *binary,
+ const struct ia_css_output_configuration *config_dmem);
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
+int ia_css_configure_raw(const struct ia_css_binary *binary,
+ const struct ia_css_raw_configuration *config_dmem);
-void
-ia_css_configure_ref(
- const struct ia_css_binary *binary,
- const struct ia_css_ref_configuration *config_dmem);
+int ia_css_configure_tnr(const struct ia_css_binary *binary,
+ const struct ia_css_tnr_configuration *config_dmem);
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
+int ia_css_configure_ref(const struct ia_css_binary *binary,
+ const struct ia_css_ref_configuration *config_dmem);
-void
-ia_css_configure_vf(
- const struct ia_css_binary *binary,
- const struct ia_css_vf_configuration *config_dmem);
+int ia_css_configure_vf(const struct ia_css_binary *binary,
+ const struct ia_css_vf_configuration *config_dmem);
#endif /* IA_CSS_INCLUDE_CONFIGURATION */
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c b/drivers/staging/media/atomisp/pci/ia_css_isp_params.c
index d9c672d8904e..503ac65da69b 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/hive/ia_css_isp_params.c
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_params.c
@@ -1721,29 +1721,6 @@ ia_css_process_xnr3(
"ia_css_process_xnr3() leave:\n");
}
}
- {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->vmem.xnr3.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->vmem.xnr3.offset;
-
- if (size) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr3() enter:\n");
-
- ia_css_xnr3_vmem_encode((struct sh_css_isp_xnr3_vmem_params *)
- &stage->binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_VMEM].address[offset],
- &params->xnr3_config,
- size);
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_VMEM] =
- true;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_process_xnr3() leave:\n");
- }
- }
}
/* Code generated by genparam/gencode.c:gen_param_process_table() */
diff --git a/drivers/staging/media/atomisp/pci/ia_css_isp_params.h b/drivers/staging/media/atomisp/pci/ia_css_isp_params.h
index 6e3082b39ed6..c2de689877d1 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_isp_params.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_params.h
@@ -121,9 +121,6 @@ struct ia_css_memory_offsets {
struct ia_css_isp_parameter sdis_vertcoef;
struct ia_css_isp_parameter sdis2_horicoef;
struct ia_css_isp_parameter sdis2_vertcoef;
-
- /* ISP2401 */
- struct ia_css_isp_parameter xnr3;
} vmem;
struct {
struct ia_css_isp_parameter bh;
diff --git a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c b/drivers/staging/media/atomisp/pci/ia_css_isp_states.c
index a6bc2e9eddea..a6bc2e9eddea 100644
--- a/drivers/staging/media/atomisp/pci/css_2400_system/hive/ia_css_isp_states.c
+++ b/drivers/staging/media/atomisp/pci/ia_css_isp_states.c
diff --git a/drivers/staging/media/atomisp/pci/ia_css_pipe.h b/drivers/staging/media/atomisp/pci/ia_css_pipe.h
index bb0abf9bffb1..fb58535bff40 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_pipe.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_pipe.h
@@ -33,7 +33,7 @@ struct ia_css_preview_settings {
/* 2401 only for these two - do we in fact use them for anything real */
struct ia_css_frame *delay_frames[MAX_NUM_VIDEO_DELAY_FRAMES];
- struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES];
+ struct ia_css_frame *tnr_frames[NUM_VIDEO_TNR_FRAMES];
struct ia_css_pipe *copy_pipe;
struct ia_css_pipe *capture_pipe;
@@ -81,7 +81,7 @@ struct ia_css_video_settings {
struct ia_css_binary vf_pp_binary;
struct ia_css_binary *yuv_scaler_binary;
struct ia_css_frame *delay_frames[MAX_NUM_VIDEO_DELAY_FRAMES];
- struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES];
+ struct ia_css_frame *tnr_frames[NUM_VIDEO_TNR_FRAMES];
struct ia_css_frame *vf_pp_in_frame;
struct ia_css_pipe *copy_pipe;
struct ia_css_pipe *capture_pipe;
diff --git a/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h b/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
index 4affd21f9e3f..7352cbf779fb 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
@@ -123,9 +123,6 @@ struct ia_css_pipe_config {
processing stages. */
/* ISP2401 */
- bool enable_luma_only;
- /** Enabling of monochrome mode for a pipeline. If enabled only luma processing
- will be done. */
bool enable_tnr;
/** Enabling of TNR (temporal noise reduction). This is only applicable to video
pipes. Non video-pipes should always set this parameter to false. */
@@ -482,29 +479,6 @@ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe,
u32 fw_handle,
bool *enable);
-/* ISP2401 */
-/* @brief Update mapped CSS and ISP arguments for QoS pipe during SP runtime.
- * @param[in] pipe Pipe handle.
- * @param[in] fw_handle Extension firmware Handle (ia_css_fw_info.handle).
- * @param[in] css_seg Parameter memory descriptors for CSS segments.
- * @param[in] isp_seg Parameter memory descriptors for ISP segments.
- *
- * @return
- * 0 : Success
- * -EINVAL : Invalid Parameters
- * -EBUSY : Inactive QOS Pipe
- * (No active stream with this pipe)
- *
- * \deprecated{This interface is used to temporarily support a late-developed,
- * specific use-case on a specific IPU2 platform. It will not be supported or
- * maintained on IPU3 or further.}
- */
-int
-ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
- u32 fw_handle,
- struct ia_css_isp_param_css_segments *css_seg,
- struct ia_css_isp_param_isp_segments *isp_seg);
-
/* @brief Get selected configuration settings
* @param[in] pipe The pipe.
* @param[out] config Configuration settings.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_stream.h b/drivers/staging/media/atomisp/pci/ia_css_stream.h
index 70b0378748f1..cf847586dc61 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_stream.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_stream.h
@@ -18,9 +18,7 @@
#include <type_support.h>
#include <system_local.h>
-#if !defined(ISP2401)
#include <input_system.h>
-#endif
#include "ia_css_types.h"
#include "ia_css_stream_public.h"
@@ -30,9 +28,7 @@
struct ia_css_stream {
struct ia_css_stream_config config;
struct ia_css_stream_info info;
-#if !defined(ISP2401)
rx_cfg_t csi_rx_config;
-#endif
bool reconfigure_css_rx;
struct ia_css_pipe *last_pipe;
int num_pipes;
diff --git a/drivers/staging/media/atomisp/pci/ia_css_stream_public.h b/drivers/staging/media/atomisp/pci/ia_css_stream_public.h
index 83846e417ae5..47846ece8d64 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_stream_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_stream_public.h
@@ -102,12 +102,10 @@ struct ia_css_stream_config {
isys_config[IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH];
struct ia_css_stream_input_config input_config;
- /* Currently, Android and Windows platforms interpret the binning_factor parameter
- * differently. In Android, the binning factor is expressed in the form
- * 2^N * 2^N, whereas in Windows platform, the binning factor is N*N
- * To use the Windows method of specification, the caller has to define
- * macro USE_WINDOWS_BINNING_FACTOR. This is for backward compatibility only
- * and will be deprecated. In the future,all platforms will use the N*N method
+ /*
+ * Currently, Linux and Windows platforms interpret the binning_factor
+ * parameter differently. In Linux, the binning factor is expressed
+ * in the form 2^N * 2^N
*/
/* ISP2401 */
unsigned int sensor_binning_factor; /** Binning factor used by sensor
@@ -202,15 +200,6 @@ int
ia_css_stream_get_info(const struct ia_css_stream *stream,
struct ia_css_stream_info *stream_info);
-/* @brief load (rebuild) a stream that was unloaded.
- * @param[in] stream The stream
- * @return 0 or the error code
- *
- * Rebuild a stream, including allocating structs, setting configuration and
- * building the required pipes.
- */
-int
-ia_css_stream_load(struct ia_css_stream *stream);
/* @brief Starts the stream.
* @param[in] stream The stream.
diff --git a/drivers/staging/media/atomisp/pci/input_system_local.h b/drivers/staging/media/atomisp/pci/input_system_local.h
index b33aa2838290..357987d629cd 100644
--- a/drivers/staging/media/atomisp/pci/input_system_local.h
+++ b/drivers/staging/media/atomisp/pci/input_system_local.h
@@ -4,6 +4,140 @@
* (c) 2020 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
*/
+#include "type_support.h"
+#include "input_system_global.h"
+
+typedef enum {
+ INPUT_SYSTEM_PORT_A = 0,
+ INPUT_SYSTEM_PORT_B,
+ INPUT_SYSTEM_PORT_C,
+ N_INPUT_SYSTEM_PORTS
+} input_system_csi_port_t;
+
+typedef struct ctrl_unit_cfg_s ctrl_unit_cfg_t;
+typedef struct input_system_network_cfg_s input_system_network_cfg_t;
+typedef struct target_cfg2400_s target_cfg2400_t;
+typedef struct channel_cfg_s channel_cfg_t;
+typedef struct backend_channel_cfg_s backend_channel_cfg_t;
+typedef struct input_system_cfg2400_s input_system_cfg2400_t;
+typedef struct mipi_port_state_s mipi_port_state_t;
+typedef struct rx_channel_state_s rx_channel_state_t;
+typedef struct input_switch_cfg_channel_s input_switch_cfg_channel_t;
+typedef struct input_switch_cfg_s input_switch_cfg_t;
+
+struct ctrl_unit_cfg_s {
+ isp2400_ib_buffer_t buffer_mipi[N_CAPTURE_UNIT_ID];
+ isp2400_ib_buffer_t buffer_acquire[N_ACQUISITION_UNIT_ID];
+};
+
+struct input_system_network_cfg_s {
+ input_system_connection_t multicast_cfg[N_CAPTURE_UNIT_ID];
+ input_system_multiplex_t mux_cfg;
+ ctrl_unit_cfg_t ctrl_unit_cfg[N_CTRL_UNIT_ID];
+};
+
+typedef struct {
+// TBD.
+ u32 dummy_parameter;
+} target_isp_cfg_t;
+
+typedef struct {
+// TBD.
+ u32 dummy_parameter;
+} target_sp_cfg_t;
+
+typedef struct {
+// TBD.
+ u32 dummy_parameter;
+} target_strm2mem_cfg_t;
+
+struct input_switch_cfg_channel_s {
+ u32 hsync_data_reg[2];
+ u32 vsync_data_reg;
+};
+
+struct backend_channel_cfg_s {
+ u32 fmt_control_word_1; // Format config.
+ u32 fmt_control_word_2;
+ u32 no_side_band;
+};
+
+typedef union {
+ csi_cfg_t csi_cfg;
+ tpg_cfg_t tpg_cfg;
+ prbs_cfg_t prbs_cfg;
+ gpfifo_cfg_t gpfifo_cfg;
+} source_cfg_t;
+
+struct input_switch_cfg_s {
+ u32 hsync_data_reg[N_RX_CHANNEL_ID * 2];
+ u32 vsync_data_reg;
+};
+
+/*
+ * In 2300 ports can be configured independently and stream
+ * formats need to be specified. In 2400, there are only 8
+ * supported configurations but the HW is fused to support
+ * only a single one.
+ *
+ * In 2300 the compressed format types are programmed by the
+ * user. In 2400 all stream formats are encoded on the stream.
+ *
+ * Use the enum to check validity of a user configuration
+ */
+typedef enum {
+ MONO_4L_1L_0L = 0,
+ MONO_3L_1L_0L,
+ MONO_2L_1L_0L,
+ MONO_1L_1L_0L,
+ STEREO_2L_1L_2L,
+ STEREO_3L_1L_1L,
+ STEREO_2L_1L_1L,
+ STEREO_1L_1L_1L,
+ N_RX_MODE
+} rx_mode_t;
+
+#define UNCOMPRESSED_BITS_PER_PIXEL_10 10
+#define UNCOMPRESSED_BITS_PER_PIXEL_12 12
+#define COMPRESSED_BITS_PER_PIXEL_6 6
+#define COMPRESSED_BITS_PER_PIXEL_7 7
+#define COMPRESSED_BITS_PER_PIXEL_8 8
+enum mipi_compressor {
+ MIPI_COMPRESSOR_NONE = 0,
+ MIPI_COMPRESSOR_10_6_10,
+ MIPI_COMPRESSOR_10_7_10,
+ MIPI_COMPRESSOR_10_8_10,
+ MIPI_COMPRESSOR_12_6_12,
+ MIPI_COMPRESSOR_12_7_12,
+ MIPI_COMPRESSOR_12_8_12,
+ N_MIPI_COMPRESSOR_METHODS
+};
+
+typedef enum mipi_compressor mipi_compressor_t;
+
+typedef enum {
+ MIPI_PREDICTOR_NONE = 0,
+ MIPI_PREDICTOR_TYPE1,
+ MIPI_PREDICTOR_TYPE2,
+ N_MIPI_PREDICTOR_TYPES
+} mipi_predictor_t;
+
+typedef struct rx_cfg_s rx_cfg_t;
+
+/*
+ * Applied per port
+ */
+struct rx_cfg_s {
+ rx_mode_t mode; /* The HW config */
+ enum mipi_port_id port; /* The port ID to apply the control on */
+ unsigned int timeout;
+ unsigned int initcount;
+ unsigned int synccount;
+ unsigned int rxcount;
+ mipi_predictor_t comp; /* Just for backward compatibility */
+ bool is_two_ppc;
+};
+
#ifdef ISP2401
# include "isp2401_input_system_local.h"
#else
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
index 82aa69b74677..2091f001502d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/bh/bh_2/ia_css_bh.host.c
@@ -13,7 +13,6 @@
* more details.
*/
-#if !defined(HAS_NO_HMEM)
#include "ia_css_types.h"
#include "sh_css_internal.h"
@@ -63,4 +62,3 @@ ia_css_bh_encode(
uDIGIT_FITTING(from->ae_y_coef_b, 16, SH_CSS_AE_YCOEF_SHIFT);
}
-#endif
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c
index 5d34f3256a43..cc415c72ad8f 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.c
@@ -34,14 +34,12 @@ ia_css_copy_output_config(
to->enable = from->enable;
}
-void
-ia_css_copy_output_configure(
- const struct ia_css_binary *binary,
- bool enable)
+int ia_css_copy_output_configure(const struct ia_css_binary *binary,
+ bool enable)
{
struct ia_css_copy_output_configuration config = default_config;
config.enable = enable;
- ia_css_configure_copy_output(binary, &config);
+ return ia_css_configure_copy_output(binary, &config);
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h
index 615cb6771884..44e3e45b0ec3 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/copy_output/copy_output_1.0/ia_css_copy_output.host.h
@@ -27,9 +27,7 @@ ia_css_copy_output_config(
const struct ia_css_copy_output_configuration *from,
unsigned int size);
-void
-ia_css_copy_output_configure(
- const struct ia_css_binary *binary,
- bool enable);
+int ia_css_copy_output_configure(const struct ia_css_binary *binary,
+ bool enable);
#endif /* __IA_CSS_COPY_OUTPUT_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c
index 38912062edd4..8c1d50f7aae4 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.c
@@ -36,30 +36,32 @@ ia_css_crop_encode(
to->crop_pos = from->crop_pos;
}
-void
-ia_css_crop_config(
- struct sh_css_isp_crop_isp_config *to,
- const struct ia_css_crop_configuration *from,
- unsigned int size)
+int ia_css_crop_config(struct sh_css_isp_crop_isp_config *to,
+ const struct ia_css_crop_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS;
+ int ret;
+
+ ret = ia_css_dma_configure_from_info(&to->port_b, from->info);
+ if (ret)
+ return ret;
- (void)size;
- ia_css_dma_configure_from_info(&to->port_b, from->info);
to->width_a_over_b = elems_a / to->port_b.elems;
/* Assume divisiblity here, may need to generalize to fixed point. */
- assert(elems_a % to->port_b.elems == 0);
+ if (elems_a % to->port_b.elems != 0)
+ return -EINVAL;
+
+ return 0;
}
-void
-ia_css_crop_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *info)
+int ia_css_crop_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *info)
{
struct ia_css_crop_configuration config = default_config;
config.info = info;
- ia_css_configure_crop(binary, &config);
+ return ia_css_configure_crop(binary, &config);
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h
index 21a259d33256..e700149c1e95 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/crop/crop_1.0/ia_css_crop.host.h
@@ -28,15 +28,11 @@ ia_css_crop_encode(
const struct ia_css_crop_config *from,
unsigned int size);
-void
-ia_css_crop_config(
- struct sh_css_isp_crop_isp_config *to,
- const struct ia_css_crop_configuration *from,
- unsigned int size);
+int ia_css_crop_config(struct sh_css_isp_crop_isp_config *to,
+ const struct ia_css_crop_configuration *from,
+ unsigned int size);
-void
-ia_css_crop_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *from);
+int ia_css_crop_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *from);
#endif /* __IA_CSS_CROP_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c
index 67f5540b48b5..07ce5b4f0816 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c
@@ -46,16 +46,14 @@ ia_css_dvs_config(
DVS_NUM_BLOCKS_Y(from->info->res.height);
}
-void
-ia_css_dvs_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *info)
+int ia_css_dvs_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *info)
{
struct ia_css_dvs_configuration config = default_config;
config.info = info;
- ia_css_configure_dvs(binary, &config);
+ return ia_css_configure_dvs(binary, &config);
}
static void
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h
index f9bc17ee0f86..332aa5496c04 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.h
@@ -35,10 +35,8 @@ ia_css_dvs_config(
const struct ia_css_dvs_configuration *from,
unsigned int size);
-void
-ia_css_dvs_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *from);
+int ia_css_dvs_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *from);
void
convert_dvs_6axis_config(
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c
index 47b5c7956fbd..57b5e11e1cfe 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c
@@ -51,26 +51,28 @@ ia_css_fpn_dump(
"fpn_enabled", fpn->enabled);
}
-void
-ia_css_fpn_config(
- struct sh_css_isp_fpn_isp_config *to,
- const struct ia_css_fpn_configuration *from,
- unsigned int size)
+int ia_css_fpn_config(struct sh_css_isp_fpn_isp_config *to,
+ const struct ia_css_fpn_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS;
+ int ret;
+
+ ret = ia_css_dma_configure_from_info(&to->port_b, from->info);
+ if (ret)
+ return ret;
- (void)size;
- ia_css_dma_configure_from_info(&to->port_b, from->info);
to->width_a_over_b = elems_a / to->port_b.elems;
/* Assume divisiblity here, may need to generalize to fixed point. */
- assert(elems_a % to->port_b.elems == 0);
+ if (elems_a % to->port_b.elems != 0)
+ return -EINVAL;
+
+ return 0;
}
-void
-ia_css_fpn_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *info)
+int ia_css_fpn_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *info)
{
struct ia_css_frame_info my_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO;
const struct ia_css_fpn_configuration config = {
@@ -85,5 +87,5 @@ ia_css_fpn_configure(
my_info.raw_bayer_order = info->raw_bayer_order;
my_info.crop_info = info->crop_info;
- ia_css_configure_fpn(binary, &config);
+ return ia_css_configure_fpn(binary, &config);
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h
index 12187d213d90..bd341fa287fe 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.h
@@ -31,15 +31,11 @@ ia_css_fpn_dump(
const struct sh_css_isp_fpn_params *fpn,
unsigned int level);
-void
-ia_css_fpn_config(
- struct sh_css_isp_fpn_isp_config *to,
- const struct ia_css_fpn_configuration *from,
- unsigned int size);
+int ia_css_fpn_config(struct sh_css_isp_fpn_isp_config *to,
+ const struct ia_css_fpn_configuration *from,
+ unsigned int size);
-void
-ia_css_fpn_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *from);
+int ia_css_fpn_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *from);
#endif /* __IA_CSS_FPN_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c
index 698550cc2fcc..85a02b6adb52 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.c
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
-/* Release Version: irci_ecr-master_20150911_0724 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h
index 04599ab590cd..83277b683c47 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr.host.h
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
-/* Release Version: irci_ecr-master_20150911_0724 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h
index 97a89fd3cfda..998c6d801756 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_param.h
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
-/* Release Version: irci_ecr-master_20150911_0724 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
index 1b4090880201..175c301ee96a 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Release Version: irci_stable_candrpv_0415_20150521_0458 */
-/* Release Version: irci_ecr-master_20150911_0724 */
/*
* Support for Intel Camera Imaging ISP subsystem.
* Copyright (c) 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c
index ea8055148fb3..c7d88552dfde 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c
@@ -22,10 +22,8 @@
#include "ia_css_isp_params.h"
#include "ia_css_frame.h"
-void
-ia_css_bayer_io_config(
- const struct ia_css_binary *binary,
- const struct sh_css_binary_args *args)
+int ia_css_bayer_io_config(const struct ia_css_binary *binary,
+ const struct sh_css_binary_args *args)
{
const struct ia_css_frame *in_frame = args->in_frame;
const struct ia_css_frame **out_frames = (const struct ia_css_frame **)
@@ -38,6 +36,7 @@ ia_css_bayer_io_config(
ddr_bits_per_element);
unsigned int size_get = 0, size_put = 0;
unsigned int offset = 0;
+ int ret;
if (binary->info->mem_offsets.offsets.param) {
size_get = binary->info->mem_offsets.offsets.param->dmem.get.size;
@@ -53,7 +52,9 @@ ia_css_bayer_io_config(
"ia_css_bayer_io_config() get part enter:\n");
#endif
- ia_css_dma_configure_from_info(&config, in_frame_info);
+ ret = ia_css_dma_configure_from_info(&config, in_frame_info);
+ if (ret)
+ return ret;
// The base_address of the input frame will be set in the ISP
to->width = in_frame_info->res.width;
to->height = in_frame_info->res.height;
@@ -79,7 +80,9 @@ ia_css_bayer_io_config(
"ia_css_bayer_io_config() put part enter:\n");
#endif
- ia_css_dma_configure_from_info(&config, &out_frames[0]->info);
+ ret = ia_css_dma_configure_from_info(&config, &out_frames[0]->info);
+ if (ret)
+ return ret;
to->base_address = out_frames[0]->data;
to->width = out_frames[0]->info.res.width;
to->height = out_frames[0]->info.res.height;
@@ -91,4 +94,5 @@ ia_css_bayer_io_config(
"ia_css_bayer_io_config() put part leave:\n");
#endif
}
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h
index 635ccb1b27d0..9c7e5a1ad57b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.h
@@ -21,9 +21,7 @@
#include "ia_css_binary.h"
#include "sh_css_internal.h"
-void
-ia_css_bayer_io_config(
- const struct ia_css_binary *binary,
- const struct sh_css_binary_args *args);
+int ia_css_bayer_io_config(const struct ia_css_binary *binary,
+ const struct sh_css_binary_args *args);
#endif /*__BAYER_IO_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c
index f8bd207b28e1..7d2ef6e26ee6 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c
@@ -22,10 +22,8 @@ more details.
#include "ia_css_isp_params.h"
#include "ia_css_frame.h"
-void
-ia_css_yuv444_io_config(
- const struct ia_css_binary *binary,
- const struct sh_css_binary_args *args)
+int ia_css_yuv444_io_config(const struct ia_css_binary *binary,
+ const struct sh_css_binary_args *args)
{
const struct ia_css_frame *in_frame = args->in_frame;
const struct ia_css_frame **out_frames = (const struct ia_css_frame **)
@@ -38,6 +36,7 @@ ia_css_yuv444_io_config(
ddr_bits_per_element);
unsigned int size_get = 0, size_put = 0;
unsigned int offset = 0;
+ int ret;
if (binary->info->mem_offsets.offsets.param) {
size_get = binary->info->mem_offsets.offsets.param->dmem.get.size;
@@ -53,7 +52,10 @@ ia_css_yuv444_io_config(
"ia_css_yuv444_io_config() get part enter:\n");
#endif
- ia_css_dma_configure_from_info(&config, in_frame_info);
+ ret = ia_css_dma_configure_from_info(&config, in_frame_info);
+ if (ret)
+ return ret;
+
// The base_address of the input frame will be set in the ISP
to->width = in_frame_info->res.width;
to->height = in_frame_info->res.height;
@@ -79,7 +81,10 @@ ia_css_yuv444_io_config(
"ia_css_yuv444_io_config() put part enter:\n");
#endif
- ia_css_dma_configure_from_info(&config, &out_frames[0]->info);
+ ret = ia_css_dma_configure_from_info(&config, &out_frames[0]->info);
+ if (ret)
+ return ret;
+
to->base_address = out_frames[0]->data;
to->width = out_frames[0]->info.res.width;
to->height = out_frames[0]->info.res.height;
@@ -91,4 +96,5 @@ ia_css_yuv444_io_config(
"ia_css_yuv444_io_config() put part leave:\n");
#endif
}
+ return 0;
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
index e7cfd380e108..13e50590f91e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
@@ -21,9 +21,7 @@ more details.
#include "ia_css_binary.h"
#include "sh_css_internal.h"
-void
-ia_css_yuv444_io_config(
- const struct ia_css_binary *binary,
- const struct sh_css_binary_args *args);
+int ia_css_yuv444_io_config(const struct ia_css_binary *binary,
+ const struct sh_css_binary_args *args);
#endif /*__YUV44_IO_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c
index 6d8a35a73750..5f186fb03642 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/iterator/iterator_1.0/ia_css_iterator.host.c
@@ -38,10 +38,9 @@ ia_css_iterator_config(
ia_css_resolution_to_sp_resolution(&to->dvs_envelope, from->dvs_envelope);
}
-int
-ia_css_iterator_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *in_info) {
+int ia_css_iterator_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *in_info)
+{
struct ia_css_frame_info my_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO;
struct ia_css_iterator_configuration config = default_config;
@@ -75,7 +74,5 @@ ia_css_iterator_configure(
my_info.res.height <<= binary->vf_downscale_log2;
}
- ia_css_configure_iterator(binary, &config);
-
- return 0;
+ return ia_css_configure_iterator(binary, &config);
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c
index c8e074f42353..be9e4ef29fce 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.c
@@ -52,49 +52,45 @@ ia_css_output_encode(
to->enable_vflip = from->enable_vflip;
}
-void
-ia_css_output_config(
- struct sh_css_isp_output_isp_config *to,
- const struct ia_css_output_configuration *from,
- unsigned int size)
+int ia_css_output_config(struct sh_css_isp_output_isp_config *to,
+ const struct ia_css_output_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS;
+ int ret;
+
+ ret = ia_css_dma_configure_from_info(&to->port_b, from->info);
+ if (ret)
+ return ret;
- (void)size;
- ia_css_dma_configure_from_info(&to->port_b, from->info);
to->width_a_over_b = elems_a / to->port_b.elems;
to->height = from->info ? from->info->res.height : 0;
to->enable = from->info != NULL;
ia_css_frame_info_to_frame_sp_info(&to->info, from->info);
/* Assume divisiblity here, may need to generalize to fixed point. */
- assert(elems_a % to->port_b.elems == 0);
+ if (elems_a % to->port_b.elems != 0)
+ return -EINVAL;
+
+ return 0;
}
-void
-ia_css_output0_config(
- struct sh_css_isp_output_isp_config *to,
- const struct ia_css_output0_configuration *from,
- unsigned int size)
+int ia_css_output0_config(struct sh_css_isp_output_isp_config *to,
+ const struct ia_css_output0_configuration *from,
+ unsigned int size)
{
- ia_css_output_config(
- to, (const struct ia_css_output_configuration *)from, size);
+ return ia_css_output_config(to, (const struct ia_css_output_configuration *)from, size);
}
-void
-ia_css_output1_config(
- struct sh_css_isp_output_isp_config *to,
- const struct ia_css_output1_configuration *from,
- unsigned int size)
+int ia_css_output1_config(struct sh_css_isp_output_isp_config *to,
+ const struct ia_css_output1_configuration *from,
+ unsigned int size)
{
- ia_css_output_config(
- to, (const struct ia_css_output_configuration *)from, size);
+ return ia_css_output_config(to, (const struct ia_css_output_configuration *)from, size);
}
-void
-ia_css_output_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *info)
+int ia_css_output_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *info)
{
if (info) {
struct ia_css_output_configuration config =
@@ -102,14 +98,13 @@ ia_css_output_configure(
config.info = info;
- ia_css_configure_output(binary, &config);
+ return ia_css_configure_output(binary, &config);
}
+ return 0;
}
-void
-ia_css_output0_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *info)
+int ia_css_output0_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *info)
{
if (info) {
struct ia_css_output0_configuration config =
@@ -117,14 +112,13 @@ ia_css_output0_configure(
config.info = info;
- ia_css_configure_output0(binary, &config);
+ return ia_css_configure_output0(binary, &config);
}
+ return 0;
}
-void
-ia_css_output1_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *info)
+int ia_css_output1_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *info)
{
if (info) {
struct ia_css_output1_configuration config =
@@ -132,8 +126,9 @@ ia_css_output1_configure(
config.info = info;
- ia_css_configure_output1(binary, &config);
+ return ia_css_configure_output1(binary, &config);
}
+ return 0;
}
void
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h
index 1f5a2242640e..c8523e95a394 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/output/output_1.0/ia_css_output.host.h
@@ -30,38 +30,26 @@ ia_css_output_encode(
const struct ia_css_output_config *from,
unsigned int size);
-void
-ia_css_output_config(
- struct sh_css_isp_output_isp_config *to,
- const struct ia_css_output_configuration *from,
- unsigned int size);
+int ia_css_output_config(struct sh_css_isp_output_isp_config *to,
+ const struct ia_css_output_configuration *from,
+ unsigned int size);
-void
-ia_css_output0_config(
- struct sh_css_isp_output_isp_config *to,
- const struct ia_css_output0_configuration *from,
- unsigned int size);
+int ia_css_output0_config(struct sh_css_isp_output_isp_config *to,
+ const struct ia_css_output0_configuration *from,
+ unsigned int size);
-void
-ia_css_output1_config(
- struct sh_css_isp_output_isp_config *to,
- const struct ia_css_output1_configuration *from,
- unsigned int size);
+int ia_css_output1_config(struct sh_css_isp_output_isp_config *to,
+ const struct ia_css_output1_configuration *from,
+ unsigned int size);
-void
-ia_css_output_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *from);
+int ia_css_output_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *from);
-void
-ia_css_output0_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *from);
+int ia_css_output0_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *from);
-void
-ia_css_output1_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *from);
+int ia_css_output1_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *from);
void
ia_css_output_dump(
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c
index 1603fd44ece3..9fd4435e96b0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.c
@@ -28,35 +28,37 @@ static const struct ia_css_qplane_configuration default_config = {
.pipe = (struct sh_css_sp_pipeline *)NULL,
};
-void
-ia_css_qplane_config(
- struct sh_css_isp_qplane_isp_config *to,
- const struct ia_css_qplane_configuration *from,
- unsigned int size)
+int ia_css_qplane_config(struct sh_css_isp_qplane_isp_config *to,
+ const struct ia_css_qplane_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS;
+ int ret;
+
+ ret = ia_css_dma_configure_from_info(&to->port_b, from->info);
+ if (ret)
+ return ret;
- (void)size;
- ia_css_dma_configure_from_info(&to->port_b, from->info);
to->width_a_over_b = elems_a / to->port_b.elems;
/* Assume divisiblity here, may need to generalize to fixed point. */
- assert(elems_a % to->port_b.elems == 0);
+ if (elems_a % to->port_b.elems != 0)
+ return -EINVAL;
to->inout_port_config = from->pipe->inout_port_config;
to->format = from->info->format;
+
+ return 0;
}
-void
-ia_css_qplane_configure(
- const struct sh_css_sp_pipeline *pipe,
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *info)
+int ia_css_qplane_configure(const struct sh_css_sp_pipeline *pipe,
+ const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *info)
{
struct ia_css_qplane_configuration config = default_config;
config.pipe = pipe;
config.info = info;
- ia_css_configure_qplane(binary, &config);
+ return ia_css_configure_qplane(binary, &config);
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h
index 8d940959f40a..b3f8fa30c8ce 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/qplane/qplane_2/ia_css_qplane.host.h
@@ -29,16 +29,12 @@
#include "ia_css_qplane_types.h"
#include "ia_css_qplane_param.h"
-void
-ia_css_qplane_config(
- struct sh_css_isp_qplane_isp_config *to,
- const struct ia_css_qplane_configuration *from,
- unsigned int size);
+int ia_css_qplane_config(struct sh_css_isp_qplane_isp_config *to,
+ const struct ia_css_qplane_configuration *from,
+ unsigned int size);
-void
-ia_css_qplane_configure(
- const struct sh_css_sp_pipeline *pipe,
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *from);
+int ia_css_qplane_configure(const struct sh_css_sp_pipeline *pipe,
+ const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *from);
#endif /* __IA_CSS_QPLANE_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c
index c505c94a7241..646d6e39c1e5 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.c
@@ -29,12 +29,6 @@ static const struct ia_css_raw_configuration default_config = {
.pipe = (struct sh_css_sp_pipeline *)NULL,
};
-static inline unsigned
-sh_css_elems_bytes_from_info(unsigned int raw_bit_depth)
-{
- return CEIL_DIV(raw_bit_depth, 8);
-}
-
/* MW: These areMIPI / ISYS properties, not camera function properties */
static enum sh_stream_format
css2isp_stream_format(enum atomisp_input_format from) {
@@ -70,17 +64,15 @@ css2isp_stream_format(enum atomisp_input_format from) {
}
}
-void
-ia_css_raw_config(
- struct sh_css_isp_raw_isp_config *to,
- const struct ia_css_raw_configuration *from,
- unsigned int size)
+int ia_css_raw_config(struct sh_css_isp_raw_isp_config *to,
+ const struct ia_css_raw_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS;
const struct ia_css_frame_info *in_info = from->in_info;
const struct ia_css_frame_info *internal_info = from->internal_info;
+ int ret;
- (void)size;
#if !defined(ISP2401)
/* 2401 input system uses input width width */
in_info = internal_info;
@@ -92,7 +84,9 @@ ia_css_raw_config(
in_info = internal_info;
#endif
- ia_css_dma_configure_from_info(&to->port_b, in_info);
+ ret = ia_css_dma_configure_from_info(&to->port_b, in_info);
+ if (ret)
+ return ret;
/* Assume divisiblity here, may need to generalize to fixed point. */
assert((in_info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) ||
@@ -110,16 +104,16 @@ ia_css_raw_config(
to->start_line = in_info->crop_info.start_line;
to->enable_left_padding = from->enable_left_padding;
#endif
+
+ return 0;
}
-void
-ia_css_raw_configure(
- const struct sh_css_sp_pipeline *pipe,
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *in_info,
- const struct ia_css_frame_info *internal_info,
- bool two_ppc,
- bool deinterleaved)
+int ia_css_raw_configure(const struct sh_css_sp_pipeline *pipe,
+ const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *in_info,
+ const struct ia_css_frame_info *internal_info,
+ bool two_ppc,
+ bool deinterleaved)
{
u8 enable_left_padding = (uint8_t)((binary->left_padding) ? 1 : 0);
struct ia_css_raw_configuration config = default_config;
@@ -132,5 +126,5 @@ ia_css_raw_configure(
config.deinterleaved = deinterleaved;
config.enable_left_padding = enable_left_padding;
- ia_css_configure_raw(binary, &config);
+ return ia_css_configure_raw(binary, &config);
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h
index 346928435a8b..23da51aabc8d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw/raw_1.0/ia_css_raw.host.h
@@ -21,19 +21,15 @@
#include "ia_css_raw_types.h"
#include "ia_css_raw_param.h"
-void
-ia_css_raw_config(
- struct sh_css_isp_raw_isp_config *to,
- const struct ia_css_raw_configuration *from,
- unsigned int size);
+int ia_css_raw_config(struct sh_css_isp_raw_isp_config *to,
+ const struct ia_css_raw_configuration *from,
+ unsigned int size);
-void
-ia_css_raw_configure(
- const struct sh_css_sp_pipeline *pipe,
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *in_info,
- const struct ia_css_frame_info *internal_info,
- bool two_ppc,
- bool deinterleaved);
+int ia_css_raw_configure(const struct sh_css_sp_pipeline *pipe,
+ const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *in_info,
+ const struct ia_css_frame_info *internal_info,
+ bool two_ppc,
+ bool deinterleaved);
#endif /* __IA_CSS_RAW_HOST_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
index 29c707ecf9f3..9b756daddee0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/raw_aa_binning/raw_aa_binning_1.0/ia_css_raa.host.c
@@ -13,7 +13,6 @@
* more details.
*/
-#if !defined(HAS_NO_HMEM)
#include "ia_css_types.h"
#include "sh_css_internal.h"
@@ -32,4 +31,3 @@ ia_css_raa_encode(
(void)from;
}
-#endif
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c
index 061558fbe329..08ed916a7eb8 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.c
@@ -22,16 +22,17 @@
#include "isp.h"
#include "ia_css_ref.host.h"
-void
-ia_css_ref_config(
- struct sh_css_isp_ref_isp_config *to,
- const struct ia_css_ref_configuration *from,
- unsigned int size)
+int ia_css_ref_config(struct sh_css_isp_ref_isp_config *to,
+ const struct ia_css_ref_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS, i;
+ int ret;
if (from->ref_frames[0]) {
- ia_css_dma_configure_from_info(&to->port_b, &from->ref_frames[0]->info);
+ ret = ia_css_dma_configure_from_info(&to->port_b, &from->ref_frames[0]->info);
+ if (ret)
+ return ret;
to->width_a_over_b = elems_a / to->port_b.elems;
to->dvs_frame_delay = from->dvs_frame_delay;
} else {
@@ -52,22 +53,25 @@ ia_css_ref_config(
}
/* Assume divisiblity here, may need to generalize to fixed point. */
- assert(elems_a % to->port_b.elems == 0);
+ if (elems_a % to->port_b.elems != 0)
+ return -EINVAL;
+
+ return 0;
}
-void
-ia_css_ref_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame * const *ref_frames,
- const uint32_t dvs_frame_delay)
+int ia_css_ref_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame * const *ref_frames,
+ const uint32_t dvs_frame_delay)
{
struct ia_css_ref_configuration config;
unsigned int i;
for (i = 0; i < MAX_NUM_VIDEO_DELAY_FRAMES; i++)
config.ref_frames[i] = ref_frames[i];
+
config.dvs_frame_delay = dvs_frame_delay;
- ia_css_configure_ref(binary, &config);
+
+ return ia_css_configure_ref(binary, &config);
}
void
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h
index 3ce590b436a1..388cd4c367ba 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ref/ref_1.0/ia_css_ref.host.h
@@ -23,17 +23,13 @@
#include "ia_css_ref_param.h"
#include "ia_css_ref_state.h"
-void
-ia_css_ref_config(
- struct sh_css_isp_ref_isp_config *to,
- const struct ia_css_ref_configuration *from,
- unsigned int size);
+int ia_css_ref_config(struct sh_css_isp_ref_isp_config *to,
+ const struct ia_css_ref_configuration *from,
+ unsigned int size);
-void
-ia_css_ref_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame * const *ref_frames,
- const uint32_t dvs_frame_delay);
+int ia_css_ref_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame * const *ref_frames,
+ const uint32_t dvs_frame_delay);
void
ia_css_init_ref_state(
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
index ba52c80df4a5..bd7b89d9475b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c
@@ -227,10 +227,6 @@ ia_css_s3a_hmem_decode(
struct ia_css_3a_statistics *host_stats,
const struct ia_css_bh_table *hmem_buf)
{
-#if defined(HAS_NO_HMEM)
- (void)host_stats;
- (void)hmem_buf;
-#else
struct ia_css_3a_rgby_output *out_ptr;
int i;
@@ -291,7 +287,6 @@ ia_css_s3a_hmem_decode(
out_ptr[0].g -= diff;
out_ptr[0].b -= diff;
out_ptr[0].y -= diff;
-#endif
}
void
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c
index f3fb4b9b3c82..6974b3424d91 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.c
@@ -23,35 +23,6 @@
#include "ia_css_sc.host.h"
-/* Code generated by genparam/genconfig.c:gen_configure_function() */
-
-/* ISP2401 */
-static void
-ia_css_configure_sc(
- const struct ia_css_binary *binary,
- const struct ia_css_sc_configuration *config_dmem)
-{
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_sc() enter:\n");
-
- {
- unsigned int offset = 0;
- unsigned int size = 0;
-
- if (binary->info->mem_offsets.offsets.config) {
- size = binary->info->mem_offsets.offsets.config->dmem.sc.size;
- offset = binary->info->mem_offsets.offsets.config->dmem.sc.offset;
- }
- if (size) {
- ia_css_sc_config((struct sh_css_isp_sc_isp_config *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_CONFIG][IA_CSS_ISP_DMEM].address[offset],
- config_dmem, size);
- }
- }
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "ia_css_configure_sc() leave:\n");
-}
-
void
ia_css_sc_encode(
struct sh_css_isp_sc_params *to,
@@ -73,45 +44,6 @@ ia_css_sc_dump(
"sc_gain_shift", sc->gain_shift);
}
-/* ISP2401 */
-void
-ia_css_sc_config(
- struct sh_css_isp_sc_isp_config *to,
- const struct ia_css_sc_configuration *from,
- unsigned int size)
-{
- u32 internal_org_x_bqs = from->internal_frame_origin_x_bqs_on_sctbl;
- u32 internal_org_y_bqs = from->internal_frame_origin_y_bqs_on_sctbl;
- u32 slice, rest, i;
-
- (void)size;
-
- /* The internal_frame_origin_x_bqs_on_sctbl is separated to 8 times of slice_vec. */
- rest = internal_org_x_bqs;
- for (i = 0; i < SH_CSS_SC_INTERPED_GAIN_HOR_SLICE_TIMES; i++) {
- slice = min(rest, ((uint32_t)ISP_SLICE_NELEMS));
- rest = rest - slice;
- to->interped_gain_hor_slice_bqs[i] = slice;
- }
-
- to->internal_frame_origin_y_bqs_on_sctbl = internal_org_y_bqs;
-}
-
-/* ISP2401 */
-void
-ia_css_sc_configure(
- const struct ia_css_binary *binary,
- u32 internal_frame_origin_x_bqs_on_sctbl,
- uint32_t internal_frame_origin_y_bqs_on_sctbl)
-{
- const struct ia_css_sc_configuration config = {
- internal_frame_origin_x_bqs_on_sctbl,
- internal_frame_origin_y_bqs_on_sctbl
- };
-
- ia_css_configure_sc(binary, &config);
-}
-
/* ------ deprecated(bz675) : from ------ */
/* It looks like @parameter{} (in *.pipe) is used to generate the process/get/set functions,
for parameters which should be used in the isp kernels.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h
index f1eb568f23d4..d103103c9a87 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc.host.h
@@ -32,39 +32,6 @@ ia_css_sc_dump(
const struct sh_css_isp_sc_params *sc,
unsigned int level);
-/* @brief Configure the shading correction.
- * @param[out] to Parameters used in the shading correction kernel in the isp.
- * @param[in] from Parameters passed from the host.
- * @param[in] size Size of the sh_css_isp_sc_isp_config structure.
- *
- * This function passes the parameters for the shading correction from the host to the isp.
- */
-/* ISP2401 */
-void
-ia_css_sc_config(
- struct sh_css_isp_sc_isp_config *to,
- const struct ia_css_sc_configuration *from,
- unsigned int size);
-
-/* @brief Configure the shading correction.
- * @param[in] binary The binary, which has the shading correction.
- * @param[in] internal_frame_origin_x_bqs_on_sctbl
- * X coordinate (in bqs) of the origin of the internal frame on the shading table.
- * @param[in] internal_frame_origin_y_bqs_on_sctbl
- * Y coordinate (in bqs) of the origin of the internal frame on the shading table.
- *
- * This function calls the ia_css_configure_sc() function.
- * (The ia_css_configure_sc() function is automatically generated in ia_css_isp.configs.c.)
- * The ia_css_configure_sc() function calls the ia_css_sc_config() function
- * to pass the parameters for the shading correction from the host to the isp.
- */
-/* ISP2401 */
-void
-ia_css_sc_configure(
- const struct ia_css_binary *binary,
- u32 internal_frame_origin_x_bqs_on_sctbl,
- uint32_t internal_frame_origin_y_bqs_on_sctbl);
-
/* ------ deprecated(bz675) : from ------ */
void
sh_css_get_shading_settings(const struct ia_css_isp_parameters *params,
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h
index aae534521b7b..1d70f6b9a0ec 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_types.h
@@ -118,18 +118,4 @@ struct ia_css_shading_settings {
/* ------ deprecated(bz675) : to ------ */
-/* Shading Correction configuration.
- *
- * NOTE: The shading table size is larger than or equal to the internal frame size.
- */
-/* ISP2401 */
-struct ia_css_sc_configuration {
- u32 internal_frame_origin_x_bqs_on_sctbl; /** Origin X (in bqs) of internal frame on shading table. */
- u32 internal_frame_origin_y_bqs_on_sctbl; /** Origin Y (in bqs) of internal frame on shading table. */
- /** NOTE: bqs = size in BQ(Bayer Quad) unit.
- 1BQ means {Gr,R,B,Gb}(2x2 pixels).
- Horizontal 1 bqs corresponds to horizontal 2 pixels.
- Vertical 1 bqs corresponds to vertical 2 pixels. */
-};
-
#endif /* __IA_CSS_SC_TYPES_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c
index ac80e6c6e67e..53050c0c49fc 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.c
@@ -71,40 +71,41 @@ ia_css_tnr_debug_dtrace(
config->threshold_y, config->threshold_uv);
}
-void
-ia_css_tnr_config(
- struct sh_css_isp_tnr_isp_config *to,
- const struct ia_css_tnr_configuration *from,
- unsigned int size)
+int ia_css_tnr_config(struct sh_css_isp_tnr_isp_config *to,
+ const struct ia_css_tnr_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS;
unsigned int i;
+ int ret;
- (void)size;
- ia_css_dma_configure_from_info(&to->port_b, &from->tnr_frames[0]->info);
+ ret = ia_css_dma_configure_from_info(&to->port_b, &from->tnr_frames[0]->info);
+ if (ret)
+ return ret;
to->width_a_over_b = elems_a / to->port_b.elems;
to->frame_height = from->tnr_frames[0]->info.res.height;
- for (i = 0; i < NUM_TNR_FRAMES; i++) {
+ for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++) {
to->tnr_frame_addr[i] = from->tnr_frames[i]->data +
from->tnr_frames[i]->planes.yuyv.offset;
}
/* Assume divisiblity here, may need to generalize to fixed point. */
- assert(elems_a % to->port_b.elems == 0);
+ if (elems_a % to->port_b.elems != 0)
+ return -EINVAL;
+
+ return 0;
}
-void
-ia_css_tnr_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame * const *frames)
+int ia_css_tnr_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame * const *frames)
{
struct ia_css_tnr_configuration config;
unsigned int i;
- for (i = 0; i < NUM_TNR_FRAMES; i++)
+ for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++)
config.tnr_frames[i] = frames[i];
- ia_css_configure_tnr(binary, &config);
+ return ia_css_configure_tnr(binary, &config);
}
void
@@ -114,7 +115,7 @@ ia_css_init_tnr_state(
{
(void)size;
- assert(NUM_TNR_FRAMES >= 2);
+ assert(NUM_VIDEO_TNR_FRAMES >= 2);
assert(sizeof(*state) == size);
state->tnr_in_buf_idx = 0;
state->tnr_out_buf_idx = 1;
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h
index 90d6e6b44a8d..acf92052b442 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr.host.h
@@ -39,16 +39,12 @@ ia_css_tnr_debug_dtrace(
const struct ia_css_tnr_config *config,
unsigned int level);
-void
-ia_css_tnr_config(
- struct sh_css_isp_tnr_isp_config *to,
- const struct ia_css_tnr_configuration *from,
- unsigned int size);
+int ia_css_tnr_config(struct sh_css_isp_tnr_isp_config *to,
+ const struct ia_css_tnr_configuration *from,
+ unsigned int size);
-void
-ia_css_tnr_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame * const *frames);
+int ia_css_tnr_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame * const *frames);
void
ia_css_init_tnr_state(
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h
index 60a2542cf685..551dd5cfa9f1 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr_1.0/ia_css_tnr_param.h
@@ -28,14 +28,14 @@ struct sh_css_isp_tnr_params {
};
struct ia_css_tnr_configuration {
- const struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES];
+ const struct ia_css_frame *tnr_frames[NUM_VIDEO_TNR_FRAMES];
};
struct sh_css_isp_tnr_isp_config {
u32 width_a_over_b;
u32 frame_height;
struct dma_port_config port_b;
- ia_css_ptr tnr_frame_addr[NUM_TNR_FRAMES];
+ ia_css_ptr tnr_frame_addr[NUM_VIDEO_TNR_FRAMES];
};
#endif /* __IA_CSS_TNR_PARAM_H */
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c
index dd3670972936..aecdcbe04ce1 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c
@@ -26,26 +26,28 @@
#include "isp.h"
-void
-ia_css_vf_config(
- struct sh_css_isp_vf_isp_config *to,
- const struct ia_css_vf_configuration *from,
- unsigned int size)
+int ia_css_vf_config(struct sh_css_isp_vf_isp_config *to,
+ const struct ia_css_vf_configuration *from,
+ unsigned int size)
{
unsigned int elems_a = ISP_VEC_NELEMS;
+ int ret;
- (void)size;
to->vf_downscale_bits = from->vf_downscale_bits;
to->enable = from->info != NULL;
if (from->info) {
ia_css_frame_info_to_frame_sp_info(&to->info, from->info);
- ia_css_dma_configure_from_info(&to->dma.port_b, from->info);
+ ret = ia_css_dma_configure_from_info(&to->dma.port_b, from->info);
+ if (ret)
+ return ret;
to->dma.width_a_over_b = elems_a / to->dma.port_b.elems;
/* Assume divisiblity here, may need to generalize to fixed point. */
- assert(elems_a % to->dma.port_b.elems == 0);
+ if (elems_a % to->dma.port_b.elems != 0)
+ return -EINVAL;
}
+ return 0;
}
/* compute the log2 of the downscale factor needed to get closest
@@ -120,12 +122,11 @@ configure_dma(
config->info = vf_info;
}
-int
-ia_css_vf_configure(
- const struct ia_css_binary *binary,
- const struct ia_css_frame_info *out_info,
- struct ia_css_frame_info *vf_info,
- unsigned int *downscale_log2) {
+int ia_css_vf_configure(const struct ia_css_binary *binary,
+ const struct ia_css_frame_info *out_info,
+ struct ia_css_frame_info *vf_info,
+ unsigned int *downscale_log2)
+{
int err;
struct ia_css_vf_configuration config;
const struct ia_css_binary_info *info = &binary->info->sp;
@@ -138,7 +139,6 @@ ia_css_vf_configure(
if (vf_info)
vf_info->raw_bit_depth = info->dma.vfdec_bits_per_pixel;
- ia_css_configure_vf(binary, &config);
- return 0;
+ return ia_css_configure_vf(binary, &config);
}
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h
index 0e8de034a00e..d6b45d3754b0 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.h
@@ -32,11 +32,9 @@ sh_css_vf_downscale_log2(
const struct ia_css_frame_info *vf_info,
unsigned int *downscale_log2);
-void
-ia_css_vf_config(
- struct sh_css_isp_vf_isp_config *to,
- const struct ia_css_vf_configuration *from,
- unsigned int size);
+int ia_css_vf_config(struct sh_css_isp_vf_isp_config *to,
+ const struct ia_css_vf_configuration *from,
+ unsigned int size);
int
ia_css_vf_configure(
diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h
index 11e439d838ae..bfe4f5976771 100644
--- a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h
+++ b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h
@@ -36,17 +36,7 @@ more details.
#define BITS8_ELEMENTS_PER_XMEM_ADDR CEIL_DIV(XMEM_WIDTH_BITS, 8)
#define BITS16_ELEMENTS_PER_XMEM_ADDR CEIL_DIV(XMEM_WIDTH_BITS, 16)
-#if ISP_VEC_NELEMS == 64
#define ISP_NWAY_LOG2 6
-#elif ISP_VEC_NELEMS == 32
-#define ISP_NWAY_LOG2 5
-#elif ISP_VEC_NELEMS == 16
-#define ISP_NWAY_LOG2 4
-#elif ISP_VEC_NELEMS == 8
-#define ISP_NWAY_LOG2 3
-#else
-#error "isp_const.h ISP_VEC_NELEMS must be one of {8, 16, 32, 64}"
-#endif
/* *****************************
* ISP input/output buffer sizes
@@ -164,9 +154,9 @@ more details.
/* [isp vmem] table size[vectors] per line per color (GR,R,B,GB),
multiples of NWAY */
#define ISP2400_SCTBL_VECTORS_PER_LINE_PER_COLOR \
- CEIL_DIV(ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
+ CEIL_DIV(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
#define ISP2401_SCTBL_VECTORS_PER_LINE_PER_COLOR \
- CEIL_DIV(ISP2401_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
+ CEIL_DIV(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
/* [isp vmem] table size[vectors] per line for 4colors (GR,R,B,GB),
multiples of NWAY */
#define SCTBL_VECTORS_PER_LINE \
diff --git a/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h b/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h
index 2614b89b8e34..6880c9b6aa65 100644
--- a/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h
+++ b/drivers/staging/media/atomisp/pci/isp2400_input_system_local.h
@@ -16,10 +16,6 @@
#ifndef __INPUT_SYSTEM_LOCAL_H_INCLUDED__
#define __INPUT_SYSTEM_LOCAL_H_INCLUDED__
-#include <type_support.h>
-
-#include "input_system_global.h"
-
#include "input_system_defs.h" /* HIVE_ISYS_GPREG_MULTICAST_A_IDX,... */
/*
@@ -33,54 +29,7 @@
#include "isp_acquisition_defs.h"
#include "input_system_ctrl_defs.h"
-typedef enum {
- INPUT_SYSTEM_PORT_A = 0,
- INPUT_SYSTEM_PORT_B,
- INPUT_SYSTEM_PORT_C,
- N_INPUT_SYSTEM_PORTS
-} input_system_csi_port_t;
-
-typedef struct ctrl_unit_cfg_s ctrl_unit_cfg_t;
-typedef struct input_system_network_cfg_s input_system_network_cfg_t;
-typedef struct target_cfg2400_s target_cfg2400_t;
-typedef struct channel_cfg_s channel_cfg_t;
-typedef struct backend_channel_cfg_s backend_channel_cfg_t;
typedef struct input_system_cfg2400_s input_system_cfg2400_t;
-typedef struct mipi_port_state_s mipi_port_state_t;
-typedef struct rx_channel_state_s rx_channel_state_t;
-typedef struct input_switch_cfg_channel_s input_switch_cfg_channel_t;
-typedef struct input_switch_cfg_s input_switch_cfg_t;
-
-struct ctrl_unit_cfg_s {
- isp2400_ib_buffer_t buffer_mipi[N_CAPTURE_UNIT_ID];
- isp2400_ib_buffer_t buffer_acquire[N_ACQUISITION_UNIT_ID];
-};
-
-struct input_system_network_cfg_s {
- input_system_connection_t multicast_cfg[N_CAPTURE_UNIT_ID];
- input_system_multiplex_t mux_cfg;
- ctrl_unit_cfg_t ctrl_unit_cfg[N_CTRL_UNIT_ID];
-};
-
-typedef struct {
-// TBD.
- u32 dummy_parameter;
-} target_isp_cfg_t;
-
-typedef struct {
-// TBD.
- u32 dummy_parameter;
-} target_sp_cfg_t;
-
-typedef struct {
-// TBD.
- u32 dummy_parameter;
-} target_strm2mem_cfg_t;
-
-struct input_switch_cfg_channel_s {
- u32 hsync_data_reg[2];
- u32 vsync_data_reg;
-};
struct target_cfg2400_s {
input_switch_cfg_channel_t input_switch_channel_cfg;
@@ -89,24 +38,6 @@ struct target_cfg2400_s {
target_strm2mem_cfg_t target_strm2mem_cfg;
};
-struct backend_channel_cfg_s {
- u32 fmt_control_word_1; // Format config.
- u32 fmt_control_word_2;
- u32 no_side_band;
-};
-
-typedef union {
- csi_cfg_t csi_cfg;
- tpg_cfg_t tpg_cfg;
- prbs_cfg_t prbs_cfg;
- gpfifo_cfg_t gpfifo_cfg;
-} source_cfg_t;
-
-struct input_switch_cfg_s {
- u32 hsync_data_reg[N_RX_CHANNEL_ID * 2];
- u32 vsync_data_reg;
-};
-
// Configuration of a channel.
struct channel_cfg_s {
u32 ch_id;
@@ -238,47 +169,6 @@ typedef struct capture_unit_state_s capture_unit_state_t;
typedef struct acquisition_unit_state_s acquisition_unit_state_t;
typedef struct ctrl_unit_state_s ctrl_unit_state_t;
-/*
- * In 2300 ports can be configured independently and stream
- * formats need to be specified. In 2400, there are only 8
- * supported configurations but the HW is fused to support
- * only a single one.
- *
- * In 2300 the compressed format types are programmed by the
- * user. In 2400 all stream formats are encoded on the stream.
- *
- * Use the enum to check validity of a user configuration
- */
-typedef enum {
- MONO_4L_1L_0L = 0,
- MONO_3L_1L_0L,
- MONO_2L_1L_0L,
- MONO_1L_1L_0L,
- STEREO_2L_1L_2L,
- STEREO_3L_1L_1L,
- STEREO_2L_1L_1L,
- STEREO_1L_1L_1L,
- N_RX_MODE
-} rx_mode_t;
-
-typedef enum {
- MIPI_PREDICTOR_NONE = 0,
- MIPI_PREDICTOR_TYPE1,
- MIPI_PREDICTOR_TYPE2,
- N_MIPI_PREDICTOR_TYPES
-} mipi_predictor_t;
-
-typedef enum {
- MIPI_COMPRESSOR_NONE = 0,
- MIPI_COMPRESSOR_10_6_10,
- MIPI_COMPRESSOR_10_7_10,
- MIPI_COMPRESSOR_10_8_10,
- MIPI_COMPRESSOR_12_6_12,
- MIPI_COMPRESSOR_12_7_12,
- MIPI_COMPRESSOR_12_8_12,
- N_MIPI_COMPRESSOR_METHODS
-} mipi_compressor_t;
-
typedef enum {
MIPI_FORMAT_RGB888 = 0,
MIPI_FORMAT_RGB555,
@@ -339,22 +229,6 @@ typedef enum {
RX_IRQ_INFO_ERR_LINE_SYNC = 1UL << _HRT_CSS_RECEIVER_IRQ_ERR_LINE_SYNC_BIT,
} rx_irq_info_t;
-typedef struct rx_cfg_s rx_cfg_t;
-
-/*
- * Applied per port
- */
-struct rx_cfg_s {
- rx_mode_t mode; /* The HW config */
- enum mipi_port_id port; /* The port ID to apply the control on */
- unsigned int timeout;
- unsigned int initcount;
- unsigned int synccount;
- unsigned int rxcount;
- mipi_predictor_t comp; /* Just for backward compatibility */
- bool is_two_ppc;
-};
-
/* NOTE: The base has already an offset of 0x0100 */
static const hrt_address __maybe_unused MIPI_PORT_OFFSET[N_MIPI_PORT_ID] = {
0x00000000UL,
diff --git a/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h b/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h
index f38773842646..e3c86069b390 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h
+++ b/drivers/staging/media/atomisp/pci/isp2401_input_system_global.h
@@ -44,11 +44,6 @@ typedef enum {
N_INPUT_SYSTEM_SOURCE_TYPE
} input_system_source_type_t;
-typedef enum {
- INPUT_SYSTEM_POLL_ON_WAIT_FOR_FRAME,
- INPUT_SYSTEM_POLL_ON_CAPTURE_REQUEST,
-} input_system_polling_mode_t;
-
typedef struct input_system_channel_s input_system_channel_t;
struct input_system_channel_s {
stream2mmio_ID_t stream2mmio_id;
@@ -111,9 +106,6 @@ struct isp2401_input_system_cfg_s {
input_system_source_type_t mode;
- /* ISP2401 */
- input_system_polling_mode_t polling_mode;
-
bool online;
bool raw_packed;
s8 linked_isys_stream_id;
@@ -165,10 +157,6 @@ struct virtual_input_system_stream_s {
u8 online;
s8 linked_isys_stream_id;
u8 valid;
-
- /* ISP2401 */
- input_system_polling_mode_t polling_mode;
- s32 subscr_index;
};
typedef struct virtual_input_system_stream_cfg_s
diff --git a/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h b/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h
index 24026090cd35..74bfa10e670e 100644
--- a/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h
+++ b/drivers/staging/media/atomisp/pci/isp2401_input_system_local.h
@@ -16,9 +16,6 @@
#ifndef __INPUT_SYSTEM_LOCAL_H_INCLUDED__
#define __INPUT_SYSTEM_LOCAL_H_INCLUDED__
-#include "type_support.h"
-#include "input_system_global.h"
-
#include "csi_rx.h"
#include "pixelgen.h"
#include "isys_stream2mmio.h"
@@ -69,29 +66,6 @@ typedef enum {
/* The number of stores for compressed format types */
#define N_MIPI_COMPRESSOR_CONTEXT (N_RX_CHANNEL_ID * N_MIPI_FORMAT_CUSTOM)
-#define UNCOMPRESSED_BITS_PER_PIXEL_10 10
-#define UNCOMPRESSED_BITS_PER_PIXEL_12 12
-#define COMPRESSED_BITS_PER_PIXEL_6 6
-#define COMPRESSED_BITS_PER_PIXEL_7 7
-#define COMPRESSED_BITS_PER_PIXEL_8 8
-enum mipi_compressor {
- MIPI_COMPRESSOR_NONE = 0,
- MIPI_COMPRESSOR_10_6_10,
- MIPI_COMPRESSOR_10_7_10,
- MIPI_COMPRESSOR_10_8_10,
- MIPI_COMPRESSOR_12_6_12,
- MIPI_COMPRESSOR_12_7_12,
- MIPI_COMPRESSOR_12_8_12,
- N_MIPI_COMPRESSOR_METHODS
-};
-
-typedef enum {
- MIPI_PREDICTOR_NONE = 0,
- MIPI_PREDICTOR_TYPE1,
- MIPI_PREDICTOR_TYPE2,
- N_MIPI_PREDICTOR_TYPES
-} mipi_predictor_t;
-
typedef struct input_system_state_s input_system_state_t;
struct input_system_state_s {
ibuf_ctrl_state_t ibuf_ctrl_state[N_IBUF_CTRL_ID];
diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h b/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
index b44099dbdacd..9935ac860bc2 100644
--- a/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
+++ b/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
@@ -94,7 +94,6 @@ struct ia_css_binary_descr {
bool enable_dpc;
/* ISP2401 */
- bool enable_luma_only;
bool enable_tnr;
bool enable_capture_pp_bli;
@@ -131,8 +130,6 @@ struct ia_css_binary {
int sctbl_width_per_color;
int sctbl_aligned_width_per_color;
int sctbl_height;
- int sctbl_legacy_width_per_color;
- int sctbl_legacy_height;
struct ia_css_sdis_info dis;
struct ia_css_resolution dvs_envelope;
bool online;
diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
index 060d38749570..406ed5fb4c6a 100644
--- a/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
+++ b/drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
@@ -108,7 +108,6 @@ ia_css_binary_internal_res(const struct ia_css_frame_info *in_info,
binary_dvs_env.height);
}
-/* ISP2400 */
/* Computation results of the origin coordinate of bayer on the shading table. */
struct sh_css_shading_table_bayer_origin_compute_results {
u32 bayer_scale_hor_ratio_in; /* Horizontal ratio (in) of bayer scaling. */
@@ -119,23 +118,7 @@ struct sh_css_shading_table_bayer_origin_compute_results {
u32 sc_bayer_origin_y_bqs_on_shading_table; /* Y coordinate (in bqs) of bayer origin on shading table. */
};
-/* ISP2401 */
-/* Requirements for the shading correction. */
-struct sh_css_binary_sc_requirements {
- /* Bayer scaling factor, for the scaling which is applied before shading correction. */
- u32 bayer_scale_hor_ratio_in; /* Horizontal ratio (in) of scaling applied BEFORE shading correction. */
- u32 bayer_scale_hor_ratio_out; /* Horizontal ratio (out) of scaling applied BEFORE shading correction. */
- u32 bayer_scale_ver_ratio_in; /* Vertical ratio (in) of scaling applied BEFORE shading correction. */
- u32 bayer_scale_ver_ratio_out; /* Vertical ratio (out) of scaling applied BEFORE shading correction. */
-
- /* ISP internal frame is composed of the real sensor data and the padding data. */
- u32 sensor_data_origin_x_bqs_on_internal; /* X origin (in bqs) of sensor data on internal frame
- at shading correction. */
- u32 sensor_data_origin_y_bqs_on_internal; /* Y origin (in bqs) of sensor data on internal frame
- at shading correction. */
-};
-
-/* ISP2400: Get the requirements for the shading correction. */
+/* Get the requirements for the shading correction. */
static int
ia_css_binary_compute_shading_table_bayer_origin(
const struct ia_css_binary *binary, /* [in] */
@@ -261,227 +244,12 @@ ia_css_binary_compute_shading_table_bayer_origin(
return err;
}
-/* ISP2401: Get the requirements for the shading correction. */
-static int
-sh_css_binary_get_sc_requirements(const struct ia_css_binary *binary, /* [in] */
- unsigned int required_bds_factor, /* [in] */
- const struct ia_css_stream_config *stream_config, /* [in] */
- struct sh_css_binary_sc_requirements *scr) /* [out] */
-{
- int err;
-
- /* Numerator and denominator of the fixed bayer downscaling factor. (numerator >= denominator) */
- unsigned int bds_num, bds_den;
-
- /* Horizontal/Vertical ratio of bayer scaling between input area and output area. */
- unsigned int bs_hor_ratio_in, bs_hor_ratio_out, bs_ver_ratio_in, bs_ver_ratio_out;
-
- /* Left padding set by InputFormatter. */
- unsigned int left_padding_bqs;
-
- /* Flags corresponding to NEED_BDS_FACTOR_2_00/NEED_BDS_FACTOR_1_50/NEED_BDS_FACTOR_1_25 macros
- * defined in isp kernels. */
- unsigned int need_bds_factor_2_00, need_bds_factor_1_50, need_bds_factor_1_25;
-
- /* Left padding adjusted inside the isp kernels. */
- unsigned int left_padding_adjusted_bqs;
-
- /* Top padding padded inside the isp kernel for bayer downscaling binaries. */
- unsigned int top_padding_bqs;
-
- /* Bayer downscaling factor 1.0 by fixed-point. */
- int bds_frac_acc = FRAC_ACC; /* FRAC_ACC is defined in ia_css_fixedbds_param.h. */
-
- /* Right/Down shift amount caused by filters applied BEFORE shading corrertion. */
- unsigned int right_shift_bqs_before_bs; /* right shift before bayer scaling */
- unsigned int right_shift_bqs_after_bs; /* right shift after bayer scaling */
- unsigned int down_shift_bqs_before_bs; /* down shift before bayer scaling */
- unsigned int down_shift_bqs_after_bs; /* down shift after bayer scaling */
-
- /* Origin of the real sensor data area on the internal frame at shading correction. */
- unsigned int sensor_data_origin_x_bqs_on_internal;
- unsigned int sensor_data_origin_y_bqs_on_internal;
-
- unsigned int bs_frac = bds_frac_acc; /* scaling factor 1.0 in fixed point */
- unsigned int bs_out, bs_in; /* scaling ratio in fixed point */
-
- IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p",
- binary, required_bds_factor, stream_config);
-
- /* Get the numerator and denominator of the required bayer downscaling factor. */
- err = sh_css_bds_factor_get_numerator_denominator(required_bds_factor,
- &bds_num, &bds_den);
- if (err) {
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
- }
-
- IA_CSS_LOG("bds_num=%d, bds_den=%d", bds_num, bds_den);
-
- /* Set the horizontal/vertical ratio of bayer scaling between input area and output area. */
- bs_hor_ratio_in = bds_num;
- bs_hor_ratio_out = bds_den;
- bs_ver_ratio_in = bds_num;
- bs_ver_ratio_out = bds_den;
-
- /* Set the left padding set by InputFormatter. (ia_css_ifmtr_configure() in ifmtr.c) */
- if (stream_config->left_padding == -1)
- left_padding_bqs = _ISP_BQS(binary->left_padding);
- else
- left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS - _ISP_BQS(stream_config->left_padding));
-
- IA_CSS_LOG("stream.left_padding=%d, binary.left_padding=%d, left_padding_bqs=%d",
- stream_config->left_padding, binary->left_padding,
- left_padding_bqs);
-
- /* Set the left padding adjusted inside the isp kernels.
- * When the bds_factor isn't 1.00, the left padding size is adjusted inside the isp,
- * before bayer downscaling. (scaled_hor_plane_index(), raw_compute_hphase() in raw.isp.c)
- */
- need_bds_factor_2_00 = ((binary->info->sp.bds.supported_bds_factors &
- (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_00) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_00) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_8_00))) != 0);
-
- need_bds_factor_1_50 = ((binary->info->sp.bds.supported_bds_factors &
- (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_50) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_25) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00))) != 0);
-
- need_bds_factor_1_25 = ((binary->info->sp.bds.supported_bds_factors &
- (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_25) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) |
- PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00))) != 0);
-
- if (binary->info->sp.pipeline.left_cropping > 0 &&
- (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25)) {
- /*
- * downscale 2.0 -> first_vec_adjusted_bqs = 128
- * downscale 1.5 -> first_vec_adjusted_bqs = 96
- * downscale 1.25 -> first_vec_adjusted_bqs = 80
- */
- unsigned int first_vec_adjusted_bqs = ISP_VEC_NELEMS * bs_hor_ratio_in / bs_hor_ratio_out;
- left_padding_adjusted_bqs = first_vec_adjusted_bqs
- - _ISP_BQS(binary->info->sp.pipeline.left_cropping);
- } else {
- left_padding_adjusted_bqs = left_padding_bqs;
- }
-
- IA_CSS_LOG("supported_bds_factors=%d, need_bds_factor:2_00=%d, 1_50=%d, 1_25=%d",
- binary->info->sp.bds.supported_bds_factors,
- need_bds_factor_2_00, need_bds_factor_1_50,
- need_bds_factor_1_25);
- IA_CSS_LOG("left_cropping=%d, left_padding_adjusted_bqs=%d",
- binary->info->sp.pipeline.left_cropping,
- left_padding_adjusted_bqs);
-
- /* Set the top padding padded inside the isp kernel for bayer downscaling binaries.
- * When the bds_factor isn't 1.00, the top padding is padded inside the isp
- * before bayer downscaling, because the top cropping size (input margin) is not enough.
- * (calculate_input_line(), raw_compute_vphase(), dma_read_raw() in raw.isp.c)
- * NOTE: In dma_read_raw(), the factor passed to raw_compute_vphase() is got by get_bds_factor_for_dma_read().
- * This factor is BDS_FPVAL_100/BDS_FPVAL_125/BDS_FPVAL_150/BDS_FPVAL_200.
- */
- top_padding_bqs = 0;
- if (binary->info->sp.pipeline.top_cropping > 0 &&
- (required_bds_factor == SH_CSS_BDS_FACTOR_1_25 ||
- required_bds_factor == SH_CSS_BDS_FACTOR_1_50 ||
- required_bds_factor == SH_CSS_BDS_FACTOR_2_00)) {
- /* Calculation from calculate_input_line() and raw_compute_vphase() in raw.isp.c. */
- int top_cropping_bqs = _ISP_BQS(binary->info->sp.pipeline.top_cropping);
- /* top cropping (in bqs) */
- int factor = bds_num * bds_frac_acc /
- bds_den; /* downscaling factor by fixed-point */
- int top_padding_bqsxfrac_acc = (top_cropping_bqs * factor - top_cropping_bqs *
- bds_frac_acc)
- + (2 * bds_frac_acc - factor); /* top padding by fixed-point (in bqs) */
-
- top_padding_bqs = (unsigned int)((top_padding_bqsxfrac_acc + bds_frac_acc / 2 -
- 1) / bds_frac_acc);
- }
-
- IA_CSS_LOG("top_cropping=%d, top_padding_bqs=%d",
- binary->info->sp.pipeline.top_cropping, top_padding_bqs);
-
- /* Set the right/down shift amount caused by filters applied BEFORE bayer scaling,
- * which scaling is applied BEFORE shading corrertion.
- *
- * When the bds_factor isn't 1.00, 3x3 anti-alias filter is applied to each color plane(Gr/R/B/Gb)
- * before bayer downscaling.
- * This filter shifts each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel.
- */
- right_shift_bqs_before_bs = 0;
- down_shift_bqs_before_bs = 0;
-
- if (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25) {
- right_shift_bqs_before_bs = 1;
- down_shift_bqs_before_bs = 1;
- }
-
- IA_CSS_LOG("right_shift_bqs_before_bs=%d, down_shift_bqs_before_bs=%d",
- right_shift_bqs_before_bs, down_shift_bqs_before_bs);
-
- /* Set the right/down shift amount caused by filters applied AFTER bayer scaling,
- * which scaling is applied BEFORE shading corrertion.
- *
- * When DPC&BNR is processed between bayer scaling and shading correction,
- * DPC&BNR moves each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel.
- */
- right_shift_bqs_after_bs = 0;
- down_shift_bqs_after_bs = 0;
-
- /* if DPC&BNR is enabled in the binary */
- if (binary->info->mem_offsets.offsets.param->dmem.dp.size != 0) {
- right_shift_bqs_after_bs = 1;
- down_shift_bqs_after_bs = 1;
- }
-
- IA_CSS_LOG("right_shift_bqs_after_bs=%d, down_shift_bqs_after_bs=%d",
- right_shift_bqs_after_bs, down_shift_bqs_after_bs);
-
- bs_out = bs_hor_ratio_out * bs_frac;
- bs_in = bs_hor_ratio_in * bs_frac;
- sensor_data_origin_x_bqs_on_internal =
- ((left_padding_adjusted_bqs + right_shift_bqs_before_bs) * bs_out + bs_in / 2) / bs_in
- + right_shift_bqs_after_bs; /* "+ bs_in/2": rounding */
-
- bs_out = bs_ver_ratio_out * bs_frac;
- bs_in = bs_ver_ratio_in * bs_frac;
- sensor_data_origin_y_bqs_on_internal =
- ((top_padding_bqs + down_shift_bqs_before_bs) * bs_out + bs_in / 2) / bs_in
- + down_shift_bqs_after_bs; /* "+ bs_in/2": rounding */
-
- scr->bayer_scale_hor_ratio_in = (uint32_t)bs_hor_ratio_in;
- scr->bayer_scale_hor_ratio_out = (uint32_t)bs_hor_ratio_out;
- scr->bayer_scale_ver_ratio_in = (uint32_t)bs_ver_ratio_in;
- scr->bayer_scale_ver_ratio_out = (uint32_t)bs_ver_ratio_out;
- scr->sensor_data_origin_x_bqs_on_internal = (uint32_t)sensor_data_origin_x_bqs_on_internal;
- scr->sensor_data_origin_y_bqs_on_internal = (uint32_t)sensor_data_origin_y_bqs_on_internal;
-
- IA_CSS_LOG("sc_requirements: %d, %d, %d, %d, %d, %d",
- scr->bayer_scale_hor_ratio_in,
- scr->bayer_scale_hor_ratio_out,
- scr->bayer_scale_ver_ratio_in, scr->bayer_scale_ver_ratio_out,
- scr->sensor_data_origin_x_bqs_on_internal,
- scr->sensor_data_origin_y_bqs_on_internal);
-
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
-}
-
/* Get the shading information of Shading Correction Type 1. */
static int
-isp2400_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in] */
- unsigned int required_bds_factor, /* [in] */
- const struct ia_css_stream_config *stream_config, /* [in] */
- struct ia_css_shading_info *info) /* [out] */
+binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in] */
+ unsigned int required_bds_factor, /* [in] */
+ const struct ia_css_stream_config *stream_config, /* [in] */
+ struct ia_css_shading_info *info) /* [out] */
{
int err;
struct sh_css_shading_table_bayer_origin_compute_results res;
@@ -522,173 +290,6 @@ isp2400_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [i
return err;
}
-/* Get the shading information of Shading Correction Type 1. */
-static int
-isp2401_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in] */
- unsigned int required_bds_factor, /* [in] */
- const struct ia_css_stream_config *stream_config, /* [in] */
- struct ia_css_shading_info *shading_info, /* [out] */
- struct ia_css_pipe_config *pipe_config) /* [out] */
-{
- int err;
- struct sh_css_binary_sc_requirements scr;
-
- u32 in_width_bqs, in_height_bqs, internal_width_bqs, internal_height_bqs;
- u32 num_hor_grids, num_ver_grids, bqs_per_grid_cell, tbl_width_bqs, tbl_height_bqs;
- u32 sensor_org_x_bqs_on_internal, sensor_org_y_bqs_on_internal, sensor_width_bqs, sensor_height_bqs;
- u32 sensor_center_x_bqs_on_internal, sensor_center_y_bqs_on_internal;
- u32 left, right, upper, lower;
- u32 adjust_left, adjust_right, adjust_upper, adjust_lower, adjust_width_bqs, adjust_height_bqs;
- u32 internal_org_x_bqs_on_tbl, internal_org_y_bqs_on_tbl;
- u32 sensor_org_x_bqs_on_tbl, sensor_org_y_bqs_on_tbl;
-
- assert(binary);
- assert(stream_config);
- assert(shading_info);
- assert(pipe_config);
-
- IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p",
- binary, required_bds_factor, stream_config);
-
- /* Initialize by default values. */
- *shading_info = DEFAULT_SHADING_INFO_TYPE_1;
-
- err = sh_css_binary_get_sc_requirements(binary, required_bds_factor, stream_config, &scr);
- if (err) {
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
- }
-
- IA_CSS_LOG("binary: id=%d, sctbl=%dx%d, deci=%d",
- binary->info->sp.id, binary->sctbl_width_per_color, binary->sctbl_height, binary->deci_factor_log2);
- IA_CSS_LOG("binary: in=%dx%d, in_padded_w=%d, int=%dx%d, int_padded_w=%d, out=%dx%d, out_padded_w=%d",
- binary->in_frame_info.res.width, binary->in_frame_info.res.height, binary->in_frame_info.padded_width,
- binary->internal_frame_info.res.width, binary->internal_frame_info.res.height,
- binary->internal_frame_info.padded_width,
- binary->out_frame_info[0].res.width, binary->out_frame_info[0].res.height,
- binary->out_frame_info[0].padded_width);
-
- /* Set the input size from sensor, which includes left/top crop size. */
- in_width_bqs = _ISP_BQS(binary->in_frame_info.res.width);
- in_height_bqs = _ISP_BQS(binary->in_frame_info.res.height);
-
- /*
- * Frame size internally used in ISP, including sensor data and padding.
- * This is the frame size, to which the shading correction is applied.
- */
- internal_width_bqs = _ISP_BQS(binary->internal_frame_info.res.width);
- internal_height_bqs = _ISP_BQS(binary->internal_frame_info.res.height);
-
- /* Shading table. */
- num_hor_grids = binary->sctbl_width_per_color;
- num_ver_grids = binary->sctbl_height;
- bqs_per_grid_cell = (1 << binary->deci_factor_log2);
- tbl_width_bqs = (num_hor_grids - 1) * bqs_per_grid_cell;
- tbl_height_bqs = (num_ver_grids - 1) * bqs_per_grid_cell;
-
- IA_CSS_LOG("tbl_width_bqs=%d, tbl_height_bqs=%d", tbl_width_bqs, tbl_height_bqs);
-
- /*
- * Real sensor data area on the internal frame at shading correction.
- * Filters and scaling are applied to the internal frame before
- * shading correction, depending on the binary.
- */
- sensor_org_x_bqs_on_internal = scr.sensor_data_origin_x_bqs_on_internal;
- sensor_org_y_bqs_on_internal = scr.sensor_data_origin_y_bqs_on_internal;
- {
- unsigned int bs_frac = 8; /* scaling factor 1.0 in fixed point (8 == FRAC_ACC macro in ISP) */
- unsigned int bs_out, bs_in; /* scaling ratio in fixed point */
-
- bs_out = scr.bayer_scale_hor_ratio_out * bs_frac;
- bs_in = scr.bayer_scale_hor_ratio_in * bs_frac;
- sensor_width_bqs = (in_width_bqs * bs_out + bs_in / 2) / bs_in; /* "+ bs_in/2": rounding */
-
- bs_out = scr.bayer_scale_ver_ratio_out * bs_frac;
- bs_in = scr.bayer_scale_ver_ratio_in * bs_frac;
- sensor_height_bqs = (in_height_bqs * bs_out + bs_in / 2) / bs_in; /* "+ bs_in/2": rounding */
- }
-
- /* Center of the sensor data on the internal frame at shading correction. */
- sensor_center_x_bqs_on_internal = sensor_org_x_bqs_on_internal + sensor_width_bqs / 2;
- sensor_center_y_bqs_on_internal = sensor_org_y_bqs_on_internal + sensor_height_bqs / 2;
-
- /* Size of left/right/upper/lower sides of the sensor center on the internal frame. */
- left = sensor_center_x_bqs_on_internal;
- right = internal_width_bqs - sensor_center_x_bqs_on_internal;
- upper = sensor_center_y_bqs_on_internal;
- lower = internal_height_bqs - sensor_center_y_bqs_on_internal;
-
- /* Align the size of left/right/upper/lower sides to a multiple of the grid cell size. */
- adjust_left = CEIL_MUL(left, bqs_per_grid_cell);
- adjust_right = CEIL_MUL(right, bqs_per_grid_cell);
- adjust_upper = CEIL_MUL(upper, bqs_per_grid_cell);
- adjust_lower = CEIL_MUL(lower, bqs_per_grid_cell);
-
- /* Shading table should cover the adjusted frame size. */
- adjust_width_bqs = adjust_left + adjust_right;
- adjust_height_bqs = adjust_upper + adjust_lower;
-
- IA_CSS_LOG("adjust_width_bqs=%d, adjust_height_bqs=%d", adjust_width_bqs, adjust_height_bqs);
-
- if (adjust_width_bqs > tbl_width_bqs || adjust_height_bqs > tbl_height_bqs) {
- IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
- return -EINVAL;
- }
-
- /* Origin of the internal frame on the shading table. */
- internal_org_x_bqs_on_tbl = adjust_left - left;
- internal_org_y_bqs_on_tbl = adjust_upper - upper;
-
- /* Origin of the real sensor data area on the shading table. */
- sensor_org_x_bqs_on_tbl = internal_org_x_bqs_on_tbl + sensor_org_x_bqs_on_internal;
- sensor_org_y_bqs_on_tbl = internal_org_y_bqs_on_tbl + sensor_org_y_bqs_on_internal;
-
- /* The shading information necessary as API is stored in the shading_info. */
- shading_info->info.type_1.num_hor_grids = num_hor_grids;
- shading_info->info.type_1.num_ver_grids = num_ver_grids;
- shading_info->info.type_1.bqs_per_grid_cell = bqs_per_grid_cell;
-
- shading_info->info.type_1.bayer_scale_hor_ratio_in = scr.bayer_scale_hor_ratio_in;
- shading_info->info.type_1.bayer_scale_hor_ratio_out = scr.bayer_scale_hor_ratio_out;
- shading_info->info.type_1.bayer_scale_ver_ratio_in = scr.bayer_scale_ver_ratio_in;
- shading_info->info.type_1.bayer_scale_ver_ratio_out = scr.bayer_scale_ver_ratio_out;
-
- shading_info->info.type_1.isp_input_sensor_data_res_bqs.width = in_width_bqs;
- shading_info->info.type_1.isp_input_sensor_data_res_bqs.height = in_height_bqs;
-
- shading_info->info.type_1.sensor_data_res_bqs.width = sensor_width_bqs;
- shading_info->info.type_1.sensor_data_res_bqs.height = sensor_height_bqs;
-
- shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x = (int32_t)sensor_org_x_bqs_on_tbl;
- shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y = (int32_t)sensor_org_y_bqs_on_tbl;
-
- /* The shading information related to ISP (but, not necessary as API) is stored in the pipe_config. */
- pipe_config->internal_frame_origin_bqs_on_sctbl.x = (int32_t)internal_org_x_bqs_on_tbl;
- pipe_config->internal_frame_origin_bqs_on_sctbl.y = (int32_t)internal_org_y_bqs_on_tbl;
-
- IA_CSS_LOG("shading_info: grids=%dx%d, cell=%d, scale=%d,%d,%d,%d, input=%dx%d, data=%dx%d, origin=(%d,%d)",
- shading_info->info.type_1.num_hor_grids,
- shading_info->info.type_1.num_ver_grids,
- shading_info->info.type_1.bqs_per_grid_cell,
- shading_info->info.type_1.bayer_scale_hor_ratio_in,
- shading_info->info.type_1.bayer_scale_hor_ratio_out,
- shading_info->info.type_1.bayer_scale_ver_ratio_in,
- shading_info->info.type_1.bayer_scale_ver_ratio_out,
- shading_info->info.type_1.isp_input_sensor_data_res_bqs.width,
- shading_info->info.type_1.isp_input_sensor_data_res_bqs.height,
- shading_info->info.type_1.sensor_data_res_bqs.width,
- shading_info->info.type_1.sensor_data_res_bqs.height,
- shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x,
- shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y);
-
- IA_CSS_LOG("pipe_config: origin=(%d,%d)",
- pipe_config->internal_frame_origin_bqs_on_sctbl.x,
- pipe_config->internal_frame_origin_bqs_on_sctbl.y);
-
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
-}
-
int
ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */
@@ -706,24 +307,13 @@ ia_css_binary_get_shading_info(const struct ia_css_binary *binary, /* [in] */
IA_CSS_ENTER_PRIVATE("binary=%p, type=%d, required_bds_factor=%d, stream_config=%p",
binary, type, required_bds_factor, stream_config);
- if (type != IA_CSS_SHADING_CORRECTION_TYPE_1) {
- err = -ENOTSUPP;
-
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
- }
-
- if (!IS_ISP2401)
- err = isp2400_binary_get_shading_info_type_1(binary,
- required_bds_factor,
- stream_config,
- shading_info);
+ if (type == IA_CSS_SHADING_CORRECTION_TYPE_1)
+ err = binary_get_shading_info_type_1(binary,
+ required_bds_factor,
+ stream_config,
+ shading_info);
else
- err = isp2401_binary_get_shading_info_type_1(binary,
- required_bds_factor,
- stream_config,
- shading_info,
- pipe_config);
+ err = -ENOTSUPP;
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
@@ -805,11 +395,7 @@ ia_css_binary_3a_grid_info(const struct ia_css_binary *binary,
s3a_info->deci_factor_log2 = binary->deci_factor_log2;
s3a_info->elem_bit_depth = SH_CSS_BAYER_BITS;
s3a_info->use_dmem = binary->info->sp.s3a.s3atbl_use_dmem;
-#if defined(HAS_NO_HMEM)
- s3a_info->has_histogram = 1;
-#else
s3a_info->has_histogram = 0;
-#endif
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
@@ -965,15 +551,9 @@ binary_grid_deci_factor_log2(int width, int height)
/* 3A/Shading decimation factor spcification (at August 2008)
* ------------------------------------------------------------------
* [Image Width (BQ)] [Decimation Factor (BQ)] [Resulting grid cells]
- #ifndef ISP2401
* 1280 ?c 32 40 ?c
* 640 ?c 1279 16 40 ?c 80
* ?c 639 8 ?c 80
- #else
- * from 1280 32 from 40
- * from 640 to 1279 16 from 40 to 80
- * to 639 8 to 80
- #endif
* ------------------------------------------------------------------
*/
/* Maximum and minimum decimation factor by the specification */
@@ -1335,26 +915,14 @@ ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
if (info->enable.sc)
{
- if (!IS_ISP2401) {
- binary->sctbl_width_per_color = _ISP2400_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci);
- binary->sctbl_aligned_width_per_color = ISP2400_SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR;
- binary->sctbl_height = _ISP2400_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci);
- } else {
- binary->sctbl_width_per_color = _ISP2401_SCTBL_WIDTH_PER_COLOR(isp_internal_width, s3a_log_deci);
- binary->sctbl_aligned_width_per_color = ISP2401_SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR;
- binary->sctbl_height = _ISP2401_SCTBL_HEIGHT(isp_internal_height, s3a_log_deci);
- binary->sctbl_legacy_width_per_color = _ISP_SCTBL_LEGACY_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci);
- binary->sctbl_legacy_height = _ISP_SCTBL_LEGACY_HEIGHT(sc_3a_dis_height, s3a_log_deci);
- }
+ binary->sctbl_width_per_color = _ISP_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci);
+ binary->sctbl_aligned_width_per_color = SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR;
+ binary->sctbl_height = _ISP_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci);
} else
{
binary->sctbl_width_per_color = 0;
binary->sctbl_aligned_width_per_color = 0;
binary->sctbl_height = 0;
- if (IS_ISP2401) {
- binary->sctbl_legacy_width_per_color = 0;
- binary->sctbl_legacy_height = 0;
- }
}
ia_css_sdis_init_info(&binary->dis,
sc_3a_dis_width,
@@ -1383,20 +951,13 @@ static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
*req_vf_info;
struct ia_css_binary_xinfo *xcandidate;
-#ifndef ISP2401
bool need_ds, need_dz, need_dvs, need_xnr, need_dpc;
-#else
- bool need_ds, need_dz, need_dvs, need_xnr, need_dpc, need_tnr;
-#endif
bool striped;
bool enable_yuv_ds;
bool enable_high_speed;
bool enable_dvs_6axis;
bool enable_reduced_pipe;
bool enable_capture_pp_bli;
-#ifdef ISP2401
- bool enable_luma_only;
-#endif
int err = -EINVAL;
bool continuous;
unsigned int isp_pipe_version;
@@ -1418,41 +979,26 @@ static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
stream_format = descr->stream_format;
req_in_info = descr->in_info;
req_bds_out_info = descr->bds_out_info;
- for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
- {
+ for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
req_out_info[i] = descr->out_info[i];
if (req_out_info[i] && (req_out_info[i]->res.width != 0))
req_bin_out_info = req_out_info[i];
}
if (!req_bin_out_info)
return -EINVAL;
-#ifndef ISP2401
req_vf_info = descr->vf_info;
-#else
-
- if ((descr->vf_info) && (descr->vf_info->res.width == 0))
- /* width==0 means that there is no vf pin (e.g. in SkyCam preview case) */
- req_vf_info = NULL;
- else
- req_vf_info = descr->vf_info;
-#endif
need_xnr = descr->enable_xnr;
need_ds = descr->enable_fractional_ds;
need_dz = false;
need_dvs = false;
need_dpc = descr->enable_dpc;
-#ifdef ISP2401
- need_tnr = descr->enable_tnr;
-#endif
+
enable_yuv_ds = descr->enable_yuv_ds;
enable_high_speed = descr->enable_high_speed;
enable_dvs_6axis = descr->enable_dvs_6axis;
enable_reduced_pipe = descr->enable_reduced_pipe;
enable_capture_pp_bli = descr->enable_capture_pp_bli;
-#ifdef ISP2401
- enable_luma_only = descr->enable_luma_only;
-#endif
continuous = descr->continuous;
striped = descr->striped;
isp_pipe_version = descr->isp_pipe_version;
@@ -1462,8 +1008,7 @@ static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
internal_res.width = 0;
internal_res.height = 0;
- if (mode == IA_CSS_BINARY_MODE_VIDEO)
- {
+ if (mode == IA_CSS_BINARY_MODE_VIDEO) {
dvs_env = descr->dvs_env;
need_dz = descr->enable_dz;
/* Video is the only mode that has a nodz variant. */
@@ -1472,8 +1017,7 @@ static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
/* print a map of the binary file */
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "BINARY INFO:\n");
- for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++)
- {
+ for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) {
xcandidate = binary_infos[i];
if (xcandidate) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%d:\n", i);
@@ -1488,8 +1032,7 @@ static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
/* printf("sh_css_binary_find: pipe version %d\n", isp_pipe_version); */
for (xcandidate = binary_infos[mode]; xcandidate;
- xcandidate = xcandidate->next)
- {
+ xcandidate = xcandidate->next) {
struct ia_css_binary_info *candidate = &xcandidate->sp;
/* printf("sh_css_binary_find: evaluating candidate:
* %d\n",candidate->id); */
@@ -1747,24 +1290,6 @@ static int __ia_css_binary_find(struct ia_css_binary_descr *descr,
continue;
}
-#ifdef ISP2401
- if (candidate->enable.luma_only != enable_luma_only) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_binary_find() [%d] continue: %d != %d\n",
- __LINE__, candidate->enable.luma_only,
- descr->enable_luma_only);
- continue;
- }
-
- if (!candidate->enable.tnr && need_tnr) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "ia_css_binary_find() [%d] continue: !%d && %d\n",
- __LINE__, candidate->enable.tnr,
- descr->enable_tnr);
- continue;
- }
-
-#endif
/* reconfigure any variable properties of the binary */
err = ia_css_binary_fill_info(xcandidate, online, two_ppc,
stream_format, req_in_info,
diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c
index 05ce0f73f5ae..f46238725eea 100644
--- a/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c
+++ b/drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c
@@ -2821,7 +2821,7 @@ ia_css_debug_pipe_graph_dump_stage(
"in", true);
}
- for (i = 0; i < NUM_TNR_FRAMES; i++) {
+ for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++) {
if (stage->args.tnr_frames[i]) {
ia_css_debug_pipe_graph_dump_frame(
stage->args.tnr_frames[i], id,
diff --git a/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h b/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h
index 31f01e0f58aa..c756a134efc3 100644
--- a/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h
+++ b/drivers/staging/media/atomisp/pci/runtime/frame/interface/ia_css_frame.h
@@ -138,27 +138,7 @@ bool ia_css_frame_is_same_type(
* @param[in] info The frame info
* @return
*/
-void ia_css_dma_configure_from_info(
- struct dma_port_config *config,
- const struct ia_css_frame_info *info);
-
-/* ISP2401 */
-/* @brief Finds the cropping resolution
- * This function finds the maximum cropping resolution in an input image keeping
- * the aspect ratio for the given output resolution.Calculates the coordinates
- * for cropping from the center and returns the starting pixel location of the
- * region in the input image. Also returns the dimension of the cropping
- * resolution.
- *
- * @param
- * @param[in] in_res Resolution of input image
- * @param[in] out_res Resolution of output image
- * @param[out] crop_res Crop resolution of input image
- * @return Returns 0 or -EINVAL on error
- */
-int
-ia_css_frame_find_crop_resolution(const struct ia_css_resolution *in_res,
- const struct ia_css_resolution *out_res,
- struct ia_css_resolution *crop_res);
+int ia_css_dma_configure_from_info(struct dma_port_config *config,
+ const struct ia_css_frame_info *info);
#endif /* __IA_CSS_FRAME_H__ */
diff --git a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c
index 10c4907187d9..a3aae638b0bf 100644
--- a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c
+++ b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c
@@ -168,25 +168,23 @@ int ia_css_frame_map(struct ia_css_frame **frame,
if (err)
return err;
- if (!err) {
- if (pgnr < ((PAGE_ALIGN(me->data_bytes)) >> PAGE_SHIFT)) {
- dev_err(atomisp_dev,
- "user space memory size is less than the expected size..\n");
- err = -ENOMEM;
- goto error;
- } else if (pgnr > ((PAGE_ALIGN(me->data_bytes)) >> PAGE_SHIFT)) {
- dev_err(atomisp_dev,
- "user space memory size is large than the expected size..\n");
- err = -ENOMEM;
- goto error;
- }
+ if (pgnr < ((PAGE_ALIGN(me->data_bytes)) >> PAGE_SHIFT)) {
+ dev_err(atomisp_dev,
+ "user space memory size is less than the expected size..\n");
+ err = -ENOMEM;
+ goto error;
+ } else if (pgnr > ((PAGE_ALIGN(me->data_bytes)) >> PAGE_SHIFT)) {
+ dev_err(atomisp_dev,
+ "user space memory size is large than the expected size..\n");
+ err = -ENOMEM;
+ goto error;
+ }
- me->data = hmm_alloc(me->data_bytes, HMM_BO_USER, 0, data,
- attribute & ATOMISP_MAP_FLAG_CACHED);
+ me->data = hmm_alloc(me->data_bytes, HMM_BO_USER, 0, data,
+ attribute & ATOMISP_MAP_FLAG_CACHED);
- if (me->data == mmgr_NULL)
- err = -EINVAL;
- }
+ if (me->data == mmgr_NULL)
+ err = -EINVAL;
error:
if (err) {
@@ -594,10 +592,8 @@ bool ia_css_frame_is_same_type(const struct ia_css_frame *frame_a,
return is_equal;
}
-void
-ia_css_dma_configure_from_info(
- struct dma_port_config *config,
- const struct ia_css_frame_info *info)
+int ia_css_dma_configure_from_info(struct dma_port_config *config,
+ const struct ia_css_frame_info *info)
{
unsigned int is_raw_packed = info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED;
unsigned int bits_per_pixel = is_raw_packed ? info->raw_bit_depth :
@@ -610,7 +606,13 @@ ia_css_dma_configure_from_info(
config->elems = (uint8_t)elems_b;
config->width = (uint16_t)info->res.width;
config->crop = 0;
- assert(config->width <= info->padded_width);
+
+ if (config->width > info->padded_width) {
+ dev_err(atomisp_dev, "internal error: padded_width is too small!\n");
+ return -EINVAL;
+ }
+
+ return 0;
}
/**************************************************************************
@@ -931,73 +933,3 @@ void ia_css_resolution_to_sp_resolution(
to->width = (uint16_t)from->width;
to->height = (uint16_t)from->height;
}
-
-/* ISP2401 */
-int
-ia_css_frame_find_crop_resolution(const struct ia_css_resolution *in_res,
- const struct ia_css_resolution *out_res,
- struct ia_css_resolution *crop_res) {
- u32 wd_even_ceil, ht_even_ceil;
- u32 in_ratio, out_ratio;
-
- if ((!in_res) || (!out_res) || (!crop_res))
- return -EINVAL;
-
- IA_CSS_ENTER_PRIVATE("in(%ux%u) -> out(%ux%u)", in_res->width,
- in_res->height, out_res->width, out_res->height);
-
- if ((in_res->width == 0)
- || (in_res->height == 0)
- || (out_res->width == 0)
- || (out_res->height == 0))
- return -EINVAL;
-
- if ((out_res->width > in_res->width) ||
- (out_res->height > in_res->height))
- return -EINVAL;
-
- /* If aspect ratio (width/height) of out_res is higher than the aspect
- * ratio of the in_res, then we crop vertically, otherwise we crop
- * horizontally.
- */
- in_ratio = in_res->width * out_res->height;
- out_ratio = out_res->width * in_res->height;
-
- if (in_ratio == out_ratio)
- {
- crop_res->width = in_res->width;
- crop_res->height = in_res->height;
- } else if (out_ratio > in_ratio)
- {
- crop_res->width = in_res->width;
- crop_res->height = ROUND_DIV(out_res->height * crop_res->width,
- out_res->width);
- } else
- {
- crop_res->height = in_res->height;
- crop_res->width = ROUND_DIV(out_res->width * crop_res->height,
- out_res->height);
- }
-
- /* Round new (cropped) width and height to an even number.
- * binarydesc_calculate_bds_factor is such that we should consider as
- * much of the input as possible. This is different only when we end up
- * with an odd number in the last step. So, we take the next even number
- * if it falls within the input, otherwise take the previous even no.
- */
- wd_even_ceil = EVEN_CEIL(crop_res->width);
- ht_even_ceil = EVEN_CEIL(crop_res->height);
- if ((wd_even_ceil > in_res->width) || (ht_even_ceil > in_res->height))
- {
- crop_res->width = EVEN_FLOOR(crop_res->width);
- crop_res->height = EVEN_FLOOR(crop_res->height);
- } else
- {
- crop_res->width = wd_even_ceil;
- crop_res->height = ht_even_ceil;
- }
-
- IA_CSS_LEAVE_PRIVATE("in(%ux%u) -> out(%ux%u)", crop_res->width,
- crop_res->height, out_res->width, out_res->height);
- return 0;
-}
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
index 82f3c19dc455..8fc7746f8639 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
@@ -189,17 +189,6 @@ ia_css_isys_error_t ia_css_isys_stream_create(
return false;
}
-#ifdef ISP2401
- /*
- * Early polling is required for timestamp accuracy in certain cause.
- * The ISYS HW polling is started on
- * ia_css_isys_stream_capture_indication() instead of
- * ia_css_pipeline_sp_wait_for_isys_stream_N() as isp processing of
- * capture takes longer than getting an ISYS frame
- */
- isys_stream->polling_mode = isys_stream_descr->polling_mode;
-
-#endif
/* create metadata channel */
if (isys_stream_descr->metadata.enable) {
rc = create_input_system_channel(isys_stream_descr, true,
diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
index d03957d1ecf4..dfc50247ea8e 100644
--- a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
+++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c
@@ -140,8 +140,7 @@ void ia_css_pipeline_start(enum ia_css_pipe_id pipe_id,
false, false, false, true, SH_CSS_BDS_FACTOR_1_00,
SH_CSS_PIPE_CONFIG_OVRD_NO_OVRD,
IA_CSS_INPUT_MODE_MEMORY, NULL, NULL,
- (enum mipi_port_id)0,
- NULL, NULL);
+ (enum mipi_port_id)0);
ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
if (!sh_css_sp_is_running()) {
diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c
index c4b35cbab373..1d605e533e29 100644
--- a/drivers/staging/media/atomisp/pci/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/sh_css.c
@@ -20,6 +20,8 @@
#include "hmm.h"
+#include "atomisp_internal.h"
+
#include "ia_css.h"
#include "sh_css_hrt.h" /* only for file 2 MIPI */
#include "ia_css_buffer.h"
@@ -62,9 +64,9 @@
#include "ia_css_mmu_private.h" /* sh_css_mmu_set_page_table_base_index() */
#include "gdc_device.h" /* HRT_GDC_N */
#include "dma.h" /* dma_set_max_burst_size() */
-#include "irq.h" /* virq */
-#include "sp.h" /* cnd_sp_irq_enable() */
-#include "isp.h" /* cnd_isp_irq_enable, ISP_VEC_NELEMS */
+#include "irq.h" /* virq */
+#include "sp.h" /* cnd_sp_irq_enable() */
+#include "isp.h" /* cnd_isp_irq_enable, ISP_VEC_NELEMS */
#include "gp_device.h" /* gp_device_reg_store() */
#define __INLINE_GPIO__
#include "gpio.h"
@@ -74,15 +76,6 @@
#define SH_CSS_VIDEO_BUFFER_ALIGNMENT 0
-#if WITH_PC_MONITORING
-#define MULTIPLE_SAMPLES 1
-#define NOF_SAMPLES 60
-#include "linux/kthread.h"
-#include "linux/sched.h"
-#include "linux/delay.h"
-#include "sh_css_metrics.h"
-static int thread_alive;
-#endif /* WITH_PC_MONITORING */
#include "ia_css_spctrl.h"
#include "ia_css_version_data.h"
@@ -97,8 +90,9 @@ static int thread_alive;
/* Size of Refcount List */
#define REFCOUNT_SIZE 1000
-/* for JPEG, we don't know the length of the image upfront,
- * but since we support sensor upto 16MP, we take this as
+/*
+ * for JPEG, we don't know the length of the image upfront,
+ * but since we support sensor up to 16MP, we take this as
* upper limit.
*/
#define JPEG_BYTES (16 * 1024 * 1024)
@@ -110,9 +104,10 @@ struct sh_css my_css;
int __printf(1, 0) (*sh_css_printf)(const char *fmt, va_list args) = NULL;
-/* modes of work: stream_create and stream_destroy will update the save/restore data
- only when in working mode, not suspend/resume
-*/
+/*
+ * modes of work: stream_create and stream_destroy will update the save/restore
+ * data only when in working mode, not suspend/resume
+ */
enum ia_sh_css_modes {
sh_css_mode_none = 0,
sh_css_mode_working,
@@ -120,40 +115,55 @@ enum ia_sh_css_modes {
sh_css_mode_resume
};
-/* a stream seed, to save and restore the stream data.
- the stream seed contains all the data required to "grow" the seed again after it was closed.
+/**
+ * struct sh_css_stream_seed - a stream seed, to save and restore the
+ * stream data.
+ *
+ * @orig_stream: pointer to restore the original handle
+ * @stream: handle, used as ID too.
+ * @stream_config: stream config struct
+ * @num_pipes: number of pipes
+ * @pipes: pipe handles
+ * @orig_pipes: pointer to restore original handle
+ * @pipe_config: pipe config structs
+ *
+ * the stream seed contains all the data required to "grow" the seed again
+ * after it was closed.
*/
struct sh_css_stream_seed {
- struct ia_css_stream
- **orig_stream; /* pointer to restore the original handle */
- struct ia_css_stream *stream; /* handle, used as ID too.*/
- struct ia_css_stream_config stream_config; /* stream config struct */
+ struct ia_css_stream **orig_stream;
+ struct ia_css_stream *stream;
+ struct ia_css_stream_config stream_config;
int num_pipes;
- struct ia_css_pipe *pipes[IA_CSS_PIPE_ID_NUM]; /* pipe handles */
- struct ia_css_pipe
- **orig_pipes[IA_CSS_PIPE_ID_NUM]; /* pointer to restore original handle */
- struct ia_css_pipe_config
- pipe_config[IA_CSS_PIPE_ID_NUM]; /* pipe config structs */
+ struct ia_css_pipe *pipes[IA_CSS_PIPE_ID_NUM];
+ struct ia_css_pipe **orig_pipes[IA_CSS_PIPE_ID_NUM];
+ struct ia_css_pipe_config pipe_config[IA_CSS_PIPE_ID_NUM];
};
#define MAX_ACTIVE_STREAMS 5
-/* A global struct for save/restore to hold all the data that should sustain power-down:
- MMU base, IRQ type, env for routines, binary loaded FW and the stream seeds.
-*/
+/*
+ * A global struct for save/restore to hold all the data that should
+ * sustain power-down: MMU base, IRQ type, env for routines, binary loaded FW
+ * and the stream seeds.
+ */
struct sh_css_save {
enum ia_sh_css_modes mode;
- u32 mmu_base; /* the last mmu_base */
+ u32 mmu_base; /* the last mmu_base */
enum ia_css_irq_type irq_type;
struct sh_css_stream_seed stream_seeds[MAX_ACTIVE_STREAMS];
- struct ia_css_fw *loaded_fw; /* fw struct previously loaded */
- struct ia_css_env driver_env; /* driver-supplied env copy */
+ struct ia_css_fw *loaded_fw; /* fw struct previously loaded */
+ struct ia_css_env driver_env; /* driver-supplied env copy */
};
static bool my_css_save_initialized; /* if my_css_save was initialized */
static struct sh_css_save my_css_save;
-/* pqiao NOTICE: this is for css internal buffer recycling when stopping pipeline,
- this array is temporary and will be replaced by resource manager*/
+/*
+ * pqiao NOTICE: this is for css internal buffer recycling when stopping
+ * pipeline,
+ * this array is temporary and will be replaced by resource manager
+ */
+
/* Taking the biggest Size for number of Elements */
#define MAX_HMM_BUFFER_NUM \
(SH_CSS_MAX_NUM_QUEUES * (IA_CSS_NUM_ELEMS_SP2HOST_BUFFER_QUEUE + 2))
@@ -181,27 +191,6 @@ allocate_delay_frames(struct ia_css_pipe *pipe);
static int
sh_css_pipe_start(struct ia_css_stream *stream);
-/* ISP 2401 */
-/*
- * @brief Stop all "ia_css_pipe" instances in the target
- * "ia_css_stream" instance.
- *
- * @param[in] stream Point to the target "ia_css_stream" instance.
- *
- * @return
- * - 0, if the "stop" requests have been successfully sent out.
- * - CSS error code, otherwise.
- *
- *
- * NOTE
- * This API sends the "stop" requests to the "ia_css_pipe"
- * instances in the same "ia_css_stream" instance. It will
- * return without waiting for all "ia_css_pipe" instatnces
- * being stopped.
- */
-static int
-sh_css_pipes_stop(struct ia_css_stream *stream);
-
/*
* @brief Check if all "ia_css_pipe" instances in the target
* "ia_css_stream" instance have stopped.
@@ -213,9 +202,6 @@ sh_css_pipes_stop(struct ia_css_stream *stream);
* instance have ben stopped.
* - false, otherwise.
*/
-/* ISP 2401 */
-static bool
-sh_css_pipes_have_stopped(struct ia_css_stream *stream);
/* ISP 2401 */
static int
@@ -224,9 +210,6 @@ ia_css_pipe_check_format(struct ia_css_pipe *pipe,
/* ISP 2401 */
static int
-check_pipe_resolutions(const struct ia_css_pipe *pipe);
-
-static int
ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
struct ia_css_fw_info *firmware);
@@ -384,10 +367,6 @@ ia_css_get_acc_configs(
struct ia_css_pipe *pipe,
struct ia_css_isp_config *config);
-#if CONFIG_ON_FRAME_ENQUEUE()
-static int set_config_on_frame_enqueue(struct ia_css_frame_info
- *info, struct frame_data_wrapper *frame);
-#endif
#ifdef ISP2401
static unsigned int get_crop_lines_for_bayer_order(const struct
@@ -396,17 +375,7 @@ static unsigned int get_crop_columns_for_bayer_order(const struct
ia_css_stream_config *config);
static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
unsigned int *extra_row, unsigned int *extra_column);
-static int
-aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
- struct ia_css_pipe *pipes[],
- bool *do_crop_status);
-
-static bool
-aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe);
-static int
-aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
- struct ia_css_resolution *effective_res);
#endif
static void
@@ -447,9 +416,10 @@ static enum ia_css_frame_format yuv422_copy_formats[] = {
IA_CSS_FRAME_FORMAT_YUYV
};
-/* Verify whether the selected output format is can be produced
+/*
+ * Verify whether the selected output format is can be produced
* by the copy binary given the stream format.
- * */
+ */
static int
verify_copy_out_frame_format(struct ia_css_pipe *pipe)
{
@@ -522,6 +492,7 @@ ia_css_stream_input_format_bits_per_pixel(struct ia_css_stream *stream)
return bpp;
}
+/* TODO: move define to proper file in tools */
#define GP_ISEL_TPG_MODE 0x90058
#if !defined(ISP2401)
@@ -573,12 +544,8 @@ sh_css_config_input_network(struct ia_css_stream *stream)
vblank_cycles = vblank_lines * (width + hblank_cycles);
sh_css_sp_configure_sync_gen(width, height, hblank_cycles,
vblank_cycles);
- if (!IS_ISP2401) {
- if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG) {
- /* TODO: move define to proper file in tools */
- ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0);
- }
- }
+ if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG)
+ ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0);
}
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"sh_css_config_input_network() leave:\n");
@@ -689,13 +656,13 @@ static unsigned int csi2_protocol_calculate_max_subpixels_per_line(
/*
* The frame format layout is shown below.
*
- * Line 0: Pixel Pixel ... Pixel
- * Line 1: Pixel Pixel ... Pixel
- * Line 2: Pixel Pixel ... Pixel
- * Line 3: Pixel Pixel ... Pixel
+ * Line 0: Pixel ... Pixel
+ * Line 1: Pixel ... Pixel
+ * Line 2: Pixel ... Pixel
+ * Line 3: Pixel ... Pixel
* ...
- * Line (n-2): Pixel Pixel ... Pixel
- * Line (n-1): Pixel Pixel ... Pixel
+ * Line (n-2): Pixel ... Pixel
+ * Line (n-1): Pixel ... Pixel
*
* In this frame format, the even-line is
* as wide as the odd-line.
@@ -906,8 +873,10 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr(
isys_stream_descr->metadata.lines_per_frame =
stream_cfg->metadata_config.resolution.height;
#ifdef ISP2401
- /* For new input system, number of str2mmio requests must be even.
- * So we round up number of metadata lines to be even. */
+ /*
+ * For new input system, number of str2mmio requests must be even.
+ * So we round up number of metadata lines to be even.
+ */
if (isys_stream_descr->metadata.lines_per_frame > 0)
isys_stream_descr->metadata.lines_per_frame +=
(isys_stream_descr->metadata.lines_per_frame & 1);
@@ -1003,22 +972,10 @@ static bool sh_css_translate_stream_cfg_to_isys_stream_descr(
isys_stream_descr->raw_packed = stream_cfg->pack_raw_pixels;
isys_stream_descr->linked_isys_stream_id = (int8_t)
stream_cfg->isys_config[isys_stream_idx].linked_isys_stream_id;
- /*
- * Early polling is required for timestamp accuracy in certain case.
- * The ISYS HW polling is started on
- * ia_css_isys_stream_capture_indication() instead of
- * ia_css_pipeline_sp_wait_for_isys_stream_N() as isp processing of
- * capture takes longer than getting an ISYS frame
- *
- * Only 2401 relevant ??
- */
-#if 0 // FIXME: NOT USED on Yocto Aero
- isys_stream_descr->polling_mode
- = early_polling ? INPUT_SYSTEM_POLL_ON_CAPTURE_REQUEST
- : INPUT_SYSTEM_POLL_ON_WAIT_FOR_FRAME;
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "sh_css_translate_stream_cfg_to_isys_stream_descr() leave:\n");
-#endif
+
+ if (IS_ISP2401)
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+ "sh_css_translate_stream_cfg_to_isys_stream_descr() leave:\n");
return rc;
}
@@ -1065,17 +1022,6 @@ sh_css_config_input_network(struct ia_css_stream *stream)
pipe = stream->last_pipe->pipe_settings.video.copy_pipe;
} else {
pipe = stream->last_pipe;
- if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
- /*
- * We need to poll the ISYS HW in capture_indication itself
- * for "non-continuous" capture usecase for getting accurate
- * isys frame capture timestamps.
- * This is because the capturepipe propcessing takes longer
- * to execute than the input system frame capture.
- * 2401 specific
- */
- early_polling = true;
- }
}
if (!pipe)
@@ -1086,7 +1032,8 @@ sh_css_config_input_network(struct ia_css_stream *stream)
binary = pipe->pipeline.stages->binary;
if (binary) {
- /* this was being done in ifmtr in 2400.
+ /*
+ * this was being done in ifmtr in 2400.
* online and cont bypass the init_in_frameinfo_memory_defaults
* so need to do it here
*/
@@ -1259,89 +1206,6 @@ static inline int stream_unregister_with_csi_rx(
}
#endif
-#if WITH_PC_MONITORING
-static struct task_struct *my_kthread; /* Handle for the monitoring thread */
-static int sh_binary_running; /* Enable sampling in the thread */
-
-static void print_pc_histo(char *core_name, struct sh_css_pc_histogram *hist)
-{
- unsigned int i;
- unsigned int cnt_run = 0;
- unsigned int cnt_stall = 0;
-
- if (!hist)
- return;
-
- sh_css_print("%s histogram length = %d\n", core_name, hist->length);
- sh_css_print("%s PC\turn\tstall\n", core_name);
-
- for (i = 0; i < hist->length; i++) {
- if ((hist->run[i] == 0) && (hist->run[i] == hist->stall[i]))
- continue;
- sh_css_print("%s %d\t%d\t%d\n",
- core_name, i, hist->run[i], hist->stall[i]);
- cnt_run += hist->run[i];
- cnt_stall += hist->stall[i];
- }
-
- sh_css_print(" Statistics for %s, cnt_run = %d, cnt_stall = %d, hist->length = %d\n",
- core_name, cnt_run, cnt_stall, hist->length);
-}
-
-static void print_pc_histogram(void)
-{
- struct ia_css_binary_metrics *metrics;
-
- for (metrics = sh_css_metrics.binary_metrics;
- metrics;
- metrics = metrics->next) {
- if (metrics->mode == IA_CSS_BINARY_MODE_PREVIEW ||
- metrics->mode == IA_CSS_BINARY_MODE_VF_PP) {
- sh_css_print("pc_histogram for binary %d is SKIPPED\n",
- metrics->id);
- continue;
- }
-
- sh_css_print(" pc_histogram for binary %d\n", metrics->id);
- print_pc_histo(" ISP", &metrics->isp_histogram);
- print_pc_histo(" SP", &metrics->sp_histogram);
- sh_css_print("print_pc_histogram() done for binary->id = %d, done.\n",
- metrics->id);
- }
-
- sh_css_print("PC_MONITORING:print_pc_histogram() -- DONE\n");
-}
-
-static int pc_monitoring(void *data)
-{
- int i = 0;
-
- (void)data;
- while (true) {
- if (sh_binary_running) {
- sh_css_metrics_sample_pcs();
-#if MULTIPLE_SAMPLES
- for (i = 0; i < NOF_SAMPLES; i++)
- sh_css_metrics_sample_pcs();
-#endif
- }
- usleep_range(10, 50);
- }
- return 0;
-}
-
-static void spying_thread_create(void)
-{
- my_kthread = kthread_run(pc_monitoring, NULL, "sh_pc_monitor");
- sh_css_metrics_enable_pc_histogram(1);
-}
-
-static void input_frame_info(struct ia_css_frame_info frame_info)
-{
- sh_css_print("SH_CSS:input_frame_info() -- frame->info.res.width = %d, frame->info.res.height = %d, format = %d\n",
- frame_info.res.width, frame_info.res.height, frame_info.format);
-}
-#endif /* WITH_PC_MONITORING */
static void
start_binary(struct ia_css_pipe *pipe,
@@ -1353,15 +1217,6 @@ start_binary(struct ia_css_pipe *pipe,
if (binary)
sh_css_metrics_start_binary(&binary->metrics);
-#if WITH_PC_MONITORING
- sh_css_print("PC_MONITORING: %s() -- binary id = %d , enable_dvs_envelope = %d\n",
- __func__, binary->info->sp.id,
- binary->info->sp.enable.dvs_envelope);
- input_frame_info(binary->in_frame_info);
-
- if (binary && binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_VIDEO)
- sh_binary_running = true;
-#endif
#if !defined(ISP2401)
if (pipe->stream->reconfigure_css_rx) {
@@ -1406,7 +1261,7 @@ void sh_css_binary_args_reset(struct sh_css_binary_args *args)
{
unsigned int i;
- for (i = 0; i < NUM_TNR_FRAMES; i++)
+ for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++)
args->tnr_frames[i] = NULL;
for (i = 0; i < MAX_NUM_VIDEO_DELAY_FRAMES; i++)
args->delay_frames[i] = NULL;
@@ -1424,20 +1279,11 @@ static void start_pipe(
enum sh_css_pipe_config_override copy_ovrd,
enum ia_css_input_mode input_mode)
{
- const struct ia_css_coordinate *coord = NULL;
- const struct ia_css_isp_parameters *params = NULL;
-
-
IA_CSS_ENTER_PRIVATE("me = %p, copy_ovrd = %d, input_mode = %d",
me, copy_ovrd, input_mode);
assert(me); /* all callers are in this file and call with non null argument */
- if (!IS_ISP2401) {
- coord = &me->config.internal_frame_origin_bqs_on_sctbl;
- params = me->stream->isp_params_configs;
- }
-
sh_css_sp_init_pipeline(&me->pipeline,
me->mode,
(uint8_t)ia_css_pipe_get_pipe_num(me),
@@ -1452,9 +1298,7 @@ static void start_pipe(
&me->stream->info.metadata_info
, (input_mode == IA_CSS_INPUT_MODE_MEMORY) ?
(enum mipi_port_id)0 :
- me->stream->config.source.port.port,
- coord,
- params);
+ me->stream->config.source.port.port);
if (me->config.mode != IA_CSS_PIPE_MODE_COPY) {
struct ia_css_pipeline_stage *stage;
@@ -1565,17 +1409,18 @@ ia_css_reset_defaults(struct sh_css *css)
/* Reset everything to zero */
memset(&default_css, 0, sizeof(default_css));
- /* Initialize the non zero values*/
+ /* Initialize the non zero values */
default_css.check_system_idle = true;
default_css.num_cont_raw_frames = NUM_CONTINUOUS_FRAMES;
- /* All should be 0: but memset does it already.
+ /*
+ * All should be 0: but memset does it already.
* default_css.num_mipi_frames[N_CSI_PORTS] = 0;
*/
default_css.irq_type = IA_CSS_IRQ_TYPE_EDGE;
- /*Set the defaults to the output */
+ /* Set the defaults to the output */
*css = default_css;
}
@@ -1638,6 +1483,7 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
* the SIZE_OF_XXX macro of the corresponding struct. If they are not
* equal, functionality will break.
*/
+
/* Check struct sh_css_ddr_address_map */
COMPILATION_ERROR_IF(sizeof(struct sh_css_ddr_address_map) != SIZE_OF_SH_CSS_DDR_ADDRESS_MAP_STRUCT);
/* Check struct host_sp_queues */
@@ -1707,8 +1553,11 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
mipi_init();
#ifndef ISP2401
- /* In case this has been programmed already, update internal
- data structure ... DEPRECATED */
+ /*
+ * In case this has been programmed already, update internal
+ * data structure ...
+ * DEPRECATED
+ */
my_css.page_table_base_index = mmu_get_page_table_base_index(MMU0_ID);
#endif
@@ -1746,9 +1595,8 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
return err;
}
fw_explicitly_loaded = false;
-#ifndef ISP2401
+
my_css_save.loaded_fw = (struct ia_css_fw *)fw;
-#endif
}
if (!sh_css_setup_spctrl_config(&sh_css_sp_fw, SP_PROG_NAME, &spctrl_cfg))
return -EINVAL;
@@ -1759,24 +1607,17 @@ ia_css_init(struct device *dev, const struct ia_css_env *env,
return err;
}
-#if WITH_PC_MONITORING
- if (!thread_alive) {
- thread_alive++;
- sh_css_print("PC_MONITORING: %s() -- create thread DISABLED\n",
- __func__);
- spying_thread_create();
- }
-#endif
if (!sh_css_hrt_system_is_idle()) {
IA_CSS_LEAVE_ERR(-EBUSY);
return -EBUSY;
}
- /* can be called here, queuing works, but:
- - when sp is started later, it will wipe queued items
- so for now we leave it for later and make sure
- updates are not called to frequently.
- sh_css_init_buffer_queues();
- */
+ /*
+ * can be called here, queuing works, but:
+ * - when sp is started later, it will wipe queued items
+ * so for now we leave it for later and make sure
+ * updates are not called to frequently.
+ * sh_css_init_buffer_queues();
+ */
#if defined(ISP2401)
gp_device_reg_store(GP_DEVICE0_ID, _REG_GP_SWITCH_ISYS2401_ADDR, 1);
@@ -1817,10 +1658,12 @@ sh_css_flush(struct ia_css_acc_fw *fw)
my_css.flush(fw);
}
-/* Mapping sp threads. Currently, this is done when a stream is created and
+/*
+ * Mapping sp threads. Currently, this is done when a stream is created and
* pipelines are ready to be converted to sp pipelines. Be careful if you are
* doing it from stream_create since we could run out of sp threads due to
- * allocation on inactive pipelines. */
+ * allocation on inactive pipelines.
+ */
static int
map_sp_threads(struct ia_css_stream *stream, bool map)
{
@@ -1884,8 +1727,10 @@ map_sp_threads(struct ia_css_stream *stream, bool map)
return err;
}
-/* creates a host pipeline skeleton for all pipes in a stream. Called during
- * stream_create. */
+/*
+ * creates a host pipeline skeleton for all pipes in a stream. Called during
+ * stream_create.
+ */
static int
create_host_pipeline_structure(struct ia_css_stream *stream)
{
@@ -1984,8 +1829,10 @@ create_host_pipeline_structure(struct ia_css_stream *stream)
return err;
}
-/* creates a host pipeline for all pipes in a stream. Called during
- * stream_start. */
+/*
+ * creates a host pipeline for all pipes in a stream. Called during
+ * stream_start.
+ */
static int
create_host_pipeline(struct ia_css_stream *stream)
{
@@ -2005,15 +1852,25 @@ create_host_pipeline(struct ia_css_stream *stream)
main_pipe = stream->last_pipe;
pipe_id = main_pipe->mode;
- /* No continuous frame allocation for capture pipe. It uses the
- * "main" pipe's frames. */
+ /*
+ * No continuous frame allocation for capture pipe. It uses the
+ * "main" pipe's frames.
+ */
if ((pipe_id == IA_CSS_PIPE_ID_PREVIEW) ||
(pipe_id == IA_CSS_PIPE_ID_VIDEO)) {
- /* About pipe_id == IA_CSS_PIPE_ID_PREVIEW && stream->config.mode != IA_CSS_INPUT_MODE_MEMORY:
- * The original condition pipe_id == IA_CSS_PIPE_ID_PREVIEW is too strong. E.g. in SkyCam (with memory
- * based input frames) there is no continuous mode and thus no need for allocated continuous frames
- * This is not only for SkyCam but for all preview cases that use DDR based input frames. For this
- * reason the stream->config.mode != IA_CSS_INPUT_MODE_MEMORY has beed added.
+ /*
+ * About
+ * pipe_id == IA_CSS_PIPE_ID_PREVIEW &&
+ * stream->config.mode != IA_CSS_INPUT_MODE_MEMORY:
+ *
+ * The original condition pipe_id == IA_CSS_PIPE_ID_PREVIEW is
+ * too strong. E.g. in SkyCam (with memory based input frames)
+ * there is no continuous mode and thus no need for allocated
+ * continuous frames.
+ * This is not only for SkyCam but for all preview cases that
+ * use DDR based input frames. For this reason the
+ * stream->config.mode != IA_CSS_INPUT_MODE_MEMORY has beed
+ * added.
*/
if (stream->config.continuous ||
(pipe_id == IA_CSS_PIPE_ID_PREVIEW &&
@@ -2223,7 +2080,7 @@ pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
/* Assign a new pipe_num .... search for empty place */
for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
if (!my_css.all_pipes[i]) {
- /*position is reserved */
+ /* position is reserved */
my_css.all_pipes[i] = (struct ia_css_pipe *)pipe;
pipe_num = i;
break;
@@ -2340,8 +2197,10 @@ ia_css_pipe_destroy(struct ia_css_pipe *pipe)
switch (pipe->config.mode) {
case IA_CSS_PIPE_MODE_PREVIEW:
- /* need to take into account that this function is also called
- on the internal copy pipe */
+ /*
+ * need to take into account that this function is also called
+ * on the internal copy pipe
+ */
if (pipe->mode == IA_CSS_PIPE_ID_PREVIEW) {
ia_css_frame_free_multiple(NUM_CONTINUOUS_FRAMES,
pipe->continuous_frames);
@@ -2369,10 +2228,10 @@ ia_css_pipe_destroy(struct ia_css_pipe *pipe)
}
}
#ifndef ISP2401
- ia_css_frame_free_multiple(NUM_TNR_FRAMES,
+ ia_css_frame_free_multiple(NUM_VIDEO_TNR_FRAMES,
pipe->pipe_settings.video.tnr_frames);
#else
- ia_css_frame_free_multiple(NUM_TNR_FRAMES,
+ ia_css_frame_free_multiple(NUM_VIDEO_TNR_FRAMES,
pipe->pipe_settings.video.tnr_frames);
#endif
ia_css_frame_free_multiple(MAX_NUM_VIDEO_DELAY_FRAMES,
@@ -2391,8 +2250,10 @@ ia_css_pipe_destroy(struct ia_css_pipe *pipe)
break;
}
- sh_css_params_free_gdc_lut(pipe->scaler_pp_lut);
- pipe->scaler_pp_lut = mmgr_NULL;
+ if (pipe->scaler_pp_lut != mmgr_NULL) {
+ hmm_free(pipe->scaler_pp_lut);
+ pipe->scaler_pp_lut = mmgr_NULL;
+ }
my_css.active_pipes[ia_css_pipe_get_pipe_num(pipe)] = NULL;
sh_css_pipe_free_shading_table(pipe);
@@ -2413,15 +2274,13 @@ void
ia_css_uninit(void)
{
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_uninit() enter: void\n");
-#if WITH_PC_MONITORING
- sh_css_print("PC_MONITORING: %s() -- started\n", __func__);
- print_pc_histogram();
-#endif
sh_css_params_free_default_gdc_lut();
/* TODO: JB: implement decent check and handling of freeing mipi frames */
- //assert(ref_count_mipi_allocation == 0); //mipi frames are not freed
+ if (!mipi_is_free())
+ dev_warn(atomisp_dev, "mipi frames are not freed.\n");
+
/* cleanup generic data */
sh_css_params_uninit();
ia_css_refcount_uninit();
@@ -2465,16 +2324,13 @@ int ia_css_irq_translate(
if (status == hrt_isp_css_irq_status_error)
return -EINVAL;
-#if WITH_PC_MONITORING
- sh_css_print("PC_MONITORING: %s() irq = %d, sh_binary_running set to 0\n",
- __func__, irq);
- sh_binary_running = 0;
-#endif
switch (irq) {
case virq_sp:
- /* When SP goes to idle, info is available in the
- * event queue. */
+ /*
+ * When SP goes to idle, info is available in the
+ * event queue.
+ */
infos |= IA_CSS_IRQ_INFO_EVENTS_READY;
break;
case virq_isp:
@@ -2582,8 +2438,10 @@ sh_css_get_sw_interrupt_value(unsigned int irq)
return irq_value;
}
-/* configure and load the copy binary, the next binary is used to
- determine whether the copy binary needs to do left padding. */
+/*
+ * configure and load the copy binary, the next binary is used to
+ * determine whether the copy binary needs to do left padding.
+ */
static int load_copy_binary(
struct ia_css_pipe *pipe,
struct ia_css_binary *copy_binary,
@@ -2670,13 +2528,11 @@ alloc_continuous_frames(struct ia_css_pipe *pipe, bool init_time)
ref_info.padded_width = CEIL_MUL(ref_info.res.width, 2 * ISP_VEC_NELEMS);
#endif
-#if !defined(HAS_NO_PACKED_RAW_PIXELS)
if (pipe->stream->config.pack_raw_pixels) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW_PACKED\n");
ref_info.format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
} else
-#endif
{
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW\n");
@@ -2780,7 +2636,8 @@ load_preview_binaries(struct ia_css_pipe *pipe)
if (err)
return err;
- /* Note: the current selection of vf_pp binary and
+ /*
+ * Note: the current selection of vf_pp binary and
* parameterization of the preview binary contains a few pieces
* of hardcoded knowledge. This needs to be cleaned up such that
* the binary selection becomes more generic.
@@ -2793,7 +2650,7 @@ load_preview_binaries(struct ia_css_pipe *pipe)
* The decision if the vf_pp binary is needed for YUV downscaling is
* made after the preview binary selection, since some preview binaries
* can perform the requested YUV downscaling.
- * */
+ */
need_vf_pp = pipe->config.enable_dz;
need_vf_pp |= pipe_out_info->format != IA_CSS_FRAME_FORMAT_YUV_LINE &&
!(pipe_out_info->format == IA_CSS_FRAME_FORMAT_NV12 ||
@@ -2805,11 +2662,12 @@ load_preview_binaries(struct ia_css_pipe *pipe)
prev_vf_info = pipe->vf_yuv_ds_input_info;
else
prev_vf_info = *pipe_out_info;
- /* If vf_pp is needed, then preview must output yuv_line.
+ /*
+ * If vf_pp is needed, then preview must output yuv_line.
* The exception is when vf_pp is manually disabled, that is only
* used in combination with a pipeline extension that requires
* yuv_line as input.
- * */
+ */
if (need_vf_pp)
ia_css_frame_info_set_format(&prev_vf_info,
IA_CSS_FRAME_FORMAT_YUV_LINE);
@@ -2827,22 +2685,12 @@ load_preview_binaries(struct ia_css_pipe *pipe)
if (err)
return err;
- if (IS_ISP2401) {
- /* The delay latency determines the number of invalid frames after
- * a stream is started. */
- pipe->num_invalid_frames = pipe->dvs_frame_delay;
- pipe->info.num_invalid_frames = pipe->num_invalid_frames;
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
- "load_preview_binaries() num_invalid_frames=%d dvs_frame_delay=%d\n",
- pipe->num_invalid_frames, pipe->dvs_frame_delay);
- }
-
/* The vf_pp binary is needed when (further) YUV downscaling is required */
need_vf_pp |= mycs->preview_binary.out_frame_info[0].res.width != pipe_out_info->res.width;
need_vf_pp |= mycs->preview_binary.out_frame_info[0].res.height != pipe_out_info->res.height;
- /* When vf_pp is needed, then the output format of the selected
+ /*
+ * When vf_pp is needed, then the output format of the selected
* preview binary must be yuv_line. If this is not the case,
* then the preview binary selection is done again.
*/
@@ -2886,12 +2734,14 @@ load_preview_binaries(struct ia_css_pipe *pipe)
}
#ifdef ISP2401
- /* When the input system is 2401, only the Direct Sensor Mode
+ /*
+ * When the input system is 2401, only the Direct Sensor Mode
* Offline Preview uses the ISP copy binary.
*/
need_isp_copy_binary = !online && sensor;
#else
- /* About pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY:
+ /*
+ * About pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY:
* This is typical the case with SkyCam (which has no input system) but it also applies to all cases
* where the driver chooses for memory based input frames. In these cases, a copy binary (which typical
* copies sensor data to DDR) does not have much use.
@@ -3245,8 +3095,10 @@ get_crop_columns_for_bayer_order(const struct ia_css_stream_config *config)
return 0;
}
-/* This function is to get the sum of all extra pixels in addition to the effective
- * input, it includes dvs envelop and filter run-in */
+/*
+ * This function is to get the sum of all extra pixels in addition to the effective
+ * input, it includes dvs envelop and filter run-in
+ */
static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
unsigned int *extra_row, unsigned int *extra_column)
{
@@ -3255,7 +3107,8 @@ static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
unsigned int i;
struct ia_css_resolution dvs_env = pipe->config.dvs_envelope;
- /* The dvs envelope info may not be correctly sent down via pipe config
+ /*
+ * The dvs envelope info may not be correctly sent down via pipe config
* The check is made and the correct value is populated in the binary info
* Use this value when computing crop, else excess lines may get trimmed
*/
@@ -3349,7 +3202,8 @@ ia_css_get_crop_offsets(
* 2. Require the special support for the online use cases.
*/
- /* ISP expects GRBG bayer order, we skip one line and/or one row
+ /*
+ * ISP expects GRBG bayer order, we skip one line and/or one row
* to correct in case the input bayer order is different.
*/
column += get_crop_columns_for_bayer_order(&pipe->stream->config);
@@ -3467,7 +3321,8 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe)
me->dvs_frame_delay = pipe->dvs_frame_delay;
#ifdef ISP2401
- /* When the input system is 2401, always enable 'in_frameinfo_memory'
+ /*
+ * When the input system is 2401, always enable 'in_frameinfo_memory'
* except for the following: online or continuous
*/
need_in_frameinfo_memory = !(pipe->stream->config.online ||
@@ -3523,7 +3378,8 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe)
in_frame = me->stages->args.out_frame[0];
} else if (pipe->stream->config.continuous) {
#ifdef ISP2401
- /* When continuous is enabled, configure in_frame with the
+ /*
+ * When continuous is enabled, configure in_frame with the
* last pipe, which is the copy pipe.
*/
in_frame = pipe->stream->last_pipe->continuous_frames[0];
@@ -3535,8 +3391,10 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe)
ia_css_pipe_util_set_output_frames(out_frames, 0,
need_yuv_pp ? NULL : out_frame);
- /* when the video binary supports a second output pin,
- it can directly produce the vf_frame. */
+ /*
+ * when the video binary supports a second output pin,
+ * it can directly produce the vf_frame.
+ */
if (need_vf_pp) {
ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary,
out_frames, in_frame, NULL);
@@ -3568,7 +3426,7 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe)
if (video_stage) {
int frm;
- for (frm = 0; frm < NUM_TNR_FRAMES; frm++) {
+ for (frm = 0; frm < NUM_VIDEO_TNR_FRAMES; frm++) {
video_stage->args.tnr_frames[frm] =
pipe->pipe_settings.video.tnr_frames[frm];
}
@@ -3708,7 +3566,8 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe)
ia_css_pipeline_clean(me);
#ifdef ISP2401
- /* When the input system is 2401, always enable 'in_frameinfo_memory'
+ /*
+ * When the input system is 2401, always enable 'in_frameinfo_memory'
* except for the following:
* - Direct Sensor Mode Online Preview
* - Buffered Sensor Mode Online Preview
@@ -3757,7 +3616,8 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe)
in_frame = me->stages->args.out_frame[0];
} else if (pipe->stream->config.continuous) {
#ifdef ISP2401
- /* When continuous is enabled, configure in_frame with the
+ /*
+ * When continuous is enabled, configure in_frame with the
* last pipe, which is the copy pipe.
*/
if (continuous || !online)
@@ -3837,8 +3697,7 @@ preview_start(struct ia_css_pipe *pipe)
struct ia_css_pipe *acc_pipe;
enum sh_css_pipe_config_override copy_ovrd;
enum ia_css_input_mode preview_pipe_input_mode;
- const struct ia_css_coordinate *coord = NULL;
- const struct ia_css_isp_parameters *params = NULL;
+ unsigned int thread_id;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
@@ -3862,22 +3721,13 @@ preview_start(struct ia_css_pipe *pipe)
}
send_raw_frames(pipe);
- {
- unsigned int thread_id;
-
- ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
- copy_ovrd = 1 << thread_id;
-
- if (pipe->stream->cont_capt) {
- ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe),
- &thread_id);
- copy_ovrd |= 1 << thread_id;
- }
- }
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ copy_ovrd = 1 << thread_id;
- if (IS_ISP2401) {
- coord = &pipe->config.internal_frame_origin_bqs_on_sctbl;
- params = pipe->stream->isp_params_configs;
+ if (pipe->stream->cont_capt) {
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe),
+ &thread_id);
+ copy_ovrd |= 1 << thread_id;
}
/* Construct and load the copy pipe */
@@ -3892,12 +3742,12 @@ preview_start(struct ia_css_pipe *pipe)
pipe->stream->config.mode,
&pipe->stream->config.metadata_config,
&pipe->stream->info.metadata_info,
- pipe->stream->config.source.port.port,
- coord,
- params);
+ pipe->stream->config.source.port.port);
- /* make the preview pipe start with mem mode input, copy handles
- the actual mode */
+ /*
+ * make the preview pipe start with mem mode input, copy handles
+ * the actual mode
+ */
preview_pipe_input_mode = IA_CSS_INPUT_MODE_MEMORY;
}
@@ -3915,9 +3765,7 @@ preview_start(struct ia_css_pipe *pipe)
IA_CSS_INPUT_MODE_MEMORY,
&pipe->stream->config.metadata_config,
&pipe->stream->info.metadata_info,
- (enum mipi_port_id)0,
- coord,
- params);
+ (enum mipi_port_id)0);
}
if (acc_pipe) {
@@ -3933,9 +3781,7 @@ preview_start(struct ia_css_pipe *pipe)
IA_CSS_INPUT_MODE_MEMORY,
NULL,
NULL,
- (enum mipi_port_id)0,
- coord,
- params);
+ (enum mipi_port_id)0);
}
start_pipe(pipe, copy_ovrd, preview_pipe_input_mode);
@@ -3968,38 +3814,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
}
buf_type = buffer->type;
- /* following code will be enabled when IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME
- is removed */
-#if 0
- if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) {
- bool found_pipe = false;
-
- for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
- if ((buffer->data.frame->info.res.width == pipe->output_info[i].res.width) &&
- (buffer->data.frame->info.res.height == pipe->output_info[i].res.height)) {
- buf_type += i;
- found_pipe = true;
- break;
- }
- }
- if (!found_pipe)
- return -EINVAL;
- }
- if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
- bool found_pipe = false;
- for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
- if ((buffer->data.frame->info.res.width == pipe->vf_output_info[i].res.width) &&
- (buffer->data.frame->info.res.height == pipe->vf_output_info[i].res.height)) {
- buf_type += i;
- found_pipe = true;
- break;
- }
- }
- if (!found_pipe)
- return -EINVAL;
- }
-#endif
pipe_id = pipe->mode;
IA_CSS_LOG("pipe_id=%d, buf_type=%d", pipe_id, buf_type);
@@ -4086,15 +3901,6 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
"ia_css_pipe_enqueue_buffer() buf_type=%d, data(DDR address)=0x%x\n",
buf_type, buffer->data.frame->data);
-#if CONFIG_ON_FRAME_ENQUEUE()
- return_err = set_config_on_frame_enqueue(
- &buffer->data.frame->info,
- &ddr_buffer.payload.frame);
- if (return_err) {
- IA_CSS_LEAVE_ERR(return_err);
- return return_err;
- }
-#endif
}
/* start of test for using rmgr for acq/rel memory */
@@ -4124,8 +3930,10 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
}
for (stage = pipeline->stages; stage; stage = stage->next) {
- /* The SP will read the params
- after it got empty 3a and dis */
+ /*
+ * The SP will read the params after it got
+ * empty 3a and dis
+ */
if (STATS_ENABLED(stage)) {
/* there is a stage that needs it */
return_err = ia_css_bufq_enqueue_buffer(thread_id,
@@ -4142,14 +3950,12 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
return_err = ia_css_bufq_enqueue_buffer(thread_id,
queue_id,
(uint32_t)h_vbuf->vptr);
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
if (!return_err &&
buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) {
IA_CSS_LOG("pfp: enqueued OF %d to q %d thread %d",
ddr_buffer.payload.frame.frame_data,
queue_id, thread_id);
}
-#endif
}
if (!return_err) {
@@ -4191,7 +3997,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
/*
* TODO: Free up the hmm memory space.
- */
+ */
int
ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
struct ia_css_buffer *buffer)
@@ -4258,7 +4064,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
hmm_buffer_record = sh_css_hmm_buffer_record_validate(
ddr_buffer_addr, buf_type);
if (hmm_buffer_record) {
- /* valid hmm_buffer_record found. Save the kernel_ptr
+ /*
+ * valid hmm_buffer_record found. Save the kernel_ptr
* for validation after performing hmm_load. The
* vbuf handle and buffer_record can be released.
*/
@@ -4276,7 +4083,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
&ddr_buffer,
sizeof(struct sh_css_hmm_buffer));
- /* if the kernel_ptr is 0 or an invalid, return an error.
+ /*
+ * if the kernel_ptr is 0 or an invalid, return an error.
* do not access the buffer via the kernal_ptr.
*/
if ((ddr_buffer.kernel_ptr == 0) ||
@@ -4290,8 +4098,11 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
}
if (ddr_buffer.kernel_ptr != 0) {
- /* buffer->exp_id : all instances to be removed later once the driver change
- * is completed. See patch #5758 for reference */
+ /*
+ * buffer->exp_id : all instances to be removed later
+ * once the driver change is completed. See patch #5758
+ * for reference
+ */
buffer->exp_id = 0;
buffer->driver_cookie = ddr_buffer.cookie_ptr;
buffer->timing_data = ddr_buffer.timing_data;
@@ -4307,8 +4118,10 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
if (pipe && pipe->stop_requested) {
#if !defined(ISP2401)
- /* free mipi frames only for old input system
- * for 2401 it is done in ia_css_stream_destroy call
+ /*
+ * free mipi frames only for old input
+ * system for 2401 it is done in
+ * ia_css_stream_destroy call
*/
return_err = free_mipi_frames(pipe);
if (return_err) {
@@ -4345,12 +4158,10 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
sh_css_sp_get_binary_copy_size();
#endif
}
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) {
IA_CSS_LOG("pfp: dequeued OF %d with config id %d thread %d",
frame->data, frame->isp_config_id, thread_id);
}
-#endif
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
"ia_css_pipe_dequeue_buffer() buf_type=%d, data(DDR address)=0x%x\n",
@@ -4419,45 +4230,41 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
* 4) "enum ia_css_event_type convert_event_sp_to_host_domain" (sh_css.c)
*/
static enum ia_css_event_type convert_event_sp_to_host_domain[] = {
- IA_CSS_EVENT_TYPE_OUTPUT_FRAME_DONE, /** Output frame ready. */
- IA_CSS_EVENT_TYPE_SECOND_OUTPUT_FRAME_DONE, /** Second output frame ready. */
- IA_CSS_EVENT_TYPE_VF_OUTPUT_FRAME_DONE, /** Viewfinder Output frame ready. */
- IA_CSS_EVENT_TYPE_SECOND_VF_OUTPUT_FRAME_DONE, /** Second viewfinder Output frame ready. */
- IA_CSS_EVENT_TYPE_3A_STATISTICS_DONE, /** Indication that 3A statistics are available. */
- IA_CSS_EVENT_TYPE_DIS_STATISTICS_DONE, /** Indication that DIS statistics are available. */
- IA_CSS_EVENT_TYPE_PIPELINE_DONE, /** Pipeline Done event, sent after last pipeline stage. */
- IA_CSS_EVENT_TYPE_FRAME_TAGGED, /** Frame tagged. */
- IA_CSS_EVENT_TYPE_INPUT_FRAME_DONE, /** Input frame ready. */
- IA_CSS_EVENT_TYPE_METADATA_DONE, /** Metadata ready. */
- IA_CSS_EVENT_TYPE_LACE_STATISTICS_DONE, /** Indication that LACE statistics are available. */
- IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE, /** Extension stage executed. */
- IA_CSS_EVENT_TYPE_TIMER, /** Timing measurement data. */
- IA_CSS_EVENT_TYPE_PORT_EOF, /** End Of Frame event, sent when in buffered sensor mode. */
- IA_CSS_EVENT_TYPE_FW_WARNING, /** Performance warning encountered by FW */
- IA_CSS_EVENT_TYPE_FW_ASSERT, /** Assertion hit by FW */
+ IA_CSS_EVENT_TYPE_OUTPUT_FRAME_DONE, /* Output frame ready. */
+ IA_CSS_EVENT_TYPE_SECOND_OUTPUT_FRAME_DONE, /* Second output frame ready. */
+ IA_CSS_EVENT_TYPE_VF_OUTPUT_FRAME_DONE, /* Viewfinder Output frame ready. */
+ IA_CSS_EVENT_TYPE_SECOND_VF_OUTPUT_FRAME_DONE, /* Second viewfinder Output frame ready. */
+ IA_CSS_EVENT_TYPE_3A_STATISTICS_DONE, /* Indication that 3A statistics are available. */
+ IA_CSS_EVENT_TYPE_DIS_STATISTICS_DONE, /* Indication that DIS statistics are available. */
+ IA_CSS_EVENT_TYPE_PIPELINE_DONE, /* Pipeline Done event, sent after last pipeline stage. */
+ IA_CSS_EVENT_TYPE_FRAME_TAGGED, /* Frame tagged. */
+ IA_CSS_EVENT_TYPE_INPUT_FRAME_DONE, /* Input frame ready. */
+ IA_CSS_EVENT_TYPE_METADATA_DONE, /* Metadata ready. */
+ IA_CSS_EVENT_TYPE_LACE_STATISTICS_DONE, /* Indication that LACE statistics are available. */
+ IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE, /* Extension stage executed. */
+ IA_CSS_EVENT_TYPE_TIMER, /* Timing measurement data. */
+ IA_CSS_EVENT_TYPE_PORT_EOF, /* End Of Frame event, sent when in buffered sensor mode. */
+ IA_CSS_EVENT_TYPE_FW_WARNING, /* Performance warning encountered by FW */
+ IA_CSS_EVENT_TYPE_FW_ASSERT, /* Assertion hit by FW */
0, /* error if sp passes SH_CSS_SP_EVENT_NR_OF_TYPES as a valid event. */
};
int
-ia_css_dequeue_event(struct ia_css_event *event)
-{
- return ia_css_dequeue_psys_event(event);
-}
-
-int
ia_css_dequeue_psys_event(struct ia_css_event *event)
{
enum ia_css_pipe_id pipe_id = 0;
u8 payload[4] = {0, 0, 0, 0};
int ret_err;
- /*TODO:
+ /*
+ * TODO:
* a) use generic decoding function , same as the one used by sp.
* b) group decode and dequeue into eventQueue module
*
* We skip the IA_CSS_ENTER logging call
* to avoid flooding the logs when the host application
- * uses polling. */
+ * uses polling.
+ */
if (!event)
return -EINVAL;
@@ -4476,9 +4283,11 @@ ia_css_dequeue_psys_event(struct ia_css_event *event)
ia_css_bufq_enqueue_psys_event(
IA_CSS_PSYS_SW_EVENT_EVENT_DEQUEUED, 0, 0, 0);
- /* Events are decoded into 4 bytes of payload, the first byte
+ /*
+ * Events are decoded into 4 bytes of payload, the first byte
* contains the sp event type. This is converted to a host enum.
- * TODO: can this enum conversion be eliminated */
+ * TODO: can this enum conversion be eliminated
+ */
event->type = convert_event_sp_to_host_domain[payload[0]];
/* Some sane default values since not all events use all fields. */
event->pipe = NULL;
@@ -4491,7 +4300,10 @@ ia_css_dequeue_psys_event(struct ia_css_event *event)
event->timer_subcode = 0;
if (event->type == IA_CSS_EVENT_TYPE_TIMER) {
- /* timer event ??? get the 2nd event and decode the data into the event struct */
+ /*
+ * timer event ??? get the 2nd event and decode the data
+ * into the event struct
+ */
u32 tmp_data;
/* 1st event: LSB 16-bit timer data and code */
event->timer_data = ((payload[1] & 0xFF) | ((payload[3] & 0xFF) << 8));
@@ -4500,8 +4312,10 @@ ia_css_dequeue_psys_event(struct ia_css_event *event)
ret_err = ia_css_bufq_dequeue_psys_event(payload);
if (ret_err) {
/* no 2nd event ??? an error */
- /* Putting IA_CSS_ERROR is resulting in failures in
- * Merrifield smoke testing */
+ /*
+ * Putting IA_CSS_ERROR is resulting in failures in
+ * Merrifield smoke testing
+ */
IA_CSS_WARNING("Timer: Error de-queuing the 2nd TIMER event!!!\n");
return ret_err;
}
@@ -4515,11 +4329,15 @@ ia_css_dequeue_psys_event(struct ia_css_event *event)
event->timer_data |= (tmp_data << 16);
event->timer_subcode = payload[2];
} else {
- /* It's a non timer event. So clear first half of the timer event data.
- * If the second part of the TIMER event is not received, we discard
- * the first half of the timer data and process the non timer event without
- * affecting the flow. So the non timer event falls through
- * the code. */
+ /*
+ * It's a non timer event. So clear first half of the
+ * timer event data.
+ * If the second part of the TIMER event is not
+ * received, we discard the first half of the timer
+ * data and process the non timer event without
+ * affecting the flow. So the non timer event falls
+ * through the code.
+ */
event->timer_data = 0;
event->timer_code = 0;
event->timer_subcode = 0;
@@ -4540,9 +4358,11 @@ ia_css_dequeue_psys_event(struct ia_css_event *event)
event->fw_assert_line_no = (payload[2] << 8) + payload[3];
/* payload[2] is line_no>>8, payload[3] is line_no&0xff */
} else if (event->type != IA_CSS_EVENT_TYPE_TIMER) {
- /* pipe related events.
+ /*
+ * pipe related events.
* payload[1] contains the pipe_num,
- * payload[2] contains the pipe_id. These are different. */
+ * payload[2] contains the pipe_id. These are different.
+ */
event->pipe = find_pipe_by_num(payload[1]);
pipe_id = (enum ia_css_pipe_id)payload[2];
/* Check to see if pipe still exists */
@@ -4594,9 +4414,11 @@ ia_css_dequeue_isys_event(struct ia_css_event *event)
u8 payload[4] = {0, 0, 0, 0};
int err = 0;
- /* We skip the IA_CSS_ENTER logging call
+ /*
+ * We skip the IA_CSS_ENTER logging call
* to avoid flooding the logs when the host application
- * uses polling. */
+ * uses polling.
+ */
if (!event)
return -EINVAL;
@@ -4720,7 +4542,8 @@ sh_css_pipe_start(struct ia_css_stream *stream)
return err;
}
- /* Force ISP parameter calculation after a mode change
+ /*
+ * Force ISP parameter calculation after a mode change
* Acceleration API examples pass NULL for stream but they
* don't use ISP parameters anyway. So this should be okay.
* The SP binary (jpeg) copy does not use any parameters.
@@ -4889,185 +4712,6 @@ ia_css_stream_get_buffer_depth(struct ia_css_stream *stream,
return 0;
}
-/*
- * @brief Stop all "ia_css_pipe" instances in the target
- * "ia_css_stream" instance.
- *
- * Refer to "Local prototypes" for more info.
- */
-/* ISP2401 */
-static int
-sh_css_pipes_stop(struct ia_css_stream *stream)
-{
- int err = 0;
- struct ia_css_pipe *main_pipe;
- enum ia_css_pipe_id main_pipe_id;
- int i;
-
- if (!stream) {
- IA_CSS_LOG("stream does NOT exist!");
- err = -EINVAL;
- goto ERR;
- }
-
- main_pipe = stream->last_pipe;
- if (!main_pipe) {
- IA_CSS_LOG("main_pipe does NOT exist!");
- err = -EINVAL;
- goto ERR;
- }
-
- main_pipe_id = main_pipe->mode;
- IA_CSS_ENTER_PRIVATE("main_pipe_id=%d", main_pipe_id);
-
- /*
- * Stop all "ia_css_pipe" instances in this target
- * "ia_css_stream" instance.
- */
- for (i = 0; i < stream->num_pipes; i++) {
- /* send the "stop" request to the "ia_css_pipe" instance */
- IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
- stream->pipes[i]->pipeline.pipe_id);
- err = ia_css_pipeline_request_stop(&stream->pipes[i]->pipeline);
-
- /*
- * Exit this loop if "ia_css_pipeline_request_stop()"
- * returns the error code.
- *
- * The error code would be generated in the following
- * two cases:
- * (1) The Scalar Processor has already been stopped.
- * (2) The "Host->SP" event queue is full.
- *
- * As the convention of using CSS API 2.0/2.1, such CSS
- * error code would be propogated from the CSS-internal
- * API returned value to the CSS API returned value. Then
- * the CSS driver should capture these error code and
- * handle it in the driver exception handling mechanism.
- */
- if (err)
- goto ERR;
- }
-
- /*
- * In the CSS firmware use scenario "Continuous Preview"
- * as well as "Continuous Video", the "ia_css_pipe" instance
- * "Copy Pipe" is activated. This "Copy Pipe" is private to
- * the CSS firmware so that it is not listed in the target
- * "ia_css_stream" instance.
- *
- * We need to stop this "Copy Pipe", as well.
- */
- if (main_pipe->stream->config.continuous) {
- struct ia_css_pipe *copy_pipe = NULL;
-
- /* get the reference to "Copy Pipe" */
- if (main_pipe_id == IA_CSS_PIPE_ID_PREVIEW)
- copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
- else if (main_pipe_id == IA_CSS_PIPE_ID_VIDEO)
- copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
-
- /* return the error code if "Copy Pipe" does NOT exist */
- if (!copy_pipe) {
- IA_CSS_LOG("Copy Pipe does NOT exist!");
- err = -EINVAL;
- goto ERR;
- }
-
- /* send the "stop" request to "Copy Pipe" */
- IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
- copy_pipe->pipeline.pipe_id);
- err = ia_css_pipeline_request_stop(&copy_pipe->pipeline);
- }
-
-ERR:
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
-}
-
-/*
- * @brief Check if all "ia_css_pipe" instances in the target
- * "ia_css_stream" instance have stopped.
- *
- * Refer to "Local prototypes" for more info.
- */
-/* ISP2401 */
-static bool
-sh_css_pipes_have_stopped(struct ia_css_stream *stream)
-{
- bool rval = true;
-
- struct ia_css_pipe *main_pipe;
- enum ia_css_pipe_id main_pipe_id;
-
- int i;
-
- if (!stream) {
- IA_CSS_LOG("stream does NOT exist!");
- rval = false;
- goto RET;
- }
-
- main_pipe = stream->last_pipe;
-
- if (!main_pipe) {
- IA_CSS_LOG("main_pipe does NOT exist!");
- rval = false;
- goto RET;
- }
-
- main_pipe_id = main_pipe->mode;
- IA_CSS_ENTER_PRIVATE("main_pipe_id=%d", main_pipe_id);
-
- /*
- * Check if every "ia_css_pipe" instance in this target
- * "ia_css_stream" instance has stopped.
- */
- for (i = 0; i < stream->num_pipes; i++) {
- rval = rval && ia_css_pipeline_has_stopped(&stream->pipes[i]->pipeline);
- IA_CSS_LOG("Pipe has stopped: pipe_id=%d, stopped=%d",
- stream->pipes[i]->pipeline.pipe_id,
- rval);
- }
-
- /*
- * In the CSS firmware use scenario "Continuous Preview"
- * as well as "Continuous Video", the "ia_css_pipe" instance
- * "Copy Pipe" is activated. This "Copy Pipe" is private to
- * the CSS firmware so that it is not listed in the target
- * "ia_css_stream" instance.
- *
- * We need to check if this "Copy Pipe" has stopped, as well.
- */
- if (main_pipe->stream->config.continuous) {
- struct ia_css_pipe *copy_pipe = NULL;
-
- /* get the reference to "Copy Pipe" */
- if (main_pipe_id == IA_CSS_PIPE_ID_PREVIEW)
- copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
- else if (main_pipe_id == IA_CSS_PIPE_ID_VIDEO)
- copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
-
- /* return if "Copy Pipe" does NOT exist */
- if (!copy_pipe) {
- IA_CSS_LOG("Copy Pipe does NOT exist!");
-
- rval = false;
- goto RET;
- }
-
- /* check if "Copy Pipe" has stopped or not */
- rval = rval && ia_css_pipeline_has_stopped(&copy_pipe->pipeline);
- IA_CSS_LOG("Pipe has stopped: pipe_id=%d, stopped=%d",
- copy_pipe->pipeline.pipe_id,
- rval);
- }
-
-RET:
- IA_CSS_LEAVE_PRIVATE("rval=%d", rval);
- return rval;
-}
-
#if !defined(ISP2401)
unsigned int
sh_css_get_mipi_sizes_for_check(const unsigned int port, const unsigned int idx)
@@ -5137,11 +4781,13 @@ sh_css_pipe_get_shading_info(struct ia_css_pipe *pipe,
(const struct ia_css_stream_config *)&pipe->stream->config,
shading_info, pipe_config);
- /* Other function calls can be added here when other shading correction types will be added
- * in the future.
+ /*
+ * Other function calls can be added here when other shading
+ * correction types will be added in the future.
*/
} else {
- /* When the pipe does not have a binary which has the shading
+ /*
+ * When the pipe does not have a binary which has the shading
* correction, this function does not need to fill the shading
* information. It is not a error case, and then
* this function should return 0.
@@ -5180,6 +4826,8 @@ sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe,
ia_css_binary_dvs_stat_grid_info(binary, info, pipe);
} else {
memset(&info->dvs_grid, 0, sizeof(info->dvs_grid));
+ memset(&info->dvs_grid.dvs_stat_grid_info, 0,
+ sizeof(info->dvs_grid.dvs_stat_grid_info));
}
if (binary) {
@@ -5254,7 +4902,8 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
IA_CSS_ENTER_PRIVATE("");
assert(pipe);
assert(pipe->mode == IA_CSS_PIPE_ID_VIDEO);
- /* we only test the video_binary because offline video doesn't need a
+ /*
+ * we only test the video_binary because offline video doesn't need a
* vf_pp binary and online does not (always use) the copy_binary.
* All are always reset at the same time anyway.
*/
@@ -5367,7 +5016,8 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
if (err)
return err;
- /* In the case where video_vf_info is not NULL, this allows
+ /*
+ * In the case where video_vf_info is not NULL, this allows
* us to find a potential video library with desired vf format.
* If success, no vf_pp binary is needed.
* If failed, we will look up video binary with YUV_LINE vf format
@@ -5382,17 +5032,23 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
else
return err;
} else if (video_vf_info) {
- /* The first video binary lookup is successful, but we may
- * still need vf_pp binary based on additiona check */
+ /*
+ * The first video binary lookup is successful, but we
+ * may still need vf_pp binary based on additional check
+ */
num_output_pins = mycs->video_binary.info->num_output_pins;
vf_ds_log2 = mycs->video_binary.vf_downscale_log2;
- /* If the binary has dual output pins, we need vf_pp if the resolution
- * is different. */
+ /*
+ * If the binary has dual output pins, we need vf_pp
+ * if the resolution is different.
+ */
need_vf_pp |= ((num_output_pins == 2) && vf_res_different_than_output);
- /* If the binary has single output pin, we need vf_pp if additional
- * scaling is needed for vf */
+ /*
+ * If the binary has single output pin, we need vf_pp
+ * if additional scaling is needed for vf
+ */
need_vf_pp |= ((num_output_pins == 1) &&
((video_vf_info->res.width << vf_ds_log2 != pipe_out_info->res.width) ||
(video_vf_info->res.height << vf_ds_log2 != pipe_out_info->res.height)));
@@ -5422,19 +5078,25 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
}
}
- /* If a video binary does not use a ref_frame, we set the frame delay
- * to 0. This is the case for the 1-stage low-power video binary. */
+ /*
+ * If a video binary does not use a ref_frame, we set the frame delay
+ * to 0. This is the case for the 1-stage low-power video binary.
+ */
if (!mycs->video_binary.info->sp.enable.ref_frame)
pipe->dvs_frame_delay = 0;
- /* The delay latency determines the number of invalid frames after
- * a stream is started. */
+ /*
+ * The delay latency determines the number of invalid frames after
+ * a stream is started.
+ */
pipe->num_invalid_frames = pipe->dvs_frame_delay;
pipe->info.num_invalid_frames = pipe->num_invalid_frames;
- /* Viewfinder frames also decrement num_invalid_frames. If the pipe
+ /*
+ * Viewfinder frames also decrement num_invalid_frames. If the pipe
* outputs a viewfinder output, then we need double the number of
- * invalid frames */
+ * invalid frames
+ */
if (video_vf_info)
pipe->num_invalid_frames *= 2;
@@ -5446,7 +5108,8 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
#if !defined(ISP2401)
/* Copy */
if (!online && !continuous) {
- /* TODO: what exactly needs doing, prepend the copy binary to
+ /*
+ * TODO: what exactly needs doing, prepend the copy binary to
* video base this only on !online?
*/
err = load_copy_binary(pipe,
@@ -5459,7 +5122,6 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
(void)continuous;
#endif
-#if !defined(HAS_OUTPUT_SYSTEM)
if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] && need_vf_pp) {
struct ia_css_binary_descr vf_pp_descr;
@@ -5469,8 +5131,11 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
&mycs->video_binary.vf_frame_info,
pipe_vf_out_info);
} else {
- /* output from main binary is not yuv line. currently this is
- * possible only when bci is enabled on vfpp output */
+ /*
+ * output from main binary is not yuv line. currently
+ * this is possible only when bci is enabled on vfpp
+ * output
+ */
assert(pipe->config.enable_vfpp_bci);
ia_css_pipe_get_yuvscaler_binarydesc(pipe, &vf_pp_descr,
&mycs->video_binary.vf_frame_info,
@@ -5482,7 +5147,6 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
if (err)
return err;
}
-#endif
err = allocate_delay_frames(pipe);
@@ -5490,35 +5154,10 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
return err;
if (mycs->video_binary.info->sp.enable.block_output) {
- unsigned int tnr_width;
- unsigned int tnr_height;
-
tnr_info = mycs->video_binary.out_frame_info[0];
- if (IS_ISP2401) {
- /* Select resolution for TNR. If
- * output_system_in_resolution(GDC_out_resolution) is
- * being used, then select that as it will also be in resolution for
- * TNR. At present, it only make sense for Skycam */
- if (pipe->config.output_system_in_res.width &&
- pipe->config.output_system_in_res.height) {
- tnr_width = pipe->config.output_system_in_res.width;
- tnr_height = pipe->config.output_system_in_res.height;
- } else {
- tnr_width = tnr_info.res.width;
- tnr_height = tnr_info.res.height;
- }
-
- /* Make tnr reference buffers output block width(in pix) align */
- tnr_info.res.width = CEIL_MUL(tnr_width,
- (mycs->video_binary.info->sp.block.block_width * ISP_NWAY));
- tnr_info.padded_width = tnr_info.res.width;
- } else {
- tnr_height = tnr_info.res.height;
- }
-
/* Make tnr reference buffers output block height align */
- tnr_info.res.height = CEIL_MUL(tnr_height,
+ tnr_info.res.height = CEIL_MUL(tnr_info.res.height,
mycs->video_binary.info->sp.block.output_block_height);
} else {
tnr_info = mycs->video_binary.internal_frame_info;
@@ -5526,7 +5165,7 @@ static int load_video_binaries(struct ia_css_pipe *pipe)
tnr_info.format = IA_CSS_FRAME_FORMAT_YUV_LINE;
tnr_info.raw_bit_depth = SH_CSS_TNR_BIT_DEPTH;
- for (i = 0; i < NUM_TNR_FRAMES; i++) {
+ for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++) {
if (mycs->tnr_frames[i]) {
ia_css_frame_free(mycs->tnr_frames[i]);
mycs->tnr_frames[i] = NULL;
@@ -5574,9 +5213,7 @@ static int video_start(struct ia_css_pipe *pipe)
struct ia_css_pipe *copy_pipe, *capture_pipe;
enum sh_css_pipe_config_override copy_ovrd;
enum ia_css_input_mode video_pipe_input_mode;
-
- const struct ia_css_coordinate *coord = NULL;
- const struct ia_css_isp_parameters *params = NULL;
+ unsigned int thread_id;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
@@ -5598,22 +5235,14 @@ static int video_start(struct ia_css_pipe *pipe)
return err;
send_raw_frames(pipe);
- {
- unsigned int thread_id;
-
- ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
- copy_ovrd = 1 << thread_id;
- if (pipe->stream->cont_capt) {
- ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe),
- &thread_id);
- copy_ovrd |= 1 << thread_id;
- }
- }
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ copy_ovrd = 1 << thread_id;
- if (IS_ISP2401) {
- coord = &pipe->config.internal_frame_origin_bqs_on_sctbl;
- params = pipe->stream->isp_params_configs;
+ if (pipe->stream->cont_capt) {
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe),
+ &thread_id);
+ copy_ovrd |= 1 << thread_id;
}
/* Construct and load the copy pipe */
@@ -5628,12 +5257,12 @@ static int video_start(struct ia_css_pipe *pipe)
pipe->stream->config.mode,
&pipe->stream->config.metadata_config,
&pipe->stream->info.metadata_info,
- pipe->stream->config.source.port.port,
- coord,
- params);
+ pipe->stream->config.source.port.port);
- /* make the video pipe start with mem mode input, copy handles
- the actual mode */
+ /*
+ * make the video pipe start with mem mode input, copy handles
+ * the actual mode
+ */
video_pipe_input_mode = IA_CSS_INPUT_MODE_MEMORY;
}
@@ -5651,9 +5280,7 @@ static int video_start(struct ia_css_pipe *pipe)
IA_CSS_INPUT_MODE_MEMORY,
&pipe->stream->config.metadata_config,
&pipe->stream->info.metadata_info,
- (enum mipi_port_id)0,
- coord,
- params);
+ (enum mipi_port_id)0);
}
start_pipe(pipe, copy_ovrd, video_pipe_input_mode);
@@ -5763,12 +5390,6 @@ static bool need_capture_pp(
assert(pipe);
assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE);
- if (IS_ISP2401) {
- /* ldc and capture_pp are not supported in the same pipeline */
- if (need_capt_ldc(pipe))
- return false;
- }
-
/* determine whether we need to use the capture_pp binary.
* This is needed for:
* 1. XNR or
@@ -5891,9 +5512,11 @@ static int load_primary_binaries(
}
need_pp = need_capture_pp(pipe);
- /* we use the vf output info to get the primary/capture_pp binary
- configured for vf_veceven. It will select the closest downscaling
- factor. */
+ /*
+ * we use the vf output info to get the primary/capture_pp binary
+ * configured for vf_veceven. It will select the closest downscaling
+ * factor.
+ */
vf_info = *pipe_vf_out_info;
/*
@@ -5905,13 +5528,15 @@ static int load_primary_binaries(
* required. This should not be considered as a clean solution.
* Proper investigation should be done to come up with the clean
* solution.
- * */
+ */
ia_css_frame_info_set_format(&vf_info, IA_CSS_FRAME_FORMAT_YUV_LINE);
- /* TODO: All this yuv_scaler and capturepp calculation logic
+ /*
+ * TODO: All this yuv_scaler and capturepp calculation logic
* can be shared later. Capture_pp is also a yuv_scale binary
* with extra XNR funcionality. Therefore, it can be made as the
- * first step of the cascade. */
+ * first step of the cascade.
+ */
capt_pp_out_info = pipe->out_yuv_ds_input_info;
capt_pp_out_info.format = IA_CSS_FRAME_FORMAT_YUV420;
capt_pp_out_info.res.width /= MAX_PREFERRED_YUV_DS_PER_STEP;
@@ -5973,33 +5598,13 @@ static int load_primary_binaries(
/* TODO Do we disable ldc for skycam */
need_ldc = need_capt_ldc(pipe);
- if (IS_ISP2401 && need_ldc) {
- /* ldc and capt_pp are not supported in the same pipeline */
- struct ia_css_binary_descr capt_ldc_descr;
-
- ia_css_pipe_get_ldc_binarydesc(pipe,
- &capt_ldc_descr, &prim_out_info,
- &capt_pp_out_info);
-
- err = ia_css_binary_find(&capt_ldc_descr,
- &mycs->capture_ldc_binary);
- if (err) {
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
- }
- need_pp = false;
- need_ldc = false;
- }
/* we build up the pipeline starting at the end */
/* Capture post-processing */
if (need_pp) {
struct ia_css_binary_descr capture_pp_descr;
- if (!IS_ISP2401)
- capt_pp_in_info = need_ldc ? &capt_ldc_out_info : &prim_out_info;
- else
- capt_pp_in_info = &prim_out_info;
+ capt_pp_in_info = need_ldc ? &capt_ldc_out_info : &prim_out_info;
ia_css_pipe_get_capturepp_binarydesc(pipe,
&capture_pp_descr,
@@ -6057,15 +5662,15 @@ static int load_primary_binaries(
vf_pp_in_info = &mycs->primary_binary[mycs->num_primary_stage - 1].vf_frame_info;
/*
- * WARNING: The #if def flag has been added below as a
- * temporary solution to solve the problem of enabling the
- * view finder in a single binary in a capture flow. The
- * vf-pp stage has been removed for Skycam in the solution
- * provided. The vf-pp stage should be re-introduced when
- * required. Thisshould not be considered as a clean solution.
- * Proper * investigation should be done to come up with the clean
- * solution.
- * */
+ * WARNING: The #if def flag has been added below as a
+ * temporary solution to solve the problem of enabling the
+ * view finder in a single binary in a capture flow. The
+ * vf-pp stage has been removed for Skycam in the solution
+ * provided. The vf-pp stage should be re-introduced when
+ * required. Thisshould not be considered as a clean solution.
+ * Proper * investigation should be done to come up with the clean
+ * solution.
+ */
if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
struct ia_css_binary_descr vf_pp_descr;
@@ -6083,9 +5688,10 @@ static int load_primary_binaries(
return err;
#ifdef ISP2401
- /* When the input system is 2401, only the Direct Sensor Mode
- * Offline Capture uses the ISP copy binary.
- */
+ /*
+ * When the input system is 2401, only the Direct Sensor Mode
+ * Offline Capture uses the ISP copy binary.
+ */
need_isp_copy_binary = !online && sensor;
#else
need_isp_copy_binary = !online && !continuous && !memory;
@@ -6139,17 +5745,19 @@ allocate_delay_frames(struct ia_css_pipe *pipe)
struct ia_css_video_settings *mycs_video = &pipe->pipe_settings.video;
ref_info = mycs_video->video_binary.internal_frame_info;
- /*The ref frame expects
- * 1. Y plane
- * 2. UV plane with line interleaving, like below
- * UUUUUU(width/2 times) VVVVVVVV..(width/2 times)
- *
- * This format is not YUV420(which has Y, U and V planes).
- * Its closer to NV12, except that the UV plane has UV
- * interleaving, like UVUVUVUVUVUVUVUVU...
- *
- * TODO: make this ref_frame format as a separate frame format
- */
+
+ /*
+ * The ref frame expects
+ * 1. Y plane
+ * 2. UV plane with line interleaving, like below
+ * UUUUUU(width/2 times) VVVVVVVV..(width/2 times)
+ *
+ * This format is not YUV420(which has Y, U and V planes).
+ * Its closer to NV12, except that the UV plane has UV
+ * interleaving, like UVUVUVUVUVUVUVUVU...
+ *
+ * TODO: make this ref_frame format as a separate frame format
+ */
ref_info.format = IA_CSS_FRAME_FORMAT_NV12;
delay_frames = mycs_video->delay_frames;
}
@@ -6158,17 +5766,19 @@ allocate_delay_frames(struct ia_css_pipe *pipe)
struct ia_css_preview_settings *mycs_preview = &pipe->pipe_settings.preview;
ref_info = mycs_preview->preview_binary.internal_frame_info;
- /*The ref frame expects
- * 1. Y plane
- * 2. UV plane with line interleaving, like below
- * UUUUUU(width/2 times) VVVVVVVV..(width/2 times)
- *
- * This format is not YUV420(which has Y, U and V planes).
- * Its closer to NV12, except that the UV plane has UV
- * interleaving, like UVUVUVUVUVUVUVUVU...
- *
- * TODO: make this ref_frame format as a separate frame format
- */
+
+ /*
+ * The ref frame expects
+ * 1. Y plane
+ * 2. UV plane with line interleaving, like below
+ * UUUUUU(width/2 times) VVVVVVVV..(width/2 times)
+ *
+ * This format is not YUV420(which has Y, U and V planes).
+ * Its closer to NV12, except that the UV plane has UV
+ * interleaving, like UVUVUVUVUVUVUVUVU...
+ *
+ * TODO: make this ref_frame format as a separate frame format
+ */
ref_info.format = IA_CSS_FRAME_FORMAT_NV12;
delay_frames = mycs_preview->delay_frames;
}
@@ -6625,9 +6235,11 @@ need_yuv_scaler_stage(const struct ia_css_pipe *pipe)
return false;
}
-/* TODO: it is temporarily created from ia_css_pipe_create_cas_scaler_desc */
-/* which has some hard-coded knowledge which prevents reuse of the function. */
-/* Later, merge this with ia_css_pipe_create_cas_scaler_desc */
+/*
+ * TODO: it is temporarily created from ia_css_pipe_create_cas_scaler_desc
+ * which has some hard-coded knowledge which prevents reuse of the function.
+ * Later, merge this with ia_css_pipe_create_cas_scaler_desc
+ */
static int ia_css_pipe_create_cas_scaler_desc_single_output(
struct ia_css_frame_info *cas_scaler_in_info,
struct ia_css_frame_info *cas_scaler_out_info,
@@ -7024,22 +6636,22 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe)
#if defined(ISP2401)
/*
- * NOTES
- * - Why does the "yuvpp" pipe needs "isp_copy_binary" (i.e. ISP Copy) when
- * its input is "ATOMISP_INPUT_FORMAT_YUV422_8"?
- *
- * In most use cases, the first stage in the "yuvpp" pipe is the "yuv_scale_
- * binary". However, the "yuv_scale_binary" does NOT support the input-frame
- * format as "IA_CSS_STREAM _FORMAT_YUV422_8".
- *
- * Hence, the "isp_copy_binary" is required to be present in front of the "yuv
- * _scale_binary". It would translate the input-frame to the frame formats that
- * are supported by the "yuv_scale_binary".
- *
- * Please refer to "FrameWork/css/isp/pipes/capture_pp/capture_pp_1.0/capture_
- * pp_defs.h" for the list of input-frame formats that are supported by the
- * "yuv_scale_binary".
- */
+ * NOTES
+ * - Why does the "yuvpp" pipe needs "isp_copy_binary" (i.e. ISP Copy) when
+ * its input is "ATOMISP_INPUT_FORMAT_YUV422_8"?
+ *
+ * In most use cases, the first stage in the "yuvpp" pipe is the "yuv_scale_
+ * binary". However, the "yuv_scale_binary" does NOT support the input-frame
+ * format as "IA_CSS_STREAM _FORMAT_YUV422_8".
+ *
+ * Hence, the "isp_copy_binary" is required to be present in front of the "yuv
+ * _scale_binary". It would translate the input-frame to the frame formats that
+ * are supported by the "yuv_scale_binary".
+ *
+ * Please refer to "FrameWork/css/isp/pipes/capture_pp/capture_pp_1.0/capture_
+ * pp_defs.h" for the list of input-frame formats that are supported by the
+ * "yuv_scale_binary".
+ */
need_isp_copy_binary =
(pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_YUV422_8);
#else /* !ISP2401 */
@@ -7055,23 +6667,23 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe)
goto ERR;
/*
- * NOTES
- * - Why is "pipe->pipe_settings.capture.copy_binary.online" specified?
- *
- * In some use cases, the first stage in the "yuvpp" pipe is the
- * "isp_copy_binary". The "isp_copy_binary" is designed to process
- * the input from either the system DDR or from the IPU internal VMEM.
- * So it provides the flag "online" to specify where its input is from,
- * i.e.:
- *
- * (1) "online <= true", the input is from the IPU internal VMEM.
- * (2) "online <= false", the input is from the system DDR.
- *
- * In other use cases, the first stage in the "yuvpp" pipe is the
- * "yuv_scale_binary". "The "yuv_scale_binary" is designed to process the
- * input ONLY from the system DDR. So it does not provide the flag "online"
- * to specify where its input is from.
- */
+ * NOTES
+ * - Why is "pipe->pipe_settings.capture.copy_binary.online" specified?
+ *
+ * In some use cases, the first stage in the "yuvpp" pipe is the
+ * "isp_copy_binary". The "isp_copy_binary" is designed to process
+ * the input from either the system DDR or from the IPU internal VMEM.
+ * So it provides the flag "online" to specify where its input is from,
+ * i.e.:
+ *
+ * (1) "online <= true", the input is from the IPU internal VMEM.
+ * (2) "online <= false", the input is from the system DDR.
+ *
+ * In other use cases, the first stage in the "yuvpp" pipe is the
+ * "yuv_scale_binary". "The "yuv_scale_binary" is designed to process the
+ * input ONLY from the system DDR. So it does not provide the flag "online"
+ * to specify where its input is from.
+ */
pipe->pipe_settings.capture.copy_binary.online = pipe->stream->config.online;
}
@@ -7162,6 +6774,7 @@ static int yuvpp_start(struct ia_css_pipe *pipe)
int err = 0;
enum sh_css_pipe_config_override copy_ovrd;
enum ia_css_input_mode yuvpp_pipe_input_mode;
+ unsigned int thread_id;
IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
@@ -7181,12 +6794,8 @@ static int yuvpp_start(struct ia_css_pipe *pipe)
return err;
}
- {
- unsigned int thread_id;
-
- ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
- copy_ovrd = 1 << thread_id;
- }
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ copy_ovrd = 1 << thread_id;
start_pipe(pipe, copy_ovrd, yuvpp_pipe_input_mode);
@@ -7264,8 +6873,11 @@ sh_css_pipe_load_binaries(struct ia_css_pipe *pipe)
}
if (err) {
if (sh_css_pipe_unload_binaries(pipe)) {
- /* currently css does not support multiple error returns in a single function,
- * using -EINVAL in this case */
+ /*
+ * currently css does not support multiple error
+ * returns in a single function, using -EINVAL in
+ * this case
+ */
err = -EINVAL;
}
}
@@ -7316,12 +6928,13 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe)
num_output_stage = pipe->pipe_settings.yuvpp.num_output;
#ifdef ISP2401
- /* When the input system is 2401, always enable 'in_frameinfo_memory'
- * except for the following:
- * - Direct Sensor Mode Online Capture
- * - Direct Sensor Mode Continuous Capture
- * - Buffered Sensor Mode Continuous Capture
- */
+ /*
+ * When the input system is 2401, always enable 'in_frameinfo_memory'
+ * except for the following:
+ * - Direct Sensor Mode Online Capture
+ * - Direct Sensor Mode Continuous Capture
+ * - Buffered Sensor Mode Continuous Capture
+ */
sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR;
buffered_sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR;
online = pipe->stream->config.online;
@@ -7332,19 +6945,23 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe)
/* Construct in_frame info (only in case we have dynamic input */
need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
#endif
- /* the input frame can come from:
- * a) memory: connect yuvscaler to me->in_frame
- * b) sensor, via copy binary: connect yuvscaler to copy binary later on */
+ /*
+ * the input frame can come from:
+ *
+ * a) memory: connect yuvscaler to me->in_frame
+ * b) sensor, via copy binary: connect yuvscaler to copy binary later
+ * on
+ */
if (need_in_frameinfo_memory) {
/* TODO: improve for different input formats. */
/*
- * "pipe->stream->config.input_config.format" represents the sensor output
- * frame format, e.g. YUV422 8-bit.
- *
- * "in_frame_format" represents the imaging pipe's input frame format, e.g.
- * Bayer-Quad RAW.
- */
+ * "pipe->stream->config.input_config.format" represents the sensor output
+ * frame format, e.g. YUV422 8-bit.
+ *
+ * "in_frame_format" represents the imaging pipe's input frame format, e.g.
+ * Bayer-Quad RAW.
+ */
int in_frame_format;
if (pipe->stream->config.input_config.format ==
@@ -7353,22 +6970,22 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe)
} else if (pipe->stream->config.input_config.format ==
ATOMISP_INPUT_FORMAT_YUV422_8) {
/*
- * When the sensor output frame format is "ATOMISP_INPUT_FORMAT_YUV422_8",
- * the "isp_copy_var" binary is selected as the first stage in the yuvpp
- * pipe.
- *
- * For the "isp_copy_var" binary, it reads the YUV422-8 pixels from
- * the frame buffer (at DDR) to the frame-line buffer (at VMEM).
- *
- * By now, the "isp_copy_var" binary does NOT provide a separated
- * frame-line buffer to store the YUV422-8 pixels. Instead, it stores
- * the YUV422-8 pixels in the frame-line buffer which is designed to
- * store the Bayer-Quad RAW pixels.
- *
- * To direct the "isp_copy_var" binary reading from the RAW frame-line
- * buffer, its input frame format must be specified as "IA_CSS_FRAME_
- * FORMAT_RAW".
- */
+ * When the sensor output frame format is "ATOMISP_INPUT_FORMAT_YUV422_8",
+ * the "isp_copy_var" binary is selected as the first stage in the yuvpp
+ * pipe.
+ *
+ * For the "isp_copy_var" binary, it reads the YUV422-8 pixels from
+ * the frame buffer (at DDR) to the frame-line buffer (at VMEM).
+ *
+ * By now, the "isp_copy_var" binary does NOT provide a separated
+ * frame-line buffer to store the YUV422-8 pixels. Instead, it stores
+ * the YUV422-8 pixels in the frame-line buffer which is designed to
+ * store the Bayer-Quad RAW pixels.
+ *
+ * To direct the "isp_copy_var" binary reading from the RAW frame-line
+ * buffer, its input frame format must be specified as "IA_CSS_FRAME_
+ * FORMAT_RAW".
+ */
in_frame_format = IA_CSS_FRAME_FORMAT_RAW;
} else {
in_frame_format = IA_CSS_FRAME_FORMAT_NV12;
@@ -7667,13 +7284,14 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
ia_css_pipe_util_create_output_frames(out_frames);
#ifdef ISP2401
- /* When the input system is 2401, always enable 'in_frameinfo_memory'
- * except for the following:
- * - Direct Sensor Mode Online Capture
- * - Direct Sensor Mode Online Capture
- * - Direct Sensor Mode Continuous Capture
- * - Buffered Sensor Mode Continuous Capture
- */
+ /*
+ * When the input system is 2401, always enable 'in_frameinfo_memory'
+ * except for the following:
+ * - Direct Sensor Mode Online Capture
+ * - Direct Sensor Mode Online Capture
+ * - Direct Sensor Mode Continuous Capture
+ * - Buffered Sensor Mode Continuous Capture
+ */
sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR);
buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
online = pipe->stream->config.online;
@@ -7806,15 +7424,15 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
local_out_frame = NULL;
ia_css_pipe_util_set_output_frames(out_frames, 0, local_out_frame);
/*
- * WARNING: The #if def flag has been added below as a
- * temporary solution to solve the problem of enabling the
- * view finder in a single binary in a capture flow. The
- * vf-pp stage has been removed from Skycam in the solution
- * provided. The vf-pp stage should be re-introduced when
- * required. This * should not be considered as a clean solution.
- * Proper investigation should be done to come up with the clean
- * solution.
- * */
+ * WARNING: The #if def flag has been added below as a
+ * temporary solution to solve the problem of enabling the
+ * view finder in a single binary in a capture flow. The
+ * vf-pp stage has been removed from Skycam in the solution
+ * provided. The vf-pp stage should be re-introduced when
+ * required. This * should not be considered as a clean solution.
+ * Proper investigation should be done to come up with the clean
+ * solution.
+ */
ia_css_pipe_get_generic_stage_desc(&stage_desc,
primary_binary[i],
out_frames,
@@ -7828,8 +7446,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
return err;
}
}
- /* If we use copy iso primary,
- the input must be yuv iso raw */
+ /* If we use copy iso primary, the input must be yuv iso raw */
current_stage->args.copy_vf =
primary_binary[0]->info->sp.pipeline.mode ==
IA_CSS_BINARY_MODE_COPY;
@@ -7888,7 +7505,6 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
}
}
-#ifndef ISP2401
if (need_pp && current_stage) {
struct ia_css_frame *local_in_frame = NULL;
@@ -7908,20 +7524,6 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
}
err = add_capture_pp_stage(pipe, me, local_in_frame,
need_yuv_pp ? NULL : out_frame,
-#else
- /* ldc and capture_pp not supported in same pipeline */
- if (need_ldc && current_stage) {
- in_frame = current_stage->args.out_frame[0];
- ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
- ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
- out_frames, in_frame, NULL);
- err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
- NULL);
- } else if (need_pp && current_stage) {
- in_frame = current_stage->args.out_frame[0];
- err = add_capture_pp_stage(pipe, me, in_frame,
- need_yuv_pp ? NULL : out_frame,
-#endif
capture_pp_binary,
&current_stage);
if (err) {
@@ -7954,14 +7556,14 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
}
/*
- * WARNING: The #if def flag has been added below as a
- * temporary solution to solve the problem of enabling the
- * view finder in a single binary in a capture flow. The vf-pp
- * stage has been removed from Skycam in the solution provided.
- * The vf-pp stage should be re-introduced when required. This
- * should not be considered as a clean solution. Proper
- * investigation should be done to come up with the clean solution.
- * */
+ * WARNING: The #if def flag has been added below as a
+ * temporary solution to solve the problem of enabling the
+ * view finder in a single binary in a capture flow. The vf-pp
+ * stage has been removed from Skycam in the solution provided.
+ * The vf-pp stage should be re-introduced when required. This
+ * should not be considered as a clean solution. Proper
+ * investigation should be done to come up with the clean solution.
+ */
if (mode != IA_CSS_CAPTURE_MODE_RAW &&
mode != IA_CSS_CAPTURE_MODE_BAYER &&
current_stage && vf_frame) {
@@ -8005,6 +7607,7 @@ create_host_capture_pipeline(struct ia_css_pipe *pipe)
static int capture_start(struct ia_css_pipe *pipe)
{
struct ia_css_pipeline *me;
+ unsigned int thread_id;
int err = 0;
enum sh_css_pipe_config_override copy_ovrd;
@@ -8034,7 +7637,7 @@ static int capture_start(struct ia_css_pipe *pipe)
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
-#elif defined(ISP2401)
+#else
if (pipe->config.mode != IA_CSS_PIPE_MODE_COPY) {
err = send_mipi_frames(pipe);
if (err) {
@@ -8042,23 +7645,19 @@ static int capture_start(struct ia_css_pipe *pipe)
return err;
}
}
-
#endif
- {
- unsigned int thread_id;
+ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
+ copy_ovrd = 1 << thread_id;
- ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
- copy_ovrd = 1 << thread_id;
- }
start_pipe(pipe, copy_ovrd, pipe->stream->config.mode);
#if !defined(ISP2401)
/*
- * old isys: for IA_CSS_PIPE_MODE_COPY pipe, isys rx has to be configured,
- * which is currently done in start_binary(); but COPY pipe contains no binary,
- * and does not call start_binary(); so we need to configure the rx here.
- */
+ * old isys: for IA_CSS_PIPE_MODE_COPY pipe, isys rx has to be configured,
+ * which is currently done in start_binary(); but COPY pipe contains no binary,
+ * and does not call start_binary(); so we need to configure the rx here.
+ */
if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY &&
pipe->stream->reconfigure_css_rx) {
ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
@@ -8174,7 +7773,8 @@ append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware)
while (*l)
l = &(*l)->next;
*l = firmware;
- /*firmware->next = NULL;*/ /* when multiple acc extensions are loaded, 'next' can be not NULL */
+ /* when multiple acc extensions are loaded, 'next' can be not NULL */
+ /*firmware->next = NULL;*/
IA_CSS_LEAVE_PRIVATE("");
}
@@ -8360,9 +7960,9 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
}
/*
- * @brief Tag a specific frame in continuous capture.
- * Refer to "sh_css_internal.h" for details.
- */
+ * @brief Tag a specific frame in continuous capture.
+ * Refer to "sh_css_internal.h" for details.
+ */
int ia_css_stream_capture_frame(struct ia_css_stream *stream,
unsigned int exp_id)
{
@@ -8389,10 +7989,12 @@ int ia_css_stream_capture_frame(struct ia_css_stream *stream,
sh_css_create_tag_descr(0, 0, 0, exp_id, &tag_descr);
/* Encode the tag descriptor into a 32-bit value */
encoded_tag_descr = sh_css_encode_tag_descr(&tag_descr);
- /* Enqueue the encoded tag to the host2sp queue.
- * Note: The pipe and stage IDs for tag_cmd queue are hard-coded to 0
- * on both host and the SP side.
- * It is mainly because it is enough to have only one tag_cmd queue */
+ /*
+ * Enqueue the encoded tag to the host2sp queue.
+ * Note: The pipe and stage IDs for tag_cmd queue are hard-coded to 0
+ * on both host and the SP side.
+ * It is mainly because it is enough to have only one tag_cmd queue
+ */
err = ia_css_bufq_enqueue_tag_cmd(encoded_tag_descr);
IA_CSS_LEAVE_ERR(err);
@@ -8400,9 +8002,9 @@ int ia_css_stream_capture_frame(struct ia_css_stream *stream,
}
/*
- * @brief Configure the continuous capture.
- * Refer to "sh_css_internal.h" for details.
- */
+ * @brief Configure the continuous capture.
+ * Refer to "sh_css_internal.h" for details.
+ */
int ia_css_stream_capture(struct ia_css_stream *stream, int num_captures,
unsigned int skip, int offset)
{
@@ -8438,10 +8040,12 @@ int ia_css_stream_capture(struct ia_css_stream *stream, int num_captures,
return -EBUSY;
}
- /* Enqueue the encoded tag to the host2sp queue.
- * Note: The pipe and stage IDs for tag_cmd queue are hard-coded to 0
- * on both host and the SP side.
- * It is mainly because it is enough to have only one tag_cmd queue */
+ /*
+ * Enqueue the encoded tag to the host2sp queue.
+ * Note: The pipe and stage IDs for tag_cmd queue are hard-coded to 0
+ * on both host and the SP side.
+ * It is mainly because it is enough to have only one tag_cmd queue
+ */
return_err = ia_css_bufq_enqueue_tag_cmd((uint32_t)encoded_tag_descr);
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
@@ -8486,9 +8090,7 @@ sh_css_init_host_sp_control_vars(void)
unsigned int HIVE_ADDR_host_sp_queues_initialized;
unsigned int HIVE_ADDR_sp_sleep_mode;
unsigned int HIVE_ADDR_ia_css_dmaproxy_sp_invalidate_tlb;
-#ifndef ISP2401
unsigned int HIVE_ADDR_sp_stop_copy_preview;
-#endif
unsigned int HIVE_ADDR_host_sp_com;
unsigned int o = offsetof(struct host_sp_communication, host2sp_command)
/ sizeof(int);
@@ -8505,20 +8107,9 @@ sh_css_init_host_sp_control_vars(void)
fw->info.sp.host_sp_queues_initialized;
HIVE_ADDR_sp_sleep_mode = fw->info.sp.sleep_mode;
HIVE_ADDR_ia_css_dmaproxy_sp_invalidate_tlb = fw->info.sp.invalidate_tlb;
-#ifndef ISP2401
HIVE_ADDR_sp_stop_copy_preview = fw->info.sp.stop_copy_preview;
-#endif
HIVE_ADDR_host_sp_com = fw->info.sp.host_sp_com;
- (void)HIVE_ADDR_ia_css_ispctrl_sp_isp_started; /* Suppres warnings in CRUN */
-
- (void)HIVE_ADDR_sp_sleep_mode;
- (void)HIVE_ADDR_ia_css_dmaproxy_sp_invalidate_tlb;
-#ifndef ISP2401
- (void)HIVE_ADDR_sp_stop_copy_preview;
-#endif
- (void)HIVE_ADDR_host_sp_com;
-
sp_dmem_store_uint32(SP0_ID,
(unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started),
(uint32_t)(0));
@@ -8532,11 +8123,9 @@ sh_css_init_host_sp_control_vars(void)
sp_dmem_store_uint32(SP0_ID,
(unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb),
(uint32_t)(false));
-#ifndef ISP2401
sp_dmem_store_uint32(SP0_ID,
(unsigned int)sp_address_of(sp_stop_copy_preview),
my_css.stop_copy_preview ? (uint32_t)(1) : (uint32_t)(0));
-#endif
store_sp_array_uint(host_sp_com, o, host2sp_cmd_ready);
for (i = 0; i < N_CSI_PORTS; i++) {
@@ -8586,9 +8175,11 @@ void ia_css_stream_config_defaults(struct ia_css_stream_config *stream_config)
stream_config->online = true;
stream_config->left_padding = -1;
stream_config->pixels_per_clock = 1;
- /* temporary default value for backwards compatibility.
- * This field used to be hardcoded within CSS but this has now
- * been moved to the stream_config struct. */
+ /*
+ * temporary default value for backwards compatibility.
+ * This field used to be hardcoded within CSS but this has now
+ * been moved to the stream_config struct.
+ */
stream_config->source.port.rxcount = 0x04040404;
}
@@ -8602,7 +8193,7 @@ ia_css_acc_pipe_create(struct ia_css_pipe *pipe)
return -EINVAL;
}
- /* There is not meaning for num_execs = 0 semantically. Run atleast once. */
+ /* There is not meaning for num_execs = 0 semantically. Run at least once. */
if (pipe->config.acc_num_execs == 0)
pipe->config.acc_num_execs = 1;
@@ -8673,9 +8264,11 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
ia_css_pipe_extra_config_defaults(&internal_pipe->extra_config);
if (config->mode == IA_CSS_PIPE_MODE_ACC) {
- /* Temporary hack to migrate acceleration to CSS 2.0.
- * In the future the code for all pipe types should be
- * unified. */
+ /*
+ * Temporary hack to migrate acceleration to CSS 2.0.
+ * In the future the code for all pipe types should be
+ * unified.
+ */
*pipe = internal_pipe;
if (!internal_pipe->config.acc_extension &&
internal_pipe->config.num_acc_stages ==
@@ -8687,21 +8280,23 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
return ia_css_acc_pipe_create(internal_pipe);
}
- /* Use config value when dvs_frame_delay setting equal to 2, otherwise always 1 by default */
+ /*
+ * Use config value when dvs_frame_delay setting equal to 2,
+ * otherwise always 1 by default
+ */
if (internal_pipe->config.dvs_frame_delay == IA_CSS_FRAME_DELAY_2)
internal_pipe->dvs_frame_delay = 2;
else
internal_pipe->dvs_frame_delay = 1;
- /* we still keep enable_raw_binning for backward compatibility, for any new
- fractional bayer downscaling, we should use bayer_ds_out_res. if both are
- specified, bayer_ds_out_res will take precedence.if none is specified, we
- set bayer_ds_out_res equal to IF output resolution(IF may do cropping on
- sensor output) or use default decimation factor 1. */
- if (internal_pipe->extra_config.enable_raw_binning &&
- internal_pipe->config.bayer_ds_out_res.width) {
- /* fill some code here, if no code is needed, please remove it during integration */
- }
+ /*
+ * we still keep enable_raw_binning for backward compatibility,
+ * for any new fractional bayer downscaling, we should use
+ * bayer_ds_out_res. if both are specified, bayer_ds_out_res will
+ * take precedence.if none is specified, we set bayer_ds_out_res
+ * equal to IF output resolution(IF may do cropping on sensor output)
+ * or use default decimation factor 1.
+ */
/* YUV downscaling */
if ((internal_pipe->config.vf_pp_in_res.width ||
@@ -8905,8 +8500,10 @@ ia_css_stream_configure_rx(struct ia_css_stream *stream)
if (config->compression.type == IA_CSS_CSI2_COMPRESSION_TYPE_NONE)
stream->csi_rx_config.comp = MIPI_PREDICTOR_NONE;
else
- /* not implemented yet, requires extension of the rx_cfg_t
- * struct */
+ /*
+ * not implemented yet, requires extension of the rx_cfg_t
+ * struct
+ */
return -EINVAL;
stream->csi_rx_config.is_two_ppc = (stream->config.pixels_per_clock == 2);
@@ -8993,56 +8590,15 @@ metadata_info_init(const struct ia_css_metadata_config *mdc,
return -EINVAL;
md->resolution = mdc->resolution;
- /* We round up the stride to a multiple of the width
- * of the port going to DDR, this is a HW requirements (DMA). */
+ /*
+ * We round up the stride to a multiple of the width
+ * of the port going to DDR, this is a HW requirements (DMA).
+ */
md->stride = CEIL_MUL(mdc->resolution.width, HIVE_ISP_DDR_WORD_BYTES);
md->size = mdc->resolution.height * md->stride;
return 0;
}
-/* ISP2401 */
-static int check_pipe_resolutions(const struct ia_css_pipe *pipe)
-{
- int err = 0;
-
- IA_CSS_ENTER_PRIVATE("");
-
- if (!pipe || !pipe->stream) {
- IA_CSS_ERROR("null arguments");
- err = -EINVAL;
- goto EXIT;
- }
-
- if (ia_css_util_check_res(pipe->config.input_effective_res.width,
- pipe->config.input_effective_res.height) != 0) {
- IA_CSS_ERROR("effective resolution not supported");
- err = -EINVAL;
- goto EXIT;
- }
- if (!ia_css_util_resolution_is_zero(
- pipe->stream->config.input_config.input_res)) {
- if (!ia_css_util_res_leq(pipe->config.input_effective_res,
- pipe->stream->config.input_config.input_res)) {
- IA_CSS_ERROR("effective resolution is larger than input resolution");
- err = -EINVAL;
- goto EXIT;
- }
- }
- if (!ia_css_util_resolution_is_even(pipe->config.output_info[0].res)) {
- IA_CSS_ERROR("output resolution must be even");
- err = -EINVAL;
- goto EXIT;
- }
- if (!ia_css_util_resolution_is_even(pipe->config.vf_output_info[0].res)) {
- IA_CSS_ERROR("VF resolution must be even");
- err = -EINVAL;
- goto EXIT;
- }
-EXIT:
- IA_CSS_LEAVE_ERR_PRIVATE(err);
- return err;
-}
-
int
ia_css_stream_create(const struct ia_css_stream_config *stream_config,
int num_pipes,
@@ -9057,9 +8613,6 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
int err = -EINVAL;
struct ia_css_metadata_info md_info;
struct ia_css_resolution effective_res;
-#ifdef ISP2401
- bool aspect_ratio_crop_enabled = false;
-#endif
IA_CSS_ENTER("num_pipes=%d", num_pipes);
ia_css_debug_dump_stream_config(stream_config, num_pipes);
@@ -9236,14 +8789,6 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
IA_CSS_LOG("mode sensor/default");
}
-#ifdef ISP2401
- err = aspect_ratio_crop_init(curr_stream, pipes,
- &aspect_ratio_crop_enabled);
- if (err) {
- IA_CSS_LEAVE_ERR(err);
- goto ERR;
- }
-#endif
for (i = 0; i < num_pipes; i++) {
struct ia_css_resolution effective_res;
@@ -9256,22 +8801,6 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
if (effective_res.height == 0 || effective_res.width == 0) {
effective_res = curr_pipe->stream->config.input_config.effective_res;
-#if defined(ISP2401)
- /* The aspect ratio cropping is currently only
- * supported on the new input system. */
- if (aspect_ratio_crop_check(aspect_ratio_crop_enabled, curr_pipe)) {
- struct ia_css_resolution crop_res;
-
- err = aspect_ratio_crop(curr_pipe, &crop_res);
- if (!err) {
- effective_res = crop_res;
- } else {
- /* in case of error fallback to default
- * effective resolution from driver. */
- IA_CSS_LOG("aspect_ratio_crop() failed with err(%d)", err);
- }
- }
-#endif
curr_pipe->config.input_effective_res = effective_res;
}
IA_CSS_LOG("effective_res=%dx%d",
@@ -9279,17 +8808,6 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
effective_res.height);
}
- if (IS_ISP2401) {
- for (i = 0; i < num_pipes; i++) {
- if (pipes[i]->config.mode != IA_CSS_PIPE_MODE_ACC &&
- pipes[i]->config.mode != IA_CSS_PIPE_MODE_COPY) {
- err = check_pipe_resolutions(pipes[i]);
- if (err)
- goto ERR;
- }
- }
- }
-
err = ia_css_stream_isp_parameters_init(curr_stream);
if (err)
goto ERR;
@@ -9327,9 +8845,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
if (num_pipes >= 2) {
curr_stream->cont_capt = true;
curr_stream->disable_cont_vf = curr_stream->config.disable_cont_viewfinder;
-
- if (!IS_ISP2401)
- curr_stream->stop_copy_preview = my_css.stop_copy_preview;
+ curr_stream->stop_copy_preview = my_css.stop_copy_preview;
}
/* Create copy pipe here, since it may not be exposed to the driver */
@@ -9387,16 +8903,15 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
/* set current stream */
curr_pipe->stream = curr_stream;
- if (!IS_ISP2401) {
- /* take over effective info */
+ /* take over effective info */
+
+ effective_res = curr_pipe->config.input_effective_res;
+ err = ia_css_util_check_res(
+ effective_res.width,
+ effective_res.height);
+ if (err)
+ goto ERR;
- effective_res = curr_pipe->config.input_effective_res;
- err = ia_css_util_check_res(
- effective_res.width,
- effective_res.height);
- if (err)
- goto ERR;
- }
/* sensor binning per pipe */
if (sensor_binning_changed)
sh_css_pipe_free_shading_table(curr_pipe);
@@ -9421,9 +8936,6 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config,
goto ERR;
}
- if (IS_ISP2401)
- pipe_info->output_system_in_res_info = curr_pipe->config.output_system_in_res;
-
if (!spcopyonly) {
if (!IS_ISP2401)
err = sh_css_pipe_get_shading_info(curr_pipe,
@@ -9523,8 +9035,6 @@ ia_css_stream_destroy(struct ia_css_stream *stream)
if ((stream->last_pipe) &&
ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num)) {
#if defined(ISP2401)
- bool free_mpi;
-
for (i = 0; i < stream->num_pipes; i++) {
struct ia_css_pipe *entry = stream->pipes[i];
unsigned int sp_thread_id;
@@ -9548,19 +9058,16 @@ ia_css_stream_destroy(struct ia_css_stream *stream)
}
}
}
- free_mpi = stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR;
- if (IS_ISP2401) {
- free_mpi |= stream->config.mode == IA_CSS_INPUT_MODE_TPG;
- free_mpi |= stream->config.mode == IA_CSS_INPUT_MODE_PRBS;
- }
-
- if (free_mpi) {
+ if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
for (i = 0; i < stream->num_pipes; i++) {
struct ia_css_pipe *entry = stream->pipes[i];
- /* free any mipi frames that are remaining:
- * some test stream create-destroy cycles do not generate output frames
- * and the mipi buffer is not freed in the deque function
- */
+ /*
+ * free any mipi frames that are remaining:
+ * some test stream create-destroy cycles do
+ * not generate output frames
+ * and the mipi buffer is not freed in the
+ * deque function
+ */
if (entry)
free_mipi_frames(entry);
}
@@ -9638,58 +9145,6 @@ ia_css_stream_get_info(const struct ia_css_stream *stream,
return 0;
}
-/*
- * Rebuild a stream, including allocating structs, setting configuration and
- * building the required pipes.
- * The data is taken from the css_save struct updated upon stream creation.
- * The stream handle is used to identify the correct entry in the css_save struct
- */
-int
-ia_css_stream_load(struct ia_css_stream *stream)
-{
- int i, j, err;
-
- if (IS_ISP2401) {
- /* TODO remove function - DEPRECATED */
- (void)stream;
- return -ENOTSUPP;
- }
-
- assert(stream);
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter,\n");
- for (i = 0; i < MAX_ACTIVE_STREAMS; i++) {
- if (my_css_save.stream_seeds[i].stream != stream)
- continue;
-
- for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) {
- int k;
-
- err = ia_css_pipe_create(&my_css_save.stream_seeds[i].pipe_config[j],
- &my_css_save.stream_seeds[i].pipes[j]);
- if (!err)
- continue;
-
- for (k = 0; k < j; k++)
- ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[k]);
- return err;
- }
- err = ia_css_stream_create(&my_css_save.stream_seeds[i].stream_config,
- my_css_save.stream_seeds[i].num_pipes,
- my_css_save.stream_seeds[i].pipes,
- &my_css_save.stream_seeds[i].stream);
- if (!err)
- break;
-
- ia_css_stream_destroy(stream);
- for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++)
- ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[j]);
- return err;
- }
-
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() exit,\n");
- return 0;
-}
-
int
ia_css_stream_start(struct ia_css_stream *stream)
{
@@ -9763,16 +9218,14 @@ ia_css_stream_stop(struct ia_css_stream *stream)
}
#endif
- if (!IS_ISP2401)
- err = ia_css_pipeline_request_stop(&stream->last_pipe->pipeline);
- else
- err = sh_css_pipes_stop(stream);
-
+ err = ia_css_pipeline_request_stop(&stream->last_pipe->pipeline);
if (err)
return err;
- /* Ideally, unmapping should happen after pipeline_stop, but current
- * semantics do not allow that. */
+ /*
+ * Ideally, unmapping should happen after pipeline_stop, but current
+ * semantics do not allow that.
+ */
/* err = map_sp_threads(stream, false); */
return err;
@@ -9785,19 +9238,16 @@ ia_css_stream_has_stopped(struct ia_css_stream *stream)
assert(stream);
- if (!IS_ISP2401)
- stopped = ia_css_pipeline_has_stopped(&stream->last_pipe->pipeline);
- else
- stopped = sh_css_pipes_have_stopped(stream);
+ stopped = ia_css_pipeline_has_stopped(&stream->last_pipe->pipeline);
return stopped;
}
/* ISP2400 */
/*
- * Destroy the stream and all the pipes related to it.
- * The stream handle is used to identify the correct entry in the css_save struct
- */
+ * Destroy the stream and all the pipes related to it.
+ * The stream handle is used to identify the correct entry in the css_save struct
+ */
int
ia_css_stream_unload(struct ia_css_stream *stream)
{
@@ -10060,11 +9510,12 @@ ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe)
{
assert(pipe);
- /* KW was not sure this function was not returning a value
- that was out of range; so added an assert, and, for the
- case when asserts are not enabled, clip to the largest
- value; pipe_num is unsigned so the value cannot be too small
- */
+ /*
+ * KW was not sure this function was not returning a value
+ * that was out of range; so added an assert, and, for the
+ * case when asserts are not enabled, clip to the largest
+ * value; pipe_num is unsigned so the value cannot be too small
+ */
assert(pipe->pipe_num < IA_CSS_PIPELINE_NUM_MAX);
if (pipe->pipe_num >= IA_CSS_PIPELINE_NUM_MAX)
@@ -10119,10 +9570,10 @@ ia_css_start_sp(void)
}
/*
- * Time to wait SP for termincate. Only condition when this can happen
- * is a fatal hw failure, but we must be able to detect this and emit
- * a proper error trace.
- */
+ * Time to wait SP for termincate. Only condition when this can happen
+ * is a fatal hw failure, but we must be able to detect this and emit
+ * a proper error trace.
+ */
#define SP_SHUTDOWN_TIMEOUT_US 200000
int
@@ -10142,14 +9593,10 @@ ia_css_stop_sp(void)
}
/* For now, stop whole SP */
- if (!IS_ISP2401) {
- sh_css_write_host2sp_command(host2sp_cmd_terminate);
- } else {
- if (!sh_css_write_host2sp_command(host2sp_cmd_terminate)) {
- IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed");
- ia_css_debug_dump_sp_sw_debug_info();
- ia_css_debug_dump_debug_info(NULL);
- }
+ if (!sh_css_write_host2sp_command(host2sp_cmd_terminate)) {
+ IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed");
+ ia_css_debug_dump_sp_sw_debug_info();
+ ia_css_debug_dump_debug_info(NULL);
}
sh_css_sp_set_sp_running(false);
@@ -10245,9 +9692,7 @@ void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
-#if defined SH_CSS_ENABLE_METADATA
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
-#endif
if (pipe->pipe_settings.preview.preview_binary.info &&
pipe->pipe_settings.preview.preview_binary.info->sp.enable.s3a)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_3A_STATISTICS, map);
@@ -10260,9 +9705,7 @@ void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
-#if defined SH_CSS_ENABLE_METADATA
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
-#endif
if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_PRIMARY) {
for (i = 0; i < pipe->pipe_settings.capture.num_primary_stage; i++) {
if (pipe->pipe_settings.capture.primary_binary[i].info &&
@@ -10287,9 +9730,7 @@ void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
-#if defined SH_CSS_ENABLE_METADATA
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
-#endif
if (pipe->pipe_settings.video.video_binary.info &&
pipe->pipe_settings.video.video_binary.info->sp.enable.s3a)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_3A_STATISTICS, map);
@@ -10302,18 +9743,14 @@ void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
if (!pipe->stream->config.continuous)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
-#if defined SH_CSS_ENABLE_METADATA
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
-#endif
} else if (pipe->mode == IA_CSS_PIPE_ID_ACC) {
if (need_input_queue)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
-#if defined SH_CSS_ENABLE_METADATA
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
-#endif
} else if (pipe->mode == IA_CSS_PIPE_ID_YUVPP) {
unsigned int idx;
@@ -10325,38 +9762,11 @@ void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map)
if (need_input_queue)
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
-#if defined SH_CSS_ENABLE_METADATA
ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
-#endif
}
IA_CSS_LEAVE("");
}
-#if CONFIG_ON_FRAME_ENQUEUE()
-static int set_config_on_frame_enqueue(struct ia_css_frame_info
- *info, struct frame_data_wrapper *frame)
-{
- frame->config_on_frame_enqueue.padded_width = 0;
-
- /* currently we support configuration on frame enqueue only on YUV formats */
- /* on other formats the padded_width is zeroed for no configuration override */
- switch (info->format) {
- case IA_CSS_FRAME_FORMAT_YUV420:
- case IA_CSS_FRAME_FORMAT_NV12:
- if (info->padded_width > info->res.width)
- frame->config_on_frame_enqueue.padded_width = info->padded_width;
- else if ((info->padded_width < info->res.width) && (info->padded_width > 0))
- return -EINVAL;
-
- /* nothing to do if width == padded width or padded width is zeroed (the same) */
- break;
- default:
- break;
- }
-
- return 0;
-}
-#endif
int
ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id)
@@ -10365,8 +9775,10 @@ ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id)
IA_CSS_ENTER("");
- /* Only continuous streams have a tagger to which we can send the
- * unlock message. */
+ /*
+ * Only continuous streams have a tagger to which we can send the
+ * unlock message.
+ */
if (!stream || !stream->config.continuous) {
IA_CSS_ERROR("invalid stream pointer");
return -EINVAL;
@@ -10378,8 +9790,10 @@ ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id)
return -EINVAL;
}
- /* Send the event. Since we verified that the exp_id is valid,
- * we can safely assign it to an 8-bit argument here. */
+ /*
+ * Send the event. Since we verified that the exp_id is valid,
+ * we can safely assign it to an 8-bit argument here.
+ */
ret = ia_css_bufq_enqueue_psys_event(
IA_CSS_PSYS_SW_EVENT_UNLOCK_RAW_BUFFER, exp_id, 0, 0);
@@ -10387,9 +9801,10 @@ ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id)
return ret;
}
-/* @brief Set the state (Enable or Disable) of the Extension stage in the
- * given pipe.
- */
+/*
+ * @brief Set the state (Enable or Disable) of the Extension stage in the
+ * given pipe.
+ */
int
ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
bool enable)
@@ -10433,9 +9848,10 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
return err;
}
-/* @brief Get the state (Enable or Disable) of the Extension stage in the
- * given pipe.
- */
+/*
+ * @brief Get the state (Enable or Disable) of the Extension stage in the
+ * given pipe.
+ */
int
ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
bool *enable)
@@ -10471,215 +9887,6 @@ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle,
return err;
}
-/* ISP2401 */
-int
-ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe,
- u32 fw_handle,
- struct ia_css_isp_param_css_segments *css_seg,
- struct ia_css_isp_param_isp_segments *isp_seg)
-{
- unsigned int HIVE_ADDR_sp_group;
- static struct sh_css_sp_group sp_group;
- static struct sh_css_sp_stage sp_stage;
- static struct sh_css_isp_stage isp_stage;
- const struct ia_css_fw_info *fw;
- unsigned int thread_id;
- struct ia_css_pipeline_stage *stage;
- int err = 0;
- int stage_num = 0;
- enum ia_css_isp_memories mem;
- bool enabled;
-
- IA_CSS_ENTER("");
-
- fw = &sh_css_sp_fw;
-
- /* Parameter Check */
- if (!pipe || !pipe->stream) {
- IA_CSS_ERROR("Invalid Pipe.");
- err = -EINVAL;
- } else if (!(pipe->config.acc_extension)) {
- IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
- err = -EINVAL;
- } else if (!sh_css_sp_is_running()) {
- IA_CSS_ERROR("Leaving: queue unavailable.");
- err = -EBUSY;
- } else {
- /* Query the thread_id and stage_num corresponding to the Extension firmware */
- ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
- err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
- if (!err) {
- /* Get the Extension State */
- enabled = (SH_CSS_QOS_STAGE_IS_ENABLED(&sh_css_sp_group.pipe[thread_id],
- stage->stage_num)) ? true : false;
- /* Update mapped arg only when extension stage is not enabled */
- if (enabled) {
- IA_CSS_ERROR("Leaving: cannot update when stage is enabled.");
- err = -EBUSY;
- } else {
- stage_num = stage->stage_num;
-
- HIVE_ADDR_sp_group = fw->info.sp.group;
- sp_dmem_load(SP0_ID,
- (unsigned int)sp_address_of(sp_group),
- &sp_group,
- sizeof(struct sh_css_sp_group));
- hmm_load(sp_group.pipe[thread_id].sp_stage_addr[stage_num],
- &sp_stage, sizeof(struct sh_css_sp_stage));
-
- hmm_load(sp_stage.isp_stage_addr,
- &isp_stage, sizeof(struct sh_css_isp_stage));
-
- for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++) {
- isp_stage.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].address =
- css_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].address;
- isp_stage.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].size =
- css_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].size;
- isp_stage.binary_info.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].address
- =
- isp_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].address;
- isp_stage.binary_info.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].size
- =
- isp_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].size;
- }
-
- hmm_store(sp_stage.isp_stage_addr,
- &isp_stage,
- sizeof(struct sh_css_isp_stage));
- }
- }
- }
- IA_CSS_LEAVE("err:%d handle:%u", err, fw_handle);
- return err;
-}
-
-#ifdef ISP2401
-static int
-aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
- struct ia_css_pipe *pipes[],
- bool *do_crop_status)
-{
- int err = 0;
- int i;
- struct ia_css_pipe *curr_pipe;
- u32 pipe_mask = 0;
-
- if ((!curr_stream) ||
- (curr_stream->num_pipes == 0) ||
- (!pipes) ||
- (!do_crop_status)) {
- err = -EINVAL;
- IA_CSS_LEAVE_ERR(err);
- return err;
- }
-
- for (i = 0; i < curr_stream->num_pipes; i++) {
- curr_pipe = pipes[i];
- pipe_mask |= (1 << curr_pipe->config.mode);
- }
-
- *do_crop_status =
- (((pipe_mask & (1 << IA_CSS_PIPE_MODE_PREVIEW)) ||
- (pipe_mask & (1 << IA_CSS_PIPE_MODE_VIDEO))) &&
- (pipe_mask & (1 << IA_CSS_PIPE_MODE_CAPTURE)) &&
- curr_stream->config.continuous);
- return 0;
-}
-
-static bool
-aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe)
-{
- bool status = false;
-
- if ((curr_pipe) && enabled) {
- if ((curr_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) ||
- (curr_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) ||
- (curr_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE))
- status = true;
- }
-
- return status;
-}
-
-static int
-aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
- struct ia_css_resolution *effective_res)
-{
- int err = 0;
- struct ia_css_resolution crop_res;
- struct ia_css_resolution *in_res = NULL;
- struct ia_css_resolution *out_res = NULL;
- bool use_bds_output_info = false;
- bool use_vf_pp_in_res = false;
- bool use_capt_pp_in_res = false;
-
- if ((!curr_pipe) ||
- (!effective_res)) {
- err = -EINVAL;
- IA_CSS_LEAVE_ERR(err);
- return err;
- }
-
- if ((curr_pipe->config.mode != IA_CSS_PIPE_MODE_PREVIEW) &&
- (curr_pipe->config.mode != IA_CSS_PIPE_MODE_VIDEO) &&
- (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE)) {
- err = -EINVAL;
- IA_CSS_LEAVE_ERR(err);
- return err;
- }
-
- use_bds_output_info =
- ((curr_pipe->bds_output_info.res.width != 0) &&
- (curr_pipe->bds_output_info.res.height != 0));
-
- use_vf_pp_in_res =
- ((curr_pipe->config.vf_pp_in_res.width != 0) &&
- (curr_pipe->config.vf_pp_in_res.height != 0));
-
- use_capt_pp_in_res =
- ((curr_pipe->config.capt_pp_in_res.width != 0) &&
- (curr_pipe->config.capt_pp_in_res.height != 0));
-
- in_res = &curr_pipe->stream->config.input_config.effective_res;
- out_res = &curr_pipe->output_info[0].res;
-
- switch (curr_pipe->config.mode) {
- case IA_CSS_PIPE_MODE_PREVIEW:
- if (use_bds_output_info)
- out_res = &curr_pipe->bds_output_info.res;
- else if (use_vf_pp_in_res)
- out_res = &curr_pipe->config.vf_pp_in_res;
- break;
- case IA_CSS_PIPE_MODE_VIDEO:
- if (use_bds_output_info)
- out_res = &curr_pipe->bds_output_info.res;
- break;
- case IA_CSS_PIPE_MODE_CAPTURE:
- if (use_capt_pp_in_res)
- out_res = &curr_pipe->config.capt_pp_in_res;
- break;
- case IA_CSS_PIPE_MODE_ACC:
- case IA_CSS_PIPE_MODE_COPY:
- case IA_CSS_PIPE_MODE_YUVPP:
- default:
- IA_CSS_ERROR("aspect ratio cropping invalid args: mode[%d]\n",
- curr_pipe->config.mode);
- assert(0);
- break;
- }
-
- err = ia_css_frame_find_crop_resolution(in_res, out_res, &crop_res);
- if (!err)
- *effective_res = crop_res;
- else
- /* in case of error fallback to default
- * effective resolution from driver. */
- IA_CSS_LOG("ia_css_frame_find_crop_resolution() failed with err(%d)", err);
-
- return err;
-}
-#endif
-
static void
sh_css_hmm_buffer_record_init(void)
{
diff --git a/drivers/staging/media/atomisp/pci/sh_css_defs.h b/drivers/staging/media/atomisp/pci/sh_css_defs.h
index 30a84a587b2a..7eb10b226f0a 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_defs.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_defs.h
@@ -117,13 +117,8 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
#define SH_CSS_NUM_INPUT_BUF_LINES 4
/* Left cropping only applicable for sufficiently large nway */
-#if ISP_VEC_NELEMS == 16
-#define SH_CSS_MAX_LEFT_CROPPING 0
-#define SH_CSS_MAX_TOP_CROPPING 0
-#else
#define SH_CSS_MAX_LEFT_CROPPING 12
#define SH_CSS_MAX_TOP_CROPPING 12
-#endif
#define SH_CSS_SP_MAX_WIDTH 1280
@@ -137,13 +132,8 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
#define SH_CSS_MIN_DVS_ENVELOPE 12U
/* The FPGA system (vec_nelems == 16) only supports upto 5MP */
-#if ISP_VEC_NELEMS == 16
-#define SH_CSS_MAX_SENSOR_WIDTH 2560
-#define SH_CSS_MAX_SENSOR_HEIGHT 1920
-#else
#define SH_CSS_MAX_SENSOR_WIDTH 4608
#define SH_CSS_MAX_SENSOR_HEIGHT 3450
-#endif
/* Limited to reduce vmem pressure */
#if ISP_VMEM_DEPTH >= 3072
@@ -178,50 +168,20 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
#define SH_CSS_MORPH_TABLE_ELEMS_PER_DDR_WORD \
(HIVE_ISP_DDR_WORD_BYTES / SH_CSS_MORPH_TABLE_ELEM_BYTES)
-#define ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR (SH_CSS_MAX_BQ_GRID_WIDTH + 1)
-#define ISP2400_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR (SH_CSS_MAX_BQ_GRID_HEIGHT + 1)
-
-#define ISP2400_SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR \
- CEIL_MUL(ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
-
-/* TODO: I will move macros of "*_SCTBL_*" to SC kernel.
- "+ 2" should be "+ SH_CSS_SCTBL_CENTERING_MARGIN + SH_CSS_SCTBL_LAST_GRID_COUNT". (michie, Sep/23/2014) */
-#define ISP2401_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR (SH_CSS_MAX_BQ_GRID_WIDTH + 2)
-#define ISP2401_SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR (SH_CSS_MAX_BQ_GRID_HEIGHT + 2)
+#define SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR (SH_CSS_MAX_BQ_GRID_WIDTH + 1)
+#define SH_CSS_MAX_SCTBL_HEIGHT_PER_COLOR (SH_CSS_MAX_BQ_GRID_HEIGHT + 1)
-#define ISP2401_SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR \
- CEIL_MUL(ISP2400_SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
+#define SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR \
+ CEIL_MUL(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
/* Each line of this table is aligned to the maximum line width. */
#define SH_CSS_MAX_S3ATBL_WIDTH SH_CSS_MAX_BQ_GRID_WIDTH
/* Video mode specific DVS define */
/* The video binary supports a delay of 1 or 2 frames */
-#define VIDEO_FRAME_DELAY 2
+#define MAX_DVS_FRAME_DELAY 2
/* +1 because DVS reads the previous and writes the current frame concurrently */
-#define MAX_NUM_VIDEO_DELAY_FRAMES (VIDEO_FRAME_DELAY + 1)
-
-/* Preview mode specific DVS define. */
-/* In preview we only need GDC functionality (and not the DVS functionality) */
-/* The minimum number of DVS frames you need is 2, one were GDC reads from and another where GDC writes into */
-#define NUM_PREVIEW_DVS_FRAMES (2)
-
-/* TNR is no longer exclusive to video, SkyCam preview has TNR too (same kernel as video).
- * All uses the generic define NUM_TNR_FRAMES. The define NUM_VIDEO_TNR_FRAMES has been deprecated.
- *
- * Notes
- * 1) The value depends on the used TNR kernel and is not something that depends on the mode
- * and it is not something you just could choice.
- * 2) For the luma only pipeline a version that supports two different sets of TNR reference frames
- * is being used.
- *.
- */
-#define NUM_VALID_TNR_REF_FRAMES (1) /* At least one valid TNR reference frame is required */
-#define NUM_TNR_FRAMES_PER_REF_BUF_SET (2)
-/* In luma-only mode alternate illuminated frames are supported, that requires two double buffers */
-#define NUM_TNR_REF_BUF_SETS (1)
-
-#define NUM_TNR_FRAMES (NUM_TNR_FRAMES_PER_REF_BUF_SET * NUM_TNR_REF_BUF_SETS)
+#define MAX_NUM_VIDEO_DELAY_FRAMES (MAX_DVS_FRAME_DELAY + 1)
#define NUM_VIDEO_TNR_FRAMES 2
@@ -250,11 +210,11 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191]
CEIL_MUL(_ISP_MORPH_TABLE_WIDTH(width), \
SH_CSS_MORPH_TABLE_ELEMS_PER_DDR_WORD)
-#define _ISP2400_SCTBL_WIDTH_PER_COLOR(input_width, deci_factor_log2) \
+#define _ISP_SCTBL_WIDTH_PER_COLOR(input_width, deci_factor_log2) \
(ISP_BQ_GRID_WIDTH(input_width, deci_factor_log2) + 1)
-#define _ISP2400_SCTBL_HEIGHT(input_height, deci_factor_log2) \
+#define _ISP_SCTBL_HEIGHT(input_height, deci_factor_log2) \
(ISP_BQ_GRID_HEIGHT(input_height, deci_factor_log2) + 1)
-#define _ISP2400_SCTBL_ALIGNED_WIDTH_PER_COLOR(input_width, deci_factor_log2) \
+#define _ISP_SCTBL_ALIGNED_WIDTH_PER_COLOR(input_width, deci_factor_log2) \
CEIL_MUL(_ISP_SCTBL_WIDTH_PER_COLOR(input_width, deci_factor_log2), \
ISP_VEC_NELEMS)
diff --git a/drivers/staging/media/atomisp/pci/sh_css_firmware.c b/drivers/staging/media/atomisp/pci/sh_css_firmware.c
index e1a16a50e588..94149647b98b 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_firmware.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_firmware.c
@@ -56,8 +56,7 @@ static struct firmware_header *firmware_header;
* which will be replaced with the actual RELEASE_VERSION
* during package generation. Please do not modify
*/
-static const char *isp2400_release_version = STR(irci_stable_candrpv_0415_20150521_0458);
-static const char *isp2401_release_version = STR(irci_ecr - master_20150911_0724);
+static const char *release_version = STR(irci_stable_candrpv_0415_20150521_0458);
#define MAX_FW_REL_VER_NAME 300
static char FW_rel_ver_name[MAX_FW_REL_VER_NAME] = "---";
@@ -190,13 +189,6 @@ sh_css_check_firmware_version(struct device *dev, const char *fw_data)
{
struct sh_css_fw_bi_file_h *file_header;
- const char *release_version;
-
- if (!IS_ISP2401)
- release_version = isp2400_release_version;
- else
- release_version = isp2401_release_version;
-
firmware_header = (struct firmware_header *)fw_data;
file_header = &firmware_header->file_header;
@@ -232,12 +224,6 @@ sh_css_load_firmware(struct device *dev, const char *fw_data,
struct ia_css_fw_info *binaries;
struct sh_css_fw_bi_file_h *file_header;
int ret;
- const char *release_version;
-
- if (!IS_ISP2401)
- release_version = isp2400_release_version;
- else
- release_version = isp2401_release_version;
firmware_header = (struct firmware_header *)fw_data;
file_header = &firmware_header->file_header;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_firmware.h b/drivers/staging/media/atomisp/pci/sh_css_firmware.h
index 66cd38f08f71..a73ce703adfb 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_firmware.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_firmware.h
@@ -29,9 +29,6 @@ struct sh_css_fw_bi_file_h {
};
extern struct ia_css_fw_info sh_css_sp_fw;
-#if defined(HAS_BL)
-extern struct ia_css_fw_info sh_css_bl_fw;
-#endif /* HAS_BL */
extern struct ia_css_blob_descr *sh_css_blob_info;
extern unsigned int sh_css_num_binaries;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_internal.h b/drivers/staging/media/atomisp/pci/sh_css_internal.h
index 496faa7297a5..435b3cedd1c3 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_internal.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_internal.h
@@ -86,12 +86,6 @@
#define SH_CSS_MAX_IF_CONFIGS 3 /* Must match with IA_CSS_NR_OF_CONFIGS (not defined yet).*/
#define SH_CSS_IF_CONFIG_NOT_NEEDED 0xFF
-#define SH_CSS_ENABLE_METADATA
-
-#if defined(SH_CSS_ENABLE_METADATA) && !defined(ISP2401)
-#define SH_CSS_ENABLE_METADATA_THREAD
-#endif
-
/*
* SH_CSS_MAX_SP_THREADS:
* sp threads visible to host with connected communication queues
@@ -101,7 +95,7 @@
* these threads can't be used as image pipe
*/
-#if defined(SH_CSS_ENABLE_METADATA_THREAD)
+#if !defined(ISP2401)
#define SH_CSS_SP_INTERNAL_METADATA_THREAD 1
#else
#define SH_CSS_SP_INTERNAL_METADATA_THREAD 0
@@ -276,7 +270,7 @@ struct sh_css_binary_args {
struct ia_css_frame *in_frame; /* input frame */
const struct ia_css_frame
*delay_frames[MAX_NUM_VIDEO_DELAY_FRAMES]; /* reference input frame */
- const struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES]; /* tnr frames */
+ const struct ia_css_frame *tnr_frames[NUM_VIDEO_TNR_FRAMES]; /* tnr frames */
struct ia_css_frame
*out_frame[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; /* output frame */
struct ia_css_frame *out_vf_frame; /* viewfinder output frame */
@@ -526,7 +520,6 @@ struct sh_css_sp_pipeline {
this struct; needs cleanup */
s32 num_execs; /* number of times to run if this is
an acceleration pipe. */
-#if defined(SH_CSS_ENABLE_METADATA)
struct {
u32 format; /* Metadata format in hrt format */
u32 width; /* Width of a line */
@@ -535,10 +528,7 @@ struct sh_css_sp_pipeline {
u32 size; /* Total size (in bytes) */
ia_css_ptr cont_buf; /* Address of continuous buffer */
} metadata;
-#endif
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
u32 output_frame_queue_id;
-#endif
union {
struct {
u32 bytes_available;
@@ -551,14 +541,6 @@ struct sh_css_sp_pipeline {
u32 raw_bit_depth;
} raw;
} copy;
-
-/* ISP2401 */
-
- /* Parameters passed to Shading Correction kernel. */
- struct {
- u32 internal_frame_origin_x_bqs_on_sctbl; /* Origin X (bqs) of internal frame on shading table */
- u32 internal_frame_origin_y_bqs_on_sctbl; /* Origin Y (bqs) of internal frame on shading table */
- } shading;
};
/*
@@ -580,9 +562,7 @@ struct ia_css_frames_sp {
struct ia_css_frame_sp_info internal_frame_info;
struct ia_css_buffer_sp s3a_buf;
struct ia_css_buffer_sp dvs_buf;
-#if defined SH_CSS_ENABLE_METADATA
struct ia_css_buffer_sp metadata_buf;
-#endif
};
/* Information for a single pipeline stage for an ISP */
@@ -695,8 +675,6 @@ struct sh_css_sp_output {
unsigned int sw_interrupt_value[SH_CSS_NUM_SDW_IRQS];
};
-#define CONFIG_ON_FRAME_ENQUEUE() 0
-
/**
* @brief Data structure for the circular buffer.
* The circular buffer is empty if "start == end". The
@@ -734,9 +712,6 @@ struct sh_css_hmm_buffer {
u32 exp_id;
u32 isp_parameters_id; /** Unique ID to track which config was
actually applied to a particular frame */
-#if CONFIG_ON_FRAME_ENQUEUE()
- struct sh_css_config_on_frame_enqueue config_on_frame_enqueue;
-#endif
} frame;
ia_css_ptr ddr_ptrs;
} payload;
@@ -752,16 +727,9 @@ struct sh_css_hmm_buffer {
clock_value_t isys_eof_clock_tick;
};
-#if CONFIG_ON_FRAME_ENQUEUE()
-#define SIZE_OF_FRAME_STRUCT \
- (SIZE_OF_HRT_VADDRESS + \
- (3 * sizeof(uint32_t)) + \
- sizeof(uint32_t))
-#else
#define SIZE_OF_FRAME_STRUCT \
(SIZE_OF_HRT_VADDRESS + \
(3 * sizeof(uint32_t)))
-#endif
#define SIZE_OF_PAYLOAD_UNION \
(MAX(MAX(MAX(MAX( \
diff --git a/drivers/staging/media/atomisp/pci/sh_css_metadata.c b/drivers/staging/media/atomisp/pci/sh_css_metadata.c
deleted file mode 100644
index 04a4b7da85e2..000000000000
--- a/drivers/staging/media/atomisp/pci/sh_css_metadata.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* This file will contain the code to implement the functions declared in ia_css_metadata.h
- and associated helper functions */
diff --git a/drivers/staging/media/atomisp/pci/sh_css_metrics.c b/drivers/staging/media/atomisp/pci/sh_css_metrics.c
index 9744bbebe1bc..8ded6cdd1575 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_metrics.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_metrics.c
@@ -123,40 +123,15 @@ sh_css_metrics_sample_pcs(void)
unsigned int pc;
unsigned int msink;
-#if SUSPEND
- unsigned int sc = 0;
- unsigned int stopped_sc = 0;
- unsigned int resume_sc = 0;
-#endif
-#if MULTIPLE_PCS
- int i;
- unsigned int pc_tab[NOF_PCS];
-
- for (i = 0; i < NOF_PCS; i++)
- pc_tab[i] = 0;
-#endif
if (!pc_histogram_enabled)
return;
if (isp_histogram) {
-#if SUSPEND
- /* STOP the ISP */
- isp_ctrl_store(ISP0_ID, ISP_SC_REG, STOP_MASK);
-#endif
msink = isp_ctrl_load(ISP0_ID, ISP_CTRL_SINK_REG);
-#if MULTIPLE_PCS
- for (i = 0; i < NOF_PCS; i++)
- pc_tab[i] = isp_ctrl_load(ISP0_ID, ISP_PC_REG);
-#else
pc = isp_ctrl_load(ISP0_ID, ISP_PC_REG);
-#endif
-#if SUSPEND
- /* RESUME the ISP */
- isp_ctrl_store(ISP0_ID, ISP_SC_REG, RESUME_MASK);
-#endif
isp_histogram->msink[pc] &= msink;
stall = (msink != 0x7FF);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
index 75489f7d75ee..0acf75497ae7 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c
@@ -33,47 +33,6 @@
static u32
ref_count_mipi_allocation[N_CSI_PORTS]; /* Initialized in mipi_init */
-/*
- * Check if a source port or TPG/PRBS ID is valid
- */
-static bool ia_css_mipi_is_source_port_valid(struct ia_css_pipe *pipe,
- unsigned int *pport)
-{
- bool ret = true;
- unsigned int port = 0;
- unsigned int max_ports = 0;
-
- switch (pipe->stream->config.mode) {
- case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
- port = (unsigned int)pipe->stream->config.source.port.port;
- max_ports = N_CSI_PORTS;
- break;
- case IA_CSS_INPUT_MODE_TPG:
- port = (unsigned int)pipe->stream->config.source.tpg.id;
- max_ports = N_CSS_TPG_IDS;
- break;
- case IA_CSS_INPUT_MODE_PRBS:
- port = (unsigned int)pipe->stream->config.source.prbs.id;
- max_ports = N_CSS_PRBS_IDS;
- break;
- default:
- assert(false);
- ret = false;
- break;
- }
-
- if (ret) {
- assert(port < max_ports);
-
- if (port >= max_ports)
- ret = false;
- }
-
- *pport = port;
-
- return ret;
-}
-
/* Assumptions:
* - A line is multiple of 4 bytes = 1 word.
* - Each frame has SOF and EOF (each 1 word).
@@ -133,15 +92,11 @@ ia_css_mipi_frame_calculate_size(const unsigned int width,
break;
case ATOMISP_INPUT_FORMAT_YUV420_10: /* odd 4p, 5B, 40bits, even 4p, 10B, 80bits */
case ATOMISP_INPUT_FORMAT_RAW_10: /* 4p, 5B, 40bits */
-#if !defined(HAS_NO_PACKED_RAW_PIXELS)
/* The changes will be reverted as soon as RAW
* Buffers are deployed by the 2401 Input System
* in the non-continuous use scenario.
*/
bits_per_pixel = 10;
-#else
- bits_per_pixel = 16;
-#endif
break;
case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY: /* 2p, 3B, 24bits */
case ATOMISP_INPUT_FORMAT_RAW_12: /* 2p, 3B, 24bits */
@@ -231,6 +186,10 @@ ia_css_mipi_frame_calculate_size(const unsigned int width,
return err;
}
+/*
+ * Check if a source port or TPG/PRBS ID is valid
+ */
+
#if !defined(ISP2401)
int
ia_css_mipi_frame_enable_check_on_size(const enum mipi_port_id port,
@@ -265,16 +224,31 @@ mipi_init(void)
ref_count_mipi_allocation[i] = 0;
}
-int
-calculate_mipi_buff_size(
- struct ia_css_stream_config *stream_cfg,
- unsigned int *size_mem_words)
+bool mipi_is_free(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < N_CSI_PORTS; i++)
+ if (ref_count_mipi_allocation[i])
+ return false;
+
+ return true;
+}
+
+#if defined(ISP2401)
+/*
+ * @brief Calculate the required MIPI buffer sizes.
+ * Based on the stream configuration, calculate the
+ * required MIPI buffer sizes (in DDR words).
+ *
+ * @param[in] stream_cfg Point to the target stream configuration
+ * @param[out] size_mem_words MIPI buffer size in DDR words.
+ *
+ * @return
+ */
+static int calculate_mipi_buff_size(struct ia_css_stream_config *stream_cfg,
+ unsigned int *size_mem_words)
{
-#if !defined(ISP2401)
- int err = -EINVAL;
- (void)stream_cfg;
- (void)size_mem_words;
-#else
unsigned int width;
unsigned int height;
enum atomisp_input_format format;
@@ -366,26 +340,9 @@ calculate_mipi_buff_size(
*size_mem_words = mem_words_per_buff;
IA_CSS_LEAVE_ERR(err);
-#endif
return err;
}
-
-static bool buffers_needed(struct ia_css_pipe *pipe)
-{
- if (!IS_ISP2401) {
- if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
- return false;
- else
- return true;
- }
-
- if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR ||
- pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG ||
- pipe->stream->config.mode == IA_CSS_INPUT_MODE_PRBS)
- return false;
-
- return true;
-}
+#endif
int
allocate_mipi_frames(struct ia_css_pipe *pipe,
@@ -415,43 +372,25 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
}
#endif
-
- if (!buffers_needed(pipe)) {
+ if (pipe->stream->config.mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
"allocate_mipi_frames(%p) exit: no buffers needed for pipe mode.\n",
pipe);
return 0; /* AM TODO: Check */
}
- if (!IS_ISP2401)
- port = (unsigned int)pipe->stream->config.source.port.port;
- else
- err = ia_css_mipi_is_source_port_valid(pipe, &port);
-
- assert(port < N_CSI_PORTS);
-
- if (port >= N_CSI_PORTS || err) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "allocate_mipi_frames(%p) exit: error: port is not correct (port=%d).\n",
- pipe, port);
+ port = (unsigned int)pipe->stream->config.source.port.port;
+ if (port >= N_CSI_PORTS) {
+ IA_CSS_ERROR("allocate_mipi_frames(%p) exit: port is not correct (port=%d).",
+ pipe, port);
return -EINVAL;
}
#ifdef ISP2401
- err = calculate_mipi_buff_size(
- &pipe->stream->config,
- &my_css.mipi_frame_size[port]);
-#endif
-
-#if !defined(ISP2401)
- if (ref_count_mipi_allocation[port] != 0) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "allocate_mipi_frames(%p) exit: already allocated for this port (port=%d).\n",
- pipe, port);
- return 0;
- }
-#else
- /* 2401 system allows multiple streams to use same physical port. This is not
+ err = calculate_mipi_buff_size(&pipe->stream->config,
+ &my_css.mipi_frame_size[port]);
+ /*
+ * 2401 system allows multiple streams to use same physical port. This is not
* true for 2400 system. Currently 2401 uses MIPI buffers as a temporary solution.
* TODO AM: Once that is changed (removed) this code should be removed as well.
* In that case only 2400 related code should remain.
@@ -463,6 +402,13 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
pipe, port);
return 0;
}
+#else
+ if (ref_count_mipi_allocation[port] != 0) {
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
+ "allocate_mipi_frames(%p) exit: already allocated for this port (port=%d).\n",
+ pipe, port);
+ return 0;
+ }
#endif
ref_count_mipi_allocation[port]++;
@@ -494,9 +440,8 @@ allocate_mipi_frames(struct ia_css_pipe *pipe,
my_css.mipi_frames[port][j] = NULL;
}
}
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "allocate_mipi_frames(%p, %d) exit: error: allocation failed.\n",
- pipe, port);
+ IA_CSS_ERROR("allocate_mipi_frames(%p, %d) exit: allocation failed.",
+ pipe, port);
return err;
}
}
@@ -539,30 +484,22 @@ free_mipi_frames(struct ia_css_pipe *pipe)
if (pipe) {
assert(pipe->stream);
if ((!pipe) || (!pipe->stream)) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "free_mipi_frames(%p) exit: error: pipe or stream is null.\n",
- pipe);
+ IA_CSS_ERROR("free_mipi_frames(%p) exit: pipe or stream is null.",
+ pipe);
return -EINVAL;
}
- if (!buffers_needed(pipe)) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "free_mipi_frames(%p) exit: error: wrong mode.\n",
- pipe);
+ if (pipe->stream->config.mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
+ IA_CSS_ERROR("free_mipi_frames(%p) exit: wrong mode.",
+ pipe);
return err;
}
- if (!IS_ISP2401)
- port = (unsigned int)pipe->stream->config.source.port.port;
- else
- err = ia_css_mipi_is_source_port_valid(pipe, &port);
-
- assert(port < N_CSI_PORTS);
+ port = (unsigned int)pipe->stream->config.source.port.port;
- if (port >= N_CSI_PORTS || err) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "free_mipi_frames(%p, %d) exit: error: pipe port is not correct.\n",
- pipe, port);
+ if (port >= N_CSI_PORTS) {
+ IA_CSS_ERROR("free_mipi_frames(%p, %d) exit: pipe port is not correct.",
+ pipe, port);
return err;
}
@@ -570,9 +507,8 @@ free_mipi_frames(struct ia_css_pipe *pipe)
#if !defined(ISP2401)
assert(ref_count_mipi_allocation[port] == 1);
if (ref_count_mipi_allocation[port] != 1) {
- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
- "free_mipi_frames(%p) exit: error: wrong ref_count (ref_count=%d).\n",
- pipe, ref_count_mipi_allocation[port]);
+ IA_CSS_ERROR("free_mipi_frames(%p) exit: wrong ref_count (ref_count=%d).",
+ pipe, ref_count_mipi_allocation[port]);
return err;
}
#endif
@@ -640,11 +576,7 @@ send_mipi_frames(struct ia_css_pipe *pipe)
{
int err = -EINVAL;
unsigned int i;
-#ifndef ISP2401
unsigned int port;
-#else
- unsigned int port = 0;
-#endif
IA_CSS_ENTER_PRIVATE("pipe=%p", pipe);
@@ -657,21 +589,16 @@ send_mipi_frames(struct ia_css_pipe *pipe)
/* multi stream video needs mipi buffers */
/* nothing to be done in other cases. */
- if (!buffers_needed(pipe)) {
+ if (pipe->stream->config.mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
IA_CSS_LOG("nothing to be done for this mode");
return 0;
/* TODO: AM: maybe this should be returning an error. */
}
- if (!IS_ISP2401)
- port = (unsigned int)pipe->stream->config.source.port.port;
- else
- err = ia_css_mipi_is_source_port_valid(pipe, &port);
-
- assert(port < N_CSI_PORTS);
+ port = (unsigned int)pipe->stream->config.source.port.port;
- if (port >= N_CSI_PORTS || err) {
- IA_CSS_ERROR("send_mipi_frames(%p) exit: invalid port specified (port=%d).\n",
+ if (port >= N_CSI_PORTS) {
+ IA_CSS_ERROR("send_mipi_frames(%p) exit: invalid port specified (port=%d).",
pipe, port);
return err;
}
diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.h b/drivers/staging/media/atomisp/pci/sh_css_mipi.h
index 52f08a103883..e6c86d0ac483 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_mipi.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.h
@@ -23,6 +23,8 @@
void
mipi_init(void);
+bool mipi_is_free(void);
+
int
allocate_mipi_frames(struct ia_css_pipe *pipe, struct ia_css_stream_info *info);
@@ -32,19 +34,4 @@ free_mipi_frames(struct ia_css_pipe *pipe);
int
send_mipi_frames(struct ia_css_pipe *pipe);
-/**
- * @brief Calculate the required MIPI buffer sizes.
- * Based on the stream configuration, calculate the
- * required MIPI buffer sizes (in DDR words).
- *
- * @param[in] stream_cfg Point to the target stream configuration
- * @param[out] size_mem_words MIPI buffer size in DDR words.
- *
- * @return
- */
-int
-calculate_mipi_buff_size(
- struct ia_css_stream_config *stream_cfg,
- unsigned int *size_mem_words);
-
#endif /* __SH_CSS_MIPI_H */
diff --git a/drivers/staging/media/atomisp/pci/sh_css_morph.c b/drivers/staging/media/atomisp/pci/sh_css_morph.c
deleted file mode 100644
index edd1da941ccb..000000000000
--- a/drivers/staging/media/atomisp/pci/sh_css_morph.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* This file will contain the code to implement the functions declared in ia_css_morph.h
- and associated helper functions */
diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
index 69cc4e423d8b..41a4c9162319 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c
@@ -118,8 +118,10 @@ crop_and_interpolate(unsigned int cropped_width,
int ty, src_y0, src_y1;
unsigned int sy0, sy1, dy0, dy1, divy;
- /* calculate target point and make sure it falls within
- the table */
+ /*
+ * calculate target point and make sure it falls within
+ * the table
+ */
ty = out_start_row + i * out_cell_size;
/* calculate closest source points in shading table and
@@ -166,19 +168,24 @@ crop_and_interpolate(unsigned int cropped_width,
src_x1 = clamp(src_x1, 0, (int)table_width - 1);
tx = min(clamp(tx, 0, (int)sensor_width - 1),
(int)table_cell_w);
- /* calculate closest source points for distance
- computation */
+ /*
+ * calculate closest source points for distance
+ * computation
+ */
sx0 = min(src_x0 * in_cell_size, sensor_width - 1);
sx1 = min(src_x1 * in_cell_size, sensor_width - 1);
- /* calculate distances between source and target
- pixels */
+ /*
+ * calculate distances between source and target
+ * pixels
+ */
dx0 = tx - sx0;
dx1 = sx1 - tx;
divx = sx1 - sx0;
/* if we're at the edge, we just use the closest
- point still in the grid. We make up for the divider
- in this case by setting the distance to
- out_cell_size, since it's actually 0. */
+ * point still in the grid. We make up for the divider
+ * in this case by setting the distance to
+ * out_cell_size, since it's actually 0.
+ */
if (divx == 0) {
dx0 = 1;
divx = 1;
@@ -242,8 +249,8 @@ prepare_shading_table(const struct ia_css_shading_table *in_table,
if (!in_table) {
sh_css_params_shading_id_table_generate(target_table,
- binary->sctbl_legacy_width_per_color,
- binary->sctbl_legacy_height);
+ binary->sctbl_width_per_color,
+ binary->sctbl_height);
return;
}
@@ -271,43 +278,33 @@ prepare_shading_table(const struct ia_css_shading_table *in_table,
bds_denominator -
binary->info->sp.pipeline.top_cropping;
-#if !defined(USE_WINDOWS_BINNING_FACTOR)
- /* @deprecated{This part of the code will be replaced by the code
- * in the #else section below to make the calculation same across
- * all platforms.
- * Android and Windows platforms interpret the binning_factor parameter
- * differently. In Android, the binning factor is expressed in the form
- * 2^N * 2^N, whereas in Windows platform, the binning factor is N*N}
+ /*
+ * We take into account the binning done by the sensor. We do this
+ * by cropping the non-binned part of the shading table and then
+ * increasing the size of a grid cell with this same binning factor.
*/
-
- /* We take into account the binning done by the sensor. We do this
- by cropping the non-binned part of the shading table and then
- increasing the size of a grid cell with this same binning factor. */
input_width <<= sensor_binning;
input_height <<= sensor_binning;
- /* We also scale the padding by the same binning factor. This will
- make it much easier later on to calculate the padding of the
- shading table. */
+ /*
+ * We also scale the padding by the same binning factor. This will
+ * make it much easier later on to calculate the padding of the
+ * shading table.
+ */
left_padding <<= sensor_binning;
right_padding <<= sensor_binning;
top_padding <<= sensor_binning;
-#else
- input_width *= sensor_binning;
- input_height *= sensor_binning;
- left_padding *= sensor_binning;
- right_padding *= sensor_binning;
- top_padding *= sensor_binning;
-#endif /*USE_WINDOWS_BINNING_FACTOR*/
-
- /* during simulation, the used resolution can exceed the sensor
- resolution, so we clip it. */
+
+ /*
+ * during simulation, the used resolution can exceed the sensor
+ * resolution, so we clip it.
+ */
input_width = min(input_width, in_table->sensor_width);
input_height = min(input_height, in_table->sensor_height);
/* This prepare_shading_table() function is called only in legacy API (not in new API).
Then, the legacy shading table width and height should be used. */
- table_width = binary->sctbl_legacy_width_per_color;
- table_height = binary->sctbl_legacy_height;
+ table_width = binary->sctbl_width_per_color;
+ table_height = binary->sctbl_height;
result = ia_css_shading_table_alloc(table_width, table_height);
if (!result) {
@@ -318,8 +315,10 @@ prepare_shading_table(const struct ia_css_shading_table *in_table,
result->sensor_height = in_table->sensor_height;
result->fraction_bits = in_table->fraction_bits;
- /* now we crop the original shading table and then interpolate to the
- requested resolution and decimation factor. */
+ /*
+ * now we crop the original shading table and then interpolate to the
+ * requested resolution and decimation factor.
+ */
for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) {
crop_and_interpolate(input_width, input_height,
left_padding, right_padding, top_padding,
@@ -376,9 +375,10 @@ ia_css_shading_table_free(struct ia_css_shading_table *table)
if (!table)
return;
- /* We only output logging when the table is not NULL, otherwise
+ /*
+ * We only output logging when the table is not NULL, otherwise
* logs will give the impression that a table was freed.
- * */
+ */
IA_CSS_ENTER("");
for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) {
diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
index dbd3bfe3d343..09f87c285b8d 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
@@ -16,12 +16,10 @@
#include "gdc_device.h" /* gdc_lut_store(), ... */
#include "isp.h" /* ISP_VEC_ELEMBITS */
#include "vamem.h"
-#if !defined(HAS_NO_HMEM)
#ifndef __INLINE_HMEM__
#define __INLINE_HMEM__
#endif
#include "hmem.h"
-#endif /* !defined(HAS_NO_HMEM) */
#define IA_CSS_INCLUDE_PARAMETERS
#define IA_CSS_INCLUDE_ACC_PARAMETERS
@@ -96,9 +94,6 @@
#include "xnr/xnr_3.0/ia_css_xnr3.host.h"
-#if defined(HAS_OUTPUT_SYSTEM)
-#include <components/output_system/sc_output_system_1.0/host/output_system.host.h>
-#endif
#include "sh_css_frac.h"
#include "ia_css_bufq.h"
@@ -107,15 +102,10 @@
(sizeof(char) * (binary)->in_frame_info.res.height * \
(binary)->in_frame_info.padded_width)
-#define ISP2400_SCTBL_BYTES(binary) \
+#define SCTBL_BYTES(binary) \
(sizeof(unsigned short) * (binary)->sctbl_height * \
(binary)->sctbl_aligned_width_per_color * IA_CSS_SC_NUM_COLORS)
-#define ISP2401_SCTBL_BYTES(binary) \
- (sizeof(unsigned short) * max((binary)->sctbl_height, (binary)->sctbl_legacy_height) * \
- /* height should be the larger height between new api and legacy api */ \
- (binary)->sctbl_aligned_width_per_color * IA_CSS_SC_NUM_COLORS)
-
#define MORPH_PLANE_BYTES(binary) \
(SH_CSS_MORPH_TABLE_ELEM_BYTES * (binary)->morph_tbl_aligned_width * \
(binary)->morph_tbl_height)
@@ -734,13 +724,11 @@ sh_css_set_global_isp_config_on_pipe(
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe);
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
static int
sh_css_set_per_frame_isp_config_on_pipe(
struct ia_css_stream *stream,
const struct ia_css_isp_config *config,
struct ia_css_pipe *pipe);
-#endif
static int
sh_css_update_uds_and_crop_info_based_on_zoom_region(
@@ -1031,16 +1019,6 @@ sh_css_params_set_binning_factor(struct ia_css_stream *stream,
}
static void
-sh_css_update_shading_table_status(struct ia_css_pipe *pipe,
- struct ia_css_isp_parameters *params)
-{
- if (params && pipe && (pipe->pipe_num != params->sc_table_last_pipe_num)) {
- params->sc_table_dirty = true;
- params->sc_table_last_pipe_num = pipe->pipe_num;
- }
-}
-
-static void
sh_css_set_shading_table(struct ia_css_stream *stream,
struct ia_css_isp_parameters *params,
const struct ia_css_shading_table *table)
@@ -1053,10 +1031,9 @@ sh_css_set_shading_table(struct ia_css_stream *stream,
if (!table->enable)
table = NULL;
- if ((table != params->sc_table) || params->sc_table_dirty) {
+ if (table != params->sc_table) {
params->sc_table = table;
params->sc_table_changed = true;
- params->sc_table_dirty = false;
/* Not very clean, this goes to sh_css.c to invalidate the
* shading table for all pipes. Should replaced by a loop
* and a pipe-specific call.
@@ -1510,10 +1487,8 @@ ia_css_translate_3a_statistics(
ia_css_s3a_vmem_decode(host_stats, isp_stats->vmem_stats_hi,
isp_stats->vmem_stats_lo);
}
-#if !defined(HAS_NO_HMEM)
IA_CSS_LOG("3A: HMEM");
ia_css_s3a_hmem_decode(host_stats, isp_stats->hmem_stats);
-#endif
IA_CSS_LEAVE("void");
}
@@ -1616,57 +1591,6 @@ ia_css_set_param_exceptions(const struct ia_css_pipe *pipe,
params->dp_config.r = params->wb_config.r;
params->dp_config.b = params->wb_config.b;
params->dp_config.gb = params->wb_config.gb;
-
- if (IS_ISP2401) {
- assert(pipe);
- assert(pipe->mode < IA_CSS_PIPE_ID_NUM);
-
- if (pipe->mode < IA_CSS_PIPE_ID_NUM) {
- params->pipe_dp_config[pipe->mode].gr = params->wb_config.gr;
- params->pipe_dp_config[pipe->mode].r = params->wb_config.r;
- params->pipe_dp_config[pipe->mode].b = params->wb_config.b;
- params->pipe_dp_config[pipe->mode].gb = params->wb_config.gb;
- }
- }
-}
-
-/* ISP2401 */
-static void
-sh_css_set_dp_config(const struct ia_css_pipe *pipe,
- struct ia_css_isp_parameters *params,
- const struct ia_css_dp_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- assert(pipe);
- assert(pipe->mode < IA_CSS_PIPE_ID_NUM);
-
- IA_CSS_ENTER_PRIVATE("config=%p", config);
- ia_css_dp_debug_dtrace(config, IA_CSS_DEBUG_TRACE_PRIVATE);
- if (pipe->mode < IA_CSS_PIPE_ID_NUM) {
- params->pipe_dp_config[pipe->mode] = *config;
- params->pipe_dpc_config_changed[pipe->mode] = true;
- }
- IA_CSS_LEAVE_PRIVATE("void");
-}
-
-static void
-sh_css_get_dp_config(const struct ia_css_pipe *pipe,
- const struct ia_css_isp_parameters *params,
- struct ia_css_dp_config *config)
-{
- if (!config)
- return;
-
- assert(params);
- assert(pipe);
- IA_CSS_ENTER_PRIVATE("config=%p", config);
-
- *config = params->pipe_dp_config[pipe->mode];
-
- IA_CSS_LEAVE_PRIVATE("void");
}
static void
@@ -1740,9 +1664,7 @@ sh_css_set_pipe_dvs_6axis_config(const struct ia_css_pipe *pipe,
copy_dvs_6axis_table(params->pipe_dvs_6axis_config[pipe->mode], dvs_config);
-#if !defined(HAS_NO_DVS_6AXIS_CONFIG_UPDATE)
params->pipe_dvs_6axis_config_changed[pipe->mode] = true;
-#endif
IA_CSS_LEAVE_PRIVATE("void");
}
@@ -1908,11 +1830,9 @@ ia_css_stream_set_isp_config_on_pipe(
IA_CSS_ENTER("stream=%p, config=%p, pipe=%p", stream, config, pipe);
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
if (config->output_frame)
err = sh_css_set_per_frame_isp_config_on_pipe(stream, config, pipe);
else
-#endif
err = sh_css_set_global_isp_config_on_pipe(stream->pipes[0], config, pipe);
IA_CSS_LEAVE_ERR(err);
@@ -1933,11 +1853,9 @@ ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe,
ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "config=%p\n", config);
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
if (config->output_frame)
err = sh_css_set_per_frame_isp_config_on_pipe(pipe->stream, config, pipe);
else
-#endif
err = sh_css_set_global_isp_config_on_pipe(pipe, config, pipe_in);
IA_CSS_LEAVE_ERR(err);
return err;
@@ -1972,7 +1890,6 @@ sh_css_set_global_isp_config_on_pipe(
return err;
}
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
static int
sh_css_set_per_frame_isp_config_on_pipe(
struct ia_css_stream *stream,
@@ -2042,7 +1959,6 @@ exit:
IA_CSS_LEAVE_ERR_PRIVATE(err);
return err;
}
-#endif
static int
sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
@@ -2067,7 +1983,6 @@ sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
sh_css_set_pipe_dvs_6axis_config(pipe, params, config->dvs_6axis_config);
sh_css_set_dz_config(params, config->dz_config);
sh_css_set_motion_vector(params, config->motion_vector);
- sh_css_update_shading_table_status(pipe_in, params);
sh_css_set_shading_table(pipe->stream, params, config->shading_table);
sh_css_set_morph_table(params, config->morph_table);
sh_css_set_macc_table(params, config->macc_table);
@@ -2083,16 +1998,6 @@ sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
params->output_frame = config->output_frame;
params->isp_parameters_id = config->isp_config_id;
- /* Currently we do not offer CSS interface to set different
- * configurations for DPC, i.e. depending on DPC being enabled
- * before (NORM+OBC) or after. The folllowing code to set the
- * DPC configuration should be updated when this interface is made
- * available */
- if (IS_ISP2401) {
- sh_css_set_dp_config(pipe, params, config->dp_config);
- ia_css_set_param_exceptions(pipe, params);
- }
-
if (0 ==
sh_css_select_dp_10bpp_config(pipe, &is_dp_10bpp)) {
/* return an error when both DPC and BDS is enabled by the
@@ -2107,8 +2012,7 @@ sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe,
goto exit;
}
- if (!IS_ISP2401)
- ia_css_set_param_exceptions(pipe, params);
+ ia_css_set_param_exceptions(pipe, params);
exit:
IA_CSS_LEAVE_ERR_PRIVATE(err);
@@ -2143,7 +2047,6 @@ ia_css_pipe_get_isp_config(struct ia_css_pipe *pipe,
sh_css_get_ee_config(params, config->ee_config);
sh_css_get_baa_config(params, config->baa_config);
sh_css_get_pipe_dvs_6axis_config(pipe, params, config->dvs_6axis_config);
- sh_css_get_dp_config(pipe, params, config->dp_config);
sh_css_get_macc_table(params, config->macc_table);
sh_css_get_gamma_table(params, config->gamma_table);
sh_css_get_ctc_table(params, config->ctc_table);
@@ -2250,9 +2153,7 @@ ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
me->vmem_size = ISP_S3ATBL_HI_LO_STRIDE_BYTES *
grid->aligned_height;
}
-#if !defined(HAS_NO_HMEM)
me->hmem_size = sizeof_hmem(HMEM0_ID);
-#endif
/* All subsections need to be aligned to the system bus width */
me->dmem_size = CEIL_MUL(me->dmem_size, HIVE_ISP_DDR_WORD_BYTES);
@@ -2431,7 +2332,7 @@ sh_css_create_isp_params(struct ia_css_stream *stream,
unsigned int i;
struct sh_css_ddr_address_map *ddr_ptrs;
struct sh_css_ddr_address_map_size *ddr_ptrs_size;
- int err = 0;
+ int err;
size_t params_size;
struct ia_css_isp_parameters *params =
kvmalloc(sizeof(struct ia_css_isp_parameters), GFP_KERNEL);
@@ -2473,7 +2374,11 @@ sh_css_create_isp_params(struct ia_css_stream *stream,
succ &= (ddr_ptrs->macc_tbl != mmgr_NULL);
*isp_params_out = params;
- return err;
+
+ if (!succ)
+ return -ENOMEM;
+
+ return 0;
}
static bool
@@ -2521,29 +2426,7 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
ia_css_set_ob_config(params, &default_ob_config);
ia_css_set_dp_config(params, &default_dp_config);
- if (!IS_ISP2401) {
- ia_css_set_param_exceptions(pipe_in, params);
- } else {
- for (i = 0; i < stream->num_pipes; i++) {
- if (sh_css_select_dp_10bpp_config(stream->pipes[i],
- &is_dp_10bpp) == 0) {
- /* set the return value as false if both DPC and
- * BDS is enabled by the user. But we do not return
- * the value immediately to enable internal firmware
- * feature testing. */
- if (is_dp_10bpp) {
- sh_css_set_dp_config(stream->pipes[i], params, &default_dp_10bpp_config);
- } else {
- sh_css_set_dp_config(stream->pipes[i], params, &default_dp_config);
- }
- } else {
- retval = false;
- goto exit;
- }
-
- ia_css_set_param_exceptions(stream->pipes[i], params);
- }
- }
+ ia_css_set_param_exceptions(pipe_in, params);
ia_css_set_de_config(params, &default_de_config);
ia_css_set_gc_config(params, &default_gc_config);
@@ -2580,8 +2463,6 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
params->sc_table = NULL;
params->sc_table_changed = true;
- params->sc_table_dirty = false;
- params->sc_table_last_pipe_num = 0;
ia_css_sdis2_clear_coefficients(&params->dvs2_coefs);
params->dvs2_coef_table_changed = true;
@@ -2639,29 +2520,15 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
* BDS is enabled by the user. But we do not return
* the value immediately to enable internal firmware
* feature testing. */
-
- if (is_dp_10bpp) {
- retval = false;
- /* FIXME: should it ignore this error? */
- }
+ retval = !is_dp_10bpp;
+ /* FIXME: should it ignore this error? */
} else {
retval = false;
goto exit;
}
- if (IS_ISP2401) {
- if (stream->pipes[i]->mode < IA_CSS_PIPE_ID_NUM) {
- sh_css_set_dp_config(stream->pipes[i], params,
- &stream_params->pipe_dp_config[stream->pipes[i]->mode]);
- ia_css_set_param_exceptions(stream->pipes[i], params);
- } else {
- retval = false;
- goto exit;
- }
- }
}
- if (!IS_ISP2401)
- ia_css_set_param_exceptions(pipe_in, params);
+ ia_css_set_param_exceptions(pipe_in, params);
params->fpn_config.data = stream_params->fpn_config.data;
params->config_changed[IA_CSS_FPN_ID] =
@@ -2672,13 +2539,10 @@ sh_css_init_isp_params_from_global(struct ia_css_stream *stream,
sh_css_set_morph_table(params, stream_params->morph_table);
if (stream_params->sc_table) {
- sh_css_update_shading_table_status(pipe_in, params);
sh_css_set_shading_table(stream, params, stream_params->sc_table);
} else {
params->sc_table = NULL;
params->sc_table_changed = true;
- params->sc_table_dirty = false;
- params->sc_table_last_pipe_num = 0;
}
/* Only IA_CSS_PIPE_ID_VIDEO & IA_CSS_PIPE_ID_CAPTURE will support dvs_6axis_config*/
@@ -2771,18 +2635,6 @@ static void host_lut_store(const void *lut)
gdc_lut_store((gdc_ID_t)i, (const int (*)[HRT_GDC_N]) lut);
}
-/* Note that allocation is in ipu address space. */
-inline ia_css_ptr sh_css_params_alloc_gdc_lut(void)
-{
- return hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
-}
-
-inline void sh_css_params_free_gdc_lut(ia_css_ptr addr)
-{
- if (addr != mmgr_NULL)
- hmm_free(addr);
-}
-
int ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
const void *lut)
{
@@ -2809,14 +2661,13 @@ int ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe,
}
/* Free any existing tables. */
- sh_css_params_free_gdc_lut(pipe->scaler_pp_lut);
- pipe->scaler_pp_lut = mmgr_NULL;
+ if (pipe->scaler_pp_lut != mmgr_NULL) {
+ hmm_free(pipe->scaler_pp_lut);
+ pipe->scaler_pp_lut = mmgr_NULL;
+ }
if (!stream_started) {
- if (!IS_ISP2401)
- pipe->scaler_pp_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
- else
- pipe->scaler_pp_lut = sh_css_params_alloc_gdc_lut();
+ pipe->scaler_pp_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
if (pipe->scaler_pp_lut == mmgr_NULL) {
ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
@@ -2858,10 +2709,7 @@ int sh_css_params_map_and_store_default_gdc_lut(void)
host_lut_store((void *)zoom_table);
- if (!IS_ISP2401)
- default_gdc_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
- else
- default_gdc_lut = sh_css_params_alloc_gdc_lut();
+ default_gdc_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0);
if (default_gdc_lut == mmgr_NULL)
return -ENOMEM;
@@ -2879,8 +2727,10 @@ void sh_css_params_free_default_gdc_lut(void)
{
IA_CSS_ENTER_PRIVATE("void");
- sh_css_params_free_gdc_lut(default_gdc_lut);
- default_gdc_lut = mmgr_NULL;
+ if (default_gdc_lut != mmgr_NULL) {
+ hmm_free(default_gdc_lut);
+ default_gdc_lut = mmgr_NULL;
+ }
IA_CSS_LEAVE_PRIVATE("void");
}
@@ -3252,15 +3102,10 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
isp_pipe_version = ia_css_pipe_get_isp_pipe_version(pipe);
ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
ia_css_query_internal_queue_id(params->output_frame
? IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET
: IA_CSS_BUFFER_TYPE_PARAMETER_SET,
thread_id, &queue_id);
-#else
- ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_PARAMETER_SET, thread_id,
- &queue_id);
-#endif
if (!sh_css_sp_is_running()) {
/* SP is not running. The queues are not valid */
err = -EBUSY;
@@ -3356,12 +3201,10 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
err = ia_css_bufq_enqueue_buffer(thread_id, queue_id, (uint32_t)cpy);
if (err) {
free_ia_css_isp_parameter_set_info(cpy);
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
IA_CSS_LOG("pfp: FAILED to add config id %d for OF %d to q %d on thread %d",
isp_params_info.isp_parameters_id,
isp_params_info.output_frame_ptr,
queue_id, thread_id);
-#endif
break;
} else {
/* TMP: check discrepancy between nr of enqueued
@@ -3383,12 +3226,10 @@ sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe,
(uint8_t)thread_id,
(uint8_t)queue_id,
0);
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
IA_CSS_LOG("pfp: added config id %d for OF %d to q %d on thread %d",
isp_params_info.isp_parameters_id,
isp_params_info.output_frame_ptr,
queue_id, thread_id);
-#endif
}
/* clean-up old copy */
ia_css_dequeue_param_buffers(/*pipe_num*/);
@@ -3466,18 +3307,12 @@ sh_css_params_write_to_ddr_internal(
if (binary->info->sp.enable.sc) {
u32 enable_conv;
- size_t bytes;
-
- if (!IS_ISP2401)
- bytes = ISP2400_SCTBL_BYTES(binary);
- else
- bytes = ISP2401_SCTBL_BYTES(binary);
enable_conv = params->shading_settings.enable_shading_table_conversion;
buff_realloced = reallocate_buffer(&ddr_map->sc_tbl,
&ddr_map_size->sc_tbl,
- bytes,
+ SCTBL_BYTES(binary),
params->sc_table_changed,
&err);
if (err) {
@@ -3562,31 +3397,9 @@ sh_css_params_write_to_ddr_internal(
}
}
- /* DPC configuration is made pipe specific to allow flexibility in positioning of the
- * DPC kernel. The code below sets the pipe specific configuration to
- * individual binaries. */
- if (IS_ISP2401 &&
- params->pipe_dpc_config_changed[pipe_id] && binary->info->sp.enable.dpc) {
- unsigned int size =
- stage->binary->info->mem_offsets.offsets.param->dmem.dp.size;
-
- unsigned int offset =
- stage->binary->info->mem_offsets.offsets.param->dmem.dp.offset;
-
- if (size) {
- ia_css_dp_encode((struct sh_css_isp_dp_params *)
- &binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset],
- &params->pipe_dp_config[pipe_id], size);
-
- params->isp_params_changed = true;
- params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] =
- true;
- }
- }
-
if (params->config_changed[IA_CSS_MACC_ID] && binary->info->sp.enable.macc) {
unsigned int i, j, idx;
- unsigned int idx_map[] = {
+ static const unsigned int idx_map[] = {
0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8
};
@@ -3665,13 +3478,7 @@ sh_css_params_write_to_ddr_internal(
if (!params->pipe_dvs_6axis_config[pipe_id]) {
struct ia_css_resolution dvs_offset = {0};
- if (!IS_ISP2401) {
- dvs_offset.width = (PIX_SHIFT_FILTER_RUN_IN_X + binary->dvs_envelope.width) / 2;
- } else {
- if (binary->dvs_envelope.width || binary->dvs_envelope.height) {
- dvs_offset.width = (PIX_SHIFT_FILTER_RUN_IN_X + binary->dvs_envelope.width) / 2;
- }
- }
+ dvs_offset.width = (PIX_SHIFT_FILTER_RUN_IN_X + binary->dvs_envelope.width) / 2;
dvs_offset.height = (PIX_SHIFT_FILTER_RUN_IN_Y + binary->dvs_envelope.height) / 2;
params->pipe_dvs_6axis_config[pipe_id] =
@@ -4335,12 +4142,8 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid)
me->data = kvmalloc(grid_size * sizeof(*me->data), GFP_KERNEL);
if (!me->data)
goto err;
-#if !defined(HAS_NO_HMEM)
/* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */
me->rgby_data = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL);
-#else
- me->rgby_data = NULL;
-#endif
IA_CSS_LEAVE("return=%p", me);
return me;
diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.h b/drivers/staging/media/atomisp/pci/sh_css_params.h
index 62a7b6ada237..bbca19d0e8fc 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.h
@@ -121,8 +121,6 @@ struct ia_css_isp_parameters {
bool dvs2_coef_table_changed;
bool morph_table_changed;
bool sc_table_changed;
- bool sc_table_dirty;
- unsigned int sc_table_last_pipe_num;
bool anr_thres_changed;
/* ---- deprecated: replaced with pipe_dvs_6axis_config_changed ---- */
bool dvs_6axis_config_changed;
@@ -168,12 +166,6 @@ ia_css_params_alloc_convert_sctbl(
struct ia_css_isp_config *
sh_css_pipe_isp_config_get(struct ia_css_pipe *pipe);
-/* ipu address allocation/free for gdc lut */
-ia_css_ptr
-sh_css_params_alloc_gdc_lut(void);
-void
-sh_css_params_free_gdc_lut(ia_css_ptr addr);
-
int
sh_css_params_map_and_store_default_gdc_lut(void);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_shading.c b/drivers/staging/media/atomisp/pci/sh_css_shading.c
deleted file mode 100644
index 462caf9cb571..000000000000
--- a/drivers/staging/media/atomisp/pci/sh_css_shading.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* This file will contain the code to implement the functions declared in ia_css_shading.h
- and associated helper functions */
diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.c b/drivers/staging/media/atomisp/pci/sh_css_sp.c
index a73e8ca1e225..615500a7d3c4 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_sp.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_sp.c
@@ -330,9 +330,7 @@ sh_css_sp_start_isys_copy(struct ia_css_frame *out_frame,
unsigned int thread_id;
u8 stage_num = 0;
struct sh_css_sp_pipeline *pipe;
-#if defined SH_CSS_ENABLE_METADATA
enum sh_css_queue_id queue_id;
-#endif
assert(out_frame);
@@ -372,7 +370,6 @@ sh_css_sp_start_isys_copy(struct ia_css_frame *out_frame,
set_output_frame_buffer(out_frame, 0);
-#if defined SH_CSS_ENABLE_METADATA
if (pipe->metadata.height > 0) {
ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id,
&queue_id);
@@ -380,7 +377,6 @@ sh_css_sp_start_isys_copy(struct ia_css_frame *out_frame,
queue_id, mmgr_EXCEPTION,
IA_CSS_BUFFER_TYPE_METADATA);
}
-#endif
ia_css_debug_pipe_graph_dump_sp_raw_copy(out_frame);
}
@@ -812,29 +808,47 @@ is_sp_stage(struct ia_css_pipeline_stage *stage)
return stage->sp_func != IA_CSS_PIPELINE_NO_FUNC;
}
-static int
-configure_isp_from_args(
- const struct sh_css_sp_pipeline *pipeline,
- const struct ia_css_binary *binary,
- const struct sh_css_binary_args *args,
- bool two_ppc,
- bool deinterleaved)
+static int configure_isp_from_args(const struct sh_css_sp_pipeline *pipeline,
+ const struct ia_css_binary *binary,
+ const struct sh_css_binary_args *args,
+ bool two_ppc,
+ bool deinterleaved)
{
- ia_css_fpn_configure(binary, &binary->in_frame_info);
- ia_css_crop_configure(binary, &args->delay_frames[0]->info);
- ia_css_qplane_configure(pipeline, binary, &binary->in_frame_info);
- ia_css_output0_configure(binary, &args->out_frame[0]->info);
- ia_css_output1_configure(binary, &args->out_vf_frame->info);
- ia_css_copy_output_configure(binary, args->copy_output);
- ia_css_output0_configure(binary, &args->out_frame[0]->info);
-#ifdef ISP2401
- ia_css_sc_configure(binary, pipeline->shading.internal_frame_origin_x_bqs_on_sctbl,
- pipeline->shading.internal_frame_origin_y_bqs_on_sctbl);
-#endif
- ia_css_iterator_configure(binary, &args->in_frame->info);
- ia_css_dvs_configure(binary, &args->out_frame[0]->info);
- ia_css_output_configure(binary, &args->out_frame[0]->info);
- ia_css_raw_configure(pipeline, binary, &args->in_frame->info, &binary->in_frame_info, two_ppc, deinterleaved);
+ int ret;
+
+ ret = ia_css_fpn_configure(binary, &binary->in_frame_info);
+ if (ret)
+ return ret;
+ ret = ia_css_crop_configure(binary, &args->delay_frames[0]->info);
+ if (ret)
+ return ret;
+ ret = ia_css_qplane_configure(pipeline, binary, &binary->in_frame_info);
+ if (ret)
+ return ret;
+ ret = ia_css_output0_configure(binary, &args->out_frame[0]->info);
+ if (ret)
+ return ret;
+ ret = ia_css_output1_configure(binary, &args->out_vf_frame->info);
+ if (ret)
+ return ret;
+ ret = ia_css_copy_output_configure(binary, args->copy_output);
+ if (ret)
+ return ret;
+ ret = ia_css_output0_configure(binary, &args->out_frame[0]->info);
+ if (ret)
+ return ret;
+ ret = ia_css_iterator_configure(binary, &args->in_frame->info);
+ if (ret)
+ return ret;
+ ret = ia_css_dvs_configure(binary, &args->out_frame[0]->info);
+ if (ret)
+ return ret;
+ ret = ia_css_output_configure(binary, &args->out_frame[0]->info);
+ if (ret)
+ return ret;
+ ret = ia_css_raw_configure(pipeline, binary, &args->in_frame->info, &binary->in_frame_info, two_ppc, deinterleaved);
+ if (ret)
+ return ret;
/*
* FIXME: args->delay_frames can be NULL here
@@ -846,10 +860,13 @@ configure_isp_from_args(
* without crashing, but the pipeline should likely be built without
* adding it at the first place (or there are a hidden bug somewhere)
*/
- ia_css_ref_configure(binary, args->delay_frames, pipeline->dvs_frame_delay);
- ia_css_tnr_configure(binary, args->tnr_frames);
- ia_css_bayer_io_config(binary, args);
- return 0;
+ ret = ia_css_ref_configure(binary, args->delay_frames, pipeline->dvs_frame_delay);
+ if (ret)
+ return ret;
+ ret = ia_css_tnr_configure(binary, args->tnr_frames);
+ if (ret)
+ return ret;
+ return ia_css_bayer_io_config(binary, args);
}
static void
@@ -883,9 +900,7 @@ initialize_stage_frames(struct ia_css_frames_sp *frames)
initialize_frame_buffer_attribute(&frames->out_vf.buf_attr);
initialize_frame_buffer_attribute(&frames->s3a_buf);
initialize_frame_buffer_attribute(&frames->dvs_buf);
-#if defined SH_CSS_ENABLE_METADATA
initialize_frame_buffer_attribute(&frames->metadata_buf);
-#endif
}
static int
@@ -1011,24 +1026,20 @@ sh_css_sp_init_stage(struct ia_css_binary *binary,
mmgr_EXCEPTION,
IA_CSS_BUFFER_TYPE_DIS_STATISTICS);
}
-#if defined SH_CSS_ENABLE_METADATA
ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_METADATA, thread_id, &queue_id);
sh_css_copy_buffer_attr_to_spbuffer(&sh_css_sp_stage.frames.metadata_buf, queue_id, mmgr_EXCEPTION, IA_CSS_BUFFER_TYPE_METADATA);
-#endif
if (err)
return err;
#ifdef ISP2401
- if (stage == 0) {
- pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
- if (!pipe)
- return -EINVAL;
-
- if (args->in_frame)
- ia_css_get_crop_offsets(pipe, &args->in_frame->info);
- else
- ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
- }
+ pipe = find_pipe_by_num(sh_css_sp_group.pipe[thread_id].pipe_num);
+ if (!pipe)
+ return -EINVAL;
+
+ if (args->in_frame)
+ ia_css_get_crop_offsets(pipe, &args->in_frame->info);
+ else
+ ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
#else
(void)pipe; /*avoid build warning*/
#endif
@@ -1196,12 +1207,7 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
enum ia_css_input_mode input_mode,
const struct ia_css_metadata_config *md_config,
const struct ia_css_metadata_info *md_info,
- const enum mipi_port_id port_id,
- const struct ia_css_coordinate
- *internal_frame_origin_bqs_on_sctbl, /* Origin of internal frame
- positioned on shading table at shading correction in ISP. */
- const struct ia_css_isp_parameters *params
- )
+ const enum mipi_port_id port_id)
{
/* Get first stage */
struct ia_css_pipeline_stage *stage = NULL;
@@ -1288,7 +1294,6 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
}
sh_css_sp_group.pipe[thread_id].scaler_pp_lut = sh_css_pipe_get_pp_gdc_lut(pipe);
-#if defined(SH_CSS_ENABLE_METADATA)
if (md_info && md_info->size > 0) {
sh_css_sp_group.pipe[thread_id].metadata.width = md_info->resolution.width;
sh_css_sp_group.pipe[thread_id].metadata.height = md_info->resolution.height;
@@ -1298,37 +1303,13 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
md_config->data_type, MIPI_PREDICTOR_NONE,
&sh_css_sp_group.pipe[thread_id].metadata.format);
}
-#else
- (void)md_config;
- (void)md_info;
-#endif
-#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
sh_css_sp_group.pipe[thread_id].output_frame_queue_id = (uint32_t)SH_CSS_INVALID_QUEUE_ID;
if (pipe_id != IA_CSS_PIPE_ID_COPY) {
ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, thread_id,
(enum sh_css_queue_id *)(
&sh_css_sp_group.pipe[thread_id].output_frame_queue_id));
}
-#endif
-
- if (IS_ISP2401) {
- /* For the shading correction type 1 (the legacy shading table conversion in css is not used),
- * the parameters are passed to the isp for the shading table centering.
- */
- if (internal_frame_origin_bqs_on_sctbl &&
- params && params->shading_settings.enable_shading_table_conversion == 0) {
- sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl
- = (uint32_t)internal_frame_origin_bqs_on_sctbl->x;
- sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl
- = (uint32_t)internal_frame_origin_bqs_on_sctbl->y;
- } else {
- sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_x_bqs_on_sctbl =
- 0;
- sh_css_sp_group.pipe[thread_id].shading.internal_frame_origin_y_bqs_on_sctbl =
- 0;
- }
- }
IA_CSS_LOG("pipe_id %d port_config %08x",
pipe_id, sh_css_sp_group.pipe[thread_id].inout_port_config);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.h b/drivers/staging/media/atomisp/pci/sh_css_sp.h
index 832eed711525..f69a79b0b0da 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_sp.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_sp.h
@@ -66,12 +66,7 @@ sh_css_sp_init_pipeline(struct ia_css_pipeline *me,
enum ia_css_input_mode input_mode,
const struct ia_css_metadata_config *md_config,
const struct ia_css_metadata_info *md_info,
- const enum mipi_port_id port_id,
- const struct ia_css_coordinate
- *internal_frame_origin_bqs_on_sctbl, /* Origin of internal frame
- positioned on shading table at shading correction in ISP. */
- const struct ia_css_isp_parameters *params
- );
+ const enum mipi_port_id port_id);
void
sh_css_sp_uninit_pipeline(unsigned int pipe_num);
diff --git a/drivers/staging/media/atomisp/pci/sh_css_stream.c b/drivers/staging/media/atomisp/pci/sh_css_stream.c
deleted file mode 100644
index a768ce90f51c..000000000000
--- a/drivers/staging/media/atomisp/pci/sh_css_stream.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for Intel Camera Imaging ISP subsystem.
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- */
-
-/* This file will contain the code to implement the functions declared in ia_css_stream.h
- and associated helper functions */
diff --git a/drivers/staging/media/atomisp/pci/system_global.h b/drivers/staging/media/atomisp/pci/system_global.h
index 9b22b8c168be..060b924023ec 100644
--- a/drivers/staging/media/atomisp/pci/system_global.h
+++ b/drivers/staging/media/atomisp/pci/system_global.h
@@ -25,9 +25,6 @@
* N.B. the 3 input formatters are of 2 different classess
*/
-/* per-frame parameter handling support */
-#define SH_CSS_ENABLE_PER_FRAME_PARAMS
-
#define DMA_DDR_TO_VAMEM_WORKAROUND
#define DMA_DDR_TO_HMEM_WORKAROUND
diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig
index 20b1f6d7b69c..3c5d833322c8 100644
--- a/drivers/staging/media/hantro/Kconfig
+++ b/drivers/staging/media/hantro/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
config VIDEO_HANTRO
tristate "Hantro VPU driver"
- depends on ARCH_MXC || ARCH_ROCKCHIP || ARCH_AT91 || COMPILE_TEST
+ depends on ARCH_MXC || ARCH_ROCKCHIP || ARCH_AT91 || ARCH_SUNXI || COMPILE_TEST
depends on VIDEO_DEV && VIDEO_V4L2
select MEDIA_CONTROLLER
select MEDIA_CONTROLLER_REQUEST_API
@@ -9,6 +9,7 @@ config VIDEO_HANTRO
select VIDEOBUF2_VMALLOC
select V4L2_MEM2MEM_DEV
select V4L2_H264
+ select V4L2_VP9
help
Support for the Hantro IP based Video Processing Units present on
Rockchip and NXP i.MX8M SoCs, which accelerate video and image
@@ -39,3 +40,11 @@ config VIDEO_HANTRO_ROCKCHIP
default y
help
Enable support for RK3288, RK3328, and RK3399 SoCs.
+
+config VIDEO_HANTRO_SUNXI
+ bool "Hantro VPU Allwinner support"
+ depends on VIDEO_HANTRO
+ depends on ARCH_SUNXI || COMPILE_TEST
+ default y
+ help
+ Enable support for H6 SoC.
diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile
index 90036831fec4..ebd5ede7bef7 100644
--- a/drivers/staging/media/hantro/Makefile
+++ b/drivers/staging/media/hantro/Makefile
@@ -10,8 +10,10 @@ hantro-vpu-y += \
hantro_g1.o \
hantro_g1_h264_dec.o \
hantro_g1_mpeg2_dec.o \
- hantro_g2_hevc_dec.o \
hantro_g1_vp8_dec.o \
+ hantro_g2.o \
+ hantro_g2_hevc_dec.o \
+ hantro_g2_vp9_dec.o \
rockchip_vpu2_hw_jpeg_enc.o \
rockchip_vpu2_hw_h264_dec.o \
rockchip_vpu2_hw_mpeg2_dec.o \
@@ -20,7 +22,8 @@ hantro-vpu-y += \
hantro_h264.o \
hantro_hevc.o \
hantro_mpeg2.o \
- hantro_vp8.o
+ hantro_vp8.o \
+ hantro_vp9.o
hantro-vpu-$(CONFIG_VIDEO_HANTRO_IMX8M) += \
imx8m_vpu_hw.o
@@ -30,3 +33,6 @@ hantro-vpu-$(CONFIG_VIDEO_HANTRO_SAMA5D4) += \
hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \
rockchip_vpu_hw.o
+
+hantro-vpu-$(CONFIG_VIDEO_HANTRO_SUNXI) += \
+ sunxi_vpu_hw.o
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
index c2e2dca38628..06d0f3597694 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -16,6 +16,7 @@
#include <linux/videodev2.h>
#include <linux/wait.h>
#include <linux/clk.h>
+#include <linux/reset.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -28,6 +29,7 @@
struct hantro_ctx;
struct hantro_codec_ops;
+struct hantro_postproc_ops;
#define HANTRO_JPEG_ENCODER BIT(0)
#define HANTRO_ENCODERS 0x0000ffff
@@ -35,6 +37,7 @@ struct hantro_codec_ops;
#define HANTRO_VP8_DECODER BIT(17)
#define HANTRO_H264_DECODER BIT(18)
#define HANTRO_HEVC_DECODER BIT(19)
+#define HANTRO_VP9_DECODER BIT(20)
#define HANTRO_DECODERS 0xffff0000
/**
@@ -59,6 +62,7 @@ struct hantro_irq {
* @num_dec_fmts: Number of decoder formats.
* @postproc_fmts: Post-processor formats.
* @num_postproc_fmts: Number of post-processor formats.
+ * @postproc_ops: Post-processor ops.
* @codec: Supported codecs
* @codec_ops: Codec ops.
* @init: Initialize hardware, optional.
@@ -69,7 +73,9 @@ struct hantro_irq {
* @num_clocks: number of clocks in the array
* @reg_names: array of register range names
* @num_regs: number of register range names in the array
- * @postproc_regs: &struct hantro_postproc_regs pointer
+ * @double_buffer: core needs double buffering
+ * @legacy_regs: core uses legacy register set
+ * @late_postproc: postproc must be set up at the end of the job
*/
struct hantro_variant {
unsigned int enc_offset;
@@ -80,6 +86,7 @@ struct hantro_variant {
unsigned int num_dec_fmts;
const struct hantro_fmt *postproc_fmts;
unsigned int num_postproc_fmts;
+ const struct hantro_postproc_ops *postproc_ops;
unsigned int codec;
const struct hantro_codec_ops *codec_ops;
int (*init)(struct hantro_dev *vpu);
@@ -90,7 +97,9 @@ struct hantro_variant {
int num_clocks;
const char * const *reg_names;
int num_regs;
- const struct hantro_postproc_regs *postproc_regs;
+ unsigned int double_buffer : 1;
+ unsigned int legacy_regs : 1;
+ unsigned int late_postproc : 1;
};
/**
@@ -101,6 +110,7 @@ struct hantro_variant {
* @HANTRO_MODE_MPEG2_DEC: MPEG-2 decoder.
* @HANTRO_MODE_VP8_DEC: VP8 decoder.
* @HANTRO_MODE_HEVC_DEC: HEVC decoder.
+ * @HANTRO_MODE_VP9_DEC: VP9 decoder.
*/
enum hantro_codec_mode {
HANTRO_MODE_NONE = -1,
@@ -109,6 +119,7 @@ enum hantro_codec_mode {
HANTRO_MODE_MPEG2_DEC,
HANTRO_MODE_VP8_DEC,
HANTRO_MODE_HEVC_DEC,
+ HANTRO_MODE_VP9_DEC,
};
/*
@@ -167,6 +178,7 @@ hantro_vdev_to_func(struct video_device *vdev)
* @dev: Pointer to device for convenient logging using
* dev_ macros.
* @clocks: Array of clock handles.
+ * @resets: Array of reset handles.
* @reg_bases: Mapped addresses of VPU registers.
* @enc_base: Mapped address of VPU encoder register for convenience.
* @dec_base: Mapped address of VPU decoder register for convenience.
@@ -186,6 +198,7 @@ struct hantro_dev {
struct platform_device *pdev;
struct device *dev;
struct clk_bulk_data *clocks;
+ struct reset_control *resets;
void __iomem **reg_bases;
void __iomem *enc_base;
void __iomem *dec_base;
@@ -222,6 +235,7 @@ struct hantro_dev {
* @mpeg2_dec: MPEG-2-decoding context.
* @vp8_dec: VP8-decoding context.
* @hevc_dec: HEVC-decoding context.
+ * @vp9_dec: VP9-decoding context.
*/
struct hantro_ctx {
struct hantro_dev *dev;
@@ -249,6 +263,7 @@ struct hantro_ctx {
struct hantro_mpeg2_dec_hw_ctx mpeg2_dec;
struct hantro_vp8_dec_hw_ctx vp8_dec;
struct hantro_hevc_dec_hw_ctx hevc_dec;
+ struct hantro_vp9_dec_hw_ctx vp9_dec;
};
};
@@ -262,6 +277,7 @@ struct hantro_ctx {
* @max_depth: Maximum depth, for bitstream formats
* @enc_fmt: Format identifier for encoder registers.
* @frmsize: Supported range of frame sizes (only for bitstream formats).
+ * @postprocessed: Indicates if this format needs the post-processor.
*/
struct hantro_fmt {
char *name;
@@ -271,6 +287,7 @@ struct hantro_fmt {
int max_depth;
enum hantro_enc_fmt enc_fmt;
struct v4l2_frmsize_stepwise frmsize;
+ bool postprocessed;
};
struct hantro_reg {
@@ -296,6 +313,22 @@ struct hantro_postproc_regs {
struct hantro_reg display_width;
};
+struct hantro_vp9_decoded_buffer_info {
+ /* Info needed when the decoded frame serves as a reference frame. */
+ unsigned short width;
+ unsigned short height;
+ u32 bit_depth : 4;
+};
+
+struct hantro_decoded_buffer {
+ /* Must be the first field in this struct. */
+ struct v4l2_m2m_buffer base;
+
+ union {
+ struct hantro_vp9_decoded_buffer_info vp9;
+ };
+};
+
/* Logging helpers */
/**
@@ -366,6 +399,13 @@ static inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg)
writel(val, vpu->dec_base + reg);
}
+static inline void hantro_write_addr(struct hantro_dev *vpu,
+ unsigned long offset,
+ dma_addr_t addr)
+{
+ vdpu_write(vpu, addr & 0xffffffff, offset);
+}
+
static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg)
{
u32 val = readl(vpu->dec_base + reg);
@@ -426,6 +466,12 @@ hantro_get_dec_buf_addr(struct hantro_ctx *ctx, struct vb2_buffer *vb)
return vb2_dma_contig_plane_dma_addr(vb, 0);
}
+static inline struct hantro_decoded_buffer *
+vb2_to_hantro_decoded_buf(struct vb2_buffer *buf)
+{
+ return container_of(buf, struct hantro_decoded_buffer, base.vb.vb2_buf);
+}
+
void hantro_postproc_disable(struct hantro_ctx *ctx);
void hantro_postproc_enable(struct hantro_ctx *ctx);
void hantro_postproc_free(struct hantro_ctx *ctx);
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index fb82b9297a2b..6a51f39dde56 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -130,7 +130,7 @@ void hantro_start_prepare_run(struct hantro_ctx *ctx)
v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
&ctx->ctrl_handler);
- if (!ctx->is_encoder) {
+ if (!ctx->is_encoder && !ctx->dev->variant->late_postproc) {
if (hantro_needs_postproc(ctx, ctx->vpu_dst_fmt))
hantro_postproc_enable(ctx);
else
@@ -142,6 +142,13 @@ void hantro_end_prepare_run(struct hantro_ctx *ctx)
{
struct vb2_v4l2_buffer *src_buf;
+ if (!ctx->is_encoder && ctx->dev->variant->late_postproc) {
+ if (hantro_needs_postproc(ctx, ctx->vpu_dst_fmt))
+ hantro_postproc_enable(ctx);
+ else
+ hantro_postproc_disable(ctx);
+ }
+
src_buf = hantro_get_src_buf(ctx);
v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
&ctx->ctrl_handler);
@@ -232,7 +239,7 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
dst_vq->drv_priv = ctx;
dst_vq->ops = &hantro_queue_ops;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+ dst_vq->buf_struct_size = sizeof(struct hantro_decoded_buffer);
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
dst_vq->lock = &ctx->dev->vpu_mutex;
dst_vq->dev = ctx->dev->v4l2_dev.dev;
@@ -263,6 +270,12 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
if (sps->bit_depth_luma_minus8 != 0)
/* Only 8-bit is supported */
return -EINVAL;
+ } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
+ const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
+
+ /* We only support profile 0 */
+ if (dec_params->profile != 0)
+ return -EINVAL;
}
return 0;
}
@@ -461,6 +474,16 @@ static const struct hantro_ctrl controls[] = {
.step = 1,
.ops = &hantro_hevc_ctrl_ops,
},
+ }, {
+ .codec = HANTRO_VP9_DECODER,
+ .cfg = {
+ .id = V4L2_CID_STATELESS_VP9_FRAME,
+ },
+ }, {
+ .codec = HANTRO_VP9_DECODER,
+ .cfg = {
+ .id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR,
+ },
},
};
@@ -598,6 +621,9 @@ static const struct of_device_id of_hantro_match[] = {
#ifdef CONFIG_VIDEO_HANTRO_SAMA5D4
{ .compatible = "microchip,sama5d4-vdec", .data = &sama5d4_vdec_variant, },
#endif
+#ifdef CONFIG_VIDEO_HANTRO_SUNXI
+ { .compatible = "allwinner,sun50i-h6-vpu-g2", .data = &sunxi_vpu_variant, },
+#endif
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_hantro_match);
@@ -889,6 +915,10 @@ static int hantro_probe(struct platform_device *pdev)
return PTR_ERR(vpu->clocks[0].clk);
}
+ vpu->resets = devm_reset_control_array_get(&pdev->dev, false, true);
+ if (IS_ERR(vpu->resets))
+ return PTR_ERR(vpu->resets);
+
num_bases = vpu->variant->num_regs ?: 1;
vpu->reg_bases = devm_kcalloc(&pdev->dev, num_bases,
sizeof(*vpu->reg_bases), GFP_KERNEL);
@@ -907,6 +937,11 @@ static int hantro_probe(struct platform_device *pdev)
vpu->enc_base = vpu->reg_bases[0] + vpu->variant->enc_offset;
vpu->dec_base = vpu->reg_bases[0] + vpu->variant->dec_offset;
+ /**
+ * TODO: Eventually allow taking advantage of full 64-bit address space.
+ * Until then we assume the MSB portion of buffers' base addresses is
+ * always 0 due to this masking operation.
+ */
ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(vpu->dev, "Could not set DMA coherent mask.\n");
@@ -957,10 +992,16 @@ static int hantro_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(vpu->dev);
pm_runtime_enable(vpu->dev);
+ ret = reset_control_deassert(vpu->resets);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to deassert resets\n");
+ goto err_pm_disable;
+ }
+
ret = clk_bulk_prepare(vpu->variant->num_clocks, vpu->clocks);
if (ret) {
dev_err(&pdev->dev, "Failed to prepare clocks\n");
- return ret;
+ goto err_rst_assert;
}
ret = v4l2_device_register(&pdev->dev, &vpu->v4l2_dev);
@@ -1016,6 +1057,9 @@ err_v4l2_unreg:
v4l2_device_unregister(&vpu->v4l2_dev);
err_clk_unprepare:
clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
+err_rst_assert:
+ reset_control_assert(vpu->resets);
+err_pm_disable:
pm_runtime_dont_use_autosuspend(vpu->dev);
pm_runtime_disable(vpu->dev);
return ret;
@@ -1034,6 +1078,7 @@ static int hantro_remove(struct platform_device *pdev)
v4l2_m2m_release(vpu->m2m_dev);
v4l2_device_unregister(&vpu->v4l2_dev);
clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
+ reset_control_assert(vpu->resets);
pm_runtime_dont_use_autosuspend(vpu->dev);
pm_runtime_disable(vpu->dev);
return 0;
diff --git a/drivers/staging/media/hantro/hantro_g2.c b/drivers/staging/media/hantro/hantro_g2.c
new file mode 100644
index 000000000000..ee5f14c5f8f2
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_g2.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VPU codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd, Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+ */
+
+#include "hantro_hw.h"
+#include "hantro_g2_regs.h"
+
+void hantro_g2_check_idle(struct hantro_dev *vpu)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ u32 status;
+
+ /* Make sure the VPU is idle */
+ status = vdpu_read(vpu, G2_REG_INTERRUPT);
+ if (status & G2_REG_INTERRUPT_DEC_E) {
+ dev_warn(vpu->dev, "device still running, aborting");
+ status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS;
+ vdpu_write(vpu, status, G2_REG_INTERRUPT);
+ }
+ }
+}
+
+irqreturn_t hantro_g2_irq(int irq, void *dev_id)
+{
+ struct hantro_dev *vpu = dev_id;
+ enum vb2_buffer_state state;
+ u32 status;
+
+ status = vdpu_read(vpu, G2_REG_INTERRUPT);
+ state = (status & G2_REG_INTERRUPT_DEC_RDY_INT) ?
+ VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
+
+ vdpu_write(vpu, 0, G2_REG_INTERRUPT);
+ vdpu_write(vpu, G2_REG_CONFIG_DEC_CLK_GATE_E, G2_REG_CONFIG);
+
+ hantro_irq_done(vpu, state);
+
+ return IRQ_HANDLED;
+}
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 76a921163b9a..99d8ea7543da 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -8,20 +8,6 @@
#include "hantro_hw.h"
#include "hantro_g2_regs.h"
-#define HEVC_DEC_MODE 0xC
-
-#define BUS_WIDTH_32 0
-#define BUS_WIDTH_64 1
-#define BUS_WIDTH_128 2
-#define BUS_WIDTH_256 3
-
-static inline void hantro_write_addr(struct hantro_dev *vpu,
- unsigned long offset,
- dma_addr_t addr)
-{
- vdpu_write(vpu, addr & 0xffffffff, offset);
-}
-
static void prepare_tile_info_buffer(struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
@@ -368,6 +354,8 @@ static int set_ref(struct hantro_ctx *ctx)
const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
dma_addr_t luma_addr, chroma_addr, mv_addr = 0;
struct hantro_dev *vpu = ctx->dev;
+ struct vb2_v4l2_buffer *vb2_dst;
+ struct hantro_decoded_buffer *dst;
size_t cr_offset = hantro_hevc_chroma_offset(sps);
size_t mv_offset = hantro_hevc_motion_vectors_offset(sps);
u32 max_ref_frames;
@@ -448,32 +436,37 @@ static int set_ref(struct hantro_ctx *ctx)
if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
- hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
- hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
- hantro_write_addr(vpu, G2_REG_DMV_REF(i), mv_addr);
+ hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr);
+ hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), chroma_addr);
+ hantro_write_addr(vpu, G2_REF_MV_ADDR(i), mv_addr);
}
- luma_addr = hantro_hevc_get_ref_buf(ctx, decode_params->pic_order_cnt_val);
+ vb2_dst = hantro_get_dst_buf(ctx);
+ dst = vb2_to_hantro_decoded_buf(&vb2_dst->vb2_buf);
+ luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf);
if (!luma_addr)
return -ENOMEM;
+ if (hantro_hevc_add_ref_buf(ctx, decode_params->pic_order_cnt_val, luma_addr))
+ return -EINVAL;
+
chroma_addr = luma_addr + cr_offset;
mv_addr = luma_addr + mv_offset;
- hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
- hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
- hantro_write_addr(vpu, G2_REG_DMV_REF(i++), mv_addr);
+ hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr);
+ hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), chroma_addr);
+ hantro_write_addr(vpu, G2_REF_MV_ADDR(i++), mv_addr);
- hantro_write_addr(vpu, G2_ADDR_DST, luma_addr);
- hantro_write_addr(vpu, G2_ADDR_DST_CHR, chroma_addr);
- hantro_write_addr(vpu, G2_ADDR_DST_MV, mv_addr);
+ hantro_write_addr(vpu, G2_OUT_LUMA_ADDR, luma_addr);
+ hantro_write_addr(vpu, G2_OUT_CHROMA_ADDR, chroma_addr);
+ hantro_write_addr(vpu, G2_OUT_MV_ADDR, mv_addr);
hantro_hevc_ref_remove_unused(ctx);
for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
- hantro_write_addr(vpu, G2_REG_ADDR_REF(i), 0);
- hantro_write_addr(vpu, G2_REG_CHR_REF(i), 0);
- hantro_write_addr(vpu, G2_REG_DMV_REF(i), 0);
+ hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), 0);
+ hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), 0);
+ hantro_write_addr(vpu, G2_REF_MV_ADDR(i), 0);
}
hantro_reg_write(vpu, &g2_refer_lterm_e, dpb_longterm_e);
@@ -483,37 +476,28 @@ static int set_ref(struct hantro_ctx *ctx)
static void set_buffers(struct hantro_ctx *ctx)
{
- struct vb2_v4l2_buffer *src_buf, *dst_buf;
+ struct vb2_v4l2_buffer *src_buf;
struct hantro_dev *vpu = ctx->dev;
- const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
- const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
- size_t cr_offset = hantro_hevc_chroma_offset(sps);
- dma_addr_t src_dma, dst_dma;
+ dma_addr_t src_dma;
u32 src_len, src_buf_len;
src_buf = hantro_get_src_buf(ctx);
- dst_buf = hantro_get_dst_buf(ctx);
/* Source (stream) buffer. */
src_dma = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
src_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
src_buf_len = vb2_plane_size(&src_buf->vb2_buf, 0);
- hantro_write_addr(vpu, G2_ADDR_STR, src_dma);
+ hantro_write_addr(vpu, G2_STREAM_ADDR, src_dma);
hantro_reg_write(vpu, &g2_stream_len, src_len);
hantro_reg_write(vpu, &g2_strm_buffer_len, src_buf_len);
hantro_reg_write(vpu, &g2_strm_start_offset, 0);
hantro_reg_write(vpu, &g2_write_mvs_e, 1);
- /* Destination (decoded frame) buffer. */
- dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf);
-
- hantro_write_addr(vpu, G2_RASTER_SCAN, dst_dma);
- hantro_write_addr(vpu, G2_RASTER_SCAN_CHR, dst_dma + cr_offset);
- hantro_write_addr(vpu, G2_ADDR_TILE_SIZE, ctx->hevc_dec.tile_sizes.dma);
- hantro_write_addr(vpu, G2_TILE_FILTER, ctx->hevc_dec.tile_filter.dma);
- hantro_write_addr(vpu, G2_TILE_SAO, ctx->hevc_dec.tile_sao.dma);
- hantro_write_addr(vpu, G2_TILE_BSD, ctx->hevc_dec.tile_bsd.dma);
+ hantro_write_addr(vpu, G2_TILE_SIZES_ADDR, ctx->hevc_dec.tile_sizes.dma);
+ hantro_write_addr(vpu, G2_TILE_FILTER_ADDR, ctx->hevc_dec.tile_filter.dma);
+ hantro_write_addr(vpu, G2_TILE_SAO_ADDR, ctx->hevc_dec.tile_sao.dma);
+ hantro_write_addr(vpu, G2_TILE_BSD_ADDR, ctx->hevc_dec.tile_bsd.dma);
}
static void prepare_scaling_list_buffer(struct hantro_ctx *ctx)
@@ -563,24 +547,7 @@ static void prepare_scaling_list_buffer(struct hantro_ctx *ctx)
for (k = 0; k < 8; k++)
*p++ = sc->scaling_list_32x32[i][8 * k + j];
- hantro_write_addr(vpu, HEVC_SCALING_LIST, ctx->hevc_dec.scaling_lists.dma);
-}
-
-static void hantro_g2_check_idle(struct hantro_dev *vpu)
-{
- int i;
-
- for (i = 0; i < 3; i++) {
- u32 status;
-
- /* Make sure the VPU is idle */
- status = vdpu_read(vpu, G2_REG_INTERRUPT);
- if (status & G2_REG_INTERRUPT_DEC_E) {
- dev_warn(vpu->dev, "device still running, aborting");
- status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS;
- vdpu_write(vpu, status, G2_REG_INTERRUPT);
- }
- }
+ hantro_write_addr(vpu, G2_HEVC_SCALING_LIST_ADDR, ctx->hevc_dec.scaling_lists.dma);
}
int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
@@ -619,9 +586,6 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
/* Don't compress buffers */
hantro_reg_write(vpu, &g2_ref_compress_bypass, 1);
- /* use NV12 as output format */
- hantro_reg_write(vpu, &g2_out_rs_e, 1);
-
/* Bus width and max burst */
hantro_reg_write(vpu, &g2_buswidth, BUS_WIDTH_128);
hantro_reg_write(vpu, &g2_max_burst, 16);
diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
index bb22fa921914..b7c6f9877b9d 100644
--- a/drivers/staging/media/hantro/hantro_g2_regs.h
+++ b/drivers/staging/media/hantro/hantro_g2_regs.h
@@ -27,8 +27,22 @@
#define G2_REG_INTERRUPT_DEC_IRQ_DIS BIT(4)
#define G2_REG_INTERRUPT_DEC_E BIT(0)
+#define HEVC_DEC_MODE 0xc
+#define VP9_DEC_MODE 0xd
+
+#define BUS_WIDTH_32 0
+#define BUS_WIDTH_64 1
+#define BUS_WIDTH_128 2
+#define BUS_WIDTH_256 3
+
#define g2_strm_swap G2_DEC_REG(2, 28, 0xf)
+#define g2_strm_swap_old G2_DEC_REG(2, 27, 0x1f)
+#define g2_pic_swap G2_DEC_REG(2, 22, 0x1f)
#define g2_dirmv_swap G2_DEC_REG(2, 20, 0xf)
+#define g2_dirmv_swap_old G2_DEC_REG(2, 17, 0x1f)
+#define g2_tab0_swap_old G2_DEC_REG(2, 12, 0x1f)
+#define g2_tab1_swap_old G2_DEC_REG(2, 7, 0x1f)
+#define g2_tab2_swap_old G2_DEC_REG(2, 2, 0x1f)
#define g2_mode G2_DEC_REG(3, 27, 0x1f)
#define g2_compress_swap G2_DEC_REG(3, 20, 0xf)
@@ -37,11 +51,14 @@
#define g2_out_dis G2_DEC_REG(3, 15, 0x1)
#define g2_out_filtering_dis G2_DEC_REG(3, 14, 0x1)
#define g2_write_mvs_e G2_DEC_REG(3, 12, 0x1)
+#define g2_tab3_swap_old G2_DEC_REG(3, 7, 0x1f)
+#define g2_rscan_swap G2_DEC_REG(3, 2, 0x1f)
#define g2_pic_width_in_cbs G2_DEC_REG(4, 19, 0x1fff)
#define g2_pic_height_in_cbs G2_DEC_REG(4, 6, 0x1fff)
#define g2_num_ref_frames G2_DEC_REG(4, 0, 0x1f)
+#define g2_start_bit G2_DEC_REG(5, 25, 0x7f)
#define g2_scaling_list_e G2_DEC_REG(5, 24, 0x1)
#define g2_cb_qp_offset G2_DEC_REG(5, 19, 0x1f)
#define g2_cr_qp_offset G2_DEC_REG(5, 14, 0x1f)
@@ -49,6 +66,7 @@
#define g2_tempor_mvp_e G2_DEC_REG(5, 11, 0x1)
#define g2_max_cu_qpd_depth G2_DEC_REG(5, 5, 0x3f)
#define g2_cu_qpd_e G2_DEC_REG(5, 4, 0x1)
+#define g2_pix_shift G2_DEC_REG(5, 0, 0xf)
#define g2_stream_len G2_DEC_REG(6, 0, 0xffffffff)
@@ -71,24 +89,40 @@
#define g2_const_intra_e G2_DEC_REG(8, 31, 0x1)
#define g2_filt_ctrl_pres G2_DEC_REG(8, 30, 0x1)
+#define g2_bit_depth_y G2_DEC_REG(8, 21, 0xf)
+#define g2_bit_depth_c G2_DEC_REG(8, 17, 0xf)
#define g2_idr_pic_e G2_DEC_REG(8, 16, 0x1)
#define g2_bit_depth_pcm_y G2_DEC_REG(8, 12, 0xf)
#define g2_bit_depth_pcm_c G2_DEC_REG(8, 8, 0xf)
#define g2_bit_depth_y_minus8 G2_DEC_REG(8, 6, 0x3)
#define g2_bit_depth_c_minus8 G2_DEC_REG(8, 4, 0x3)
+#define g2_rs_out_bit_depth G2_DEC_REG(8, 4, 0xf)
#define g2_output_8_bits G2_DEC_REG(8, 3, 0x1)
+#define g2_output_format G2_DEC_REG(8, 0, 0x7)
+#define g2_pp_pix_shift G2_DEC_REG(8, 0, 0xf)
#define g2_refidx1_active G2_DEC_REG(9, 19, 0x1f)
#define g2_refidx0_active G2_DEC_REG(9, 14, 0x1f)
#define g2_hdr_skip_length G2_DEC_REG(9, 0, 0x3fff)
#define g2_start_code_e G2_DEC_REG(10, 31, 0x1)
+#define g2_init_qp_old G2_DEC_REG(10, 25, 0x3f)
#define g2_init_qp G2_DEC_REG(10, 24, 0x3f)
+#define g2_num_tile_cols_old G2_DEC_REG(10, 20, 0x1f)
#define g2_num_tile_cols G2_DEC_REG(10, 19, 0x1f)
+#define g2_num_tile_rows_old G2_DEC_REG(10, 15, 0x1f)
#define g2_num_tile_rows G2_DEC_REG(10, 14, 0x1f)
#define g2_tile_e G2_DEC_REG(10, 1, 0x1)
#define g2_entropy_sync_e G2_DEC_REG(10, 0, 0x1)
+#define vp9_transform_mode G2_DEC_REG(11, 27, 0x7)
+#define vp9_filt_sharpness G2_DEC_REG(11, 21, 0x7)
+#define vp9_mcomp_filt_type G2_DEC_REG(11, 8, 0x7)
+#define vp9_high_prec_mv_e G2_DEC_REG(11, 7, 0x1)
+#define vp9_comp_pred_mode G2_DEC_REG(11, 4, 0x3)
+#define vp9_gref_sign_bias G2_DEC_REG(11, 2, 0x1)
+#define vp9_aref_sign_bias G2_DEC_REG(11, 0, 0x1)
+
#define g2_refer_lterm_e G2_DEC_REG(12, 16, 0xffff)
#define g2_min_cb_size G2_DEC_REG(12, 13, 0x7)
#define g2_max_cb_size G2_DEC_REG(12, 10, 0x7)
@@ -147,6 +181,50 @@
#define g2_partial_ctb_y G2_DEC_REG(20, 30, 0x1)
#define g2_pic_width_4x4 G2_DEC_REG(20, 16, 0xfff)
#define g2_pic_height_4x4 G2_DEC_REG(20, 0, 0xfff)
+
+#define vp9_qp_delta_y_dc G2_DEC_REG(13, 23, 0x3f)
+#define vp9_qp_delta_ch_dc G2_DEC_REG(13, 17, 0x3f)
+#define vp9_qp_delta_ch_ac G2_DEC_REG(13, 11, 0x3f)
+#define vp9_last_sign_bias G2_DEC_REG(13, 10, 0x1)
+#define vp9_lossless_e G2_DEC_REG(13, 9, 0x1)
+#define vp9_comp_pred_var_ref1 G2_DEC_REG(13, 7, 0x3)
+#define vp9_comp_pred_var_ref0 G2_DEC_REG(13, 5, 0x3)
+#define vp9_comp_pred_fixed_ref G2_DEC_REG(13, 3, 0x3)
+#define vp9_segment_temp_upd_e G2_DEC_REG(13, 2, 0x1)
+#define vp9_segment_upd_e G2_DEC_REG(13, 1, 0x1)
+#define vp9_segment_e G2_DEC_REG(13, 0, 0x1)
+
+#define vp9_filt_level G2_DEC_REG(14, 18, 0x3f)
+#define vp9_refpic_seg0 G2_DEC_REG(14, 15, 0x7)
+#define vp9_skip_seg0 G2_DEC_REG(14, 14, 0x1)
+#define vp9_filt_level_seg0 G2_DEC_REG(14, 8, 0x3f)
+#define vp9_quant_seg0 G2_DEC_REG(14, 0, 0xff)
+
+#define vp9_refpic_seg1 G2_DEC_REG(15, 15, 0x7)
+#define vp9_skip_seg1 G2_DEC_REG(15, 14, 0x1)
+#define vp9_filt_level_seg1 G2_DEC_REG(15, 8, 0x3f)
+#define vp9_quant_seg1 G2_DEC_REG(15, 0, 0xff)
+
+#define vp9_refpic_seg2 G2_DEC_REG(16, 15, 0x7)
+#define vp9_skip_seg2 G2_DEC_REG(16, 14, 0x1)
+#define vp9_filt_level_seg2 G2_DEC_REG(16, 8, 0x3f)
+#define vp9_quant_seg2 G2_DEC_REG(16, 0, 0xff)
+
+#define vp9_refpic_seg3 G2_DEC_REG(17, 15, 0x7)
+#define vp9_skip_seg3 G2_DEC_REG(17, 14, 0x1)
+#define vp9_filt_level_seg3 G2_DEC_REG(17, 8, 0x3f)
+#define vp9_quant_seg3 G2_DEC_REG(17, 0, 0xff)
+
+#define vp9_refpic_seg4 G2_DEC_REG(18, 15, 0x7)
+#define vp9_skip_seg4 G2_DEC_REG(18, 14, 0x1)
+#define vp9_filt_level_seg4 G2_DEC_REG(18, 8, 0x3f)
+#define vp9_quant_seg4 G2_DEC_REG(18, 0, 0xff)
+
+#define vp9_refpic_seg5 G2_DEC_REG(19, 15, 0x7)
+#define vp9_skip_seg5 G2_DEC_REG(19, 14, 0x1)
+#define vp9_filt_level_seg5 G2_DEC_REG(19, 8, 0x3f)
+#define vp9_quant_seg5 G2_DEC_REG(19, 0, 0xff)
+
#define hevc_cur_poc_00 G2_DEC_REG(46, 24, 0xff)
#define hevc_cur_poc_01 G2_DEC_REG(46, 16, 0xff)
#define hevc_cur_poc_02 G2_DEC_REG(46, 8, 0xff)
@@ -167,9 +245,48 @@
#define hevc_cur_poc_14 G2_DEC_REG(49, 8, 0xff)
#define hevc_cur_poc_15 G2_DEC_REG(49, 0, 0xff)
+#define vp9_refpic_seg6 G2_DEC_REG(31, 15, 0x7)
+#define vp9_skip_seg6 G2_DEC_REG(31, 14, 0x1)
+#define vp9_filt_level_seg6 G2_DEC_REG(31, 8, 0x3f)
+#define vp9_quant_seg6 G2_DEC_REG(31, 0, 0xff)
+
+#define vp9_refpic_seg7 G2_DEC_REG(32, 15, 0x7)
+#define vp9_skip_seg7 G2_DEC_REG(32, 14, 0x1)
+#define vp9_filt_level_seg7 G2_DEC_REG(32, 8, 0x3f)
+#define vp9_quant_seg7 G2_DEC_REG(32, 0, 0xff)
+
+#define vp9_lref_width G2_DEC_REG(33, 16, 0xffff)
+#define vp9_lref_height G2_DEC_REG(33, 0, 0xffff)
+
+#define vp9_gref_width G2_DEC_REG(34, 16, 0xffff)
+#define vp9_gref_height G2_DEC_REG(34, 0, 0xffff)
+
+#define vp9_aref_width G2_DEC_REG(35, 16, 0xffff)
+#define vp9_aref_height G2_DEC_REG(35, 0, 0xffff)
+
+#define vp9_lref_hor_scale G2_DEC_REG(36, 16, 0xffff)
+#define vp9_lref_ver_scale G2_DEC_REG(36, 0, 0xffff)
+
+#define vp9_gref_hor_scale G2_DEC_REG(37, 16, 0xffff)
+#define vp9_gref_ver_scale G2_DEC_REG(37, 0, 0xffff)
+
+#define vp9_aref_hor_scale G2_DEC_REG(38, 16, 0xffff)
+#define vp9_aref_ver_scale G2_DEC_REG(38, 0, 0xffff)
+
+#define vp9_filt_ref_adj_0 G2_DEC_REG(46, 24, 0x7f)
+#define vp9_filt_ref_adj_1 G2_DEC_REG(46, 16, 0x7f)
+#define vp9_filt_ref_adj_2 G2_DEC_REG(46, 8, 0x7f)
+#define vp9_filt_ref_adj_3 G2_DEC_REG(46, 0, 0x7f)
+
+#define vp9_filt_mb_adj_0 G2_DEC_REG(47, 24, 0x7f)
+#define vp9_filt_mb_adj_1 G2_DEC_REG(47, 16, 0x7f)
+#define vp9_filt_mb_adj_2 G2_DEC_REG(47, 8, 0x7f)
+#define vp9_filt_mb_adj_3 G2_DEC_REG(47, 0, 0x7f)
+
#define g2_apf_threshold G2_DEC_REG(55, 0, 0xffff)
#define g2_clk_gate_e G2_DEC_REG(58, 16, 0x1)
+#define g2_double_buffer_e G2_DEC_REG(58, 15, 0x1)
#define g2_buswidth G2_DEC_REG(58, 8, 0x7)
#define g2_max_burst G2_DEC_REG(58, 0, 0xff)
@@ -177,20 +294,24 @@
#define G2_REG_CONFIG_DEC_CLK_GATE_E BIT(16)
#define G2_REG_CONFIG_DEC_CLK_GATE_IDLE_E BIT(17)
-#define G2_ADDR_DST (G2_SWREG(65))
-#define G2_REG_ADDR_REF(i) (G2_SWREG(67) + ((i) * 0x8))
-#define G2_ADDR_DST_CHR (G2_SWREG(99))
-#define G2_REG_CHR_REF(i) (G2_SWREG(101) + ((i) * 0x8))
-#define G2_ADDR_DST_MV (G2_SWREG(133))
-#define G2_REG_DMV_REF(i) (G2_SWREG(135) + ((i) * 0x8))
-#define G2_ADDR_TILE_SIZE (G2_SWREG(167))
-#define G2_ADDR_STR (G2_SWREG(169))
-#define HEVC_SCALING_LIST (G2_SWREG(171))
-#define G2_RASTER_SCAN (G2_SWREG(175))
-#define G2_RASTER_SCAN_CHR (G2_SWREG(177))
-#define G2_TILE_FILTER (G2_SWREG(179))
-#define G2_TILE_SAO (G2_SWREG(181))
-#define G2_TILE_BSD (G2_SWREG(183))
+#define G2_OUT_LUMA_ADDR (G2_SWREG(65))
+#define G2_REF_LUMA_ADDR(i) (G2_SWREG(67) + ((i) * 0x8))
+#define G2_VP9_SEGMENT_WRITE_ADDR (G2_SWREG(79))
+#define G2_VP9_SEGMENT_READ_ADDR (G2_SWREG(81))
+#define G2_OUT_CHROMA_ADDR (G2_SWREG(99))
+#define G2_REF_CHROMA_ADDR(i) (G2_SWREG(101) + ((i) * 0x8))
+#define G2_OUT_MV_ADDR (G2_SWREG(133))
+#define G2_REF_MV_ADDR(i) (G2_SWREG(135) + ((i) * 0x8))
+#define G2_TILE_SIZES_ADDR (G2_SWREG(167))
+#define G2_STREAM_ADDR (G2_SWREG(169))
+#define G2_HEVC_SCALING_LIST_ADDR (G2_SWREG(171))
+#define G2_VP9_CTX_COUNT_ADDR (G2_SWREG(171))
+#define G2_VP9_PROBS_ADDR (G2_SWREG(173))
+#define G2_RS_OUT_LUMA_ADDR (G2_SWREG(175))
+#define G2_RS_OUT_CHROMA_ADDR (G2_SWREG(177))
+#define G2_TILE_FILTER_ADDR (G2_SWREG(179))
+#define G2_TILE_SAO_ADDR (G2_SWREG(181))
+#define G2_TILE_BSD_ADDR (G2_SWREG(183))
#define g2_strm_buffer_len G2_DEC_REG(258, 0, 0xffffffff)
#define g2_strm_start_offset G2_DEC_REG(259, 0, 0xffffffff)
diff --git a/drivers/staging/media/hantro/hantro_g2_vp9_dec.c b/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
new file mode 100644
index 000000000000..91c21b634fab
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
@@ -0,0 +1,1022 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VP9 codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd.
+ */
+#include "media/videobuf2-core.h"
+#include "media/videobuf2-dma-contig.h"
+#include "media/videobuf2-v4l2.h"
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-vp9.h>
+
+#include "hantro.h"
+#include "hantro_vp9.h"
+#include "hantro_g2_regs.h"
+
+#define G2_ALIGN 16
+
+enum hantro_ref_frames {
+ INTRA_FRAME = 0,
+ LAST_FRAME = 1,
+ GOLDEN_FRAME = 2,
+ ALTREF_FRAME = 3,
+ MAX_REF_FRAMES = 4
+};
+
+static int start_prepare_run(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame **dec_params)
+{
+ const struct v4l2_ctrl_vp9_compressed_hdr *prob_updates;
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ struct v4l2_ctrl *ctrl;
+ unsigned int fctx_idx;
+
+ /* v4l2-specific stuff */
+ hantro_start_prepare_run(ctx);
+
+ ctrl = v4l2_ctrl_find(&ctx->ctrl_handler, V4L2_CID_STATELESS_VP9_FRAME);
+ if (WARN_ON(!ctrl))
+ return -EINVAL;
+ *dec_params = ctrl->p_cur.p;
+
+ ctrl = v4l2_ctrl_find(&ctx->ctrl_handler, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR);
+ if (WARN_ON(!ctrl))
+ return -EINVAL;
+ prob_updates = ctrl->p_cur.p;
+ vp9_ctx->cur.tx_mode = prob_updates->tx_mode;
+
+ /*
+ * vp9 stuff
+ *
+ * by this point the userspace has done all parts of 6.2 uncompressed_header()
+ * except this fragment:
+ * if ( FrameIsIntra || error_resilient_mode ) {
+ * setup_past_independence ( )
+ * if ( frame_type == KEY_FRAME || error_resilient_mode == 1 ||
+ * reset_frame_context == 3 ) {
+ * for ( i = 0; i < 4; i ++ ) {
+ * save_probs( i )
+ * }
+ * } else if ( reset_frame_context == 2 ) {
+ * save_probs( frame_context_idx )
+ * }
+ * frame_context_idx = 0
+ * }
+ */
+ fctx_idx = v4l2_vp9_reset_frame_ctx(*dec_params, vp9_ctx->frame_context);
+ vp9_ctx->cur.frame_context_idx = fctx_idx;
+
+ /* 6.1 frame(sz): load_probs() and load_probs2() */
+ vp9_ctx->probability_tables = vp9_ctx->frame_context[fctx_idx];
+
+ /*
+ * The userspace has also performed 6.3 compressed_header(), but handling the
+ * probs in a special way. All probs which need updating, except MV-related,
+ * have been read from the bitstream and translated through inv_map_table[],
+ * but no 6.3.6 inv_recenter_nonneg(v, m) has been performed. The values passed
+ * by userspace are either translated values (there are no 0 values in
+ * inv_map_table[]), or zero to indicate no update. All MV-related probs which need
+ * updating have been read from the bitstream and (mv_prob << 1) | 1 has been
+ * performed. The values passed by userspace are either new values
+ * to replace old ones (the above mentioned shift and bitwise or never result in
+ * a zero) or zero to indicate no update.
+ * fw_update_probs() performs actual probs updates or leaves probs as-is
+ * for values for which a zero was passed from userspace.
+ */
+ v4l2_vp9_fw_update_probs(&vp9_ctx->probability_tables, prob_updates, *dec_params);
+
+ return 0;
+}
+
+static size_t chroma_offset(const struct hantro_ctx *ctx,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ int bytes_per_pixel = dec_params->bit_depth == 8 ? 1 : 2;
+
+ return ctx->src_fmt.width * ctx->src_fmt.height * bytes_per_pixel;
+}
+
+static size_t mv_offset(const struct hantro_ctx *ctx,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ size_t cr_offset = chroma_offset(ctx, dec_params);
+
+ return ALIGN((cr_offset * 3) / 2, G2_ALIGN);
+}
+
+static struct hantro_decoded_buffer *
+get_ref_buf(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp)
+{
+ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
+ struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
+ int buf_idx;
+
+ /*
+ * If a ref is unused or invalid, address of current destination
+ * buffer is returned.
+ */
+ buf_idx = vb2_find_timestamp(cap_q, timestamp, 0);
+ if (buf_idx < 0)
+ return vb2_to_hantro_decoded_buf(&dst->vb2_buf);
+
+ return vb2_to_hantro_decoded_buf(vb2_get_buffer(cap_q, buf_idx));
+}
+
+static void update_dec_buf_info(struct hantro_decoded_buffer *buf,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ buf->vp9.width = dec_params->frame_width_minus_1 + 1;
+ buf->vp9.height = dec_params->frame_height_minus_1 + 1;
+ buf->vp9.bit_depth = dec_params->bit_depth;
+}
+
+static void update_ctx_cur_info(struct hantro_vp9_dec_hw_ctx *vp9_ctx,
+ struct hantro_decoded_buffer *buf,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ vp9_ctx->cur.valid = true;
+ vp9_ctx->cur.reference_mode = dec_params->reference_mode;
+ vp9_ctx->cur.interpolation_filter = dec_params->interpolation_filter;
+ vp9_ctx->cur.flags = dec_params->flags;
+ vp9_ctx->cur.timestamp = buf->base.vb.vb2_buf.timestamp;
+}
+
+static void config_output(struct hantro_ctx *ctx,
+ struct hantro_decoded_buffer *dst,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ dma_addr_t luma_addr, chroma_addr, mv_addr;
+
+ hantro_reg_write(ctx->dev, &g2_out_dis, 0);
+ if (!ctx->dev->variant->legacy_regs)
+ hantro_reg_write(ctx->dev, &g2_output_format, 0);
+
+ luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf);
+ hantro_write_addr(ctx->dev, G2_OUT_LUMA_ADDR, luma_addr);
+
+ chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
+ hantro_write_addr(ctx->dev, G2_OUT_CHROMA_ADDR, chroma_addr);
+
+ mv_addr = luma_addr + mv_offset(ctx, dec_params);
+ hantro_write_addr(ctx->dev, G2_OUT_MV_ADDR, mv_addr);
+}
+
+struct hantro_vp9_ref_reg {
+ const struct hantro_reg width;
+ const struct hantro_reg height;
+ const struct hantro_reg hor_scale;
+ const struct hantro_reg ver_scale;
+ u32 y_base;
+ u32 c_base;
+};
+
+static void config_ref(struct hantro_ctx *ctx,
+ struct hantro_decoded_buffer *dst,
+ const struct hantro_vp9_ref_reg *ref_reg,
+ const struct v4l2_ctrl_vp9_frame *dec_params,
+ u64 ref_ts)
+{
+ struct hantro_decoded_buffer *buf;
+ dma_addr_t luma_addr, chroma_addr;
+ u32 refw, refh;
+
+ buf = get_ref_buf(ctx, &dst->base.vb, ref_ts);
+ refw = buf->vp9.width;
+ refh = buf->vp9.height;
+
+ hantro_reg_write(ctx->dev, &ref_reg->width, refw);
+ hantro_reg_write(ctx->dev, &ref_reg->height, refh);
+
+ hantro_reg_write(ctx->dev, &ref_reg->hor_scale, (refw << 14) / dst->vp9.width);
+ hantro_reg_write(ctx->dev, &ref_reg->ver_scale, (refh << 14) / dst->vp9.height);
+
+ luma_addr = hantro_get_dec_buf_addr(ctx, &buf->base.vb.vb2_buf);
+ hantro_write_addr(ctx->dev, ref_reg->y_base, luma_addr);
+
+ chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
+ hantro_write_addr(ctx->dev, ref_reg->c_base, chroma_addr);
+}
+
+static void config_ref_registers(struct hantro_ctx *ctx,
+ const struct v4l2_ctrl_vp9_frame *dec_params,
+ struct hantro_decoded_buffer *dst,
+ struct hantro_decoded_buffer *mv_ref)
+{
+ static const struct hantro_vp9_ref_reg ref_regs[] = {
+ {
+ /* Last */
+ .width = vp9_lref_width,
+ .height = vp9_lref_height,
+ .hor_scale = vp9_lref_hor_scale,
+ .ver_scale = vp9_lref_ver_scale,
+ .y_base = G2_REF_LUMA_ADDR(0),
+ .c_base = G2_REF_CHROMA_ADDR(0),
+ }, {
+ /* Golden */
+ .width = vp9_gref_width,
+ .height = vp9_gref_height,
+ .hor_scale = vp9_gref_hor_scale,
+ .ver_scale = vp9_gref_ver_scale,
+ .y_base = G2_REF_LUMA_ADDR(4),
+ .c_base = G2_REF_CHROMA_ADDR(4),
+ }, {
+ /* Altref */
+ .width = vp9_aref_width,
+ .height = vp9_aref_height,
+ .hor_scale = vp9_aref_hor_scale,
+ .ver_scale = vp9_aref_ver_scale,
+ .y_base = G2_REF_LUMA_ADDR(5),
+ .c_base = G2_REF_CHROMA_ADDR(5),
+ },
+ };
+ dma_addr_t mv_addr;
+
+ config_ref(ctx, dst, &ref_regs[0], dec_params, dec_params->last_frame_ts);
+ config_ref(ctx, dst, &ref_regs[1], dec_params, dec_params->golden_frame_ts);
+ config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params->alt_frame_ts);
+
+ mv_addr = hantro_get_dec_buf_addr(ctx, &mv_ref->base.vb.vb2_buf) +
+ mv_offset(ctx, dec_params);
+ hantro_write_addr(ctx->dev, G2_REF_MV_ADDR(0), mv_addr);
+
+ hantro_reg_write(ctx->dev, &vp9_last_sign_bias,
+ dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_LAST ? 1 : 0);
+
+ hantro_reg_write(ctx->dev, &vp9_gref_sign_bias,
+ dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_GOLDEN ? 1 : 0);
+
+ hantro_reg_write(ctx->dev, &vp9_aref_sign_bias,
+ dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_ALT ? 1 : 0);
+}
+
+static void recompute_tile_info(unsigned short *tile_info, unsigned int tiles, unsigned int sbs)
+{
+ int i;
+ unsigned int accumulated = 0;
+ unsigned int next_accumulated;
+
+ for (i = 1; i <= tiles; ++i) {
+ next_accumulated = i * sbs / tiles;
+ *tile_info++ = next_accumulated - accumulated;
+ accumulated = next_accumulated;
+ }
+}
+
+static void
+recompute_tile_rc_info(struct hantro_ctx *ctx,
+ unsigned int tile_r, unsigned int tile_c,
+ unsigned int sbs_r, unsigned int sbs_c)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+
+ recompute_tile_info(vp9_ctx->tile_r_info, tile_r, sbs_r);
+ recompute_tile_info(vp9_ctx->tile_c_info, tile_c, sbs_c);
+
+ vp9_ctx->last_tile_r = tile_r;
+ vp9_ctx->last_tile_c = tile_c;
+ vp9_ctx->last_sbs_r = sbs_r;
+ vp9_ctx->last_sbs_c = sbs_c;
+}
+
+static inline unsigned int first_tile_row(unsigned int tile_r, unsigned int sbs_r)
+{
+ if (tile_r == sbs_r + 1)
+ return 1;
+
+ if (tile_r == sbs_r + 2)
+ return 2;
+
+ return 0;
+}
+
+static void
+fill_tile_info(struct hantro_ctx *ctx,
+ unsigned int tile_r, unsigned int tile_c,
+ unsigned int sbs_r, unsigned int sbs_c,
+ unsigned short *tile_mem)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ unsigned int i, j;
+ bool first = true;
+
+ for (i = first_tile_row(tile_r, sbs_r); i < tile_r; ++i) {
+ unsigned short r_info = vp9_ctx->tile_r_info[i];
+
+ if (first) {
+ if (i > 0)
+ r_info += vp9_ctx->tile_r_info[0];
+ if (i == 2)
+ r_info += vp9_ctx->tile_r_info[1];
+ first = false;
+ }
+ for (j = 0; j < tile_c; ++j) {
+ *tile_mem++ = vp9_ctx->tile_c_info[j];
+ *tile_mem++ = r_info;
+ }
+ }
+}
+
+static void
+config_tiles(struct hantro_ctx *ctx,
+ const struct v4l2_ctrl_vp9_frame *dec_params,
+ struct hantro_decoded_buffer *dst)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ struct hantro_aux_buf *misc = &vp9_ctx->misc;
+ struct hantro_aux_buf *tile_edge = &vp9_ctx->tile_edge;
+ dma_addr_t addr;
+ unsigned short *tile_mem;
+ unsigned int rows, cols;
+
+ addr = misc->dma + vp9_ctx->tile_info_offset;
+ hantro_write_addr(ctx->dev, G2_TILE_SIZES_ADDR, addr);
+
+ tile_mem = misc->cpu + vp9_ctx->tile_info_offset;
+ if (dec_params->tile_cols_log2 || dec_params->tile_rows_log2) {
+ unsigned int tile_r = (1 << dec_params->tile_rows_log2);
+ unsigned int tile_c = (1 << dec_params->tile_cols_log2);
+ unsigned int sbs_r = hantro_vp9_num_sbs(dst->vp9.height);
+ unsigned int sbs_c = hantro_vp9_num_sbs(dst->vp9.width);
+
+ if (tile_r != vp9_ctx->last_tile_r || tile_c != vp9_ctx->last_tile_c ||
+ sbs_r != vp9_ctx->last_sbs_r || sbs_c != vp9_ctx->last_sbs_c)
+ recompute_tile_rc_info(ctx, tile_r, tile_c, sbs_r, sbs_c);
+
+ fill_tile_info(ctx, tile_r, tile_c, sbs_r, sbs_c, tile_mem);
+
+ cols = tile_c;
+ rows = tile_r;
+ hantro_reg_write(ctx->dev, &g2_tile_e, 1);
+ } else {
+ tile_mem[0] = hantro_vp9_num_sbs(dst->vp9.width);
+ tile_mem[1] = hantro_vp9_num_sbs(dst->vp9.height);
+
+ cols = 1;
+ rows = 1;
+ hantro_reg_write(ctx->dev, &g2_tile_e, 0);
+ }
+
+ if (ctx->dev->variant->legacy_regs) {
+ hantro_reg_write(ctx->dev, &g2_num_tile_cols_old, cols);
+ hantro_reg_write(ctx->dev, &g2_num_tile_rows_old, rows);
+ } else {
+ hantro_reg_write(ctx->dev, &g2_num_tile_cols, cols);
+ hantro_reg_write(ctx->dev, &g2_num_tile_rows, rows);
+ }
+
+ /* provide aux buffers even if no tiles are used */
+ addr = tile_edge->dma;
+ hantro_write_addr(ctx->dev, G2_TILE_FILTER_ADDR, addr);
+
+ addr = tile_edge->dma + vp9_ctx->bsd_ctrl_offset;
+ hantro_write_addr(ctx->dev, G2_TILE_BSD_ADDR, addr);
+}
+
+static void
+update_feat_and_flag(struct hantro_vp9_dec_hw_ctx *vp9_ctx,
+ const struct v4l2_vp9_segmentation *seg,
+ unsigned int feature,
+ unsigned int segid)
+{
+ u8 mask = V4L2_VP9_SEGMENT_FEATURE_ENABLED(feature);
+
+ vp9_ctx->feature_data[segid][feature] = seg->feature_data[segid][feature];
+ vp9_ctx->feature_enabled[segid] &= ~mask;
+ vp9_ctx->feature_enabled[segid] |= (seg->feature_enabled[segid] & mask);
+}
+
+static inline s16 clip3(s16 x, s16 y, s16 z)
+{
+ return (z < x) ? x : (z > y) ? y : z;
+}
+
+static s16 feat_val_clip3(s16 feat_val, s16 feature_data, bool absolute, u8 clip)
+{
+ if (absolute)
+ return feature_data;
+
+ return clip3(0, 255, feat_val + feature_data);
+}
+
+static void config_segment(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ const struct v4l2_vp9_segmentation *seg;
+ s16 feat_val;
+ unsigned char feat_id;
+ unsigned int segid;
+ bool segment_enabled, absolute, update_data;
+
+ static const struct hantro_reg seg_regs[8][V4L2_VP9_SEG_LVL_MAX] = {
+ { vp9_quant_seg0, vp9_filt_level_seg0, vp9_refpic_seg0, vp9_skip_seg0 },
+ { vp9_quant_seg1, vp9_filt_level_seg1, vp9_refpic_seg1, vp9_skip_seg1 },
+ { vp9_quant_seg2, vp9_filt_level_seg2, vp9_refpic_seg2, vp9_skip_seg2 },
+ { vp9_quant_seg3, vp9_filt_level_seg3, vp9_refpic_seg3, vp9_skip_seg3 },
+ { vp9_quant_seg4, vp9_filt_level_seg4, vp9_refpic_seg4, vp9_skip_seg4 },
+ { vp9_quant_seg5, vp9_filt_level_seg5, vp9_refpic_seg5, vp9_skip_seg5 },
+ { vp9_quant_seg6, vp9_filt_level_seg6, vp9_refpic_seg6, vp9_skip_seg6 },
+ { vp9_quant_seg7, vp9_filt_level_seg7, vp9_refpic_seg7, vp9_skip_seg7 },
+ };
+
+ segment_enabled = !!(dec_params->seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED);
+ hantro_reg_write(ctx->dev, &vp9_segment_e, segment_enabled);
+ hantro_reg_write(ctx->dev, &vp9_segment_upd_e,
+ !!(dec_params->seg.flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP));
+ hantro_reg_write(ctx->dev, &vp9_segment_temp_upd_e,
+ !!(dec_params->seg.flags & V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE));
+
+ seg = &dec_params->seg;
+ absolute = !!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE);
+ update_data = !!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA);
+
+ for (segid = 0; segid < 8; ++segid) {
+ /* Quantizer segment feature */
+ feat_id = V4L2_VP9_SEG_LVL_ALT_Q;
+ feat_val = dec_params->quant.base_q_idx;
+ if (segment_enabled) {
+ if (update_data)
+ update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+ if (v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled, feat_id, segid))
+ feat_val = feat_val_clip3(feat_val,
+ vp9_ctx->feature_data[segid][feat_id],
+ absolute, 255);
+ }
+ hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+
+ /* Loop filter segment feature */
+ feat_id = V4L2_VP9_SEG_LVL_ALT_L;
+ feat_val = dec_params->lf.level;
+ if (segment_enabled) {
+ if (update_data)
+ update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+ if (v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled, feat_id, segid))
+ feat_val = feat_val_clip3(feat_val,
+ vp9_ctx->feature_data[segid][feat_id],
+ absolute, 63);
+ }
+ hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+
+ /* Reference frame segment feature */
+ feat_id = V4L2_VP9_SEG_LVL_REF_FRAME;
+ feat_val = 0;
+ if (segment_enabled) {
+ if (update_data)
+ update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+ if (!(dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
+ v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled, feat_id, segid))
+ feat_val = vp9_ctx->feature_data[segid][feat_id] + 1;
+ }
+ hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+
+ /* Skip segment feature */
+ feat_id = V4L2_VP9_SEG_LVL_SKIP;
+ feat_val = 0;
+ if (segment_enabled) {
+ if (update_data)
+ update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+ feat_val = v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled,
+ feat_id, segid) ? 1 : 0;
+ }
+ hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+ }
+}
+
+static void config_loop_filter(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ bool d = dec_params->lf.flags & V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED;
+
+ hantro_reg_write(ctx->dev, &vp9_filt_level, dec_params->lf.level);
+ hantro_reg_write(ctx->dev, &g2_out_filtering_dis, dec_params->lf.level == 0);
+ hantro_reg_write(ctx->dev, &vp9_filt_sharpness, dec_params->lf.sharpness);
+
+ hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_0, d ? dec_params->lf.ref_deltas[0] : 0);
+ hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_1, d ? dec_params->lf.ref_deltas[1] : 0);
+ hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_2, d ? dec_params->lf.ref_deltas[2] : 0);
+ hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_3, d ? dec_params->lf.ref_deltas[3] : 0);
+ hantro_reg_write(ctx->dev, &vp9_filt_mb_adj_0, d ? dec_params->lf.mode_deltas[0] : 0);
+ hantro_reg_write(ctx->dev, &vp9_filt_mb_adj_1, d ? dec_params->lf.mode_deltas[1] : 0);
+}
+
+static void config_picture_dimensions(struct hantro_ctx *ctx, struct hantro_decoded_buffer *dst)
+{
+ u32 pic_w_4x4, pic_h_4x4;
+
+ hantro_reg_write(ctx->dev, &g2_pic_width_in_cbs, (dst->vp9.width + 7) / 8);
+ hantro_reg_write(ctx->dev, &g2_pic_height_in_cbs, (dst->vp9.height + 7) / 8);
+ pic_w_4x4 = roundup(dst->vp9.width, 8) >> 2;
+ pic_h_4x4 = roundup(dst->vp9.height, 8) >> 2;
+ hantro_reg_write(ctx->dev, &g2_pic_width_4x4, pic_w_4x4);
+ hantro_reg_write(ctx->dev, &g2_pic_height_4x4, pic_h_4x4);
+}
+
+static void
+config_bit_depth(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ if (ctx->dev->variant->legacy_regs) {
+ u8 pp_shift = 0;
+
+ hantro_reg_write(ctx->dev, &g2_bit_depth_y, dec_params->bit_depth);
+ hantro_reg_write(ctx->dev, &g2_bit_depth_c, dec_params->bit_depth);
+ hantro_reg_write(ctx->dev, &g2_rs_out_bit_depth, dec_params->bit_depth);
+
+ if (dec_params->bit_depth > 8)
+ pp_shift = 16 - dec_params->bit_depth;
+
+ hantro_reg_write(ctx->dev, &g2_pp_pix_shift, pp_shift);
+ hantro_reg_write(ctx->dev, &g2_pix_shift, 0);
+ } else {
+ hantro_reg_write(ctx->dev, &g2_bit_depth_y_minus8, dec_params->bit_depth - 8);
+ hantro_reg_write(ctx->dev, &g2_bit_depth_c_minus8, dec_params->bit_depth - 8);
+ }
+}
+
+static inline bool is_lossless(const struct v4l2_vp9_quantization *quant)
+{
+ return quant->base_q_idx == 0 && quant->delta_q_uv_ac == 0 &&
+ quant->delta_q_uv_dc == 0 && quant->delta_q_y_dc == 0;
+}
+
+static void
+config_quant(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ hantro_reg_write(ctx->dev, &vp9_qp_delta_y_dc, dec_params->quant.delta_q_y_dc);
+ hantro_reg_write(ctx->dev, &vp9_qp_delta_ch_dc, dec_params->quant.delta_q_uv_dc);
+ hantro_reg_write(ctx->dev, &vp9_qp_delta_ch_ac, dec_params->quant.delta_q_uv_ac);
+ hantro_reg_write(ctx->dev, &vp9_lossless_e, is_lossless(&dec_params->quant));
+}
+
+static u32
+hantro_interp_filter_from_v4l2(unsigned int interpolation_filter)
+{
+ switch (interpolation_filter) {
+ case V4L2_VP9_INTERP_FILTER_EIGHTTAP:
+ return 0x1;
+ case V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH:
+ return 0;
+ case V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP:
+ return 0x2;
+ case V4L2_VP9_INTERP_FILTER_BILINEAR:
+ return 0x3;
+ case V4L2_VP9_INTERP_FILTER_SWITCHABLE:
+ return 0x4;
+ }
+
+ return 0;
+}
+
+static void
+config_others(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params,
+ bool intra_only, bool resolution_change)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+
+ hantro_reg_write(ctx->dev, &g2_idr_pic_e, intra_only);
+
+ hantro_reg_write(ctx->dev, &vp9_transform_mode, vp9_ctx->cur.tx_mode);
+
+ hantro_reg_write(ctx->dev, &vp9_mcomp_filt_type, intra_only ?
+ 0 : hantro_interp_filter_from_v4l2(dec_params->interpolation_filter));
+
+ hantro_reg_write(ctx->dev, &vp9_high_prec_mv_e,
+ !!(dec_params->flags & V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV));
+
+ hantro_reg_write(ctx->dev, &vp9_comp_pred_mode, dec_params->reference_mode);
+
+ hantro_reg_write(ctx->dev, &g2_tempor_mvp_e,
+ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
+ !(vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
+ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_INTRA_ONLY) &&
+ !resolution_change &&
+ vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME
+ );
+
+ hantro_reg_write(ctx->dev, &g2_write_mvs_e,
+ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME));
+}
+
+static void
+config_compound_reference(struct hantro_ctx *ctx,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ u32 comp_fixed_ref, comp_var_ref[2];
+ bool last_ref_frame_sign_bias;
+ bool golden_ref_frame_sign_bias;
+ bool alt_ref_frame_sign_bias;
+ bool comp_ref_allowed = 0;
+
+ comp_fixed_ref = 0;
+ comp_var_ref[0] = 0;
+ comp_var_ref[1] = 0;
+
+ last_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_LAST;
+ golden_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_GOLDEN;
+ alt_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_ALT;
+
+ /* 6.3.12 Frame reference mode syntax */
+ comp_ref_allowed |= golden_ref_frame_sign_bias != last_ref_frame_sign_bias;
+ comp_ref_allowed |= alt_ref_frame_sign_bias != last_ref_frame_sign_bias;
+
+ if (comp_ref_allowed) {
+ if (last_ref_frame_sign_bias ==
+ golden_ref_frame_sign_bias) {
+ comp_fixed_ref = ALTREF_FRAME;
+ comp_var_ref[0] = LAST_FRAME;
+ comp_var_ref[1] = GOLDEN_FRAME;
+ } else if (last_ref_frame_sign_bias ==
+ alt_ref_frame_sign_bias) {
+ comp_fixed_ref = GOLDEN_FRAME;
+ comp_var_ref[0] = LAST_FRAME;
+ comp_var_ref[1] = ALTREF_FRAME;
+ } else {
+ comp_fixed_ref = LAST_FRAME;
+ comp_var_ref[0] = GOLDEN_FRAME;
+ comp_var_ref[1] = ALTREF_FRAME;
+ }
+ }
+
+ hantro_reg_write(ctx->dev, &vp9_comp_pred_fixed_ref, comp_fixed_ref);
+ hantro_reg_write(ctx->dev, &vp9_comp_pred_var_ref0, comp_var_ref[0]);
+ hantro_reg_write(ctx->dev, &vp9_comp_pred_var_ref1, comp_var_ref[1]);
+}
+
+#define INNER_LOOP \
+do { \
+ for (m = 0; m < ARRAY_SIZE(adaptive->coef[0][0][0][0]); ++m) { \
+ memcpy(adaptive->coef[i][j][k][l][m], \
+ probs->coef[i][j][k][l][m], \
+ sizeof(probs->coef[i][j][k][l][m])); \
+ \
+ adaptive->coef[i][j][k][l][m][3] = 0; \
+ } \
+} while (0)
+
+static void config_probs(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ struct hantro_aux_buf *misc = &vp9_ctx->misc;
+ struct hantro_g2_all_probs *all_probs = misc->cpu;
+ struct hantro_g2_probs *adaptive;
+ struct hantro_g2_mv_probs *mv;
+ const struct v4l2_vp9_segmentation *seg = &dec_params->seg;
+ const struct v4l2_vp9_frame_context *probs = &vp9_ctx->probability_tables;
+ int i, j, k, l, m;
+
+ for (i = 0; i < ARRAY_SIZE(all_probs->kf_y_mode_prob); ++i)
+ for (j = 0; j < ARRAY_SIZE(all_probs->kf_y_mode_prob[0]); ++j) {
+ memcpy(all_probs->kf_y_mode_prob[i][j],
+ v4l2_vp9_kf_y_mode_prob[i][j],
+ ARRAY_SIZE(all_probs->kf_y_mode_prob[i][j]));
+
+ all_probs->kf_y_mode_prob_tail[i][j][0] =
+ v4l2_vp9_kf_y_mode_prob[i][j][8];
+ }
+
+ memcpy(all_probs->mb_segment_tree_probs, seg->tree_probs,
+ sizeof(all_probs->mb_segment_tree_probs));
+
+ memcpy(all_probs->segment_pred_probs, seg->pred_probs,
+ sizeof(all_probs->segment_pred_probs));
+
+ for (i = 0; i < ARRAY_SIZE(all_probs->kf_uv_mode_prob); ++i) {
+ memcpy(all_probs->kf_uv_mode_prob[i], v4l2_vp9_kf_uv_mode_prob[i],
+ ARRAY_SIZE(all_probs->kf_uv_mode_prob[i]));
+
+ all_probs->kf_uv_mode_prob_tail[i][0] = v4l2_vp9_kf_uv_mode_prob[i][8];
+ }
+
+ adaptive = &all_probs->probs;
+
+ for (i = 0; i < ARRAY_SIZE(adaptive->inter_mode); ++i) {
+ memcpy(adaptive->inter_mode[i], probs->inter_mode[i],
+ ARRAY_SIZE(probs->inter_mode[i]));
+
+ adaptive->inter_mode[i][3] = 0;
+ }
+
+ memcpy(adaptive->is_inter, probs->is_inter, sizeof(adaptive->is_inter));
+
+ for (i = 0; i < ARRAY_SIZE(adaptive->uv_mode); ++i) {
+ memcpy(adaptive->uv_mode[i], probs->uv_mode[i],
+ sizeof(adaptive->uv_mode[i]));
+ adaptive->uv_mode_tail[i][0] = probs->uv_mode[i][8];
+ }
+
+ memcpy(adaptive->tx8, probs->tx8, sizeof(adaptive->tx8));
+ memcpy(adaptive->tx16, probs->tx16, sizeof(adaptive->tx16));
+ memcpy(adaptive->tx32, probs->tx32, sizeof(adaptive->tx32));
+
+ for (i = 0; i < ARRAY_SIZE(adaptive->y_mode); ++i) {
+ memcpy(adaptive->y_mode[i], probs->y_mode[i],
+ ARRAY_SIZE(adaptive->y_mode[i]));
+
+ adaptive->y_mode_tail[i][0] = probs->y_mode[i][8];
+ }
+
+ for (i = 0; i < ARRAY_SIZE(adaptive->partition[0]); ++i) {
+ memcpy(adaptive->partition[0][i], v4l2_vp9_kf_partition_probs[i],
+ sizeof(v4l2_vp9_kf_partition_probs[i]));
+
+ adaptive->partition[0][i][3] = 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(adaptive->partition[1]); ++i) {
+ memcpy(adaptive->partition[1][i], probs->partition[i],
+ sizeof(probs->partition[i]));
+
+ adaptive->partition[1][i][3] = 0;
+ }
+
+ memcpy(adaptive->interp_filter, probs->interp_filter,
+ sizeof(adaptive->interp_filter));
+
+ memcpy(adaptive->comp_mode, probs->comp_mode, sizeof(adaptive->comp_mode));
+
+ memcpy(adaptive->skip, probs->skip, sizeof(adaptive->skip));
+
+ mv = &adaptive->mv;
+
+ memcpy(mv->joint, probs->mv.joint, sizeof(mv->joint));
+ memcpy(mv->sign, probs->mv.sign, sizeof(mv->sign));
+ memcpy(mv->class0_bit, probs->mv.class0_bit, sizeof(mv->class0_bit));
+ memcpy(mv->fr, probs->mv.fr, sizeof(mv->fr));
+ memcpy(mv->class0_hp, probs->mv.class0_hp, sizeof(mv->class0_hp));
+ memcpy(mv->hp, probs->mv.hp, sizeof(mv->hp));
+ memcpy(mv->classes, probs->mv.classes, sizeof(mv->classes));
+ memcpy(mv->class0_fr, probs->mv.class0_fr, sizeof(mv->class0_fr));
+ memcpy(mv->bits, probs->mv.bits, sizeof(mv->bits));
+
+ memcpy(adaptive->single_ref, probs->single_ref, sizeof(adaptive->single_ref));
+
+ memcpy(adaptive->comp_ref, probs->comp_ref, sizeof(adaptive->comp_ref));
+
+ for (i = 0; i < ARRAY_SIZE(adaptive->coef); ++i)
+ for (j = 0; j < ARRAY_SIZE(adaptive->coef[0]); ++j)
+ for (k = 0; k < ARRAY_SIZE(adaptive->coef[0][0]); ++k)
+ for (l = 0; l < ARRAY_SIZE(adaptive->coef[0][0][0]); ++l)
+ INNER_LOOP;
+
+ hantro_write_addr(ctx->dev, G2_VP9_PROBS_ADDR, misc->dma);
+}
+
+static void config_counts(struct hantro_ctx *ctx)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
+ struct hantro_aux_buf *misc = &vp9_dec->misc;
+ dma_addr_t addr = misc->dma + vp9_dec->ctx_counters_offset;
+
+ hantro_write_addr(ctx->dev, G2_VP9_CTX_COUNT_ADDR, addr);
+}
+
+static void config_seg_map(struct hantro_ctx *ctx,
+ const struct v4l2_ctrl_vp9_frame *dec_params,
+ bool intra_only, bool update_map)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ struct hantro_aux_buf *segment_map = &vp9_ctx->segment_map;
+ dma_addr_t addr;
+
+ if (intra_only ||
+ (dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT)) {
+ memset(segment_map->cpu, 0, segment_map->size);
+ memset(vp9_ctx->feature_data, 0, sizeof(vp9_ctx->feature_data));
+ memset(vp9_ctx->feature_enabled, 0, sizeof(vp9_ctx->feature_enabled));
+ }
+
+ addr = segment_map->dma + vp9_ctx->active_segment * vp9_ctx->segment_map_size;
+ hantro_write_addr(ctx->dev, G2_VP9_SEGMENT_READ_ADDR, addr);
+
+ addr = segment_map->dma + (1 - vp9_ctx->active_segment) * vp9_ctx->segment_map_size;
+ hantro_write_addr(ctx->dev, G2_VP9_SEGMENT_WRITE_ADDR, addr);
+
+ if (update_map)
+ vp9_ctx->active_segment = 1 - vp9_ctx->active_segment;
+}
+
+static void
+config_source(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params,
+ struct vb2_v4l2_buffer *vb2_src)
+{
+ dma_addr_t stream_base, tmp_addr;
+ unsigned int headres_size;
+ u32 src_len, start_bit, src_buf_len;
+
+ headres_size = dec_params->uncompressed_header_size
+ + dec_params->compressed_header_size;
+
+ stream_base = vb2_dma_contig_plane_dma_addr(&vb2_src->vb2_buf, 0);
+
+ tmp_addr = stream_base + headres_size;
+ if (ctx->dev->variant->legacy_regs)
+ hantro_write_addr(ctx->dev, G2_STREAM_ADDR, (tmp_addr & ~0xf));
+ else
+ hantro_write_addr(ctx->dev, G2_STREAM_ADDR, stream_base);
+
+ start_bit = (tmp_addr & 0xf) * 8;
+ hantro_reg_write(ctx->dev, &g2_start_bit, start_bit);
+
+ src_len = vb2_get_plane_payload(&vb2_src->vb2_buf, 0);
+ src_len += start_bit / 8 - headres_size;
+ hantro_reg_write(ctx->dev, &g2_stream_len, src_len);
+
+ if (!ctx->dev->variant->legacy_regs) {
+ tmp_addr &= ~0xf;
+ hantro_reg_write(ctx->dev, &g2_strm_start_offset, tmp_addr - stream_base);
+ src_buf_len = vb2_plane_size(&vb2_src->vb2_buf, 0);
+ hantro_reg_write(ctx->dev, &g2_strm_buffer_len, src_buf_len);
+ }
+}
+
+static void
+config_registers(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params,
+ struct vb2_v4l2_buffer *vb2_src, struct vb2_v4l2_buffer *vb2_dst)
+{
+ struct hantro_decoded_buffer *dst, *last, *mv_ref;
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ const struct v4l2_vp9_segmentation *seg;
+ bool intra_only, resolution_change;
+
+ /* vp9 stuff */
+ dst = vb2_to_hantro_decoded_buf(&vb2_dst->vb2_buf);
+
+ if (vp9_ctx->last.valid)
+ last = get_ref_buf(ctx, &dst->base.vb, vp9_ctx->last.timestamp);
+ else
+ last = dst;
+
+ update_dec_buf_info(dst, dec_params);
+ update_ctx_cur_info(vp9_ctx, dst, dec_params);
+ seg = &dec_params->seg;
+
+ intra_only = !!(dec_params->flags &
+ (V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+ V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
+
+ if (!intra_only &&
+ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+ vp9_ctx->last.valid)
+ mv_ref = last;
+ else
+ mv_ref = dst;
+
+ resolution_change = dst->vp9.width != last->vp9.width ||
+ dst->vp9.height != last->vp9.height;
+
+ /* configure basic registers */
+ hantro_reg_write(ctx->dev, &g2_mode, VP9_DEC_MODE);
+ if (!ctx->dev->variant->legacy_regs) {
+ hantro_reg_write(ctx->dev, &g2_strm_swap, 0xf);
+ hantro_reg_write(ctx->dev, &g2_dirmv_swap, 0xf);
+ hantro_reg_write(ctx->dev, &g2_compress_swap, 0xf);
+ hantro_reg_write(ctx->dev, &g2_ref_compress_bypass, 1);
+ } else {
+ hantro_reg_write(ctx->dev, &g2_strm_swap_old, 0x1f);
+ hantro_reg_write(ctx->dev, &g2_pic_swap, 0x10);
+ hantro_reg_write(ctx->dev, &g2_dirmv_swap_old, 0x10);
+ hantro_reg_write(ctx->dev, &g2_tab0_swap_old, 0x10);
+ hantro_reg_write(ctx->dev, &g2_tab1_swap_old, 0x10);
+ hantro_reg_write(ctx->dev, &g2_tab2_swap_old, 0x10);
+ hantro_reg_write(ctx->dev, &g2_tab3_swap_old, 0x10);
+ hantro_reg_write(ctx->dev, &g2_rscan_swap, 0x10);
+ }
+ hantro_reg_write(ctx->dev, &g2_buswidth, BUS_WIDTH_128);
+ hantro_reg_write(ctx->dev, &g2_max_burst, 16);
+ hantro_reg_write(ctx->dev, &g2_apf_threshold, 8);
+ hantro_reg_write(ctx->dev, &g2_clk_gate_e, 1);
+ hantro_reg_write(ctx->dev, &g2_max_cb_size, 6);
+ hantro_reg_write(ctx->dev, &g2_min_cb_size, 3);
+ if (ctx->dev->variant->double_buffer)
+ hantro_reg_write(ctx->dev, &g2_double_buffer_e, 1);
+
+ config_output(ctx, dst, dec_params);
+
+ if (!intra_only)
+ config_ref_registers(ctx, dec_params, dst, mv_ref);
+
+ config_tiles(ctx, dec_params, dst);
+ config_segment(ctx, dec_params);
+ config_loop_filter(ctx, dec_params);
+ config_picture_dimensions(ctx, dst);
+ config_bit_depth(ctx, dec_params);
+ config_quant(ctx, dec_params);
+ config_others(ctx, dec_params, intra_only, resolution_change);
+ config_compound_reference(ctx, dec_params);
+ config_probs(ctx, dec_params);
+ config_counts(ctx);
+ config_seg_map(ctx, dec_params, intra_only,
+ seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP);
+ config_source(ctx, dec_params, vb2_src);
+}
+
+int hantro_g2_vp9_dec_run(struct hantro_ctx *ctx)
+{
+ const struct v4l2_ctrl_vp9_frame *decode_params;
+ struct vb2_v4l2_buffer *src;
+ struct vb2_v4l2_buffer *dst;
+ int ret;
+
+ hantro_g2_check_idle(ctx->dev);
+
+ ret = start_prepare_run(ctx, &decode_params);
+ if (ret) {
+ hantro_end_prepare_run(ctx);
+ return ret;
+ }
+
+ src = hantro_get_src_buf(ctx);
+ dst = hantro_get_dst_buf(ctx);
+
+ config_registers(ctx, decode_params, src, dst);
+
+ hantro_end_prepare_run(ctx);
+
+ vdpu_write(ctx->dev, G2_REG_INTERRUPT_DEC_E, G2_REG_INTERRUPT);
+
+ return 0;
+}
+
+#define copy_tx_and_skip(p1, p2) \
+do { \
+ memcpy((p1)->tx8, (p2)->tx8, sizeof((p1)->tx8)); \
+ memcpy((p1)->tx16, (p2)->tx16, sizeof((p1)->tx16)); \
+ memcpy((p1)->tx32, (p2)->tx32, sizeof((p1)->tx32)); \
+ memcpy((p1)->skip, (p2)->skip, sizeof((p1)->skip)); \
+} while (0)
+
+void hantro_g2_vp9_dec_done(struct hantro_ctx *ctx)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ unsigned int fctx_idx;
+
+ if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX))
+ goto out_update_last;
+
+ fctx_idx = vp9_ctx->cur.frame_context_idx;
+
+ if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE)) {
+ /* error_resilient_mode == 0 && frame_parallel_decoding_mode == 0 */
+ struct v4l2_vp9_frame_context *probs = &vp9_ctx->probability_tables;
+ bool frame_is_intra = vp9_ctx->cur.flags &
+ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY);
+ struct tx_and_skip {
+ u8 tx8[2][1];
+ u8 tx16[2][2];
+ u8 tx32[2][3];
+ u8 skip[3];
+ } _tx_skip, *tx_skip = &_tx_skip;
+ struct v4l2_vp9_frame_symbol_counts *counts;
+ struct symbol_counts *hantro_cnts;
+ u32 tx16p[2][4];
+ int i;
+
+ /* buffer the forward-updated TX and skip probs */
+ if (frame_is_intra)
+ copy_tx_and_skip(tx_skip, probs);
+
+ /* 6.1.2 refresh_probs(): load_probs() and load_probs2() */
+ *probs = vp9_ctx->frame_context[fctx_idx];
+
+ /* if FrameIsIntra then undo the effect of load_probs2() */
+ if (frame_is_intra)
+ copy_tx_and_skip(probs, tx_skip);
+
+ counts = &vp9_ctx->cnts;
+ hantro_cnts = vp9_ctx->misc.cpu + vp9_ctx->ctx_counters_offset;
+ for (i = 0; i < ARRAY_SIZE(tx16p); ++i) {
+ memcpy(tx16p[i],
+ hantro_cnts->tx16x16_count[i],
+ sizeof(hantro_cnts->tx16x16_count[0]));
+ tx16p[i][3] = 0;
+ }
+ counts->tx16p = &tx16p;
+
+ v4l2_vp9_adapt_coef_probs(probs, counts,
+ !vp9_ctx->last.valid ||
+ vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME,
+ frame_is_intra);
+
+ if (!frame_is_intra) {
+ /* load_probs2() already done */
+ u32 mv_mode[7][4];
+
+ for (i = 0; i < ARRAY_SIZE(mv_mode); ++i) {
+ mv_mode[i][0] = hantro_cnts->inter_mode_counts[i][1][0];
+ mv_mode[i][1] = hantro_cnts->inter_mode_counts[i][2][0];
+ mv_mode[i][2] = hantro_cnts->inter_mode_counts[i][0][0];
+ mv_mode[i][3] = hantro_cnts->inter_mode_counts[i][2][1];
+ }
+ counts->mv_mode = &mv_mode;
+ v4l2_vp9_adapt_noncoef_probs(&vp9_ctx->probability_tables, counts,
+ vp9_ctx->cur.reference_mode,
+ vp9_ctx->cur.interpolation_filter,
+ vp9_ctx->cur.tx_mode, vp9_ctx->cur.flags);
+ }
+ }
+
+ vp9_ctx->frame_context[fctx_idx] = vp9_ctx->probability_tables;
+
+out_update_last:
+ vp9_ctx->last = vp9_ctx->cur;
+}
diff --git a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
index 56cf261a8e95..1450013d3685 100644
--- a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
+++ b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
@@ -113,9 +113,8 @@ int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx)
hantro_h1_set_src_img_ctrl(vpu, ctx);
hantro_h1_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf);
- hantro_h1_jpeg_enc_set_qtable(vpu,
- hantro_jpeg_get_qtable(0),
- hantro_jpeg_get_qtable(1));
+ hantro_h1_jpeg_enc_set_qtable(vpu, jpeg_ctx.hw_luma_qtable,
+ jpeg_ctx.hw_chroma_qtable);
reg = H1_REG_AXI_CTRL_OUTPUT_SWAP16
| H1_REG_AXI_CTRL_INPUT_SWAP16
@@ -140,7 +139,7 @@ int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx)
return 0;
}
-void hantro_jpeg_enc_done(struct hantro_ctx *ctx)
+void hantro_h1_jpeg_enc_done(struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
u32 bytesused = vepu_read(vpu, H1_REG_STR_BUF_LIMIT) / 8;
diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
index ee03123e7704..b49a41d7ae91 100644
--- a/drivers/staging/media/hantro/hantro_hevc.c
+++ b/drivers/staging/media/hantro/hantro_hevc.c
@@ -44,47 +44,6 @@ size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps)
return ALIGN((cr_offset * 3) / 2, G2_ALIGN);
}
-static size_t hantro_hevc_mv_size(const struct v4l2_ctrl_hevc_sps *sps)
-{
- u32 min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3;
- u32 ctb_log2_size_y = min_cb_log2_size_y + sps->log2_diff_max_min_luma_coding_block_size;
- u32 pic_width_in_ctbs_y = (sps->pic_width_in_luma_samples + (1 << ctb_log2_size_y) - 1)
- >> ctb_log2_size_y;
- u32 pic_height_in_ctbs_y = (sps->pic_height_in_luma_samples + (1 << ctb_log2_size_y) - 1)
- >> ctb_log2_size_y;
- size_t mv_size;
-
- mv_size = pic_width_in_ctbs_y * pic_height_in_ctbs_y *
- (1 << (2 * (ctb_log2_size_y - 4))) * 16;
-
- vpu_debug(4, "%dx%d (CTBs) %zu MV bytes\n",
- pic_width_in_ctbs_y, pic_height_in_ctbs_y, mv_size);
-
- return mv_size;
-}
-
-static size_t hantro_hevc_ref_size(struct hantro_ctx *ctx)
-{
- const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
- const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
-
- return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps);
-}
-
-static void hantro_hevc_ref_free(struct hantro_ctx *ctx)
-{
- struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
- struct hantro_dev *vpu = ctx->dev;
- int i;
-
- for (i = 0; i < NUM_REF_PICTURES; i++) {
- if (hevc_dec->ref_bufs[i].cpu)
- dma_free_coherent(vpu->dev, hevc_dec->ref_bufs[i].size,
- hevc_dec->ref_bufs[i].cpu,
- hevc_dec->ref_bufs[i].dma);
- }
-}
-
static void hantro_hevc_ref_init(struct hantro_ctx *ctx)
{
struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
@@ -108,37 +67,25 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
}
}
- /* Allocate a new reference buffer */
+ return 0;
+}
+
+int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
+{
+ struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
+ int i;
+
+ /* Add a new reference buffer */
for (i = 0; i < NUM_REF_PICTURES; i++) {
if (hevc_dec->ref_bufs_poc[i] == UNUSED_REF) {
- if (!hevc_dec->ref_bufs[i].cpu) {
- struct hantro_dev *vpu = ctx->dev;
-
- /*
- * Allocate the space needed for the raw data +
- * motion vector data. Optimizations could be to
- * allocate raw data in non coherent memory and only
- * clear the motion vector data.
- */
- hevc_dec->ref_bufs[i].cpu =
- dma_alloc_coherent(vpu->dev,
- hantro_hevc_ref_size(ctx),
- &hevc_dec->ref_bufs[i].dma,
- GFP_KERNEL);
- if (!hevc_dec->ref_bufs[i].cpu)
- return 0;
-
- hevc_dec->ref_bufs[i].size = hantro_hevc_ref_size(ctx);
- }
hevc_dec->ref_bufs_used |= 1 << i;
- memset(hevc_dec->ref_bufs[i].cpu, 0, hantro_hevc_ref_size(ctx));
hevc_dec->ref_bufs_poc[i] = poc;
-
- return hevc_dec->ref_bufs[i].dma;
+ hevc_dec->ref_bufs[i].dma = addr;
+ return 0;
}
}
- return 0;
+ return -EINVAL;
}
void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx)
@@ -314,8 +261,6 @@ void hantro_hevc_dec_exit(struct hantro_ctx *ctx)
hevc_dec->tile_bsd.cpu,
hevc_dec->tile_bsd.dma);
hevc_dec->tile_bsd.cpu = NULL;
-
- hantro_hevc_ref_free(ctx);
}
int hantro_hevc_dec_init(struct hantro_ctx *ctx)
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 267a6d33a47b..4a19ae8940b9 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/v4l2-controls.h>
#include <media/v4l2-ctrls.h>
+#include <media/v4l2-vp9.h>
#include <media/videobuf2-core.h>
#define DEC_8190_ALIGN_MASK 0x07U
@@ -166,6 +167,82 @@ struct hantro_vp8_dec_hw_ctx {
};
/**
+ * struct hantro_vp9_frame_info
+ *
+ * @valid: frame info valid flag
+ * @frame_context_idx: index of frame context
+ * @reference_mode: inter prediction type
+ * @tx_mode: transform mode
+ * @interpolation_filter: filter selection for inter prediction
+ * @flags: frame flags
+ * @timestamp: frame timestamp
+ */
+struct hantro_vp9_frame_info {
+ u32 valid : 1;
+ u32 frame_context_idx : 2;
+ u32 reference_mode : 2;
+ u32 tx_mode : 3;
+ u32 interpolation_filter : 3;
+ u32 flags;
+ u64 timestamp;
+};
+
+#define MAX_SB_COLS 64
+#define MAX_SB_ROWS 34
+
+/**
+ * struct hantro_vp9_dec_hw_ctx
+ *
+ * @tile_edge: auxiliary DMA buffer for tile edge processing
+ * @segment_map: auxiliary DMA buffer for segment map
+ * @misc: auxiliary DMA buffer for tile info, probabilities and hw counters
+ * @cnts: vp9 library struct for abstracting hw counters access
+ * @probability_tables: VP9 probability tables implied by the spec
+ * @frame_context: VP9 frame contexts
+ * @cur: current frame information
+ * @last: last frame information
+ * @bsd_ctrl_offset: bsd offset into tile_edge
+ * @segment_map_size: size of segment map
+ * @ctx_counters_offset: hw counters offset into misc
+ * @tile_info_offset: tile info offset into misc
+ * @tile_r_info: per-tile information array
+ * @tile_c_info: per-tile information array
+ * @last_tile_r: last number of tile rows
+ * @last_tile_c: last number of tile cols
+ * @last_sbs_r: last number of superblock rows
+ * @last_sbs_c: last number of superblock cols
+ * @active_segment: number of active segment (alternating between 0 and 1)
+ * @feature_enabled: segmentation feature enabled flags
+ * @feature_data: segmentation feature data
+ */
+struct hantro_vp9_dec_hw_ctx {
+ struct hantro_aux_buf tile_edge;
+ struct hantro_aux_buf segment_map;
+ struct hantro_aux_buf misc;
+ struct v4l2_vp9_frame_symbol_counts cnts;
+ struct v4l2_vp9_frame_context probability_tables;
+ struct v4l2_vp9_frame_context frame_context[4];
+ struct hantro_vp9_frame_info cur;
+ struct hantro_vp9_frame_info last;
+
+ unsigned int bsd_ctrl_offset;
+ unsigned int segment_map_size;
+ unsigned int ctx_counters_offset;
+ unsigned int tile_info_offset;
+
+ unsigned short tile_r_info[MAX_SB_ROWS];
+ unsigned short tile_c_info[MAX_SB_COLS];
+ unsigned int last_tile_r;
+ unsigned int last_tile_c;
+ unsigned int last_sbs_r;
+ unsigned int last_sbs_c;
+
+ unsigned int active_segment;
+ u8 feature_enabled[8];
+ s16 feature_data[8][4];
+};
+
+/**
* struct hantro_postproc_ctx
*
* @dec_q: References buffers, in decoder format.
@@ -175,6 +252,17 @@ struct hantro_postproc_ctx {
};
/**
+ * struct hantro_postproc_ops - post-processor operations
+ *
+ * @enable: Enable the post-processor block. Optional.
+ * @disable: Disable the post-processor block. Optional.
+ */
+struct hantro_postproc_ops {
+ void (*enable)(struct hantro_ctx *ctx);
+ void (*disable)(struct hantro_ctx *ctx);
+};
+
+/**
* struct hantro_codec_ops - codec mode specific operations
*
* @init: If needed, can be used for initialization.
@@ -220,8 +308,10 @@ extern const struct hantro_variant rk3288_vpu_variant;
extern const struct hantro_variant rk3328_vpu_variant;
extern const struct hantro_variant rk3399_vpu_variant;
extern const struct hantro_variant sama5d4_vdec_variant;
+extern const struct hantro_variant sunxi_vpu_variant;
-extern const struct hantro_postproc_regs hantro_g1_postproc_regs;
+extern const struct hantro_postproc_ops hantro_g1_postproc_ops;
+extern const struct hantro_postproc_ops hantro_g2_postproc_ops;
extern const u32 hantro_vp8_dec_mc_filter[8][6];
@@ -239,7 +329,8 @@ int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx);
int rockchip_vpu2_jpeg_enc_run(struct hantro_ctx *ctx);
int hantro_jpeg_enc_init(struct hantro_ctx *ctx);
void hantro_jpeg_enc_exit(struct hantro_ctx *ctx);
-void hantro_jpeg_enc_done(struct hantro_ctx *ctx);
+void hantro_h1_jpeg_enc_done(struct hantro_ctx *ctx);
+void rockchip_vpu2_jpeg_enc_done(struct hantro_ctx *ctx);
dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
unsigned int dpb_idx);
@@ -256,10 +347,29 @@ void hantro_hevc_dec_exit(struct hantro_ctx *ctx);
int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx);
int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
+int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps);
size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps);
+static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
+{
+ return (dimension + 63) / 64;
+}
+
+static inline size_t
+hantro_vp9_mv_size(unsigned int width, unsigned int height)
+{
+ int num_ctbs;
+
+ /*
+ * There can be up to (CTBs x 64) number of blocks,
+ * and the motion vector for each block needs 16 bytes.
+ */
+ num_ctbs = hantro_vp9_num_sbs(width) * hantro_vp9_num_sbs(height);
+ return (num_ctbs * 64) * 16;
+}
+
static inline size_t
hantro_h264_mv_size(unsigned int width, unsigned int height)
{
@@ -287,6 +397,16 @@ hantro_h264_mv_size(unsigned int width, unsigned int height)
return 64 * MB_WIDTH(width) * MB_WIDTH(height) + 32;
}
+static inline size_t
+hantro_hevc_mv_size(unsigned int width, unsigned int height)
+{
+ /*
+ * A CTB can be 64x64, 32x32 or 16x16.
+ * Allocated memory for the "worse" case: 16x16
+ */
+ return width * height / 16;
+}
+
int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx);
int rockchip_vpu2_mpeg2_dec_run(struct hantro_ctx *ctx);
void hantro_mpeg2_dec_copy_qtable(u8 *qtable,
@@ -301,4 +421,11 @@ void hantro_vp8_dec_exit(struct hantro_ctx *ctx);
void hantro_vp8_prob_update(struct hantro_ctx *ctx,
const struct v4l2_ctrl_vp8_frame *hdr);
+int hantro_g2_vp9_dec_run(struct hantro_ctx *ctx);
+void hantro_g2_vp9_dec_done(struct hantro_ctx *ctx);
+int hantro_vp9_dec_init(struct hantro_ctx *ctx);
+void hantro_vp9_dec_exit(struct hantro_ctx *ctx);
+void hantro_g2_check_idle(struct hantro_dev *vpu);
+irqreturn_t hantro_g2_irq(int irq, void *dev_id);
+
#endif /* HANTRO_HW_H_ */
diff --git a/drivers/staging/media/hantro/hantro_jpeg.c b/drivers/staging/media/hantro/hantro_jpeg.c
index 36c140fc6a36..df62fbdff7c9 100644
--- a/drivers/staging/media/hantro/hantro_jpeg.c
+++ b/drivers/staging/media/hantro/hantro_jpeg.c
@@ -36,8 +36,6 @@ static const unsigned char luma_q_table[] = {
0x48, 0x5c, 0x5f, 0x62, 0x70, 0x64, 0x67, 0x63
};
-static unsigned char luma_q_table_reordered[ARRAY_SIZE(luma_q_table)];
-
static const unsigned char chroma_q_table[] = {
0x11, 0x12, 0x18, 0x2f, 0x63, 0x63, 0x63, 0x63,
0x12, 0x15, 0x1a, 0x42, 0x63, 0x63, 0x63, 0x63,
@@ -49,8 +47,6 @@ static const unsigned char chroma_q_table[] = {
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
};
-static unsigned char chroma_q_table_reordered[ARRAY_SIZE(chroma_q_table)];
-
static const unsigned char zigzag[64] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
@@ -277,7 +273,7 @@ jpeg_scale_quant_table(unsigned char *file_q_tab,
}
}
-static void jpeg_set_quality(unsigned char *buffer, int quality)
+static void jpeg_set_quality(struct hantro_jpeg_ctx *ctx)
{
int scale;
@@ -285,24 +281,15 @@ static void jpeg_set_quality(unsigned char *buffer, int quality)
* Non-linear scaling factor:
* [5,50] -> [1000..100], [51,100] -> [98..0]
*/
- if (quality < 50)
- scale = 5000 / quality;
+ if (ctx->quality < 50)
+ scale = 5000 / ctx->quality;
else
- scale = 200 - 2 * quality;
-
- jpeg_scale_quant_table(buffer + LUMA_QUANT_OFF,
- luma_q_table_reordered,
- luma_q_table, scale);
- jpeg_scale_quant_table(buffer + CHROMA_QUANT_OFF,
- chroma_q_table_reordered,
- chroma_q_table, scale);
-}
+ scale = 200 - 2 * ctx->quality;
-unsigned char *hantro_jpeg_get_qtable(int index)
-{
- if (index == 0)
- return luma_q_table_reordered;
- return chroma_q_table_reordered;
+ jpeg_scale_quant_table(ctx->buffer + LUMA_QUANT_OFF,
+ ctx->hw_luma_qtable, luma_q_table, scale);
+ jpeg_scale_quant_table(ctx->buffer + CHROMA_QUANT_OFF,
+ ctx->hw_chroma_qtable, chroma_q_table, scale);
}
void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx)
@@ -324,7 +311,7 @@ void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx)
memcpy(buf + HUFF_CHROMA_AC_OFF, chroma_ac_table,
sizeof(chroma_ac_table));
- jpeg_set_quality(buf, ctx->quality);
+ jpeg_set_quality(ctx);
}
int hantro_jpeg_enc_init(struct hantro_ctx *ctx)
diff --git a/drivers/staging/media/hantro/hantro_jpeg.h b/drivers/staging/media/hantro/hantro_jpeg.h
index 9474a00277f8..035ab25b803f 100644
--- a/drivers/staging/media/hantro/hantro_jpeg.h
+++ b/drivers/staging/media/hantro/hantro_jpeg.h
@@ -1,13 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#define JPEG_HEADER_SIZE 601
+#define JPEG_QUANT_SIZE 64
struct hantro_jpeg_ctx {
int width;
int height;
int quality;
unsigned char *buffer;
+ unsigned char hw_luma_qtable[JPEG_QUANT_SIZE];
+ unsigned char hw_chroma_qtable[JPEG_QUANT_SIZE];
};
-unsigned char *hantro_jpeg_get_qtable(int index);
void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx);
diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c
index ed8916c950a4..248abe5423f0 100644
--- a/drivers/staging/media/hantro/hantro_postproc.c
+++ b/drivers/staging/media/hantro/hantro_postproc.c
@@ -11,18 +11,19 @@
#include "hantro.h"
#include "hantro_hw.h"
#include "hantro_g1_regs.h"
+#include "hantro_g2_regs.h"
#define HANTRO_PP_REG_WRITE(vpu, reg_name, val) \
{ \
hantro_reg_write(vpu, \
- &(vpu)->variant->postproc_regs->reg_name, \
+ &hantro_g1_postproc_regs.reg_name, \
val); \
}
#define HANTRO_PP_REG_WRITE_S(vpu, reg_name, val) \
{ \
hantro_reg_write_s(vpu, \
- &(vpu)->variant->postproc_regs->reg_name, \
+ &hantro_g1_postproc_regs.reg_name, \
val); \
}
@@ -33,7 +34,7 @@
#define VPU_PP_OUT_RGB 0x0
#define VPU_PP_OUT_YUYV 0x3
-const struct hantro_postproc_regs hantro_g1_postproc_regs = {
+static const struct hantro_postproc_regs hantro_g1_postproc_regs = {
.pipeline_en = {G1_REG_PP_INTERRUPT, 1, 0x1},
.max_burst = {G1_REG_PP_DEV_CONFIG, 0, 0x1f},
.clk_gate = {G1_REG_PP_DEV_CONFIG, 1, 0x1},
@@ -53,27 +54,18 @@ const struct hantro_postproc_regs hantro_g1_postproc_regs = {
bool hantro_needs_postproc(const struct hantro_ctx *ctx,
const struct hantro_fmt *fmt)
{
- struct hantro_dev *vpu = ctx->dev;
-
if (ctx->is_encoder)
return false;
-
- if (!vpu->variant->postproc_fmts)
- return false;
-
- return fmt->fourcc != V4L2_PIX_FMT_NV12;
+ return fmt->postprocessed;
}
-void hantro_postproc_enable(struct hantro_ctx *ctx)
+static void hantro_postproc_g1_enable(struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
struct vb2_v4l2_buffer *dst_buf;
u32 src_pp_fmt, dst_pp_fmt;
dma_addr_t dst_dma;
- if (!vpu->variant->postproc_regs)
- return;
-
/* Turn on pipeline mode. Must be done first. */
HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x1);
@@ -108,6 +100,21 @@ void hantro_postproc_enable(struct hantro_ctx *ctx)
HANTRO_PP_REG_WRITE(vpu, display_width, ctx->dst_fmt.width);
}
+static void hantro_postproc_g2_enable(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+ struct vb2_v4l2_buffer *dst_buf;
+ size_t chroma_offset = ctx->dst_fmt.width * ctx->dst_fmt.height;
+ dma_addr_t dst_dma;
+
+ dst_buf = hantro_get_dst_buf(ctx);
+ dst_dma = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+
+ hantro_write_addr(vpu, G2_RS_OUT_LUMA_ADDR, dst_dma);
+ hantro_write_addr(vpu, G2_RS_OUT_CHROMA_ADDR, dst_dma + chroma_offset);
+ hantro_reg_write(vpu, &g2_out_rs_e, 1);
+}
+
void hantro_postproc_free(struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
@@ -132,9 +139,16 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
unsigned int num_buffers = cap_queue->num_buffers;
unsigned int i, buf_size;
- buf_size = ctx->dst_fmt.plane_fmt[0].sizeimage +
- hantro_h264_mv_size(ctx->dst_fmt.width,
- ctx->dst_fmt.height);
+ buf_size = ctx->dst_fmt.plane_fmt[0].sizeimage;
+ if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
+ buf_size += hantro_h264_mv_size(ctx->dst_fmt.width,
+ ctx->dst_fmt.height);
+ else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME)
+ buf_size += hantro_vp9_mv_size(ctx->dst_fmt.width,
+ ctx->dst_fmt.height);
+ else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE)
+ buf_size += hantro_hevc_mv_size(ctx->dst_fmt.width,
+ ctx->dst_fmt.height);
for (i = 0; i < num_buffers; ++i) {
struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i];
@@ -153,12 +167,42 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
return 0;
}
+static void hantro_postproc_g1_disable(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+
+ HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0);
+}
+
+static void hantro_postproc_g2_disable(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+
+ hantro_reg_write(vpu, &g2_out_rs_e, 0);
+}
+
void hantro_postproc_disable(struct hantro_ctx *ctx)
{
struct hantro_dev *vpu = ctx->dev;
- if (!vpu->variant->postproc_regs)
- return;
+ if (vpu->variant->postproc_ops && vpu->variant->postproc_ops->disable)
+ vpu->variant->postproc_ops->disable(ctx);
+}
+
+void hantro_postproc_enable(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
- HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0);
+ if (vpu->variant->postproc_ops && vpu->variant->postproc_ops->enable)
+ vpu->variant->postproc_ops->enable(ctx);
}
+
+const struct hantro_postproc_ops hantro_g1_postproc_ops = {
+ .enable = hantro_postproc_g1_enable,
+ .disable = hantro_postproc_g1_disable,
+};
+
+const struct hantro_postproc_ops hantro_g2_postproc_ops = {
+ .enable = hantro_postproc_g2_enable,
+ .disable = hantro_postproc_g2_disable,
+};
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
index bcb0bdff4a9a..e595905b3bd7 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.c
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
@@ -23,8 +23,6 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-sg.h>
#include "hantro.h"
#include "hantro_hw.h"
@@ -285,6 +283,16 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
pix_mp->plane_fmt[0].sizeimage +=
hantro_h264_mv_size(pix_mp->width,
pix_mp->height);
+ else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME &&
+ !hantro_needs_postproc(ctx, fmt))
+ pix_mp->plane_fmt[0].sizeimage +=
+ hantro_vp9_mv_size(pix_mp->width,
+ pix_mp->height);
+ else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE &&
+ !hantro_needs_postproc(ctx, fmt))
+ pix_mp->plane_fmt[0].sizeimage +=
+ hantro_hevc_mv_size(pix_mp->width,
+ pix_mp->height);
} else if (!pix_mp->plane_fmt[0].sizeimage) {
/*
* For coded formats the application can specify
@@ -393,6 +401,7 @@ hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc)
case V4L2_PIX_FMT_VP8_FRAME:
case V4L2_PIX_FMT_H264_SLICE:
case V4L2_PIX_FMT_HEVC_SLICE:
+ case V4L2_PIX_FMT_VP9_FRAME:
ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true;
break;
default:
diff --git a/drivers/staging/media/hantro/hantro_vp9.c b/drivers/staging/media/hantro/hantro_vp9.c
new file mode 100644
index 000000000000..566cd376c097
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_vp9.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VP9 codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd.
+ */
+
+#include <linux/types.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "hantro.h"
+#include "hantro_hw.h"
+#include "hantro_vp9.h"
+
+#define POW2(x) (1 << (x))
+
+#define MAX_LOG2_TILE_COLUMNS 6
+#define MAX_NUM_TILE_COLS POW2(MAX_LOG2_TILE_COLUMNS)
+#define MAX_TILE_COLS 20
+#define MAX_TILE_ROWS 22
+
+static size_t hantro_vp9_tile_filter_size(unsigned int height)
+{
+ u32 h, height32, size;
+
+ h = roundup(height, 8);
+
+ height32 = roundup(h, 64);
+ size = 24 * height32 * (MAX_NUM_TILE_COLS - 1); /* luma: 8, chroma: 8 + 8 */
+
+ return size;
+}
+
+static size_t hantro_vp9_bsd_control_size(unsigned int height)
+{
+ u32 h, height32;
+
+ h = roundup(height, 8);
+ height32 = roundup(h, 64);
+
+ return 16 * (height32 / 4) * (MAX_NUM_TILE_COLS - 1);
+}
+
+static size_t hantro_vp9_segment_map_size(unsigned int width, unsigned int height)
+{
+ u32 w, h;
+ int num_ctbs;
+
+ w = roundup(width, 8);
+ h = roundup(height, 8);
+ num_ctbs = ((w + 63) / 64) * ((h + 63) / 64);
+
+ return num_ctbs * 32;
+}
+
+static inline size_t hantro_vp9_prob_tab_size(void)
+{
+ return roundup(sizeof(struct hantro_g2_all_probs), 16);
+}
+
+static inline size_t hantro_vp9_count_tab_size(void)
+{
+ return roundup(sizeof(struct symbol_counts), 16);
+}
+
+static inline size_t hantro_vp9_tile_info_size(void)
+{
+ return roundup((MAX_TILE_COLS * MAX_TILE_ROWS * 4 * sizeof(u16) + 15 + 16) & ~0xf, 16);
+}
+
+static void *get_coeffs_arr(struct symbol_counts *cnts, int i, int j, int k, int l, int m)
+{
+ if (i == 0)
+ return &cnts->count_coeffs[j][k][l][m];
+
+ if (i == 1)
+ return &cnts->count_coeffs8x8[j][k][l][m];
+
+ if (i == 2)
+ return &cnts->count_coeffs16x16[j][k][l][m];
+
+ if (i == 3)
+ return &cnts->count_coeffs32x32[j][k][l][m];
+
+ return NULL;
+}
+
+static void *get_eobs1(struct symbol_counts *cnts, int i, int j, int k, int l, int m)
+{
+ if (i == 0)
+ return &cnts->count_coeffs[j][k][l][m][3];
+
+ if (i == 1)
+ return &cnts->count_coeffs8x8[j][k][l][m][3];
+
+ if (i == 2)
+ return &cnts->count_coeffs16x16[j][k][l][m][3];
+
+ if (i == 3)
+ return &cnts->count_coeffs32x32[j][k][l][m][3];
+
+ return NULL;
+}
+
+#define INNER_LOOP \
+ do { \
+ for (m = 0; m < ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0][0][0]); ++m) { \
+ vp9_ctx->cnts.coeff[i][j][k][l][m] = \
+ get_coeffs_arr(cnts, i, j, k, l, m); \
+ vp9_ctx->cnts.eob[i][j][k][l][m][0] = \
+ &cnts->count_eobs[i][j][k][l][m]; \
+ vp9_ctx->cnts.eob[i][j][k][l][m][1] = \
+ get_eobs1(cnts, i, j, k, l, m); \
+ } \
+ } while (0)
+
+static void init_v4l2_vp9_count_tbl(struct hantro_ctx *ctx)
+{
+ struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+ struct symbol_counts *cnts = vp9_ctx->misc.cpu + vp9_ctx->ctx_counters_offset;
+ int i, j, k, l, m;
+
+ vp9_ctx->cnts.partition = &cnts->partition_counts;
+ vp9_ctx->cnts.skip = &cnts->mbskip_count;
+ vp9_ctx->cnts.intra_inter = &cnts->intra_inter_count;
+ vp9_ctx->cnts.tx32p = &cnts->tx32x32_count;
+ /*
+ * g2 hardware uses tx16x16_count[2][3], while the api
+ * expects tx16p[2][4], so this must be explicitly copied
+ * into vp9_ctx->cnts.tx16p when passing the data to the
+ * vp9 library function
+ */
+ vp9_ctx->cnts.tx8p = &cnts->tx8x8_count;
+
+ vp9_ctx->cnts.y_mode = &cnts->sb_ymode_counts;
+ vp9_ctx->cnts.uv_mode = &cnts->uv_mode_counts;
+ vp9_ctx->cnts.comp = &cnts->comp_inter_count;
+ vp9_ctx->cnts.comp_ref = &cnts->comp_ref_count;
+ vp9_ctx->cnts.single_ref = &cnts->single_ref_count;
+ vp9_ctx->cnts.filter = &cnts->switchable_interp_counts;
+ vp9_ctx->cnts.mv_joint = &cnts->mv_counts.joints;
+ vp9_ctx->cnts.sign = &cnts->mv_counts.sign;
+ vp9_ctx->cnts.classes = &cnts->mv_counts.classes;
+ vp9_ctx->cnts.class0 = &cnts->mv_counts.class0;
+ vp9_ctx->cnts.bits = &cnts->mv_counts.bits;
+ vp9_ctx->cnts.class0_fp = &cnts->mv_counts.class0_fp;
+ vp9_ctx->cnts.fp = &cnts->mv_counts.fp;
+ vp9_ctx->cnts.class0_hp = &cnts->mv_counts.class0_hp;
+ vp9_ctx->cnts.hp = &cnts->mv_counts.hp;
+
+ for (i = 0; i < ARRAY_SIZE(vp9_ctx->cnts.coeff); ++i)
+ for (j = 0; j < ARRAY_SIZE(vp9_ctx->cnts.coeff[i]); ++j)
+ for (k = 0; k < ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0]); ++k)
+ for (l = 0; l < ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0][0]); ++l)
+ INNER_LOOP;
+}
+
+int hantro_vp9_dec_init(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+ const struct hantro_variant *variant = vpu->variant;
+ struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
+ struct hantro_aux_buf *tile_edge = &vp9_dec->tile_edge;
+ struct hantro_aux_buf *segment_map = &vp9_dec->segment_map;
+ struct hantro_aux_buf *misc = &vp9_dec->misc;
+ u32 i, max_width, max_height, size;
+
+ if (variant->num_dec_fmts < 1)
+ return -EINVAL;
+
+ for (i = 0; i < variant->num_dec_fmts; ++i)
+ if (variant->dec_fmts[i].fourcc == V4L2_PIX_FMT_VP9_FRAME)
+ break;
+
+ if (i == variant->num_dec_fmts)
+ return -EINVAL;
+
+ max_width = vpu->variant->dec_fmts[i].frmsize.max_width;
+ max_height = vpu->variant->dec_fmts[i].frmsize.max_height;
+
+ size = hantro_vp9_tile_filter_size(max_height);
+ vp9_dec->bsd_ctrl_offset = size;
+ size += hantro_vp9_bsd_control_size(max_height);
+
+ tile_edge->cpu = dma_alloc_coherent(vpu->dev, size, &tile_edge->dma, GFP_KERNEL);
+ if (!tile_edge->cpu)
+ return -ENOMEM;
+
+ tile_edge->size = size;
+ memset(tile_edge->cpu, 0, size);
+
+ size = hantro_vp9_segment_map_size(max_width, max_height);
+ vp9_dec->segment_map_size = size;
+ size *= 2; /* we need two areas of this size, used alternately */
+
+ segment_map->cpu = dma_alloc_coherent(vpu->dev, size, &segment_map->dma, GFP_KERNEL);
+ if (!segment_map->cpu)
+ goto err_segment_map;
+
+ segment_map->size = size;
+ memset(segment_map->cpu, 0, size);
+
+ size = hantro_vp9_prob_tab_size();
+ vp9_dec->ctx_counters_offset = size;
+ size += hantro_vp9_count_tab_size();
+ vp9_dec->tile_info_offset = size;
+ size += hantro_vp9_tile_info_size();
+
+ misc->cpu = dma_alloc_coherent(vpu->dev, size, &misc->dma, GFP_KERNEL);
+ if (!misc->cpu)
+ goto err_misc;
+
+ misc->size = size;
+ memset(misc->cpu, 0, size);
+
+ init_v4l2_vp9_count_tbl(ctx);
+
+ return 0;
+
+err_misc:
+ dma_free_coherent(vpu->dev, segment_map->size, segment_map->cpu, segment_map->dma);
+
+err_segment_map:
+ dma_free_coherent(vpu->dev, tile_edge->size, tile_edge->cpu, tile_edge->dma);
+
+ return -ENOMEM;
+}
+
+void hantro_vp9_dec_exit(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+ struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
+ struct hantro_aux_buf *tile_edge = &vp9_dec->tile_edge;
+ struct hantro_aux_buf *segment_map = &vp9_dec->segment_map;
+ struct hantro_aux_buf *misc = &vp9_dec->misc;
+
+ dma_free_coherent(vpu->dev, misc->size, misc->cpu, misc->dma);
+ dma_free_coherent(vpu->dev, segment_map->size, segment_map->cpu, segment_map->dma);
+ dma_free_coherent(vpu->dev, tile_edge->size, tile_edge->cpu, tile_edge->dma);
+}
diff --git a/drivers/staging/media/hantro/hantro_vp9.h b/drivers/staging/media/hantro/hantro_vp9.h
new file mode 100644
index 000000000000..26b69275f098
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_vp9.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Hantro VP9 codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd.
+ */
+
+struct hantro_g2_mv_probs {
+ u8 joint[3];
+ u8 sign[2];
+ u8 class0_bit[2][1];
+ u8 fr[2][3];
+ u8 class0_hp[2];
+ u8 hp[2];
+ u8 classes[2][10];
+ u8 class0_fr[2][2][3];
+ u8 bits[2][10];
+};
+
+struct hantro_g2_probs {
+ u8 inter_mode[7][4];
+ u8 is_inter[4];
+ u8 uv_mode[10][8];
+ u8 tx8[2][1];
+ u8 tx16[2][2];
+ u8 tx32[2][3];
+ u8 y_mode_tail[4][1];
+ u8 y_mode[4][8];
+ u8 partition[2][16][4]; /* [keyframe][][], [inter][][] */
+ u8 uv_mode_tail[10][1];
+ u8 interp_filter[4][2];
+ u8 comp_mode[5];
+ u8 skip[3];
+
+ u8 pad1[1];
+
+ struct hantro_g2_mv_probs mv;
+
+ u8 single_ref[5][2];
+ u8 comp_ref[5];
+
+ u8 pad2[17];
+
+ u8 coef[4][2][2][6][6][4];
+};
+
+struct hantro_g2_all_probs {
+ u8 kf_y_mode_prob[10][10][8];
+
+ u8 kf_y_mode_prob_tail[10][10][1];
+ u8 ref_pred_probs[3];
+ u8 mb_segment_tree_probs[7];
+ u8 segment_pred_probs[3];
+ u8 ref_scores[4];
+ u8 prob_comppred[2];
+
+ u8 pad1[9];
+
+ u8 kf_uv_mode_prob[10][8];
+ u8 kf_uv_mode_prob_tail[10][1];
+
+ u8 pad2[6];
+
+ struct hantro_g2_probs probs;
+};
+
+struct mv_counts {
+ u32 joints[4];
+ u32 sign[2][2];
+ u32 classes[2][11];
+ u32 class0[2][2];
+ u32 bits[2][10][2];
+ u32 class0_fp[2][2][4];
+ u32 fp[2][4];
+ u32 class0_hp[2][2];
+ u32 hp[2][2];
+};
+
+struct symbol_counts {
+ u32 inter_mode_counts[7][3][2];
+ u32 sb_ymode_counts[4][10];
+ u32 uv_mode_counts[10][10];
+ u32 partition_counts[16][4];
+ u32 switchable_interp_counts[4][3];
+ u32 intra_inter_count[4][2];
+ u32 comp_inter_count[5][2];
+ u32 single_ref_count[5][2][2];
+ u32 comp_ref_count[5][2];
+ u32 tx32x32_count[2][4];
+ u32 tx16x16_count[2][3];
+ u32 tx8x8_count[2][2];
+ u32 mbskip_count[3][2];
+
+ struct mv_counts mv_counts;
+
+ u32 count_coeffs[2][2][6][6][4];
+ u32 count_coeffs8x8[2][2][6][6][4];
+ u32 count_coeffs16x16[2][2][6][6][4];
+ u32 count_coeffs32x32[2][2][6][6][4];
+
+ u32 count_eobs[4][2][2][6][6];
+};
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index ea919bfb9891..f5991b8e553a 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -82,6 +82,7 @@ static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = {
{
.fourcc = V4L2_PIX_FMT_YUYV,
.codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
},
};
@@ -131,10 +132,18 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
},
};
-static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
+static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
{
.fourcc = V4L2_PIX_FMT_NV12,
.codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
+ },
+};
+
+static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12_4L4,
+ .codec_mode = HANTRO_MODE_NONE,
},
{
.fourcc = V4L2_PIX_FMT_HEVC_SLICE,
@@ -149,6 +158,19 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
.step_height = MB_DIM,
},
},
+ {
+ .fourcc = V4L2_PIX_FMT_VP9_FRAME,
+ .codec_mode = HANTRO_MODE_VP9_DEC,
+ .max_depth = 2,
+ .frmsize = {
+ .min_width = 48,
+ .max_width = 3840,
+ .step_width = MB_DIM,
+ .min_height = 48,
+ .max_height = 2160,
+ .step_height = MB_DIM,
+ },
+ },
};
static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
@@ -169,24 +191,6 @@ static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static irqreturn_t imx8m_vpu_g2_irq(int irq, void *dev_id)
-{
- struct hantro_dev *vpu = dev_id;
- enum vb2_buffer_state state;
- u32 status;
-
- status = vdpu_read(vpu, G2_REG_INTERRUPT);
- state = (status & G2_REG_INTERRUPT_DEC_RDY_INT) ?
- VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
-
- vdpu_write(vpu, 0, G2_REG_INTERRUPT);
- vdpu_write(vpu, G2_REG_CONFIG_DEC_CLK_GATE_E, G2_REG_CONFIG);
-
- hantro_irq_done(vpu, state);
-
- return IRQ_HANDLED;
-}
-
static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)
{
vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];
@@ -240,6 +244,13 @@ static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
.init = hantro_hevc_dec_init,
.exit = hantro_hevc_dec_exit,
},
+ [HANTRO_MODE_VP9_DEC] = {
+ .run = hantro_g2_vp9_dec_run,
+ .done = hantro_g2_vp9_dec_done,
+ .reset = imx8m_vpu_g2_reset,
+ .init = hantro_vp9_dec_init,
+ .exit = hantro_vp9_dec_exit,
+ },
};
/*
@@ -251,7 +262,7 @@ static const struct hantro_irq imx8mq_irqs[] = {
};
static const struct hantro_irq imx8mq_g2_irqs[] = {
- { "g2", imx8m_vpu_g2_irq },
+ { "g2", hantro_g2_irq },
};
static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };
@@ -262,7 +273,7 @@ const struct hantro_variant imx8mq_vpu_variant = {
.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
.postproc_fmts = imx8m_vpu_postproc_fmts,
.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
- .postproc_regs = &hantro_g1_postproc_regs,
+ .postproc_ops = &hantro_g1_postproc_ops,
.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
HANTRO_H264_DECODER,
.codec_ops = imx8mq_vpu_codec_ops,
@@ -280,7 +291,10 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
.dec_offset = 0x0,
.dec_fmts = imx8m_vpu_g2_dec_fmts,
.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),
- .codec = HANTRO_HEVC_DECODER,
+ .postproc_fmts = imx8m_vpu_g2_postproc_fmts,
+ .num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_g2_postproc_fmts),
+ .postproc_ops = &hantro_g2_postproc_ops,
+ .codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
.codec_ops = imx8mq_vpu_g2_codec_ops,
.init = imx8mq_vpu_hw_init,
.runtime_resume = imx8mq_runtime_resume,
diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c b/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c
index 991213ce1610..4df16f59fb97 100644
--- a/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c
+++ b/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c
@@ -143,9 +143,8 @@ int rockchip_vpu2_jpeg_enc_run(struct hantro_ctx *ctx)
rockchip_vpu2_set_src_img_ctrl(vpu, ctx);
rockchip_vpu2_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf);
- rockchip_vpu2_jpeg_enc_set_qtable(vpu,
- hantro_jpeg_get_qtable(0),
- hantro_jpeg_get_qtable(1));
+ rockchip_vpu2_jpeg_enc_set_qtable(vpu, jpeg_ctx.hw_luma_qtable,
+ jpeg_ctx.hw_chroma_qtable);
reg = VEPU_REG_OUTPUT_SWAP32
| VEPU_REG_OUTPUT_SWAP16
@@ -171,3 +170,20 @@ int rockchip_vpu2_jpeg_enc_run(struct hantro_ctx *ctx)
return 0;
}
+
+void rockchip_vpu2_jpeg_enc_done(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+ u32 bytesused = vepu_read(vpu, VEPU_REG_STR_BUF_LIMIT) / 8;
+ struct vb2_v4l2_buffer *dst_buf = hantro_get_dst_buf(ctx);
+
+ /*
+ * TODO: Rework the JPEG encoder to eliminate the need
+ * for a bounce buffer.
+ */
+ memcpy(vb2_plane_vaddr(&dst_buf->vb2_buf, 0) +
+ ctx->vpu_dst_fmt->header_size,
+ ctx->jpeg_enc.bounce_buffer.cpu, bytesused);
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
+ ctx->vpu_dst_fmt->header_size + bytesused);
+}
diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
index d4f52957cc53..c203b606e6e7 100644
--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
+++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
@@ -62,6 +62,7 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = {
{
.fourcc = V4L2_PIX_FMT_YUYV,
.codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
},
};
@@ -343,7 +344,7 @@ static const struct hantro_codec_ops rk3066_vpu_codec_ops[] = {
.run = hantro_h1_jpeg_enc_run,
.reset = rockchip_vpu1_enc_reset,
.init = hantro_jpeg_enc_init,
- .done = hantro_jpeg_enc_done,
+ .done = hantro_h1_jpeg_enc_done,
.exit = hantro_jpeg_enc_exit,
},
[HANTRO_MODE_H264_DEC] = {
@@ -371,7 +372,7 @@ static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = {
.run = hantro_h1_jpeg_enc_run,
.reset = rockchip_vpu1_enc_reset,
.init = hantro_jpeg_enc_init,
- .done = hantro_jpeg_enc_done,
+ .done = hantro_h1_jpeg_enc_done,
.exit = hantro_jpeg_enc_exit,
},
[HANTRO_MODE_H264_DEC] = {
@@ -399,6 +400,7 @@ static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = {
.run = rockchip_vpu2_jpeg_enc_run,
.reset = rockchip_vpu2_enc_reset,
.init = hantro_jpeg_enc_init,
+ .done = rockchip_vpu2_jpeg_enc_done,
.exit = hantro_jpeg_enc_exit,
},
[HANTRO_MODE_H264_DEC] = {
@@ -460,7 +462,7 @@ const struct hantro_variant rk3036_vpu_variant = {
.num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts),
.postproc_fmts = rockchip_vpu1_postproc_fmts,
.num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
- .postproc_regs = &hantro_g1_postproc_regs,
+ .postproc_ops = &hantro_g1_postproc_ops,
.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
HANTRO_H264_DECODER,
.codec_ops = rk3036_vpu_codec_ops,
@@ -485,7 +487,7 @@ const struct hantro_variant rk3066_vpu_variant = {
.num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts),
.postproc_fmts = rockchip_vpu1_postproc_fmts,
.num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
- .postproc_regs = &hantro_g1_postproc_regs,
+ .postproc_ops = &hantro_g1_postproc_ops,
.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
.codec_ops = rk3066_vpu_codec_ops,
@@ -505,7 +507,7 @@ const struct hantro_variant rk3288_vpu_variant = {
.num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts),
.postproc_fmts = rockchip_vpu1_postproc_fmts,
.num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
- .postproc_regs = &hantro_g1_postproc_regs,
+ .postproc_ops = &hantro_g1_postproc_ops,
.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
.codec_ops = rk3288_vpu_codec_ops,
diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
index 9c3b8cd0b239..b2fc1c5613e1 100644
--- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
@@ -15,6 +15,7 @@ static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = {
{
.fourcc = V4L2_PIX_FMT_YUYV,
.codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
},
};
@@ -100,7 +101,7 @@ const struct hantro_variant sama5d4_vdec_variant = {
.num_dec_fmts = ARRAY_SIZE(sama5d4_vdec_fmts),
.postproc_fmts = sama5d4_vdec_postproc_fmts,
.num_postproc_fmts = ARRAY_SIZE(sama5d4_vdec_postproc_fmts),
- .postproc_regs = &hantro_g1_postproc_regs,
+ .postproc_ops = &hantro_g1_postproc_ops,
.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
HANTRO_H264_DECODER,
.codec_ops = sama5d4_vdec_codec_ops,
diff --git a/drivers/staging/media/hantro/sunxi_vpu_hw.c b/drivers/staging/media/hantro/sunxi_vpu_hw.c
new file mode 100644
index 000000000000..90633406c4eb
--- /dev/null
+++ b/drivers/staging/media/hantro/sunxi_vpu_hw.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner Hantro G2 VPU codec driver
+ *
+ * Copyright (C) 2021 Jernej Skrabec <jernej.skrabec@gmail.com>
+ */
+
+#include <linux/clk.h>
+
+#include "hantro.h"
+
+static const struct hantro_fmt sunxi_vpu_postproc_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
+ },
+};
+
+static const struct hantro_fmt sunxi_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12_4L4,
+ .codec_mode = HANTRO_MODE_NONE,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_VP9_FRAME,
+ .codec_mode = HANTRO_MODE_VP9_DEC,
+ .max_depth = 2,
+ .frmsize = {
+ .min_width = 48,
+ .max_width = 3840,
+ .step_width = MB_DIM,
+ .min_height = 48,
+ .max_height = 2160,
+ .step_height = MB_DIM,
+ },
+ },
+};
+
+static int sunxi_vpu_hw_init(struct hantro_dev *vpu)
+{
+ clk_set_rate(vpu->clocks[0].clk, 300000000);
+
+ return 0;
+}
+
+static void sunxi_vpu_reset(struct hantro_ctx *ctx)
+{
+ struct hantro_dev *vpu = ctx->dev;
+
+ reset_control_reset(vpu->resets);
+}
+
+static const struct hantro_codec_ops sunxi_vpu_codec_ops[] = {
+ [HANTRO_MODE_VP9_DEC] = {
+ .run = hantro_g2_vp9_dec_run,
+ .done = hantro_g2_vp9_dec_done,
+ .reset = sunxi_vpu_reset,
+ .init = hantro_vp9_dec_init,
+ .exit = hantro_vp9_dec_exit,
+ },
+};
+
+static const struct hantro_irq sunxi_irqs[] = {
+ { NULL, hantro_g2_irq },
+};
+
+static const char * const sunxi_clk_names[] = { "mod", "bus" };
+
+const struct hantro_variant sunxi_vpu_variant = {
+ .dec_fmts = sunxi_vpu_dec_fmts,
+ .num_dec_fmts = ARRAY_SIZE(sunxi_vpu_dec_fmts),
+ .postproc_fmts = sunxi_vpu_postproc_fmts,
+ .num_postproc_fmts = ARRAY_SIZE(sunxi_vpu_postproc_fmts),
+ .postproc_ops = &hantro_g2_postproc_ops,
+ .codec = HANTRO_VP9_DECODER,
+ .codec_ops = sunxi_vpu_codec_ops,
+ .init = sunxi_vpu_hw_init,
+ .irqs = sunxi_irqs,
+ .num_irqs = ARRAY_SIZE(sunxi_irqs),
+ .clk_names = sunxi_clk_names,
+ .num_clocks = ARRAY_SIZE(sunxi_clk_names),
+ .double_buffer = 1,
+ .legacy_regs = 1,
+ .late_postproc = 1,
+};
diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c
index eb6da9b9d8ba..1fd39a2fca98 100644
--- a/drivers/staging/media/imx/imx-media-csc-scaler.c
+++ b/drivers/staging/media/imx/imx-media-csc-scaler.c
@@ -820,7 +820,7 @@ static const struct v4l2_file_operations ipu_csc_scaler_fops = {
.mmap = v4l2_m2m_fop_mmap,
};
-static struct v4l2_m2m_ops m2m_ops = {
+static const struct v4l2_m2m_ops m2m_ops = {
.device_run = device_run,
.job_abort = job_abort,
};
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 1caa100be33d..bd7f156f2d52 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -150,7 +150,7 @@ static inline bool requires_passthrough(struct v4l2_fwnode_endpoint *ep,
const struct imx_media_pixfmt *incc)
{
if (ep->bus_type == V4L2_MBUS_BT656) // including BT.1120
- return 0;
+ return false;
return incc->bayer || is_parallel_16bit_bus(ep) ||
(is_parallel_bus(ep) &&
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index 6f90acf9c725..94bc866ca28c 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -569,48 +569,6 @@ int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
}
EXPORT_SYMBOL_GPL(imx_media_mbus_fmt_to_pix_fmt);
-int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image,
- const struct v4l2_mbus_framefmt *mbus)
-{
- int ret;
-
- memset(image, 0, sizeof(*image));
-
- ret = imx_media_mbus_fmt_to_pix_fmt(&image->pix, mbus, NULL);
- if (ret)
- return ret;
-
- image->rect.width = mbus->width;
- image->rect.height = mbus->height;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(imx_media_mbus_fmt_to_ipu_image);
-
-int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
- const struct ipu_image *image)
-{
- const struct imx_media_pixfmt *fmt;
-
- fmt = imx_media_find_pixel_format(image->pix.pixelformat,
- PIXFMT_SEL_ANY);
- if (!fmt || !fmt->codes || !fmt->codes[0])
- return -EINVAL;
-
- memset(mbus, 0, sizeof(*mbus));
- mbus->width = image->pix.width;
- mbus->height = image->pix.height;
- mbus->code = fmt->codes[0];
- mbus->field = image->pix.field;
- mbus->colorspace = image->pix.colorspace;
- mbus->xfer_func = image->pix.xfer_func;
- mbus->ycbcr_enc = image->pix.ycbcr_enc;
- mbus->quantization = image->pix.quantization;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(imx_media_ipu_image_to_mbus_fmt);
-
void imx_media_free_dma_buf(struct device *dev,
struct imx_media_dma_buf *buf)
{
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index 6740e7917458..f263fc3adbb9 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -199,10 +199,6 @@ void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt,
int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
const struct v4l2_mbus_framefmt *mbus,
const struct imx_media_pixfmt *cc);
-int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image,
- const struct v4l2_mbus_framefmt *mbus);
-int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
- const struct ipu_image *image);
void imx_media_grp_id_to_sd_name(char *sd_name, int sz,
u32 grp_id, int ipu_id);
struct v4l2_subdev *
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index a0941fc2907b..558b256ac935 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -382,13 +382,17 @@ static int csi2_start(struct csi2_dev *csi2)
csi2_enable(csi2, true);
/* Step 5 */
+ ret = v4l2_subdev_call(csi2->src_sd, video, pre_streamon,
+ V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP);
+ if (ret && ret != -ENOIOCTLCMD)
+ goto err_assert_reset;
csi2_dphy_wait_stopstate(csi2, lanes);
/* Step 6 */
ret = v4l2_subdev_call(csi2->src_sd, video, s_stream, 1);
ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
if (ret)
- goto err_assert_reset;
+ goto err_stop_lp11;
/* Step 7 */
ret = csi2_dphy_wait_clock_lane(csi2);
@@ -399,6 +403,8 @@ static int csi2_start(struct csi2_dev *csi2)
err_stop_upstream:
v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
+err_stop_lp11:
+ v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
err_assert_reset:
csi2_enable(csi2, false);
err_disable_clk:
@@ -410,6 +416,7 @@ static void csi2_stop(struct csi2_dev *csi2)
{
/* stop upstream */
v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
+ v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
csi2_enable(csi2, false);
clk_disable_unprepare(csi2->pix_clk);
diff --git a/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h
index 585f55981c86..dbdd015ce220 100644
--- a/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h
+++ b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h
@@ -34,11 +34,17 @@
* struct ipu3_uapi_grid_config - Grid plane config
*
* @width: Grid horizontal dimensions, in number of grid blocks(cells).
+ * For AWB, the range is (16, 80).
+ * For AF/AE, the range is (16, 32).
* @height: Grid vertical dimensions, in number of grid cells.
+ * For AWB, the range is (16, 60).
+ * For AF/AE, the range is (16, 24).
* @block_width_log2: Log2 of the width of each cell in pixels.
- * for (2^3, 2^4, 2^5, 2^6, 2^7), values [3, 7].
+ * For AWB, the range is [3, 6].
+ * For AF/AE, the range is [3, 7].
* @block_height_log2: Log2 of the height of each cell in pixels.
- * for (2^3, 2^4, 2^5, 2^6, 2^7), values [3, 7].
+ * For AWB, the range is [3, 6].
+ * For AF/AE, the range is [3, 7].
* @height_per_slice: The number of blocks in vertical axis per slice.
* Default 2.
* @x_start: X value of top left corner of Region of Interest(ROI).
@@ -61,17 +67,39 @@ struct ipu3_uapi_grid_config {
__u16 y_end;
} __packed;
+/**
+ * struct ipu3_uapi_awb_set_item - Memory layout for each cell in AWB
+ *
+ * @Gr_avg: Green average for red lines in the cell.
+ * @R_avg: Red average in the cell.
+ * @B_avg: Blue average in the cell.
+ * @Gb_avg: Green average for blue lines in the cell.
+ * @sat_ratio: Percentage of pixels over the thresholds specified in
+ * ipu3_uapi_awb_config_s, coded from 0 to 255.
+ * @padding0: Unused byte for padding.
+ * @padding1: Unused byte for padding.
+ * @padding2: Unused byte for padding.
+ */
+struct ipu3_uapi_awb_set_item {
+ __u8 Gr_avg;
+ __u8 R_avg;
+ __u8 B_avg;
+ __u8 Gb_avg;
+ __u8 sat_ratio;
+ __u8 padding0;
+ __u8 padding1;
+ __u8 padding2;
+} __attribute__((packed));
+
/*
* The grid based data is divided into "slices" called set, each slice of setX
* refers to ipu3_uapi_grid_config width * height_per_slice.
*/
#define IPU3_UAPI_AWB_MAX_SETS 60
/* Based on grid size 80 * 60 and cell size 16 x 16 */
-#define IPU3_UAPI_AWB_SET_SIZE 1280
-#define IPU3_UAPI_AWB_MD_ITEM_SIZE 8
+#define IPU3_UAPI_AWB_SET_SIZE 160
#define IPU3_UAPI_AWB_SPARE_FOR_BUBBLES \
- (IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES * \
- IPU3_UAPI_AWB_MD_ITEM_SIZE)
+ (IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES)
#define IPU3_UAPI_AWB_MAX_BUFFER_SIZE \
(IPU3_UAPI_AWB_MAX_SETS * \
(IPU3_UAPI_AWB_SET_SIZE + IPU3_UAPI_AWB_SPARE_FOR_BUBBLES))
@@ -83,7 +111,7 @@ struct ipu3_uapi_grid_config {
* the average values for each color channel.
*/
struct ipu3_uapi_awb_raw_buffer {
- __u8 meta_data[IPU3_UAPI_AWB_MAX_BUFFER_SIZE]
+ struct ipu3_uapi_awb_set_item meta_data[IPU3_UAPI_AWB_MAX_BUFFER_SIZE]
__attribute__((aligned(32)));
} __packed;
diff --git a/drivers/staging/media/ipu3/ipu3-css-params.c b/drivers/staging/media/ipu3/ipu3-css-params.c
index e9d6bd9e9332..d9e3c3785075 100644
--- a/drivers/staging/media/ipu3/ipu3-css-params.c
+++ b/drivers/staging/media/ipu3/ipu3-css-params.c
@@ -771,7 +771,6 @@ static int imgu_css_osys_calc_frame_and_stripe_params(
*/
{
unsigned int i;
- int pin_scale = 0;
/*Input resolution */
stripe_params[s].input_width = stripe_input_width_y;
@@ -791,8 +790,6 @@ static int imgu_css_osys_calc_frame_and_stripe_params(
reso.pin_height[i];
stripe_params[s].output_offset[i] =
stripe_offset_out_y;
-
- pin_scale += frame_params[i].scaled;
} else {
/* Unscaled pin */
stripe_params[s].output_width[i] =
diff --git a/drivers/staging/media/max96712/Kconfig b/drivers/staging/media/max96712/Kconfig
new file mode 100644
index 000000000000..acde14fd5c4d
--- /dev/null
+++ b/drivers/staging/media/max96712/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+config VIDEO_MAX96712
+ tristate "Maxim MAX96712 Quad GMSL2 Deserializer support"
+ depends on I2C
+ depends on OF_GPIO
+ depends on VIDEO_V4L2
+ select V4L2_FWNODE
+ select VIDEO_V4L2_SUBDEV_API
+ select MEDIA_CONTROLLER
+ help
+ This driver supports the Maxim MAX96712 Quad GMSL2 Deserializer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called max96712.
diff --git a/drivers/staging/media/max96712/Makefile b/drivers/staging/media/max96712/Makefile
new file mode 100644
index 000000000000..70c1974ce3f0
--- /dev/null
+++ b/drivers/staging/media/max96712/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_MAX96712) += max96712.o
diff --git a/drivers/staging/media/max96712/max96712.c b/drivers/staging/media/max96712/max96712.c
new file mode 100644
index 000000000000..9bc72d9a858b
--- /dev/null
+++ b/drivers/staging/media/max96712/max96712.c
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim MAX9286 Quad GMSL2 Deserializer Driver
+ *
+ * Copyright (C) 2021 Renesas Electronics Corporation
+ * Copyright (C) 2021 Niklas Söderlund
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/regmap.h>
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define MAX96712_ID 0x20
+
+#define MAX96712_DPLL_FREQ 1000
+
+enum max96712_pattern {
+ MAX96712_PATTERN_CHECKERBOARD = 0,
+ MAX96712_PATTERN_GRADIENT,
+};
+
+struct max96712_priv {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct gpio_desc *gpiod_pwdn;
+
+ struct v4l2_fwnode_bus_mipi_csi2 mipi;
+
+ struct v4l2_subdev sd;
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct media_pad pads[1];
+
+ enum max96712_pattern pattern;
+};
+
+static int max96712_read(struct max96712_priv *priv, int reg)
+{
+ int ret, val;
+
+ ret = regmap_read(priv->regmap, reg, &val);
+ if (ret) {
+ dev_err(&priv->client->dev, "read 0x%04x failed\n", reg);
+ return ret;
+ }
+
+ return val;
+}
+
+static int max96712_write(struct max96712_priv *priv, unsigned int reg, u8 val)
+{
+ int ret;
+
+ ret = regmap_write(priv->regmap, reg, val);
+ if (ret)
+ dev_err(&priv->client->dev, "write 0x%04x failed\n", reg);
+
+ return ret;
+}
+
+static int max96712_update_bits(struct max96712_priv *priv, unsigned int reg,
+ u8 mask, u8 val)
+{
+ int ret;
+
+ ret = regmap_update_bits(priv->regmap, reg, mask, val);
+ if (ret)
+ dev_err(&priv->client->dev, "update 0x%04x failed\n", reg);
+
+ return ret;
+}
+
+static int max96712_write_bulk(struct max96712_priv *priv, unsigned int reg,
+ const void *val, size_t val_count)
+{
+ int ret;
+
+ ret = regmap_bulk_write(priv->regmap, reg, val, val_count);
+ if (ret)
+ dev_err(&priv->client->dev, "bulk write 0x%04x failed\n", reg);
+
+ return ret;
+}
+
+static int max96712_write_bulk_value(struct max96712_priv *priv,
+ unsigned int reg, unsigned int val,
+ size_t val_count)
+{
+ unsigned int i;
+ u8 values[4];
+
+ for (i = 1; i <= val_count; i++)
+ values[i - 1] = (val >> ((val_count - i) * 8)) & 0xff;
+
+ return max96712_write_bulk(priv, reg, &values, val_count);
+}
+
+static void max96712_reset(struct max96712_priv *priv)
+{
+ max96712_update_bits(priv, 0x13, 0x40, 0x40);
+ msleep(20);
+}
+
+static void max96712_mipi_enable(struct max96712_priv *priv, bool enable)
+{
+ if (enable) {
+ max96712_update_bits(priv, 0x40b, 0x02, 0x02);
+ max96712_update_bits(priv, 0x8a0, 0x80, 0x80);
+ } else {
+ max96712_update_bits(priv, 0x8a0, 0x80, 0x00);
+ max96712_update_bits(priv, 0x40b, 0x02, 0x00);
+ }
+}
+
+static void max96712_mipi_configure(struct max96712_priv *priv)
+{
+ unsigned int i;
+ u8 phy5 = 0;
+
+ max96712_mipi_enable(priv, false);
+
+ /* Select 2x4 mode. */
+ max96712_write(priv, 0x8a0, 0x04);
+
+ /* Configure a 4-lane DPHY using PHY0 and PHY1. */
+ /* TODO: Add support for 2-lane and 1-lane configurations. */
+ /* TODO: Add support CPHY mode. */
+ max96712_write(priv, 0x94a, 0xc0);
+
+ /* Configure lane mapping for PHY0 and PHY1. */
+ /* TODO: Add support for lane swapping. */
+ max96712_write(priv, 0x8a3, 0xe4);
+
+ /* Configure lane polarity for PHY0 and PHY1. */
+ for (i = 0; i < priv->mipi.num_data_lanes + 1; i++)
+ if (priv->mipi.lane_polarities[i])
+ phy5 |= BIT(i == 0 ? 5 : i < 3 ? i - 1 : i);
+ max96712_write(priv, 0x8a5, phy5);
+
+ /* Set link frequency for PHY0 and PHY1. */
+ max96712_update_bits(priv, 0x415, 0x3f,
+ ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));
+ max96712_update_bits(priv, 0x418, 0x3f,
+ ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));
+
+ /* Enable PHY0 and PHY1 */
+ max96712_update_bits(priv, 0x8a2, 0xf0, 0x30);
+}
+
+static void max96712_pattern_enable(struct max96712_priv *priv, bool enable)
+{
+ const u32 h_active = 1920;
+ const u32 h_fp = 88;
+ const u32 h_sw = 44;
+ const u32 h_bp = 148;
+ const u32 h_tot = h_active + h_fp + h_sw + h_bp;
+
+ const u32 v_active = 1080;
+ const u32 v_fp = 4;
+ const u32 v_sw = 5;
+ const u32 v_bp = 36;
+ const u32 v_tot = v_active + v_fp + v_sw + v_bp;
+
+ if (!enable) {
+ max96712_write(priv, 0x1051, 0x00);
+ return;
+ }
+
+ /* PCLK 75MHz. */
+ max96712_write(priv, 0x0009, 0x01);
+
+ /* Configure Video Timing Generator for 1920x1080 @ 30 fps. */
+ max96712_write_bulk_value(priv, 0x1052, 0, 3);
+ max96712_write_bulk_value(priv, 0x1055, v_sw * h_tot, 3);
+ max96712_write_bulk_value(priv, 0x1058,
+ (v_active + v_fp + + v_bp) * h_tot, 3);
+ max96712_write_bulk_value(priv, 0x105b, 0, 3);
+ max96712_write_bulk_value(priv, 0x105e, h_sw, 2);
+ max96712_write_bulk_value(priv, 0x1060, h_active + h_fp + h_bp, 2);
+ max96712_write_bulk_value(priv, 0x1062, v_tot, 2);
+ max96712_write_bulk_value(priv, 0x1064,
+ h_tot * (v_sw + v_bp) + (h_sw + h_bp), 3);
+ max96712_write_bulk_value(priv, 0x1067, h_active, 2);
+ max96712_write_bulk_value(priv, 0x1069, h_fp + h_sw + h_bp, 2);
+ max96712_write_bulk_value(priv, 0x106b, v_active, 2);
+
+ /* Generate VS, HS and DE in free-running mode. */
+ max96712_write(priv, 0x1050, 0xfb);
+
+ /* Configure Video Pattern Generator. */
+ if (priv->pattern == MAX96712_PATTERN_CHECKERBOARD) {
+ /* Set checkerboard pattern size. */
+ max96712_write(priv, 0x1074, 0x3c);
+ max96712_write(priv, 0x1075, 0x3c);
+ max96712_write(priv, 0x1076, 0x3c);
+
+ /* Set checkerboard pattern colors. */
+ max96712_write_bulk_value(priv, 0x106e, 0xfecc00, 3);
+ max96712_write_bulk_value(priv, 0x1071, 0x006aa7, 3);
+
+ /* Generate checkerboard pattern. */
+ max96712_write(priv, 0x1051, 0x10);
+ } else {
+ /* Set gradient increment. */
+ max96712_write(priv, 0x106d, 0x10);
+
+ /* Generate gradient pattern. */
+ max96712_write(priv, 0x1051, 0x20);
+ }
+}
+
+static int max96712_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct max96712_priv *priv = v4l2_get_subdevdata(sd);
+
+ if (enable) {
+ max96712_pattern_enable(priv, true);
+ max96712_mipi_enable(priv, true);
+ } else {
+ max96712_mipi_enable(priv, false);
+ max96712_pattern_enable(priv, false);
+ }
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops max96712_video_ops = {
+ .s_stream = max96712_s_stream,
+};
+
+static int max96712_get_pad_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *format)
+{
+ format->format.width = 1920;
+ format->format.height = 1080;
+ format->format.code = MEDIA_BUS_FMT_RGB888_1X24;
+ format->format.field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_pad_ops max96712_pad_ops = {
+ .get_fmt = max96712_get_pad_format,
+ .set_fmt = max96712_get_pad_format,
+};
+
+static const struct v4l2_subdev_ops max96712_subdev_ops = {
+ .video = &max96712_video_ops,
+ .pad = &max96712_pad_ops,
+};
+
+static const char * const max96712_test_pattern[] = {
+ "Checkerboard",
+ "Gradient",
+};
+
+static int max96712_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct max96712_priv *priv =
+ container_of(ctrl->handler, struct max96712_priv, ctrl_handler);
+
+ switch (ctrl->id) {
+ case V4L2_CID_TEST_PATTERN:
+ priv->pattern = ctrl->val ?
+ MAX96712_PATTERN_GRADIENT :
+ MAX96712_PATTERN_CHECKERBOARD;
+ break;
+ }
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops max96712_ctrl_ops = {
+ .s_ctrl = max96712_s_ctrl,
+};
+
+static int max96712_v4l2_register(struct max96712_priv *priv)
+{
+ long pixel_rate;
+ int ret;
+
+ v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96712_subdev_ops);
+ priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+
+ v4l2_ctrl_handler_init(&priv->ctrl_handler, 2);
+
+ /*
+ * TODO: Once V4L2_CID_LINK_FREQ is changed from a menu control to an
+ * INT64 control it should be used here instead of V4L2_CID_PIXEL_RATE.
+ */
+ pixel_rate = MAX96712_DPLL_FREQ / priv->mipi.num_data_lanes * 1000000;
+ v4l2_ctrl_new_std(&priv->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
+ pixel_rate, pixel_rate, 1, pixel_rate);
+
+ v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &max96712_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(max96712_test_pattern) - 1,
+ 0, 0, max96712_test_pattern);
+
+ priv->sd.ctrl_handler = &priv->ctrl_handler;
+ ret = priv->ctrl_handler.error;
+ if (ret)
+ goto error;
+
+ priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
+ ret = media_entity_pads_init(&priv->sd.entity, 1, priv->pads);
+ if (ret)
+ goto error;
+
+ v4l2_set_subdevdata(&priv->sd, priv);
+
+ ret = v4l2_async_register_subdev(&priv->sd);
+ if (ret < 0) {
+ dev_err(&priv->client->dev, "Unable to register subdevice\n");
+ goto error;
+ }
+
+ return 0;
+error:
+ v4l2_ctrl_handler_free(&priv->ctrl_handler);
+
+ return ret;
+}
+
+static int max96712_parse_dt(struct max96712_priv *priv)
+{
+ struct fwnode_handle *ep;
+ struct v4l2_fwnode_endpoint v4l2_ep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ int ret;
+
+ ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(&priv->client->dev), 4,
+ 0, 0);
+ if (!ep) {
+ dev_err(&priv->client->dev, "Not connected to subdevice\n");
+ return -EINVAL;
+ }
+
+ ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
+ fwnode_handle_put(ep);
+ if (ret) {
+ dev_err(&priv->client->dev, "Could not parse v4l2 endpoint\n");
+ return -EINVAL;
+ }
+
+ if (v4l2_ep.bus.mipi_csi2.num_data_lanes != 4) {
+ dev_err(&priv->client->dev, "Only 4 data lanes supported\n");
+ return -EINVAL;
+ }
+
+ priv->mipi = v4l2_ep.bus.mipi_csi2;
+
+ return 0;
+}
+
+static const struct regmap_config max96712_i2c_regmap = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x1f00,
+};
+
+static int max96712_probe(struct i2c_client *client)
+{
+ struct max96712_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->client = client;
+ i2c_set_clientdata(client, priv);
+
+ priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->gpiod_pwdn))
+ return PTR_ERR(priv->gpiod_pwdn);
+
+ gpiod_set_consumer_name(priv->gpiod_pwdn, "max96712-pwdn");
+ gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
+
+ if (priv->gpiod_pwdn)
+ usleep_range(4000, 5000);
+
+ if (max96712_read(priv, 0x4a) != MAX96712_ID)
+ return -ENODEV;
+
+ max96712_reset(priv);
+
+ ret = max96712_parse_dt(priv);
+ if (ret)
+ return ret;
+
+ max96712_mipi_configure(priv);
+
+ return max96712_v4l2_register(priv);
+}
+
+static int max96712_remove(struct i2c_client *client)
+{
+ struct max96712_priv *priv = i2c_get_clientdata(client);
+
+ v4l2_async_unregister_subdev(&priv->sd);
+
+ gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
+
+ return 0;
+}
+
+static const struct of_device_id max96712_of_table[] = {
+ { .compatible = "maxim,max96712" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, max96712_of_table);
+
+static struct i2c_driver max96712_i2c_driver = {
+ .driver = {
+ .name = "max96712",
+ .of_match_table = of_match_ptr(max96712_of_table),
+ },
+ .probe_new = max96712_probe,
+ .remove = max96712_remove,
+};
+
+module_i2c_driver(max96712_i2c_driver);
+
+MODULE_DESCRIPTION("Maxim MAX96712 Quad GMSL2 Deserializer Driver");
+MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
index b9125c295d1d..203d7afa085d 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
@@ -276,13 +276,13 @@ static void dst_buf_done(struct amvdec_session *sess,
switch (sess->pixfmt_cap) {
case V4L2_PIX_FMT_NV12M:
- vbuf->vb2_buf.planes[0].bytesused = output_size;
- vbuf->vb2_buf.planes[1].bytesused = output_size / 2;
+ vb2_set_plane_payload(&vbuf->vb2_buf, 0, output_size);
+ vb2_set_plane_payload(&vbuf->vb2_buf, 1, output_size / 2);
break;
case V4L2_PIX_FMT_YUV420M:
- vbuf->vb2_buf.planes[0].bytesused = output_size;
- vbuf->vb2_buf.planes[1].bytesused = output_size / 4;
- vbuf->vb2_buf.planes[2].bytesused = output_size / 4;
+ vb2_set_plane_payload(&vbuf->vb2_buf, 0, output_size);
+ vb2_set_plane_payload(&vbuf->vb2_buf, 1, output_size / 4);
+ vb2_set_plane_payload(&vbuf->vb2_buf, 2, output_size / 4);
break;
}
diff --git a/drivers/staging/media/rkvdec/Kconfig b/drivers/staging/media/rkvdec/Kconfig
index c02199b5e0fd..dc7292f346fa 100644
--- a/drivers/staging/media/rkvdec/Kconfig
+++ b/drivers/staging/media/rkvdec/Kconfig
@@ -9,6 +9,7 @@ config VIDEO_ROCKCHIP_VDEC
select VIDEOBUF2_VMALLOC
select V4L2_MEM2MEM_DEV
select V4L2_H264
+ select V4L2_VP9
help
Support for the Rockchip Video Decoder IP present on Rockchip SoCs,
which accelerates video decoding.
diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/staging/media/rkvdec/Makefile
index c08fed0a39f9..cb86b429cfaa 100644
--- a/drivers/staging/media/rkvdec/Makefile
+++ b/drivers/staging/media/rkvdec/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rockchip-vdec.o
-rockchip-vdec-y += rkvdec.o rkvdec-h264.o
+rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-vp9.o
diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c
new file mode 100644
index 000000000000..311a12656072
--- /dev/null
+++ b/drivers/staging/media/rkvdec/rkvdec-vp9.c
@@ -0,0 +1,1072 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Video Decoder VP9 backend
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ * Boris Brezillon <boris.brezillon@collabora.com>
+ * Copyright (C) 2021 Collabora, Ltd.
+ * Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+ *
+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
+ * Alpha Lin <Alpha.Lin@rock-chips.com>
+ */
+
+/*
+ * For following the vp9 spec please start reading this driver
+ * code from rkvdec_vp9_run() followed by rkvdec_vp9_done().
+ */
+
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-vp9.h>
+
+#include "rkvdec.h"
+#include "rkvdec-regs.h"
+
+#define RKVDEC_VP9_PROBE_SIZE 4864
+#define RKVDEC_VP9_COUNT_SIZE 13232
+#define RKVDEC_VP9_MAX_SEGMAP_SIZE 73728
+
+struct rkvdec_vp9_intra_mode_probs {
+ u8 y_mode[105];
+ u8 uv_mode[23];
+};
+
+struct rkvdec_vp9_intra_only_frame_probs {
+ u8 coef_intra[4][2][128];
+ struct rkvdec_vp9_intra_mode_probs intra_mode[10];
+};
+
+struct rkvdec_vp9_inter_frame_probs {
+ u8 y_mode[4][9];
+ u8 comp_mode[5];
+ u8 comp_ref[5];
+ u8 single_ref[5][2];
+ u8 inter_mode[7][3];
+ u8 interp_filter[4][2];
+ u8 padding0[11];
+ u8 coef[2][4][2][128];
+ u8 uv_mode_0_2[3][9];
+ u8 padding1[5];
+ u8 uv_mode_3_5[3][9];
+ u8 padding2[5];
+ u8 uv_mode_6_8[3][9];
+ u8 padding3[5];
+ u8 uv_mode_9[9];
+ u8 padding4[7];
+ u8 padding5[16];
+ struct {
+ u8 joint[3];
+ u8 sign[2];
+ u8 classes[2][10];
+ u8 class0_bit[2];
+ u8 bits[2][10];
+ u8 class0_fr[2][2][3];
+ u8 fr[2][3];
+ u8 class0_hp[2];
+ u8 hp[2];
+ } mv;
+};
+
+struct rkvdec_vp9_probs {
+ u8 partition[16][3];
+ u8 pred[3];
+ u8 tree[7];
+ u8 skip[3];
+ u8 tx32[2][3];
+ u8 tx16[2][2];
+ u8 tx8[2][1];
+ u8 is_inter[4];
+ /* 128 bit alignment */
+ u8 padding0[3];
+ union {
+ struct rkvdec_vp9_inter_frame_probs inter;
+ struct rkvdec_vp9_intra_only_frame_probs intra_only;
+ };
+};
+
+/* Data structure describing auxiliary buffer format. */
+struct rkvdec_vp9_priv_tbl {
+ struct rkvdec_vp9_probs probs;
+ u8 segmap[2][RKVDEC_VP9_MAX_SEGMAP_SIZE];
+};
+
+struct rkvdec_vp9_refs_counts {
+ u32 eob[2];
+ u32 coeff[3];
+};
+
+struct rkvdec_vp9_inter_frame_symbol_counts {
+ u32 partition[16][4];
+ u32 skip[3][2];
+ u32 inter[4][2];
+ u32 tx32p[2][4];
+ u32 tx16p[2][4];
+ u32 tx8p[2][2];
+ u32 y_mode[4][10];
+ u32 uv_mode[10][10];
+ u32 comp[5][2];
+ u32 comp_ref[5][2];
+ u32 single_ref[5][2][2];
+ u32 mv_mode[7][4];
+ u32 filter[4][3];
+ u32 mv_joint[4];
+ u32 sign[2][2];
+ /* add 1 element for align */
+ u32 classes[2][11 + 1];
+ u32 class0[2][2];
+ u32 bits[2][10][2];
+ u32 class0_fp[2][2][4];
+ u32 fp[2][4];
+ u32 class0_hp[2][2];
+ u32 hp[2][2];
+ struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6];
+};
+
+struct rkvdec_vp9_intra_frame_symbol_counts {
+ u32 partition[4][4][4];
+ u32 skip[3][2];
+ u32 intra[4][2];
+ u32 tx32p[2][4];
+ u32 tx16p[2][4];
+ u32 tx8p[2][2];
+ struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6];
+};
+
+struct rkvdec_vp9_run {
+ struct rkvdec_run base;
+ const struct v4l2_ctrl_vp9_frame *decode_params;
+};
+
+struct rkvdec_vp9_frame_info {
+ u32 valid : 1;
+ u32 segmapid : 1;
+ u32 frame_context_idx : 2;
+ u32 reference_mode : 2;
+ u32 tx_mode : 3;
+ u32 interpolation_filter : 3;
+ u32 flags;
+ u64 timestamp;
+ struct v4l2_vp9_segmentation seg;
+ struct v4l2_vp9_loop_filter lf;
+};
+
+struct rkvdec_vp9_ctx {
+ struct rkvdec_aux_buf priv_tbl;
+ struct rkvdec_aux_buf count_tbl;
+ struct v4l2_vp9_frame_symbol_counts inter_cnts;
+ struct v4l2_vp9_frame_symbol_counts intra_cnts;
+ struct v4l2_vp9_frame_context probability_tables;
+ struct v4l2_vp9_frame_context frame_context[4];
+ struct rkvdec_vp9_frame_info cur;
+ struct rkvdec_vp9_frame_info last;
+};
+
+static void write_coeff_plane(const u8 coef[6][6][3], u8 *coeff_plane)
+{
+ unsigned int idx = 0, byte_count = 0;
+ int k, m, n;
+ u8 p;
+
+ for (k = 0; k < 6; k++) {
+ for (m = 0; m < 6; m++) {
+ for (n = 0; n < 3; n++) {
+ p = coef[k][m][n];
+ coeff_plane[idx++] = p;
+ byte_count++;
+ if (byte_count == 27) {
+ idx += 5;
+ byte_count = 0;
+ }
+ }
+ }
+ }
+}
+
+static void init_intra_only_probs(struct rkvdec_ctx *ctx,
+ const struct rkvdec_vp9_run *run)
+{
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu;
+ struct rkvdec_vp9_intra_only_frame_probs *rkprobs;
+ const struct v4l2_vp9_frame_context *probs;
+ unsigned int i, j, k;
+
+ rkprobs = &tbl->probs.intra_only;
+ probs = &vp9_ctx->probability_tables;
+
+ /*
+ * intra only 149 x 128 bits ,aligned to 152 x 128 bits coeff related
+ * prob 64 x 128 bits
+ */
+ for (i = 0; i < ARRAY_SIZE(probs->coef); i++) {
+ for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++)
+ write_coeff_plane(probs->coef[i][j][0],
+ rkprobs->coef_intra[i][j]);
+ }
+
+ /* intra mode prob 80 x 128 bits */
+ for (i = 0; i < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob); i++) {
+ unsigned int byte_count = 0;
+ int idx = 0;
+
+ /* vp9_kf_y_mode_prob */
+ for (j = 0; j < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob[0]); j++) {
+ for (k = 0; k < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob[0][0]);
+ k++) {
+ u8 val = v4l2_vp9_kf_y_mode_prob[i][j][k];
+
+ rkprobs->intra_mode[i].y_mode[idx++] = val;
+ byte_count++;
+ if (byte_count == 27) {
+ byte_count = 0;
+ idx += 5;
+ }
+ }
+ }
+
+ }
+
+ for (i = 0; i < sizeof(v4l2_vp9_kf_uv_mode_prob); ++i) {
+ const u8 *ptr = (const u8 *)v4l2_vp9_kf_uv_mode_prob;
+
+ rkprobs->intra_mode[i / 23].uv_mode[i % 23] = ptr[i];
+ }
+}
+
+static void init_inter_probs(struct rkvdec_ctx *ctx,
+ const struct rkvdec_vp9_run *run)
+{
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu;
+ struct rkvdec_vp9_inter_frame_probs *rkprobs;
+ const struct v4l2_vp9_frame_context *probs;
+ unsigned int i, j, k;
+
+ rkprobs = &tbl->probs.inter;
+ probs = &vp9_ctx->probability_tables;
+
+ /*
+ * inter probs
+ * 151 x 128 bits, aligned to 152 x 128 bits
+ * inter only
+ * intra_y_mode & inter_block info 6 x 128 bits
+ */
+
+ memcpy(rkprobs->y_mode, probs->y_mode, sizeof(rkprobs->y_mode));
+ memcpy(rkprobs->comp_mode, probs->comp_mode,
+ sizeof(rkprobs->comp_mode));
+ memcpy(rkprobs->comp_ref, probs->comp_ref,
+ sizeof(rkprobs->comp_ref));
+ memcpy(rkprobs->single_ref, probs->single_ref,
+ sizeof(rkprobs->single_ref));
+ memcpy(rkprobs->inter_mode, probs->inter_mode,
+ sizeof(rkprobs->inter_mode));
+ memcpy(rkprobs->interp_filter, probs->interp_filter,
+ sizeof(rkprobs->interp_filter));
+
+ /* 128 x 128 bits coeff related */
+ for (i = 0; i < ARRAY_SIZE(probs->coef); i++) {
+ for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++) {
+ for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++)
+ write_coeff_plane(probs->coef[i][j][k],
+ rkprobs->coef[k][i][j]);
+ }
+ }
+
+ /* intra uv mode 6 x 128 */
+ memcpy(rkprobs->uv_mode_0_2, &probs->uv_mode[0],
+ sizeof(rkprobs->uv_mode_0_2));
+ memcpy(rkprobs->uv_mode_3_5, &probs->uv_mode[3],
+ sizeof(rkprobs->uv_mode_3_5));
+ memcpy(rkprobs->uv_mode_6_8, &probs->uv_mode[6],
+ sizeof(rkprobs->uv_mode_6_8));
+ memcpy(rkprobs->uv_mode_9, &probs->uv_mode[9],
+ sizeof(rkprobs->uv_mode_9));
+
+ /* mv related 6 x 128 */
+ memcpy(rkprobs->mv.joint, probs->mv.joint,
+ sizeof(rkprobs->mv.joint));
+ memcpy(rkprobs->mv.sign, probs->mv.sign,
+ sizeof(rkprobs->mv.sign));
+ memcpy(rkprobs->mv.classes, probs->mv.classes,
+ sizeof(rkprobs->mv.classes));
+ memcpy(rkprobs->mv.class0_bit, probs->mv.class0_bit,
+ sizeof(rkprobs->mv.class0_bit));
+ memcpy(rkprobs->mv.bits, probs->mv.bits,
+ sizeof(rkprobs->mv.bits));
+ memcpy(rkprobs->mv.class0_fr, probs->mv.class0_fr,
+ sizeof(rkprobs->mv.class0_fr));
+ memcpy(rkprobs->mv.fr, probs->mv.fr,
+ sizeof(rkprobs->mv.fr));
+ memcpy(rkprobs->mv.class0_hp, probs->mv.class0_hp,
+ sizeof(rkprobs->mv.class0_hp));
+ memcpy(rkprobs->mv.hp, probs->mv.hp,
+ sizeof(rkprobs->mv.hp));
+}
+
+static void init_probs(struct rkvdec_ctx *ctx,
+ const struct rkvdec_vp9_run *run)
+{
+ const struct v4l2_ctrl_vp9_frame *dec_params;
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu;
+ struct rkvdec_vp9_probs *rkprobs = &tbl->probs;
+ const struct v4l2_vp9_segmentation *seg;
+ const struct v4l2_vp9_frame_context *probs;
+ bool intra_only;
+
+ dec_params = run->decode_params;
+ probs = &vp9_ctx->probability_tables;
+ seg = &dec_params->seg;
+
+ memset(rkprobs, 0, sizeof(*rkprobs));
+
+ intra_only = !!(dec_params->flags &
+ (V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+ V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
+
+ /* sb info 5 x 128 bit */
+ memcpy(rkprobs->partition,
+ intra_only ? v4l2_vp9_kf_partition_probs : probs->partition,
+ sizeof(rkprobs->partition));
+
+ memcpy(rkprobs->pred, seg->pred_probs, sizeof(rkprobs->pred));
+ memcpy(rkprobs->tree, seg->tree_probs, sizeof(rkprobs->tree));
+ memcpy(rkprobs->skip, probs->skip, sizeof(rkprobs->skip));
+ memcpy(rkprobs->tx32, probs->tx32, sizeof(rkprobs->tx32));
+ memcpy(rkprobs->tx16, probs->tx16, sizeof(rkprobs->tx16));
+ memcpy(rkprobs->tx8, probs->tx8, sizeof(rkprobs->tx8));
+ memcpy(rkprobs->is_inter, probs->is_inter, sizeof(rkprobs->is_inter));
+
+ if (intra_only)
+ init_intra_only_probs(ctx, run);
+ else
+ init_inter_probs(ctx, run);
+}
+
+struct rkvdec_vp9_ref_reg {
+ u32 reg_frm_size;
+ u32 reg_hor_stride;
+ u32 reg_y_stride;
+ u32 reg_yuv_stride;
+ u32 reg_ref_base;
+};
+
+static struct rkvdec_vp9_ref_reg ref_regs[] = {
+ {
+ .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(0),
+ .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(0),
+ .reg_y_stride = RKVDEC_VP9_LAST_FRAME_YSTRIDE,
+ .reg_yuv_stride = RKVDEC_VP9_LAST_FRAME_YUVSTRIDE,
+ .reg_ref_base = RKVDEC_REG_VP9_LAST_FRAME_BASE,
+ },
+ {
+ .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(1),
+ .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(1),
+ .reg_y_stride = RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE,
+ .reg_yuv_stride = 0,
+ .reg_ref_base = RKVDEC_REG_VP9_GOLDEN_FRAME_BASE,
+ },
+ {
+ .reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(2),
+ .reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(2),
+ .reg_y_stride = RKVDEC_VP9_ALTREF_FRAME_YSTRIDE,
+ .reg_yuv_stride = 0,
+ .reg_ref_base = RKVDEC_REG_VP9_ALTREF_FRAME_BASE,
+ }
+};
+
+static struct rkvdec_decoded_buffer *
+get_ref_buf(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp)
+{
+ struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
+ struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
+ int buf_idx;
+
+ /*
+ * If a ref is unused or invalid, address of current destination
+ * buffer is returned.
+ */
+ buf_idx = vb2_find_timestamp(cap_q, timestamp, 0);
+ if (buf_idx < 0)
+ return vb2_to_rkvdec_decoded_buf(&dst->vb2_buf);
+
+ return vb2_to_rkvdec_decoded_buf(vb2_get_buffer(cap_q, buf_idx));
+}
+
+static dma_addr_t get_mv_base_addr(struct rkvdec_decoded_buffer *buf)
+{
+ unsigned int aligned_pitch, aligned_height, yuv_len;
+
+ aligned_height = round_up(buf->vp9.height, 64);
+ aligned_pitch = round_up(buf->vp9.width * buf->vp9.bit_depth, 512) / 8;
+ yuv_len = (aligned_height * aligned_pitch * 3) / 2;
+
+ return vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 0) +
+ yuv_len;
+}
+
+static void config_ref_registers(struct rkvdec_ctx *ctx,
+ const struct rkvdec_vp9_run *run,
+ struct rkvdec_decoded_buffer *ref_buf,
+ struct rkvdec_vp9_ref_reg *ref_reg)
+{
+ unsigned int aligned_pitch, aligned_height, y_len, yuv_len;
+ struct rkvdec_dev *rkvdec = ctx->dev;
+
+ aligned_height = round_up(ref_buf->vp9.height, 64);
+ writel_relaxed(RKVDEC_VP9_FRAMEWIDTH(ref_buf->vp9.width) |
+ RKVDEC_VP9_FRAMEHEIGHT(ref_buf->vp9.height),
+ rkvdec->regs + ref_reg->reg_frm_size);
+
+ writel_relaxed(vb2_dma_contig_plane_dma_addr(&ref_buf->base.vb.vb2_buf, 0),
+ rkvdec->regs + ref_reg->reg_ref_base);
+
+ if (&ref_buf->base.vb == run->base.bufs.dst)
+ return;
+
+ aligned_pitch = round_up(ref_buf->vp9.width * ref_buf->vp9.bit_depth, 512) / 8;
+ y_len = aligned_height * aligned_pitch;
+ yuv_len = (y_len * 3) / 2;
+
+ writel_relaxed(RKVDEC_HOR_Y_VIRSTRIDE(aligned_pitch / 16) |
+ RKVDEC_HOR_UV_VIRSTRIDE(aligned_pitch / 16),
+ rkvdec->regs + ref_reg->reg_hor_stride);
+ writel_relaxed(RKVDEC_VP9_REF_YSTRIDE(y_len / 16),
+ rkvdec->regs + ref_reg->reg_y_stride);
+
+ if (!ref_reg->reg_yuv_stride)
+ return;
+
+ writel_relaxed(RKVDEC_VP9_REF_YUVSTRIDE(yuv_len / 16),
+ rkvdec->regs + ref_reg->reg_yuv_stride);
+}
+
+static void config_seg_registers(struct rkvdec_ctx *ctx, unsigned int segid)
+{
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ const struct v4l2_vp9_segmentation *seg;
+ struct rkvdec_dev *rkvdec = ctx->dev;
+ s16 feature_val;
+ int feature_id;
+ u32 val = 0;
+
+ seg = vp9_ctx->last.valid ? &vp9_ctx->last.seg : &vp9_ctx->cur.seg;
+ feature_id = V4L2_VP9_SEG_LVL_ALT_Q;
+ if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
+ feature_val = seg->feature_data[segid][feature_id];
+ val |= RKVDEC_SEGID_FRAME_QP_DELTA_EN(1) |
+ RKVDEC_SEGID_FRAME_QP_DELTA(feature_val);
+ }
+
+ feature_id = V4L2_VP9_SEG_LVL_ALT_L;
+ if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
+ feature_val = seg->feature_data[segid][feature_id];
+ val |= RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(1) |
+ RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(feature_val);
+ }
+
+ feature_id = V4L2_VP9_SEG_LVL_REF_FRAME;
+ if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
+ feature_val = seg->feature_data[segid][feature_id];
+ val |= RKVDEC_SEGID_REFERINFO_EN(1) |
+ RKVDEC_SEGID_REFERINFO(feature_val);
+ }
+
+ feature_id = V4L2_VP9_SEG_LVL_SKIP;
+ if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid))
+ val |= RKVDEC_SEGID_FRAME_SKIP_EN(1);
+
+ if (!segid &&
+ (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
+ val |= RKVDEC_SEGID_ABS_DELTA(1);
+
+ writel_relaxed(val, rkvdec->regs + RKVDEC_VP9_SEGID_GRP(segid));
+}
+
+static void update_dec_buf_info(struct rkvdec_decoded_buffer *buf,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ buf->vp9.width = dec_params->frame_width_minus_1 + 1;
+ buf->vp9.height = dec_params->frame_height_minus_1 + 1;
+ buf->vp9.bit_depth = dec_params->bit_depth;
+}
+
+static void update_ctx_cur_info(struct rkvdec_vp9_ctx *vp9_ctx,
+ struct rkvdec_decoded_buffer *buf,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ vp9_ctx->cur.valid = true;
+ vp9_ctx->cur.reference_mode = dec_params->reference_mode;
+ vp9_ctx->cur.interpolation_filter = dec_params->interpolation_filter;
+ vp9_ctx->cur.flags = dec_params->flags;
+ vp9_ctx->cur.timestamp = buf->base.vb.vb2_buf.timestamp;
+ vp9_ctx->cur.seg = dec_params->seg;
+ vp9_ctx->cur.lf = dec_params->lf;
+}
+
+static void update_ctx_last_info(struct rkvdec_vp9_ctx *vp9_ctx)
+{
+ vp9_ctx->last = vp9_ctx->cur;
+}
+
+static void config_registers(struct rkvdec_ctx *ctx,
+ const struct rkvdec_vp9_run *run)
+{
+ unsigned int y_len, uv_len, yuv_len, bit_depth, aligned_height, aligned_pitch, stream_len;
+ const struct v4l2_ctrl_vp9_frame *dec_params;
+ struct rkvdec_decoded_buffer *ref_bufs[3];
+ struct rkvdec_decoded_buffer *dst, *last, *mv_ref;
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ u32 val, last_frame_info = 0;
+ const struct v4l2_vp9_segmentation *seg;
+ struct rkvdec_dev *rkvdec = ctx->dev;
+ dma_addr_t addr;
+ bool intra_only;
+ unsigned int i;
+
+ dec_params = run->decode_params;
+ dst = vb2_to_rkvdec_decoded_buf(&run->base.bufs.dst->vb2_buf);
+ ref_bufs[0] = get_ref_buf(ctx, &dst->base.vb, dec_params->last_frame_ts);
+ ref_bufs[1] = get_ref_buf(ctx, &dst->base.vb, dec_params->golden_frame_ts);
+ ref_bufs[2] = get_ref_buf(ctx, &dst->base.vb, dec_params->alt_frame_ts);
+
+ if (vp9_ctx->last.valid)
+ last = get_ref_buf(ctx, &dst->base.vb, vp9_ctx->last.timestamp);
+ else
+ last = dst;
+
+ update_dec_buf_info(dst, dec_params);
+ update_ctx_cur_info(vp9_ctx, dst, dec_params);
+ seg = &dec_params->seg;
+
+ intra_only = !!(dec_params->flags &
+ (V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+ V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
+
+ writel_relaxed(RKVDEC_MODE(RKVDEC_MODE_VP9),
+ rkvdec->regs + RKVDEC_REG_SYSCTRL);
+
+ bit_depth = dec_params->bit_depth;
+ aligned_height = round_up(ctx->decoded_fmt.fmt.pix_mp.height, 64);
+
+ aligned_pitch = round_up(ctx->decoded_fmt.fmt.pix_mp.width *
+ bit_depth,
+ 512) / 8;
+ y_len = aligned_height * aligned_pitch;
+ uv_len = y_len / 2;
+ yuv_len = y_len + uv_len;
+
+ writel_relaxed(RKVDEC_Y_HOR_VIRSTRIDE(aligned_pitch / 16) |
+ RKVDEC_UV_HOR_VIRSTRIDE(aligned_pitch / 16),
+ rkvdec->regs + RKVDEC_REG_PICPAR);
+ writel_relaxed(RKVDEC_Y_VIRSTRIDE(y_len / 16),
+ rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
+ writel_relaxed(RKVDEC_YUV_VIRSTRIDE(yuv_len / 16),
+ rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
+
+ stream_len = vb2_get_plane_payload(&run->base.bufs.src->vb2_buf, 0);
+ writel_relaxed(RKVDEC_STRM_LEN(stream_len),
+ rkvdec->regs + RKVDEC_REG_STRM_LEN);
+
+ /*
+ * Reset count buffer, because decoder only output intra related syntax
+ * counts when decoding intra frame, but update entropy need to update
+ * all the probabilities.
+ */
+ if (intra_only)
+ memset(vp9_ctx->count_tbl.cpu, 0, vp9_ctx->count_tbl.size);
+
+ vp9_ctx->cur.segmapid = vp9_ctx->last.segmapid;
+ if (!intra_only &&
+ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+ (!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED) ||
+ (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP)))
+ vp9_ctx->cur.segmapid++;
+
+ for (i = 0; i < ARRAY_SIZE(ref_bufs); i++)
+ config_ref_registers(ctx, run, ref_bufs[i], &ref_regs[i]);
+
+ for (i = 0; i < 8; i++)
+ config_seg_registers(ctx, i);
+
+ writel_relaxed(RKVDEC_VP9_TX_MODE(vp9_ctx->cur.tx_mode) |
+ RKVDEC_VP9_FRAME_REF_MODE(dec_params->reference_mode),
+ rkvdec->regs + RKVDEC_VP9_CPRHEADER_CONFIG);
+
+ if (!intra_only) {
+ const struct v4l2_vp9_loop_filter *lf;
+ s8 delta;
+
+ if (vp9_ctx->last.valid)
+ lf = &vp9_ctx->last.lf;
+ else
+ lf = &vp9_ctx->cur.lf;
+
+ val = 0;
+ for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++) {
+ delta = lf->ref_deltas[i];
+ val |= RKVDEC_REF_DELTAS_LASTFRAME(i, delta);
+ }
+
+ writel_relaxed(val,
+ rkvdec->regs + RKVDEC_VP9_REF_DELTAS_LASTFRAME);
+
+ for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++) {
+ delta = lf->mode_deltas[i];
+ last_frame_info |= RKVDEC_MODE_DELTAS_LASTFRAME(i,
+ delta);
+ }
+ }
+
+ if (vp9_ctx->last.valid && !intra_only &&
+ vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED)
+ last_frame_info |= RKVDEC_SEG_EN_LASTFRAME;
+
+ if (vp9_ctx->last.valid &&
+ vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME)
+ last_frame_info |= RKVDEC_LAST_SHOW_FRAME;
+
+ if (vp9_ctx->last.valid &&
+ vp9_ctx->last.flags &
+ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY))
+ last_frame_info |= RKVDEC_LAST_INTRA_ONLY;
+
+ if (vp9_ctx->last.valid &&
+ last->vp9.width == dst->vp9.width &&
+ last->vp9.height == dst->vp9.height)
+ last_frame_info |= RKVDEC_LAST_WIDHHEIGHT_EQCUR;
+
+ writel_relaxed(last_frame_info,
+ rkvdec->regs + RKVDEC_VP9_INFO_LASTFRAME);
+
+ writel_relaxed(stream_len - dec_params->compressed_header_size -
+ dec_params->uncompressed_header_size,
+ rkvdec->regs + RKVDEC_VP9_LASTTILE_SIZE);
+
+ for (i = 0; !intra_only && i < ARRAY_SIZE(ref_bufs); i++) {
+ unsigned int refw = ref_bufs[i]->vp9.width;
+ unsigned int refh = ref_bufs[i]->vp9.height;
+ u32 hscale, vscale;
+
+ hscale = (refw << 14) / dst->vp9.width;
+ vscale = (refh << 14) / dst->vp9.height;
+ writel_relaxed(RKVDEC_VP9_REF_HOR_SCALE(hscale) |
+ RKVDEC_VP9_REF_VER_SCALE(vscale),
+ rkvdec->regs + RKVDEC_VP9_REF_SCALE(i));
+ }
+
+ addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0);
+ writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
+ addr = vb2_dma_contig_plane_dma_addr(&run->base.bufs.src->vb2_buf, 0);
+ writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
+ writel_relaxed(vp9_ctx->priv_tbl.dma +
+ offsetof(struct rkvdec_vp9_priv_tbl, probs),
+ rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
+ writel_relaxed(vp9_ctx->count_tbl.dma,
+ rkvdec->regs + RKVDEC_REG_VP9COUNT_BASE);
+
+ writel_relaxed(vp9_ctx->priv_tbl.dma +
+ offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
+ (RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid),
+ rkvdec->regs + RKVDEC_REG_VP9_SEGIDCUR_BASE);
+ writel_relaxed(vp9_ctx->priv_tbl.dma +
+ offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
+ (RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid)),
+ rkvdec->regs + RKVDEC_REG_VP9_SEGIDLAST_BASE);
+
+ if (!intra_only &&
+ !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+ vp9_ctx->last.valid)
+ mv_ref = last;
+ else
+ mv_ref = dst;
+
+ writel_relaxed(get_mv_base_addr(mv_ref),
+ rkvdec->regs + RKVDEC_VP9_REF_COLMV_BASE);
+
+ writel_relaxed(ctx->decoded_fmt.fmt.pix_mp.width |
+ (ctx->decoded_fmt.fmt.pix_mp.height << 16),
+ rkvdec->regs + RKVDEC_REG_PERFORMANCE_CYCLE);
+}
+
+static int validate_dec_params(struct rkvdec_ctx *ctx,
+ const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+ unsigned int aligned_width, aligned_height;
+
+ /* We only support profile 0. */
+ if (dec_params->profile != 0) {
+ dev_err(ctx->dev->dev, "unsupported profile %d\n",
+ dec_params->profile);
+ return -EINVAL;
+ }
+
+ aligned_width = round_up(dec_params->frame_width_minus_1 + 1, 64);
+ aligned_height = round_up(dec_params->frame_height_minus_1 + 1, 64);
+
+ /*
+ * Userspace should update the capture/decoded format when the
+ * resolution changes.
+ */
+ if (aligned_width != ctx->decoded_fmt.fmt.pix_mp.width ||
+ aligned_height != ctx->decoded_fmt.fmt.pix_mp.height) {
+ dev_err(ctx->dev->dev,
+ "unexpected bitstream resolution %dx%d\n",
+ dec_params->frame_width_minus_1 + 1,
+ dec_params->frame_height_minus_1 + 1);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rkvdec_vp9_run_preamble(struct rkvdec_ctx *ctx,
+ struct rkvdec_vp9_run *run)
+{
+ const struct v4l2_ctrl_vp9_frame *dec_params;
+ const struct v4l2_ctrl_vp9_compressed_hdr *prob_updates;
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ struct v4l2_ctrl *ctrl;
+ unsigned int fctx_idx;
+ int ret;
+
+ /* v4l2-specific stuff */
+ rkvdec_run_preamble(ctx, &run->base);
+
+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+ V4L2_CID_STATELESS_VP9_FRAME);
+ if (WARN_ON(!ctrl))
+ return -EINVAL;
+ dec_params = ctrl->p_cur.p;
+
+ ret = validate_dec_params(ctx, dec_params);
+ if (ret)
+ return ret;
+
+ run->decode_params = dec_params;
+
+ ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR);
+ if (WARN_ON(!ctrl))
+ return -EINVAL;
+ prob_updates = ctrl->p_cur.p;
+ vp9_ctx->cur.tx_mode = prob_updates->tx_mode;
+
+ /*
+ * vp9 stuff
+ *
+ * by this point the userspace has done all parts of 6.2 uncompressed_header()
+ * except this fragment:
+ * if ( FrameIsIntra || error_resilient_mode ) {
+ * setup_past_independence ( )
+ * if ( frame_type == KEY_FRAME || error_resilient_mode == 1 ||
+ * reset_frame_context == 3 ) {
+ * for ( i = 0; i < 4; i ++ ) {
+ * save_probs( i )
+ * }
+ * } else if ( reset_frame_context == 2 ) {
+ * save_probs( frame_context_idx )
+ * }
+ * frame_context_idx = 0
+ * }
+ */
+ fctx_idx = v4l2_vp9_reset_frame_ctx(dec_params, vp9_ctx->frame_context);
+ vp9_ctx->cur.frame_context_idx = fctx_idx;
+
+ /* 6.1 frame(sz): load_probs() and load_probs2() */
+ vp9_ctx->probability_tables = vp9_ctx->frame_context[fctx_idx];
+
+ /*
+ * The userspace has also performed 6.3 compressed_header(), but handling the
+ * probs in a special way. All probs which need updating, except MV-related,
+ * have been read from the bitstream and translated through inv_map_table[],
+ * but no 6.3.6 inv_recenter_nonneg(v, m) has been performed. The values passed
+ * by userspace are either translated values (there are no 0 values in
+ * inv_map_table[]), or zero to indicate no update. All MV-related probs which need
+ * updating have been read from the bitstream and (mv_prob << 1) | 1 has been
+ * performed. The values passed by userspace are either new values
+ * to replace old ones (the above mentioned shift and bitwise or never result in
+ * a zero) or zero to indicate no update.
+ * fw_update_probs() performs actual probs updates or leaves probs as-is
+ * for values for which a zero was passed from userspace.
+ */
+ v4l2_vp9_fw_update_probs(&vp9_ctx->probability_tables, prob_updates, dec_params);
+
+ return 0;
+}
+
+static int rkvdec_vp9_run(struct rkvdec_ctx *ctx)
+{
+ struct rkvdec_dev *rkvdec = ctx->dev;
+ struct rkvdec_vp9_run run = { };
+ int ret;
+
+ ret = rkvdec_vp9_run_preamble(ctx, &run);
+ if (ret) {
+ rkvdec_run_postamble(ctx, &run.base);
+ return ret;
+ }
+
+ /* Prepare probs. */
+ init_probs(ctx, &run);
+
+ /* Configure hardware registers. */
+ config_registers(ctx, &run);
+
+ rkvdec_run_postamble(ctx, &run.base);
+
+ schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000));
+
+ writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
+ writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
+
+ writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
+ /* Start decoding! */
+ writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E |
+ RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E,
+ rkvdec->regs + RKVDEC_REG_INTERRUPT);
+
+ return 0;
+}
+
+#define copy_tx_and_skip(p1, p2) \
+do { \
+ memcpy((p1)->tx8, (p2)->tx8, sizeof((p1)->tx8)); \
+ memcpy((p1)->tx16, (p2)->tx16, sizeof((p1)->tx16)); \
+ memcpy((p1)->tx32, (p2)->tx32, sizeof((p1)->tx32)); \
+ memcpy((p1)->skip, (p2)->skip, sizeof((p1)->skip)); \
+} while (0)
+
+static void rkvdec_vp9_done(struct rkvdec_ctx *ctx,
+ struct vb2_v4l2_buffer *src_buf,
+ struct vb2_v4l2_buffer *dst_buf,
+ enum vb2_buffer_state result)
+{
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ unsigned int fctx_idx;
+
+ /* v4l2-specific stuff */
+ if (result == VB2_BUF_STATE_ERROR)
+ goto out_update_last;
+
+ /*
+ * vp9 stuff
+ *
+ * 6.1.2 refresh_probs()
+ *
+ * In the spec a complementary condition goes last in 6.1.2 refresh_probs(),
+ * but it makes no sense to perform all the activities from the first "if"
+ * there if we actually are not refreshing the frame context. On top of that,
+ * because of 6.2 uncompressed_header() whenever error_resilient_mode == 1,
+ * refresh_frame_context == 0. Consequently, if we don't jump to out_update_last
+ * it means error_resilient_mode must be 0.
+ */
+ if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX))
+ goto out_update_last;
+
+ fctx_idx = vp9_ctx->cur.frame_context_idx;
+
+ if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE)) {
+ /* error_resilient_mode == 0 && frame_parallel_decoding_mode == 0 */
+ struct v4l2_vp9_frame_context *probs = &vp9_ctx->probability_tables;
+ bool frame_is_intra = vp9_ctx->cur.flags &
+ (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY);
+ struct tx_and_skip {
+ u8 tx8[2][1];
+ u8 tx16[2][2];
+ u8 tx32[2][3];
+ u8 skip[3];
+ } _tx_skip, *tx_skip = &_tx_skip;
+ struct v4l2_vp9_frame_symbol_counts *counts;
+
+ /* buffer the forward-updated TX and skip probs */
+ if (frame_is_intra)
+ copy_tx_and_skip(tx_skip, probs);
+
+ /* 6.1.2 refresh_probs(): load_probs() and load_probs2() */
+ *probs = vp9_ctx->frame_context[fctx_idx];
+
+ /* if FrameIsIntra then undo the effect of load_probs2() */
+ if (frame_is_intra)
+ copy_tx_and_skip(probs, tx_skip);
+
+ counts = frame_is_intra ? &vp9_ctx->intra_cnts : &vp9_ctx->inter_cnts;
+ v4l2_vp9_adapt_coef_probs(probs, counts,
+ !vp9_ctx->last.valid ||
+ vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME,
+ frame_is_intra);
+ if (!frame_is_intra) {
+ const struct rkvdec_vp9_inter_frame_symbol_counts *inter_cnts;
+ u32 classes[2][11];
+ int i;
+
+ inter_cnts = vp9_ctx->count_tbl.cpu;
+ for (i = 0; i < ARRAY_SIZE(classes); ++i)
+ memcpy(classes[i], inter_cnts->classes[i], sizeof(classes[0]));
+ counts->classes = &classes;
+
+ /* load_probs2() already done */
+ v4l2_vp9_adapt_noncoef_probs(&vp9_ctx->probability_tables, counts,
+ vp9_ctx->cur.reference_mode,
+ vp9_ctx->cur.interpolation_filter,
+ vp9_ctx->cur.tx_mode, vp9_ctx->cur.flags);
+ }
+ }
+
+ /* 6.1.2 refresh_probs(): save_probs(fctx_idx) */
+ vp9_ctx->frame_context[fctx_idx] = vp9_ctx->probability_tables;
+
+out_update_last:
+ update_ctx_last_info(vp9_ctx);
+}
+
+static void rkvdec_init_v4l2_vp9_count_tbl(struct rkvdec_ctx *ctx)
+{
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ struct rkvdec_vp9_intra_frame_symbol_counts *intra_cnts = vp9_ctx->count_tbl.cpu;
+ struct rkvdec_vp9_inter_frame_symbol_counts *inter_cnts = vp9_ctx->count_tbl.cpu;
+ int i, j, k, l, m;
+
+ vp9_ctx->inter_cnts.partition = &inter_cnts->partition;
+ vp9_ctx->inter_cnts.skip = &inter_cnts->skip;
+ vp9_ctx->inter_cnts.intra_inter = &inter_cnts->inter;
+ vp9_ctx->inter_cnts.tx32p = &inter_cnts->tx32p;
+ vp9_ctx->inter_cnts.tx16p = &inter_cnts->tx16p;
+ vp9_ctx->inter_cnts.tx8p = &inter_cnts->tx8p;
+
+ vp9_ctx->intra_cnts.partition = (u32 (*)[16][4])(&intra_cnts->partition);
+ vp9_ctx->intra_cnts.skip = &intra_cnts->skip;
+ vp9_ctx->intra_cnts.intra_inter = &intra_cnts->intra;
+ vp9_ctx->intra_cnts.tx32p = &intra_cnts->tx32p;
+ vp9_ctx->intra_cnts.tx16p = &intra_cnts->tx16p;
+ vp9_ctx->intra_cnts.tx8p = &intra_cnts->tx8p;
+
+ vp9_ctx->inter_cnts.y_mode = &inter_cnts->y_mode;
+ vp9_ctx->inter_cnts.uv_mode = &inter_cnts->uv_mode;
+ vp9_ctx->inter_cnts.comp = &inter_cnts->comp;
+ vp9_ctx->inter_cnts.comp_ref = &inter_cnts->comp_ref;
+ vp9_ctx->inter_cnts.single_ref = &inter_cnts->single_ref;
+ vp9_ctx->inter_cnts.mv_mode = &inter_cnts->mv_mode;
+ vp9_ctx->inter_cnts.filter = &inter_cnts->filter;
+ vp9_ctx->inter_cnts.mv_joint = &inter_cnts->mv_joint;
+ vp9_ctx->inter_cnts.sign = &inter_cnts->sign;
+ /*
+ * rk hardware actually uses "u32 classes[2][11 + 1];"
+ * instead of "u32 classes[2][11];", so this must be explicitly
+ * copied into vp9_ctx->classes when passing the data to the
+ * vp9 library function
+ */
+ vp9_ctx->inter_cnts.class0 = &inter_cnts->class0;
+ vp9_ctx->inter_cnts.bits = &inter_cnts->bits;
+ vp9_ctx->inter_cnts.class0_fp = &inter_cnts->class0_fp;
+ vp9_ctx->inter_cnts.fp = &inter_cnts->fp;
+ vp9_ctx->inter_cnts.class0_hp = &inter_cnts->class0_hp;
+ vp9_ctx->inter_cnts.hp = &inter_cnts->hp;
+
+#define INNERMOST_LOOP \
+ do { \
+ for (m = 0; m < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0][0][0]); ++m) {\
+ vp9_ctx->inter_cnts.coeff[i][j][k][l][m] = \
+ &inter_cnts->ref_cnt[k][i][j][l][m].coeff; \
+ vp9_ctx->inter_cnts.eob[i][j][k][l][m][0] = \
+ &inter_cnts->ref_cnt[k][i][j][l][m].eob[0]; \
+ vp9_ctx->inter_cnts.eob[i][j][k][l][m][1] = \
+ &inter_cnts->ref_cnt[k][i][j][l][m].eob[1]; \
+ \
+ vp9_ctx->intra_cnts.coeff[i][j][k][l][m] = \
+ &intra_cnts->ref_cnt[k][i][j][l][m].coeff; \
+ vp9_ctx->intra_cnts.eob[i][j][k][l][m][0] = \
+ &intra_cnts->ref_cnt[k][i][j][l][m].eob[0]; \
+ vp9_ctx->intra_cnts.eob[i][j][k][l][m][1] = \
+ &intra_cnts->ref_cnt[k][i][j][l][m].eob[1]; \
+ } \
+ } while (0)
+
+ for (i = 0; i < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff); ++i)
+ for (j = 0; j < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0]); ++j)
+ for (k = 0; k < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0]); ++k)
+ for (l = 0; l < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0][0]); ++l)
+ INNERMOST_LOOP;
+#undef INNERMOST_LOOP
+}
+
+static int rkvdec_vp9_start(struct rkvdec_ctx *ctx)
+{
+ struct rkvdec_dev *rkvdec = ctx->dev;
+ struct rkvdec_vp9_priv_tbl *priv_tbl;
+ struct rkvdec_vp9_ctx *vp9_ctx;
+ unsigned char *count_tbl;
+ int ret;
+
+ vp9_ctx = kzalloc(sizeof(*vp9_ctx), GFP_KERNEL);
+ if (!vp9_ctx)
+ return -ENOMEM;
+
+ ctx->priv = vp9_ctx;
+
+ priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+ &vp9_ctx->priv_tbl.dma, GFP_KERNEL);
+ if (!priv_tbl) {
+ ret = -ENOMEM;
+ goto err_free_ctx;
+ }
+
+ vp9_ctx->priv_tbl.size = sizeof(*priv_tbl);
+ vp9_ctx->priv_tbl.cpu = priv_tbl;
+ memset(priv_tbl, 0, sizeof(*priv_tbl));
+
+ count_tbl = dma_alloc_coherent(rkvdec->dev, RKVDEC_VP9_COUNT_SIZE,
+ &vp9_ctx->count_tbl.dma, GFP_KERNEL);
+ if (!count_tbl) {
+ ret = -ENOMEM;
+ goto err_free_priv_tbl;
+ }
+
+ vp9_ctx->count_tbl.size = RKVDEC_VP9_COUNT_SIZE;
+ vp9_ctx->count_tbl.cpu = count_tbl;
+ memset(count_tbl, 0, sizeof(*count_tbl));
+ rkvdec_init_v4l2_vp9_count_tbl(ctx);
+
+ return 0;
+
+err_free_priv_tbl:
+ dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size,
+ vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma);
+
+err_free_ctx:
+ kfree(vp9_ctx);
+ return ret;
+}
+
+static void rkvdec_vp9_stop(struct rkvdec_ctx *ctx)
+{
+ struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+ struct rkvdec_dev *rkvdec = ctx->dev;
+
+ dma_free_coherent(rkvdec->dev, vp9_ctx->count_tbl.size,
+ vp9_ctx->count_tbl.cpu, vp9_ctx->count_tbl.dma);
+ dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size,
+ vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma);
+ kfree(vp9_ctx);
+}
+
+static int rkvdec_vp9_adjust_fmt(struct rkvdec_ctx *ctx,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
+
+ fmt->num_planes = 1;
+ if (!fmt->plane_fmt[0].sizeimage)
+ fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * 2;
+ return 0;
+}
+
+const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops = {
+ .adjust_fmt = rkvdec_vp9_adjust_fmt,
+ .start = rkvdec_vp9_start,
+ .stop = rkvdec_vp9_stop,
+ .run = rkvdec_vp9_run,
+ .done = rkvdec_vp9_done,
+};
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index 4fd4a2907da7..c0cf3488f970 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -99,10 +99,30 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
.num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
};
-static const u32 rkvdec_h264_decoded_fmts[] = {
+static const u32 rkvdec_h264_vp9_decoded_fmts[] = {
V4L2_PIX_FMT_NV12,
};
+static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
+ {
+ .cfg.id = V4L2_CID_STATELESS_VP9_FRAME,
+ },
+ {
+ .cfg.id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR,
+ },
+ {
+ .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+ .cfg.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+ .cfg.max = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+ .cfg.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+ },
+};
+
+static const struct rkvdec_ctrls rkvdec_vp9_ctrls = {
+ .ctrls = rkvdec_vp9_ctrl_descs,
+ .num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs),
+};
+
static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
{
.fourcc = V4L2_PIX_FMT_H264_SLICE,
@@ -116,8 +136,23 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
},
.ctrls = &rkvdec_h264_ctrls,
.ops = &rkvdec_h264_fmt_ops,
- .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
- .decoded_fmts = rkvdec_h264_decoded_fmts,
+ .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
+ .decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_VP9_FRAME,
+ .frmsize = {
+ .min_width = 64,
+ .max_width = 4096,
+ .step_width = 64,
+ .min_height = 64,
+ .max_height = 2304,
+ .step_height = 64,
+ },
+ .ctrls = &rkvdec_vp9_ctrls,
+ .ops = &rkvdec_vp9_fmt_ops,
+ .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
+ .decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
}
};
@@ -677,7 +712,7 @@ static void rkvdec_device_run(void *priv)
rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
}
-static struct v4l2_m2m_ops rkvdec_m2m_ops = {
+static const struct v4l2_m2m_ops rkvdec_m2m_ops = {
.device_run = rkvdec_device_run,
};
diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h
index 52ac3874c5e5..2f4ea1786b93 100644
--- a/drivers/staging/media/rkvdec/rkvdec.h
+++ b/drivers/staging/media/rkvdec/rkvdec.h
@@ -42,14 +42,18 @@ struct rkvdec_run {
struct rkvdec_vp9_decoded_buffer_info {
/* Info needed when the decoded frame serves as a reference frame. */
- u16 width;
- u16 height;
- u32 bit_depth : 4;
+ unsigned short width;
+ unsigned short height;
+ unsigned int bit_depth : 4;
};
struct rkvdec_decoded_buffer {
/* Must be the first field in this struct. */
struct v4l2_m2m_buffer base;
+
+ union {
+ struct rkvdec_vp9_decoded_buffer_info vp9;
+ };
};
static inline struct rkvdec_decoded_buffer *
@@ -116,4 +120,6 @@ void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
+extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
+
#endif /* RKVDEC_H_ */
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index c76fc97d97a0..4a4b714b0f26 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -580,6 +580,14 @@ static const struct cedrus_variant sun8i_r40_cedrus_variant = {
.mod_rate = 297000000,
};
+static const struct cedrus_variant sun20i_d1_cedrus_variant = {
+ .capabilities = CEDRUS_CAPABILITY_UNTILED |
+ CEDRUS_CAPABILITY_MPEG2_DEC |
+ CEDRUS_CAPABILITY_H264_DEC |
+ CEDRUS_CAPABILITY_H265_DEC,
+ .mod_rate = 432000000,
+};
+
static const struct cedrus_variant sun50i_a64_cedrus_variant = {
.capabilities = CEDRUS_CAPABILITY_UNTILED |
CEDRUS_CAPABILITY_MPEG2_DEC |
@@ -638,6 +646,10 @@ static const struct of_device_id cedrus_dt_match[] = {
.data = &sun8i_r40_cedrus_variant,
},
{
+ .compatible = "allwinner,sun20i-d1-video-engine",
+ .data = &sun20i_d1_cedrus_variant,
+ },
+ {
.compatible = "allwinner,sun50i-a64-video-engine",
.data = &sun50i_a64_cedrus_variant,
},
diff --git a/drivers/staging/media/tegra-vde/vde.c b/drivers/staging/media/tegra-vde/vde.c
index 859f60a70904..a8f1a024c343 100644
--- a/drivers/staging/media/tegra-vde/vde.c
+++ b/drivers/staging/media/tegra-vde/vde.c
@@ -85,6 +85,96 @@ static int tegra_vde_wait_mbe(struct tegra_vde *vde)
(tmp >= 0x10), 1, 100);
}
+static int tegra_vde_alloc_bo(struct tegra_vde *vde,
+ struct tegra_vde_bo **ret_bo,
+ enum dma_data_direction dma_dir,
+ size_t size)
+{
+ struct device *dev = vde->miscdev.parent;
+ struct tegra_vde_bo *bo;
+ int err;
+
+ bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+ if (!bo)
+ return -ENOMEM;
+
+ bo->vde = vde;
+ bo->size = size;
+ bo->dma_dir = dma_dir;
+ bo->dma_attrs = DMA_ATTR_WRITE_COMBINE |
+ DMA_ATTR_NO_KERNEL_MAPPING;
+
+ if (!vde->domain)
+ bo->dma_attrs |= DMA_ATTR_FORCE_CONTIGUOUS;
+
+ bo->dma_cookie = dma_alloc_attrs(dev, bo->size, &bo->dma_handle,
+ GFP_KERNEL, bo->dma_attrs);
+ if (!bo->dma_cookie) {
+ dev_err(dev, "Failed to allocate DMA buffer of size: %zu\n",
+ bo->size);
+ err = -ENOMEM;
+ goto free_bo;
+ }
+
+ err = dma_get_sgtable_attrs(dev, &bo->sgt, bo->dma_cookie,
+ bo->dma_handle, bo->size, bo->dma_attrs);
+ if (err) {
+ dev_err(dev, "Failed to get DMA buffer SG table: %d\n", err);
+ goto free_attrs;
+ }
+
+ err = dma_map_sgtable(dev, &bo->sgt, bo->dma_dir, bo->dma_attrs);
+ if (err) {
+ dev_err(dev, "Failed to map DMA buffer SG table: %d\n", err);
+ goto free_table;
+ }
+
+ if (vde->domain) {
+ err = tegra_vde_iommu_map(vde, &bo->sgt, &bo->iova, bo->size);
+ if (err) {
+ dev_err(dev, "Failed to map DMA buffer IOVA: %d\n", err);
+ goto unmap_sgtable;
+ }
+
+ bo->dma_addr = iova_dma_addr(&vde->iova, bo->iova);
+ } else {
+ bo->dma_addr = sg_dma_address(bo->sgt.sgl);
+ }
+
+ *ret_bo = bo;
+
+ return 0;
+
+unmap_sgtable:
+ dma_unmap_sgtable(dev, &bo->sgt, bo->dma_dir, bo->dma_attrs);
+free_table:
+ sg_free_table(&bo->sgt);
+free_attrs:
+ dma_free_attrs(dev, bo->size, bo->dma_cookie, bo->dma_handle,
+ bo->dma_attrs);
+free_bo:
+ kfree(bo);
+
+ return err;
+}
+
+static void tegra_vde_free_bo(struct tegra_vde_bo *bo)
+{
+ struct tegra_vde *vde = bo->vde;
+ struct device *dev = vde->miscdev.parent;
+
+ if (vde->domain)
+ tegra_vde_iommu_unmap(vde, bo->iova);
+
+ dma_unmap_sgtable(dev, &bo->sgt, bo->dma_dir, bo->dma_attrs);
+
+ sg_free_table(&bo->sgt);
+
+ dma_free_attrs(dev, bo->size, bo->dma_cookie, bo->dma_handle,
+ bo->dma_attrs);
+ kfree(bo);
+}
+
static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde,
unsigned int refs_nb,
bool setup_refs)
@@ -250,7 +340,7 @@ static void tegra_vde_setup_iram_tables(struct tegra_vde *vde,
value |= frame->frame_num;
} else {
aux_addr = 0x6ADEAD00;
- value = 0;
+ value = 0x3f;
}
tegra_vde_setup_iram_entry(vde, 0, i, value, aux_addr);
@@ -425,6 +515,9 @@ static int tegra_vde_setup_hw_context(struct tegra_vde *vde,
tegra_vde_writel(vde, bitstream_data_addr, vde->sxe, 0x6C);
+ if (vde->soc->supports_ref_pic_marking)
+ tegra_vde_writel(vde, vde->secure_bo->dma_addr, vde->sxe, 0x7c);
+
value = 0x10000005;
value |= ctx->pic_width_in_mbs << 11;
value |= ctx->pic_height_in_mbs << 3;
@@ -994,6 +1087,8 @@ static int tegra_vde_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, vde);
+ vde->soc = of_device_get_match_data(&pdev->dev);
+
vde->sxe = devm_platform_ioremap_resource_byname(pdev, "sxe");
if (IS_ERR(vde->sxe))
return PTR_ERR(vde->sxe);
@@ -1098,12 +1193,6 @@ static int tegra_vde_probe(struct platform_device *pdev)
goto err_gen_free;
}
- err = misc_register(&vde->miscdev);
- if (err) {
- dev_err(dev, "Failed to register misc device: %d\n", err);
- goto err_deinit_iommu;
- }
-
pm_runtime_enable(dev);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 300);
@@ -1119,15 +1208,26 @@ static int tegra_vde_probe(struct platform_device *pdev)
pm_runtime_put(dev);
+ err = tegra_vde_alloc_bo(vde, &vde->secure_bo, DMA_FROM_DEVICE, 4096);
+ if (err) {
+ dev_err(dev, "Failed to allocate secure BO: %d\n", err);
+ goto err_pm_runtime;
+ }
+
+ err = misc_register(&vde->miscdev);
+ if (err) {
+ dev_err(dev, "Failed to register misc device: %d\n", err);
+ goto err_free_secure_bo;
+ }
+
return 0;
+err_free_secure_bo:
+ tegra_vde_free_bo(vde->secure_bo);
err_pm_runtime:
- misc_deregister(&vde->miscdev);
-
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_disable(dev);
-err_deinit_iommu:
tegra_vde_iommu_deinit(vde);
err_gen_free:
@@ -1142,6 +1242,10 @@ static int tegra_vde_remove(struct platform_device *pdev)
struct tegra_vde *vde = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
+ misc_deregister(&vde->miscdev);
+
+ tegra_vde_free_bo(vde->secure_bo);
+
/*
* As it increments RPM usage_count even on errors, we don't need to
* check the returned code here.
@@ -1158,8 +1262,6 @@ static int tegra_vde_remove(struct platform_device *pdev)
pm_runtime_put_noidle(dev);
clk_disable_unprepare(vde->clk);
- misc_deregister(&vde->miscdev);
-
tegra_vde_dmabuf_cache_unmap_all(vde);
tegra_vde_iommu_deinit(vde);
@@ -1214,8 +1316,27 @@ static const struct dev_pm_ops tegra_vde_pm_ops = {
tegra_vde_pm_resume)
};
+static const struct tegra_vde_soc tegra124_vde_soc = {
+ .supports_ref_pic_marking = true,
+};
+
+static const struct tegra_vde_soc tegra114_vde_soc = {
+ .supports_ref_pic_marking = true,
+};
+
+static const struct tegra_vde_soc tegra30_vde_soc = {
+ .supports_ref_pic_marking = false,
+};
+
+static const struct tegra_vde_soc tegra20_vde_soc = {
+ .supports_ref_pic_marking = false,
+};
+
static const struct of_device_id tegra_vde_of_match[] = {
- { .compatible = "nvidia,tegra20-vde", },
+ { .compatible = "nvidia,tegra124-vde", .data = &tegra124_vde_soc },
+ { .compatible = "nvidia,tegra114-vde", .data = &tegra114_vde_soc },
+ { .compatible = "nvidia,tegra30-vde", .data = &tegra30_vde_soc },
+ { .compatible = "nvidia,tegra20-vde", .data = &tegra20_vde_soc },
{ },
};
MODULE_DEVICE_TABLE(of, tegra_vde_of_match);
diff --git a/drivers/staging/media/tegra-vde/vde.h b/drivers/staging/media/tegra-vde/vde.h
index 5561291b0c88..bbd42b8d9991 100644
--- a/drivers/staging/media/tegra-vde/vde.h
+++ b/drivers/staging/media/tegra-vde/vde.h
@@ -24,6 +24,22 @@ struct iommu_domain;
struct reset_control;
struct dma_buf_attachment;
+struct tegra_vde_soc {
+ bool supports_ref_pic_marking;
+};
+
+struct tegra_vde_bo {
+ struct iova *iova;
+ struct sg_table sgt;
+ struct tegra_vde *vde;
+ enum dma_data_direction dma_dir;
+ unsigned long dma_attrs;
+ dma_addr_t dma_handle;
+ dma_addr_t dma_addr;
+ void *dma_cookie;
+ size_t size;
+};
+
struct tegra_vde {
void __iomem *sxe;
void __iomem *bsev;
@@ -48,6 +64,8 @@ struct tegra_vde {
struct iova_domain iova;
struct iova *iova_resv_static_addresses;
struct iova *iova_resv_last_page;
+ const struct tegra_vde_soc *soc;
+ struct tegra_vde_bo *secure_bo;
dma_addr_t iram_lists_addr;
u32 *iram;
};
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 480f9207a4c6..2f93ecf05dac 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -202,7 +202,8 @@ struct acpi_device_flags {
u32 coherent_dma:1;
u32 cca_seen:1;
u32 enumeration_by_parent:1;
- u32 reserved:19;
+ u32 honor_deps:1;
+ u32 reserved:18;
};
/* File System */
@@ -285,6 +286,7 @@ struct acpi_dep_data {
struct list_head node;
acpi_handle supplier;
acpi_handle consumer;
+ bool honor_dep;
};
/* Performance Management */
@@ -693,6 +695,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
+bool acpi_dev_ready_for_enumeration(const struct acpi_device *device);
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
struct acpi_device *
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 16119ac1aa97..7d4f52ceb7b5 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -1025,8 +1025,9 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
struct acpi_resource_i2c_serialbus **i2c);
int i2c_acpi_client_count(struct acpi_device *adev);
u32 i2c_acpi_find_bus_speed(struct device *dev);
-struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
- struct i2c_board_info *info);
+struct i2c_client *i2c_acpi_new_device_by_fwnode(struct fwnode_handle *fwnode,
+ int index,
+ struct i2c_board_info *info);
struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
bool i2c_acpi_waive_d0_probe(struct device *dev);
#else
@@ -1043,8 +1044,9 @@ static inline u32 i2c_acpi_find_bus_speed(struct device *dev)
{
return 0;
}
-static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
- int index, struct i2c_board_info *info)
+static inline struct i2c_client *i2c_acpi_new_device_by_fwnode(
+ struct fwnode_handle *fwnode, int index,
+ struct i2c_board_info *info)
{
return ERR_PTR(-ENODEV);
}
@@ -1058,4 +1060,11 @@ static inline bool i2c_acpi_waive_d0_probe(struct device *dev)
}
#endif /* CONFIG_ACPI */
+static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
+ int index,
+ struct i2c_board_info *info)
+{
+ return i2c_acpi_new_device_by_fwnode(dev_fwnode(dev), index, info);
+}
+
#endif /* _LINUX_I2C_H */
diff --git a/include/linux/platform_data/tps68470.h b/include/linux/platform_data/tps68470.h
new file mode 100644
index 000000000000..126d082c3f2e
--- /dev/null
+++ b/include/linux/platform_data/tps68470.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * TI TPS68470 PMIC platform data definition.
+ *
+ * Copyright (c) 2021 Red Hat Inc.
+ *
+ * Red Hat authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+#ifndef __PDATA_TPS68470_H
+#define __PDATA_TPS68470_H
+
+enum tps68470_regulators {
+ TPS68470_CORE,
+ TPS68470_ANA,
+ TPS68470_VCM,
+ TPS68470_VIO,
+ TPS68470_VSIO,
+ TPS68470_AUX1,
+ TPS68470_AUX2,
+ TPS68470_NUM_REGULATORS
+};
+
+struct regulator_init_data;
+
+struct tps68470_regulator_platform_data {
+ const struct regulator_init_data *reg_init_data[TPS68470_NUM_REGULATORS];
+};
+
+struct tps68470_clk_platform_data {
+ const char *consumer_dev_name;
+ const char *consumer_con_id;
+};
+
+#endif
diff --git a/include/media/cec.h b/include/media/cec.h
index 208c9613c07e..77346f757036 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -26,13 +26,17 @@
* @dev: cec device
* @cdev: cec character device
* @minor: device node minor number
+ * @lock: lock to serialize open/release and registration
* @registered: the device was correctly registered
* @unregistered: the device was unregistered
+ * @lock_fhs: lock to control access to @fhs
* @fhs: the list of open filehandles (cec_fh)
- * @lock: lock to control access to this structure
*
* This structure represents a cec-related device node.
*
+ * To add or remove filehandles from @fhs the @lock must be taken first,
+ * followed by @lock_fhs. It is safe to access @fhs if either lock is held.
+ *
* The @parent is a physical device. It must be set by core or device drivers
* before registering the node.
*/
@@ -43,10 +47,13 @@ struct cec_devnode {
/* device info */
int minor;
+ /* serialize open/release and registration */
+ struct mutex lock;
bool registered;
bool unregistered;
+ /* protect access to fhs */
+ struct mutex lock_fhs;
struct list_head fhs;
- struct mutex lock;
};
struct cec_adapter;
diff --git a/include/media/dmxdev.h b/include/media/dmxdev.h
index baafa3b8aca4..63219a699370 100644
--- a/include/media/dmxdev.h
+++ b/include/media/dmxdev.h
@@ -21,7 +21,6 @@
#include <linux/types.h>
#include <linux/spinlock.h>
-#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/wait.h>
diff --git a/include/media/dvb_frontend.h b/include/media/dvb_frontend.h
index 0d76fa4551b3..e7c44870f20d 100644
--- a/include/media/dvb_frontend.h
+++ b/include/media/dvb_frontend.h
@@ -364,6 +364,10 @@ struct dvb_frontend_internal_info {
* allocated by the driver.
* @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep.
+ * @suspend: callback function used to inform that the Kernel will
+ * suspend.
+ * @resume: callback function used to inform that the Kernel is
+ * resuming from suspend.
* @write: callback function used by some demod legacy drivers to
* allow other drivers to write data into their registers.
* Should not be used on new drivers.
@@ -443,6 +447,8 @@ struct dvb_frontend_ops {
int (*init)(struct dvb_frontend* fe);
int (*sleep)(struct dvb_frontend* fe);
+ int (*suspend)(struct dvb_frontend *fe);
+ int (*resume)(struct dvb_frontend *fe);
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
@@ -755,7 +761,8 @@ void dvb_frontend_detach(struct dvb_frontend *fe);
* &dvb_frontend_ops.tuner_ops.suspend\(\) is available, it calls it. Otherwise,
* it will call &dvb_frontend_ops.tuner_ops.sleep\(\), if available.
*
- * It will also call &dvb_frontend_ops.sleep\(\) to put the demod to suspend.
+ * It will also call &dvb_frontend_ops.suspend\(\) to put the demod to suspend,
+ * if available. Otherwise it will call &dvb_frontend_ops.sleep\(\).
*
* The drivers should also call dvb_frontend_suspend\(\) as part of their
* handler for the &device_driver.suspend\(\).
@@ -769,7 +776,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe);
*
* This function resumes the usual operation of the tuner after resume.
*
- * In order to resume the frontend, it calls the demod &dvb_frontend_ops.init\(\).
+ * In order to resume the frontend, it calls the demod
+ * &dvb_frontend_ops.resume\(\) if available. Otherwise it calls demod
+ * &dvb_frontend_ops.init\(\).
*
* If &dvb_frontend_ops.tuner_ops.resume\(\) is available, It, it calls it.
* Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available.
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 8c5b7978e1d9..ab9d3b7cd799 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -59,7 +59,6 @@ enum rc_filter_type {
* @rc: rcdev for this lirc chardev
* @carrier_low: when setting the carrier range, first the low end must be
* set with an ioctl and then the high end with another ioctl
- * @send_timeout_reports: report timeouts in lirc raw IR.
* @rawir: queue for incoming raw IR
* @scancodes: queue for incoming decoded scancodes
* @wait_poll: poll struct for lirc device
@@ -72,7 +71,6 @@ struct lirc_fh {
struct list_head list;
struct rc_dev *rc;
int carrier_low;
- bool send_timeout_reports;
DECLARE_KFIFO_PTR(rawir, unsigned int);
DECLARE_KFIFO_PTR(scancodes, struct lirc_scancode);
wait_queue_head_t wait_poll;
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 575b59fbac77..b3ce438f1329 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -50,6 +50,8 @@ struct video_device;
* @p_h264_decode_params: Pointer to a struct v4l2_ctrl_h264_decode_params.
* @p_h264_pred_weights: Pointer to a struct v4l2_ctrl_h264_pred_weights.
* @p_vp8_frame: Pointer to a VP8 frame params structure.
+ * @p_vp9_compressed_hdr_probs: Pointer to a VP9 frame compressed header probs structure.
+ * @p_vp9_frame: Pointer to a VP9 frame params structure.
* @p_hevc_sps: Pointer to an HEVC sequence parameter set structure.
* @p_hevc_pps: Pointer to an HEVC picture parameter set structure.
* @p_hevc_slice_params: Pointer to an HEVC slice parameters structure.
@@ -80,6 +82,8 @@ union v4l2_ctrl_ptr {
struct v4l2_ctrl_hevc_sps *p_hevc_sps;
struct v4l2_ctrl_hevc_pps *p_hevc_pps;
struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
+ struct v4l2_ctrl_vp9_compressed_hdr *p_vp9_compressed_hdr_probs;
+ struct v4l2_ctrl_vp9_frame *p_vp9_frame;
struct v4l2_ctrl_hdr10_cll_info *p_hdr10_cll;
struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
struct v4l2_area *p_area;
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 5a91b548ecc0..fdbd5257e020 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -495,6 +495,11 @@ __poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
struct vm_area_struct *vma);
+#ifndef CONFIG_MMU
+unsigned long v4l2_m2m_get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags);
+#endif
/**
* v4l2_m2m_init() - initialize per-driver m2m data
*
diff --git a/include/media/v4l2-vp9.h b/include/media/v4l2-vp9.h
new file mode 100644
index 000000000000..05478ad6d4ab
--- /dev/null
+++ b/include/media/v4l2-vp9.h
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Helper functions for vp9 codecs.
+ *
+ * Copyright (c) 2021 Collabora, Ltd.
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+ */
+
+#ifndef _MEDIA_V4L2_VP9_H
+#define _MEDIA_V4L2_VP9_H
+
+#include <media/v4l2-ctrls.h>
+
+/**
+ * struct v4l2_vp9_frame_mv_context - motion vector-related probabilities
+ *
+ * @joint: motion vector joint probabilities.
+ * @sign: motion vector sign probabilities.
+ * @classes: motion vector class probabilities.
+ * @class0_bit: motion vector class0 bit probabilities.
+ * @bits: motion vector bits probabilities.
+ * @class0_fr: motion vector class0 fractional bit probabilities.
+ * @fr: motion vector fractional bit probabilities.
+ * @class0_hp: motion vector class0 high precision fractional bit probabilities.
+ * @hp: motion vector high precision fractional bit probabilities.
+ *
+ * A member of v4l2_vp9_frame_context.
+ */
+struct v4l2_vp9_frame_mv_context {
+ u8 joint[3];
+ u8 sign[2];
+ u8 classes[2][10];
+ u8 class0_bit[2];
+ u8 bits[2][10];
+ u8 class0_fr[2][2][3];
+ u8 fr[2][3];
+ u8 class0_hp[2];
+ u8 hp[2];
+};
+
+/**
+ * struct v4l2_vp9_frame_context - frame probabilities, including motion-vector related
+ *
+ * @tx8: TX 8x8 probabilities.
+ * @tx16: TX 16x16 probabilities.
+ * @tx32: TX 32x32 probabilities.
+ * @coef: coefficient probabilities.
+ * @skip: skip probabilities.
+ * @inter_mode: inter mode probabilities.
+ * @interp_filter: interpolation filter probabilities.
+ * @is_inter: is inter-block probabilities.
+ * @comp_mode: compound prediction mode probabilities.
+ * @single_ref: single ref probabilities.
+ * @comp_ref: compound ref probabilities.
+ * @y_mode: Y prediction mode probabilities.
+ * @uv_mode: UV prediction mode probabilities.
+ * @partition: partition probabilities.
+ * @mv: motion vector probabilities.
+ *
+ * Drivers which need to keep track of frame context(s) can use this struct.
+ * The members correspond to probability tables, which are specified only implicitly in the
+ * vp9 spec. Section 10.5 "Default probability tables" contains all the types of involved
+ * tables, i.e. the actual tables are of the same kind, and when they are reset (which is
+ * mandated by the spec sometimes) they are overwritten with values from the default tables.
+ */
+struct v4l2_vp9_frame_context {
+ u8 tx8[2][1];
+ u8 tx16[2][2];
+ u8 tx32[2][3];
+ u8 coef[4][2][2][6][6][3];
+ u8 skip[3];
+ u8 inter_mode[7][3];
+ u8 interp_filter[4][2];
+ u8 is_inter[4];
+ u8 comp_mode[5];
+ u8 single_ref[5][2];
+ u8 comp_ref[5];
+ u8 y_mode[4][9];
+ u8 uv_mode[10][9];
+ u8 partition[16][3];
+
+ struct v4l2_vp9_frame_mv_context mv;
+};
+
+/**
+ * struct v4l2_vp9_frame_symbol_counts - pointers to arrays of symbol counts
+ *
+ * @partition: partition counts.
+ * @skip: skip counts.
+ * @intra_inter: is inter-block counts.
+ * @tx32p: TX32 counts.
+ * @tx16p: TX16 counts.
+ * @tx8p: TX8 counts.
+ * @y_mode: Y prediction mode counts.
+ * @uv_mode: UV prediction mode counts.
+ * @comp: compound prediction mode counts.
+ * @comp_ref: compound ref counts.
+ * @single_ref: single ref counts.
+ * @mv_mode: inter mode counts.
+ * @filter: interpolation filter counts.
+ * @mv_joint: motion vector joint counts.
+ * @sign: motion vector sign counts.
+ * @classes: motion vector class counts.
+ * @class0: motion vector class0 bit counts.
+ * @bits: motion vector bits counts.
+ * @class0_fp: motion vector class0 fractional bit counts.
+ * @fp: motion vector fractional bit counts.
+ * @class0_hp: motion vector class0 high precision fractional bit counts.
+ * @hp: motion vector high precision fractional bit counts.
+ * @coeff: coefficient counts.
+ * @eob: eob counts
+ *
+ * The fields correspond to what is specified in section 8.3 "Clear counts process" of the spec.
+ * Different pieces of hardware can report the counts in different order, so we cannot rely on
+ * simply overlaying a struct on a relevant block of memory. Instead we provide pointers to
+ * arrays or array of pointers to arrays in case of coeff, or array of pointers for eob.
+ */
+struct v4l2_vp9_frame_symbol_counts {
+ u32 (*partition)[16][4];
+ u32 (*skip)[3][2];
+ u32 (*intra_inter)[4][2];
+ u32 (*tx32p)[2][4];
+ u32 (*tx16p)[2][4];
+ u32 (*tx8p)[2][2];
+ u32 (*y_mode)[4][10];
+ u32 (*uv_mode)[10][10];
+ u32 (*comp)[5][2];
+ u32 (*comp_ref)[5][2];
+ u32 (*single_ref)[5][2][2];
+ u32 (*mv_mode)[7][4];
+ u32 (*filter)[4][3];
+ u32 (*mv_joint)[4];
+ u32 (*sign)[2][2];
+ u32 (*classes)[2][11];
+ u32 (*class0)[2][2];
+ u32 (*bits)[2][10][2];
+ u32 (*class0_fp)[2][2][4];
+ u32 (*fp)[2][4];
+ u32 (*class0_hp)[2][2];
+ u32 (*hp)[2][2];
+ u32 (*coeff[4][2][2][6][6])[3];
+ u32 *eob[4][2][2][6][6][2];
+};
+
+extern const u8 v4l2_vp9_kf_y_mode_prob[10][10][9]; /* Section 10.4 of the spec */
+extern const u8 v4l2_vp9_kf_partition_probs[16][3]; /* Section 10.4 of the spec */
+extern const u8 v4l2_vp9_kf_uv_mode_prob[10][9]; /* Section 10.4 of the spec */
+extern const struct v4l2_vp9_frame_context v4l2_vp9_default_probs; /* Section 10.5 of the spec */
+
+/**
+ * v4l2_vp9_fw_update_probs() - Perform forward update of vp9 probabilities
+ *
+ * @probs: current probabilities values
+ * @deltas: delta values from compressed header
+ * @dec_params: vp9 frame decoding parameters
+ *
+ * This function performs forward updates of probabilities for the vp9 boolean decoder.
+ * The frame header can contain a directive to update the probabilities (deltas), if so, then
+ * the deltas are provided in the header, too. The userspace parses those and passes the said
+ * deltas struct to the kernel.
+ */
+void v4l2_vp9_fw_update_probs(struct v4l2_vp9_frame_context *probs,
+ const struct v4l2_ctrl_vp9_compressed_hdr *deltas,
+ const struct v4l2_ctrl_vp9_frame *dec_params);
+
+/**
+ * v4l2_vp9_reset_frame_ctx() - Reset appropriate frame context
+ *
+ * @dec_params: vp9 frame decoding parameters
+ * @frame_context: array of the 4 frame contexts
+ *
+ * This function resets appropriate frame contexts, based on what's in dec_params.
+ *
+ * Returns the frame context index after the update, which might be reset to zero if
+ * mandated by the spec.
+ */
+u8 v4l2_vp9_reset_frame_ctx(const struct v4l2_ctrl_vp9_frame *dec_params,
+ struct v4l2_vp9_frame_context *frame_context);
+
+/**
+ * v4l2_vp9_adapt_coef_probs() - Perform backward update of vp9 coefficients probabilities
+ *
+ * @probs: current probabilities values
+ * @counts: values of symbol counts after the current frame has been decoded
+ * @use_128: flag to request that 128 is used as update factor if true, otherwise 112 is used
+ * @frame_is_intra: flag indicating that FrameIsIntra is true
+ *
+ * This function performs backward updates of coefficients probabilities for the vp9 boolean
+ * decoder. After a frame has been decoded the counts of how many times a given symbol has
+ * occurred are known and are used to update the probability of each symbol.
+ */
+void v4l2_vp9_adapt_coef_probs(struct v4l2_vp9_frame_context *probs,
+ struct v4l2_vp9_frame_symbol_counts *counts,
+ bool use_128,
+ bool frame_is_intra);
+
+/**
+ * v4l2_vp9_adapt_noncoef_probs() - Perform backward update of vp9 non-coefficients probabilities
+ *
+ * @probs: current probabilities values
+ * @counts: values of symbol counts after the current frame has been decoded
+ * @reference_mode: specifies the type of inter prediction to be used. See
+ * &v4l2_vp9_reference_mode for more details
+ * @interpolation_filter: specifies the filter selection used for performing inter prediction.
+ * See &v4l2_vp9_interpolation_filter for more details
+ * @tx_mode: specifies the TX mode. See &v4l2_vp9_tx_mode for more details
+ * @flags: combination of V4L2_VP9_FRAME_FLAG_* flags
+ *
+ * This function performs backward updates of non-coefficients probabilities for the vp9 boolean
+ * decoder. After a frame has been decoded the counts of how many times a given symbol has
+ * occurred are known and are used to update the probability of each symbol.
+ */
+void v4l2_vp9_adapt_noncoef_probs(struct v4l2_vp9_frame_context *probs,
+ struct v4l2_vp9_frame_symbol_counts *counts,
+ u8 reference_mode, u8 interpolation_filter, u8 tx_mode,
+ u32 flags);
+
+/**
+ * v4l2_vp9_seg_feat_enabled() - Check if a segmentation feature is enabled
+ *
+ * @feature_enabled: array of 8-bit flags (for all segments)
+ * @feature: id of the feature to check
+ * @segid: id of the segment to look up
+ *
+ * This function returns true if a given feature is active in a given segment.
+ */
+bool
+v4l2_vp9_seg_feat_enabled(const u8 *feature_enabled,
+ unsigned int feature,
+ unsigned int segid);
+
+#endif /* _MEDIA_V4L2_VP9_H */
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 2467284e5f26..5468b633b9d2 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -1155,8 +1155,15 @@ static inline void *vb2_get_drv_priv(struct vb2_queue *q)
static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
unsigned int plane_no, unsigned long size)
{
- if (plane_no < vb->num_planes)
+ /*
+ * size must never be larger than the buffer length, so
+ * warn and clamp to the buffer length if that's the case.
+ */
+ if (plane_no < vb->num_planes) {
+ if (WARN_ON_ONCE(size > vb->planes[plane_no].length))
+ size = vb->planes[plane_no].length;
vb->planes[plane_no].bytesused = size;
+ }
}
/**
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 5fea5feb0412..c8e0f84d204d 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -128,6 +128,7 @@ enum v4l2_colorfx {
V4L2_COLORFX_SOLARIZATION = 13,
V4L2_COLORFX_ANTIQUE = 14,
V4L2_COLORFX_SET_CBCR = 15,
+ V4L2_COLORFX_SET_RGB = 16,
};
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
@@ -145,9 +146,10 @@ enum v4l2_colorfx {
#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41)
#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
+#define V4L2_CID_COLORFX_RGB (V4L2_CID_BASE+43)
/* last CID + 1 */
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+44)
/* USER-class private control IDs */
@@ -2016,6 +2018,290 @@ struct v4l2_ctrl_hdr10_mastering_display {
__u32 min_display_mastering_luminance;
};
+/* Stateless VP9 controls */
+
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED 0x1
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE 0x2
+
+/**
+ * struct v4l2_vp9_loop_filter - VP9 loop filter parameters
+ *
+ * @ref_deltas: contains the adjustment needed for the filter level based on the
+ * chosen reference frame. If this syntax element is not present in the bitstream,
+ * users should pass its last value.
+ * @mode_deltas: contains the adjustment needed for the filter level based on the
+ * chosen mode. If this syntax element is not present in the bitstream, users should
+ * pass its last value.
+ * @level: indicates the loop filter strength.
+ * @sharpness: indicates the sharpness level.
+ * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_{} flags.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * This structure contains all loop filter related parameters. See sections
+ * '7.2.8 Loop filter semantics' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_loop_filter {
+ __s8 ref_deltas[4];
+ __s8 mode_deltas[2];
+ __u8 level;
+ __u8 sharpness;
+ __u8 flags;
+ __u8 reserved[7];
+};
+
+/**
+ * struct v4l2_vp9_quantization - VP9 quantization parameters
+ *
+ * @base_q_idx: indicates the base frame qindex.
+ * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx.
+ * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx.
+ * @delta_q_uv_ac: indicates the UV AC quantizer relative to base_q_idx.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.9 Quantization params
+ * syntax' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_quantization {
+ __u8 base_q_idx;
+ __s8 delta_q_y_dc;
+ __s8 delta_q_uv_dc;
+ __s8 delta_q_uv_ac;
+ __u8 reserved[4];
+};
+
+#define V4L2_VP9_SEGMENTATION_FLAG_ENABLED 0x01
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP 0x02
+#define V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE 0x04
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA 0x08
+#define V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE 0x10
+
+#define V4L2_VP9_SEG_LVL_ALT_Q 0
+#define V4L2_VP9_SEG_LVL_ALT_L 1
+#define V4L2_VP9_SEG_LVL_REF_FRAME 2
+#define V4L2_VP9_SEG_LVL_SKIP 3
+#define V4L2_VP9_SEG_LVL_MAX 4
+
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id) (1 << (id))
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK 0xf
+
+/**
+ * struct v4l2_vp9_segmentation - VP9 segmentation parameters
+ *
+ * @feature_data: data attached to each feature. Data entry is only valid if
+ * the feature is enabled. The array shall be indexed with segment number as
+ * the first dimension (0..7) and one of V4L2_VP9_SEG_{} as the second dimension.
+ * @feature_enabled: bitmask defining which features are enabled in each segment.
+ * The value for each segment is a combination of V4L2_VP9_SEGMENT_FEATURE_ENABLED(id)
+ * values where id is one of V4L2_VP9_SEG_LVL_{}.
+ * @tree_probs: specifies the probability values to be used when decoding a
+ * Segment-ID. See '5.15. Segmentation map' section of the VP9 specification
+ * for more details.
+ * @pred_probs: specifies the probability values to be used when decoding a
+ * Predicted-Segment-ID. See '6.4.14. Get segment id syntax' section of :ref:`vp9`
+ * for more details.
+ * @flags: combination of V4L2_VP9_SEGMENTATION_FLAG_{} flags.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.10 Segmentation params syntax' of
+ * the VP9 specification for more details.
+ */
+struct v4l2_vp9_segmentation {
+ __s16 feature_data[8][4];
+ __u8 feature_enabled[8];
+ __u8 tree_probs[7];
+ __u8 pred_probs[3];
+ __u8 flags;
+ __u8 reserved[5];
+};
+
+#define V4L2_VP9_FRAME_FLAG_KEY_FRAME 0x001
+#define V4L2_VP9_FRAME_FLAG_SHOW_FRAME 0x002
+#define V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT 0x004
+#define V4L2_VP9_FRAME_FLAG_INTRA_ONLY 0x008
+#define V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV 0x010
+#define V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX 0x020
+#define V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE 0x040
+#define V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING 0x080
+#define V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING 0x100
+#define V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING 0x200
+
+#define V4L2_VP9_SIGN_BIAS_LAST 0x1
+#define V4L2_VP9_SIGN_BIAS_GOLDEN 0x2
+#define V4L2_VP9_SIGN_BIAS_ALT 0x4
+
+#define V4L2_VP9_RESET_FRAME_CTX_NONE 0
+#define V4L2_VP9_RESET_FRAME_CTX_SPEC 1
+#define V4L2_VP9_RESET_FRAME_CTX_ALL 2
+
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP 0
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH 1
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP 2
+#define V4L2_VP9_INTERP_FILTER_BILINEAR 3
+#define V4L2_VP9_INTERP_FILTER_SWITCHABLE 4
+
+#define V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE 0
+#define V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE 1
+#define V4L2_VP9_REFERENCE_MODE_SELECT 2
+
+#define V4L2_VP9_PROFILE_MAX 3
+
+#define V4L2_CID_STATELESS_VP9_FRAME (V4L2_CID_CODEC_STATELESS_BASE + 300)
+/**
+ * struct v4l2_ctrl_vp9_frame - VP9 frame decoding control
+ *
+ * @lf: loop filter parameters. See &v4l2_vp9_loop_filter for more details.
+ * @quant: quantization parameters. See &v4l2_vp9_quantization for more details.
+ * @seg: segmentation parameters. See &v4l2_vp9_segmentation for more details.
+ * @flags: combination of V4L2_VP9_FRAME_FLAG_{} flags.
+ * @compressed_header_size: compressed header size in bytes.
+ * @uncompressed_header_size: uncompressed header size in bytes.
+ * @frame_width_minus_1: add 1 to it and you'll get the frame width expressed in pixels.
+ * @frame_height_minus_1: add 1 to it and you'll get the frame height expressed in pixels.
+ * @render_width_minus_1: add 1 to it and you'll get the expected render width expressed in
+ * pixels. This is not used during the decoding process but might be used by HW scalers
+ * to prepare a frame that's ready for scanout.
+ * @render_height_minus_1: add 1 to it and you'll get the expected render height expressed in
+ * pixels. This is not used during the decoding process but might be used by HW scalers
+ * to prepare a frame that's ready for scanout.
+ * @last_frame_ts: "last" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @golden_frame_ts: "golden" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @alt_frame_ts: "alt" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @ref_frame_sign_bias: a bitfield specifying whether the sign bias is set for a given
+ * reference frame. Either of V4L2_VP9_SIGN_BIAS_{}.
+ * @reset_frame_context: specifies whether the frame context should be reset to default values.
+ * Either of V4L2_VP9_RESET_FRAME_CTX_{}.
+ * @frame_context_idx: frame context that should be used/updated.
+ * @profile: VP9 profile. Can be 0, 1, 2 or 3.
+ * @bit_depth: bits per components. Can be 8, 10 or 12. Note that not all profiles support
+ * 10 and/or 12 bits depths.
+ * @interpolation_filter: specifies the filter selection used for performing inter prediction.
+ * Set to one of V4L2_VP9_INTERP_FILTER_{}.
+ * @tile_cols_log2: specifies the base 2 logarithm of the width of each tile (where the width
+ * is measured in units of 8x8 blocks). Shall be less than or equal to 6.
+ * @tile_rows_log2: specifies the base 2 logarithm of the height of each tile (where the height
+ * is measured in units of 8x8 blocks).
+ * @reference_mode: specifies the type of inter prediction to be used.
+ * Set to one of V4L2_VP9_REFERENCE_MODE_{}.
+ * @reserved: padding field. Should be zeroed by applications.
+ */
+struct v4l2_ctrl_vp9_frame {
+ struct v4l2_vp9_loop_filter lf;
+ struct v4l2_vp9_quantization quant;
+ struct v4l2_vp9_segmentation seg;
+ __u32 flags;
+ __u16 compressed_header_size;
+ __u16 uncompressed_header_size;
+ __u16 frame_width_minus_1;
+ __u16 frame_height_minus_1;
+ __u16 render_width_minus_1;
+ __u16 render_height_minus_1;
+ __u64 last_frame_ts;
+ __u64 golden_frame_ts;
+ __u64 alt_frame_ts;
+ __u8 ref_frame_sign_bias;
+ __u8 reset_frame_context;
+ __u8 frame_context_idx;
+ __u8 profile;
+ __u8 bit_depth;
+ __u8 interpolation_filter;
+ __u8 tile_cols_log2;
+ __u8 tile_rows_log2;
+ __u8 reference_mode;
+ __u8 reserved[7];
+};
+
+#define V4L2_VP9_NUM_FRAME_CTX 4
+
+/**
+ * struct v4l2_vp9_mv_probs - VP9 Motion vector probability updates
+ * @joint: motion vector joint probability updates.
+ * @sign: motion vector sign probability updates.
+ * @classes: motion vector class probability updates.
+ * @class0_bit: motion vector class0 bit probability updates.
+ * @bits: motion vector bits probability updates.
+ * @class0_fr: motion vector class0 fractional bit probability updates.
+ * @fr: motion vector fractional bit probability updates.
+ * @class0_hp: motion vector class0 high precision fractional bit probability updates.
+ * @hp: motion vector high precision fractional bit probability updates.
+ *
+ * This structure contains new values of motion vector probabilities.
+ * A value of zero in an array element means there is no update of the relevant probability.
+ * See `struct v4l2_vp9_prob_updates` for details.
+ */
+struct v4l2_vp9_mv_probs {
+ __u8 joint[3];
+ __u8 sign[2];
+ __u8 classes[2][10];
+ __u8 class0_bit[2];
+ __u8 bits[2][10];
+ __u8 class0_fr[2][2][3];
+ __u8 fr[2][3];
+ __u8 class0_hp[2];
+ __u8 hp[2];
+};
+
+#define V4L2_CID_STATELESS_VP9_COMPRESSED_HDR (V4L2_CID_CODEC_STATELESS_BASE + 301)
+
+#define V4L2_VP9_TX_MODE_ONLY_4X4 0
+#define V4L2_VP9_TX_MODE_ALLOW_8X8 1
+#define V4L2_VP9_TX_MODE_ALLOW_16X16 2
+#define V4L2_VP9_TX_MODE_ALLOW_32X32 3
+#define V4L2_VP9_TX_MODE_SELECT 4
+
+/**
+ * struct v4l2_ctrl_vp9_compressed_hdr - VP9 probability updates control
+ * @tx_mode: specifies the TX mode. Set to one of V4L2_VP9_TX_MODE_{}.
+ * @tx8: TX 8x8 probability updates.
+ * @tx16: TX 16x16 probability updates.
+ * @tx32: TX 32x32 probability updates.
+ * @coef: coefficient probability updates.
+ * @skip: skip probability updates.
+ * @inter_mode: inter mode probability updates.
+ * @interp_filter: interpolation filter probability updates.
+ * @is_inter: is inter-block probability updates.
+ * @comp_mode: compound prediction mode probability updates.
+ * @single_ref: single ref probability updates.
+ * @comp_ref: compound ref probability updates.
+ * @y_mode: Y prediction mode probability updates.
+ * @uv_mode: UV prediction mode probability updates.
+ * @partition: partition probability updates.
+ * @mv: motion vector probability updates.
+ *
+ * This structure holds the probabilities update as parsed in the compressed
+ * header (Spec 6.3). These values represent the value of probability update after
+ * being translated with inv_map_table[] (see 6.3.5). A value of zero in an array element
+ * means that there is no update of the relevant probability.
+ *
+ * This control is optional and needs to be used when dealing with the hardware which is
+ * not capable of parsing the compressed header itself. Only drivers which need it will
+ * implement it.
+ */
+struct v4l2_ctrl_vp9_compressed_hdr {
+ __u8 tx_mode;
+ __u8 tx8[2][1];
+ __u8 tx16[2][2];
+ __u8 tx32[2][3];
+ __u8 coef[4][2][2][6][6][3];
+ __u8 skip[3];
+ __u8 inter_mode[7][3];
+ __u8 interp_filter[4][2];
+ __u8 is_inter[4];
+ __u8 comp_mode[5];
+ __u8 single_ref[5][2];
+ __u8 comp_ref[5];
+ __u8 y_mode[4][9];
+ __u8 uv_mode[10][9];
+ __u8 partition[16][3];
+
+ struct v4l2_vp9_mv_probs mv;
+};
+
/* MPEG-compression definitions kept for backwards compatibility */
#ifndef __KERNEL__
#define V4L2_CTRL_CLASS_MPEG V4L2_CTRL_CLASS_CODEC
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index f118fe7a9f58..df8b9c486ba1 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -703,6 +703,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') /* VP8 parsed frame */
#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
+#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F') /* VP9 parsed frame */
#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */
#define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */
#define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */
@@ -1759,6 +1760,8 @@ struct v4l2_ext_control {
struct v4l2_ctrl_mpeg2_sequence __user *p_mpeg2_sequence;
struct v4l2_ctrl_mpeg2_picture __user *p_mpeg2_picture;
struct v4l2_ctrl_mpeg2_quantisation __user *p_mpeg2_quantisation;
+ struct v4l2_ctrl_vp9_compressed_hdr __user *p_vp9_compressed_hdr_probs;
+ struct v4l2_ctrl_vp9_frame __user *p_vp9_frame;
void __user *ptr;
};
} __attribute__ ((packed));
@@ -1823,6 +1826,9 @@ enum v4l2_ctrl_type {
V4L2_CTRL_TYPE_MPEG2_QUANTISATION = 0x0250,
V4L2_CTRL_TYPE_MPEG2_SEQUENCE = 0x0251,
V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252,
+
+ V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260,
+ V4L2_CTRL_TYPE_VP9_FRAME = 0x0261,
};
/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */