History

Merge tag 'media/v6.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab: - v4l2 core: - sub-device framework routing improvements - NV12M tiled variants added to v4l2_format_info - some fixes at control handler freeing logic - fixed H264 SEPARATE_COLOUR_PLANE check - new staging driver: Intel IPU7 PCI - Rockchip video decoder driver got promoted from staging - iris: added HEVC/VP9 encoder/decoder support - vsp1: driver has gained Renesas VSPX support - uvc: - switched to vb2 ioctl helpers - added MSXU 1.5 metadata support - atomisp: GC0310 sensor driver cleanups in preparation for moving it out of staging - Lots of cleanup, fixes and improvements * tag 'media/v6.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (310 commits) media: rkvdec: Unstage the driver media: rkvdec: Remove TODO file media: dt-bindings: rockchip: Add RK3576 Video Decoder bindings media: dt-bindings: rockchip: Document RK3588 Video Decoder bindings media: amphion: Support dmabuf and v4l2 buffer without binding media: verisilicon: postproc: 4K support media: v4l2: Add support for NV12M tiled variants to v4l2_format_info() media: uvcvideo: Use a count variable for meta_formats instead of 0 terminating media: uvcvideo: Auto-set UVC_QUIRK_MSXU_META media: uvcvideo: Introduce V4L2_META_FMT_UVC_MSXU_1_5 media: uvcvideo: Introduce dev->meta_formats media: Documentation: Add note about UVCH length field media: uvcvideo: Do not mark valid metadata as invalid media: uvcvideo: uvc_v4l2_unlocked_ioctl: Invert PM logic media: core: export v4l2_translate_cmd media: uvcvideo: Turn on the camera if V4L2_EVENT_SUB_FL_SEND_INITIAL media: uvcvideo: Remove stream->is_streaming field media: uvcvideo: Split uvc_stop_streaming() media: uvcvideo: Handle locks in uvc_queue_return_buffers media: uvcvideo: Use vb2 ioctl and fop helpers ...

Linus Torvalds committed 1 year ago

Commit 0cdee262 parents 2715260 d968e50314 files · +23131 −4600Browse files

Unified · Split

314 files
  1. .mailmap +3 −2
  2. Documentation/devicetree/bindings/media/cdns,csi2rx.yaml +8 −0
  3. Documentation/devicetree/bindings/media/fsl,imx6q-vdoa.yaml +42 −0
  4. Documentation/devicetree/bindings/media/fsl,imx8qm-isi.yaml +117 −0
  5. Documentation/devicetree/bindings/media/fsl,imx8qxp-isi.yaml +106 −0
  6. Documentation/devicetree/bindings/media/fsl-vdoa.txt +0 −21
  7. Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml +5 −8
  8. Documentation/devicetree/bindings/media/i2c/onnn,mt9m114.yaml +9 −0
  9. Documentation/devicetree/bindings/media/i2c/ovti,ov8858.yaml +3 −1
  10. Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml +16 −13
  11. Documentation/devicetree/bindings/media/i2c/sony,imx258.yaml +3 −1
  12. Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml +25 −3
  13. Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml +34 −4
  14. Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml +7 −7
  15. Documentation/devicetree/bindings/media/renesas,fcp.yaml +1 −0
  16. Documentation/devicetree/bindings/media/renesas,vsp1.yaml +1 −0
  17. Documentation/devicetree/bindings/media/rockchip,vdec.yaml +77 −3
  18. Documentation/driver-api/media/v4l2-controls.rst +3 −6
  19. Documentation/userspace-api/media/cec/cec-pin-error-inj.rst +42 −0
  20. Documentation/userspace-api/media/v4l/biblio.rst +1 −1
  21. Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst +2 −2
  22. Documentation/userspace-api/media/v4l/ext-ctrls-fm-rx.rst +3 −8
  23. Documentation/userspace-api/media/v4l/ext-ctrls-fm-tx.rst +7 −14
  24. Documentation/userspace-api/media/v4l/meta-formats.rst +1 −0
  25. Documentation/userspace-api/media/v4l/metafmt-uvc-msxu-1-5.rst +23 −0
  26. Documentation/userspace-api/media/v4l/metafmt-uvc.rst +3 −1
  27. Documentation/userspace-api/media/v4l/pixfmt-bayer.rst +1 −0
  28. Documentation/userspace-api/media/v4l/pixfmt-rawnn-cru.rst +143 −0
  29. Documentation/userspace-api/media/v4l/pixfmt-srggb12p.rst +2 −2
  30. Documentation/userspace-api/media/v4l/pixfmt-srggb14p.rst +1 −1
  31. MAINTAINERS +31 −1
  32. drivers/media/cec/core/cec-pin-error-inj.c +58 −1
  33. drivers/media/cec/core/cec-pin-priv.h +8 −0
  34. drivers/media/cec/core/cec-pin.c +30 −1
  35. drivers/media/cec/platform/cec-gpio/cec-gpio.c +30 −28
  36. drivers/media/cec/usb/rainshadow/rainshadow-cec.c +2 −1
  37. drivers/media/common/b2c2/flexcop-i2c.c +1 −1
  38. drivers/media/dvb-frontends/cxd2820r_core.c +3 −3
  39. drivers/media/dvb-frontends/dib7000p.c +8 −0
  40. drivers/media/i2c/Kconfig +14 −27
  41. drivers/media/i2c/adv7180.c +0 −16
  42. drivers/media/i2c/adv748x/adv748x-afe.c +0 −17
  43. drivers/media/i2c/adv748x/adv748x-hdmi.c +0 −10
  44. drivers/media/i2c/adv7604.c +2 −2
  45. drivers/media/i2c/ds90ub913.c +3 −11
  46. drivers/media/i2c/ds90ub953.c +5 −14
  47. drivers/media/i2c/ds90ub960.c +0 −8
  48. drivers/media/i2c/dw9714.c +45 −17
  49. drivers/media/i2c/hi556.c +42 −31
  50. drivers/media/i2c/imx214.c +200 −63
  51. drivers/media/i2c/imx290.c +0 −1
  52. drivers/media/i2c/imx415.c +1 −1
  53. drivers/media/i2c/lt6911uxe.c +1 −1
  54. drivers/media/i2c/max9286.c +4 −4
  55. drivers/media/i2c/max96714.c +0 −7
  56. drivers/media/i2c/max96717.c +5 −6
  57. drivers/media/i2c/mt9m114.c +103 −68
  58. drivers/media/i2c/ov2659.c +2 −1
  59. drivers/media/i2c/ov2740.c +7 −11
  60. drivers/media/i2c/ov5670.c +7 −2
  61. drivers/media/i2c/ov5693.c +6 −1
  62. drivers/media/i2c/ov7251.c +6 −1
  63. drivers/media/i2c/ov8865.c +2 −1
  64. drivers/media/i2c/saa7115.c +2 −10
  65. drivers/media/i2c/tc358743.c +89 −49
  66. drivers/media/i2c/tda1997x.c +2 −2
  67. drivers/media/i2c/vd55g1.c +16 −16
  68. drivers/media/pci/cx18/cx18-av-vbi.c +2 −10
  69. drivers/media/pci/cx18/cx18-driver.h +0 −12
  70. drivers/media/pci/cx18/cx18-fileops.c +1 −1
  71. drivers/media/pci/cx18/cx18-ioctl.c +1 −1
  72. drivers/media/pci/intel/ipu-bridge.c +10 −3
  73. drivers/media/pci/intel/ipu3/ipu3-cio2.c +32 −50
  74. drivers/media/pci/intel/ipu3/ipu3-cio2.h +0 −2
  75. drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +6 −6
  76. drivers/media/pci/intel/ipu6/ipu6-isys.h +1 −1
  77. drivers/media/pci/intel/ivsc/mei_ace.c +3 −1
  78. drivers/media/pci/intel/ivsc/mei_csi.c +3 −1
  79. drivers/media/pci/mgb4/mgb4_vout.c +8 −1
  80. drivers/media/pci/saa7164/saa7164-buffer.c +0 −20
  81. drivers/media/pci/saa7164/saa7164-cmd.c +0 −28
  82. drivers/media/pci/saa7164/saa7164.h +0 −2
  83. drivers/media/pci/solo6x10/solo6x10-gpio.c +5 −17
  84. drivers/media/platform/amphion/vdec.c +249 −45
  85. drivers/media/platform/amphion/vpu.h +5 −2
  86. drivers/media/platform/amphion/vpu_color.c +0 −73
  87. drivers/media/platform/amphion/vpu_dbg.c +14 −1
  88. drivers/media/platform/amphion/vpu_defs.h +12 −0
  89. drivers/media/platform/amphion/vpu_helpers.c +123 −0
  90. drivers/media/platform/amphion/vpu_helpers.h +7 −5
  91. drivers/media/platform/amphion/vpu_malone.c +4 −1
  92. drivers/media/platform/amphion/vpu_mbox.c +0 −4
  93. drivers/media/platform/amphion/vpu_mbox.h +0 −1
  94. drivers/media/platform/amphion/vpu_v4l2.c +11 −0
  95. drivers/media/platform/cadence/cdns-csi2rx.c +131 −0
  96. drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +36 −11
  97. drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +1 −0
  98. drivers/media/platform/nxp/imx-mipi-csis.c +25 −43
  99. drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c +66 −69
  100. drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h +3 −3
  101. drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c +8 −10
  102. drivers/media/platform/nxp/imx8mq-mipi-csi2.c +155 −14
  103. drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +1 −2
  104. drivers/media/platform/qcom/camss/camss-csiphy.c +0 −5
  105. drivers/media/platform/qcom/camss/camss-csiphy.h +0 −1
  106. drivers/media/platform/qcom/camss/camss-video.c +25 −14
  107. drivers/media/platform/qcom/camss/camss.c +53 −54
  108. drivers/media/platform/qcom/iris/iris_buffer.c +31 −4
  109. drivers/media/platform/qcom/iris/iris_buffer.h +2 −1
  110. drivers/media/platform/qcom/iris/iris_ctrls.c +25 −10
  111. drivers/media/platform/qcom/iris/iris_hfi_common.h +1 −0
  112. drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +29 −19
  113. drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h +4 −1
  114. drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c +28 −9
  115. drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +126 −17
  116. drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h +5 −0
  117. drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +47 −9
  118. drivers/media/platform/qcom/iris/iris_hfi_queue.c +1 −1
  119. drivers/media/platform/qcom/iris/iris_instance.h +6 −0
  120. drivers/media/platform/qcom/iris/iris_platform_common.h +21 −7
  121. drivers/media/platform/qcom/iris/iris_platform_gen2.c +174 −24
  122. drivers/media/platform/qcom/iris/iris_platform_qcs8300.h +101 −25
  123. drivers/media/platform/qcom/iris/iris_platform_sm8250.c +3 −12
  124. drivers/media/platform/qcom/iris/iris_probe.c +1 −1
  125. drivers/media/platform/qcom/iris/iris_state.c +1 −1
  126. drivers/media/platform/qcom/iris/iris_state.h +1 −0
  127. drivers/media/platform/qcom/iris/iris_vb2.c +10 −8
  128. drivers/media/platform/qcom/iris/iris_vdec.c +72 −44
  129. drivers/media/platform/qcom/iris/iris_vdec.h +11 −0
  130. drivers/media/platform/qcom/iris/iris_vidc.c +31 −5
  131. drivers/media/platform/qcom/iris/iris_vpu_buffer.c +386 −11
  132. drivers/media/platform/qcom/iris/iris_vpu_buffer.h +43 −3
  133. drivers/media/platform/qcom/venus/core.c +9 −9
  134. drivers/media/platform/qcom/venus/core.h +2 −0
  135. drivers/media/platform/qcom/venus/hfi_msgs.c +58 −25
  136. drivers/media/platform/qcom/venus/hfi_venus.c +5 −0
  137. drivers/media/platform/qcom/venus/pm_helpers.c +34 −24
  138. drivers/media/platform/qcom/venus/vdec.c +3 −5
  139. drivers/media/platform/qcom/venus/venc.c +3 −5
  140. drivers/media/platform/raspberrypi/pisp_be/Kconfig +1 −0
  141. drivers/media/platform/raspberrypi/pisp_be/pisp_be.c +104 −103
  142. drivers/media/platform/raspberrypi/rp1-cfe/cfe.c +1 −3
  143. drivers/media/platform/renesas/rcar-csi2.c +290 −46
  144. drivers/media/platform/renesas/rcar-fcp.c +36 −0
  145. drivers/media/platform/renesas/rcar-vin/rcar-core.c +269 −425
  146. drivers/media/platform/renesas/rcar-vin/rcar-dma.c +33 −44
  147. drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c +20 −472
  148. drivers/media/platform/renesas/rcar-vin/rcar-vin.h +4 −12
  149. drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c +3 −3
  150. drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h +9 −5
  151. drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c +32 −13
  152. drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c +89 −19
  153. drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c +29 −13
  154. drivers/media/platform/renesas/vsp1/Makefile +1 −0
  155. drivers/media/platform/renesas/vsp1/vsp1.h +1 −0
  156. drivers/media/platform/renesas/vsp1/vsp1_dl.c +25 −0
  157. drivers/media/platform/renesas/vsp1/vsp1_drm.c +1 −0
  158. drivers/media/platform/renesas/vsp1/vsp1_drv.c +20 −2
  159. drivers/media/platform/renesas/vsp1/vsp1_pipe.c +3 −0
  160. drivers/media/platform/renesas/vsp1/vsp1_regs.h +1 −0
  161. drivers/media/platform/renesas/vsp1/vsp1_vspx.c +633 −0
  162. drivers/media/platform/renesas/vsp1/vsp1_vspx.h +16 −0
  163. drivers/media/platform/rockchip/Kconfig +1 −0
  164. drivers/media/platform/rockchip/Makefile +1 −0
  165. drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +2 −0
  166. drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +146 −4
  167. drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h +25 −74
  168. drivers/media/platform/rockchip/rkvdec/Kconfig +0 −0
  169. drivers/media/platform/rockchip/rkvdec/Makefile +0 −0
  170. drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c +0 −0
  171. drivers/media/platform/rockchip/rkvdec/rkvdec-regs.h +0 −0
  172. drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c +0 −0
  173. drivers/media/platform/rockchip/rkvdec/rkvdec.c +36 −7
  174. drivers/media/platform/rockchip/rkvdec/rkvdec.h +1 −0
  175. drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.c +1 −1
  176. drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.h +0 −2
  177. drivers/media/platform/samsung/exynos4-is/fimc-is.c +1 −1
  178. drivers/media/platform/samsung/exynos4-is/media-dev.c +8 −19
  179. drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c +12 −22
  180. drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c +2 −0
  181. drivers/media/platform/ti/vpe/vpdma.c +0 −32
  182. drivers/media/platform/ti/vpe/vpdma.h +0 −3
  183. drivers/media/platform/verisilicon/hantro.h +2 −0
  184. drivers/media/platform/verisilicon/hantro_g1_regs.h +1 −1
  185. drivers/media/platform/verisilicon/hantro_h264.c +3 −3
  186. drivers/media/platform/verisilicon/hantro_postproc.c +5 −1
  187. drivers/media/platform/verisilicon/rockchip_vpu_hw.c +0 −9
  188. drivers/media/platform/xilinx/xilinx-vipp.c +2 −5
  189. drivers/media/rc/ir-spi.c +26 −14
  190. drivers/media/test-drivers/vivid/vivid-ctrls.c +2 −1
  191. drivers/media/test-drivers/vivid/vivid-vbi-gen.c +2 −6
  192. drivers/media/test-drivers/vivid/vivid-vid-cap.c +2 −2
  193. drivers/media/usb/gspca/vicam.c +8 −2
  194. drivers/media/usb/hdpvr/hdpvr-i2c.c +8 −22
  195. drivers/media/usb/usbtv/usbtv-video.c +4 −0
  196. drivers/media/usb/uvc/uvc_ctrl.c +89 −42
  197. drivers/media/usb/uvc/uvc_driver.c +35 −39
  198. drivers/media/usb/uvc/uvc_metadata.c +107 −15
  199. drivers/media/usb/uvc/uvc_queue.c +42 −157
  200. drivers/media/usb/uvc/uvc_v4l2.c +53 −313
  201. drivers/media/usb/uvc/uvc_video.c +15 −6
  202. drivers/media/usb/uvc/uvcvideo.h +13 −33
  203. drivers/media/v4l2-core/v4l2-common.c +36 −4
  204. drivers/media/v4l2-core/v4l2-ctrls-core.c +12 −8
  205. drivers/media/v4l2-core/v4l2-i2c.c +2 −1
  206. drivers/media/v4l2-core/v4l2-ioctl.c +8 −2
  207. drivers/media/v4l2-core/v4l2-jpeg.c +0 −80
  208. drivers/media/v4l2-core/v4l2-subdev.c +27 −4
  209. drivers/platform/x86/intel/int3472/tps68470_board_data.c +128 −0
  210. drivers/staging/media/Kconfig +2 −2
  211. drivers/staging/media/Makefile +1 −1
  212. drivers/staging/media/atomisp/Kconfig +1 −0
  213. drivers/staging/media/atomisp/Makefile +0 −1
  214. drivers/staging/media/atomisp/TODO +0 −2
  215. drivers/staging/media/atomisp/i2c/Kconfig +1 −0
  216. drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +341 −270
  217. drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +0 −2
  218. drivers/staging/media/atomisp/i2c/gc2235.h +8 −8
  219. drivers/staging/media/atomisp/i2c/ov2722.h +8 −8
  220. drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +1 −1
  221. drivers/staging/media/atomisp/pci/atomisp_csi2.h +0 −17
  222. drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c +25 −208
  223. drivers/staging/media/atomisp/pci/atomisp_drvfs.c +0 −155
  224. drivers/staging/media/atomisp/pci/atomisp_drvfs.h +0 −15
  225. drivers/staging/media/atomisp/pci/atomisp_fops.c +1 −4
  226. drivers/staging/media/atomisp/pci/atomisp_ioctl.c +60 −69
  227. drivers/staging/media/atomisp/pci/atomisp_subdev.h +0 −3
  228. drivers/staging/media/atomisp/pci/atomisp_v4l2.c +1 −4
  229. drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h +0 −5
  230. drivers/staging/media/atomisp/pci/hmm/hmm.c +0 −91
  231. drivers/staging/media/atomisp/pci/hmm/hmm_bo.c +2 −3
  232. drivers/staging/media/atomisp/pci/ia_css_pipe.h +0 −2
  233. drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h +3 −1
  234. drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h +4 −2
  235. drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c +2 −2
  236. drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h +12 −10
  237. drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c +4 −2
  238. drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h +1 −1
  239. drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c +1 −2
  240. drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h +4 −2
  241. drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h +0 −157
  242. drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c +0 −1
  243. drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c +15 −14
  244. drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c +5 −6
  245. drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c +1 −1
  246. drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h +0 −1
  247. drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c +0 −2
  248. drivers/staging/media/atomisp/pci/sh_css.c +0 −27
  249. drivers/staging/media/atomisp/pci/sh_css_defs.h +6 −6
  250. drivers/staging/media/atomisp/pci/sh_css_internal.h +3 −5
  251. drivers/staging/media/atomisp/pci/sh_css_mipi.c +0 −11
  252. drivers/staging/media/atomisp/pci/sh_css_mipi.h +0 −2
  253. drivers/staging/media/atomisp/pci/sh_css_param_dvs.h +11 −11
  254. drivers/staging/media/atomisp/pci/sh_css_params.c +6 −6
  255. drivers/staging/media/imx/imx-media-csc-scaler.c +1 −1
  256. drivers/staging/media/ipu7/Kconfig +19 −0
  257. drivers/staging/media/ipu7/Makefile +23 −0
  258. drivers/staging/media/ipu7/TODO +28 −0
  259. drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h +163 −0
  260. drivers/staging/media/ipu7/abi/ipu7_fw_common_abi.h +175 −0
  261. drivers/staging/media/ipu7/abi/ipu7_fw_config_abi.h +19 −0
  262. drivers/staging/media/ipu7/abi/ipu7_fw_insys_config_abi.h +19 −0
  263. drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h +412 −0
  264. drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h +465 −0
  265. drivers/staging/media/ipu7/abi/ipu7_fw_psys_config_abi.h +24 −0
  266. drivers/staging/media/ipu7/abi/ipu7_fw_syscom_abi.h +49 −0
  267. drivers/staging/media/ipu7/ipu7-boot.c +430 −0
  268. drivers/staging/media/ipu7/ipu7-boot.h +25 −0
  269. drivers/staging/media/ipu7/ipu7-bus.c +158 −0
  270. drivers/staging/media/ipu7/ipu7-bus.h +69 −0
  271. drivers/staging/media/ipu7/ipu7-buttress-regs.h +461 −0
  272. drivers/staging/media/ipu7/ipu7-buttress.c +1192 −0
  273. drivers/staging/media/ipu7/ipu7-buttress.h +77 −0
  274. drivers/staging/media/ipu7/ipu7-cpd.c +276 −0
  275. drivers/staging/media/ipu7/ipu7-cpd.h +16 −0
  276. drivers/staging/media/ipu7/ipu7-dma.c +477 −0
  277. drivers/staging/media/ipu7/ipu7-dma.h +46 −0
  278. drivers/staging/media/ipu7/ipu7-fw-isys.c +301 −0
  279. drivers/staging/media/ipu7/ipu7-fw-isys.h +39 −0
  280. drivers/staging/media/ipu7/ipu7-isys-csi-phy.c +1034 −0
  281. drivers/staging/media/ipu7/ipu7-isys-csi-phy.h +16 −0
  282. drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h +1197 −0
  283. drivers/staging/media/ipu7/ipu7-isys-csi2.c +543 −0
  284. drivers/staging/media/ipu7/ipu7-isys-csi2.h +64 −0
  285. drivers/staging/media/ipu7/ipu7-isys-queue.c +829 −0
  286. drivers/staging/media/ipu7/ipu7-isys-queue.h +72 −0
  287. drivers/staging/media/ipu7/ipu7-isys-subdev.c +348 −0
  288. drivers/staging/media/ipu7/ipu7-isys-subdev.h +53 −0
  289. drivers/staging/media/ipu7/ipu7-isys-video.c +1112 −0
  290. drivers/staging/media/ipu7/ipu7-isys-video.h +117 −0
  291. drivers/staging/media/ipu7/ipu7-isys.c +1166 −0
  292. drivers/staging/media/ipu7/ipu7-isys.h +140 −0
  293. drivers/staging/media/ipu7/ipu7-mmu.c +853 −0
  294. drivers/staging/media/ipu7/ipu7-mmu.h +414 −0
  295. drivers/staging/media/ipu7/ipu7-platform-regs.h +82 −0
  296. drivers/staging/media/ipu7/ipu7-syscom.c +78 −0
  297. drivers/staging/media/ipu7/ipu7-syscom.h +35 −0
  298. drivers/staging/media/ipu7/ipu7.c +2783 −0
  299. drivers/staging/media/ipu7/ipu7.h +242 −0
  300. drivers/staging/media/rkvdec/TODO +0 −11
  301. drivers/staging/media/sunxi/cedrus/cedrus_hw.c +18 −1
  302. drivers/staging/media/sunxi/cedrus/cedrus_video.c +18 −0
  303. include/linux/usb/uvc.h +3 −0
  304. include/media/rcar-fcp.h +5 −0
  305. include/media/v4l2-ctrls.h +3 −1
  306. include/media/v4l2-dev.h +10 −4
  307. include/media/v4l2-ioctl.h +1 −0
  308. include/media/v4l2-jpeg.h +0 −9
  309. include/media/v4l2-subdev.h +0 −3
  310. include/media/vsp1.h +89 −0
  311. include/uapi/linux/media/raspberrypi/pisp_be_config.h +5 −4
  312. include/uapi/linux/rkisp1-config.h +105 −1
  313. include/uapi/linux/v4l2-controls.h +6 −0
  314. include/uapi/linux/videodev2.h +8 −1
.mailmap+3−2
@@ -287,8 +287,9 @@ Gustavo Padovan <padovan@profusion.mobi> · 286 unmodified lines
287287 Hamza Mahfooz <hamzamahfooz@linux.microsoft.com> <hamza.mahfooz@amd.com>
288288 Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org>
289289 Hans de Goede <hansg@kernel.org> <hdegoede@redhat.com>
290−Hans Verkuil <hverkuil@xs4all.nl> <hansverk@cisco.com>
291−Hans Verkuil <hverkuil@xs4all.nl> <hverkuil-cisco@xs4all.nl>
290+Hans Verkuil <hverkuil@kernel.org> <hverkuil@xs4all.nl>
291+Hans Verkuil <hverkuil@kernel.org> <hverkuil-cisco@xs4all.nl>
292+Hans Verkuil <hverkuil@kernel.org> <hansverk@cisco.com>
292293 Harry Yoo <harry.yoo@oracle.com> <42.hyeyoo@gmail.com>
293294 Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>
294295 Heiko Carstens <hca@linux.ibm.com> <heiko.carstens@de.ibm.com>
Documentation/devicetree/bindings/media/cdns,csi2rx.yaml+8−0
@@ -24,6 +24,14 @@ properties: · 23 unmodified lines
2424 reg:
2525 maxItems: 1
2626
27+ interrupts:
28+ maxItems: 2
29+
30+ interrupt-names:
31+ items:
32+ - const: error_irq
33+ - const: irq
34+
2735 clocks:
2836 items:
2937 - description: CSI2Rx system clock
Documentation/devicetree/bindings/media/fsl,imx6q-vdoa.yaml+42−0
@@ -0,0 +1,42 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/fsl,imx6q-vdoa.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Freescale Video Data Order Adapter
8+
9+description:
10+ The Video Data Order Adapter (VDOA) is present on the i.MX6q. Its sole purpose
11+ is to reorder video data from the macroblock tiled order produced by the CODA
12+ 960 VPU to the conventional raster-scan order for scanout.
13+
14+maintainers:
15+ - Frank Li <Frank.Li@nxp.com>
16+
17+properties:
18+ compatible:
19+ const: "fsl,imx6q-vdoa"
20+
21+ reg:
22+ maxItems: 1
23+
24+ interrupts:
25+ maxItems: 1
26+
27+ clocks:
28+ maxItems: 1
29+
30+additionalProperties: false
31+
32+examples:
33+ - |
34+ #include <dt-bindings/interrupt-controller/irq.h>
35+ #include <dt-bindings/clock/imx6qdl-clock.h>
36+
37+ vdoa@21e4000 {
38+ compatible = "fsl,imx6q-vdoa";
39+ reg = <0x021e4000 0x4000>;
40+ interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
41+ clocks = <&clks IMX6QDL_CLK_VDOA>;
42+ };
Documentation/devicetree/bindings/media/fsl,imx8qm-isi.yaml+117−0
@@ -0,0 +1,117 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/fsl,imx8qm-isi.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: i.MX8QM Image Sensing Interface
8+
9+maintainers:
10+ - Frank Li <Frank.Li@nxp.com>
11+
12+description:
13+ The Image Sensing Interface (ISI) combines image processing pipelines with
14+ DMA engines to process and capture frames originating from a variety of
15+ sources. The inputs to the ISI go through Pixel Link interfaces, and their
16+ number and nature is SoC-dependent. They cover both capture interfaces (MIPI
17+ CSI-2 RX, HDMI RX, ...) and display engine outputs for writeback support.
18+
19+properties:
20+ compatible:
21+ enum:
22+ - fsl,imx8qm-isi
23+
24+ reg:
25+ maxItems: 1
26+
27+ clocks:
28+ maxItems: 8
29+
30+ clock-names:
31+ items:
32+ - const: per0
33+ - const: per1
34+ - const: per2
35+ - const: per3
36+ - const: per4
37+ - const: per5
38+ - const: per6
39+ - const: per7
40+
41+ interrupts:
42+ maxItems: 8
43+
44+ power-domains:
45+ maxItems: 8
46+
47+ ports:
48+ $ref: /schemas/graph.yaml#/properties/ports
49+ properties:
50+ port@2:
51+ $ref: /schemas/graph.yaml#/properties/port
52+ description: MIPI CSI-2 RX 0
53+ port@3:
54+ $ref: /schemas/graph.yaml#/properties/port
55+ description: MIPI CSI-2 RX 1
56+ port@4:
57+ $ref: /schemas/graph.yaml#/properties/port
58+ description: HDMI RX
59+
60+required:
61+ - compatible
62+ - reg
63+ - clocks
64+ - clock-names
65+ - interrupts
66+ - power-domains
67+ - ports
68+
69+additionalProperties: false
70+
71+examples:
72+ - |
73+ #include <dt-bindings/interrupt-controller/arm-gic.h>
74+ #include <dt-bindings/interrupt-controller/irq.h>
75+ #include <dt-bindings/clock/imx8-clock.h>
76+ #include <dt-bindings/clock/imx8-lpcg.h>
77+ #include <dt-bindings/firmware/imx/rsrc.h>
78+
79+ image-controller@58100000 {
80+ compatible = "fsl,imx8qm-isi";
81+ reg = <0x58100000 0x80000>;
82+ interrupts = <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
83+ <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>,
84+ <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>,
85+ <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>,
86+ <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>,
87+ <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
88+ <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
89+ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>;
90+ clocks = <&pdma0_lpcg IMX_LPCG_CLK_0>,
91+ <&pdma1_lpcg IMX_LPCG_CLK_0>,
92+ <&pdma2_lpcg IMX_LPCG_CLK_0>,
93+ <&pdma3_lpcg IMX_LPCG_CLK_0>,
94+ <&pdma4_lpcg IMX_LPCG_CLK_0>,
95+ <&pdma5_lpcg IMX_LPCG_CLK_0>,
96+ <&pdma6_lpcg IMX_LPCG_CLK_0>,
97+ <&pdma7_lpcg IMX_LPCG_CLK_0>;
98+ clock-names = "per0", "per1", "per2", "per3",
99+ "per4", "per5", "per6", "per7";
100+ power-domains = <&pd IMX_SC_R_ISI_CH0>, <&pd IMX_SC_R_ISI_CH1>,
101+ <&pd IMX_SC_R_ISI_CH2>, <&pd IMX_SC_R_ISI_CH3>,
102+ <&pd IMX_SC_R_ISI_CH4>, <&pd IMX_SC_R_ISI_CH5>,
103+ <&pd IMX_SC_R_ISI_CH6>, <&pd IMX_SC_R_ISI_CH7>;
104+
105+ ports {
106+ #address-cells = <1>;
107+ #size-cells = <0>;
108+
109+ port@2 {
110+ reg = <2>;
111+ endpoint {
112+ remote-endpoint = <&mipi_csi0_out>;
113+ };
114+ };
115+ };
116+ };
117+...
Documentation/devicetree/bindings/media/fsl,imx8qxp-isi.yaml+106−0
@@ -0,0 +1,106 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/media/fsl,imx8qxp-isi.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: i.MX8QXP Image Sensing Interface
8+
9+maintainers:
10+ - Frank Li <Frank.Li@nxp.com>
11+
12+description:
13+ The Image Sensing Interface (ISI) combines image processing pipelines with
14+ DMA engines to process and capture frames originating from a variety of
15+ sources. The inputs to the ISI go through Pixel Link interfaces, and their
16+ number and nature is SoC-dependent. They cover both capture interfaces (MIPI
17+ CSI-2 RX, HDMI RX, ...) and display engine outputs for writeback support.
18+
19+properties:
20+ compatible:
21+ enum:
22+ - fsl,imx8qxp-isi
23+
24+ reg:
25+ maxItems: 1
26+
27+ clocks:
28+ maxItems: 6
29+
30+ clock-names:
31+ items:
32+ - const: per0
33+ - const: per1
34+ - const: per2
35+ - const: per3
36+ - const: per4
37+ - const: per5
38+
39+ interrupts:
40+ maxItems: 6
41+
42+ power-domains:
43+ maxItems: 6
44+
45+ ports:
46+ $ref: /schemas/graph.yaml#/properties/ports
47+ properties:
48+ port@2:
49+ $ref: /schemas/graph.yaml#/properties/port
50+ description: MIPI CSI-2 RX 0
51+ port@6:
52+ $ref: /schemas/graph.yaml#/properties/port
53+ description: CSI-2 Parallel RX
54+
55+required:
56+ - compatible
57+ - reg
58+ - clocks
59+ - clock-names
60+ - interrupts
61+ - power-domains
62+ - ports
63+
64+additionalProperties: false
65+
66+examples:
67+ - |
68+ #include <dt-bindings/interrupt-controller/arm-gic.h>
69+ #include <dt-bindings/interrupt-controller/irq.h>
70+ #include <dt-bindings/clock/imx8-clock.h>
71+ #include <dt-bindings/clock/imx8-lpcg.h>
72+ #include <dt-bindings/firmware/imx/rsrc.h>
73+
74+ image-controller@58100000 {
75+ compatible = "fsl,imx8qxp-isi";
76+ reg = <0x58100000 0x60000>;
77+ interrupts = <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
78+ <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>,
79+ <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>,
80+ <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>,
81+ <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>,
82+ <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>;
83+ clocks = <&pdma0_lpcg IMX_LPCG_CLK_0>,
84+ <&pdma1_lpcg IMX_LPCG_CLK_0>,
85+ <&pdma2_lpcg IMX_LPCG_CLK_0>,
86+ <&pdma3_lpcg IMX_LPCG_CLK_0>,
87+ <&pdma4_lpcg IMX_LPCG_CLK_0>,
88+ <&pdma5_lpcg IMX_LPCG_CLK_0>;
89+ clock-names = "per0", "per1", "per2", "per3", "per4", "per5";
90+ power-domains = <&pd IMX_SC_R_ISI_CH0>, <&pd IMX_SC_R_ISI_CH1>,
91+ <&pd IMX_SC_R_ISI_CH2>, <&pd IMX_SC_R_ISI_CH3>,
92+ <&pd IMX_SC_R_ISI_CH4>, <&pd IMX_SC_R_ISI_CH5>;
93+
94+ ports {
95+ #address-cells = <1>;
96+ #size-cells = <0>;
97+
98+ port@2 {
99+ reg = <2>;
100+ endpoint {
101+ remote-endpoint = <&mipi_csi0_out>;
102+ };
103+ };
104+ };
105+ };
106+...
Documentation/devicetree/bindings/media/fsl-vdoa.txt+0−21
@@ -1,21 +0,0 @@
1−Freescale Video Data Order Adapter
2−==================================
3−
4−The Video Data Order Adapter (VDOA) is present on the i.MX6q. Its sole purpose
5−is to reorder video data from the macroblock tiled order produced by the CODA
6−960 VPU to the conventional raster-scan order for scanout.
7−
8−Required properties:
9−- compatible: must be "fsl,imx6q-vdoa"
10−- reg: the register base and size for the device registers
11−- interrupts: the VDOA interrupt
12−- clocks: the vdoa clock
13−
14−Example:
15−
16−vdoa@21e4000 {
17− compatible = "fsl,imx6q-vdoa";
18− reg = <0x021e4000 0x4000>;
19− interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
20− clocks = <&clks IMX6QDL_CLK_VDOA>;
21−};
Documentation/devicetree/bindings/media/i2c/mipi-ccs.yaml+5−8
@@ -23,6 +23,9 @@ description: · 22 unmodified lines
2323 More detailed documentation can be found in
2424 Documentation/devicetree/bindings/media/video-interfaces.txt .
2525
26+allOf:
27+ - $ref: /schemas/media/video-interface-devices.yaml#
28+
2629 properties:
2730 compatible:
2831 oneOf:
@@ -58,16 +61,10 @@ properties: · 29 unmodified lines
5861 documentation.
5962 maxItems: 1
6063
61− flash-leds:
62− description: Flash LED phandles. See ../video-interfaces.txt for details.
63−
64− lens-focus:
65− description: Lens focus controller phandles. See ../video-interfaces.txt
66− for details.
64+ flash-leds: true
65+ lens-focus: true
6766
6867 rotation:
69− description: Rotation of the sensor. See ../video-interfaces.txt for
70− details.
7168 enum: [ 0, 180 ]
7269
7370 port:
Documentation/devicetree/bindings/media/i2c/onnn,mt9m114.yaml+9−0
@@ -70,6 +70,15 @@ properties: · 69 unmodified lines
7070 - bus-type
7171 - link-frequencies
7272
73+ slew-rate:
74+ $ref: /schemas/types.yaml#/definitions/uint32
75+ description:
76+ Slew rate ot the output pads DOUT[7:0], LINE_VALID, FRAME_VALID and
77+ PIXCLK. Higher values imply steeper voltage-flanks on the pads.
78+ minimum: 0
79+ maximum: 7
80+ default: 7
81+
7382 required:
7483 - compatible
7584 - reg
Documentation/devicetree/bindings/media/i2c/ovti,ov8858.yaml+3−1
@@ -15,6 +15,8 @@ description: | · 14 unmodified lines
1515 controlled through an I2C-compatible SCCB bus. The sensor transmits images
1616 on a MIPI CSI-2 output interface with up to 4 data lanes.
1717
18+$ref: /schemas/media/video-interface-devices.yaml#
19+
1820 properties:
1921 compatible:
2022 const: ovti,ov8858
@@ -69,7 +71,7 @@ required: · 48 unmodified lines
6971 - clocks
7072 - port
7173
72−additionalProperties: false
74+unevaluatedProperties: false
7375
7476 examples:
7577 - |
Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml+16−13
@@ -33,20 +33,21 @@ properties: · 32 unmodified lines
3333
3434 clock-frequency:
3535 description: Frequency of the xclk clock in Hz.
36+ deprecated: true
3637
3738 enable-gpios:
3839 description: GPIO descriptor for the enable pin.
3940 maxItems: 1
4041
41− vdddo-supply:
42− description: Chip digital IO regulator (1.8V).
43−
4442 vdda-supply:
4543 description: Chip analog regulator (2.7V).
4644
4745 vddd-supply:
4846 description: Chip digital core regulator (1.12V).
4947
48+ vdddo-supply:
49+ description: Chip digital IO regulator (1.8V).
50+
5051 flash-leds: true
5152 lens-focus: true
5253
@@ -84,11 +85,10 @@ required: · 31 unmodified lines
8485 - compatible
8586 - reg
8687 - clocks
87− - clock-frequency
8888 - enable-gpios
89− - vdddo-supply
9089 - vdda-supply
9190 - vddd-supply
91+ - vdddo-supply
9292 - port
9393
9494 unevaluatedProperties: false
@@ -104,22 +104,25 @@ examples: · 9 unmodified lines
104104 camera-sensor@1a {
105105 compatible = "sony,imx214";
106106 reg = <0x1a>;
107− vdddo-supply = <&pm8994_lvs1>;
108− vddd-supply = <&camera_vddd_1v12>;
107+
108+ clocks = <&camera_clk>;
109+ assigned-clocks = <&camera_clk>;
110+ assigned-clock-rates = <24000000>;
111+
112+ enable-gpios = <&msmgpio 25 GPIO_ACTIVE_HIGH>;
113+
109114 vdda-supply = <&pm8994_l17>;
115+ vddd-supply = <&camera_vddd_1v12>;
116+ vdddo-supply = <&pm8994_lvs1>;
117+
110118 lens-focus = <&ad5820>;
111− enable-gpios = <&msmgpio 25 GPIO_ACTIVE_HIGH>;
112− clocks = <&camera_clk>;
113− clock-frequency = <24000000>;
114119
115120 port {
116121 imx214_ep: endpoint {
117122 data-lanes = <1 2 3 4>;
118− link-frequencies = /bits/ 64 <480000000>;
123+ link-frequencies = /bits/ 64 <600000000>;
119124 remote-endpoint = <&csiphy0_ep>;
120125 };
121126 };
122127 };
123128 };
124−
125−...
Documentation/devicetree/bindings/media/i2c/sony,imx258.yaml+3−1
@@ -18,6 +18,8 @@ description: |- · 17 unmodified lines
1818 The camera module does not expose the model through registers, so the
1919 exact model needs to be specified.
2020
21+$ref: /schemas/media/video-interface-devices.yaml#
22+
2123 properties:
2224 compatible:
2325 enum:
@@ -81,7 +83,7 @@ required: · 57 unmodified lines
8183 - reg
8284 - port
8385
84−additionalProperties: false
86+unevaluatedProperties: false
8587
8688 examples:
8789 - |
Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml+25−3
@@ -22,10 +22,14 @@ properties: · 21 unmodified lines
2222 - nxp,imx8qxp-jpgdec
2323 - nxp,imx8qxp-jpgenc
2424 - items:
25− - const: nxp,imx8qm-jpgdec
25+ - enum:
26+ - nxp,imx8qm-jpgdec
27+ - nxp,imx95-jpgdec
2628 - const: nxp,imx8qxp-jpgdec
2729 - items:
28− - const: nxp,imx8qm-jpgenc
30+ - enum:
31+ - nxp,imx8qm-jpgenc
32+ - nxp,imx95-jpgenc
2933 - const: nxp,imx8qxp-jpgenc
3034
3135 reg:
@@ -48,7 +52,7 @@ properties: · 16 unmodified lines
4852 description:
4953 List of phandle and PM domain specifier as documented in
5054 Documentation/devicetree/bindings/power/power_domain.txt
51− minItems: 2 # Wrapper and 1 slot
55+ minItems: 1 # Wrapper and all slots
5256 maxItems: 5 # Wrapper and 4 slots
5357
5458 required:
@@ -58,6 +62,24 @@ required: · 3 unmodified lines
5862 - interrupts
5963 - power-domains
6064
65+allOf:
66+ - if:
67+ properties:
68+ compatible:
69+ contains:
70+ enum:
71+ - nxp,imx95-jpgenc
72+ - nxp,imx95-jpgdec
73+ then:
74+ properties:
75+ power-domains:
76+ maxItems: 1
77+ else:
78+ properties:
79+ power-domains:
80+ minItems: 2 # Wrapper and 1 slot
81+
82+
6183 additionalProperties: false
6284
6385 examples:
Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml+34−4
@@ -16,11 +16,19 @@ description: |- · 15 unmodified lines
1616
1717 properties:
1818 compatible:
19− enum:
20− - fsl,imx8mq-mipi-csi2
19+ oneOf:
20+ - enum:
21+ - fsl,imx8mq-mipi-csi2
22+ - fsl,imx8qxp-mipi-csi2
23+ - items:
24+ - const: fsl,imx8qm-mipi-csi2
25+ - const: fsl,imx8qxp-mipi-csi2
2126
2227 reg:
23− maxItems: 1
28+ items:
29+ - description: MIPI CSI-2 RX host controller register.
30+ - description: MIPI CSI-2 control and status register (csr).
31+ minItems: 1
2432
2533 clocks:
2634 items:
@@ -46,6 +54,7 @@ properties: · 19 unmodified lines
4654 - description: CORE_RESET reset register bit definition
4755 - description: PHY_REF_RESET reset register bit definition
4856 - description: ESC_RESET reset register bit definition
57+ minItems: 1
4958
5059 fsl,mipi-phy-gpr:
5160 description: |
@@ -113,9 +122,30 @@ required: · 61 unmodified lines
113122 - clock-names
114123 - power-domains
115124 - resets
116− - fsl,mipi-phy-gpr
117125 - ports
118126
127+allOf:
128+ - if:
129+ properties:
130+ compatible:
131+ contains:
132+ enum:
133+ - fsl,imx8qxp-mipi-csi2
134+ then:
135+ properties:
136+ reg:
137+ minItems: 2
138+ resets:
139+ maxItems: 1
140+ else:
141+ properties:
142+ reg:
143+ maxItems: 1
144+ resets:
145+ minItems: 3
146+ required:
147+ - fsl,mipi-phy-gpr
148+
119149 additionalProperties: false
120150
121151 examples:
Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml+7−7
@@ -133,7 +133,7 @@ properties: · 132 unmodified lines
133133 CSI input ports.
134134
135135 patternProperties:
136− "^port@[0-3]+$":
136+ "^port@[0-3]$":
137137 $ref: /schemas/graph.yaml#/$defs/port-base
138138 unevaluatedProperties: false
139139
@@ -146,15 +146,16 @@ properties: · 6 unmodified lines
146146 unevaluatedProperties: false
147147
148148 properties:
149− clock-lanes:
150− maxItems: 1
151−
152149 data-lanes:
153150 minItems: 1
154151 maxItems: 4
155152
153+ bus-type:
154+ enum:
155+ - 1 # MEDIA_BUS_TYPE_CSI2_CPHY
156+ - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
157+
156158 required:
157− - clock-lanes
158159 - data-lanes
159160
160161 required:
@@ -189,7 +190,7 @@ examples: · 28 unmodified lines
189190 #address-cells = <2>;
190191 #size-cells = <2>;
191192
192− camss: isp@acb6000 {
193+ camss: isp@acb7000 {
193194 compatible = "qcom,x1e80100-camss";
194195
195196 reg = <0 0x0acb7000 0 0x2000>,
@@ -357,7 +358,6 @@ examples: · 161 unmodified lines
357358 port@0 {
358359 reg = <0>;
359360 csiphy_ep0: endpoint {
360− clock-lanes = <7>;
361361 data-lanes = <0 1>;
362362 remote-endpoint = <&sensor_ep>;
363363 };
Documentation/devicetree/bindings/media/renesas,fcp.yaml+1−0
@@ -30,6 +30,7 @@ properties: · 29 unmodified lines
3030 - renesas,r9a07g043u-fcpvd # RZ/G2UL
3131 - renesas,r9a07g044-fcpvd # RZ/G2{L,LC}
3232 - renesas,r9a07g054-fcpvd # RZ/V2L
33+ - renesas,r9a09g056-fcpvd # RZ/V2N
3334 - renesas,r9a09g057-fcpvd # RZ/V2H(P)
3435 - const: renesas,fcpv # Generic FCP for VSP fallback
3536
Documentation/devicetree/bindings/media/renesas,vsp1.yaml+1−0
@@ -25,6 +25,7 @@ properties: · 24 unmodified lines
2525 - enum:
2626 - renesas,r9a07g043u-vsp2 # RZ/G2UL
2727 - renesas,r9a07g054-vsp2 # RZ/V2L
28+ - renesas,r9a09g056-vsp2 # RZ/V2N
2829 - renesas,r9a09g057-vsp2 # RZ/V2H(P)
2930 - const: renesas,r9a07g044-vsp2 # RZ/G2L fallback
3031
Documentation/devicetree/bindings/media/rockchip,vdec.yaml+77−3
@@ -10,13 +10,15 @@ maintainers: · 9 unmodified lines
1010 - Heiko Stuebner <heiko@sntech.de>
1111
1212 description: |-
13− The Rockchip rk3399 has a stateless Video Decoder that can decodes H.264,
14− HEVC an VP9 streams.
13+ Rockchip SoCs have variants of the same stateless Video Decoder that can
14+ decodes H.264, HEVC, VP9 and AV1 streams, depending on the variant.
1515
1616 properties:
1717 compatible:
1818 oneOf:
1919 - const: rockchip,rk3399-vdec
20+ - const: rockchip,rk3576-vdec
21+ - const: rockchip,rk3588-vdec
2022 - items:
2123 - enum:
2224 - rockchip,rk3228-vdec
@@ -24,35 +26,72 @@ properties: · 1 unmodified line
2426 - const: rockchip,rk3399-vdec
2527
2628 reg:
27− maxItems: 1
29+ minItems: 1
30+ items:
31+ - description: The function configuration registers base
32+ - description: The link table configuration registers base
33+ - description: The cache configuration registers base
34+
35+ reg-names:
36+ items:
37+ - const: function
38+ - const: link
39+ - const: cache
2840
2941 interrupts:
3042 maxItems: 1
3143
3244 clocks:
45+ minItems: 4
3346 items:
3447 - description: The Video Decoder AXI interface clock
3548 - description: The Video Decoder AHB interface clock
3649 - description: The Video Decoded CABAC clock
3750 - description: The Video Decoder core clock
51+ - description: The Video decoder HEVC CABAC clock
3852
3953 clock-names:
54+ minItems: 4
4055 items:
4156 - const: axi
4257 - const: ahb
4358 - const: cabac
4459 - const: core
60+ - const: hevc_cabac
4561
4662 assigned-clocks: true
4763
4864 assigned-clock-rates: true
4965
66+ resets:
67+ items:
68+ - description: The Video Decoder AXI interface reset
69+ - description: The Video Decoder AHB interface reset
70+ - description: The Video Decoded CABAC reset
71+ - description: The Video Decoder core reset
72+ - description: The Video decoder HEVC CABAC reset
73+
74+ reset-names:
75+ items:
76+ - const: axi
77+ - const: ahb
78+ - const: cabac
79+ - const: core
80+ - const: hevc_cabac
81+
5082 power-domains:
5183 maxItems: 1
5284
5385 iommus:
5486 maxItems: 1
5587
88+ sram:
89+ $ref: /schemas/types.yaml#/definitions/phandle
90+ description: |
91+ phandle to a reserved on-chip SRAM regions.
92+ Some SoCs, like rk3588 provide on-chip SRAM to store temporary
93+ buffers during decoding.
94+
5695 required:
5796 - compatible
5897 - reg
@@ -61,6 +100,41 @@ required: · 2 unmodified lines
61100 - clock-names
62101 - power-domains
63102
103+allOf:
104+ - if:
105+ properties:
106+ compatible:
107+ contains:
108+ enum:
109+ - rockchip,rk3576-vdec
110+ - rockchip,rk3588-vdec
111+ then:
112+ properties:
113+ reg:
114+ minItems: 3
115+ reg-names:
116+ minItems: 3
117+ clocks:
118+ minItems: 5
119+ clock-names:
120+ minItems: 5
121+ resets:
122+ minItems: 5
123+ reset-names:
124+ minItems: 5
125+ else:
126+ properties:
127+ reg:
128+ maxItems: 1
129+ reg-names: false
130+ clocks:
131+ maxItems: 4
132+ clock-names:
133+ maxItems: 4
134+ resets: false
135+ reset-names: false
136+ sram: false
137+
64138 additionalProperties: false
65139
66140 examples:
Documentation/driver-api/media/v4l2-controls.rst+3−6
@@ -110,6 +110,7 @@ For sub-device drivers: · 109 unmodified lines
110110
111111 v4l2_ctrl_handler_free(&foo->ctrl_handler);
112112
113+:c:func:`v4l2_ctrl_handler_free` does not touch the handler's ``error`` field.
113114
114115 2) Add controls:
115116
@@ -191,12 +192,8 @@ These functions are typically called right after the · 75 unmodified lines
191192 V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
192193 0, test_pattern);
193194 ...
194− if (foo->ctrl_handler.error) {
195− int err = foo->ctrl_handler.error;
196−
197− v4l2_ctrl_handler_free(&foo->ctrl_handler);
198− return err;
199− }
195+ if (foo->ctrl_handler.error)
196+ return v4l2_ctrl_handler_free(&foo->ctrl_handler);
200197
201198 The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to
202199 the new control, but if you do not need to access the pointer outside the
Documentation/userspace-api/media/cec/cec-pin-error-inj.rst+42−0
@@ -41,6 +41,9 @@ error injection status:: · 40 unmodified lines
4141 # <op> rx-clear clear all rx error injections for <op>
4242 # <op> tx-clear clear all tx error injections for <op>
4343 #
44+ # RX error injection settings:
45+ # rx-no-low-drive do not generate low-drive pulses
46+ #
4447 # RX error injection:
4548 # <op>[,<mode>] rx-nack NACK the message instead of sending an ACK
4649 # <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position
@@ -53,6 +56,10 @@ error injection status:: · 6 unmodified lines
5356 # tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse
5457 # tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse
5558 # tx-custom-pulse transmit the custom pulse once the bus is idle
59+ # tx-glitch-low-usecs <usecs> define the 'low' time for the glitch pulse
60+ # tx-glitch-high-usecs <usecs> define the 'high' time for the glitch pulse
61+ # tx-glitch-falling-edge send the glitch pulse after every falling edge
62+ # tx-glitch-rising-edge send the glitch pulse after every rising edge
5663 #
5764 # TX error injection:
5865 # <op>[,<mode>] tx-no-eom don't set the EOM bit
@@ -193,6 +200,14 @@ Receive Messages · 134 unmodified lines
193200 This does not work if the remote CEC transmitter has logical address
194201 0 ('TV') since that will always win.
195202
203+``rx-no-low-drive``
204+ The receiver will ignore situations that would normally generate a
205+ Low Drive pulse (3.6 ms). This is typically done if a spurious pulse is
206+ detected when receiving a message, and it indicates to the transmitter that
207+ the message has to be retransmitted since the receiver got confused.
208+ Disabling this is useful to test how other CEC devices handle glitches
209+ by ensuring we will not be the one that generates a Low Drive.
210+
196211 Transmit Messages
197212 -----------------
198213
@@ -327,3 +342,30 @@ Custom Pulses · 128 unmodified lines
327342
328343 ``tx-custom-pulse``
329344 Transmit a single custom pulse as soon as the CEC bus is idle.
345+
346+Glitch Pulses
347+-------------
348+
349+This emulates what happens if the signal on the CEC line is seeing spurious
350+pulses. Typically this happens after the falling or rising edge where there
351+is a short voltage fluctuation that, if the CEC hardware doesn't do
352+deglitching, can be seen as a spurious pulse and can cause a Low Drive
353+condition or corrupt data.
354+
355+``tx-glitch-low-usecs <usecs>``
356+ This defines the duration in microseconds that the glitch pulse pulls
357+ the CEC line low. The default is 1 microsecond. The range is 0-100
358+ microseconds. If 0, then no glitch pulse will be generated.
359+
360+``tx-glitch-high-usecs <usecs>``
361+ This defines the duration in microseconds that the glitch pulse keeps the
362+ CEC line high (unless another CEC adapter pulls it low in that time).
363+ The default is 1 microseconds. The range is 0-100 microseconds. If 0, then
364+ no glitch pulse will be generated.The total period of the glitch pulse is
365+ ``tx-custom-low-usecs + tx-custom-high-usecs``.
366+
367+``tx-glitch-falling-edge``
368+ Send the glitch pulse right after the falling edge.
369+
370+``tx-glitch-rising-edge``
371+ Send the glitch pulse right after the rising edge.
Documentation/userspace-api/media/v4l/biblio.rst+1−1
@@ -150,7 +150,7 @@ ITU-T.81 · 149 unmodified lines
150150 ========
151151
152152
153−:title: ITU-T Recommendation T.81 "Information Technology --- Digital Compression and Coding of Continous-Tone Still Images --- Requirements and Guidelines"
153+:title: ITU-T Recommendation T.81 "Information Technology --- Digital Compression and Coding of Continuous-Tone Still Images --- Requirements and Guidelines"
154154
155155 :author: International Telecommunication Union (http://www.itu.int)
156156
Documentation/userspace-api/media/v4l/dev-sliced-vbi.rst+2−2
@@ -48,7 +48,7 @@ capabilities, and they may support :ref:`control` ioctls. · 47 unmodified lines
4848 The :ref:`video standard <standard>` ioctls provide information vital
4949 to program a sliced VBI device, therefore must be supported.
5050
51−.. _sliced-vbi-format-negotitation:
51+.. _sliced-vbi-format-negotiation:
5252
5353 Sliced VBI Format Negotiation
5454 =============================
@@ -377,7 +377,7 @@ Sliced VBI Data in MPEG Streams · 322 unmodified lines
377377
378378 If a device can produce an MPEG output stream, it may be capable of
379379 providing
380−:ref:`negotiated sliced VBI services <sliced-vbi-format-negotitation>`
380+:ref:`negotiated sliced VBI services <sliced-vbi-format-negotiation>`
381381 as data embedded in the MPEG stream. Users or applications control this
382382 sliced VBI data insertion with the
383383 :ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`
Documentation/userspace-api/media/v4l/ext-ctrls-fm-rx.rst+3−8
@@ -64,17 +64,12 @@ FM_RX Control IDs · 63 unmodified lines
6464 broadcasts speech. If the transmitter doesn't make this distinction,
6565 then it will be set.
6666
67−``V4L2_CID_TUNE_DEEMPHASIS``
68− (enum)
69−
70−enum v4l2_deemphasis -
67+``V4L2_CID_TUNE_DEEMPHASIS (enum)``
7168 Configures the de-emphasis value for reception. A de-emphasis filter
7269 is applied to the broadcast to accentuate the high audio
7370 frequencies. Depending on the region, a time constant of either 50
74− or 75 useconds is used. The enum v4l2_deemphasis defines possible
75− values for de-emphasis. Here they are:
76−
77−
71+ or 75 microseconds is used. The enum v4l2_deemphasis defines possible
72+ values for de-emphasis. They are:
7873
7974 .. flat-table::
8075 :header-rows: 0
Documentation/userspace-api/media/v4l/ext-ctrls-fm-tx.rst+7−14
@@ -104,7 +104,7 @@ FM_TX Control IDs · 103 unmodified lines
104104
105105 ``V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (integer)``
106106 Sets the audio deviation limiter feature release time. Unit is in
107− useconds. Step and range are driver-specific.
107+ microseconds. Step and range are driver-specific.
108108
109109 ``V4L2_CID_AUDIO_LIMITER_DEVIATION (integer)``
110110 Configures audio frequency deviation level in Hz. The range and step
@@ -121,16 +121,16 @@ FM_TX Control IDs · 10 unmodified lines
121121 range and step are driver-specific.
122122
123123 ``V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (integer)``
124− Sets the threshold level for audio compression freature. It is a dB
124+ Sets the threshold level for audio compression feature. It is a dB
125125 value. The range and step are driver-specific.
126126
127127 ``V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (integer)``
128− Sets the attack time for audio compression feature. It is a useconds
128+ Sets the attack time for audio compression feature. It is a microseconds
129129 value. The range and step are driver-specific.
130130
131131 ``V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (integer)``
132132 Sets the release time for audio compression feature. It is a
133− useconds value. The range and step are driver-specific.
133+ microseconds value. The range and step are driver-specific.
134134
135135 ``V4L2_CID_PILOT_TONE_ENABLED (boolean)``
136136 Enables or disables the pilot tone generation feature.
@@ -143,17 +143,12 @@ FM_TX Control IDs · 6 unmodified lines
143143 Configures pilot tone frequency value. Unit is in Hz. The range and
144144 step are driver-specific.
145145
146−``V4L2_CID_TUNE_PREEMPHASIS``
147− (enum)
148−
149−enum v4l2_preemphasis -
146+``V4L2_CID_TUNE_PREEMPHASIS (enum)``
150147 Configures the pre-emphasis value for broadcasting. A pre-emphasis
151148 filter is applied to the broadcast to accentuate the high audio
152149 frequencies. Depending on the region, a time constant of either 50
153− or 75 useconds is used. The enum v4l2_preemphasis defines possible
154− values for pre-emphasis. Here they are:
155−
156−
150+ or 75 microseconds is used. The enum v4l2_preemphasis defines possible
151+ values for pre-emphasis. They are:
157152
158153 .. flat-table::
159154 :header-rows: 0
@@ -166,8 +161,6 @@ enum v4l2_preemphasis - · 6 unmodified lines
166161 * - ``V4L2_PREEMPHASIS_75_uS``
167162 - A pre-emphasis of 75 uS is used.
168163
169−
170−
171164 ``V4L2_CID_TUNE_POWER_LEVEL (integer)``
172165 Sets the output power level for signal transmission. Unit is in
173166 dBuV. Range and step are driver-specific.
Documentation/userspace-api/media/v4l/meta-formats.rst+1−0
@@ -20,6 +20,7 @@ These formats are used for the :ref:`metadata` interface only. · 19 unmodified lines
2020 metafmt-pisp-fe
2121 metafmt-rkisp1
2222 metafmt-uvc
23+ metafmt-uvc-msxu-1-5
2324 metafmt-vivid
2425 metafmt-vsp1-hgo
2526 metafmt-vsp1-hgt
Documentation/userspace-api/media/v4l/metafmt-uvc-msxu-1-5.rst+23−0
@@ -0,0 +1,23 @@
1+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
2+
3+.. _v4l2-meta-fmt-uvc-msxu-1-5:
4+
5+***********************************
6+V4L2_META_FMT_UVC_MSXU_1_5 ('UVCM')
7+***********************************
8+
9+Microsoft(R)'s UVC Payload Metadata.
10+
11+
12+Description
13+===========
14+
15+V4L2_META_FMT_UVC_MSXU_1_5 buffers follow the metadata buffer layout of
16+V4L2_META_FMT_UVC with the only difference that it includes all the UVC
17+metadata in the `buffer[]` field, not just the first 2-12 bytes.
18+
19+The metadata format follows the specification from Microsoft(R) [1].
20+
21+.. _1:
22+
23+[1] https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/uvc-extensions-1-5
Documentation/userspace-api/media/v4l/metafmt-uvc.rst+3−1
@@ -44,7 +44,9 @@ Each individual block contains the following fields: · 43 unmodified lines
4444 them
4545 * - :cspan:`1` *The rest is an exact copy of the UVC payload header:*
4646 * - __u8 length;
47− - length of the rest of the block, including this field
47+ - length of the rest of the block, including this field. Please note that
48+ regardless of this value, for V4L2_META_FMT_UVC the kernel will never
49+ copy more than 2-12 bytes.
4850 * - __u8 flags;
4951 - Flags, indicating presence of other standard UVC fields
5052 * - __u8 buf[];
Documentation/userspace-api/media/v4l/pixfmt-bayer.rst+1−0
@@ -19,6 +19,7 @@ orders. See also `the Wikipedia article on Bayer filter · 18 unmodified lines
1919 .. toctree::
2020 :maxdepth: 1
2121
22+ pixfmt-rawnn-cru
2223 pixfmt-srggb8
2324 pixfmt-srggb8-pisp-comp
2425 pixfmt-srggb10
Documentation/userspace-api/media/v4l/pixfmt-rawnn-cru.rst+143−0
@@ -0,0 +1,143 @@
1+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
2+
3+.. _v4l2-pix-fmt-raw-cru10:
4+.. _v4l2-pix-fmt-raw-cru12:
5+.. _v4l2-pix-fmt-raw-cru14:
6+.. _v4l2-pix-fmt-raw-cru20:
7+
8+**********************************************************************************************************************************
9+V4L2_PIX_FMT_RAW_CRU10 ('CR10'), V4L2_PIX_FMT_RAW_CRU12 ('CR12'), V4L2_PIX_FMT_RAW_CRU14 ('CR14'), V4L2_PIX_FMT_RAW_CRU20 ('CR20')
10+**********************************************************************************************************************************
11+
12+===============================================================
13+Renesas RZ/V2H Camera Receiver Unit 64-bit packed pixel formats
14+===============================================================
15+
16+| V4L2_PIX_FMT_RAW_CRU10 (CR10)
17+| V4L2_PIX_FMT_RAW_CRU12 (CR12)
18+| V4L2_PIX_FMT_RAW_CRU14 (CR14)
19+| V4L2_PIX_FMT_RAW_CRU20 (CR20)
20+
21+Description
22+===========
23+
24+These pixel formats are some of the RAW outputs for the Camera Receiver Unit in
25+the Renesas RZ/V2H SoC. They are raw formats which pack pixels contiguously into
26+64-bit units, with the 4 or 8 most significant bits padded.
27+
28+**Byte Order**
29+
30+.. flat-table:: RAW formats
31+ :header-rows: 2
32+ :stub-columns: 0
33+ :widths: 36 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
34+ :fill-cells:
35+
36+ * - :rspan:`1` Pixel Format Code
37+ - :cspan:`63` Data organization
38+ * - 63
39+ - 62
40+ - 61
41+ - 60
42+ - 59
43+ - 58
44+ - 57
45+ - 56
46+ - 55
47+ - 54
48+ - 53
49+ - 52
50+ - 51
51+ - 50
52+ - 49
53+ - 48
54+ - 47
55+ - 46
56+ - 45
57+ - 44
58+ - 43
59+ - 42
60+ - 41
61+ - 40
62+ - 39
63+ - 38
64+ - 37
65+ - 36
66+ - 35
67+ - 34
68+ - 33
69+ - 32
70+ - 31
71+ - 30
72+ - 29
73+ - 28
74+ - 27
75+ - 26
76+ - 25
77+ - 24
78+ - 23
79+ - 22
80+ - 21
81+ - 20
82+ - 19
83+ - 18
84+ - 17
85+ - 16
86+ - 15
87+ - 14
88+ - 13
89+ - 12
90+ - 11
91+ - 10
92+ - 9
93+ - 8
94+ - 7
95+ - 6
96+ - 5
97+ - 4
98+ - 3
99+ - 2
100+ - 1
101+ - 0
102+ * - V4L2_PIX_FMT_RAW_CRU10
103+ - 0
104+ - 0
105+ - 0
106+ - 0
107+ - :cspan:`9` P5
108+ - :cspan:`9` P4
109+ - :cspan:`9` P3
110+ - :cspan:`9` P2
111+ - :cspan:`9` P1
112+ - :cspan:`9` P0
113+ * - V4L2_PIX_FMT_RAW_CRU12
114+ - 0
115+ - 0
116+ - 0
117+ - 0
118+ - :cspan:`11` P4
119+ - :cspan:`11` P3
120+ - :cspan:`11` P2
121+ - :cspan:`11` P1
122+ - :cspan:`11` P0
123+ * - V4L2_PIX_FMT_RAW_CRU14
124+ - 0
125+ - 0
126+ - 0
127+ - 0
128+ - 0
129+ - 0
130+ - 0
131+ - 0
132+ - :cspan:`13` P3
133+ - :cspan:`13` P2
134+ - :cspan:`13` P1
135+ - :cspan:`13` P0
136+ * - V4L2_PIX_FMT_RAW_CRU20
137+ - 0
138+ - 0
139+ - 0
140+ - 0
141+ - :cspan:`19` P2
142+ - :cspan:`19` P1
143+ - :cspan:`19` P0
Documentation/userspace-api/media/v4l/pixfmt-srggb12p.rst+2−2
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 .. _v4l2-pix-fmt-sgrbg12p:
77
88 *******************************************************************************************************************************
9−V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC'),
9+V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC')
1010 *******************************************************************************************************************************
1111
1212
@@ -20,7 +20,7 @@ Description · 7 unmodified lines
2020 These four pixel formats are packed raw sRGB / Bayer formats with 12
2121 bits per colour. Every two consecutive samples are packed into three
2222 bytes. Each of the first two bytes contain the 8 high order bits of
23−the pixels, and the third byte contains the four least significants
23+the pixels, and the third byte contains the four least significant
2424 bits of each pixel, in the same order.
2525
2626 Each n-pixel row contains n/2 green samples and n/2 blue or red
Documentation/userspace-api/media/v4l/pixfmt-srggb14p.rst+1−1
@@ -24,7 +24,7 @@ These four pixel formats are packed raw sRGB / Bayer formats with 14 · 23 unmodified lines
2424 bits per colour. Every four consecutive samples are packed into seven
2525 bytes. Each of the first four bytes contain the eight high order bits
2626 of the pixels, and the three following bytes contains the six least
27−significants bits of each pixel, in the same order.
27+significant bits of each pixel, in the same order.
2828
2929 Each n-pixel row contains n/2 green samples and n/2 blue or red samples,
3030 with alternating green-red and green-blue rows. They are conventionally
MAINTAINERS+31−1
@@ -824,7 +824,7 @@ F: drivers/media/platform/allegro-dvt/ · 823 unmodified lines
824824
825825 ALLIED VISION ALVIUM CAMERA DRIVER
826826 M: Tommaso Merciai <tomm.merciai@gmail.com>
827−M: Martin Hecht <martin.hecht@avnet.eu>
827+M: Martin Hecht <mhecht73@gmail.com>
828828 L: linux-media@vger.kernel.org
829829 S: Maintained
830830 F: Documentation/devicetree/bindings/media/i2c/alliedvision,alvium-csi2.yaml
@@ -12397,6 +12397,15 @@ T: git git://linuxtv.org/media.git · 11566 unmodified lines
1239712397 F: Documentation/admin-guide/media/ipu6-isys.rst
1239812398 F: drivers/media/pci/intel/ipu6/
1239912399
12400+INTEL IPU7 INPUT SYSTEM DRIVER
12401+M: Sakari Ailus <sakari.ailus@linux.intel.com>
12402+R: Bingbu Cao <bingbu.cao@intel.com>
12403+R: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
12404+L: linux-media@vger.kernel.org
12405+S: Maintained
12406+T: git git://linuxtv.org/media.git
12407+F: drivers/staging/media/ipu7/
12408+
1240012409 INTEL ISHTP ECLITE DRIVER
1240112410 M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
1240212411 L: platform-driver-x86@vger.kernel.org
@@ -12684,6 +12693,16 @@ W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi · 281 unmodified lines
1268412693 T: git https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git/
1268512694 F: drivers/net/wireless/intel/iwlwifi/
1268612695
12696+INTEL VISION SENSING CONTROLLER DRIVER
12697+M: Sakari Ailus <sakari.ailus@linux.intel.com>
12698+R: Bingbu Cao <bingbu.cao@intel.com>
12699+R: Lixu Zhang <lixu.zhang@intel.com>
12700+R: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
12701+L: linux-media@vger.kernel.org
12702+S: Maintained
12703+T: git git://linuxtv.org/media.git
12704+F: drivers/media/pci/intel/ivsc/
12705+
1268712706 INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER
1268812707 S: Orphan
1268912708 W: https://slimbootloader.github.io/security/firmware-update.html
@@ -18134,6 +18153,7 @@ NXP i.MX 8M ISI DRIVER · 5444 unmodified lines
1813418153 M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
1813518154 L: linux-media@vger.kernel.org
1813618155 S: Maintained
18156+F: Documentation/devicetree/bindings/media/fsl,imx8*-isi.yaml
1813718157 F: Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
1813818158 F: drivers/media/platform/nxp/imx8-isi/
1813918159
@@ -20548,6 +20568,7 @@ QUALCOMM CAMERA SUBSYSTEM DRIVER · 2408 unmodified lines
2054820568 M: Robert Foss <rfoss@kernel.org>
2054920569 M: Todor Tomov <todor.too@gmail.com>
2055020570 M: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
20571+R: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
2055120572 L: linux-media@vger.kernel.org
2055220573 S: Maintained
2055320574 F: Documentation/admin-guide/media/qcom_camss.rst
@@ -21693,6 +21714,14 @@ S: Maintained · 1139 unmodified lines
2169321714 F: Documentation/devicetree/bindings/media/rockchip-rga.yaml
2169421715 F: drivers/media/platform/rockchip/rga/
2169521716
21717+ROCKCHIP RKVDEC VIDEO DECODER DRIVER
21718+M: Detlev Casanova <detlev.casanova@collabora.com>
21719+L: linux-media@vger.kernel.org
21720+L: linux-rockchip@lists.infradead.org
21721+S: Maintained
21722+F: Documentation/devicetree/bindings/media/rockchip,vdec.yaml
21723+F: drivers/media/platform/rockchip/rkvdec/
21724+
2169621725 ROCKCHIP RK3308 INTERNAL AUDIO CODEC
2169721726 M: Luca Ceresoli <luca.ceresoli@bootlin.com>
2169821727 S: Maintained
@@ -26081,6 +26110,7 @@ S: Maintained · 4382 unmodified lines
2608126110 W: http://www.ideasonboard.org/uvc/
2608226111 T: git git://linuxtv.org/media.git
2608326112 F: Documentation/userspace-api/media/drivers/uvcvideo.rst
26113+F: Documentation/userspace-api/media/v4l/metafmt-uvc-msxu-1-5.rst
2608426114 F: Documentation/userspace-api/media/v4l/metafmt-uvc.rst
2608526115 F: drivers/media/common/uvc.c
2608626116 F: drivers/media/usb/uvc/
drivers/media/cec/core/cec-pin-error-inj.c+58−1
@@ -91,16 +91,22 @@ bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line) · 90 unmodified lines
9191 if (!strcmp(token, "clear")) {
9292 memset(pin->error_inj, 0, sizeof(pin->error_inj));
9393 pin->rx_toggle = pin->tx_toggle = false;
94+ pin->rx_no_low_drive = false;
9495 pin->tx_ignore_nack_until_eom = false;
9596 pin->tx_custom_pulse = false;
9697 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
9798 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
99+ pin->tx_glitch_low_usecs = CEC_TIM_GLITCH_DEFAULT;
100+ pin->tx_glitch_high_usecs = CEC_TIM_GLITCH_DEFAULT;
101+ pin->tx_glitch_falling_edge = false;
102+ pin->tx_glitch_rising_edge = false;
98103 return true;
99104 }
100105 if (!strcmp(token, "rx-clear")) {
101106 for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++)
102107 pin->error_inj[i] &= ~CEC_ERROR_INJ_RX_MASK;
103108 pin->rx_toggle = false;
109+ pin->rx_no_low_drive = false;
104110 return true;
105111 }
106112 if (!strcmp(token, "tx-clear")) {
@@ -111,6 +117,14 @@ bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line) · 4 unmodified lines
111117 pin->tx_custom_pulse = false;
112118 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
113119 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
120+ pin->tx_glitch_low_usecs = CEC_TIM_GLITCH_DEFAULT;
121+ pin->tx_glitch_high_usecs = CEC_TIM_GLITCH_DEFAULT;
122+ pin->tx_glitch_falling_edge = false;
123+ pin->tx_glitch_rising_edge = false;
124+ return true;
125+ }
126+ if (!strcmp(token, "rx-no-low-drive")) {
127+ pin->rx_no_low_drive = true;
114128 return true;
115129 }
116130 if (!strcmp(token, "tx-ignore-nack-until-eom")) {
@@ -122,6 +136,14 @@ bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line) · 5 unmodified lines
122136 cec_pin_start_timer(pin);
123137 return true;
124138 }
139+ if (!strcmp(token, "tx-glitch-falling-edge")) {
140+ pin->tx_glitch_falling_edge = true;
141+ return true;
142+ }
143+ if (!strcmp(token, "tx-glitch-rising-edge")) {
144+ pin->tx_glitch_rising_edge = true;
145+ return true;
146+ }
125147 if (!p)
126148 return false;
127149
@@ -139,7 +161,23 @@ bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line) · 11 unmodified lines
139161
140162 if (kstrtou32(p, 0, &usecs) || usecs > 10000000)
141163 return false;
142− pin->tx_custom_high_usecs = usecs;
164+ pin->tx_glitch_high_usecs = usecs;
165+ return true;
166+ }
167+ if (!strcmp(token, "tx-glitch-low-usecs")) {
168+ u32 usecs;
169+
170+ if (kstrtou32(p, 0, &usecs) || usecs > 100)
171+ return false;
172+ pin->tx_glitch_low_usecs = usecs;
173+ return true;
174+ }
175+ if (!strcmp(token, "tx-glitch-high-usecs")) {
176+ u32 usecs;
177+
178+ if (kstrtou32(p, 0, &usecs) || usecs > 100)
179+ return false;
180+ pin->tx_glitch_high_usecs = usecs;
143181 return true;
144182 }
145183
@@ -273,6 +311,9 @@ int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf) · 127 unmodified lines
273311 seq_puts(sf, "# <op> rx-clear clear all rx error injections for <op>\n");
274312 seq_puts(sf, "# <op> tx-clear clear all tx error injections for <op>\n");
275313 seq_puts(sf, "#\n");
314+ seq_puts(sf, "# RX error injection settings:\n");
315+ seq_puts(sf, "# rx-no-low-drive do not generate low-drive pulses\n");
316+ seq_puts(sf, "#\n");
276317 seq_puts(sf, "# RX error injection:\n");
277318 seq_puts(sf, "# <op>[,<mode>] rx-nack NACK the message instead of sending an ACK\n");
278319 seq_puts(sf, "# <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position\n");
@@ -285,6 +326,10 @@ int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf) · 6 unmodified lines
285326 seq_puts(sf, "# tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse\n");
286327 seq_puts(sf, "# tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse\n");
287328 seq_puts(sf, "# tx-custom-pulse transmit the custom pulse once the bus is idle\n");
329+ seq_puts(sf, "# tx-glitch-low-usecs <usecs> define the 'low' time for the glitch pulse\n");
330+ seq_puts(sf, "# tx-glitch-high-usecs <usecs> define the 'high' time for the glitch pulse\n");
331+ seq_puts(sf, "# tx-glitch-falling-edge send the glitch pulse after every falling edge\n");
332+ seq_puts(sf, "# tx-glitch-rising-edge send the glitch pulse after every rising edge\n");
288333 seq_puts(sf, "#\n");
289334 seq_puts(sf, "# TX error injection:\n");
290335 seq_puts(sf, "# <op>[,<mode>] tx-no-eom don't set the EOM bit\n");
@@ -332,8 +377,14 @@ int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf) · 41 unmodified lines
332377 }
333378 }
334379
380+ if (pin->rx_no_low_drive)
381+ seq_puts(sf, "rx-no-low-drive\n");
335382 if (pin->tx_ignore_nack_until_eom)
336383 seq_puts(sf, "tx-ignore-nack-until-eom\n");
384+ if (pin->tx_glitch_falling_edge)
385+ seq_puts(sf, "tx-glitch-falling-edge\n");
386+ if (pin->tx_glitch_rising_edge)
387+ seq_puts(sf, "tx-glitch-rising-edge\n");
337388 if (pin->tx_custom_pulse)
338389 seq_puts(sf, "tx-custom-pulse\n");
339390 if (pin->tx_custom_low_usecs != CEC_TIM_CUSTOM_DEFAULT)
@@ -342,5 +393,11 @@ int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf) · 2 unmodified lines
342393 if (pin->tx_custom_high_usecs != CEC_TIM_CUSTOM_DEFAULT)
343394 seq_printf(sf, "tx-custom-high-usecs %u\n",
344395 pin->tx_custom_high_usecs);
396+ if (pin->tx_glitch_low_usecs != CEC_TIM_GLITCH_DEFAULT)
397+ seq_printf(sf, "tx-glitch-low-usecs %u\n",
398+ pin->tx_glitch_low_usecs);
399+ if (pin->tx_glitch_high_usecs != CEC_TIM_GLITCH_DEFAULT)
400+ seq_printf(sf, "tx-glitch-high-usecs %u\n",
401+ pin->tx_glitch_high_usecs);
345402 return 0;
346403 }
drivers/media/cec/core/cec-pin-priv.h+8−0
@@ -164,6 +164,9 @@ enum cec_pin_state { · 163 unmodified lines
164164 /* The default for the low/high time of the custom pulse */
165165 #define CEC_TIM_CUSTOM_DEFAULT 1000
166166
167+/* The default for the low/high time of the glitch pulse */
168+#define CEC_TIM_GLITCH_DEFAULT 1
169+
167170 #define CEC_NUM_PIN_EVENTS 128
168171 #define CEC_PIN_EVENT_FL_IS_HIGH (1 << 0)
169172 #define CEC_PIN_EVENT_FL_DROPPED (1 << 1)
@@ -225,12 +228,17 @@ struct cec_pin { · 55 unmodified lines
225228 u32 timer_max_overrun;
226229 u32 timer_sum_overrun;
227230
231+ bool rx_no_low_drive;
228232 u32 tx_custom_low_usecs;
229233 u32 tx_custom_high_usecs;
234+ u32 tx_glitch_low_usecs;
235+ u32 tx_glitch_high_usecs;
230236 bool tx_ignore_nack_until_eom;
231237 bool tx_custom_pulse;
232238 bool tx_generated_poll;
233239 bool tx_post_eom;
240+ bool tx_glitch_falling_edge;
241+ bool tx_glitch_rising_edge;
234242 u8 tx_extra_bytes;
235243 u32 tx_low_drive_cnt;
236244 #ifdef CONFIG_CEC_PIN_ERROR_INJ
drivers/media/cec/core/cec-pin.c+30−1
@@ -142,15 +142,42 @@ static bool cec_pin_read(struct cec_pin *pin) · 141 unmodified lines
142142 return v;
143143 }
144144
145+static void cec_pin_insert_glitch(struct cec_pin *pin, bool rising_edge)
146+{
147+ /*
148+ * Insert a short glitch after the falling or rising edge to
149+ * simulate reflections on the CEC line. This can be used to
150+ * test deglitch filters, which should be present in CEC devices
151+ * to deal with noise on the line.
152+ */
153+ if (!pin->tx_glitch_high_usecs || !pin->tx_glitch_low_usecs)
154+ return;
155+ if (rising_edge) {
156+ udelay(pin->tx_glitch_high_usecs);
157+ call_void_pin_op(pin, low);
158+ udelay(pin->tx_glitch_low_usecs);
159+ call_void_pin_op(pin, high);
160+ } else {
161+ udelay(pin->tx_glitch_low_usecs);
162+ call_void_pin_op(pin, high);
163+ udelay(pin->tx_glitch_high_usecs);
164+ call_void_pin_op(pin, low);
165+ }
166+}
167+
145168 static void cec_pin_low(struct cec_pin *pin)
146169 {
147170 call_void_pin_op(pin, low);
171+ if (pin->tx_glitch_falling_edge && pin->adap->cec_pin_is_high)
172+ cec_pin_insert_glitch(pin, false);
148173 cec_pin_update(pin, false, false);
149174 }
150175
151176 static bool cec_pin_high(struct cec_pin *pin)
152177 {
153178 call_void_pin_op(pin, high);
179+ if (pin->tx_glitch_rising_edge && !pin->adap->cec_pin_is_high)
180+ cec_pin_insert_glitch(pin, true);
154181 return cec_pin_read(pin);
155182 }
156183
@@ -770,7 +797,7 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) · 613 unmodified lines
770797 * Go to low drive state when the total bit time is
771798 * too short.
772799 */
773− if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) {
800+ if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN && !pin->rx_no_low_drive) {
774801 if (!pin->rx_data_bit_too_short_cnt++) {
775802 pin->rx_data_bit_too_short_ts = ktime_to_ns(pin->ts);
776803 pin->rx_data_bit_too_short_delta = delta;
@@ -1350,6 +1377,8 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, · 573 unmodified lines
13501377 init_waitqueue_head(&pin->kthread_waitq);
13511378 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
13521379 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;
1380+ pin->tx_glitch_low_usecs = CEC_TIM_GLITCH_DEFAULT;
1381+ pin->tx_glitch_high_usecs = CEC_TIM_GLITCH_DEFAULT;
13531382
13541383 adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name,
13551384 caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN,
drivers/media/cec/platform/cec-gpio/cec-gpio.c+30−28
@@ -61,49 +61,51 @@ static void cec_gpio_low(struct cec_adapter *adap) · 60 unmodified lines
6161 gpiod_set_value(cec->cec_gpio, 0);
6262 }
6363
64−static irqreturn_t cec_hpd_gpio_irq_handler_thread(int irq, void *priv)
64+static irqreturn_t cec_gpio_5v_irq_handler_thread(int irq, void *priv)
6565 {
6666 struct cec_gpio *cec = priv;
67+ int val = gpiod_get_value_cansleep(cec->v5_gpio);
68+ bool is_high = val > 0;
6769
68− cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts);
70+ if (val < 0 || is_high == cec->v5_is_high)
71+ return IRQ_HANDLED;
72+
73+ cec->v5_is_high = is_high;
74+ cec_queue_pin_5v_event(cec->adap, cec->v5_is_high, cec->v5_ts);
6975 return IRQ_HANDLED;
7076 }
7177
72−static irqreturn_t cec_5v_gpio_irq_handler(int irq, void *priv)
78+static irqreturn_t cec_gpio_5v_irq_handler(int irq, void *priv)
7379 {
7480 struct cec_gpio *cec = priv;
75− int val = gpiod_get_value(cec->v5_gpio);
76− bool is_high = val > 0;
7781
78− if (val < 0 || is_high == cec->v5_is_high)
79− return IRQ_HANDLED;
8082 cec->v5_ts = ktime_get();
81− cec->v5_is_high = is_high;
8283 return IRQ_WAKE_THREAD;
8384 }
8485
85−static irqreturn_t cec_5v_gpio_irq_handler_thread(int irq, void *priv)
86+static irqreturn_t cec_gpio_hpd_irq_handler_thread(int irq, void *priv)
8687 {
8788 struct cec_gpio *cec = priv;
89+ int val = gpiod_get_value_cansleep(cec->hpd_gpio);
90+ bool is_high = val > 0;
8891
89− cec_queue_pin_5v_event(cec->adap, cec->v5_is_high, cec->v5_ts);
92+ if (val < 0 || is_high == cec->hpd_is_high)
93+ return IRQ_HANDLED;
94+
95+ cec->hpd_is_high = is_high;
96+ cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts);
9097 return IRQ_HANDLED;
9198 }
9299
93−static irqreturn_t cec_hpd_gpio_irq_handler(int irq, void *priv)
100+static irqreturn_t cec_gpio_hpd_irq_handler(int irq, void *priv)
94101 {
95102 struct cec_gpio *cec = priv;
96− int val = gpiod_get_value(cec->hpd_gpio);
97− bool is_high = val > 0;
98103
99− if (val < 0 || is_high == cec->hpd_is_high)
100− return IRQ_HANDLED;
101104 cec->hpd_ts = ktime_get();
102− cec->hpd_is_high = is_high;
103105 return IRQ_WAKE_THREAD;
104106 }
105107
106−static irqreturn_t cec_gpio_irq_handler(int irq, void *priv)
108+static irqreturn_t cec_gpio_cec_irq_handler(int irq, void *priv)
107109 {
108110 struct cec_gpio *cec = priv;
109111 int val = gpiod_get_value(cec->cec_gpio);
@@ -113,7 +115,7 @@ static irqreturn_t cec_gpio_irq_handler(int irq, void *priv) · 3 unmodified lines
113115 return IRQ_HANDLED;
114116 }
115117
116−static bool cec_gpio_enable_irq(struct cec_adapter *adap)
118+static bool cec_gpio_cec_enable_irq(struct cec_adapter *adap)
117119 {
118120 struct cec_gpio *cec = cec_get_drvdata(adap);
119121
@@ -121,7 +123,7 @@ static bool cec_gpio_enable_irq(struct cec_adapter *adap) · 1 unmodified line
121123 return true;
122124 }
123125
124−static void cec_gpio_disable_irq(struct cec_adapter *adap)
126+static void cec_gpio_cec_disable_irq(struct cec_adapter *adap)
125127 {
126128 struct cec_gpio *cec = cec_get_drvdata(adap);
127129
@@ -148,7 +150,7 @@ static int cec_gpio_read_hpd(struct cec_adapter *adap) · 20 unmodified lines
148150
149151 if (!cec->hpd_gpio)
150152 return -ENOTTY;
151− return gpiod_get_value(cec->hpd_gpio);
153+ return gpiod_get_value_cansleep(cec->hpd_gpio);
152154 }
153155
154156 static int cec_gpio_read_5v(struct cec_adapter *adap)
@@ -157,15 +159,15 @@ static int cec_gpio_read_5v(struct cec_adapter *adap) · 2 unmodified lines
157159
158160 if (!cec->v5_gpio)
159161 return -ENOTTY;
160− return gpiod_get_value(cec->v5_gpio);
162+ return gpiod_get_value_cansleep(cec->v5_gpio);
161163 }
162164
163165 static const struct cec_pin_ops cec_gpio_pin_ops = {
164166 .read = cec_gpio_read,
165167 .low = cec_gpio_low,
166168 .high = cec_gpio_high,
167− .enable_irq = cec_gpio_enable_irq,
168− .disable_irq = cec_gpio_disable_irq,
169+ .enable_irq = cec_gpio_cec_enable_irq,
170+ .disable_irq = cec_gpio_cec_disable_irq,
169171 .status = cec_gpio_status,
170172 .read_hpd = cec_gpio_read_hpd,
171173 .read_5v = cec_gpio_read_5v,
@@ -209,7 +211,7 @@ static int cec_gpio_probe(struct platform_device *pdev) · 37 unmodified lines
209211 if (IS_ERR(cec->adap))
210212 return PTR_ERR(cec->adap);
211213
212− ret = devm_request_irq(dev, cec->cec_irq, cec_gpio_irq_handler,
214+ ret = devm_request_irq(dev, cec->cec_irq, cec_gpio_cec_irq_handler,
213215 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,
214216 cec->adap->name, cec);
215217 if (ret)
@@ -218,8 +220,8 @@ static int cec_gpio_probe(struct platform_device *pdev) · 2 unmodified lines
218220 if (cec->hpd_gpio) {
219221 cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio);
220222 ret = devm_request_threaded_irq(dev, cec->hpd_irq,
221− cec_hpd_gpio_irq_handler,
222− cec_hpd_gpio_irq_handler_thread,
223+ cec_gpio_hpd_irq_handler,
224+ cec_gpio_hpd_irq_handler_thread,
223225 IRQF_ONESHOT |
224226 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
225227 "hpd-gpio", cec);
@@ -230,8 +232,8 @@ static int cec_gpio_probe(struct platform_device *pdev) · 4 unmodified lines
230232 if (cec->v5_gpio) {
231233 cec->v5_irq = gpiod_to_irq(cec->v5_gpio);
232234 ret = devm_request_threaded_irq(dev, cec->v5_irq,
233− cec_5v_gpio_irq_handler,
234− cec_5v_gpio_irq_handler_thread,
235+ cec_gpio_5v_irq_handler,
236+ cec_gpio_5v_irq_handler_thread,
235237 IRQF_ONESHOT |
236238 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
237239 "v5-gpio", cec);
drivers/media/cec/usb/rainshadow/rainshadow-cec.c+2−1
@@ -171,11 +171,12 @@ static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data, · 170 unmodified lines
171171 {
172172 struct rain *rain = serio_get_drvdata(serio);
173173
174+ spin_lock(&rain->buf_lock);
174175 if (rain->buf_len == DATA_SIZE) {
176+ spin_unlock(&rain->buf_lock);
175177 dev_warn_once(rain->dev, "buffer overflow\n");
176178 return IRQ_HANDLED;
177179 }
178− spin_lock(&rain->buf_lock);
179180 rain->buf_len++;
180181 rain->buf[rain->buf_wr_idx] = data;
181182 rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff;
drivers/media/common/b2c2/flexcop-i2c.c+1−1
@@ -209,7 +209,7 @@ static u32 flexcop_i2c_func(struct i2c_adapter *adapter) · 208 unmodified lines
209209 return I2C_FUNC_I2C;
210210 }
211211
212−static struct i2c_algorithm flexcop_algo = {
212+static const struct i2c_algorithm flexcop_algo = {
213213 .master_xfer = flexcop_master_xfer,
214214 .functionality = flexcop_i2c_func,
215215 };
drivers/media/dvb-frontends/cxd2820r_core.c+3−3
@@ -433,7 +433,7 @@ static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr, · 432 unmodified lines
433433 return cxd2820r_gpio(&priv->fe, gpio);
434434 }
435435
436−static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
436+static int cxd2820r_gpio_set(struct gpio_chip *chip, unsigned int nr, int val)
437437 {
438438 struct cxd2820r_priv *priv = gpiochip_get_data(chip);
439439 struct i2c_client *client = priv->client[0];
@@ -446,7 +446,7 @@ static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val) · 6 unmodified lines
446446
447447 (void) cxd2820r_gpio(&priv->fe, gpio);
448448
449− return;
449+ return 0;
450450 }
451451
452452 static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr)
@@ -651,7 +651,7 @@ static int cxd2820r_probe(struct i2c_client *client) · 198 unmodified lines
651651 priv->gpio_chip.parent = &client->dev;
652652 priv->gpio_chip.owner = THIS_MODULE;
653653 priv->gpio_chip.direction_output = cxd2820r_gpio_direction_output;
654− priv->gpio_chip.set = cxd2820r_gpio_set;
654+ priv->gpio_chip.set_rv = cxd2820r_gpio_set;
655655 priv->gpio_chip.get = cxd2820r_gpio_get;
656656 priv->gpio_chip.base = -1; /* Dynamic allocation */
657657 priv->gpio_chip.ngpio = GPIO_COUNT;
drivers/media/dvb-frontends/dib7000p.c+8−0
@@ -2193,6 +2193,8 @@ static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_ms · 2192 unmodified lines
21932193 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
21942194 u8 n_overflow = 1;
21952195 u16 i = 1000;
2196+ if (msg[0].len < 3)
2197+ return -EOPNOTSUPP;
21962198 u16 serpar_num = msg[0].buf[0];
21972199
21982200 while (n_overflow == 1 && i) {
@@ -2212,6 +2214,8 @@ static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg · 13 unmodified lines
22122214 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
22132215 u8 n_overflow = 1, n_empty = 1;
22142216 u16 i = 1000;
2217+ if (msg[0].len < 1 || msg[1].len < 2)
2218+ return -EOPNOTSUPP;
22152219 u16 serpar_num = msg[0].buf[0];
22162220 u16 read_word;
22172221
@@ -2256,8 +2260,12 @@ static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, · 38 unmodified lines
22562260 u16 word;
22572261
22582262 if (num == 1) { /* write */
2263+ if (msg[0].len < 3)
2264+ return -EOPNOTSUPP;
22592265 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
22602266 } else {
2267+ if (msg[1].len < 2)
2268+ return -EOPNOTSUPP;
22612269 word = dib7000p_read_word(state, apb_address);
22622270 msg[1].buf[0] = (word >> 8) & 0xff;
22632271 msg[1].buf[1] = (word) & 0xff;
drivers/media/i2c/Kconfig+14−27
@@ -141,6 +141,7 @@ config VIDEO_IMX214 · 140 unmodified lines
141141 depends on GPIOLIB
142142 select REGMAP_I2C
143143 select V4L2_CCI_I2C
144+ select VIDEO_CCS_PLL
144145 help
145146 This is a Video4Linux2 sensor driver for the Sony
146147 IMX214 camera.
@@ -765,24 +766,25 @@ config VIDEO_THP7312 · 618 unmodified lines
765766
766767 endmenu
767768
768−menu "Lens drivers"
769− visible if MEDIA_CAMERA_SUPPORT
769+menuconfig VIDEO_CAMERA_LENS
770+ bool "Lens drivers"
771+ depends on MEDIA_CAMERA_SUPPORT && I2C
772+ select MEDIA_CONTROLLER
773+ select V4L2_FWNODE
774+ select VIDEO_V4L2_SUBDEV_API
775+ default y
776+
777+if VIDEO_CAMERA_LENS
770778
771779 config VIDEO_AD5820
772780 tristate "AD5820 lens voice coil support"
773− depends on GPIOLIB && I2C && VIDEO_DEV
774− select MEDIA_CONTROLLER
775− select V4L2_ASYNC
781+ depends on GPIOLIB
776782 help
777783 This is a driver for the AD5820 camera lens voice coil.
778784 It is used for example in Nokia N900 (RX-51).
779785
780786 config VIDEO_AK7375
781787 tristate "AK7375 lens voice coil support"
782− depends on I2C && VIDEO_DEV
783− select MEDIA_CONTROLLER
784− select VIDEO_V4L2_SUBDEV_API
785− select V4L2_ASYNC
786788 help
787789 This is a driver for the AK7375 camera lens voice coil.
788790 AK7375 is a 12 bit DAC with 120mA output current sink
@@ -791,10 +793,7 @@ config VIDEO_AK7375 · 2 unmodified lines
791793
792794 config VIDEO_DW9714
793795 tristate "DW9714 lens voice coil support"
794− depends on I2C && VIDEO_DEV
795− select MEDIA_CONTROLLER
796− select VIDEO_V4L2_SUBDEV_API
797− select V4L2_ASYNC
796+ depends on GPIOLIB
798797 help
799798 This is a driver for the DW9714 camera lens voice coil.
800799 DW9714 is a 10 bit DAC with 120mA output current sink
@@ -803,10 +802,6 @@ config VIDEO_DW9714 · 2 unmodified lines
803802
804803 config VIDEO_DW9719
805804 tristate "DW9719 lens voice coil support"
806− depends on I2C && VIDEO_DEV
807− select MEDIA_CONTROLLER
808− select VIDEO_V4L2_SUBDEV_API
809− select V4L2_ASYNC
810805 select V4L2_CCI_I2C
811806 help
812807 This is a driver for the DW9719 camera lens voice coil.
@@ -815,10 +810,6 @@ config VIDEO_DW9719 · 2 unmodified lines
815810
816811 config VIDEO_DW9768
817812 tristate "DW9768 lens voice coil support"
818− depends on I2C && VIDEO_DEV
819− select MEDIA_CONTROLLER
820− select VIDEO_V4L2_SUBDEV_API
821− select V4L2_FWNODE
822813 help
823814 This is a driver for the DW9768 camera lens voice coil.
824815 DW9768 is a 10 bit DAC with 100mA output current sink
@@ -827,17 +818,13 @@ config VIDEO_DW9768 · 2 unmodified lines
827818
828819 config VIDEO_DW9807_VCM
829820 tristate "DW9807 lens voice coil support"
830− depends on I2C && VIDEO_DEV
831− select MEDIA_CONTROLLER
832− select VIDEO_V4L2_SUBDEV_API
833− select V4L2_ASYNC
834821 help
835822 This is a driver for the DW9807 camera lens voice coil.
836823 DW9807 is a 10 bit DAC with 100mA output current sink
837824 capability. This is designed for linear control of
838825 voice coil motors, controlled via I2C serial interface.
839826
840−endmenu
827+endif
841828
842829 menu "Flash devices"
843830 visible if MEDIA_CAMERA_SUPPORT
@@ -1684,7 +1671,7 @@ config VIDEO_MAX96714 · 840 unmodified lines
16841671
16851672 config VIDEO_MAX96717
16861673 tristate "Maxim MAX96717 GMSL2 Serializer support"
1687− depends on OF && I2C && VIDEO_DEV && COMMON_CLK
1674+ depends on I2C && VIDEO_DEV && COMMON_CLK
16881675 select I2C_MUX
16891676 select MEDIA_CONTROLLER
16901677 select GPIOLIB
drivers/media/i2c/adv7180.c+0−16
@@ -868,21 +868,6 @@ static int adv7180_get_skip_frames(struct v4l2_subdev *sd, u32 *frames) · 867 unmodified lines
868868 return 0;
869869 }
870870
871−static int adv7180_g_pixelaspect(struct v4l2_subdev *sd, struct v4l2_fract *aspect)
872−{
873− struct adv7180_state *state = to_state(sd);
874−
875− if (state->curr_norm & V4L2_STD_525_60) {
876− aspect->numerator = 11;
877− aspect->denominator = 10;
878− } else {
879− aspect->numerator = 54;
880− aspect->denominator = 59;
881− }
882−
883− return 0;
884−}
885−
886871 static int adv7180_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
887872 {
888873 *norm = V4L2_STD_ALL;
@@ -929,7 +914,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = { · 40 unmodified lines
929914 .querystd = adv7180_querystd,
930915 .g_input_status = adv7180_g_input_status,
931916 .s_routing = adv7180_s_routing,
932− .g_pixelaspect = adv7180_g_pixelaspect,
933917 .g_tvnorms = adv7180_g_tvnorms,
934918 .s_stream = adv7180_s_stream,
935919 };
drivers/media/i2c/adv748x/adv748x-afe.c+0−17
@@ -161,22 +161,6 @@ int adv748x_afe_s_input(struct adv748x_afe *afe, unsigned int input) · 160 unmodified lines
161161 return sdp_write(state, ADV748X_SDP_INSEL, input);
162162 }
163163
164−static int adv748x_afe_g_pixelaspect(struct v4l2_subdev *sd,
165− struct v4l2_fract *aspect)
166−{
167− struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
168−
169− if (afe->curr_norm & V4L2_STD_525_60) {
170− aspect->numerator = 11;
171− aspect->denominator = 10;
172− } else {
173− aspect->numerator = 54;
174− aspect->denominator = 59;
175− }
176−
177− return 0;
178−}
179−
180164 /* -----------------------------------------------------------------------------
181165 * v4l2_subdev_video_ops
182166 */
@@ -307,7 +291,6 @@ static const struct v4l2_subdev_video_ops adv748x_afe_video_ops = { · 124 unmodified lines
307291 .g_tvnorms = adv748x_afe_g_tvnorms,
308292 .g_input_status = adv748x_afe_g_input_status,
309293 .s_stream = adv748x_afe_s_stream,
310− .g_pixelaspect = adv748x_afe_g_pixelaspect,
311294 };
312295
313296 /* -----------------------------------------------------------------------------
drivers/media/i2c/adv748x/adv748x-hdmi.c+0−10
@@ -382,19 +382,9 @@ done: · 381 unmodified lines
382382 return ret;
383383 }
384384
385−static int adv748x_hdmi_g_pixelaspect(struct v4l2_subdev *sd,
386− struct v4l2_fract *aspect)
387−{
388− aspect->numerator = 1;
389− aspect->denominator = 1;
390−
391− return 0;
392−}
393−
394385 static const struct v4l2_subdev_video_ops adv748x_video_ops_hdmi = {
395386 .g_input_status = adv748x_hdmi_g_input_status,
396387 .s_stream = adv748x_hdmi_s_stream,
397− .g_pixelaspect = adv748x_hdmi_g_pixelaspect,
398388 };
399389
400390 /* -----------------------------------------------------------------------------
drivers/media/i2c/adv7604.c+2−2
@@ -2448,8 +2448,8 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) · 2447 unmodified lines
24482448 }
24492449 cec_s_phys_addr(state->cec_adap, parent_pa, false);
24502450
2451− /* enable hotplug after 100 ms */
2452− schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 10);
2451+ /* enable hotplug after 143 ms */
2452+ schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 7);
24532453 return 0;
24542454 }
24552455
drivers/media/i2c/ds90ub913.c+3−11
@@ -203,9 +203,9 @@ static int ub913_gpio_direction_out(struct gpio_chip *gc, unsigned int offset, · 202 unmodified lines
203203 0));
204204 }
205205
206−static void ub913_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
206+static int ub913_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
207207 {
208− ub913_gpio_direction_out(gc, offset, value);
208+ return ub913_gpio_direction_out(gc, offset, value);
209209 }
210210
211211 static int ub913_gpio_of_xlate(struct gpio_chip *gc,
@@ -235,7 +235,7 @@ static int ub913_gpiochip_probe(struct ub913_data *priv) · 23 unmodified lines
235235 gc->ngpio = UB913_NUM_GPIOS;
236236 gc->get_direction = ub913_gpio_get_direction;
237237 gc->direction_output = ub913_gpio_direction_out;
238− gc->set = ub913_gpio_set;
238+ gc->set_rv = ub913_gpio_set;
239239 gc->of_xlate = ub913_gpio_of_xlate;
240240 gc->of_gpio_n_cells = 2;
241241
@@ -337,14 +337,6 @@ static int _ub913_set_routing(struct v4l2_subdev *sd, · 95 unmodified lines
337337 unsigned int i;
338338 int ret;
339339
340− /*
341− * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
342− * frame desc is made dynamically allocated.
343− */
344−
345− if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
346− return -EINVAL;
347−
348340 ret = v4l2_subdev_routing_validate(sd, routing,
349341 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
350342 if (ret)
drivers/media/i2c/ds90ub953.c+5−14
@@ -317,14 +317,13 @@ static int ub953_gpio_get(struct gpio_chip *gc, unsigned int offset) · 316 unmodified lines
317317 return !!(v & UB953_REG_GPIO_PIN_STS_GPIO_STS(offset));
318318 }
319319
320−static void ub953_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
320+static int ub953_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
321321 {
322322 struct ub953_data *priv = gpiochip_get_data(gc);
323323
324− regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA,
325− UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset),
326− value ? UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset) :
327− 0);
324+ return regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA,
325+ UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset),
326+ value ? UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset) : 0);
328327 }
329328
330329 static int ub953_gpio_of_xlate(struct gpio_chip *gc,
@@ -362,7 +361,7 @@ static int ub953_gpiochip_probe(struct ub953_data *priv) · 31 unmodified lines
362361 gc->direction_input = ub953_gpio_direction_in;
363362 gc->direction_output = ub953_gpio_direction_out;
364363 gc->get = ub953_gpio_get;
365− gc->set = ub953_gpio_set;
364+ gc->set_rv = ub953_gpio_set;
366365 gc->of_xlate = ub953_gpio_of_xlate;
367366 gc->of_gpio_n_cells = 2;
368367
@@ -400,14 +399,6 @@ static int _ub953_set_routing(struct v4l2_subdev *sd, · 31 unmodified lines
400399 };
401400 int ret;
402401
403− /*
404− * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
405− * frame desc is made dynamically allocated.
406− */
407−
408− if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
409− return -EINVAL;
410−
411402 ret = v4l2_subdev_routing_validate(sd, routing,
412403 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
413404 if (ret)
drivers/media/i2c/ds90ub960.c+0−8
@@ -3861,14 +3861,6 @@ static int _ub960_set_routing(struct v4l2_subdev *sd, · 3860 unmodified lines
38613861 };
38623862 int ret;
38633863
3864− /*
3865− * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
3866− * frame desc is made dynamically allocated.
3867− */
3868−
3869− if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
3870− return -E2BIG;
3871−
38723864 ret = v4l2_subdev_routing_validate(sd, routing,
38733865 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 |
38743866 V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX);
drivers/media/i2c/dw9714.c+45−17
@@ -2,6 +2,7 @@ · 1 unmodified line
22 // Copyright (c) 2015--2017 Intel Corporation.
33
44 #include <linux/delay.h>
5+#include <linux/gpio/consumer.h>
56 #include <linux/i2c.h>
67 #include <linux/module.h>
78 #include <linux/pm_runtime.h>
@@ -38,6 +39,7 @@ struct dw9714_device { · 30 unmodified lines
3839 struct v4l2_subdev sd;
3940 u16 current_val;
4041 struct regulator *vcc;
42+ struct gpio_desc *powerdown_gpio;
4143 };
4244
4345 static inline struct dw9714_device *to_dw9714_vcm(struct v4l2_ctrl *ctrl)
@@ -137,6 +139,28 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm) · 93 unmodified lines
137139 return hdl->error;
138140 }
139141
142+static int dw9714_power_up(struct dw9714_device *dw9714_dev)
143+{
144+ int ret;
145+
146+ ret = regulator_enable(dw9714_dev->vcc);
147+ if (ret)
148+ return ret;
149+
150+ gpiod_set_value_cansleep(dw9714_dev->powerdown_gpio, 0);
151+
152+ usleep_range(1000, 2000);
153+
154+ return 0;
155+}
156+
157+static int dw9714_power_down(struct dw9714_device *dw9714_dev)
158+{
159+ gpiod_set_value_cansleep(dw9714_dev->powerdown_gpio, 1);
160+
161+ return regulator_disable(dw9714_dev->vcc);
162+}
163+
140164 static int dw9714_probe(struct i2c_client *client)
141165 {
142166 struct dw9714_device *dw9714_dev;
@@ -144,20 +168,25 @@ static int dw9714_probe(struct i2c_client *client) · 1 unmodified line
144168
145169 dw9714_dev = devm_kzalloc(&client->dev, sizeof(*dw9714_dev),
146170 GFP_KERNEL);
147− if (dw9714_dev == NULL)
171+ if (!dw9714_dev)
148172 return -ENOMEM;
149173
150174 dw9714_dev->vcc = devm_regulator_get(&client->dev, "vcc");
151175 if (IS_ERR(dw9714_dev->vcc))
152176 return PTR_ERR(dw9714_dev->vcc);
153177
154− rval = regulator_enable(dw9714_dev->vcc);
155− if (rval < 0) {
156− dev_err(&client->dev, "failed to enable vcc: %d\n", rval);
157− return rval;
158− }
178+ dw9714_dev->powerdown_gpio = devm_gpiod_get_optional(&client->dev,
179+ "powerdown",
180+ GPIOD_OUT_HIGH);
181+ if (IS_ERR(dw9714_dev->powerdown_gpio))
182+ return dev_err_probe(&client->dev,
183+ PTR_ERR(dw9714_dev->powerdown_gpio),
184+ "could not get powerdown gpio\n");
159185
160− usleep_range(1000, 2000);
186+ rval = dw9714_power_up(dw9714_dev);
187+ if (rval)
188+ return dev_err_probe(&client->dev, rval,
189+ "failed to power up: %d\n", rval);
161190
162191 v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
163192 dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
@@ -185,7 +214,7 @@ static int dw9714_probe(struct i2c_client *client) · 21 unmodified lines
185214 return 0;
186215
187216 err_cleanup:
188− regulator_disable(dw9714_dev->vcc);
217+ dw9714_power_down(dw9714_dev);
189218 v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);
190219 media_entity_cleanup(&dw9714_dev->sd.entity);
191220
@@ -200,10 +229,10 @@ static void dw9714_remove(struct i2c_client *client) · 8 unmodified lines
200229
201230 pm_runtime_disable(&client->dev);
202231 if (!pm_runtime_status_suspended(&client->dev)) {
203− ret = regulator_disable(dw9714_dev->vcc);
232+ ret = dw9714_power_down(dw9714_dev);
204233 if (ret) {
205234 dev_err(&client->dev,
206− "Failed to disable vcc: %d\n", ret);
235+ "Failed to power down: %d\n", ret);
207236 }
208237 }
209238 pm_runtime_set_suspended(&client->dev);
@@ -234,9 +263,9 @@ static int __maybe_unused dw9714_vcm_suspend(struct device *dev) · 24 unmodified lines
234263 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
235264 }
236265
237− ret = regulator_disable(dw9714_dev->vcc);
266+ ret = dw9714_power_down(dw9714_dev);
238267 if (ret)
239− dev_err(dev, "Failed to disable vcc: %d\n", ret);
268+ dev_err(dev, "Failed to power down: %d\n", ret);
240269
241270 return ret;
242271 }
@@ -247,7 +276,7 @@ static int __maybe_unused dw9714_vcm_suspend(struct device *dev) · 4 unmodified lines
247276 * The lens position is gradually moved in units of DW9714_CTRL_STEPS,
248277 * to make the movements smoothly.
249278 */
250−static int __maybe_unused dw9714_vcm_resume(struct device *dev)
279+static int __maybe_unused dw9714_vcm_resume(struct device *dev)
251280 {
252281 struct i2c_client *client = to_i2c_client(dev);
253282 struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -257,12 +286,11 @@ static int __maybe_unused dw9714_vcm_resume(struct device *dev) · 3 unmodified lines
257286 if (pm_runtime_suspended(&client->dev))
258287 return 0;
259288
260− ret = regulator_enable(dw9714_dev->vcc);
289+ ret = dw9714_power_up(dw9714_dev);
261290 if (ret) {
262− dev_err(dev, "Failed to enable vcc: %d\n", ret);
291+ dev_err(dev, "Failed to power up: %d\n", ret);
263292 return ret;
264293 }
265− usleep_range(1000, 2000);
266294
267295 for (val = dw9714_dev->current_val % DW9714_CTRL_STEPS;
268296 val < dw9714_dev->current_val + DW9714_CTRL_STEPS - 1;
@@ -271,7 +299,7 @@ static int __maybe_unused dw9714_vcm_resume(struct device *dev) · 2 unmodified lines
271299 DW9714_VAL(val, DW9714_DEFAULT_S));
272300 if (ret)
273301 dev_err_ratelimited(dev, "%s I2C failure: %d",
274− __func__, ret);
302+ __func__, ret);
275303 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
276304 }
277305
drivers/media/i2c/hi556.c+42−31
@@ -624,6 +624,12 @@ static const struct hi556_mode supported_modes[] = { · 623 unmodified lines
624624 },
625625 };
626626
627+static const char * const hi556_supply_names[] = {
628+ "dovdd", /* Digital I/O power */
629+ "avdd", /* Analog power */
630+ "dvdd", /* Digital core power */
631+};
632+
627633 struct hi556 {
628634 struct v4l2_subdev sd;
629635 struct media_pad pad;
@@ -639,7 +645,7 @@ struct hi556 { · 9 unmodified lines
639645 /* GPIOs, clocks, etc. */
640646 struct gpio_desc *reset_gpio;
641647 struct clk *clk;
642− struct regulator *avdd;
648+ struct regulator_bulk_data supplies[ARRAY_SIZE(hi556_supply_names)];
643649
644650 /* Current mode */
645651 const struct hi556_mode *cur_mode;
@@ -756,21 +762,23 @@ static int hi556_test_pattern(struct hi556 *hi556, u32 pattern) · 110 unmodified lines
756762 int ret;
757763 u32 val;
758764
759− if (pattern) {
760− ret = hi556_read_reg(hi556, HI556_REG_ISP,
761− HI556_REG_VALUE_08BIT, &val);
762− if (ret)
763− return ret;
765+ ret = hi556_read_reg(hi556, HI556_REG_ISP,
766+ HI556_REG_VALUE_08BIT, &val);
767+ if (ret)
768+ return ret;
764769
765− ret = hi556_write_reg(hi556, HI556_REG_ISP,
766− HI556_REG_VALUE_08BIT,
767− val | HI556_REG_ISP_TPG_EN);
768− if (ret)
769− return ret;
770− }
770+ val = pattern ? (val | HI556_REG_ISP_TPG_EN) :
771+ (val & ~HI556_REG_ISP_TPG_EN);
772+
773+ ret = hi556_write_reg(hi556, HI556_REG_ISP,
774+ HI556_REG_VALUE_08BIT, val);
775+ if (ret)
776+ return ret;
777+
778+ val = pattern ? BIT(pattern - 1) : 0;
771779
772780 return hi556_write_reg(hi556, HI556_REG_TEST_PATTERN,
773− HI556_REG_VALUE_08BIT, pattern);
781+ HI556_REG_VALUE_08BIT, val);
774782 }
775783
776784 static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
@@ -1289,17 +1297,10 @@ static int hi556_suspend(struct device *dev) · 512 unmodified lines
12891297 {
12901298 struct v4l2_subdev *sd = dev_get_drvdata(dev);
12911299 struct hi556 *hi556 = to_hi556(sd);
1292− int ret;
12931300
12941301 gpiod_set_value_cansleep(hi556->reset_gpio, 1);
1295−
1296− ret = regulator_disable(hi556->avdd);
1297− if (ret) {
1298− dev_err(dev, "failed to disable avdd: %d\n", ret);
1299− gpiod_set_value_cansleep(hi556->reset_gpio, 0);
1300− return ret;
1301− }
1302−
1302+ regulator_bulk_disable(ARRAY_SIZE(hi556_supply_names),
1303+ hi556->supplies);
13031304 clk_disable_unprepare(hi556->clk);
13041305 return 0;
13051306 }
@@ -1314,14 +1315,20 @@ static int hi556_resume(struct device *dev) · 8 unmodified lines
13141315 if (ret)
13151316 return ret;
13161317
1317− ret = regulator_enable(hi556->avdd);
1318+ ret = regulator_bulk_enable(ARRAY_SIZE(hi556_supply_names),
1319+ hi556->supplies);
13181320 if (ret) {
1319− dev_err(dev, "failed to enable avdd: %d\n", ret);
1321+ dev_err(dev, "failed to enable regulators: %d", ret);
13201322 clk_disable_unprepare(hi556->clk);
13211323 return ret;
13221324 }
13231325
1324− gpiod_set_value_cansleep(hi556->reset_gpio, 0);
1326+ if (hi556->reset_gpio) {
1327+ /* Assert reset for at least 2ms on back to back off-on */
1328+ usleep_range(2000, 2200);
1329+ gpiod_set_value_cansleep(hi556->reset_gpio, 0);
1330+ }
1331+
13251332 usleep_range(5000, 5500);
13261333 return 0;
13271334 }
@@ -1330,7 +1337,7 @@ static int hi556_probe(struct i2c_client *client) · 2 unmodified lines
13301337 {
13311338 struct hi556 *hi556;
13321339 bool full_power;
1333− int ret;
1340+ int i, ret;
13341341
13351342 ret = hi556_check_hwcfg(&client->dev);
13361343 if (ret)
@@ -1353,11 +1360,15 @@ static int hi556_probe(struct i2c_client *client) · 16 unmodified lines
13531360 return dev_err_probe(&client->dev, PTR_ERR(hi556->clk),
13541361 "failed to get clock\n");
13551362
1356− /* The regulator core will provide a "dummy" regulator if necessary */
1357− hi556->avdd = devm_regulator_get(&client->dev, "avdd");
1358− if (IS_ERR(hi556->avdd))
1359− return dev_err_probe(&client->dev, PTR_ERR(hi556->avdd),
1360− "failed to get avdd regulator\n");
1363+ for (i = 0; i < ARRAY_SIZE(hi556_supply_names); i++)
1364+ hi556->supplies[i].supply = hi556_supply_names[i];
1365+
1366+ ret = devm_regulator_bulk_get(&client->dev,
1367+ ARRAY_SIZE(hi556_supply_names),
1368+ hi556->supplies);
1369+ if (ret)
1370+ return dev_err_probe(&client->dev, ret,
1371+ "failed to get regulators\n");
13611372
13621373 full_power = acpi_dev_state_d0(&client->dev);
13631374 if (full_power) {
drivers/media/i2c/imx214.c+200−63
@@ -20,6 +20,8 @@ · 19 unmodified lines
2020 #include <media/v4l2-fwnode.h>
2121 #include <media/v4l2-subdev.h>
2222
23+#include "ccs-pll.h"
24+
2325 /* Chip ID */
2426 #define IMX214_REG_CHIP_ID CCI_REG16(0x0016)
2527 #define IMX214_CHIP_ID 0x0214
@@ -30,11 +32,9 @@ · 4 unmodified lines
3032
3133 #define IMX214_REG_FAST_STANDBY_CTRL CCI_REG8(0x0106)
3234
33−#define IMX214_DEFAULT_CLK_FREQ 24000000
3435 #define IMX214_DEFAULT_LINK_FREQ 600000000
3536 /* Keep wrong link frequency for backward compatibility */
3637 #define IMX214_DEFAULT_LINK_FREQ_LEGACY 480000000
37−#define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
3838 #define IMX214_FPS 30
3939
4040 /* V-TIMING internal */
@@ -84,6 +84,7 @@ · 43 unmodified lines
8484 #define IMX214_CSI_DATA_FORMAT_RAW10 0x0A0A
8585 #define IMX214_CSI_DATA_FORMAT_COMP6 0x0A06
8686 #define IMX214_CSI_DATA_FORMAT_COMP8 0x0A08
87+#define IMX214_BITS_PER_PIXEL_MASK 0xFF
8788
8889 #define IMX214_REG_CSI_LANE_MODE CCI_REG8(0x0114)
8990 #define IMX214_CSI_2_LANE_MODE 1
@@ -249,6 +250,10 @@ struct imx214 { · 159 unmodified lines
249250 struct clk *xclk;
250251 struct regmap *regmap;
251252
253+ struct ccs_pll pll;
254+
255+ struct v4l2_fwnode_endpoint bus_cfg;
256+
252257 struct v4l2_subdev sd;
253258 struct media_pad pad;
254259
@@ -299,16 +304,6 @@ static const struct cci_reg_sequence mode_4096x2304[] = { · 44 unmodified lines
299304 { IMX214_REG_DIG_CROP_WIDTH, 4096 },
300305 { IMX214_REG_DIG_CROP_HEIGHT, 2304 },
301306
302− { IMX214_REG_VTPXCK_DIV, 5 },
303− { IMX214_REG_VTSYCK_DIV, 2 },
304− { IMX214_REG_PREPLLCK_VT_DIV, 3 },
305− { IMX214_REG_PLL_VT_MPY, 150 },
306− { IMX214_REG_OPPXCK_DIV, 10 },
307− { IMX214_REG_OPSYCK_DIV, 1 },
308− { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE },
309−
310− { IMX214_REG_REQ_LINK_BIT_RATE, IMX214_LINK_BIT_RATE_MBPS(4800) },
311−
312307 { CCI_REG8(0x3A03), 0x09 },
313308 { CCI_REG8(0x3A04), 0x50 },
314309 { CCI_REG8(0x3A05), 0x01 },
@@ -362,16 +357,6 @@ static const struct cci_reg_sequence mode_1920x1080[] = { · 47 unmodified lines
362357 { IMX214_REG_DIG_CROP_WIDTH, 1920 },
363358 { IMX214_REG_DIG_CROP_HEIGHT, 1080 },
364359
365− { IMX214_REG_VTPXCK_DIV, 5 },
366− { IMX214_REG_VTSYCK_DIV, 2 },
367− { IMX214_REG_PREPLLCK_VT_DIV, 3 },
368− { IMX214_REG_PLL_VT_MPY, 150 },
369− { IMX214_REG_OPPXCK_DIV, 10 },
370− { IMX214_REG_OPSYCK_DIV, 1 },
371− { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE },
372−
373− { IMX214_REG_REQ_LINK_BIT_RATE, IMX214_LINK_BIT_RATE_MBPS(4800) },
374−
375360 { CCI_REG8(0x3A03), 0x04 },
376361 { CCI_REG8(0x3A04), 0xF8 },
377362 { CCI_REG8(0x3A05), 0x02 },
@@ -405,9 +390,6 @@ static const struct cci_reg_sequence mode_table_common[] = { · 27 unmodified lines
405390 /* ATR setting */
406391 { IMX214_REG_ATR_FAST_MOVE, 2 },
407392
408− /* external clock setting */
409− { IMX214_REG_EXCK_FREQ, IMX214_EXCK_FREQ(IMX214_DEFAULT_CLK_FREQ / 1000000) },
410−
411393 /* global setting */
412394 /* basic config */
413395 { IMX214_REG_MASK_CORR_FRAMES, IMX214_CORR_FRAMES_MASK },
@@ -777,6 +759,30 @@ static int imx214_entity_init_state(struct v4l2_subdev *subdev, · 363 unmodified lines
777759 return 0;
778760 }
779761
762+static int imx214_configure_pll(struct imx214 *imx214)
763+{
764+ int ret = 0;
765+
766+ cci_write(imx214->regmap, IMX214_REG_VTPXCK_DIV,
767+ imx214->pll.vt_bk.pix_clk_div, &ret);
768+ cci_write(imx214->regmap, IMX214_REG_VTSYCK_DIV,
769+ imx214->pll.vt_bk.sys_clk_div, &ret);
770+ cci_write(imx214->regmap, IMX214_REG_PREPLLCK_VT_DIV,
771+ imx214->pll.vt_fr.pre_pll_clk_div, &ret);
772+ cci_write(imx214->regmap, IMX214_REG_PLL_VT_MPY,
773+ imx214->pll.vt_fr.pll_multiplier, &ret);
774+ cci_write(imx214->regmap, IMX214_REG_OPPXCK_DIV,
775+ imx214->pll.op_bk.pix_clk_div, &ret);
776+ cci_write(imx214->regmap, IMX214_REG_OPSYCK_DIV,
777+ imx214->pll.op_bk.sys_clk_div, &ret);
778+ cci_write(imx214->regmap, IMX214_REG_PLL_MULT_DRIV,
779+ IMX214_PLL_SINGLE, &ret);
780+ cci_write(imx214->regmap, IMX214_REG_EXCK_FREQ,
781+ IMX214_EXCK_FREQ(imx214->pll.ext_clk_freq_hz / 1000000), &ret);
782+
783+ return ret;
784+}
785+
780786 static int imx214_update_digital_gain(struct imx214 *imx214, u32 val)
781787 {
782788 int ret = 0;
@@ -877,9 +883,6 @@ static const struct v4l2_ctrl_ops imx214_ctrl_ops = { · 94 unmodified lines
877883
878884 static int imx214_ctrls_init(struct imx214 *imx214)
879885 {
880− static const s64 link_freq[] = {
881− IMX214_DEFAULT_LINK_FREQ
882− };
883886 static const struct v4l2_area unit_size = {
884887 .width = 1120,
885888 .height = 1120,
@@ -900,15 +903,14 @@ static int imx214_ctrls_init(struct imx214 *imx214) · 14 unmodified lines
900903 if (ret)
901904 return ret;
902905
903− imx214->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, NULL,
904− V4L2_CID_PIXEL_RATE, 0,
905− IMX214_DEFAULT_PIXEL_RATE, 1,
906− IMX214_DEFAULT_PIXEL_RATE);
906+ imx214->pixel_rate =
907+ v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_PIXEL_RATE, 1,
908+ INT_MAX, 1, 1);
907909
908910 imx214->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, NULL,
909911 V4L2_CID_LINK_FREQ,
910− ARRAY_SIZE(link_freq) - 1,
911− 0, link_freq);
912+ imx214->bus_cfg.nr_of_link_frequencies - 1,
913+ 0, imx214->bus_cfg.link_frequencies);
912914 if (imx214->link_freq)
913915 imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
914916
@@ -1011,6 +1013,7 @@ static int imx214_start_streaming(struct imx214 *imx214) · 96 unmodified lines
10111013 const struct v4l2_mbus_framefmt *fmt;
10121014 struct v4l2_subdev_state *state;
10131015 const struct imx214_mode *mode;
1016+ int bit_rate_mbps;
10141017 int ret;
10151018
10161019 ret = cci_multi_reg_write(imx214->regmap, mode_table_common,
@@ -1020,6 +1023,21 @@ static int imx214_start_streaming(struct imx214 *imx214) · 3 unmodified lines
10201023 return ret;
10211024 }
10221025
1026+ ret = imx214_configure_pll(imx214);
1027+ if (ret) {
1028+ dev_err(imx214->dev, "failed to configure PLL: %d\n", ret);
1029+ return ret;
1030+ }
1031+
1032+ bit_rate_mbps = (imx214->pll.pixel_rate_csi / 1000000)
1033+ * imx214->pll.bits_per_pixel;
1034+ ret = cci_write(imx214->regmap, IMX214_REG_REQ_LINK_BIT_RATE,
1035+ IMX214_LINK_BIT_RATE_MBPS(bit_rate_mbps), NULL);
1036+ if (ret) {
1037+ dev_err(imx214->dev, "failed to configure link bit rate\n");
1038+ return ret;
1039+ }
1040+
10231041 ret = cci_write(imx214->regmap, IMX214_REG_CSI_LANE_MODE,
10241042 IMX214_CSI_4_LANE_MODE, NULL);
10251043 if (ret) {
@@ -1097,6 +1115,109 @@ err_rpm_put: · 71 unmodified lines
10971115 return ret;
10981116 }
10991117
1118+static int imx214_pll_calculate(struct imx214 *imx214, struct ccs_pll *pll,
1119+ unsigned int link_freq)
1120+{
1121+ struct ccs_pll_limits limits = {
1122+ .min_ext_clk_freq_hz = 6000000,
1123+ .max_ext_clk_freq_hz = 27000000,
1124+
1125+ .vt_fr = {
1126+ .min_pre_pll_clk_div = 1,
1127+ .max_pre_pll_clk_div = 15,
1128+ /* Value is educated guess as we don't have a spec */
1129+ .min_pll_ip_clk_freq_hz = 6000000,
1130+ /* Value is educated guess as we don't have a spec */
1131+ .max_pll_ip_clk_freq_hz = 12000000,
1132+ .min_pll_multiplier = 12,
1133+ .max_pll_multiplier = 1200,
1134+ .min_pll_op_clk_freq_hz = 338000000,
1135+ .max_pll_op_clk_freq_hz = 1200000000,
1136+ },
1137+ .vt_bk = {
1138+ .min_sys_clk_div = 2,
1139+ .max_sys_clk_div = 4,
1140+ .min_pix_clk_div = 5,
1141+ .max_pix_clk_div = 10,
1142+ .min_pix_clk_freq_hz = 30000000,
1143+ .max_pix_clk_freq_hz = 120000000,
1144+ },
1145+ .op_bk = {
1146+ .min_sys_clk_div = 1,
1147+ .max_sys_clk_div = 2,
1148+ .min_pix_clk_div = 6,
1149+ .max_pix_clk_div = 10,
1150+ .min_pix_clk_freq_hz = 30000000,
1151+ .max_pix_clk_freq_hz = 120000000,
1152+ },
1153+
1154+ .min_line_length_pck_bin = IMX214_PPL_DEFAULT,
1155+ .min_line_length_pck = IMX214_PPL_DEFAULT,
1156+ };
1157+ unsigned int num_lanes = imx214->bus_cfg.bus.mipi_csi2.num_data_lanes;
1158+
1159+ /*
1160+ * There are no documented constraints on the sys clock frequency, for
1161+ * either branch. Recover them based on the PLL output clock frequency
1162+ * and sys_clk_div limits on one hand, and the pix clock frequency and
1163+ * the pix_clk_div limits on the other hand.
1164+ */
1165+ limits.vt_bk.min_sys_clk_freq_hz =
1166+ max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.vt_bk.max_sys_clk_div,
1167+ limits.vt_bk.min_pix_clk_freq_hz * limits.vt_bk.min_pix_clk_div);
1168+ limits.vt_bk.max_sys_clk_freq_hz =
1169+ min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.vt_bk.min_sys_clk_div,
1170+ limits.vt_bk.max_pix_clk_freq_hz * limits.vt_bk.max_pix_clk_div);
1171+
1172+ limits.op_bk.min_sys_clk_freq_hz =
1173+ max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.op_bk.max_sys_clk_div,
1174+ limits.op_bk.min_pix_clk_freq_hz * limits.op_bk.min_pix_clk_div);
1175+ limits.op_bk.max_sys_clk_freq_hz =
1176+ min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.op_bk.min_sys_clk_div,
1177+ limits.op_bk.max_pix_clk_freq_hz * limits.op_bk.max_pix_clk_div);
1178+
1179+ memset(pll, 0, sizeof(*pll));
1180+
1181+ pll->bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY;
1182+ pll->op_lanes = num_lanes;
1183+ pll->vt_lanes = num_lanes;
1184+ pll->csi2.lanes = num_lanes;
1185+
1186+ pll->binning_horizontal = 1;
1187+ pll->binning_vertical = 1;
1188+ pll->scale_m = 1;
1189+ pll->scale_n = 1;
1190+ pll->bits_per_pixel =
1191+ IMX214_CSI_DATA_FORMAT_RAW10 & IMX214_BITS_PER_PIXEL_MASK;
1192+ pll->flags = CCS_PLL_FLAG_LANE_SPEED_MODEL;
1193+ pll->link_freq = link_freq;
1194+ pll->ext_clk_freq_hz = clk_get_rate(imx214->xclk);
1195+
1196+ return ccs_pll_calculate(imx214->dev, &limits, pll);
1197+}
1198+
1199+static int imx214_pll_update(struct imx214 *imx214)
1200+{
1201+ u64 link_freq;
1202+ int ret;
1203+
1204+ link_freq = imx214->bus_cfg.link_frequencies[imx214->link_freq->val];
1205+ ret = imx214_pll_calculate(imx214, &imx214->pll, link_freq);
1206+ if (ret) {
1207+ dev_err(imx214->dev, "PLL calculations failed: %d\n", ret);
1208+ return ret;
1209+ }
1210+
1211+ ret = v4l2_ctrl_s_ctrl_int64(imx214->pixel_rate,
1212+ imx214->pll.pixel_rate_pixel_array);
1213+ if (ret) {
1214+ dev_err(imx214->dev, "failed to set pixel rate\n");
1215+ return ret;
1216+ }
1217+
1218+ return 0;
1219+}
1220+
11001221 static int imx214_get_frame_interval(struct v4l2_subdev *subdev,
11011222 struct v4l2_subdev_state *sd_state,
11021223 struct v4l2_subdev_frame_interval *fival)
@@ -1203,12 +1324,10 @@ static int imx214_identify_module(struct imx214 *imx214) · 100 unmodified lines
12031324 return 0;
12041325 }
12051326
1206−static int imx214_parse_fwnode(struct device *dev)
1327+static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
12071328 {
1329+ struct v4l2_fwnode_endpoint *bus_cfg = &imx214->bus_cfg;
12081330 struct fwnode_handle *endpoint;
1209− struct v4l2_fwnode_endpoint bus_cfg = {
1210− .bus_type = V4L2_MBUS_CSI2_DPHY,
1211− };
12121331 unsigned int i;
12131332 int ret;
12141333
@@ -1216,42 +1335,52 @@ static int imx214_parse_fwnode(struct device *dev) · 1 unmodified line
12161335 if (!endpoint)
12171336 return dev_err_probe(dev, -EINVAL, "endpoint node not found\n");
12181337
1219− ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
1338+ bus_cfg->bus_type = V4L2_MBUS_CSI2_DPHY;
1339+ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, bus_cfg);
1340+ fwnode_handle_put(endpoint);
12201341 if (ret) {
12211342 dev_err_probe(dev, ret, "parsing endpoint node failed\n");
1222− goto done;
1343+ goto error;
12231344 }
12241345
12251346 /* Check the number of MIPI CSI2 data lanes */
1226− if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
1347+ if (bus_cfg->bus.mipi_csi2.num_data_lanes != 4) {
12271348 ret = dev_err_probe(dev, -EINVAL,
12281349 "only 4 data lanes are currently supported\n");
1229− goto done;
1350+ goto error;
12301351 }
12311352
1232− if (bus_cfg.nr_of_link_frequencies != 1)
1353+ if (bus_cfg->nr_of_link_frequencies != 1)
12331354 dev_warn(dev, "Only one link-frequency supported, please review your DT. Continuing anyway\n");
12341355
1235− for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
1236− if (bus_cfg.link_frequencies[i] == IMX214_DEFAULT_LINK_FREQ)
1356+ for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) {
1357+ u64 freq = bus_cfg->link_frequencies[i];
1358+ struct ccs_pll pll;
1359+
1360+ if (!imx214_pll_calculate(imx214, &pll, freq))
12371361 break;
1238− if (bus_cfg.link_frequencies[i] ==
1239− IMX214_DEFAULT_LINK_FREQ_LEGACY) {
1362+ if (freq == IMX214_DEFAULT_LINK_FREQ_LEGACY) {
12401363 dev_warn(dev,
12411364 "link-frequencies %d not supported, please review your DT. Continuing anyway\n",
12421365 IMX214_DEFAULT_LINK_FREQ);
1366+ freq = IMX214_DEFAULT_LINK_FREQ;
1367+ if (imx214_pll_calculate(imx214, &pll, freq))
1368+ continue;
1369+ bus_cfg->link_frequencies[i] = freq;
12431370 break;
12441371 }
12451372 }
12461373
1247− if (i == bus_cfg.nr_of_link_frequencies)
1374+ if (i == bus_cfg->nr_of_link_frequencies)
12481375 ret = dev_err_probe(dev, -EINVAL,
1249− "link-frequencies %d not supported, please review your DT\n",
1250− IMX214_DEFAULT_LINK_FREQ);
1376+ "link-frequencies %lld not supported, please review your DT\n",
1377+ bus_cfg->nr_of_link_frequencies ?
1378+ bus_cfg->link_frequencies[0] : 0);
12511379
1252−done:
1253− v4l2_fwnode_endpoint_free(&bus_cfg);
1254− fwnode_handle_put(endpoint);
1380+ return 0;
1381+
1382+error:
1383+ v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
12551384 return ret;
12561385 }
12571386
@@ -1261,10 +1390,6 @@ static int imx214_probe(struct i2c_client *client) · 3 unmodified lines
12611390 struct imx214 *imx214;
12621391 int ret;
12631392
1264− ret = imx214_parse_fwnode(dev);
1265− if (ret)
1266− return ret;
1267−
12681393 imx214 = devm_kzalloc(dev, sizeof(*imx214), GFP_KERNEL);
12691394 if (!imx214)
12701395 return -ENOMEM;
@@ -1276,11 +1401,6 @@ static int imx214_probe(struct i2c_client *client) · 5 unmodified lines
12761401 return dev_err_probe(dev, PTR_ERR(imx214->xclk),
12771402 "failed to get xclk\n");
12781403
1279− ret = clk_set_rate(imx214->xclk, IMX214_DEFAULT_CLK_FREQ);
1280− if (ret)
1281− return dev_err_probe(dev, ret,
1282− "failed to set xclk frequency\n");
1283−
12841404 ret = imx214_get_regulators(dev, imx214);
12851405 if (ret < 0)
12861406 return dev_err_probe(dev, ret, "failed to get regulators\n");
@@ -1295,6 +1415,10 @@ static int imx214_probe(struct i2c_client *client) · 8 unmodified lines
12951415 return dev_err_probe(dev, PTR_ERR(imx214->regmap),
12961416 "failed to initialize CCI\n");
12971417
1418+ ret = imx214_parse_fwnode(dev, imx214);
1419+ if (ret)
1420+ return ret;
1421+
12981422 v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);
12991423 imx214->sd.internal_ops = &imx214_internal_ops;
13001424
@@ -1302,7 +1426,9 @@ static int imx214_probe(struct i2c_client *client) · 1 unmodified line
13021426 * Enable power initially, to avoid warnings
13031427 * from clk_disable on power_off
13041428 */
1305− imx214_power_on(imx214->dev);
1429+ ret = imx214_power_on(imx214->dev);
1430+ if (ret < 0)
1431+ goto error_fwnode;
13061432
13071433 ret = imx214_identify_module(imx214);
13081434 if (ret)
@@ -1333,6 +1459,12 @@ static int imx214_probe(struct i2c_client *client) · 24 unmodified lines
13331459 pm_runtime_set_active(imx214->dev);
13341460 pm_runtime_enable(imx214->dev);
13351461
1462+ ret = imx214_pll_update(imx214);
1463+ if (ret < 0) {
1464+ dev_err_probe(dev, ret, "failed to update PLL\n");
1465+ goto error_subdev_cleanup;
1466+ }
1467+
13361468 ret = v4l2_async_register_subdev_sensor(&imx214->sd);
13371469 if (ret < 0) {
13381470 dev_err_probe(dev, ret,
@@ -1358,6 +1490,9 @@ free_ctrl: · 19 unmodified lines
13581490 error_power_off:
13591491 imx214_power_off(imx214->dev);
13601492
1493+error_fwnode:
1494+ v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1495+
13611496 return ret;
13621497 }
13631498
@@ -1370,6 +1505,8 @@ static void imx214_remove(struct i2c_client *client) · 6 unmodified lines
13701505 v4l2_subdev_cleanup(sd);
13711506 media_entity_cleanup(&imx214->sd.entity);
13721507 v4l2_ctrl_handler_free(&imx214->ctrls);
1508+ v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1509+
13731510 pm_runtime_disable(&client->dev);
13741511 if (!pm_runtime_status_suspended(&client->dev)) {
13751512 imx214_power_off(imx214->dev);
drivers/media/i2c/imx290.c+0−1
@@ -1294,7 +1294,6 @@ static int imx290_subdev_init(struct imx290 *imx290) · 1293 unmodified lines
12941294 * will already be prevented even before the delay.
12951295 */
12961296 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
1297− imx290->sd.dev = imx290->dev;
12981297 pm_runtime_mark_last_busy(imx290->dev);
12991298 pm_runtime_put_autosuspend(imx290->dev);
13001299
drivers/media/i2c/imx415.c+1−1
@@ -1251,7 +1251,7 @@ static int imx415_parse_hw_config(struct imx415 *sensor) · 1250 unmodified lines
12511251 return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
12521252 "failed to get reset GPIO\n");
12531253
1254− sensor->clk = devm_clk_get(sensor->dev, "inck");
1254+ sensor->clk = devm_clk_get(sensor->dev, NULL);
12551255 if (IS_ERR(sensor->clk))
12561256 return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
12571257 "failed to get clock\n");
drivers/media/i2c/lt6911uxe.c+1−1
@@ -600,7 +600,7 @@ static int lt6911uxe_probe(struct i2c_client *client) · 599 unmodified lines
600600
601601 v4l2_i2c_subdev_init(&lt6911uxe->sd, client, &lt6911uxe_subdev_ops);
602602
603− lt6911uxe->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_IN);
603+ lt6911uxe->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
604604 if (IS_ERR(lt6911uxe->reset_gpio))
605605 return dev_err_probe(dev, PTR_ERR(lt6911uxe->reset_gpio),
606606 "failed to get reset gpio\n");
drivers/media/i2c/max9286.c+4−4
@@ -1193,12 +1193,12 @@ static int max9286_gpio_set(struct max9286_priv *priv, unsigned int offset, · 1192 unmodified lines
11931193 MAX9286_0X0F_RESERVED | priv->gpio_state);
11941194 }
11951195
1196−static void max9286_gpiochip_set(struct gpio_chip *chip,
1197− unsigned int offset, int value)
1196+static int max9286_gpiochip_set(struct gpio_chip *chip,
1197+ unsigned int offset, int value)
11981198 {
11991199 struct max9286_priv *priv = gpiochip_get_data(chip);
12001200
1201− max9286_gpio_set(priv, offset, value);
1201+ return max9286_gpio_set(priv, offset, value);
12021202 }
12031203
12041204 static int max9286_gpiochip_get(struct gpio_chip *chip, unsigned int offset)
@@ -1220,7 +1220,7 @@ static int max9286_register_gpio(struct max9286_priv *priv) · 15 unmodified lines
12201220 gpio->owner = THIS_MODULE;
12211221 gpio->ngpio = 2;
12221222 gpio->base = -1;
1223− gpio->set = max9286_gpiochip_set;
1223+ gpio->set_rv = max9286_gpiochip_set;
12241224 gpio->get = max9286_gpiochip_get;
12251225 gpio->can_sleep = true;
12261226
drivers/media/i2c/max96714.c+0−7
@@ -370,13 +370,6 @@ static int _max96714_set_routing(struct v4l2_subdev *sd, · 369 unmodified lines
370370 };
371371 int ret;
372372
373− /*
374− * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
375− * frame desc is made dynamically allocated.
376− */
377− if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
378− return -EINVAL;
379−
380373 ret = v4l2_subdev_routing_validate(sd, routing,
381374 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
382375 if (ret)
drivers/media/i2c/max96717.c+5−6
@@ -297,13 +297,13 @@ static int max96717_gpiochip_get(struct gpio_chip *gpiochip, · 296 unmodified lines
297297 return !!(val & MAX96717_GPIO_OUT);
298298 }
299299
300−static void max96717_gpiochip_set(struct gpio_chip *gpiochip,
301− unsigned int offset, int value)
300+static int max96717_gpiochip_set(struct gpio_chip *gpiochip,
301+ unsigned int offset, int value)
302302 {
303303 struct max96717_priv *priv = gpiochip_get_data(gpiochip);
304304
305− cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
306− MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);
305+ return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
306+ MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);
307307 }
308308
309309 static int max96717_gpio_get_direction(struct gpio_chip *gpiochip,
@@ -355,9 +355,8 @@ static int max96717_gpiochip_probe(struct max96717_priv *priv) · 45 unmodified lines
355355 gc->get_direction = max96717_gpio_get_direction;
356356 gc->direction_input = max96717_gpio_direction_in;
357357 gc->direction_output = max96717_gpio_direction_out;
358− gc->set = max96717_gpiochip_set;
358+ gc->set_rv = max96717_gpiochip_set;
359359 gc->get = max96717_gpiochip_get;
360− gc->of_gpio_n_cells = 2;
361360
362361 /* Disable GPIO forwarding */
363362 for (i = 0; i < gc->ngpio; i++)
drivers/media/i2c/mt9m114.c+103−68
@@ -261,6 +261,7 @@ · 260 unmodified lines
261261 #define MT9M114_CAM_PGA_PGA_CONTROL CCI_REG16(0xc95e)
262262 #define MT9M114_CAM_SYSCTL_PLL_ENABLE CCI_REG8(0xc97e)
263263 #define MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE BIT(0)
264+#define MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE 0x00
264265 #define MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N CCI_REG16(0xc980)
265266 #define MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(m, n) (((n) << 8) | (m))
266267 #define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P CCI_REG16(0xc982)
@@ -377,6 +378,7 @@ struct mt9m114 { · 110 unmodified lines
377378 struct gpio_desc *reset;
378379 struct regulator_bulk_data supplies[3];
379380 struct v4l2_fwnode_endpoint bus_cfg;
381+ bool bypass_pll;
380382
381383 struct {
382384 unsigned int m;
@@ -743,14 +745,21 @@ static int mt9m114_initialize(struct mt9m114 *sensor) · 360 unmodified lines
743745 }
744746
745747 /* Configure the PLL. */
746− cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
747− MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret);
748− cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N,
749− MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m,
750− sensor->pll.n),
751− &ret);
752− cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P,
753− MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), &ret);
748+ if (sensor->bypass_pll) {
749+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
750+ MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE, &ret);
751+ } else {
752+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
753+ MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret);
754+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N,
755+ MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m,
756+ sensor->pll.n),
757+ &ret);
758+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P,
759+ MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p),
760+ &ret);
761+ }
762+
754763 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK,
755764 sensor->pixrate, &ret);
756765
@@ -781,41 +790,25 @@ static int mt9m114_initialize(struct mt9m114 *sensor) · 24 unmodified lines
781790 return 0;
782791 }
783792
784−static int mt9m114_configure(struct mt9m114 *sensor,
785− struct v4l2_subdev_state *pa_state,
786− struct v4l2_subdev_state *ifp_state)
793+static int mt9m114_configure_pa(struct mt9m114 *sensor,
794+ struct v4l2_subdev_state *state)
787795 {
788− const struct v4l2_mbus_framefmt *pa_format;
789− const struct v4l2_rect *pa_crop;
790− const struct mt9m114_format_info *ifp_info;
791− const struct v4l2_mbus_framefmt *ifp_format;
792− const struct v4l2_rect *ifp_crop;
793− const struct v4l2_rect *ifp_compose;
796+ const struct v4l2_mbus_framefmt *format;
797+ const struct v4l2_rect *crop;
794798 unsigned int hratio, vratio;
795− u64 output_format;
796799 u64 read_mode;
797− int ret = 0;
798−
799− pa_format = v4l2_subdev_state_get_format(pa_state, 0);
800− pa_crop = v4l2_subdev_state_get_crop(pa_state, 0);
800+ int ret;
801801
802− ifp_format = v4l2_subdev_state_get_format(ifp_state, 1);
803− ifp_info = mt9m114_format_info(sensor, 1, ifp_format->code);
804− ifp_crop = v4l2_subdev_state_get_crop(ifp_state, 0);
805− ifp_compose = v4l2_subdev_state_get_compose(ifp_state, 0);
802+ format = v4l2_subdev_state_get_format(state, 0);
803+ crop = v4l2_subdev_state_get_crop(state, 0);
806804
807805 ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
808806 &read_mode, NULL);
809807 if (ret < 0)
810808 return ret;
811809
812− ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,
813− &output_format, NULL);
814− if (ret < 0)
815− return ret;
816−
817− hratio = pa_crop->width / pa_format->width;
818− vratio = pa_crop->height / pa_format->height;
810+ hratio = crop->width / format->width;
811+ vratio = crop->height / format->height;
819812
820813 /*
821814 * Pixel array crop and binning. The CAM_SENSOR_CFG_CPIPE_LAST_ROW
@@ -824,15 +817,15 @@ static int mt9m114_configure(struct mt9m114 *sensor, · 2 unmodified lines
824817 * example sensor modes.
825818 */
826819 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START,
827− pa_crop->left, &ret);
820+ crop->left, &ret);
828821 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START,
829− pa_crop->top, &ret);
822+ crop->top, &ret);
830823 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END,
831− pa_crop->width + pa_crop->left - 1, &ret);
824+ crop->width + crop->left - 1, &ret);
832825 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END,
833− pa_crop->height + pa_crop->top - 1, &ret);
826+ crop->height + crop->top - 1, &ret);
834827 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW,
835− (pa_crop->height - 4) / vratio - 1, &ret);
828+ (crop->height - 4) / vratio - 1, &ret);
836829
837830 read_mode &= ~(MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK |
838831 MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK);
@@ -845,6 +838,29 @@ static int mt9m114_configure(struct mt9m114 *sensor, · 6 unmodified lines
845838 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
846839 read_mode, &ret);
847840
841+ return ret;
842+}
843+
844+static int mt9m114_configure_ifp(struct mt9m114 *sensor,
845+ struct v4l2_subdev_state *state)
846+{
847+ const struct mt9m114_format_info *info;
848+ const struct v4l2_mbus_framefmt *format;
849+ const struct v4l2_rect *crop;
850+ const struct v4l2_rect *compose;
851+ u64 output_format;
852+ int ret = 0;
853+
854+ format = v4l2_subdev_state_get_format(state, 1);
855+ info = mt9m114_format_info(sensor, 1, format->code);
856+ crop = v4l2_subdev_state_get_crop(state, 0);
857+ compose = v4l2_subdev_state_get_compose(state, 0);
858+
859+ ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,
860+ &output_format, NULL);
861+ if (ret < 0)
862+ return ret;
863+
848864 /*
849865 * Color pipeline (IFP) cropping and scaling. Subtract 4 from the left
850866 * and top coordinates to compensate for the lines and columns removed
@@ -852,18 +868,18 @@ static int mt9m114_configure(struct mt9m114 *sensor, · 1 unmodified line
852868 * not in the hardware.
853869 */
854870 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET,
855− ifp_crop->left - 4, &ret);
871+ crop->left - 4, &ret);
856872 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET,
857− ifp_crop->top - 4, &ret);
873+ crop->top - 4, &ret);
858874 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH,
859− ifp_crop->width, &ret);
875+ crop->width, &ret);
860876 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT,
861− ifp_crop->height, &ret);
877+ crop->height, &ret);
862878
863879 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH,
864− ifp_compose->width, &ret);
880+ compose->width, &ret);
865881 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT,
866− ifp_compose->height, &ret);
882+ compose->height, &ret);
867883
868884 /* AWB and AE windows, use the full frame. */
869885 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART,
@@ -871,18 +887,18 @@ static int mt9m114_configure(struct mt9m114 *sensor, · 1 unmodified line
871887 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART,
872888 0, &ret);
873889 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND,
874− ifp_compose->width - 1, &ret);
890+ compose->width - 1, &ret);
875891 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND,
876− ifp_compose->height - 1, &ret);
892+ compose->height - 1, &ret);
877893
878894 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART,
879895 0, &ret);
880896 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART,
881897 0, &ret);
882898 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND,
883− ifp_compose->width / 5 - 1, &ret);
899+ compose->width / 5 - 1, &ret);
884900 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND,
885− ifp_compose->height / 5 - 1, &ret);
901+ compose->height / 5 - 1, &ret);
886902
887903 cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE,
888904 MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN |
@@ -894,7 +910,7 @@ static int mt9m114_configure(struct mt9m114 *sensor, · 5 unmodified lines
894910 MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK |
895911 MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES |
896912 MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE);
897− output_format |= ifp_info->output_format;
913+ output_format |= info->output_format;
898914
899915 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,
900916 output_format, &ret);
@@ -925,7 +941,11 @@ static int mt9m114_start_streaming(struct mt9m114 *sensor, · 24 unmodified lines
925941 if (ret)
926942 return ret;
927943
928− ret = mt9m114_configure(sensor, pa_state, ifp_state);
944+ ret = mt9m114_configure_ifp(sensor, ifp_state);
945+ if (ret)
946+ goto error;
947+
948+ ret = mt9m114_configure_pa(sensor, pa_state);
929949 if (ret)
930950 goto error;
931951
@@ -1599,13 +1619,9 @@ static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev *sd, · 667 unmodified lines
15991619 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
16001620 return -EINVAL;
16011621
1602− mutex_lock(sensor->ifp.hdl.lock);
1603−
16041622 ival->numerator = 1;
16051623 ival->denominator = sensor->ifp.frame_rate;
16061624
1607− mutex_unlock(sensor->ifp.hdl.lock);
1608−
16091625 return 0;
16101626 }
16111627
@@ -1624,8 +1640,6 @@ static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd, · 12 unmodified lines
16241640 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
16251641 return -EINVAL;
16261642
1627− mutex_lock(sensor->ifp.hdl.lock);
1628−
16291643 if (ival->numerator != 0 && ival->denominator != 0)
16301644 sensor->ifp.frame_rate = min_t(unsigned int,
16311645 ival->denominator / ival->numerator,
@@ -1639,8 +1653,6 @@ static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd, · 7 unmodified lines
16391653 if (sensor->streaming)
16401654 ret = mt9m114_set_frame_rate(sensor);
16411655
1642− mutex_unlock(sensor->ifp.hdl.lock);
1643−
16441656 return ret;
16451657 }
16461658
@@ -2235,9 +2247,22 @@ static const struct dev_pm_ops mt9m114_pm_ops = { · 588 unmodified lines
22352247 * Probe & Remove
22362248 */
22372249
2250+static int mt9m114_verify_link_frequency(struct mt9m114 *sensor,
2251+ unsigned int pixrate)
2252+{
2253+ unsigned int link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY
2254+ ? pixrate * 8 : pixrate * 2;
2255+
2256+ if (sensor->bus_cfg.nr_of_link_frequencies != 1 ||
2257+ sensor->bus_cfg.link_frequencies[0] != link_freq)
2258+ return -EINVAL;
2259+
2260+ return 0;
2261+}
2262+
22382263 static int mt9m114_clk_init(struct mt9m114 *sensor)
22392264 {
2240− unsigned int link_freq;
2265+ unsigned int pixrate;
22412266
22422267 /* Hardcode the PLL multiplier and dividers to default settings. */
22432268 sensor->pll.m = 32;
@@ -2249,19 +2274,29 @@ static int mt9m114_clk_init(struct mt9m114 *sensor) · 5 unmodified lines
22492274 * for 16-bit per pixel, transmitted in DDR over a single lane. For
22502275 * parallel mode, the sensor ouputs one pixel in two PIXCLK cycles.
22512276 */
2252− sensor->pixrate = clk_get_rate(sensor->clk) * sensor->pll.m
2253− / ((sensor->pll.n + 1) * (sensor->pll.p + 1));
22542277
2255− link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY
2256− ? sensor->pixrate * 8 : sensor->pixrate * 2;
2278+ /*
2279+ * Check if EXTCLK fits the configured link frequency. Bypass the PLL
2280+ * in this case.
2281+ */
2282+ pixrate = clk_get_rate(sensor->clk) / 2;
2283+ if (mt9m114_verify_link_frequency(sensor, pixrate) == 0) {
2284+ sensor->pixrate = pixrate;
2285+ sensor->bypass_pll = true;
2286+ return 0;
2287+ }
22572288
2258− if (sensor->bus_cfg.nr_of_link_frequencies != 1 ||
2259− sensor->bus_cfg.link_frequencies[0] != link_freq) {
2260− dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n");
2261− return -EINVAL;
2289+ /* Check if the PLL configuration fits the configured link frequency. */
2290+ pixrate = clk_get_rate(sensor->clk) * sensor->pll.m
2291+ / ((sensor->pll.n + 1) * (sensor->pll.p + 1));
2292+ if (mt9m114_verify_link_frequency(sensor, pixrate) == 0) {
2293+ sensor->pixrate = pixrate;
2294+ sensor->bypass_pll = false;
2295+ return 0;
22622296 }
22632297
2264− return 0;
2298+ dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n");
2299+ return -EINVAL;
22652300 }
22662301
22672302 static int mt9m114_identify(struct mt9m114 *sensor)
drivers/media/i2c/ov2659.c+2−1
@@ -1469,14 +1469,15 @@ static int ov2659_probe(struct i2c_client *client) · 1468 unmodified lines
14691469 V4L2_CID_TEST_PATTERN,
14701470 ARRAY_SIZE(ov2659_test_pattern_menu) - 1,
14711471 0, 0, ov2659_test_pattern_menu);
1472− ov2659->sd.ctrl_handler = &ov2659->ctrls;
14731472
14741473 if (ov2659->ctrls.error) {
14751474 dev_err(&client->dev, "%s: control initialization error %d\n",
14761475 __func__, ov2659->ctrls.error);
1476+ v4l2_ctrl_handler_free(&ov2659->ctrls);
14771477 return ov2659->ctrls.error;
14781478 }
14791479
1480+ ov2659->sd.ctrl_handler = &ov2659->ctrls;
14801481 sd = &ov2659->sd;
14811482 client->flags |= I2C_CLIENT_SCCB;
14821483
drivers/media/i2c/ov2740.c+7−11
@@ -766,11 +766,9 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 765 unmodified lines
766766 {
767767 struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
768768 struct v4l2_ctrl_handler *ctrl_hdlr;
769− const struct ov2740_mode *cur_mode;
770769 s64 exposure_max, h_blank, pixel_rate;
771770 u32 vblank_min, vblank_max, vblank_default;
772771 struct v4l2_fwnode_device_properties props;
773− int size;
774772 int ret;
775773
776774 ctrl_hdlr = &ov2740->ctrl_handler;
@@ -778,12 +776,10 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 1 unmodified line
778776 if (ret)
779777 return ret;
780778
781− cur_mode = ov2740->cur_mode;
782− size = ARRAY_SIZE(link_freq_menu_items);
783−
784779 ov2740->link_freq =
785780 v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov2740_ctrl_ops,
786− V4L2_CID_LINK_FREQ, size - 1,
781+ V4L2_CID_LINK_FREQ,
782+ ARRAY_SIZE(link_freq_menu_items) - 1,
787783 ov2740->supported_modes->link_freq_index,
788784 link_freq_menu_items);
789785 if (ov2740->link_freq)
@@ -794,14 +790,14 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 4 unmodified lines
794790 V4L2_CID_PIXEL_RATE, 0,
795791 pixel_rate, 1, pixel_rate);
796792
797− vblank_min = cur_mode->vts_min - cur_mode->height;
798− vblank_max = cur_mode->vts_max - cur_mode->height;
799− vblank_default = cur_mode->vts_def - cur_mode->height;
793+ vblank_min = ov2740->cur_mode->vts_min - ov2740->cur_mode->height;
794+ vblank_max = ov2740->cur_mode->vts_max - ov2740->cur_mode->height;
795+ vblank_default = ov2740->cur_mode->vts_def - ov2740->cur_mode->height;
800796 ov2740->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
801797 V4L2_CID_VBLANK, vblank_min,
802798 vblank_max, 1, vblank_default);
803799
804− h_blank = cur_mode->hts - cur_mode->width;
800+ h_blank = ov2740->cur_mode->hts - ov2740->cur_mode->width;
805801 ov2740->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
806802 V4L2_CID_HBLANK, h_blank, h_blank, 1,
807803 h_blank);
@@ -814,7 +810,7 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 6 unmodified lines
814810 v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
815811 OV2740_DGTL_GAIN_MIN, OV2740_DGTL_GAIN_MAX,
816812 OV2740_DGTL_GAIN_STEP, OV2740_DGTL_GAIN_DEFAULT);
817− exposure_max = cur_mode->vts_def - OV2740_EXPOSURE_MAX_MARGIN;
813+ exposure_max = ov2740->cur_mode->vts_def - OV2740_EXPOSURE_MAX_MARGIN;
818814 ov2740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
819815 V4L2_CID_EXPOSURE,
820816 OV2740_EXPOSURE_MIN, exposure_max,
drivers/media/i2c/ov5670.c+7−2
@@ -2688,10 +2688,15 @@ static int ov5670_probe(struct i2c_client *client) · 2687 unmodified lines
26882688 if (ret)
26892689 return dev_err_probe(&client->dev, ret, "GPIO probe failed\n");
26902690
2691− /* Graph Endpoint */
2691+ /*
2692+ * Graph Endpoint. If it's missing we defer rather than fail, as this
2693+ * sensor is known to co-exist on systems with the IPU3 and so it might
2694+ * be created by the ipu-bridge.
2695+ */
26922696 handle = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
26932697 if (!handle)
2694− return dev_err_probe(&client->dev, -ENXIO, "Endpoint for node get failed\n");
2698+ return dev_err_probe(&client->dev, -EPROBE_DEFER,
2699+ "Endpoint for node get failed\n");
26952700
26962701 ov5670->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
26972702 ov5670->endpoint.bus.mipi_csi2.num_data_lanes = 2;
drivers/media/i2c/ov5693.c+6−1
@@ -1222,9 +1222,14 @@ static int ov5693_check_hwcfg(struct ov5693_device *ov5693) · 1221 unmodified lines
12221222 unsigned int i;
12231223 int ret;
12241224
1225+ /*
1226+ * Sometimes the fwnode graph is initialized by the bridge driver
1227+ * Bridge drivers doing this may also add GPIO mappings, wait for this.
1228+ */
12251229 endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
12261230 if (!endpoint)
1227− return -EPROBE_DEFER; /* Could be provided by cio2-bridge */
1231+ return dev_err_probe(ov5693->dev, -EPROBE_DEFER,
1232+ "waiting for fwnode graph endpoint\n");
12281233
12291234 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
12301235 fwnode_handle_put(endpoint);
drivers/media/i2c/ov7251.c+6−1
@@ -1486,9 +1486,14 @@ static int ov7251_check_hwcfg(struct ov7251 *ov7251) · 1485 unmodified lines
14861486 unsigned int i, j;
14871487 int ret;
14881488
1489+ /*
1490+ * Sometimes the fwnode graph is initialized by the bridge driver
1491+ * Bridge drivers doing this may also add GPIO mappings, wait for this.
1492+ */
14891493 endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
14901494 if (!endpoint)
1491− return -EPROBE_DEFER; /* could be provided by cio2-bridge */
1495+ return dev_err_probe(ov7251->dev, -EPROBE_DEFER,
1496+ "waiting for fwnode graph endpoint\n");
14921497
14931498 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
14941499 fwnode_handle_put(endpoint);
drivers/media/i2c/ov8865.c+2−1
@@ -2991,7 +2991,8 @@ static int ov8865_probe(struct i2c_client *client) · 2990 unmodified lines
29912991
29922992 handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
29932993 if (!handle)
2994− return -EPROBE_DEFER;
2994+ return dev_err_probe(dev, -EPROBE_DEFER,
2995+ "waiting for fwnode graph endpoint\n");
29952996
29962997 sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
29972998
drivers/media/i2c/saa7115.c+2−10
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525
2626 #include "saa711x_regs.h"
2727
28+#include <linux/bitops.h>
2829 #include <linux/kernel.h>
2930 #include <linux/module.h>
3031 #include <linux/slab.h>
@@ -664,15 +665,6 @@ static const unsigned char saa7115_init_misc[] = { · 633 unmodified lines
664665 0x00, 0x00
665666 };
666667
667−static int saa711x_odd_parity(u8 c)
668−{
669− c ^= (c >> 4);
670− c ^= (c >> 2);
671− c ^= (c >> 1);
672−
673− return c & 1;
674−}
675−
676668 static int saa711x_decode_vps(u8 *dst, u8 *p)
677669 {
678670 static const u8 biphase_tbl[] = {
@@ -1227,7 +1219,7 @@ static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vb · 548 unmodified lines
12271219 vbi->type = V4L2_SLICED_TELETEXT_B;
12281220 break;
12291221 case 4:
1230− if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1222+ if (!parity8(p[0]) || !parity8(p[1]))
12311223 return 0;
12321224 vbi->type = V4L2_SLICED_CAPTION_525;
12331225 break;
drivers/media/i2c/tc358743.c+89−49
@@ -114,7 +114,7 @@ static inline struct tc358743_state *to_state(struct v4l2_subdev *sd) · 113 unmodified lines
114114
115115 /* --------------- I2C --------------- */
116116
117−static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
117+static int i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
118118 {
119119 struct tc358743_state *state = to_state(sd);
120120 struct i2c_client *client = state->i2c_client;
@@ -140,6 +140,7 @@ static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) · 19 unmodified lines
140140 v4l2_err(sd, "%s: reading register 0x%x from 0x%x failed: %d\n",
141141 __func__, reg, client->addr, err);
142142 }
143+ return err != ARRAY_SIZE(msgs);
143144 }
144145
145146 static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
@@ -196,15 +197,24 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) · 50 unmodified lines
196197 }
197198 }
198199
199−static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
200+static noinline u32 i2c_rdreg_err(struct v4l2_subdev *sd, u16 reg, u32 n,
201+ int *err)
200202 {
203+ int error;
201204 __le32 val = 0;
202205
203− i2c_rd(sd, reg, (u8 __force *)&val, n);
206+ error = i2c_rd(sd, reg, (u8 __force *)&val, n);
207+ if (err)
208+ *err = error;
204209
205210 return le32_to_cpu(val);
206211 }
207212
213+static inline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
214+{
215+ return i2c_rdreg_err(sd, reg, n, NULL);
216+}
217+
208218 static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n)
209219 {
210220 __le32 raw = cpu_to_le32(val);
@@ -233,6 +243,13 @@ static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) · 22 unmodified lines
233243 return i2c_rdreg(sd, reg, 2);
234244 }
235245
246+static int i2c_rd16_err(struct v4l2_subdev *sd, u16 reg, u16 *value)
247+{
248+ int err;
249+ *value = i2c_rdreg_err(sd, reg, 2, &err);
250+ return err;
251+}
252+
236253 static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val)
237254 {
238255 i2c_wrreg(sd, reg, val, 2);
@@ -420,9 +437,9 @@ static void tc358743_enable_edid(struct v4l2_subdev *sd) · 181 unmodified lines
420437
421438 v4l2_dbg(2, debug, sd, "%s:\n", __func__);
422439
423− /* Enable hotplug after 100 ms. DDC access to EDID is also enabled when
440+ /* Enable hotplug after 143 ms. DDC access to EDID is also enabled when
424441 * hotplug is enabled. See register DDC_CTL */
425− schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 10);
442+ schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 7);
426443
427444 tc358743_enable_interrupts(sd, true);
428445 tc358743_s_ctrl_detect_tx_5v(sd);
@@ -1691,12 +1708,23 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd, · 1262 unmodified lines
16911708 return 0;
16921709 }
16931710
1711+static u32 tc358743_g_colorspace(u32 code)
1712+{
1713+ switch (code) {
1714+ case MEDIA_BUS_FMT_RGB888_1X24:
1715+ return V4L2_COLORSPACE_SRGB;
1716+ case MEDIA_BUS_FMT_UYVY8_1X16:
1717+ return V4L2_COLORSPACE_SMPTE170M;
1718+ default:
1719+ return 0;
1720+ }
1721+}
1722+
16941723 static int tc358743_get_fmt(struct v4l2_subdev *sd,
16951724 struct v4l2_subdev_state *sd_state,
16961725 struct v4l2_subdev_format *format)
16971726 {
16981727 struct tc358743_state *state = to_state(sd);
1699− u8 vi_rep = i2c_rd8(sd, VI_REP);
17001728
17011729 if (format->pad != 0)
17021730 return -EINVAL;
@@ -1706,23 +1734,7 @@ static int tc358743_get_fmt(struct v4l2_subdev *sd, · 3 unmodified lines
17061734 format->format.height = state->timings.bt.height;
17071735 format->format.field = V4L2_FIELD_NONE;
17081736
1709− switch (vi_rep & MASK_VOUT_COLOR_SEL) {
1710− case MASK_VOUT_COLOR_RGB_FULL:
1711− case MASK_VOUT_COLOR_RGB_LIMITED:
1712− format->format.colorspace = V4L2_COLORSPACE_SRGB;
1713− break;
1714− case MASK_VOUT_COLOR_601_YCBCR_LIMITED:
1715− case MASK_VOUT_COLOR_601_YCBCR_FULL:
1716− format->format.colorspace = V4L2_COLORSPACE_SMPTE170M;
1717− break;
1718− case MASK_VOUT_COLOR_709_YCBCR_FULL:
1719− case MASK_VOUT_COLOR_709_YCBCR_LIMITED:
1720− format->format.colorspace = V4L2_COLORSPACE_REC709;
1721− break;
1722− default:
1723− format->format.colorspace = 0;
1724− break;
1725− }
1737+ format->format.colorspace = tc358743_g_colorspace(format->format.code);
17261738
17271739 return 0;
17281740 }
@@ -1736,19 +1748,14 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd, · 7 unmodified lines
17361748 u32 code = format->format.code; /* is overwritten by get_fmt */
17371749 int ret = tc358743_get_fmt(sd, sd_state, format);
17381750
1739− format->format.code = code;
1751+ if (code == MEDIA_BUS_FMT_RGB888_1X24 ||
1752+ code == MEDIA_BUS_FMT_UYVY8_1X16)
1753+ format->format.code = code;
1754+ format->format.colorspace = tc358743_g_colorspace(format->format.code);
17401755
17411756 if (ret)
17421757 return ret;
17431758
1744− switch (code) {
1745− case MEDIA_BUS_FMT_RGB888_1X24:
1746− case MEDIA_BUS_FMT_UYVY8_1X16:
1747− break;
1748− default:
1749− return -EINVAL;
1750− }
1751−
17521759 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
17531760 return 0;
17541761
@@ -1972,8 +1979,19 @@ static int tc358743_probe_of(struct tc358743_state *state) · 217 unmodified lines
19721979 state->pdata.refclk_hz = clk_get_rate(refclk);
19731980 state->pdata.ddc5v_delay = DDC5V_DELAY_100_MS;
19741981 state->pdata.enable_hdcp = false;
1975− /* A FIFO level of 16 should be enough for 2-lane 720p60 at 594 MHz. */
1976− state->pdata.fifo_level = 16;
1982+ /*
1983+ * Ideally the FIFO trigger level should be set based on the input and
1984+ * output data rates, but the calculations required are buried in
1985+ * Toshiba's register settings spreadsheet.
1986+ * A value of 16 works with a 594Mbps data rate for 720p60 (using 2
1987+ * lanes) and 1080p60 (using 4 lanes), but fails when the data rate
1988+ * is increased, or a lower pixel clock is used that result in CSI
1989+ * reading out faster than the data is arriving.
1990+ *
1991+ * A value of 374 works with both those modes at 594Mbps, and with most
1992+ * modes on 972Mbps.
1993+ */
1994+ state->pdata.fifo_level = 374;
19771995 /*
19781996 * The PLL input clock is obtained by dividing refclk by pll_prd.
19791997 * It must be between 6 MHz and 40 MHz, lower frequency is better.
@@ -1993,6 +2011,7 @@ static int tc358743_probe_of(struct tc358743_state *state) · 13 unmodified lines
19932011 /*
19942012 * The CSI bps per lane must be between 62.5 Mbps and 1 Gbps.
19952013 * The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60.
2014+ * 972 Mbps allows 1080P50 UYVY over 2-lane.
19962015 */
19972016 bps_pr_lane = 2 * endpoint.link_frequencies[0];
19982017 if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) {
@@ -2006,23 +2025,42 @@ static int tc358743_probe_of(struct tc358743_state *state) · 7 unmodified lines
20062025 state->pdata.refclk_hz * state->pdata.pll_prd;
20072026
20082027 /*
2009− * FIXME: These timings are from REF_02 for 594 Mbps per lane (297 MHz
2010− * link frequency). In principle it should be possible to calculate
2028+ * FIXME: These timings are from REF_02 for 594 or 972 Mbps per lane
2029+ * (297 MHz or 486 MHz link frequency).
2030+ * In principle it should be possible to calculate
20112031 * them based on link frequency and resolution.
20122032 */
2013− if (bps_pr_lane != 594000000U)
2033+ switch (bps_pr_lane) {
2034+ default:
20142035 dev_warn(dev, "untested bps per lane: %u bps\n", bps_pr_lane);
2015− state->pdata.lineinitcnt = 0xe80;
2016− state->pdata.lptxtimecnt = 0x003;
2017− /* tclk-preparecnt: 3, tclk-zerocnt: 20 */
2018− state->pdata.tclk_headercnt = 0x1403;
2019− state->pdata.tclk_trailcnt = 0x00;
2020− /* ths-preparecnt: 3, ths-zerocnt: 1 */
2021− state->pdata.ths_headercnt = 0x0103;
2022− state->pdata.twakeup = 0x4882;
2023− state->pdata.tclk_postcnt = 0x008;
2024− state->pdata.ths_trailcnt = 0x2;
2025− state->pdata.hstxvregcnt = 0;
2036+ fallthrough;
2037+ case 594000000U:
2038+ state->pdata.lineinitcnt = 0xe80;
2039+ state->pdata.lptxtimecnt = 0x003;
2040+ /* tclk-preparecnt: 3, tclk-zerocnt: 20 */
2041+ state->pdata.tclk_headercnt = 0x1403;
2042+ state->pdata.tclk_trailcnt = 0x00;
2043+ /* ths-preparecnt: 3, ths-zerocnt: 1 */
2044+ state->pdata.ths_headercnt = 0x0103;
2045+ state->pdata.twakeup = 0x4882;
2046+ state->pdata.tclk_postcnt = 0x008;
2047+ state->pdata.ths_trailcnt = 0x2;
2048+ state->pdata.hstxvregcnt = 0;
2049+ break;
2050+ case 972000000U:
2051+ state->pdata.lineinitcnt = 0x1b58;
2052+ state->pdata.lptxtimecnt = 0x007;
2053+ /* tclk-preparecnt: 6, tclk-zerocnt: 40 */
2054+ state->pdata.tclk_headercnt = 0x2806;
2055+ state->pdata.tclk_trailcnt = 0x00;
2056+ /* ths-preparecnt: 6, ths-zerocnt: 8 */
2057+ state->pdata.ths_headercnt = 0x0806;
2058+ state->pdata.twakeup = 0x4268;
2059+ state->pdata.tclk_postcnt = 0x008;
2060+ state->pdata.ths_trailcnt = 0x5;
2061+ state->pdata.hstxvregcnt = 0;
2062+ break;
2063+ }
20262064
20272065 state->reset_gpio = devm_gpiod_get_optional(dev, "reset",
20282066 GPIOD_OUT_LOW);
@@ -2061,6 +2099,7 @@ static int tc358743_probe(struct i2c_client *client) · 32 unmodified lines
20612099 struct tc358743_platform_data *pdata = client->dev.platform_data;
20622100 struct v4l2_subdev *sd;
20632101 u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK;
2102+ u16 chipid;
20642103 int err;
20652104
20662105 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -2092,7 +2131,8 @@ static int tc358743_probe(struct i2c_client *client) · 25 unmodified lines
20922131 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
20932132
20942133 /* i2c access */
2095− if ((i2c_rd16(sd, CHIPID) & MASK_CHIPID) != 0) {
2134+ if (i2c_rd16_err(sd, CHIPID, &chipid) ||
2135+ (chipid & MASK_CHIPID) != 0) {
20962136 v4l2_info(sd, "not a TC358743 on address 0x%x\n",
20972137 client->addr << 1);
20982138 return -ENODEV;
drivers/media/i2c/tda1997x.c+2−2
@@ -589,8 +589,8 @@ static void tda1997x_enable_edid(struct v4l2_subdev *sd) · 588 unmodified lines
589589
590590 v4l2_dbg(1, debug, sd, "%s\n", __func__);
591591
592− /* Enable hotplug after 100ms */
593− schedule_delayed_work(&state->delayed_work_enable_hpd, HZ / 10);
592+ /* Enable hotplug after 143ms */
593+ schedule_delayed_work(&state->delayed_work_enable_hpd, HZ / 7);
594594 }
595595
596596 /* -----------------------------------------------------------------------------
drivers/media/i2c/vd55g1.c+16−16
@@ -111,9 +111,9 @@ · 110 unmodified lines
111111
112112 #define VD55G1_WIDTH 804
113113 #define VD55G1_HEIGHT 704
114−#define VD55G1_DEFAULT_MODE 0
114+#define VD55G1_MODE_DEF 0
115115 #define VD55G1_NB_GPIOS 4
116−#define VD55G1_MEDIA_BUS_FMT_DEF MEDIA_BUS_FMT_Y8_1X8
116+#define VD55G1_MBUS_CODE_DEF 0
117117 #define VD55G1_DGAIN_DEF 256
118118 #define VD55G1_AGAIN_DEF 19
119119 #define VD55G1_EXPO_MAX_TERM 64
@@ -129,8 +129,8 @@ · 9 unmodified lines
129129 #define VD55G1_FWPATCH_REVISION_MINOR 9
130130 #define VD55G1_XCLK_FREQ_MIN (6 * HZ_PER_MHZ)
131131 #define VD55G1_XCLK_FREQ_MAX (27 * HZ_PER_MHZ)
132−#define VD55G1_MIPI_RATE_MIN (250 * HZ_PER_MHZ)
133−#define VD55G1_MIPI_RATE_MAX (1200 * HZ_PER_MHZ)
132+#define VD55G1_MIPI_RATE_MIN (250 * MEGA)
133+#define VD55G1_MIPI_RATE_MAX (1200 * MEGA)
134134
135135 static const u8 patch_array[] = {
136136 0x44, 0x03, 0x09, 0x02, 0xe6, 0x01, 0x42, 0x00, 0xea, 0x01, 0x42, 0x00,
@@ -883,10 +883,9 @@ static int vd55g1_apply_cold_start(struct vd55g1 *sensor, · 746 unmodified lines
883883 return ret;
884884 }
885885
886−static void vd55g1_update_img_pad_format(struct vd55g1 *sensor,
887− const struct vd55g1_mode *mode,
888− u32 code,
889− struct v4l2_mbus_framefmt *fmt)
886+static void vd55g1_update_pad_fmt(struct vd55g1 *sensor,
887+ const struct vd55g1_mode *mode, u32 code,
888+ struct v4l2_mbus_framefmt *fmt)
890889 {
891890 fmt->code = code;
892891 fmt->width = mode->width;
@@ -1038,8 +1037,6 @@ static int vd55g1_enable_streams(struct v4l2_subdev *sd, · 145 unmodified lines
10381037 if (ret < 0)
10391038 return ret;
10401039
1041− vd55g1_write(sensor, VD55G1_REG_EXT_CLOCK, sensor->xclk_freq, &ret);
1042−
10431040 /* Configure output */
10441041 vd55g1_write(sensor, VD55G1_REG_MIPI_DATA_RATE,
10451042 sensor->mipi_rate, &ret);
@@ -1084,7 +1081,7 @@ static int vd55g1_enable_streams(struct v4l2_subdev *sd, · 38 unmodified lines
10841081
10851082 err_rpm_put:
10861083 pm_runtime_put(sensor->dev);
1087− return 0;
1084+ return -EINVAL;
10881085 }
10891086
10901087 static int vd55g1_disable_streams(struct v4l2_subdev *sd,
@@ -1231,8 +1228,8 @@ static int vd55g1_set_pad_fmt(struct v4l2_subdev *sd, · 140 unmodified lines
12311228 width, height, sd_fmt->format.width,
12321229 sd_fmt->format.height);
12331230
1234− vd55g1_update_img_pad_format(sensor, new_mode, sd_fmt->format.code,
1235− &sd_fmt->format);
1231+ vd55g1_update_pad_fmt(sensor, new_mode, sd_fmt->format.code,
1232+ &sd_fmt->format);
12361233
12371234 /*
12381235 * Use binning to maximize the crop rectangle size, and centre it in the
@@ -1262,7 +1259,6 @@ static int vd55g1_set_pad_fmt(struct v4l2_subdev *sd, · 23 unmodified lines
12621259 static int vd55g1_init_state(struct v4l2_subdev *sd,
12631260 struct v4l2_subdev_state *sd_state)
12641261 {
1265− unsigned int def_mode = VD55G1_DEFAULT_MODE;
12661262 struct vd55g1 *sensor = to_vd55g1(sd);
12671263 struct v4l2_subdev_format fmt = { 0 };
12681264 struct v4l2_subdev_route routes[] = {
@@ -1279,8 +1275,9 @@ static int vd55g1_init_state(struct v4l2_subdev *sd, · 10 unmodified lines
12791275 if (ret)
12801276 return ret;
12811277
1282− vd55g1_update_img_pad_format(sensor, &vd55g1_supported_modes[def_mode],
1283− VD55G1_MEDIA_BUS_FMT_DEF, &fmt.format);
1278+ vd55g1_update_pad_fmt(sensor, &vd55g1_supported_modes[VD55G1_MODE_DEF],
1279+ vd55g1_mbus_codes[VD55G1_MBUS_CODE_DEF].code,
1280+ &fmt.format);
12841281
12851282 return vd55g1_set_pad_fmt(sd, sd_state, &fmt);
12861283 }
@@ -1613,6 +1610,9 @@ static int vd55g1_power_on(struct device *dev) · 326 unmodified lines
16131610 goto disable_clock;
16141611 }
16151612
1613+ /* Setup clock now to advance through system FSM states */
1614+ vd55g1_write(sensor, VD55G1_REG_EXT_CLOCK, sensor->xclk_freq, &ret);
1615+
16161616 ret = vd55g1_patch(sensor);
16171617 if (ret) {
16181618 dev_err(dev, "Sensor patch failed %d\n", ret);
drivers/media/pci/cx18/cx18-av-vbi.c+2−10
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 */
99
1010
11+#include <linux/bitops.h>
1112 #include "cx18-driver.h"
1213
1314 /*
@@ -56,15 +57,6 @@ struct vbi_anc_data { · 42 unmodified lines
5657 /* u8 fill[]; Variable number of fill bytes */
5758 };
5859
59−static int odd_parity(u8 c)
60−{
61− c ^= (c >> 4);
62− c ^= (c >> 2);
63− c ^= (c >> 1);
64−
65− return c & 1;
66−}
67−
6860 static int decode_vps(u8 *dst, u8 *p)
6961 {
7062 static const u8 biphase_tbl[] = {
@@ -278,7 +270,7 @@ int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, · 207 unmodified lines
278270 break;
279271 case 6:
280272 sdid = V4L2_SLICED_CAPTION_525;
281− err = !odd_parity(p[0]) || !odd_parity(p[1]);
273+ err = !parity8(p[0]) || !parity8(p[1]);
282274 break;
283275 case 9:
284276 sdid = V4L2_SLICED_VPS;
drivers/media/pci/cx18/cx18-driver.h+0−12
@@ -271,18 +271,6 @@ struct cx18_options { · 270 unmodified lines
271271 #define CX18_SLICED_TYPE_WSS_625 (5)
272272 #define CX18_SLICED_TYPE_VPS (7)
273273
274−/**
275− * list_entry_is_past_end - check if a previous loop cursor is off list end
276− * @pos: the type * previously used as a loop cursor.
277− * @head: the head for your list.
278− * @member: the name of the list_head within the struct.
279− *
280− * Check if the entry's list_head is the head of the list, thus it's not a
281− * real entry but was the loop cursor that walked past the end
282− */
283−#define list_entry_is_past_end(pos, head, member) \
284− (&pos->member == (head))
285−
286274 struct cx18_vb2_buffer {
287275 /* Common video buffer sub-system struct */
288276 struct vb2_v4l2_buffer vb;
drivers/media/pci/cx18/cx18-fileops.c+1−1
@@ -371,7 +371,7 @@ static size_t cx18_copy_mdl_to_user(struct cx18_stream *s, · 370 unmodified lines
371371 mdl->curr_buf = list_first_entry(&mdl->buf_list,
372372 struct cx18_buffer, list);
373373
374− if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
374+ if (list_entry_is_head(mdl->curr_buf, &mdl->buf_list, list)) {
375375 /*
376376 * For some reason we've exhausted the buffers, but the MDL
377377 * object still said some data was unread.
drivers/media/pci/cx18/cx18-ioctl.c+1−1
@@ -764,7 +764,7 @@ static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl, · 763 unmodified lines
764764 mdl->curr_buf = list_first_entry(&mdl->buf_list,
765765 struct cx18_buffer, list);
766766
767− if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
767+ if (list_entry_is_head(mdl->curr_buf, &mdl->buf_list, list)) {
768768 /*
769769 * For some reason we've exhausted the buffers, but the MDL
770770 * object still said some data was unread.
drivers/media/pci/intel/ipu-bridge.c+10−3
@@ -55,11 +55,15 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { · 54 unmodified lines
5555 /* Himax HM2172 */
5656 IPU_SENSOR_CONFIG("HIMX2172", 1, 384000000),
5757 /* GalaxyCore GC0310 */
58− IPU_SENSOR_CONFIG("INT0310", 0),
58+ IPU_SENSOR_CONFIG("INT0310", 1, 55692000),
5959 /* Omnivision OV5693 */
6060 IPU_SENSOR_CONFIG("INT33BE", 1, 419200000),
61+ /* Onsemi MT9M114 */
62+ IPU_SENSOR_CONFIG("INT33F0", 1, 384000000),
6163 /* Omnivision OV2740 */
6264 IPU_SENSOR_CONFIG("INT3474", 1, 180000000),
65+ /* Omnivision OV5670 */
66+ IPU_SENSOR_CONFIG("INT3479", 1, 422400000),
6367 /* Omnivision OV8865 */
6468 IPU_SENSOR_CONFIG("INT347A", 1, 360000000),
6569 /* Omnivision OV7251 */
@@ -78,7 +82,7 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { · 12 unmodified lines
7882 /* Omnivision OV08A10 */
7983 IPU_SENSOR_CONFIG("OVTI08A1", 1, 500000000),
8084 /* Omnivision OV08x40 */
81− IPU_SENSOR_CONFIG("OVTI08F4", 1, 400000000),
85+ IPU_SENSOR_CONFIG("OVTI08F4", 3, 400000000, 749000000, 800000000),
8286 /* Omnivision OV13B10 */
8387 IPU_SENSOR_CONFIG("OVTI13B1", 1, 560000000),
8488 IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
@@ -86,6 +90,8 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { · 1 unmodified line
8690 IPU_SENSOR_CONFIG("OVTI2680", 1, 331200000),
8791 /* Omnivision OV8856 */
8892 IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000),
93+ /* Toshiba T4KA3 */
94+ IPU_SENSOR_CONFIG("XMCC0003", 1, 321468000),
8995 };
9096
9197 static const struct ipu_property_names prop_names = {
@@ -809,7 +815,8 @@ int ipu_bridge_init(struct device *dev, · 717 unmodified lines
809815 return 0;
810816
811817 if (!ipu_bridge_ivsc_is_ready())
812− return -EPROBE_DEFER;
818+ return dev_err_probe(dev, -EPROBE_DEFER,
819+ "waiting for IVSC to become ready\n");
813820
814821 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
815822 if (!bridge)
drivers/media/pci/intel/ipu3/ipu3-cio2.c+32−50
@@ -358,6 +358,8 @@ static int cio2_hw_init(struct cio2_device *cio2, struct cio2_queue *q) · 357 unmodified lines
358358 static const int FBPT_WIDTH = DIV_ROUND_UP(CIO2_MAX_LOPS,
359359 CIO2_FBPT_SUBENTRY_UNIT);
360360 const u32 num_buffers1 = CIO2_MAX_BUFFERS - 1;
361+ struct v4l2_subdev_state *state;
362+ const struct v4l2_mbus_framefmt *format;
361363 const struct ipu3_cio2_fmt *fmt;
362364 void __iomem *const base = cio2->base;
363365 u8 lanes, csi2bus = q->csi2.port;
@@ -365,7 +367,13 @@ static int cio2_hw_init(struct cio2_device *cio2, struct cio2_queue *q) · 1 unmodified line
365367 struct cio2_csi2_timing timing = { 0 };
366368 int i, r;
367369
368− fmt = cio2_find_format(NULL, &q->subdev_fmt.code);
370+ state = v4l2_subdev_lock_and_get_active_state(&q->subdev);
371+ format = v4l2_subdev_state_get_format(state, CIO2_PAD_SINK);
372+
373+ fmt = cio2_find_format(NULL, &format->code);
374+
375+ v4l2_subdev_unlock_state(state);
376+
369377 if (!fmt)
370378 return -EINVAL;
371379
@@ -1194,9 +1202,9 @@ static int cio2_subdev_subscribe_event(struct v4l2_subdev *sd, · 822 unmodified lines
11941202 return v4l2_event_subscribe(fh, sub, 0, NULL);
11951203 }
11961204
1197−static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1205+static int cio2_subdev_init_state(struct v4l2_subdev *sd,
1206+ struct v4l2_subdev_state *state)
11981207 {
1199− struct v4l2_mbus_framefmt *format;
12001208 const struct v4l2_mbus_framefmt fmt_default = {
12011209 .width = 1936,
12021210 .height = 1096,
@@ -1207,42 +1215,23 @@ static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) · 4 unmodified lines
12071215 .quantization = V4L2_QUANTIZATION_DEFAULT,
12081216 .xfer_func = V4L2_XFER_FUNC_DEFAULT,
12091217 };
1218+ struct v4l2_mbus_framefmt *format;
12101219
1211− /* Initialize try_fmt */
1212− format = v4l2_subdev_state_get_format(fh->state, CIO2_PAD_SINK);
1220+ /* Initialize the format on the sink and source pads. */
1221+ format = v4l2_subdev_state_get_format(state, CIO2_PAD_SINK);
12131222 *format = fmt_default;
12141223
12151224 /* same as sink */
1216− format = v4l2_subdev_state_get_format(fh->state, CIO2_PAD_SOURCE);
1225+ format = v4l2_subdev_state_get_format(state, CIO2_PAD_SOURCE);
12171226 *format = fmt_default;
12181227
12191228 return 0;
12201229 }
12211230
1222−static int cio2_subdev_get_fmt(struct v4l2_subdev *sd,
1223− struct v4l2_subdev_state *sd_state,
1224− struct v4l2_subdev_format *fmt)
1225−{
1226− struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
1227−
1228− mutex_lock(&q->subdev_lock);
1229−
1230− if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
1231− fmt->format = *v4l2_subdev_state_get_format(sd_state,
1232− fmt->pad);
1233− else
1234− fmt->format = q->subdev_fmt;
1235−
1236− mutex_unlock(&q->subdev_lock);
1237−
1238− return 0;
1239−}
1240−
12411231 static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
12421232 struct v4l2_subdev_state *sd_state,
12431233 struct v4l2_subdev_format *fmt)
12441234 {
1245− struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
12461235 struct v4l2_mbus_framefmt *mbus;
12471236 u32 mbus_code = fmt->format.code;
12481237 unsigned int i;
@@ -1252,12 +1241,7 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd, · 3 unmodified lines
12521241 * source always propagates from sink
12531242 */
12541243 if (fmt->pad == CIO2_PAD_SOURCE)
1255− return cio2_subdev_get_fmt(sd, sd_state, fmt);
1256−
1257− if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
1258− mbus = v4l2_subdev_state_get_format(sd_state, fmt->pad);
1259− else
1260− mbus = &q->subdev_fmt;
1244+ return v4l2_subdev_get_fmt(sd, sd_state, fmt);
12611245
12621246 fmt->format.code = formats[0].mbus_code;
12631247
@@ -1272,9 +1256,12 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd, · 8 unmodified lines
12721256 fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_HEIGHT);
12731257 fmt->format.field = V4L2_FIELD_NONE;
12741258
1275− mutex_lock(&q->subdev_lock);
1259+ mbus = v4l2_subdev_state_get_format(sd_state, CIO2_PAD_SINK);
1260+ *mbus = fmt->format;
1261+
1262+ /* Propagate the format to the source pad. */
1263+ mbus = v4l2_subdev_state_get_format(sd_state, CIO2_PAD_SOURCE);
12761264 *mbus = fmt->format;
1277− mutex_unlock(&q->subdev_lock);
12781265
12791266 return 0;
12801267 }
@@ -1345,12 +1332,12 @@ static const struct v4l2_subdev_core_ops cio2_subdev_core_ops = { · 64 unmodified lines
13451332 };
13461333
13471334 static const struct v4l2_subdev_internal_ops cio2_subdev_internal_ops = {
1348− .open = cio2_subdev_open,
1335+ .init_state = cio2_subdev_init_state,
13491336 };
13501337
13511338 static const struct v4l2_subdev_pad_ops cio2_subdev_pad_ops = {
13521339 .link_validate = v4l2_subdev_link_validate_default,
1353− .get_fmt = cio2_subdev_get_fmt,
1340+ .get_fmt = v4l2_subdev_get_fmt,
13541341 .set_fmt = cio2_subdev_set_fmt,
13551342 .enum_mbus_code = cio2_subdev_enum_mbus_code,
13561343 };
@@ -1502,28 +1489,18 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q) · 145 unmodified lines
15021489 {
15031490 static const u32 default_width = 1936;
15041491 static const u32 default_height = 1096;
1505− const struct ipu3_cio2_fmt dflt_fmt = formats[0];
15061492 struct device *dev = &cio2->pci_dev->dev;
15071493 struct video_device *vdev = &q->vdev;
15081494 struct vb2_queue *vbq = &q->vbq;
15091495 struct v4l2_subdev *subdev = &q->subdev;
1510− struct v4l2_mbus_framefmt *fmt;
15111496 int r;
15121497
15131498 /* Initialize miscellaneous variables */
15141499 mutex_init(&q->lock);
1515− mutex_init(&q->subdev_lock);
1516−
1517− /* Initialize formats to default values */
1518− fmt = &q->subdev_fmt;
1519− fmt->width = default_width;
1520− fmt->height = default_height;
1521− fmt->code = dflt_fmt.mbus_code;
1522− fmt->field = V4L2_FIELD_NONE;
15231500
15241501 q->format.width = default_width;
15251502 q->format.height = default_height;
1526− q->format.pixelformat = dflt_fmt.fourcc;
1503+ q->format.pixelformat = formats[0].fourcc;
15271504 q->format.colorspace = V4L2_COLORSPACE_RAW;
15281505 q->format.field = V4L2_FIELD_NONE;
15291506 q->format.num_planes = 1;
@@ -1567,9 +1544,16 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q) · 37 unmodified lines
15671544 CIO2_ENTITY_NAME " %td", q - cio2->queue);
15681545 subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
15691546 v4l2_set_subdevdata(subdev, cio2);
1547+
1548+ r = v4l2_subdev_init_finalize(subdev);
1549+ if (r) {
1550+ dev_err(dev, "failed to initialize subdev (%d)\n", r);
1551+ goto fail_subdev;
1552+ }
1553+
15701554 r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev);
15711555 if (r) {
1572− dev_err(dev, "failed initialize subdev (%d)\n", r);
1556+ dev_err(dev, "failed to register subdev (%d)\n", r);
15731557 goto fail_subdev;
15741558 }
15751559
@@ -1626,7 +1610,6 @@ fail_vdev_media_entity: · 50 unmodified lines
16261610 fail_subdev_media_entity:
16271611 cio2_fbpt_exit(q, dev);
16281612 fail_fbpt:
1629− mutex_destroy(&q->subdev_lock);
16301613 mutex_destroy(&q->lock);
16311614
16321615 return r;
@@ -1639,7 +1622,6 @@ static void cio2_queue_exit(struct cio2_device *cio2, struct cio2_queue *q) · 6 unmodified lines
16391622 v4l2_device_unregister_subdev(&q->subdev);
16401623 media_entity_cleanup(&q->subdev.entity);
16411624 cio2_fbpt_exit(q, &cio2->pci_dev->dev);
1642− mutex_destroy(&q->subdev_lock);
16431625 mutex_destroy(&q->lock);
16441626 }
16451627
drivers/media/pci/intel/ipu3/ipu3-cio2.h+0−2
@@ -351,9 +351,7 @@ struct cio2_queue { · 350 unmodified lines
351351
352352 /* Subdev, /dev/v4l-subdevX */
353353 struct v4l2_subdev subdev;
354− struct mutex subdev_lock; /* Serialise acces to subdev_fmt field */
355354 struct media_pad subdev_pads[CIO2_PADS];
356− struct v4l2_mbus_framefmt subdev_fmt;
357355 atomic_t frame_sequence;
358356
359357 /* Video device, /dev/videoX */
drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c+6−6
@@ -354,9 +354,9 @@ static int ipu6_isys_csi2_enable_streams(struct v4l2_subdev *sd, · 353 unmodified lines
354354 remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
355355 remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
356356
357− sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,
358− CSI2_PAD_SINK,
359− &streams_mask);
357+ sink_streams =
358+ v4l2_subdev_state_xlate_streams(state, pad, CSI2_PAD_SINK,
359+ &streams_mask);
360360
361361 ret = ipu6_isys_csi2_calc_timing(csi2, &timing, CSI2_ACCINV);
362362 if (ret)
@@ -384,9 +384,9 @@ static int ipu6_isys_csi2_disable_streams(struct v4l2_subdev *sd, · 21 unmodified lines
384384 struct media_pad *remote_pad;
385385 u64 sink_streams;
386386
387− sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,
388− CSI2_PAD_SINK,
389− &streams_mask);
387+ sink_streams =
388+ v4l2_subdev_state_xlate_streams(state, pad, CSI2_PAD_SINK,
389+ &streams_mask);
390390
391391 remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
392392 remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
drivers/media/pci/intel/ipu6/ipu6-isys.h+1−1
@@ -40,7 +40,7 @@ struct ipu6_bus_device; · 39 unmodified lines
4040 #define IPU6_ISYS_NUM_RECV_QUEUE 1
4141
4242 #define IPU6_ISYS_MIN_WIDTH 2U
43−#define IPU6_ISYS_MIN_HEIGHT 2U
43+#define IPU6_ISYS_MIN_HEIGHT 1U
4444 #define IPU6_ISYS_MAX_WIDTH 4672U
4545 #define IPU6_ISYS_MAX_HEIGHT 3416U
4646
drivers/media/pci/intel/ivsc/mei_ace.c+3−1
@@ -529,6 +529,8 @@ static void mei_ace_remove(struct mei_cl_device *cldev) · 528 unmodified lines
529529
530530 ace_set_camera_owner(ace, ACE_CAMERA_IVSC);
531531
532+ mei_cldev_disable(cldev);
533+
532534 mutex_destroy(&ace->lock);
533535 }
534536
@@ -574,7 +576,7 @@ static struct mei_cl_driver mei_ace_driver = { · 39 unmodified lines
574576
575577 module_mei_cl_driver(mei_ace_driver);
576578
577−MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
579+MODULE_AUTHOR("Wentong Wu");
578580 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
579581 MODULE_DESCRIPTION("Device driver for IVSC ACE");
580582 MODULE_LICENSE("GPL");
drivers/media/pci/intel/ivsc/mei_csi.c+3−1
@@ -760,6 +760,8 @@ static void mei_csi_remove(struct mei_cl_device *cldev) · 759 unmodified lines
760760
761761 pm_runtime_disable(&cldev->dev);
762762
763+ mei_cldev_disable(cldev);
764+
763765 mutex_destroy(&csi->lock);
764766 }
765767
@@ -783,7 +785,7 @@ static struct mei_cl_driver mei_csi_driver = { · 17 unmodified lines
783785 module_mei_cl_driver(mei_csi_driver);
784786
785787 MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
786−MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
788+MODULE_AUTHOR("Wentong Wu");
787789 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
788790 MODULE_DESCRIPTION("Device driver for IVSC CSI");
789791 MODULE_LICENSE("GPL");
drivers/media/pci/mgb4/mgb4_vout.c+8−1
@@ -492,7 +492,14 @@ static int vidioc_s_dv_timings(struct file *file, void *fh, · 491 unmodified lines
492492 static int vidioc_enum_dv_timings(struct file *file, void *fh,
493493 struct v4l2_enum_dv_timings *timings)
494494 {
495− return v4l2_enum_dv_timings_cap(timings, &video_timings_cap, NULL, NULL);
495+ struct mgb4_vout_dev *voutdev = video_drvdata(file);
496+
497+ if (timings->index != 0)
498+ return -EINVAL;
499+
500+ get_timings(voutdev, &timings->timings);
501+
502+ return 0;
496503 }
497504
498505 static int vidioc_dv_timings_cap(struct file *file, void *fh,
drivers/media/pci/saa7164/saa7164-buffer.c+0−20
@@ -52,26 +52,6 @@ · 51 unmodified lines
5252 * | etc
5353 */
5454
55−void saa7164_buffer_display(struct saa7164_buffer *buf)
56−{
57− struct saa7164_dev *dev = buf->port->dev;
58− int i;
59−
60− dprintk(DBGLVL_BUF, "%s() buffer @ 0x%p nr=%d\n",
61− __func__, buf, buf->idx);
62− dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08llx len = 0x%x\n",
63− buf->cpu, (long long)buf->dma, buf->pci_size);
64− dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n",
65− buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size);
66−
67− /* Format the Page Table Entries to point into the data buffer */
68− for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
69−
70− dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
71− i, buf->pt_cpu, (u64)*(buf->pt_cpu));
72−
73− }
74−}
7555 /* Allocate a new buffer structure and associated PCI space in bytes.
7656 * len must be a multiple of sizeof(u64)
7757 */
drivers/media/pci/saa7164/saa7164-cmd.c+0−28
@@ -295,34 +295,6 @@ static int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno) · 294 unmodified lines
295295 return ret;
296296 }
297297
298−void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
299−{
300− int i;
301− dprintk(DBGLVL_CMD, "%s()\n", __func__);
302−
303− mutex_lock(&dev->lock);
304− for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
305− if (dev->cmds[i].inuse == 1) {
306− dprintk(DBGLVL_CMD,
307− "seqno %d inuse, sig = %d, t/out = %d\n",
308− dev->cmds[i].seqno,
309− dev->cmds[i].signalled,
310− dev->cmds[i].timeout);
311− }
312− }
313−
314− for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
315− if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
316− (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
317− dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
318− __func__, i);
319− dev->cmds[i].signalled = 1;
320− wake_up(&dev->cmds[i].wait);
321− }
322− }
323− mutex_unlock(&dev->lock);
324−}
325−
326298 int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
327299 u16 controlselector, u16 size, void *buf)
328300 {
drivers/media/pci/saa7164/saa7164.h+0−2
@@ -508,7 +508,6 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg, · 507 unmodified lines
508508 int saa7164_cmd_send(struct saa7164_dev *dev,
509509 u8 id, enum tmComResCmd command, u16 controlselector,
510510 u16 size, void *buf);
511−void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
512511 int saa7164_irq_dequeue(struct saa7164_dev *dev);
513512
514513 /* ----------------------------------------------------------- */
@@ -570,7 +569,6 @@ extern int saa7164_dvb_unregister(struct saa7164_port *port); · 55 unmodified lines
570569 extern struct saa7164_buffer *saa7164_buffer_alloc(
571570 struct saa7164_port *port, u32 len);
572571 extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf);
573−extern void saa7164_buffer_display(struct saa7164_buffer *buf);
574572 extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i);
575573 extern int saa7164_buffer_cfg_port(struct saa7164_port *port);
576574 extern struct saa7164_user_buffer *saa7164_buffer_alloc_user(
drivers/media/pci/solo6x10/solo6x10-gpio.c+5−17
@@ -116,18 +116,6 @@ static int solo_gpiochip_get_direction(struct gpio_chip *chip, · 115 unmodified lines
116116 return -1;
117117 }
118118
119−static int solo_gpiochip_direction_input(struct gpio_chip *chip,
120− unsigned int offset)
121−{
122− return -1;
123−}
124−
125−static int solo_gpiochip_direction_output(struct gpio_chip *chip,
126− unsigned int offset, int value)
127−{
128− return -1;
129−}
130−
131119 static int solo_gpiochip_get(struct gpio_chip *chip,
132120 unsigned int offset)
133121 {
@@ -139,8 +127,8 @@ static int solo_gpiochip_get(struct gpio_chip *chip, · 5 unmodified lines
139127 return 1 & (ret >> (offset + 8));
140128 }
141129
142−static void solo_gpiochip_set(struct gpio_chip *chip,
143− unsigned int offset, int value)
130+static int solo_gpiochip_set(struct gpio_chip *chip,
131+ unsigned int offset, int value)
144132 {
145133 struct solo_dev *solo_dev = gpiochip_get_data(chip);
146134
@@ -148,6 +136,8 @@ static void solo_gpiochip_set(struct gpio_chip *chip, · 1 unmodified line
148136 solo_gpio_set(solo_dev, 1 << (offset + 8));
149137 else
150138 solo_gpio_clear(solo_dev, 1 << (offset + 8));
139+
140+ return 0;
151141 }
152142 #endif
153143
@@ -167,10 +157,8 @@ int solo_gpio_init(struct solo_dev *solo_dev) · 13 unmodified lines
167157 solo_dev->gpio_dev.can_sleep = 0;
168158
169159 solo_dev->gpio_dev.get_direction = solo_gpiochip_get_direction;
170− solo_dev->gpio_dev.direction_input = solo_gpiochip_direction_input;
171− solo_dev->gpio_dev.direction_output = solo_gpiochip_direction_output;
172160 solo_dev->gpio_dev.get = solo_gpiochip_get;
173− solo_dev->gpio_dev.set = solo_gpiochip_set;
161+ solo_dev->gpio_dev.set_rv = solo_gpiochip_set;
174162
175163 ret = gpiochip_add_data(&solo_dev->gpio_dev, solo_dev);
176164
drivers/media/platform/amphion/vdec.c+249−45
@@ -26,6 +26,7 @@ · 25 unmodified lines
2626 #include "vpu_cmds.h"
2727 #include "vpu_rpc.h"
2828
29+#define VDEC_SLOT_CNT_DFT 32
2930 #define VDEC_MIN_BUFFER_CAP 8
3031 #define VDEC_MIN_BUFFER_OUT 8
3132
@@ -41,6 +42,14 @@ struct vdec_fs_info { · 9 unmodified lines
4142 u32 tag;
4243 };
4344
45+struct vdec_frame_store_t {
46+ struct vpu_vb2_buffer *curr;
47+ struct vpu_vb2_buffer *pend;
48+ dma_addr_t addr;
49+ unsigned int state;
50+ u32 tag;
51+};
52+
4453 struct vdec_t {
4554 u32 seq_hdr_found;
4655 struct vpu_buffer udata;
@@ -48,7 +57,8 @@ struct vdec_t { · 1 unmodified line
4857 struct vpu_dec_codec_info codec_info;
4958 enum vpu_codec_state state;
5059
51− struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
60+ struct vdec_frame_store_t *slots;
61+ u32 slot_count;
5262 u32 req_frame_count;
5363 struct vdec_fs_info mbi;
5464 struct vdec_fs_info dcp;
@@ -232,6 +242,35 @@ static int vdec_ctrl_init(struct vpu_inst *inst) · 177 unmodified lines
232242 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,
233243 0, 1, 1, 0);
234244
245+ v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
246+ V4L2_CID_MPEG_VIDEO_H264_PROFILE,
247+ V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
248+ ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
249+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
250+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
251+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED) |
252+ (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
253+ V4L2_MPEG_VIDEO_H264_PROFILE_MAIN);
254+
255+ v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
256+ V4L2_CID_MPEG_VIDEO_H264_LEVEL,
257+ V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
258+ 0,
259+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
260+
261+ v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
262+ V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
263+ V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
264+ ~((1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
265+ (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)),
266+ V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN);
267+
268+ v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL,
269+ V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
270+ V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
271+ 0,
272+ V4L2_MPEG_VIDEO_HEVC_LEVEL_4);
273+
235274 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
236275 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
237276 if (ctrl)
@@ -258,6 +297,63 @@ static int vdec_ctrl_init(struct vpu_inst *inst) · 20 unmodified lines
258297 return 0;
259298 }
260299
300+static void vdec_attach_frame_store(struct vpu_inst *inst, struct vb2_buffer *vb)
301+{
302+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
303+ struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
304+ struct vdec_t *vdec = inst->priv;
305+ struct vdec_frame_store_t *new_slots = NULL;
306+ dma_addr_t addr;
307+ int i;
308+
309+ addr = vpu_get_vb_phy_addr(vb, 0);
310+ for (i = 0; i < vdec->slot_count; i++) {
311+ if (addr == vdec->slots[i].addr) {
312+ if (vdec->slots[i].curr && vdec->slots[i].curr != vpu_buf) {
313+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED);
314+ vdec->slots[i].pend = vpu_buf;
315+ } else {
316+ vpu_set_buffer_state(vbuf, vdec->slots[i].state);
317+ }
318+ vpu_buf->fs_id = i;
319+ return;
320+ }
321+ }
322+
323+ for (i = 0; i < vdec->slot_count; i++) {
324+ if (!vdec->slots[i].addr) {
325+ vdec->slots[i].addr = addr;
326+ vpu_buf->fs_id = i;
327+ return;
328+ }
329+ }
330+
331+ new_slots = krealloc_array(vdec->slots, vdec->slot_count * 2,
332+ sizeof(*vdec->slots),
333+ GFP_KERNEL | __GFP_ZERO);
334+ if (!new_slots) {
335+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_ERROR);
336+ return;
337+ }
338+
339+ vdec->slots = new_slots;
340+ vdec->slot_count *= 2;
341+
342+ vdec->slots[i].addr = addr;
343+ vpu_buf->fs_id = i;
344+}
345+
346+static void vdec_reset_frame_store(struct vpu_inst *inst)
347+{
348+ struct vdec_t *vdec = inst->priv;
349+
350+ if (!vdec->slots || !vdec->slot_count)
351+ return;
352+
353+ vpu_trace(inst->dev, "inst[%d] reset slots\n", inst->id);
354+ memset(vdec->slots, 0, sizeof(*vdec->slots) * vdec->slot_count);
355+}
356+
261357 static void vdec_handle_resolution_change(struct vpu_inst *inst)
262358 {
263359 struct vdec_t *vdec = inst->priv;
@@ -714,11 +810,11 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg) · 450 unmodified lines
714810 struct vb2_v4l2_buffer *src_buf;
715811 int ret = 0;
716812
717− if (!info || info->id >= ARRAY_SIZE(vdec->slots))
813+ if (!info || info->id >= vdec->slot_count)
718814 return -EINVAL;
719815
720816 vpu_inst_lock(inst);
721− vpu_buf = vdec->slots[info->id];
817+ vpu_buf = vdec->slots[info->id].curr;
722818 if (!vpu_buf) {
723819 dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
724820 ret = -EINVAL;
@@ -739,11 +835,13 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg) · 14 unmodified lines
739835 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
740836 dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
741837 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
838+ vdec->slots[info->id].state = VPU_BUF_STATE_DECODED;
742839 vdec->decoded_frame_count++;
743840 if (vdec->params.display_delay_enable) {
744841 struct vpu_format *cur_fmt;
745842
746843 cur_fmt = vpu_get_format(inst, inst->cap_format.type);
844+ vdec->slots[info->id].state = VPU_BUF_STATE_READY;
747845 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
748846 for (int i = 0; i < vbuf->vb2_buf.num_planes; i++)
749847 vb2_set_plane_payload(&vbuf->vb2_buf,
@@ -766,11 +864,11 @@ static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma) · 16 unmodified lines
766864 struct vdec_t *vdec = inst->priv;
767865 int i;
768866
769− for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
770− if (!vdec->slots[i])
867+ for (i = 0; i < vdec->slot_count; i++) {
868+ if (!vdec->slots[i].curr)
771869 continue;
772− if (luma == vdec->slots[i]->luma)
773− return vdec->slots[i];
870+ if (luma == vdec->slots[i].addr)
871+ return vdec->slots[i].curr;
774872 }
775873
776874 return NULL;
@@ -804,11 +902,11 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame) · 27 unmodified lines
804902
805903 cur_fmt = vpu_get_format(inst, inst->cap_format.type);
806904 vbuf = &vpu_buf->m2m_buf.vb;
807− if (vbuf->vb2_buf.index != frame->id)
808− dev_err(inst->dev, "[%d] buffer id(%d, %d) mismatch\n",
809− inst->id, vbuf->vb2_buf.index, frame->id);
905+ if (vpu_buf->fs_id != frame->id)
906+ dev_err(inst->dev, "[%d] buffer id(%d(%d), %d) mismatch\n",
907+ inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index, frame->id);
810908
811− if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable)
909+ if (vdec->params.display_delay_enable)
812910 return;
813911
814912 if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
@@ -821,10 +919,11 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame) · 6 unmodified lines
821919 vbuf->sequence = vdec->sequence;
822920 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
823921
824− v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
825922 vpu_inst_lock(inst);
923+ vdec->slots[vpu_buf->fs_id].state = VPU_BUF_STATE_READY;
826924 vdec->display_frame_count++;
827925 vpu_inst_unlock(inst);
926+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
828927 dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
829928 inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
830929 }
@@ -1052,18 +1151,30 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb · 221 unmodified lines
10521151 if (!vbuf)
10531152 return -EINVAL;
10541153
1055− if (vdec->slots[vbuf->vb2_buf.index]) {
1056− dev_err(inst->dev, "[%d] repeat alloc fs %d\n",
1057− inst->id, vbuf->vb2_buf.index);
1154+ vpu_buf = to_vpu_vb2_buffer(vbuf);
1155+ if (vpu_buf->fs_id < 0 || vpu_buf->fs_id >= vdec->slot_count) {
1156+ dev_err(inst->dev, "invalid fs %d for v4l2 buffer %d\n",
1157+ vpu_buf->fs_id, vbuf->vb2_buf.index);
10581158 return -EINVAL;
10591159 }
10601160
1161+ if (vdec->slots[vpu_buf->fs_id].curr) {
1162+ if (vdec->slots[vpu_buf->fs_id].curr != vpu_buf) {
1163+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED);
1164+ vdec->slots[vpu_buf->fs_id].pend = vpu_buf;
1165+ } else {
1166+ vpu_set_buffer_state(vbuf, vdec->slots[vpu_buf->fs_id].state);
1167+ }
1168+ dev_err(inst->dev, "[%d] repeat alloc fs %d (v4l2 index %d)\n",
1169+ inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index);
1170+ return -EAGAIN;
1171+ }
1172+
10611173 dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n",
10621174 inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag);
1063− vpu_buf = to_vpu_vb2_buffer(vbuf);
10641175
10651176 memset(&info, 0, sizeof(info));
1066− info.id = vbuf->vb2_buf.index;
1177+ info.id = vpu_buf->fs_id;
10671178 info.type = MEM_RES_FRAME;
10681179 info.tag = vdec->seq_tag;
10691180 info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
@@ -1078,12 +1189,13 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb · 8 unmodified lines
10781189 if (ret)
10791190 return ret;
10801191
1081− vpu_buf->tag = info.tag;
10821192 vpu_buf->luma = info.luma_addr;
10831193 vpu_buf->chroma_u = info.chroma_addr;
10841194 vpu_buf->chroma_v = 0;
10851195 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
1086− vdec->slots[info.id] = vpu_buf;
1196+ vdec->slots[info.id].tag = info.tag;
1197+ vdec->slots[info.id].curr = vpu_buf;
1198+ vdec->slots[info.id].state = VPU_BUF_STATE_INUSE;
10871199 vdec->req_frame_count--;
10881200
10891201 return 0;
@@ -1144,25 +1256,76 @@ static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *v · 54 unmodified lines
11441256 v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
11451257 }
11461258
1147−static void vdec_clear_slots(struct vpu_inst *inst)
1259+static void vdec_release_curr_frame_store(struct vpu_inst *inst, u32 id)
11481260 {
11491261 struct vdec_t *vdec = inst->priv;
11501262 struct vpu_vb2_buffer *vpu_buf;
11511263 struct vb2_v4l2_buffer *vbuf;
1264+
1265+ if (id >= vdec->slot_count)
1266+ return;
1267+ if (!vdec->slots[id].curr)
1268+ return;
1269+
1270+ vpu_buf = vdec->slots[id].curr;
1271+ vbuf = &vpu_buf->m2m_buf.vb;
1272+
1273+ vdec_response_fs_release(inst, id, vdec->slots[id].tag);
1274+ if (vpu_buf->fs_id == id) {
1275+ if (vpu_buf->state != VPU_BUF_STATE_READY)
1276+ vdec_recycle_buffer(inst, vbuf);
1277+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
1278+ }
1279+
1280+ vdec->slots[id].curr = NULL;
1281+ vdec->slots[id].state = VPU_BUF_STATE_IDLE;
1282+
1283+ if (vdec->slots[id].pend) {
1284+ vpu_set_buffer_state(&vdec->slots[id].pend->m2m_buf.vb, VPU_BUF_STATE_IDLE);
1285+ vdec->slots[id].pend = NULL;
1286+ }
1287+}
1288+
1289+static void vdec_clear_slots(struct vpu_inst *inst)
1290+{
1291+ struct vdec_t *vdec = inst->priv;
11521292 int i;
11531293
1154− for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
1155− if (!vdec->slots[i])
1294+ for (i = 0; i < vdec->slot_count; i++) {
1295+ if (!vdec->slots[i].curr)
11561296 continue;
11571297
1158− vpu_buf = vdec->slots[i];
1159− vbuf = &vpu_buf->m2m_buf.vb;
1160−
11611298 vpu_trace(inst->dev, "clear slot %d\n", i);
1162− vdec_response_fs_release(inst, i, vpu_buf->tag);
1163− vdec_recycle_buffer(inst, vbuf);
1164− vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
1165− vdec->slots[i] = NULL;
1299+ vdec_release_curr_frame_store(inst, i);
1300+ }
1301+}
1302+
1303+static void vdec_update_v4l2_ctrl(struct vpu_inst *inst, u32 id, u32 val)
1304+{
1305+ struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id);
1306+
1307+ if (ctrl)
1308+ v4l2_ctrl_s_ctrl(ctrl, val);
1309+}
1310+
1311+static void vdec_update_v4l2_profile_level(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
1312+{
1313+ switch (inst->out_format.pixfmt) {
1314+ case V4L2_PIX_FMT_H264:
1315+ case V4L2_PIX_FMT_H264_MVC:
1316+ vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1317+ vpu_get_h264_v4l2_profile(hdr));
1318+ vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1319+ vpu_get_h264_v4l2_level(hdr));
1320+ break;
1321+ case V4L2_PIX_FMT_HEVC:
1322+ vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
1323+ vpu_get_hevc_v4l2_profile(hdr));
1324+ vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
1325+ vpu_get_hevc_v4l2_level(hdr));
1326+ break;
1327+ default:
1328+ return;
11661329 }
11671330 }
11681331
@@ -1189,6 +1352,7 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info · 20 unmodified lines
11891352 vdec_init_crop(inst);
11901353 vdec_init_mbi(inst);
11911354 vdec_init_dcp(inst);
1355+ vdec_update_v4l2_profile_level(inst, hdr);
11921356 if (!vdec->seq_hdr_found) {
11931357 vdec->seq_tag = vdec->codec_info.tag;
11941358 if (vdec->is_source_changed) {
@@ -1263,39 +1427,29 @@ static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs) · 68 unmodified lines
12631427 static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
12641428 {
12651429 struct vdec_t *vdec = inst->priv;
1266− struct vpu_vb2_buffer *vpu_buf;
1267− struct vb2_v4l2_buffer *vbuf;
12681430
1269− if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
1431+ if (!fs || fs->id >= vdec->slot_count)
12701432 return;
12711433 if (fs->type != MEM_RES_FRAME)
12721434 return;
12731435
1274− if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
1436+ if (fs->id >= vdec->slot_count) {
12751437 dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
12761438 return;
12771439 }
12781440
12791441 vpu_inst_lock(inst);
1280− vpu_buf = vdec->slots[fs->id];
1281− vdec->slots[fs->id] = NULL;
1282−
1283− if (!vpu_buf) {
1442+ if (!vdec->slots[fs->id].curr) {
12841443 dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
12851444 goto exit;
12861445 }
12871446
1288− vbuf = &vpu_buf->m2m_buf.vb;
1289− if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
1447+ if (vdec->slots[fs->id].state == VPU_BUF_STATE_DECODED) {
12901448 dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
12911449 vdec->sequence++;
12921450 }
12931451
1294− vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
1295− if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_READY)
1296− vdec_recycle_buffer(inst, vbuf);
1297−
1298− vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
1452+ vdec_release_curr_frame_store(inst, fs->id);
12991453 vpu_process_capture_buffer(inst);
13001454
13011455 exit:
@@ -1485,6 +1639,11 @@ static void vdec_cleanup(struct vpu_inst *inst) · 183 unmodified lines
14851639 return;
14861640
14871641 vdec = inst->priv;
1642+ if (vdec) {
1643+ kfree(vdec->slots);
1644+ vdec->slots = NULL;
1645+ vdec->slot_count = 0;
1646+ }
14881647 vfree(vdec);
14891648 inst->priv = NULL;
14901649 vfree(inst);
@@ -1606,11 +1765,43 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type) · 115 unmodified lines
16061765 return 0;
16071766 }
16081767
1609−static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
1768+static int vdec_get_slot_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
16101769 {
16111770 struct vdec_t *vdec = inst->priv;
1771+ struct vpu_vb2_buffer *vpu_buf;
16121772 int num = -1;
16131773
1774+ vpu_inst_lock(inst);
1775+ if (i >= vdec->slot_count || !vdec->slots[i].addr)
1776+ goto exit;
1777+
1778+ vpu_buf = vdec->slots[i].curr;
1779+
1780+ num = scnprintf(str, size, "slot[%2d] :", i);
1781+ if (vpu_buf) {
1782+ num += scnprintf(str + num, size - num, " %2d",
1783+ vpu_buf->m2m_buf.vb.vb2_buf.index);
1784+ num += scnprintf(str + num, size - num, "; state = %d", vdec->slots[i].state);
1785+ } else {
1786+ num += scnprintf(str + num, size - num, " -1");
1787+ }
1788+
1789+ if (vdec->slots[i].pend)
1790+ num += scnprintf(str + num, size - num, "; %d",
1791+ vdec->slots[i].pend->m2m_buf.vb.vb2_buf.index);
1792+
1793+ num += scnprintf(str + num, size - num, "\n");
1794+exit:
1795+ vpu_inst_unlock(inst);
1796+
1797+ return num;
1798+}
1799+
1800+static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
1801+{
1802+ struct vdec_t *vdec = inst->priv;
1803+ int num;
1804+
16141805 switch (i) {
16151806 case 0:
16161807 num = scnprintf(str, size,
@@ -1664,6 +1855,7 @@ static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i · 47 unmodified lines
16641855 vdec->codec_info.vui_present);
16651856 break;
16661857 default:
1858+ num = vdec_get_slot_debug_info(inst, str, size, i - 10);
16671859 break;
16681860 }
16691861
@@ -1687,6 +1879,8 @@ static struct vpu_inst_ops vdec_inst_ops = { · 17 unmodified lines
16871879 .get_debug_info = vdec_get_debug_info,
16881880 .wait_prepare = vpu_inst_unlock,
16891881 .wait_finish = vpu_inst_lock,
1882+ .attach_frame_store = vdec_attach_frame_store,
1883+ .reset_frame_store = vdec_reset_frame_store,
16901884 };
16911885
16921886 static void vdec_init(struct file *file)
@@ -1727,6 +1921,16 @@ static int vdec_open(struct file *file) · 34 unmodified lines
17271921 return -ENOMEM;
17281922 }
17291923
1924+ vdec->slots = kmalloc_array(VDEC_SLOT_CNT_DFT,
1925+ sizeof(*vdec->slots),
1926+ GFP_KERNEL | __GFP_ZERO);
1927+ if (!vdec->slots) {
1928+ vfree(vdec);
1929+ vfree(inst);
1930+ return -ENOMEM;
1931+ }
1932+ vdec->slot_count = VDEC_SLOT_CNT_DFT;
1933+
17301934 inst->ops = &vdec_inst_ops;
17311935 inst->formats = vdec_formats;
17321936 inst->type = VPU_CORE_TYPE_DEC;
drivers/media/platform/amphion/vpu.h+5−2
@@ -222,6 +222,8 @@ struct vpu_inst_ops { · 221 unmodified lines
222222 int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
223223 void (*wait_prepare)(struct vpu_inst *inst);
224224 void (*wait_finish)(struct vpu_inst *inst);
225+ void (*attach_frame_store)(struct vpu_inst *inst, struct vb2_buffer *vb);
226+ void (*reset_frame_store)(struct vpu_inst *inst);
225227 };
226228
227229 struct vpu_inst {
@@ -295,7 +297,8 @@ enum { · 67 unmodified lines
295297 VPU_BUF_STATE_DECODED,
296298 VPU_BUF_STATE_READY,
297299 VPU_BUF_STATE_SKIP,
298− VPU_BUF_STATE_ERROR
300+ VPU_BUF_STATE_ERROR,
301+ VPU_BUF_STATE_CHANGED
299302 };
300303
301304 struct vpu_vb2_buffer {
@@ -304,8 +307,8 @@ struct vpu_vb2_buffer { · 2 unmodified lines
304307 dma_addr_t chroma_u;
305308 dma_addr_t chroma_v;
306309 unsigned int state;
307− u32 tag;
308310 u32 average_qp;
311+ s32 fs_id;
309312 };
310313
311314 void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);
drivers/media/platform/amphion/vpu_color.c+0−73
@@ -108,76 +108,3 @@ u32 vpu_color_cvrt_full_range_i2v(u32 full_range) · 107 unmodified lines
108108
109109 return V4L2_QUANTIZATION_LIM_RANGE;
110110 }
111−
112−int vpu_color_check_primaries(u32 primaries)
113−{
114− return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
115−}
116−
117−int vpu_color_check_transfers(u32 transfers)
118−{
119− return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
120−}
121−
122−int vpu_color_check_matrix(u32 matrix)
123−{
124− return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
125−}
126−
127−int vpu_color_check_full_range(u32 full_range)
128−{
129− int ret = -EINVAL;
130−
131− switch (full_range) {
132− case V4L2_QUANTIZATION_FULL_RANGE:
133− case V4L2_QUANTIZATION_LIM_RANGE:
134− ret = 0;
135− break;
136− default:
137− break;
138− }
139−
140− return ret;
141−}
142−
143−int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
144−{
145− u32 transfers;
146− u32 matrix;
147− u32 full_range;
148−
149− switch (primaries) {
150− case V4L2_COLORSPACE_REC709:
151− transfers = V4L2_XFER_FUNC_709;
152− matrix = V4L2_YCBCR_ENC_709;
153− break;
154− case V4L2_COLORSPACE_470_SYSTEM_M:
155− case V4L2_COLORSPACE_470_SYSTEM_BG:
156− case V4L2_COLORSPACE_SMPTE170M:
157− transfers = V4L2_XFER_FUNC_709;
158− matrix = V4L2_YCBCR_ENC_601;
159− break;
160− case V4L2_COLORSPACE_SMPTE240M:
161− transfers = V4L2_XFER_FUNC_SMPTE240M;
162− matrix = V4L2_YCBCR_ENC_SMPTE240M;
163− break;
164− case V4L2_COLORSPACE_BT2020:
165− transfers = V4L2_XFER_FUNC_709;
166− matrix = V4L2_YCBCR_ENC_BT2020;
167− break;
168− default:
169− transfers = V4L2_XFER_FUNC_DEFAULT;
170− matrix = V4L2_YCBCR_ENC_DEFAULT;
171− break;
172− }
173− full_range = V4L2_QUANTIZATION_LIM_RANGE;
174−
175− if (ptransfers)
176− *ptransfers = transfers;
177− if (pmatrix)
178− *pmatrix = matrix;
179− if (pfull_range)
180− *pfull_range = full_range;
181−
182− return 0;
183−}
drivers/media/platform/amphion/vpu_dbg.c+14−1
@@ -48,6 +48,7 @@ static char *vpu_stat_name[] = { · 47 unmodified lines
4848 [VPU_BUF_STATE_READY] = "ready",
4949 [VPU_BUF_STATE_SKIP] = "skip",
5050 [VPU_BUF_STATE_ERROR] = "error",
51+ [VPU_BUF_STATE_CHANGED] = "changed",
5152 };
5253
5354 static inline const char *to_vpu_stat_name(int state)
@@ -164,6 +165,7 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) · 110 unmodified lines
164165 for (i = 0; i < vb2_get_num_buffers(vq); i++) {
165166 struct vb2_buffer *vb;
166167 struct vb2_v4l2_buffer *vbuf;
168+ struct vpu_vb2_buffer *vpu_buf;
167169
168170 vb = vb2_get_buffer(vq, i);
169171 if (!vb)
@@ -173,13 +175,24 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) · 3 unmodified lines
173175 continue;
174176
175177 vbuf = to_vb2_v4l2_buffer(vb);
178+ vpu_buf = to_vpu_vb2_buffer(vbuf);
176179
177180 num = scnprintf(str, sizeof(str),
178− "capture[%2d] state = %10s, %8s\n",
181+ "capture[%2d] state = %10s, %8s",
179182 i, vb2_stat_name[vb->state],
180183 to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
181184 if (seq_write(s, str, num))
182185 return 0;
186+
187+ if (vpu_buf->fs_id >= 0) {
188+ num = scnprintf(str, sizeof(str), "; fs %d", vpu_buf->fs_id);
189+ if (seq_write(s, str, num))
190+ return 0;
191+ }
192+
193+ num = scnprintf(str, sizeof(str), "\n");
194+ if (seq_write(s, str, num))
195+ return 0;
183196 }
184197
185198 num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
drivers/media/platform/amphion/vpu_defs.h+12−0
@@ -134,6 +134,7 @@ struct vpu_dec_codec_info { · 133 unmodified lines
134134 u32 decoded_height;
135135 struct v4l2_fract frame_rate;
136136 u32 dsp_asp_ratio;
137+ u32 profile_idc;
137138 u32 level_idc;
138139 u32 bit_depth_luma;
139140 u32 bit_depth_chroma;
@@ -147,6 +148,17 @@ struct vpu_dec_codec_info { · 7 unmodified lines
147148 u32 mbi_size;
148149 u32 dcp_size;
149150 u32 stride;
151+ union {
152+ struct {
153+ u32 constraint_set5_flag : 1;
154+ u32 constraint_set4_flag : 1;
155+ u32 constraint_set3_flag : 1;
156+ u32 constraint_set2_flag : 1;
157+ u32 constraint_set1_flag : 1;
158+ u32 constraint_set0_flag : 1;
159+ };
160+ u32 constraint_set_flags;
161+ };
150162 };
151163
152164 struct vpu_dec_pic_info {
drivers/media/platform/amphion/vpu_helpers.c+123−0
@@ -509,3 +509,126 @@ const char *vpu_codec_state_name(enum vpu_codec_state state) · 508 unmodified lines
509509 }
510510 return "<unknown>";
511511 }
512+
513+struct codec_id_mapping {
514+ u32 id;
515+ u32 v4l2_id;
516+};
517+
518+static struct codec_id_mapping h264_profiles[] = {
519+ {66, V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE},
520+ {77, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN},
521+ {88, V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED},
522+ {100, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH}
523+};
524+
525+static struct codec_id_mapping h264_levels[] = {
526+ {10, V4L2_MPEG_VIDEO_H264_LEVEL_1_0},
527+ {9, V4L2_MPEG_VIDEO_H264_LEVEL_1B},
528+ {11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1},
529+ {12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2},
530+ {13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3},
531+ {20, V4L2_MPEG_VIDEO_H264_LEVEL_2_0},
532+ {21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1},
533+ {22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2},
534+ {30, V4L2_MPEG_VIDEO_H264_LEVEL_3_0},
535+ {31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1},
536+ {32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2},
537+ {40, V4L2_MPEG_VIDEO_H264_LEVEL_4_0},
538+ {41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1},
539+ {42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2},
540+ {50, V4L2_MPEG_VIDEO_H264_LEVEL_5_0},
541+ {51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1},
542+ {52, V4L2_MPEG_VIDEO_H264_LEVEL_5_2},
543+ {60, V4L2_MPEG_VIDEO_H264_LEVEL_6_0},
544+ {61, V4L2_MPEG_VIDEO_H264_LEVEL_6_1},
545+ {62, V4L2_MPEG_VIDEO_H264_LEVEL_6_2}
546+};
547+
548+static struct codec_id_mapping hevc_profiles[] = {
549+ {1, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN},
550+ {2, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10}
551+};
552+
553+static struct codec_id_mapping hevc_levels[] = {
554+ {30, V4L2_MPEG_VIDEO_HEVC_LEVEL_1},
555+ {60, V4L2_MPEG_VIDEO_HEVC_LEVEL_2},
556+ {63, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1},
557+ {90, V4L2_MPEG_VIDEO_HEVC_LEVEL_3},
558+ {93, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1},
559+ {120, V4L2_MPEG_VIDEO_HEVC_LEVEL_4},
560+ {123, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1},
561+ {150, V4L2_MPEG_VIDEO_HEVC_LEVEL_5},
562+ {153, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1},
563+ {156, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2},
564+ {180, V4L2_MPEG_VIDEO_HEVC_LEVEL_6},
565+ {183, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1},
566+ {186, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2}
567+};
568+
569+static u32 vpu_find_v4l2_id(u32 id, struct codec_id_mapping *array, u32 array_sz)
570+{
571+ u32 i;
572+
573+ if (!array || !array_sz)
574+ return 0;
575+
576+ for (i = 0; i < array_sz; i++) {
577+ if (id == array[i].id)
578+ return array[i].v4l2_id;
579+ }
580+
581+ return 0;
582+}
583+
584+u32 vpu_get_h264_v4l2_profile(struct vpu_dec_codec_info *hdr)
585+{
586+ if (!hdr)
587+ return 0;
588+
589+ /*
590+ * In H.264 Document section A.2.1.1 Constrained Baseline profile
591+ * Conformance of a bitstream to the Constrained Baseline profile is indicated by
592+ * profile_idc being equal to 66 with constraint_set1_flag being equal to 1.
593+ */
594+ if (hdr->profile_idc == 66 && hdr->constraint_set1_flag)
595+ return V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
596+
597+ return vpu_find_v4l2_id(hdr->profile_idc, h264_profiles, ARRAY_SIZE(h264_profiles));
598+}
599+
600+u32 vpu_get_h264_v4l2_level(struct vpu_dec_codec_info *hdr)
601+{
602+ if (!hdr)
603+ return 0;
604+
605+ /*
606+ * In H.264 Document section 7.4.2.1.1 Sequence parameter set data semantics
607+ * If profile_idc is equal to 66, 77, or 88 and level_idc is equal to 11,
608+ * constraint_set3_flag equal to 1 indicates that the coded video sequence
609+ * obeys all constraints specified in Annex A for level 1b
610+ * and constraint_set3_flag equal to 0 indicates that the coded video sequence
611+ * obeys all constraints specified in Annex A for level 1.1.
612+ */
613+ if (hdr->level_idc == 11 && hdr->constraint_set3_flag &&
614+ (hdr->profile_idc == 66 || hdr->profile_idc == 77 || hdr->profile_idc == 88))
615+ return V4L2_MPEG_VIDEO_H264_LEVEL_1B;
616+
617+ return vpu_find_v4l2_id(hdr->level_idc, h264_levels, ARRAY_SIZE(h264_levels));
618+}
619+
620+u32 vpu_get_hevc_v4l2_profile(struct vpu_dec_codec_info *hdr)
621+{
622+ if (!hdr)
623+ return 0;
624+
625+ return vpu_find_v4l2_id(hdr->profile_idc, hevc_profiles, ARRAY_SIZE(hevc_profiles));
626+}
627+
628+u32 vpu_get_hevc_v4l2_level(struct vpu_dec_codec_info *hdr)
629+{
630+ if (!hdr)
631+ return 0;
632+
633+ return vpu_find_v4l2_id(hdr->level_idc, hevc_levels, ARRAY_SIZE(hevc_levels));
634+}
drivers/media/platform/amphion/vpu_helpers.h+7−5
@@ -6,6 +6,8 @@ · 5 unmodified lines
66 #ifndef _AMPHION_VPU_HELPERS_H
77 #define _AMPHION_VPU_HELPERS_H
88
9+#include "vpu_defs.h"
10+
911 struct vpu_pair {
1012 u32 src;
1113 u32 dst;
@@ -54,10 +56,6 @@ static inline u8 vpu_helper_read_byte(struct vpu_buffer *stream_buffer, u32 pos) · 42 unmodified lines
5456 return pdata[pos % stream_buffer->length];
5557 }
5658
57−int vpu_color_check_primaries(u32 primaries);
58−int vpu_color_check_transfers(u32 transfers);
59−int vpu_color_check_matrix(u32 matrix);
60−int vpu_color_check_full_range(u32 full_range);
6159 u32 vpu_color_cvrt_primaries_v2i(u32 primaries);
6260 u32 vpu_color_cvrt_primaries_i2v(u32 primaries);
6361 u32 vpu_color_cvrt_transfers_v2i(u32 transfers);
@@ -66,8 +64,12 @@ u32 vpu_color_cvrt_matrix_v2i(u32 matrix); · 2 unmodified lines
6664 u32 vpu_color_cvrt_matrix_i2v(u32 matrix);
6765 u32 vpu_color_cvrt_full_range_v2i(u32 full_range);
6866 u32 vpu_color_cvrt_full_range_i2v(u32 full_range);
69−int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range);
7067
7168 int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
7269 int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
70+
71+u32 vpu_get_h264_v4l2_profile(struct vpu_dec_codec_info *hdr);
72+u32 vpu_get_h264_v4l2_level(struct vpu_dec_codec_info *hdr);
73+u32 vpu_get_hevc_v4l2_profile(struct vpu_dec_codec_info *hdr);
74+u32 vpu_get_hevc_v4l2_level(struct vpu_dec_codec_info *hdr);
7375 #endif
drivers/media/platform/amphion/vpu_malone.c+4−1
@@ -908,7 +908,8 @@ static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt, · 907 unmodified lines
908908 info->frame_rate.numerator = 1000;
909909 info->frame_rate.denominator = pkt->data[8];
910910 info->dsp_asp_ratio = pkt->data[9];
911− info->level_idc = pkt->data[10];
911+ info->profile_idc = (pkt->data[10] >> 8) & 0xff;
912+ info->level_idc = pkt->data[10] & 0xff;
912913 info->bit_depth_luma = pkt->data[13];
913914 info->bit_depth_chroma = pkt->data[14];
914915 info->chroma_fmt = pkt->data[15];
@@ -925,6 +926,8 @@ static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt, · 10 unmodified lines
925926 info->pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128;
926927 else
927928 info->pixfmt = V4L2_PIX_FMT_NV12M_8L128;
929+ if (pkt->hdr.num > 28)
930+ info->constraint_set_flags = pkt->data[28];
928931 if (info->frame_rate.numerator && info->frame_rate.denominator) {
929932 unsigned long n, d;
930933
drivers/media/platform/amphion/vpu_mbox.c+0−4
@@ -109,7 +109,3 @@ void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data) · 108 unmodified lines
109109 mbox_send_message(core->tx_data.ch, &data);
110110 mbox_send_message(core->tx_type.ch, &type);
111111 }
112−
113−void vpu_mbox_enable_rx(struct vpu_dev *dev)
114−{
115−}
drivers/media/platform/amphion/vpu_mbox.h+0−1
@@ -11,6 +11,5 @@ int vpu_mbox_request(struct vpu_core *core); · 10 unmodified lines
1111 void vpu_mbox_free(struct vpu_core *core);
1212 void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data);
1313 void vpu_mbox_send_type(struct vpu_core *core, u32 type);
14−void vpu_mbox_enable_rx(struct vpu_dev *dev);
1514
1615 #endif
drivers/media/platform/amphion/vpu_v4l2.c+11−0
@@ -501,14 +501,25 @@ static int vpu_vb2_queue_setup(struct vb2_queue *vq, · 500 unmodified lines
501501 call_void_vop(inst, release);
502502 }
503503
504+ if (V4L2_TYPE_IS_CAPTURE(vq->type))
505+ call_void_vop(inst, reset_frame_store);
506+
504507 return 0;
505508 }
506509
507510 static int vpu_vb2_buf_init(struct vb2_buffer *vb)
508511 {
509512 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
513+ struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
514+ struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
510515
516+ vpu_buf->fs_id = -1;
511517 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
518+
519+ if (!inst->ops->attach_frame_store || V4L2_TYPE_IS_OUTPUT(vb->type))
520+ return 0;
521+
522+ call_void_vop(inst, attach_frame_store, vb);
512523 return 0;
513524 }
514525
drivers/media/platform/cadence/cdns-csi2rx.c+131−0
@@ -57,6 +57,25 @@ · 56 unmodified lines
5757 #define CSI2RX_LANES_MAX 4
5858 #define CSI2RX_STREAMS_MAX 4
5959
60+#define CSI2RX_ERROR_IRQS_REG 0x28
61+#define CSI2RX_ERROR_IRQS_MASK_REG 0x2C
62+
63+#define CSI2RX_STREAM3_FIFO_OVERFLOW_IRQ BIT(19)
64+#define CSI2RX_STREAM2_FIFO_OVERFLOW_IRQ BIT(18)
65+#define CSI2RX_STREAM1_FIFO_OVERFLOW_IRQ BIT(17)
66+#define CSI2RX_STREAM0_FIFO_OVERFLOW_IRQ BIT(16)
67+#define CSI2RX_FRONT_TRUNC_HDR_IRQ BIT(12)
68+#define CSI2RX_PROT_TRUNCATED_PACKET_IRQ BIT(11)
69+#define CSI2RX_FRONT_LP_NO_PAYLOAD_IRQ BIT(10)
70+#define CSI2RX_SP_INVALID_RCVD_IRQ BIT(9)
71+#define CSI2RX_DATA_ID_IRQ BIT(7)
72+#define CSI2RX_HEADER_CORRECTED_ECC_IRQ BIT(6)
73+#define CSI2RX_HEADER_ECC_IRQ BIT(5)
74+#define CSI2RX_PAYLOAD_CRC_IRQ BIT(4)
75+
76+#define CSI2RX_ECC_ERRORS GENMASK(7, 4)
77+#define CSI2RX_PACKET_ERRORS GENMASK(12, 9)
78+
6079 enum csi2rx_pads {
6180 CSI2RX_PAD_SINK,
6281 CSI2RX_PAD_SOURCE_STREAM0,
@@ -71,9 +90,32 @@ struct csi2rx_fmt { · 8 unmodified lines
7190 u8 bpp;
7291 };
7392
93+struct csi2rx_event {
94+ u32 mask;
95+ const char *name;
96+};
97+
98+static const struct csi2rx_event csi2rx_events[] = {
99+ { CSI2RX_STREAM3_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 3 FIFO detected" },
100+ { CSI2RX_STREAM2_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 2 FIFO detected" },
101+ { CSI2RX_STREAM1_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 1 FIFO detected" },
102+ { CSI2RX_STREAM0_FIFO_OVERFLOW_IRQ, "Overflow of the Stream 0 FIFO detected" },
103+ { CSI2RX_FRONT_TRUNC_HDR_IRQ, "A truncated header [short or long] has been received" },
104+ { CSI2RX_PROT_TRUNCATED_PACKET_IRQ, "A truncated long packet has been received" },
105+ { CSI2RX_FRONT_LP_NO_PAYLOAD_IRQ, "A truncated long packet has been received. No payload" },
106+ { CSI2RX_SP_INVALID_RCVD_IRQ, "A reserved or invalid short packet has been received" },
107+ { CSI2RX_DATA_ID_IRQ, "Data ID error in the header packet" },
108+ { CSI2RX_HEADER_CORRECTED_ECC_IRQ, "ECC error detected and corrected" },
109+ { CSI2RX_HEADER_ECC_IRQ, "Unrecoverable ECC error" },
110+ { CSI2RX_PAYLOAD_CRC_IRQ, "CRC error" },
111+};
112+
113+#define CSI2RX_NUM_EVENTS ARRAY_SIZE(csi2rx_events)
114+
74115 struct csi2rx_priv {
75116 struct device *dev;
76117 unsigned int count;
118+ int error_irq;
77119
78120 /*
79121 * Used to prevent race conditions between multiple,
@@ -95,6 +137,7 @@ struct csi2rx_priv { · 15 unmodified lines
95137 u8 max_lanes;
96138 u8 max_streams;
97139 bool has_internal_dphy;
140+ u32 events[CSI2RX_NUM_EVENTS];
98141
99142 struct v4l2_subdev subdev;
100143 struct v4l2_async_notifier notifier;
@@ -124,6 +167,54 @@ static const struct csi2rx_fmt formats[] = { · 23 unmodified lines
124167 { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, },
125168 };
126169
170+static void csi2rx_configure_error_irq_mask(void __iomem *base,
171+ struct csi2rx_priv *csi2rx)
172+{
173+ u32 error_irq_mask = 0;
174+
175+ error_irq_mask |= CSI2RX_ECC_ERRORS;
176+ error_irq_mask |= CSI2RX_PACKET_ERRORS;
177+
178+ /*
179+ * Iterate through all source pads and check if they are linked
180+ * to an active remote pad. If an active remote pad is found,
181+ * calculate the corresponding bit position and set it in
182+ * mask, enabling the stream overflow error in the mask.
183+ */
184+ for (int i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++) {
185+ struct media_pad *remote_pad;
186+
187+ remote_pad = media_pad_remote_pad_first(&csi2rx->pads[i]);
188+ if (remote_pad) {
189+ int pad = i - CSI2RX_PAD_SOURCE_STREAM0;
190+ u32 bit_mask = CSI2RX_STREAM0_FIFO_OVERFLOW_IRQ << pad;
191+
192+ error_irq_mask |= bit_mask;
193+ }
194+ }
195+
196+ writel(error_irq_mask, base + CSI2RX_ERROR_IRQS_MASK_REG);
197+}
198+
199+static irqreturn_t csi2rx_irq_handler(int irq, void *dev_id)
200+{
201+ struct csi2rx_priv *csi2rx = dev_id;
202+ int i;
203+ u32 error_status, error_mask;
204+
205+ error_status = readl(csi2rx->base + CSI2RX_ERROR_IRQS_REG);
206+ error_mask = readl(csi2rx->base + CSI2RX_ERROR_IRQS_MASK_REG);
207+
208+ for (i = 0; i < CSI2RX_NUM_EVENTS; i++)
209+ if ((error_status & csi2rx_events[i].mask) &&
210+ (error_mask & csi2rx_events[i].mask))
211+ csi2rx->events[i]++;
212+
213+ writel(error_status, csi2rx->base + CSI2RX_ERROR_IRQS_REG);
214+
215+ return IRQ_HANDLED;
216+}
217+
127218 static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
128219 {
129220 unsigned int i;
@@ -220,6 +311,9 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) · 90 unmodified lines
220311 reset_control_deassert(csi2rx->p_rst);
221312 csi2rx_reset(csi2rx);
222313
314+ if (csi2rx->error_irq >= 0)
315+ csi2rx_configure_error_irq_mask(csi2rx->base, csi2rx);
316+
223317 reg = csi2rx->num_lanes << 8;
224318 for (i = 0; i < csi2rx->num_lanes; i++) {
225319 reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csi2rx->lanes[i]);
@@ -332,6 +426,8 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx) · 106 unmodified lines
332426 reset_control_assert(csi2rx->sys_rst);
333427 clk_disable_unprepare(csi2rx->sys_clk);
334428
429+ writel(0, csi2rx->base + CSI2RX_ERROR_IRQS_MASK_REG);
430+
335431 for (i = 0; i < csi2rx->max_streams; i++) {
336432 writel(CSI2RX_STREAM_CTRL_STOP,
337433 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
@@ -363,6 +459,21 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx) · 25 unmodified lines
363459 }
364460 }
365461
462+static int csi2rx_log_status(struct v4l2_subdev *sd)
463+{
464+ struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(sd);
465+ unsigned int i;
466+
467+ for (i = 0; i < CSI2RX_NUM_EVENTS; i++) {
468+ if (csi2rx->events[i])
469+ dev_info(csi2rx->dev, "%s events: %d\n",
470+ csi2rx_events[i].name,
471+ csi2rx->events[i]);
472+ }
473+
474+ return 0;
475+}
476+
366477 static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
367478 {
368479 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
@@ -468,7 +579,12 @@ static const struct v4l2_subdev_video_ops csi2rx_video_ops = { · 99 unmodified lines
468579 .s_stream = csi2rx_s_stream,
469580 };
470581
582+static const struct v4l2_subdev_core_ops csi2rx_core_ops = {
583+ .log_status = csi2rx_log_status,
584+};
585+
471586 static const struct v4l2_subdev_ops csi2rx_subdev_ops = {
587+ .core = &csi2rx_core_ops,
472588 .video = &csi2rx_video_ops,
473589 .pad = &csi2rx_pad_ops,
474590 };
@@ -705,6 +821,21 @@ static int csi2rx_probe(struct platform_device *pdev) · 230 unmodified lines
705821 if (ret)
706822 goto err_cleanup;
707823
824+ csi2rx->error_irq = platform_get_irq_byname_optional(pdev, "error_irq");
825+
826+ if (csi2rx->error_irq < 0) {
827+ dev_dbg(csi2rx->dev, "Optional interrupt not defined, proceeding without it\n");
828+ } else {
829+ ret = devm_request_irq(csi2rx->dev, csi2rx->error_irq,
830+ csi2rx_irq_handler, 0,
831+ dev_name(&pdev->dev), csi2rx);
832+ if (ret) {
833+ dev_err(csi2rx->dev,
834+ "Unable to request interrupt: %d\n", ret);
835+ goto err_cleanup;
836+ }
837+ }
838+
708839 ret = v4l2_subdev_init_finalize(&csi2rx->subdev);
709840 if (ret)
710841 goto err_cleanup;
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c+36−11
@@ -598,6 +598,27 @@ static void _bswap16(u16 *a) · 597 unmodified lines
598598 *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);
599599 }
600600
601+static dma_addr_t mxc_jpeg_get_plane_dma_addr(struct vb2_buffer *buf, unsigned int plane_no)
602+{
603+ if (plane_no >= buf->num_planes)
604+ return 0;
605+ return vb2_dma_contig_plane_dma_addr(buf, plane_no) + buf->planes[plane_no].data_offset;
606+}
607+
608+static void *mxc_jpeg_get_plane_vaddr(struct vb2_buffer *buf, unsigned int plane_no)
609+{
610+ if (plane_no >= buf->num_planes)
611+ return NULL;
612+ return vb2_plane_vaddr(buf, plane_no) + buf->planes[plane_no].data_offset;
613+}
614+
615+static unsigned long mxc_jpeg_get_plane_payload(struct vb2_buffer *buf, unsigned int plane_no)
616+{
617+ if (plane_no >= buf->num_planes)
618+ return 0;
619+ return vb2_get_plane_payload(buf, plane_no) - buf->planes[plane_no].data_offset;
620+}
621+
601622 static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf,
602623 unsigned long len)
603624 {
@@ -610,11 +631,11 @@ static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf, · 6 unmodified lines
610631 return;
611632
612633 for (plane_no = 0; plane_no < buf->num_planes; plane_no++) {
613− payload = vb2_get_plane_payload(buf, plane_no);
634+ payload = mxc_jpeg_get_plane_payload(buf, plane_no);
614635 if (len == 0)
615636 len = payload;
616− dma_addr = vb2_dma_contig_plane_dma_addr(buf, plane_no);
617− vaddr = vb2_plane_vaddr(buf, plane_no);
637+ dma_addr = mxc_jpeg_get_plane_dma_addr(buf, plane_no);
638+ vaddr = mxc_jpeg_get_plane_vaddr(buf, plane_no);
618639 v4l2_dbg(3, debug, &jpeg->v4l2_dev,
619640 "plane %d (vaddr=%p dma_addr=%x payload=%ld):",
620641 plane_no, vaddr, dma_addr, payload);
@@ -712,16 +733,15 @@ static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc, · 91 unmodified lines
712733 struct mxc_jpeg_q_data *q_data;
713734
714735 q_data = mxc_jpeg_get_q_data(ctx, raw_buf->type);
715− desc->buf_base0 = vb2_dma_contig_plane_dma_addr(raw_buf, 0);
736+ desc->buf_base0 = mxc_jpeg_get_plane_dma_addr(raw_buf, 0);
716737 desc->buf_base1 = 0;
717738 if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) {
718739 if (raw_buf->num_planes == 2)
719− desc->buf_base1 = vb2_dma_contig_plane_dma_addr(raw_buf, 1);
740+ desc->buf_base1 = mxc_jpeg_get_plane_dma_addr(raw_buf, 1);
720741 else
721742 desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0];
722743 }
723− desc->stm_bufbase = vb2_dma_contig_plane_dma_addr(jpeg_buf, 0) +
724− offset;
744+ desc->stm_bufbase = mxc_jpeg_get_plane_dma_addr(jpeg_buf, 0) + offset;
725745 }
726746
727747 static bool mxc_jpeg_is_extended_sequential(const struct mxc_jpeg_fmt *fmt)
@@ -1029,8 +1049,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) · 301 unmodified lines
10291049 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload);
10301050 }
10311051 dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n",
1032− vb2_get_plane_payload(&dst_buf->vb2_buf, 0),
1033− vb2_get_plane_payload(&dst_buf->vb2_buf, 1));
1052+ mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 0),
1053+ mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 1));
10341054 }
10351055
10361056 /* short preview of the results */
@@ -1889,8 +1909,8 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) · 852 unmodified lines
18891909 struct mxc_jpeg_sof *psof = NULL;
18901910 struct mxc_jpeg_sos *psos = NULL;
18911911 struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb);
1892− u8 *src_addr = (u8 *)vb2_plane_vaddr(vb, 0);
1893− u32 size = vb2_get_plane_payload(vb, 0);
1912+ u8 *src_addr = (u8 *)mxc_jpeg_get_plane_vaddr(vb, 0);
1913+ u32 size = mxc_jpeg_get_plane_payload(vb, 0);
18941914 int ret;
18951915
18961916 memset(&header, 0, sizeof(header));
@@ -2027,6 +2047,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) · 130 unmodified lines
20272047 i, vb2_plane_size(vb, i), sizeimage);
20282048 return -EINVAL;
20292049 }
2050+ if (!IS_ALIGNED(mxc_jpeg_get_plane_dma_addr(vb, i), MXC_JPEG_ADDR_ALIGNMENT)) {
2051+ dev_err(dev, "planes[%d] address is not %d aligned\n",
2052+ i, MXC_JPEG_ADDR_ALIGNMENT);
2053+ return -EINVAL;
2054+ }
20302055 }
20312056 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
20322057 vb2_set_plane_payload(vb, 0, 0);
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h+1−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030 #define MXC_JPEG_MAX_PLANES 2
3131 #define MXC_JPEG_PATTERN_WIDTH 128
3232 #define MXC_JPEG_PATTERN_HEIGHT 64
33+#define MXC_JPEG_ADDR_ALIGNMENT 16
3334
3435 enum mxc_jpeg_enc_state {
3536 MXC_JPEG_ENCODING = 0, /* jpeg encode phase */
drivers/media/platform/nxp/imx-mipi-csis.c+25−43
@@ -28,6 +28,7 @@ · 27 unmodified lines
2828 #include <linux/reset.h>
2929 #include <linux/spinlock.h>
3030
31+#include <media/mipi-csi2.h>
3132 #include <media/v4l2-common.h>
3233 #include <media/v4l2-device.h>
3334 #include <media/v4l2-event.h>
@@ -229,25 +230,6 @@ · 195 unmodified lines
229230
230231 #define DEFAULT_SCLK_CSIS_FREQ 166000000UL
231232
232−/* MIPI CSI-2 Data Types */
233−#define MIPI_CSI2_DATA_TYPE_YUV420_8 0x18
234−#define MIPI_CSI2_DATA_TYPE_YUV420_10 0x19
235−#define MIPI_CSI2_DATA_TYPE_LE_YUV420_8 0x1a
236−#define MIPI_CSI2_DATA_TYPE_CS_YUV420_8 0x1c
237−#define MIPI_CSI2_DATA_TYPE_CS_YUV420_10 0x1d
238−#define MIPI_CSI2_DATA_TYPE_YUV422_8 0x1e
239−#define MIPI_CSI2_DATA_TYPE_YUV422_10 0x1f
240−#define MIPI_CSI2_DATA_TYPE_RGB565 0x22
241−#define MIPI_CSI2_DATA_TYPE_RGB666 0x23
242−#define MIPI_CSI2_DATA_TYPE_RGB888 0x24
243−#define MIPI_CSI2_DATA_TYPE_RAW6 0x28
244−#define MIPI_CSI2_DATA_TYPE_RAW7 0x29
245−#define MIPI_CSI2_DATA_TYPE_RAW8 0x2a
246−#define MIPI_CSI2_DATA_TYPE_RAW10 0x2b
247−#define MIPI_CSI2_DATA_TYPE_RAW12 0x2c
248−#define MIPI_CSI2_DATA_TYPE_RAW14 0x2d
249−#define MIPI_CSI2_DATA_TYPE_USER(x) (0x30 + (x))
250−
251233 struct mipi_csis_event {
252234 bool debug;
253235 u32 mask;
@@ -357,116 +339,116 @@ static const struct csis_pix_format mipi_csis_formats[] = { · 103 unmodified lines
357339 {
358340 .code = MEDIA_BUS_FMT_UYVY8_1X16,
359341 .output = MEDIA_BUS_FMT_UYVY8_1X16,
360− .data_type = MIPI_CSI2_DATA_TYPE_YUV422_8,
342+ .data_type = MIPI_CSI2_DT_YUV422_8B,
361343 .width = 16,
362344 },
363345 /* RGB formats. */
364346 {
365347 .code = MEDIA_BUS_FMT_RGB565_1X16,
366348 .output = MEDIA_BUS_FMT_RGB565_1X16,
367− .data_type = MIPI_CSI2_DATA_TYPE_RGB565,
349+ .data_type = MIPI_CSI2_DT_RGB565,
368350 .width = 16,
369351 }, {
370352 .code = MEDIA_BUS_FMT_BGR888_1X24,
371353 .output = MEDIA_BUS_FMT_RGB888_1X24,
372− .data_type = MIPI_CSI2_DATA_TYPE_RGB888,
354+ .data_type = MIPI_CSI2_DT_RGB888,
373355 .width = 24,
374356 },
375357 /* RAW (Bayer and greyscale) formats. */
376358 {
377359 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
378360 .output = MEDIA_BUS_FMT_SBGGR8_1X8,
379− .data_type = MIPI_CSI2_DATA_TYPE_RAW8,
361+ .data_type = MIPI_CSI2_DT_RAW8,
380362 .width = 8,
381363 }, {
382364 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
383365 .output = MEDIA_BUS_FMT_SGBRG8_1X8,
384− .data_type = MIPI_CSI2_DATA_TYPE_RAW8,
366+ .data_type = MIPI_CSI2_DT_RAW8,
385367 .width = 8,
386368 }, {
387369 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
388370 .output = MEDIA_BUS_FMT_SGRBG8_1X8,
389− .data_type = MIPI_CSI2_DATA_TYPE_RAW8,
371+ .data_type = MIPI_CSI2_DT_RAW8,
390372 .width = 8,
391373 }, {
392374 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
393375 .output = MEDIA_BUS_FMT_SRGGB8_1X8,
394− .data_type = MIPI_CSI2_DATA_TYPE_RAW8,
376+ .data_type = MIPI_CSI2_DT_RAW8,
395377 .width = 8,
396378 }, {
397379 .code = MEDIA_BUS_FMT_Y8_1X8,
398380 .output = MEDIA_BUS_FMT_Y8_1X8,
399− .data_type = MIPI_CSI2_DATA_TYPE_RAW8,
381+ .data_type = MIPI_CSI2_DT_RAW8,
400382 .width = 8,
401383 }, {
402384 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
403385 .output = MEDIA_BUS_FMT_SBGGR10_1X10,
404− .data_type = MIPI_CSI2_DATA_TYPE_RAW10,
386+ .data_type = MIPI_CSI2_DT_RAW10,
405387 .width = 10,
406388 }, {
407389 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
408390 .output = MEDIA_BUS_FMT_SGBRG10_1X10,
409− .data_type = MIPI_CSI2_DATA_TYPE_RAW10,
391+ .data_type = MIPI_CSI2_DT_RAW10,
410392 .width = 10,
411393 }, {
412394 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
413395 .output = MEDIA_BUS_FMT_SGRBG10_1X10,
414− .data_type = MIPI_CSI2_DATA_TYPE_RAW10,
396+ .data_type = MIPI_CSI2_DT_RAW10,
415397 .width = 10,
416398 }, {
417399 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
418400 .output = MEDIA_BUS_FMT_SRGGB10_1X10,
419− .data_type = MIPI_CSI2_DATA_TYPE_RAW10,
401+ .data_type = MIPI_CSI2_DT_RAW10,
420402 .width = 10,
421403 }, {
422404 .code = MEDIA_BUS_FMT_Y10_1X10,
423405 .output = MEDIA_BUS_FMT_Y10_1X10,
424− .data_type = MIPI_CSI2_DATA_TYPE_RAW10,
406+ .data_type = MIPI_CSI2_DT_RAW10,
425407 .width = 10,
426408 }, {
427409 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
428410 .output = MEDIA_BUS_FMT_SBGGR12_1X12,
429− .data_type = MIPI_CSI2_DATA_TYPE_RAW12,
411+ .data_type = MIPI_CSI2_DT_RAW12,
430412 .width = 12,
431413 }, {
432414 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
433415 .output = MEDIA_BUS_FMT_SGBRG12_1X12,
434− .data_type = MIPI_CSI2_DATA_TYPE_RAW12,
416+ .data_type = MIPI_CSI2_DT_RAW12,
435417 .width = 12,
436418 }, {
437419 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
438420 .output = MEDIA_BUS_FMT_SGRBG12_1X12,
439− .data_type = MIPI_CSI2_DATA_TYPE_RAW12,
421+ .data_type = MIPI_CSI2_DT_RAW12,
440422 .width = 12,
441423 }, {
442424 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
443425 .output = MEDIA_BUS_FMT_SRGGB12_1X12,
444− .data_type = MIPI_CSI2_DATA_TYPE_RAW12,
426+ .data_type = MIPI_CSI2_DT_RAW12,
445427 .width = 12,
446428 }, {
447429 .code = MEDIA_BUS_FMT_Y12_1X12,
448430 .output = MEDIA_BUS_FMT_Y12_1X12,
449− .data_type = MIPI_CSI2_DATA_TYPE_RAW12,
431+ .data_type = MIPI_CSI2_DT_RAW12,
450432 .width = 12,
451433 }, {
452434 .code = MEDIA_BUS_FMT_SBGGR14_1X14,
453435 .output = MEDIA_BUS_FMT_SBGGR14_1X14,
454− .data_type = MIPI_CSI2_DATA_TYPE_RAW14,
436+ .data_type = MIPI_CSI2_DT_RAW14,
455437 .width = 14,
456438 }, {
457439 .code = MEDIA_BUS_FMT_SGBRG14_1X14,
458440 .output = MEDIA_BUS_FMT_SGBRG14_1X14,
459− .data_type = MIPI_CSI2_DATA_TYPE_RAW14,
441+ .data_type = MIPI_CSI2_DT_RAW14,
460442 .width = 14,
461443 }, {
462444 .code = MEDIA_BUS_FMT_SGRBG14_1X14,
463445 .output = MEDIA_BUS_FMT_SGRBG14_1X14,
464− .data_type = MIPI_CSI2_DATA_TYPE_RAW14,
446+ .data_type = MIPI_CSI2_DT_RAW14,
465447 .width = 14,
466448 }, {
467449 .code = MEDIA_BUS_FMT_SRGGB14_1X14,
468450 .output = MEDIA_BUS_FMT_SRGGB14_1X14,
469− .data_type = MIPI_CSI2_DATA_TYPE_RAW14,
451+ .data_type = MIPI_CSI2_DT_RAW14,
470452 .width = 14,
471453 },
472454 /* JPEG */
@@ -494,7 +476,7 @@ static const struct csis_pix_format mipi_csis_formats[] = { · 21 unmodified lines
494476 * SoC that can support quad pixel mode, this will have to be
495477 * revisited.
496478 */
497− .data_type = MIPI_CSI2_DATA_TYPE_RAW8,
479+ .data_type = MIPI_CSI2_DT_RAW8,
498480 .width = 8,
499481 }
500482 };
@@ -583,7 +565,7 @@ static void __mipi_csis_set_format(struct mipi_csis_device *csis, · 82 unmodified lines
583565 *
584566 * TODO: Verify which other formats require DUAL (or QUAD) modes.
585567 */
586− if (csis_fmt->data_type == MIPI_CSI2_DATA_TYPE_YUV422_8)
568+ if (csis_fmt->data_type == MIPI_CSI2_DT_YUV422_8B)
587569 val |= MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL;
588570
589571 val |= MIPI_CSIS_ISPCFG_FMT(csis_fmt->data_type);
drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c+66−69
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 * Copyright 2019-2020 NXP
44 */
55
6+#include <linux/bits.h>
67 #include <linux/clk.h>
78 #include <linux/device.h>
89 #include <linux/errno.h>
@@ -245,26 +246,41 @@ static void mxc_isi_v4l2_cleanup(struct mxc_isi_dev *isi) · 236 unmodified lines
245246
246247 /* Panic will assert when the buffers are 50% full */
247248
248−/* For i.MX8QXP C0 and i.MX8MN ISI IER version */
249+/* For i.MX8MN ISI IER version */
249250 static const struct mxc_isi_ier_reg mxc_imx8_isi_ier_v1 = {
250− .oflw_y_buf_en = { .offset = 19, .mask = 0x80000 },
251− .oflw_u_buf_en = { .offset = 21, .mask = 0x200000 },
252− .oflw_v_buf_en = { .offset = 23, .mask = 0x800000 },
251+ .oflw_y_buf_en = { .mask = BIT(19) },
252+ .oflw_u_buf_en = { .mask = BIT(21) },
253+ .oflw_v_buf_en = { .mask = BIT(23) },
253254
254− .panic_y_buf_en = {.offset = 20, .mask = 0x100000 },
255− .panic_u_buf_en = {.offset = 22, .mask = 0x400000 },
256− .panic_v_buf_en = {.offset = 24, .mask = 0x1000000 },
255+ .panic_y_buf_en = { .mask = BIT(20) },
256+ .panic_u_buf_en = { .mask = BIT(22) },
257+ .panic_v_buf_en = { .mask = BIT(24) },
257258 };
258259
259−/* For i.MX8MP ISI IER version */
260+/* For i.MX8QXP C0 and i.MX8MP ISI IER version */
260261 static const struct mxc_isi_ier_reg mxc_imx8_isi_ier_v2 = {
261− .oflw_y_buf_en = { .offset = 18, .mask = 0x40000 },
262− .oflw_u_buf_en = { .offset = 20, .mask = 0x100000 },
263− .oflw_v_buf_en = { .offset = 22, .mask = 0x400000 },
262+ .oflw_y_buf_en = { .mask = BIT(18) },
263+ .oflw_u_buf_en = { .mask = BIT(20) },
264+ .oflw_v_buf_en = { .mask = BIT(22) },
264265
265− .panic_y_buf_en = {.offset = 19, .mask = 0x80000 },
266− .panic_u_buf_en = {.offset = 21, .mask = 0x200000 },
267− .panic_v_buf_en = {.offset = 23, .mask = 0x800000 },
266+ .panic_y_buf_en = { .mask = BIT(19) },
267+ .panic_u_buf_en = { .mask = BIT(21) },
268+ .panic_v_buf_en = { .mask = BIT(23) },
269+};
270+
271+/* For i.MX8QM ISI IER version */
272+static const struct mxc_isi_ier_reg mxc_imx8_isi_ier_qm = {
273+ .oflw_y_buf_en = { .mask = BIT(16) },
274+ .oflw_u_buf_en = { .mask = BIT(19) },
275+ .oflw_v_buf_en = { .mask = BIT(22) },
276+
277+ .excs_oflw_y_buf_en = { .mask = BIT(17) },
278+ .excs_oflw_u_buf_en = { .mask = BIT(20) },
279+ .excs_oflw_v_buf_en = { .mask = BIT(23) },
280+
281+ .panic_y_buf_en = { .mask = BIT(18) },
282+ .panic_u_buf_en = { .mask = BIT(21) },
283+ .panic_v_buf_en = { .mask = BIT(24) },
268284 };
269285
270286 /* Panic will assert when the buffers are 50% full */
@@ -274,11 +290,6 @@ static const struct mxc_isi_set_thd mxc_imx8_isi_thd_v1 = { · 3 unmodified lines
274290 .panic_set_thd_v = { .mask = 0xf0000, .offset = 16, .threshold = 0x7 },
275291 };
276292
277−static const struct clk_bulk_data mxc_imx8mn_clks[] = {
278− { .id = "axi" },
279− { .id = "apb" },
280−};
281−
282293 static const struct mxc_isi_plat_data mxc_imx8mn_data = {
283294 .model = MXC_ISI_IMX8MN,
284295 .num_ports = 1,
@@ -286,8 +297,6 @@ static const struct mxc_isi_plat_data mxc_imx8mn_data = { · 1 unmodified line
286297 .reg_offset = 0,
287298 .ier_reg = &mxc_imx8_isi_ier_v1,
288299 .set_thd = &mxc_imx8_isi_thd_v1,
289− .clks = mxc_imx8mn_clks,
290− .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
291300 .buf_active_reverse = false,
292301 .gasket_ops = &mxc_imx8_gasket_ops,
293302 .has_36bit_dma = false,
@@ -300,8 +309,6 @@ static const struct mxc_isi_plat_data mxc_imx8mp_data = { · 6 unmodified lines
300309 .reg_offset = 0x2000,
301310 .ier_reg = &mxc_imx8_isi_ier_v2,
302311 .set_thd = &mxc_imx8_isi_thd_v1,
303− .clks = mxc_imx8mn_clks,
304− .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
305312 .buf_active_reverse = true,
306313 .gasket_ops = &mxc_imx8_gasket_ops,
307314 .has_36bit_dma = true,
@@ -314,8 +321,6 @@ static const struct mxc_isi_plat_data mxc_imx8ulp_data = { · 6 unmodified lines
314321 .reg_offset = 0x0,
315322 .ier_reg = &mxc_imx8_isi_ier_v2,
316323 .set_thd = &mxc_imx8_isi_thd_v1,
317− .clks = mxc_imx8mn_clks,
318− .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
319324 .buf_active_reverse = true,
320325 .has_36bit_dma = false,
321326 };
@@ -327,13 +332,33 @@ static const struct mxc_isi_plat_data mxc_imx93_data = { · 5 unmodified lines
327332 .reg_offset = 0,
328333 .ier_reg = &mxc_imx8_isi_ier_v2,
329334 .set_thd = &mxc_imx8_isi_thd_v1,
330− .clks = mxc_imx8mn_clks,
331− .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
332335 .buf_active_reverse = true,
333336 .gasket_ops = &mxc_imx93_gasket_ops,
334337 .has_36bit_dma = false,
335338 };
336339
340+static const struct mxc_isi_plat_data mxc_imx8qm_data = {
341+ .model = MXC_ISI_IMX8QM,
342+ .num_ports = 5,
343+ .num_channels = 8,
344+ .reg_offset = 0x10000,
345+ .ier_reg = &mxc_imx8_isi_ier_qm,
346+ .set_thd = &mxc_imx8_isi_thd_v1,
347+ .buf_active_reverse = true,
348+ .has_36bit_dma = false,
349+};
350+
351+static const struct mxc_isi_plat_data mxc_imx8qxp_data = {
352+ .model = MXC_ISI_IMX8QXP,
353+ .num_ports = 5,
354+ .num_channels = 6,
355+ .reg_offset = 0x10000,
356+ .ier_reg = &mxc_imx8_isi_ier_v2,
357+ .set_thd = &mxc_imx8_isi_thd_v1,
358+ .buf_active_reverse = true,
359+ .has_36bit_dma = false,
360+};
361+
337362 /* -----------------------------------------------------------------------------
338363 * Power management
339364 */
@@ -385,7 +410,7 @@ static int mxc_isi_runtime_suspend(struct device *dev) · 45 unmodified lines
385410 {
386411 struct mxc_isi_dev *isi = dev_get_drvdata(dev);
387412
388− clk_bulk_disable_unprepare(isi->pdata->num_clks, isi->clks);
413+ clk_bulk_disable_unprepare(isi->num_clks, isi->clks);
389414
390415 return 0;
391416 }
@@ -395,7 +420,7 @@ static int mxc_isi_runtime_resume(struct device *dev) · 3 unmodified lines
395420 struct mxc_isi_dev *isi = dev_get_drvdata(dev);
396421 int ret;
397422
398− ret = clk_bulk_prepare_enable(isi->pdata->num_clks, isi->clks);
423+ ret = clk_bulk_prepare_enable(isi->num_clks, isi->clks);
399424 if (ret) {
400425 dev_err(dev, "Failed to enable clocks (%d)\n", ret);
401426 return ret;
@@ -413,27 +438,6 @@ static const struct dev_pm_ops mxc_isi_pm_ops = { · 11 unmodified lines
413438 * Probe, remove & driver
414439 */
415440
416−static int mxc_isi_clk_get(struct mxc_isi_dev *isi)
417−{
418− unsigned int size = isi->pdata->num_clks
419− * sizeof(*isi->clks);
420− int ret;
421−
422− isi->clks = devm_kmemdup(isi->dev, isi->pdata->clks, size, GFP_KERNEL);
423− if (!isi->clks)
424− return -ENOMEM;
425−
426− ret = devm_clk_bulk_get(isi->dev, isi->pdata->num_clks,
427− isi->clks);
428− if (ret < 0) {
429− dev_err(isi->dev, "Failed to acquire clocks: %d\n",
430− ret);
431− return ret;
432− }
433−
434− return 0;
435−}
436−
437441 static int mxc_isi_probe(struct platform_device *pdev)
438442 {
439443 struct device *dev = &pdev->dev;
@@ -456,34 +460,25 @@ static int mxc_isi_probe(struct platform_device *pdev) · 16 unmodified lines
456460 if (!isi->pipes)
457461 return -ENOMEM;
458462
459− ret = mxc_isi_clk_get(isi);
460− if (ret < 0) {
461− dev_err(dev, "Failed to get clocks\n");
462− return ret;
463− }
463+ isi->num_clks = devm_clk_bulk_get_all(dev, &isi->clks);
464+ if (isi->num_clks < 0)
465+ return dev_err_probe(dev, isi->num_clks, "Failed to get clocks\n");
464466
465467 isi->regs = devm_platform_ioremap_resource(pdev, 0);
466− if (IS_ERR(isi->regs)) {
467− dev_err(dev, "Failed to get ISI register map\n");
468− return PTR_ERR(isi->regs);
469− }
468+ if (IS_ERR(isi->regs))
469+ return dev_err_probe(dev, PTR_ERR(isi->regs),
470+ "Failed to get ISI register map\n");
470471
471472 if (isi->pdata->gasket_ops) {
472473 isi->gasket = syscon_regmap_lookup_by_phandle(dev->of_node,
473474 "fsl,blk-ctrl");
474− if (IS_ERR(isi->gasket)) {
475− ret = PTR_ERR(isi->gasket);
476− dev_err(dev, "failed to get gasket: %d\n", ret);
477− return ret;
478− }
475+ if (IS_ERR(isi->gasket))
476+ return dev_err_probe(dev, PTR_ERR(isi->gasket),
477+ "failed to get gasket\n");
479478 }
480479
481480 dma_size = isi->pdata->has_36bit_dma ? 36 : 32;
482− ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_size));
483− if (ret) {
484− dev_err(dev, "failed to set DMA mask\n");
485− return ret;
486− }
481+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_size));
487482
488483 pm_runtime_enable(dev);
489484
@@ -541,6 +536,8 @@ static void mxc_isi_remove(struct platform_device *pdev) · 51 unmodified lines
541536 static const struct of_device_id mxc_isi_of_match[] = {
542537 { .compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data },
543538 { .compatible = "fsl,imx8mp-isi", .data = &mxc_imx8mp_data },
539+ { .compatible = "fsl,imx8qm-isi", .data = &mxc_imx8qm_data },
540+ { .compatible = "fsl,imx8qxp-isi", .data = &mxc_imx8qxp_data },
544541 { .compatible = "fsl,imx8ulp-isi", .data = &mxc_imx8ulp_data },
545542 { .compatible = "fsl,imx93-isi", .data = &mxc_imx93_data },
546543 { /* sentinel */ },
drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h+3−3
@@ -114,7 +114,6 @@ struct mxc_isi_buffer { · 113 unmodified lines
114114 };
115115
116116 struct mxc_isi_reg {
117− u32 offset;
118117 u32 mask;
119118 };
120119
@@ -158,6 +157,8 @@ struct mxc_gasket_ops { · 37 unmodified lines
158157 enum model {
159158 MXC_ISI_IMX8MN,
160159 MXC_ISI_IMX8MP,
160+ MXC_ISI_IMX8QM,
161+ MXC_ISI_IMX8QXP,
161162 MXC_ISI_IMX8ULP,
162163 MXC_ISI_IMX93,
163164 };
@@ -170,8 +171,6 @@ struct mxc_isi_plat_data { · 6 unmodified lines
170171 const struct mxc_isi_ier_reg *ier_reg;
171172 const struct mxc_isi_set_thd *set_thd;
172173 const struct mxc_gasket_ops *gasket_ops;
173− const struct clk_bulk_data *clks;
174− unsigned int num_clks;
175174 bool buf_active_reverse;
176175 bool has_36bit_dma;
177176 };
@@ -283,6 +282,7 @@ struct mxc_isi_dev { · 105 unmodified lines
283282
284283 void __iomem *regs;
285284 struct clk_bulk_data *clks;
285+ int num_clks;
286286 struct regmap *gasket;
287287
288288 struct mxc_isi_crossbar crossbar;
drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c+8−10
@@ -188,11 +188,12 @@ static int mxc_isi_crossbar_init_state(struct v4l2_subdev *sd, · 187 unmodified lines
188188 * Create a 1:1 mapping between pixel link inputs and outputs to
189189 * pipelines by default.
190190 */
191− routes = kcalloc(xbar->num_sources, sizeof(*routes), GFP_KERNEL);
191+ routing.num_routes = min(xbar->num_sinks - 1, xbar->num_sources);
192+ routes = kcalloc(routing.num_routes, sizeof(*routes), GFP_KERNEL);
192193 if (!routes)
193194 return -ENOMEM;
194195
195− for (i = 0; i < xbar->num_sources; ++i) {
196+ for (i = 0; i < routing.num_routes; ++i) {
196197 struct v4l2_subdev_route *route = &routes[i];
197198
198199 route->sink_pad = i;
@@ -200,7 +201,6 @@ static int mxc_isi_crossbar_init_state(struct v4l2_subdev *sd, · 1 unmodified line
200201 route->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
201202 }
202203
203− routing.num_routes = xbar->num_sources;
204204 routing.routes = routes;
205205
206206 ret = __mxc_isi_crossbar_set_routing(sd, state, &routing);
@@ -352,9 +352,8 @@ static int mxc_isi_crossbar_enable_streams(struct v4l2_subdev *sd, · 145 unmodified lines
352352 sink_streams);
353353 if (ret) {
354354 dev_err(xbar->isi->dev,
355− "failed to %s streams 0x%llx on '%s':%u: %d\n",
356− "enable", sink_streams, remote_sd->name,
357− remote_pad, ret);
355+ "failed to enable streams 0x%llx on '%s':%u: %d\n",
356+ sink_streams, remote_sd->name, remote_pad, ret);
358357 mxc_isi_crossbar_gasket_disable(xbar, sink_pad);
359358 return ret;
360359 }
@@ -392,9 +391,8 @@ static int mxc_isi_crossbar_disable_streams(struct v4l2_subdev *sd, · 31 unmodified lines
392391 sink_streams);
393392 if (ret)
394393 dev_err(xbar->isi->dev,
395− "failed to %s streams 0x%llx on '%s':%u: %d\n",
396− "disable", sink_streams, remote_sd->name,
397− remote_pad, ret);
394+ "failed to disable streams 0x%llx on '%s':%u: %d\n",
395+ sink_streams, remote_sd->name, remote_pad, ret);
398396
399397 mxc_isi_crossbar_gasket_disable(xbar, sink_pad);
400398 }
@@ -453,7 +451,7 @@ int mxc_isi_crossbar_init(struct mxc_isi_dev *isi) · 52 unmodified lines
453451 * the memory input.
454452 */
455453 xbar->num_sinks = isi->pdata->num_ports + 1;
456− xbar->num_sources = isi->pdata->num_ports;
454+ xbar->num_sources = isi->pdata->num_channels;
457455 num_pads = xbar->num_sinks + xbar->num_sources;
458456
459457 xbar->pads = kcalloc(num_pads, sizeof(*xbar->pads), GFP_KERNEL);
drivers/media/platform/nxp/imx8mq-mipi-csi2.c+155−14
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 * Copyright (C) 2021 Purism SPC
66 */
77
8+#include <linux/bitfield.h>
89 #include <linux/clk.h>
910 #include <linux/clk-provider.h>
1011 #include <linux/delay.h>
@@ -62,6 +63,8 @@ · 51 unmodified lines
6263 #define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x188
6364 #define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x130
6465
66+struct csi_state;
67+
6568 enum {
6669 ST_POWERED = 1,
6770 ST_STREAMING = 2,
@@ -83,11 +86,11 @@ static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = { · 15 unmodified lines
8386
8487 #define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
8588
86−#define GPR_CSI2_1_RX_ENABLE BIT(13)
87−#define GPR_CSI2_1_VID_INTFC_ENB BIT(12)
88−#define GPR_CSI2_1_HSEL BIT(10)
89−#define GPR_CSI2_1_CONT_CLK_MODE BIT(8)
90−#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)
89+struct imx8mq_plat_data {
90+ int (*enable)(struct csi_state *state, u32 hs_settle);
91+ void (*disable)(struct csi_state *state);
92+ bool use_reg_csr;
93+};
9194
9295 /*
9396 * The send level configures the number of entries that must accumulate in
@@ -106,6 +109,7 @@ static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = { · 12 unmodified lines
106109
107110 struct csi_state {
108111 struct device *dev;
112+ const struct imx8mq_plat_data *pdata;
109113 void __iomem *regs;
110114 struct clk_bulk_data clks[CSI2_NUM_CLKS];
111115 struct reset_control *rst;
@@ -137,6 +141,123 @@ struct csi2_pix_format { · 25 unmodified lines
137141 u8 width;
138142 };
139143
144+/* -----------------------------------------------------------------------------
145+ * i.MX8MQ GPR
146+ */
147+
148+#define GPR_CSI2_1_RX_ENABLE BIT(13)
149+#define GPR_CSI2_1_VID_INTFC_ENB BIT(12)
150+#define GPR_CSI2_1_HSEL BIT(10)
151+#define GPR_CSI2_1_CONT_CLK_MODE BIT(8)
152+#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)
153+
154+static int imx8mq_gpr_enable(struct csi_state *state, u32 hs_settle)
155+{
156+ regmap_update_bits(state->phy_gpr,
157+ state->phy_gpr_reg,
158+ 0x3fff,
159+ GPR_CSI2_1_RX_ENABLE |
160+ GPR_CSI2_1_VID_INTFC_ENB |
161+ GPR_CSI2_1_HSEL |
162+ GPR_CSI2_1_CONT_CLK_MODE |
163+ GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle));
164+
165+ return 0;
166+}
167+
168+static const struct imx8mq_plat_data imx8mq_data = {
169+ .enable = imx8mq_gpr_enable,
170+};
171+
172+/* -----------------------------------------------------------------------------
173+ * i.MX8QXP
174+ */
175+
176+#define CSI2SS_PL_CLK_INTERVAL_US 100
177+#define CSI2SS_PL_CLK_TIMEOUT_US 100000
178+
179+#define CSI2SS_PLM_CTRL 0x0
180+#define CSI2SS_PLM_CTRL_ENABLE_PL BIT(0)
181+#define CSI2SS_PLM_CTRL_VSYNC_OVERRIDE BIT(9)
182+#define CSI2SS_PLM_CTRL_HSYNC_OVERRIDE BIT(10)
183+#define CSI2SS_PLM_CTRL_VALID_OVERRIDE BIT(11)
184+#define CSI2SS_PLM_CTRL_POLARITY_HIGH BIT(12)
185+#define CSI2SS_PLM_CTRL_PL_CLK_RUN BIT(31)
186+
187+#define CSI2SS_PHY_CTRL 0x4
188+#define CSI2SS_PHY_CTRL_RX_ENABLE BIT(0)
189+#define CSI2SS_PHY_CTRL_AUTO_PD_EN BIT(1)
190+#define CSI2SS_PHY_CTRL_DDRCLK_EN BIT(2)
191+#define CSI2SS_PHY_CTRL_CONT_CLK_MODE BIT(3)
192+#define CSI2SS_PHY_CTRL_RX_HS_SETTLE_MASK GENMASK(9, 4)
193+#define CSI2SS_PHY_CTRL_RTERM_SEL BIT(21)
194+#define CSI2SS_PHY_CTRL_PD BIT(22)
195+
196+#define CSI2SS_DATA_TYPE_DISABLE_BF 0x38
197+#define CSI2SS_DATA_TYPE_DISABLE_BF_MASK GENMASK(23, 0)
198+
199+#define CSI2SS_CTRL_CLK_RESET 0x44
200+#define CSI2SS_CTRL_CLK_RESET_EN BIT(0)
201+
202+static int imx8qxp_gpr_enable(struct csi_state *state, u32 hs_settle)
203+{
204+ int ret;
205+ u32 val;
206+
207+ /* Clear format */
208+ regmap_clear_bits(state->phy_gpr, CSI2SS_DATA_TYPE_DISABLE_BF,
209+ CSI2SS_DATA_TYPE_DISABLE_BF_MASK);
210+
211+ regmap_write(state->phy_gpr, CSI2SS_PLM_CTRL, 0x0);
212+
213+ regmap_write(state->phy_gpr, CSI2SS_PHY_CTRL,
214+ FIELD_PREP(CSI2SS_PHY_CTRL_RX_HS_SETTLE_MASK, hs_settle) |
215+ CSI2SS_PHY_CTRL_RX_ENABLE | CSI2SS_PHY_CTRL_DDRCLK_EN |
216+ CSI2SS_PHY_CTRL_CONT_CLK_MODE | CSI2SS_PHY_CTRL_PD |
217+ CSI2SS_PHY_CTRL_RTERM_SEL | CSI2SS_PHY_CTRL_AUTO_PD_EN);
218+
219+ ret = regmap_read_poll_timeout(state->phy_gpr, CSI2SS_PLM_CTRL,
220+ val, !(val & CSI2SS_PLM_CTRL_PL_CLK_RUN),
221+ CSI2SS_PL_CLK_INTERVAL_US,
222+ CSI2SS_PL_CLK_TIMEOUT_US);
223+
224+ if (ret) {
225+ dev_err(state->dev, "Timeout waiting for Pixel-Link clock\n");
226+ return ret;
227+ }
228+
229+ /* Enable Pixel link Master */
230+ regmap_set_bits(state->phy_gpr, CSI2SS_PLM_CTRL,
231+ CSI2SS_PLM_CTRL_ENABLE_PL | CSI2SS_PLM_CTRL_VALID_OVERRIDE);
232+
233+ /* PHY Enable */
234+ regmap_clear_bits(state->phy_gpr, CSI2SS_PHY_CTRL,
235+ CSI2SS_PHY_CTRL_PD | CSI2SS_PLM_CTRL_POLARITY_HIGH);
236+
237+ /* Release Reset */
238+ regmap_set_bits(state->phy_gpr, CSI2SS_CTRL_CLK_RESET, CSI2SS_CTRL_CLK_RESET_EN);
239+
240+ return ret;
241+}
242+
243+static void imx8qxp_gpr_disable(struct csi_state *state)
244+{
245+ /* Disable Pixel Link */
246+ regmap_write(state->phy_gpr, CSI2SS_PLM_CTRL, 0x0);
247+
248+ /* Disable PHY */
249+ regmap_write(state->phy_gpr, CSI2SS_PHY_CTRL, 0x0);
250+
251+ regmap_clear_bits(state->phy_gpr, CSI2SS_CTRL_CLK_RESET,
252+ CSI2SS_CTRL_CLK_RESET_EN);
253+};
254+
255+static const struct imx8mq_plat_data imx8qxp_data = {
256+ .enable = imx8qxp_gpr_enable,
257+ .disable = imx8qxp_gpr_disable,
258+ .use_reg_csr = true,
259+};
260+
140261 static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {
141262 /* RAW (Bayer and greyscale) formats. */
142263 {
@@ -371,14 +492,9 @@ static int imx8mq_mipi_csi_start_stream(struct csi_state *state, · 228 unmodified lines
371492 if (ret)
372493 return ret;
373494
374− regmap_update_bits(state->phy_gpr,
375− state->phy_gpr_reg,
376− 0x3fff,
377− GPR_CSI2_1_RX_ENABLE |
378− GPR_CSI2_1_VID_INTFC_ENB |
379− GPR_CSI2_1_HSEL |
380− GPR_CSI2_1_CONT_CLK_MODE |
381− GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle));
495+ ret = state->pdata->enable(state, hs_settle);
496+ if (ret)
497+ return ret;
382498
383499 return 0;
384500 }
@@ -386,6 +502,9 @@ static int imx8mq_mipi_csi_start_stream(struct csi_state *state, · 1 unmodified line
386502 static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)
387503 {
388504 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);
505+
506+ if (state->pdata->disable)
507+ state->pdata->disable(state);
389508 }
390509
391510 /* -----------------------------------------------------------------------------
@@ -837,6 +956,25 @@ static int imx8mq_mipi_csi_parse_dt(struct csi_state *state) · 445 unmodified lines
837956 return PTR_ERR(state->rst);
838957 }
839958
959+ if (state->pdata->use_reg_csr) {
960+ const struct regmap_config regmap_config = {
961+ .reg_bits = 32,
962+ .val_bits = 32,
963+ .reg_stride = 4,
964+ };
965+ void __iomem *base;
966+
967+ base = devm_platform_ioremap_resource(to_platform_device(dev), 1);
968+ if (IS_ERR(base))
969+ return dev_err_probe(dev, PTR_ERR(base), "Missing CSR register\n");
970+
971+ state->phy_gpr = devm_regmap_init_mmio(dev, base, &regmap_config);
972+ if (IS_ERR(state->phy_gpr))
973+ return dev_err_probe(dev, PTR_ERR(state->phy_gpr),
974+ "Failed to init CSI MMIO regmap\n");
975+ return 0;
976+ }
977+
840978 ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,
841979 ARRAY_SIZE(out_val));
842980 if (ret) {
@@ -876,6 +1014,8 @@ static int imx8mq_mipi_csi_probe(struct platform_device *pdev) · 33 unmodified lines
8761014
8771015 state->dev = dev;
8781016
1017+ state->pdata = of_device_get_match_data(dev);
1018+
8791019 ret = imx8mq_mipi_csi_parse_dt(state);
8801020 if (ret < 0) {
8811021 dev_err(dev, "Failed to parse device tree: %d\n", ret);
@@ -953,7 +1093,8 @@ static void imx8mq_mipi_csi_remove(struct platform_device *pdev) · 71 unmodified lines
9531093 }
9541094
9551095 static const struct of_device_id imx8mq_mipi_csi_of_match[] = {
956− { .compatible = "fsl,imx8mq-mipi-csi2", },
1096+ { .compatible = "fsl,imx8mq-mipi-csi2", .data = &imx8mq_data },
1097+ { .compatible = "fsl,imx8qxp-mipi-csi2", .data = &imx8qxp_data },
9571098 { /* sentinel */ },
9581099 };
9591100 MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match);
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c+1−2
@@ -849,8 +849,7 @@ static int csiphy_init(struct csiphy_device *csiphy) · 848 unmodified lines
849849 regs->offset = 0x1000;
850850 break;
851851 default:
852− WARN(1, "unknown csiphy version\n");
853− return -ENODEV;
852+ break;
854853 }
855854
856855 return 0;
drivers/media/platform/qcom/camss/camss-csiphy.c+0−5
@@ -103,11 +103,6 @@ const struct csiphy_formats csiphy_formats_8x96 = { · 102 unmodified lines
103103 .formats = formats_8x96
104104 };
105105
106−const struct csiphy_formats csiphy_formats_sc7280 = {
107− .nformats = ARRAY_SIZE(formats_sdm845),
108− .formats = formats_sdm845
109−};
110−
111106 const struct csiphy_formats csiphy_formats_sdm845 = {
112107 .nformats = ARRAY_SIZE(formats_sdm845),
113108 .formats = formats_sdm845
drivers/media/platform/qcom/camss/camss-csiphy.h+0−1
@@ -126,7 +126,6 @@ void msm_csiphy_unregister_entity(struct csiphy_device *csiphy); · 125 unmodified lines
126126
127127 extern const struct csiphy_formats csiphy_formats_8x16;
128128 extern const struct csiphy_formats csiphy_formats_8x96;
129−extern const struct csiphy_formats csiphy_formats_sc7280;
130129 extern const struct csiphy_formats csiphy_formats_sdm845;
131130
132131 extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
drivers/media/platform/qcom/camss/camss-video.c+25−14
@@ -225,6 +225,21 @@ static int video_check_format(struct camss_video *video) · 224 unmodified lines
225225 return 0;
226226 }
227227
228+static int video_prepare_streaming(struct vb2_queue *q)
229+{
230+ struct camss_video *video = vb2_get_drv_priv(q);
231+ struct video_device *vdev = &video->vdev;
232+ int ret;
233+
234+ ret = v4l2_pipeline_pm_get(&vdev->entity);
235+ if (ret < 0) {
236+ dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
237+ ret);
238+ }
239+
240+ return ret;
241+}
242+
228243 static int video_start_streaming(struct vb2_queue *q, unsigned int count)
229244 {
230245 struct camss_video *video = vb2_get_drv_priv(q);
@@ -308,13 +323,23 @@ static void video_stop_streaming(struct vb2_queue *q) · 77 unmodified lines
308323 video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
309324 }
310325
326+static void video_unprepare_streaming(struct vb2_queue *q)
327+{
328+ struct camss_video *video = vb2_get_drv_priv(q);
329+ struct video_device *vdev = &video->vdev;
330+
331+ v4l2_pipeline_pm_put(&vdev->entity);
332+}
333+
311334 static const struct vb2_ops msm_video_vb2_q_ops = {
312335 .queue_setup = video_queue_setup,
313336 .buf_init = video_buf_init,
314337 .buf_prepare = video_buf_prepare,
315338 .buf_queue = video_buf_queue,
339+ .prepare_streaming = video_prepare_streaming,
316340 .start_streaming = video_start_streaming,
317341 .stop_streaming = video_stop_streaming,
342+ .unprepare_streaming = video_unprepare_streaming,
318343 };
319344
320345 /* -----------------------------------------------------------------------------
@@ -599,20 +624,10 @@ static int video_open(struct file *file) · 278 unmodified lines
599624
600625 file->private_data = vfh;
601626
602− ret = v4l2_pipeline_pm_get(&vdev->entity);
603− if (ret < 0) {
604− dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
605− ret);
606− goto error_pm_use;
607− }
608−
609627 mutex_unlock(&video->lock);
610628
611629 return 0;
612630
613−error_pm_use:
614− v4l2_fh_release(file);
615−
616631 error_alloc:
617632 mutex_unlock(&video->lock);
618633
@@ -621,12 +636,8 @@ error_alloc: · 2 unmodified lines
621636
622637 static int video_release(struct file *file)
623638 {
624− struct video_device *vdev = video_devdata(file);
625−
626639 vb2_fop_release(file);
627640
628− v4l2_pipeline_pm_put(&vdev->entity);
629−
630641 file->private_data = NULL;
631642
632643 return 0;
drivers/media/platform/qcom/camss/camss.c+53−54
@@ -1481,7 +1481,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 1480 unmodified lines
14811481 .csiphy = {
14821482 .id = 0,
14831483 .hw_ops = &csiphy_ops_3ph_1_0,
1484− .formats = &csiphy_formats_sc7280
1484+ .formats = &csiphy_formats_sdm845,
14851485 }
14861486 },
14871487 /* CSIPHY1 */
@@ -1496,7 +1496,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
14961496 .csiphy = {
14971497 .id = 1,
14981498 .hw_ops = &csiphy_ops_3ph_1_0,
1499− .formats = &csiphy_formats_sc7280
1499+ .formats = &csiphy_formats_sdm845,
15001500 }
15011501 },
15021502 /* CSIPHY2 */
@@ -1511,7 +1511,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
15111511 .csiphy = {
15121512 .id = 2,
15131513 .hw_ops = &csiphy_ops_3ph_1_0,
1514− .formats = &csiphy_formats_sc7280
1514+ .formats = &csiphy_formats_sdm845,
15151515 }
15161516 },
15171517 /* CSIPHY3 */
@@ -1526,7 +1526,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
15261526 .csiphy = {
15271527 .id = 3,
15281528 .hw_ops = &csiphy_ops_3ph_1_0,
1529− .formats = &csiphy_formats_sc7280
1529+ .formats = &csiphy_formats_sdm845,
15301530 }
15311531 },
15321532 /* CSIPHY4 */
@@ -1541,7 +1541,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
15411541 .csiphy = {
15421542 .id = 4,
15431543 .hw_ops = &csiphy_ops_3ph_1_0,
1544− .formats = &csiphy_formats_sc7280
1544+ .formats = &csiphy_formats_sdm845,
15451545 }
15461546 },
15471547 };
@@ -2486,8 +2486,8 @@ static const struct resources_icc icc_res_sm8550[] = { · 938 unmodified lines
24862486 static const struct camss_subdev_resources csiphy_res_x1e80100[] = {
24872487 /* CSIPHY0 */
24882488 {
2489− .regulators = { "vdd-csiphy-0p8-supply",
2490− "vdd-csiphy-1p2-supply" },
2489+ .regulators = { "vdd-csiphy-0p8",
2490+ "vdd-csiphy-1p2" },
24912491 .clock = { "csiphy0", "csiphy0_timer" },
24922492 .clock_rate = { { 300000000, 400000000, 480000000 },
24932493 { 266666667, 400000000 } },
@@ -2501,8 +2501,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { · 7 unmodified lines
25012501 },
25022502 /* CSIPHY1 */
25032503 {
2504− .regulators = { "vdd-csiphy-0p8-supply",
2505− "vdd-csiphy-1p2-supply" },
2504+ .regulators = { "vdd-csiphy-0p8",
2505+ "vdd-csiphy-1p2" },
25062506 .clock = { "csiphy1", "csiphy1_timer" },
25072507 .clock_rate = { { 300000000, 400000000, 480000000 },
25082508 { 266666667, 400000000 } },
@@ -2516,8 +2516,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { · 7 unmodified lines
25162516 },
25172517 /* CSIPHY2 */
25182518 {
2519− .regulators = { "vdd-csiphy-0p8-supply",
2520− "vdd-csiphy-1p2-supply" },
2519+ .regulators = { "vdd-csiphy-0p8",
2520+ "vdd-csiphy-1p2" },
25212521 .clock = { "csiphy2", "csiphy2_timer" },
25222522 .clock_rate = { { 300000000, 400000000, 480000000 },
25232523 { 266666667, 400000000 } },
@@ -2531,8 +2531,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { · 7 unmodified lines
25312531 },
25322532 /* CSIPHY4 */
25332533 {
2534− .regulators = { "vdd-csiphy-0p8-supply",
2535− "vdd-csiphy-1p2-supply" },
2534+ .regulators = { "vdd-csiphy-0p8",
2535+ "vdd-csiphy-1p2" },
25362536 .clock = { "csiphy4", "csiphy4_timer" },
25372537 .clock_rate = { { 300000000, 400000000, 480000000 },
25382538 { 266666667, 400000000 } },
@@ -3386,43 +3386,39 @@ static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) · 847 unmodified lines
33863386 struct camss *camss = container_of(async, struct camss, notifier);
33873387 struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
33883388 struct v4l2_subdev *sd;
3389− int ret;
33903389
33913390 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
3392− if (sd->host_priv) {
3393− struct media_entity *sensor = &sd->entity;
3394− struct csiphy_device *csiphy =
3395− (struct csiphy_device *) sd->host_priv;
3396− struct media_entity *input = &csiphy->subdev.entity;
3397− unsigned int i;
3398−
3399− for (i = 0; i < sensor->num_pads; i++) {
3400− if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
3401− break;
3402− }
3403− if (i == sensor->num_pads) {
3404− dev_err(camss->dev,
3405− "No source pad in external entity\n");
3406− return -EINVAL;
3407− }
3391+ struct csiphy_device *csiphy = sd->host_priv;
3392+ struct media_entity *input, *sensor;
3393+ unsigned int i;
3394+ int ret;
34083395
3409− ret = media_create_pad_link(sensor, i,
3410− input, MSM_CSIPHY_PAD_SINK,
3411− MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
3412− if (ret < 0) {
3413− camss_link_err(camss, sensor->name,
3414− input->name,
3415− ret);
3416− return ret;
3417− }
3396+ if (!csiphy)
3397+ continue;
3398+
3399+ input = &csiphy->subdev.entity;
3400+ sensor = &sd->entity;
3401+
3402+ for (i = 0; i < sensor->num_pads; i++) {
3403+ if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
3404+ break;
3405+ }
3406+ if (i == sensor->num_pads) {
3407+ dev_err(camss->dev,
3408+ "No source pad in external entity\n");
3409+ return -EINVAL;
34183410 }
3419− }
34203411
3421− ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
3422− if (ret < 0)
3423− return ret;
3412+ ret = media_create_pad_link(sensor, i, input,
3413+ MSM_CSIPHY_PAD_SINK,
3414+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
3415+ if (ret < 0) {
3416+ camss_link_err(camss, sensor->name, input->name, ret);
3417+ return ret;
3418+ }
3419+ }
34243420
3425− return media_device_register(&camss->media_dev);
3421+ return v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
34263422 }
34273423
34283424 static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {
@@ -3625,7 +3621,7 @@ static int camss_probe(struct platform_device *pdev) · 196 unmodified lines
36253621 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
36263622 if (ret < 0) {
36273623 dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
3628− goto err_genpd_cleanup;
3624+ goto err_media_device_cleanup;
36293625 }
36303626
36313627 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
@@ -3646,6 +3642,12 @@ static int camss_probe(struct platform_device *pdev) · 14 unmodified lines
36463642 if (ret < 0)
36473643 goto err_register_subdevs;
36483644
3645+ ret = media_device_register(&camss->media_dev);
3646+ if (ret < 0) {
3647+ dev_err(dev, "Failed to register media device: %d\n", ret);
3648+ goto err_register_subdevs;
3649+ }
3650+
36493651 if (num_subdevs) {
36503652 camss->notifier.ops = &camss_subdev_notifier_ops;
36513653
@@ -3654,32 +3656,29 @@ static int camss_probe(struct platform_device *pdev) · 2 unmodified lines
36543656 dev_err(dev,
36553657 "Failed to register async subdev nodes: %d\n",
36563658 ret);
3657− goto err_register_subdevs;
3659+ goto err_media_device_unregister;
36583660 }
36593661 } else {
36603662 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
36613663 if (ret < 0) {
36623664 dev_err(dev, "Failed to register subdev nodes: %d\n",
36633665 ret);
3664− goto err_register_subdevs;
3665− }
3666−
3667− ret = media_device_register(&camss->media_dev);
3668− if (ret < 0) {
3669− dev_err(dev, "Failed to register media device: %d\n",
3670− ret);
3671− goto err_register_subdevs;
3666+ goto err_media_device_unregister;
36723667 }
36733668 }
36743669
36753670 return 0;
36763671
3672+err_media_device_unregister:
3673+ media_device_unregister(&camss->media_dev);
36773674 err_register_subdevs:
36783675 camss_unregister_entities(camss);
36793676 err_v4l2_device_unregister:
36803677 v4l2_device_unregister(&camss->v4l2_dev);
36813678 v4l2_async_nf_cleanup(&camss->notifier);
36823679 pm_runtime_disable(dev);
3680+err_media_device_cleanup:
3681+ media_device_cleanup(&camss->media_dev);
36833682 err_genpd_cleanup:
36843683 camss_genpd_cleanup(camss);
36853684
drivers/media/platform/qcom/iris/iris_buffer.c+31−4
@@ -205,6 +205,9 @@ static u32 iris_bitstream_buffer_size(struct iris_inst *inst) · 204 unmodified lines
205205 if (num_mbs > NUM_MBS_4K) {
206206 div_factor = 4;
207207 base_res_mbs = caps->max_mbpf;
208+ } else {
209+ if (inst->codec == V4L2_PIX_FMT_VP9)
210+ div_factor = 1;
208211 }
209212
210213 /*
@@ -376,7 +379,7 @@ int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf · 165 unmodified lines
376379 return 0;
377380 }
378381
379−int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane)
382+static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool force)
380383 {
381384 const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
382385 struct iris_buffer *buf, *next;
@@ -396,6 +399,14 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) · 13 unmodified lines
396399 for (i = 0; i < len; i++) {
397400 buffers = &inst->buffers[internal_buf_type[i]];
398401 list_for_each_entry_safe(buf, next, &buffers->list, list) {
402+ /*
403+ * during stream on, skip destroying internal(DPB) buffer
404+ * if firmware did not return it.
405+ * during close, destroy all buffers irrespectively.
406+ */
407+ if (!force && buf->attr & BUF_ATTR_QUEUED)
408+ continue;
409+
399410 ret = iris_destroy_internal_buffer(inst, buf);
400411 if (ret)
401412 return ret;
@@ -405,6 +416,16 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) · 3 unmodified lines
405416 return 0;
406417 }
407418
419+int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane)
420+{
421+ return iris_destroy_internal_buffers(inst, plane, true);
422+}
423+
424+int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane)
425+{
426+ return iris_destroy_internal_buffers(inst, plane, false);
427+}
428+
408429 static int iris_release_internal_buffers(struct iris_inst *inst,
409430 enum iris_buffer_type buffer_type)
410431 {
@@ -593,10 +614,13 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) · 182 unmodified lines
593614
594615 vb2 = &vbuf->vb2_buf;
595616
596− if (buf->flags & V4L2_BUF_FLAG_ERROR)
617+ if (buf->flags & V4L2_BUF_FLAG_ERROR) {
597618 state = VB2_BUF_STATE_ERROR;
598− else
599− state = VB2_BUF_STATE_DONE;
619+ vb2_set_plane_payload(vb2, 0, 0);
620+ vb2->timestamp = 0;
621+ v4l2_m2m_buf_done(vbuf, state);
622+ return 0;
623+ }
600624
601625 vbuf->flags |= buf->flags;
602626
@@ -615,7 +639,10 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) · 12 unmodified lines
615639 v4l2_event_queue_fh(&inst->fh, &ev);
616640 v4l2_m2m_mark_stopped(m2m_ctx);
617641 }
642+ inst->last_buffer_dequeued = true;
618643 }
644+
645+ state = VB2_BUF_STATE_DONE;
619646 vb2->timestamp = buf->timestamp;
620647 v4l2_m2m_buf_done(vbuf, state);
621648
drivers/media/platform/qcom/iris/iris_buffer.h+2−1
@@ -106,7 +106,8 @@ void iris_get_internal_buffers(struct iris_inst *inst, u32 plane); · 105 unmodified lines
106106 int iris_create_internal_buffers(struct iris_inst *inst, u32 plane);
107107 int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane);
108108 int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer);
109−int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane);
109+int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane);
110+int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane);
110111 int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
111112 int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst);
112113 int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
drivers/media/platform/qcom/iris/iris_ctrls.c+25−10
@@ -17,12 +17,20 @@ static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id) · 16 unmodified lines
1717 static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
1818 {
1919 switch (id) {
20− case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
21− return DEBLOCK;
2220 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
23− return PROFILE;
21+ return PROFILE_H264;
22+ case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
23+ return PROFILE_HEVC;
24+ case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
25+ return PROFILE_VP9;
2426 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
25− return LEVEL;
27+ return LEVEL_H264;
28+ case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
29+ return LEVEL_HEVC;
30+ case V4L2_CID_MPEG_VIDEO_VP9_LEVEL:
31+ return LEVEL_VP9;
32+ case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
33+ return TIER;
2634 default:
2735 return INST_FW_CAP_MAX;
2836 }
@@ -34,12 +42,20 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id) · 5 unmodified lines
3442 return 0;
3543
3644 switch (cap_id) {
37− case DEBLOCK:
38− return V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER;
39− case PROFILE:
45+ case PROFILE_H264:
4046 return V4L2_CID_MPEG_VIDEO_H264_PROFILE;
41− case LEVEL:
47+ case PROFILE_HEVC:
48+ return V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
49+ case PROFILE_VP9:
50+ return V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
51+ case LEVEL_H264:
4252 return V4L2_CID_MPEG_VIDEO_H264_LEVEL;
53+ case LEVEL_HEVC:
54+ return V4L2_CID_MPEG_VIDEO_HEVC_LEVEL;
55+ case LEVEL_VP9:
56+ return V4L2_CID_MPEG_VIDEO_VP9_LEVEL;
57+ case TIER:
58+ return V4L2_CID_MPEG_VIDEO_HEVC_TIER;
4359 default:
4460 return 0;
4561 }
@@ -84,8 +100,6 @@ int iris_ctrls_init(struct iris_inst *inst) · 38 unmodified lines
84100 if (iris_get_v4l2_id(cap[idx].cap_id))
85101 num_ctrls++;
86102 }
87− if (!num_ctrls)
88− return -EINVAL;
89103
90104 /* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */
91105
@@ -163,6 +177,7 @@ void iris_session_init_caps(struct iris_core *core) · 71 unmodified lines
163177 core->inst_fw_caps[cap_id].value = caps[i].value;
164178 core->inst_fw_caps[cap_id].flags = caps[i].flags;
165179 core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id;
180+ core->inst_fw_caps[cap_id].set = caps[i].set;
166181 }
167182 }
168183
drivers/media/platform/qcom/iris/iris_hfi_common.h+1−0
@@ -140,6 +140,7 @@ struct hfi_subscription_params { · 139 unmodified lines
140140 u32 color_info;
141141 u32 profile;
142142 u32 level;
143+ u32 tier;
143144 };
144145
145146 u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries);
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c+29−19
@@ -88,16 +88,29 @@ static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core) · 87 unmodified lines
8888 static int iris_hfi_gen1_session_open(struct iris_inst *inst)
8989 {
9090 struct hfi_session_open_pkt packet;
91+ u32 codec = 0;
9192 int ret;
9293
9394 if (inst->state != IRIS_INST_DEINIT)
9495 return -EALREADY;
9596
97+ switch (inst->codec) {
98+ case V4L2_PIX_FMT_H264:
99+ codec = HFI_VIDEO_CODEC_H264;
100+ break;
101+ case V4L2_PIX_FMT_HEVC:
102+ codec = HFI_VIDEO_CODEC_HEVC;
103+ break;
104+ case V4L2_PIX_FMT_VP9:
105+ codec = HFI_VIDEO_CODEC_VP9;
106+ break;
107+ }
108+
96109 packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);
97110 packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT;
98111 packet.shdr.session_id = inst->session_id;
99112 packet.session_domain = HFI_SESSION_TYPE_DEC;
100− packet.session_codec = HFI_VIDEO_CODEC_H264;
113+ packet.session_codec = codec;
101114
102115 reinit_completion(&inst->completion);
103116
@@ -208,8 +221,10 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) · 104 unmodified lines
208221 flush_pkt.flush_type = flush_type;
209222
210223 ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
211− if (!ret)
224+ if (!ret) {
225+ inst->flush_responses_pending++;
212226 ret = iris_wait_for_session_response(inst, true);
227+ }
213228 }
214229
215230 return ret;
@@ -386,6 +401,8 @@ static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane) · 170 unmodified lines
386401 ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
387402 ip_pkt.shdr.session_id = inst->session_id;
388403 ip_pkt.flags = HFI_BUFFERFLAG_EOS;
404+ if (inst->codec == V4L2_PIX_FMT_VP9)
405+ ip_pkt.packet_buffer = 0xdeadb000;
389406
390407 return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
391408 }
@@ -490,14 +507,6 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p · 98 unmodified lines
490507 packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm);
491508 break;
492509 }
493− case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: {
494− struct hfi_enable *en = prop_data;
495− u32 *in = pdata;
496−
497− en->enable = *in;
498− packet->shdr.hdr.size += sizeof(u32) + sizeof(*en);
499− break;
500− }
501510 default:
502511 return -EINVAL;
503512 }
@@ -546,14 +555,15 @@ static int iris_hfi_gen1_set_resolution(struct iris_inst *inst) · 42 unmodified lines
546555 struct hfi_framesize fs;
547556 int ret;
548557
549− fs.buffer_type = HFI_BUFFER_INPUT;
550− fs.width = inst->fmt_src->fmt.pix_mp.width;
551− fs.height = inst->fmt_src->fmt.pix_mp.height;
552−
553− ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
554− if (ret)
555− return ret;
558+ if (!iris_drc_pending(inst)) {
559+ fs.buffer_type = HFI_BUFFER_INPUT;
560+ fs.width = inst->fmt_src->fmt.pix_mp.width;
561+ fs.height = inst->fmt_src->fmt.pix_mp.height;
556562
563+ ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
564+ if (ret)
565+ return ret;
566+ }
557567 fs.buffer_type = HFI_BUFFER_OUTPUT2;
558568 fs.width = inst->fmt_dst->fmt.pix_mp.width;
559569 fs.height = inst->fmt_dst->fmt.pix_mp.height;
@@ -768,8 +778,8 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p · 208 unmodified lines
768778 iris_hfi_gen1_set_bufsize},
769779 };
770780
771− config_params = core->iris_platform_data->input_config_params;
772− config_params_size = core->iris_platform_data->input_config_params_size;
781+ config_params = core->iris_platform_data->input_config_params_default;
782+ config_params_size = core->iris_platform_data->input_config_params_default_size;
773783
774784 if (V4L2_TYPE_IS_OUTPUT(plane)) {
775785 for (i = 0; i < config_params_size; i++) {
drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h+4−1
@@ -13,6 +13,8 @@ · 12 unmodified lines
1313 #define HFI_SESSION_TYPE_DEC 2
1414
1515 #define HFI_VIDEO_CODEC_H264 0x00000002
16+#define HFI_VIDEO_CODEC_HEVC 0x00002000
17+#define HFI_VIDEO_CODEC_VP9 0x00004000
1618
1719 #define HFI_ERR_NONE 0x0
1820
@@ -65,7 +67,6 @@ · 46 unmodified lines
6567
6668 #define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS 0x202001
6769
68−#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER 0x1200001
6970 #define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS 0x120300e
7071 #define HFI_PROPERTY_CONFIG_VDEC_ENTROPY 0x1204004
7172
@@ -117,6 +118,8 @@ · 45 unmodified lines
117118 #define HFI_FRAME_NOTCODED 0x7f002000
118119 #define HFI_FRAME_YUV 0x7f004000
119120 #define HFI_UNUSED_PICT 0x10000000
121+#define HFI_BUFFERFLAG_DATACORRUPT 0x00000008
122+#define HFI_BUFFERFLAG_DROP_FRAME 0x20000000
120123
121124 struct hfi_pkt_hdr {
122125 u32 size;
drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c+28−9
@@ -200,14 +200,14 @@ static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst, · 199 unmodified lines
200200
201201 iris_hfi_gen1_read_changed_params(inst, pkt);
202202
203− if (inst->state != IRIS_INST_ERROR) {
204− reinit_completion(&inst->flush_completion);
203+ if (inst->state != IRIS_INST_ERROR && !(inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) {
205204
206205 flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
207206 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
208207 flush_pkt.shdr.session_id = inst->session_id;
209208 flush_pkt.flush_type = HFI_FLUSH_OUTPUT;
210− iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size);
209+ if (!iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size))
210+ inst->flush_responses_pending++;
211211 }
212212
213213 iris_vdec_src_change(inst);
@@ -348,6 +348,10 @@ static void iris_hfi_gen1_session_etb_done(struct iris_inst *inst, void *packet) · 134 unmodified lines
348348 struct iris_buffer *buf = NULL;
349349 bool found = false;
350350
351+ /* EOS buffer sent via drain won't be in v4l2 buffer list */
352+ if (pkt->packet_buffer == 0xdeadb000)
353+ return;
354+
351355 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) {
352356 buf = to_iris_buffer(&m2m_buffer->vb);
353357 if (buf->index == pkt->input_tag) {
@@ -408,7 +412,9 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) · 54 unmodified lines
408412 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
409413 flush_pkt.shdr.session_id = inst->session_id;
410414 flush_pkt.flush_type = HFI_FLUSH_OUTPUT;
411− iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
415+ if (!iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size))
416+ inst->flush_responses_pending++;
417+
412418 iris_inst_sub_state_change_drain_last(inst);
413419
414420 return;
@@ -455,7 +461,12 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) · 40 unmodified lines
455461 timestamp_us = timestamp_hi;
456462 timestamp_us = (timestamp_us << 32) | timestamp_lo;
457463 } else {
458− flags |= V4L2_BUF_FLAG_LAST;
464+ if (pkt->stream_id == 1 && !inst->last_buffer_dequeued) {
465+ if (iris_drc_pending(inst)) {
466+ flags |= V4L2_BUF_FLAG_LAST;
467+ inst->last_buffer_dequeued = true;
468+ }
469+ }
459470 }
460471 buf->timestamp = timestamp_us;
461472
@@ -481,6 +492,12 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) · 19 unmodified lines
481492 buf->attr |= BUF_ATTR_DEQUEUED;
482493 buf->attr |= BUF_ATTR_BUFFER_DONE;
483494
495+ if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT)
496+ flags |= V4L2_BUF_FLAG_ERROR;
497+
498+ if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME)
499+ flags |= V4L2_BUF_FLAG_ERROR;
500+
484501 buf->flags |= flags;
485502
486503 iris_vb2_buffer_done(inst, buf);
@@ -558,7 +575,6 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response · 71 unmodified lines
558575 const struct iris_hfi_gen1_response_pkt_info *pkt_info;
559576 struct device *dev = core->dev;
560577 struct hfi_session_pkt *pkt;
561− struct completion *done;
562578 struct iris_inst *inst;
563579 bool found = false;
564580 u32 i;
@@ -619,9 +635,12 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response · 54 unmodified lines
619635 if (shdr->error_type != HFI_ERR_NONE)
620636 iris_inst_change_state(inst, IRIS_INST_ERROR);
621637
622− done = pkt_info->pkt == HFI_MSG_SESSION_FLUSH ?
623− &inst->flush_completion : &inst->completion;
624− complete(done);
638+ if (pkt_info->pkt == HFI_MSG_SESSION_FLUSH) {
639+ if (!(--inst->flush_responses_pending))
640+ complete(&inst->flush_completion);
641+ } else {
642+ complete(&inst->completion);
643+ }
625644 }
626645 mutex_unlock(&inst->lock);
627646
drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c+126−17
@@ -178,7 +178,7 @@ static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst) · 177 unmodified lines
178178 sizeof(u64));
179179 }
180180
181−static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst)
181+static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst)
182182 {
183183 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
184184 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
@@ -295,7 +295,19 @@ static int iris_hfi_gen2_set_profile(struct iris_inst *inst) · 110 unmodified lines
295295 {
296296 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
297297 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
298− u32 profile = inst->fw_caps[PROFILE].value;
298+ u32 profile = 0;
299+
300+ switch (inst->codec) {
301+ case V4L2_PIX_FMT_HEVC:
302+ profile = inst->fw_caps[PROFILE_HEVC].value;
303+ break;
304+ case V4L2_PIX_FMT_VP9:
305+ profile = inst->fw_caps[PROFILE_VP9].value;
306+ break;
307+ case V4L2_PIX_FMT_H264:
308+ profile = inst->fw_caps[PROFILE_H264].value;
309+ break;
310+ }
299311
300312 inst_hfi_gen2->src_subcr_params.profile = profile;
301313
@@ -312,7 +324,19 @@ static int iris_hfi_gen2_set_level(struct iris_inst *inst) · 10 unmodified lines
312324 {
313325 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
314326 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
315− u32 level = inst->fw_caps[LEVEL].value;
327+ u32 level = 0;
328+
329+ switch (inst->codec) {
330+ case V4L2_PIX_FMT_HEVC:
331+ level = inst->fw_caps[LEVEL_HEVC].value;
332+ break;
333+ case V4L2_PIX_FMT_VP9:
334+ level = inst->fw_caps[LEVEL_VP9].value;
335+ break;
336+ case V4L2_PIX_FMT_H264:
337+ level = inst->fw_caps[LEVEL_H264].value;
338+ break;
339+ }
316340
317341 inst_hfi_gen2->src_subcr_params.level = level;
318342
@@ -367,18 +391,35 @@ static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst) · 48 unmodified lines
367391 sizeof(u64));
368392 }
369393
394+static int iris_hfi_gen2_set_tier(struct iris_inst *inst)
395+{
396+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
397+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
398+ u32 tier = inst->fw_caps[TIER].value;
399+
400+ inst_hfi_gen2->src_subcr_params.tier = tier;
401+
402+ return iris_hfi_gen2_session_set_property(inst,
403+ HFI_PROP_TIER,
404+ HFI_HOST_FLAGS_NONE,
405+ port,
406+ HFI_PAYLOAD_U32_ENUM,
407+ &tier,
408+ sizeof(u32));
409+}
410+
370411 static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
371412 {
372413 struct iris_core *core = inst->core;
373− u32 config_params_size, i, j;
374− const u32 *config_params;
414+ u32 config_params_size = 0, i, j;
415+ const u32 *config_params = NULL;
375416 int ret;
376417
377418 static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
378419 {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution },
379420 {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets },
380421 {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames },
381− {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_dpeth },
422+ {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_depth },
382423 {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count },
383424 {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count },
384425 {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace },
@@ -386,11 +427,27 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p · 1 unmodified line
386427 {HFI_PROP_LEVEL, iris_hfi_gen2_set_level },
387428 {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat },
388429 {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline },
430+ {HFI_PROP_TIER, iris_hfi_gen2_set_tier },
389431 };
390432
391433 if (V4L2_TYPE_IS_OUTPUT(plane)) {
392− config_params = core->iris_platform_data->input_config_params;
393− config_params_size = core->iris_platform_data->input_config_params_size;
434+ switch (inst->codec) {
435+ case V4L2_PIX_FMT_H264:
436+ config_params = core->iris_platform_data->input_config_params_default;
437+ config_params_size =
438+ core->iris_platform_data->input_config_params_default_size;
439+ break;
440+ case V4L2_PIX_FMT_HEVC:
441+ config_params = core->iris_platform_data->input_config_params_hevc;
442+ config_params_size =
443+ core->iris_platform_data->input_config_params_hevc_size;
444+ break;
445+ case V4L2_PIX_FMT_VP9:
446+ config_params = core->iris_platform_data->input_config_params_vp9;
447+ config_params_size =
448+ core->iris_platform_data->input_config_params_vp9_size;
449+ break;
450+ }
394451 } else {
395452 config_params = core->iris_platform_data->output_config_params;
396453 config_params_size = core->iris_platform_data->output_config_params_size;
@@ -416,7 +473,19 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p · 19 unmodified lines
416473 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
417474 {
418475 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
419− u32 codec = HFI_CODEC_DECODE_AVC;
476+ u32 codec = 0;
477+
478+ switch (inst->codec) {
479+ case V4L2_PIX_FMT_H264:
480+ codec = HFI_CODEC_DECODE_AVC;
481+ break;
482+ case V4L2_PIX_FMT_HEVC:
483+ codec = HFI_CODEC_DECODE_HEVC;
484+ break;
485+ case V4L2_PIX_FMT_VP9:
486+ codec = HFI_CODEC_DECODE_VP9;
487+ break;
488+ }
420489
421490 iris_hfi_gen2_packet_session_property(inst,
422491 HFI_PROP_CODEC,
@@ -548,8 +617,8 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 125 unmodified lines
548617 struct hfi_subscription_params subsc_params;
549618 u32 prop_type, payload_size, payload_type;
550619 struct iris_core *core = inst->core;
551− const u32 *change_param;
552− u32 change_param_size;
620+ const u32 *change_param = NULL;
621+ u32 change_param_size = 0;
553622 u32 payload[32] = {0};
554623 u32 hfi_port = 0, i;
555624 int ret;
@@ -560,8 +629,23 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 4 unmodified lines
560629 return 0;
561630 }
562631
563− change_param = core->iris_platform_data->input_config_params;
564− change_param_size = core->iris_platform_data->input_config_params_size;
632+ switch (inst->codec) {
633+ case V4L2_PIX_FMT_H264:
634+ change_param = core->iris_platform_data->input_config_params_default;
635+ change_param_size =
636+ core->iris_platform_data->input_config_params_default_size;
637+ break;
638+ case V4L2_PIX_FMT_HEVC:
639+ change_param = core->iris_platform_data->input_config_params_hevc;
640+ change_param_size =
641+ core->iris_platform_data->input_config_params_hevc_size;
642+ break;
643+ case V4L2_PIX_FMT_VP9:
644+ change_param = core->iris_platform_data->input_config_params_vp9;
645+ change_param_size =
646+ core->iris_platform_data->input_config_params_vp9_size;
647+ break;
648+ }
565649
566650 payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
567651
@@ -608,6 +692,11 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 40 unmodified lines
608692 payload_size = sizeof(u32);
609693 payload_type = HFI_PAYLOAD_U32;
610694 break;
695+ case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
696+ payload[0] = subsc_params.bit_depth;
697+ payload_size = sizeof(u32);
698+ payload_type = HFI_PAYLOAD_U32;
699+ break;
611700 case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
612701 payload[0] = subsc_params.fw_min_count;
613702 payload_size = sizeof(u32);
@@ -633,6 +722,11 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 19 unmodified lines
633722 payload_size = sizeof(u32);
634723 payload_type = HFI_PAYLOAD_U32;
635724 break;
725+ case HFI_PROP_TIER:
726+ payload[0] = subsc_params.tier;
727+ payload_size = sizeof(u32);
728+ payload_type = HFI_PAYLOAD_U32;
729+ break;
636730 default:
637731 prop_type = 0;
638732 ret = -EINVAL;
@@ -659,8 +753,8 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 20 unmodified lines
659753 static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
660754 {
661755 struct iris_core *core = inst->core;
662− u32 subscribe_prop_size, i;
663− const u32 *subcribe_prop;
756+ u32 subscribe_prop_size = 0, i;
757+ const u32 *subcribe_prop = NULL;
664758 u32 payload[32] = {0};
665759
666760 payload[0] = HFI_MODE_PROPERTY;
@@ -669,8 +763,23 @@ static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane) · 2 unmodified lines
669763 subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
670764 subcribe_prop = core->iris_platform_data->dec_input_prop;
671765 } else {
672− subscribe_prop_size = core->iris_platform_data->dec_output_prop_size;
673− subcribe_prop = core->iris_platform_data->dec_output_prop;
766+ switch (inst->codec) {
767+ case V4L2_PIX_FMT_H264:
768+ subcribe_prop = core->iris_platform_data->dec_output_prop_avc;
769+ subscribe_prop_size =
770+ core->iris_platform_data->dec_output_prop_avc_size;
771+ break;
772+ case V4L2_PIX_FMT_HEVC:
773+ subcribe_prop = core->iris_platform_data->dec_output_prop_hevc;
774+ subscribe_prop_size =
775+ core->iris_platform_data->dec_output_prop_hevc_size;
776+ break;
777+ case V4L2_PIX_FMT_VP9:
778+ subcribe_prop = core->iris_platform_data->dec_output_prop_vp9;
779+ subscribe_prop_size =
780+ core->iris_platform_data->dec_output_prop_vp9_size;
781+ break;
782+ }
674783 }
675784
676785 for (i = 0; i < subscribe_prop_size; i++)
drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h+5−0
@@ -46,6 +46,7 @@ · 45 unmodified lines
4646 #define HFI_PROP_CROP_OFFSETS 0x03000105
4747 #define HFI_PROP_PROFILE 0x03000107
4848 #define HFI_PROP_LEVEL 0x03000108
49+#define HFI_PROP_TIER 0x03000109
4950 #define HFI_PROP_STAGE 0x0300010a
5051 #define HFI_PROP_PIPE 0x0300010b
5152 #define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f
@@ -104,6 +105,9 @@ enum hfi_color_format { · 52 unmodified lines
104105 enum hfi_codec_type {
105106 HFI_CODEC_DECODE_AVC = 1,
106107 HFI_CODEC_ENCODE_AVC = 2,
108+ HFI_CODEC_DECODE_HEVC = 3,
109+ HFI_CODEC_ENCODE_HEVC = 4,
110+ HFI_CODEC_DECODE_VP9 = 5,
107111 };
108112
109113 enum hfi_picture_type {
@@ -113,6 +117,7 @@ enum hfi_picture_type { · 3 unmodified lines
113117 HFI_PICTURE_I = 0x00000008,
114118 HFI_PICTURE_CRA = 0x00000010,
115119 HFI_PICTURE_BLA = 0x00000020,
120+ HFI_PICTURE_NOSHOW = 0x00000040,
116121 };
117122
118123 enum hfi_buffer_type {
drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c+47−9
@@ -91,7 +91,9 @@ static int iris_hfi_gen2_get_driver_buffer_flags(struct iris_inst *inst, u32 hfi · 90 unmodified lines
9191 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
9292 u32 driver_flags = 0;
9393
94− if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe)
94+ if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_NOSHOW)
95+ driver_flags |= V4L2_BUF_FLAG_ERROR;
96+ else if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe)
9597 driver_flags |= V4L2_BUF_FLAG_KEYFRAME;
9698 else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_P)
9799 driver_flags |= V4L2_BUF_FLAG_PFRAME;
@@ -265,7 +267,8 @@ static int iris_hfi_gen2_handle_system_error(struct iris_core *core, · 167 unmodified lines
265267 {
266268 struct iris_inst *instance;
267269
268− dev_err(core->dev, "received system error of type %#x\n", pkt->type);
270+ if (pkt)
271+ dev_err(core->dev, "received system error of type %#x\n", pkt->type);
269272
270273 core->state = IRIS_CORE_ERROR;
271274
@@ -377,6 +380,11 @@ static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, · 105 unmodified lines
377380
378381 buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->flags);
379382
383+ if (!buf->data_size && inst->state == IRIS_INST_STREAMING &&
384+ !(hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST)) {
385+ buf->flags |= V4L2_BUF_FLAG_ERROR;
386+ }
387+
380388 return 0;
381389 }
382390
@@ -563,9 +571,23 @@ static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) · 180 unmodified lines
563571 inst->crop.width = pixmp_ip->width -
564572 ((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left;
565573
566− inst->fw_caps[PROFILE].value = subsc_params.profile;
567− inst->fw_caps[LEVEL].value = subsc_params.level;
574+ switch (inst->codec) {
575+ case V4L2_PIX_FMT_HEVC:
576+ inst->fw_caps[PROFILE_HEVC].value = subsc_params.profile;
577+ inst->fw_caps[LEVEL_HEVC].value = subsc_params.level;
578+ break;
579+ case V4L2_PIX_FMT_VP9:
580+ inst->fw_caps[PROFILE_VP9].value = subsc_params.profile;
581+ inst->fw_caps[LEVEL_VP9].value = subsc_params.level;
582+ break;
583+ case V4L2_PIX_FMT_H264:
584+ inst->fw_caps[PROFILE_H264].value = subsc_params.profile;
585+ inst->fw_caps[LEVEL_H264].value = subsc_params.level;
586+ break;
587+ }
588+
568589 inst->fw_caps[POC].value = subsc_params.pic_order_cnt;
590+ inst->fw_caps[TIER].value = subsc_params.tier;
569591
570592 if (subsc_params.bit_depth != BIT_DEPTH_8 ||
571593 !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) {
@@ -636,9 +658,6 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, · 64 unmodified lines
636658 {
637659 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
638660
639− if (pkt->port != HFI_PORT_BITSTREAM)
640− return 0;
641−
642661 if (pkt->flags & HFI_FW_FLAGS_INFORMATION)
643662 return 0;
644663
@@ -650,6 +669,9 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, · 5 unmodified lines
650669 inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0];
651670 inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1];
652671 break;
672+ case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
673+ inst_hfi_gen2->src_subcr_params.bit_depth = pkt->payload[0];
674+ break;
653675 case HFI_PROP_CODED_FRAMES:
654676 inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0];
655677 break;
@@ -668,6 +690,9 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, · 12 unmodified lines
668690 case HFI_PROP_LEVEL:
669691 inst_hfi_gen2->src_subcr_params.level = pkt->payload[0];
670692 break;
693+ case HFI_PROP_TIER:
694+ inst_hfi_gen2->src_subcr_params.tier = pkt->payload[0];
695+ break;
671696 case HFI_PROP_PICTURE_TYPE:
672697 inst_hfi_gen2->hfi_frame_info.picture_type = pkt->payload[0];
673698 break;
@@ -791,8 +816,21 @@ static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst) · 117 unmodified lines
791816 full_range, video_format,
792817 video_signal_type_present_flag);
793818
794− subsc_params->profile = inst->fw_caps[PROFILE].value;
795− subsc_params->level = inst->fw_caps[LEVEL].value;
819+ switch (inst->codec) {
820+ case V4L2_PIX_FMT_HEVC:
821+ subsc_params->profile = inst->fw_caps[PROFILE_HEVC].value;
822+ subsc_params->level = inst->fw_caps[LEVEL_HEVC].value;
823+ break;
824+ case V4L2_PIX_FMT_VP9:
825+ subsc_params->profile = inst->fw_caps[PROFILE_VP9].value;
826+ subsc_params->level = inst->fw_caps[LEVEL_VP9].value;
827+ break;
828+ case V4L2_PIX_FMT_H264:
829+ subsc_params->profile = inst->fw_caps[PROFILE_H264].value;
830+ subsc_params->level = inst->fw_caps[LEVEL_H264].value;
831+ break;
832+ }
833+
796834 subsc_params->pic_order_cnt = inst->fw_caps[POC].value;
797835 subsc_params->bit_depth = inst->fw_caps[BIT_DEPTH].value;
798836 if (inst->fw_caps[CODED_FRAMES].value ==
drivers/media/platform/qcom/iris/iris_hfi_queue.c+1−1
@@ -113,7 +113,7 @@ int iris_hfi_queue_cmd_write_locked(struct iris_core *core, void *pkt, u32 pkt_s · 112 unmodified lines
113113 {
114114 struct iris_iface_q_info *q_info = &core->command_queue;
115115
116− if (core->state == IRIS_CORE_ERROR)
116+ if (core->state == IRIS_CORE_ERROR || core->state == IRIS_CORE_DEINIT)
117117 return -EINVAL;
118118
119119 if (!iris_hfi_queue_write(q_info, pkt, pkt_size)) {
drivers/media/platform/qcom/iris/iris_instance.h+6−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 * @crop: structure of crop info
2828 * @completion: structure of signal completions
2929 * @flush_completion: structure of signal completions for flush cmd
30+ * @flush_responses_pending: counter to track number of pending flush responses
3031 * @fw_caps: array of supported instance firmware capabilities
3132 * @buffers: array of different iris buffers
3233 * @fw_min_count: minimnum count of buffers needed by fw
@@ -42,6 +43,8 @@ · 9 unmodified lines
4243 * @sequence_out: a sequence counter for output queue
4344 * @tss: timestamp metadata
4445 * @metadata_idx: index for metadata buffer
46+ * @codec: codec type
47+ * @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver
4548 */
4649
4750 struct iris_inst {
@@ -57,6 +60,7 @@ struct iris_inst { · 9 unmodified lines
5760 struct iris_hfi_rect_desc crop;
5861 struct completion completion;
5962 struct completion flush_completion;
63+ u32 flush_responses_pending;
6064 struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX];
6165 struct iris_buffers buffers[BUF_TYPE_MAX];
6266 u32 fw_min_count;
@@ -72,6 +76,8 @@ struct iris_inst { · 9 unmodified lines
7276 u32 sequence_out;
7377 struct iris_ts_metadata tss[VIDEO_MAX_FRAME];
7478 u32 metadata_idx;
79+ u32 codec;
80+ bool last_buffer_dequeued;
7581 };
7682
7783 #endif
drivers/media/platform/qcom/iris/iris_platform_common.h+21−7
@@ -21,6 +21,7 @@ struct iris_inst; · 20 unmodified lines
2121 #define DEFAULT_MAX_HOST_BUF_COUNT 64
2222 #define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256
2323 #define DEFAULT_FPS 30
24+#define NUM_MBS_8K ((8192 * 4352) / 256)
2425
2526 enum stage_type {
2627 STAGE_1 = 1,
@@ -80,8 +81,12 @@ struct platform_inst_caps { · 53 unmodified lines
8081 };
8182
8283 enum platform_inst_fw_cap_type {
83− PROFILE = 1,
84− LEVEL,
84+ PROFILE_H264 = 1,
85+ PROFILE_HEVC,
86+ PROFILE_VP9,
87+ LEVEL_H264,
88+ LEVEL_HEVC,
89+ LEVEL_VP9,
8590 INPUT_BUF_HOST_MAX_COUNT,
8691 STAGE,
8792 PIPE,
@@ -89,7 +94,7 @@ enum platform_inst_fw_cap_type { · 1 unmodified line
8994 CODED_FRAMES,
9095 BIT_DEPTH,
9196 RAP_FRAME,
92− DEBLOCK,
97+ TIER,
9398 INST_FW_CAP_MAX,
9499 };
95100
@@ -172,15 +177,24 @@ struct iris_platform_data { · 76 unmodified lines
172177 struct ubwc_config_data *ubwc_config;
173178 u32 num_vpp_pipe;
174179 u32 max_session_count;
180+ /* max number of macroblocks per frame supported */
175181 u32 max_core_mbpf;
176− const u32 *input_config_params;
177− unsigned int input_config_params_size;
182+ const u32 *input_config_params_default;
183+ unsigned int input_config_params_default_size;
184+ const u32 *input_config_params_hevc;
185+ unsigned int input_config_params_hevc_size;
186+ const u32 *input_config_params_vp9;
187+ unsigned int input_config_params_vp9_size;
178188 const u32 *output_config_params;
179189 unsigned int output_config_params_size;
180190 const u32 *dec_input_prop;
181191 unsigned int dec_input_prop_size;
182− const u32 *dec_output_prop;
183− unsigned int dec_output_prop_size;
192+ const u32 *dec_output_prop_avc;
193+ unsigned int dec_output_prop_avc_size;
194+ const u32 *dec_output_prop_hevc;
195+ unsigned int dec_output_prop_hevc_size;
196+ const u32 *dec_output_prop_vp9;
197+ unsigned int dec_output_prop_vp9_size;
184198 const u32 *dec_ip_int_buf_tbl;
185199 unsigned int dec_ip_int_buf_tbl_size;
186200 const u32 *dec_op_int_buf_tbl;
drivers/media/platform/qcom/iris/iris_platform_gen2.c+174−24
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717
1818 static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = {
1919 {
20− .cap_id = PROFILE,
20+ .cap_id = PROFILE_H264,
2121 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
2222 .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
2323 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
@@ -31,7 +31,29 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { · 7 unmodified lines
3131 .set = iris_set_u32_enum,
3232 },
3333 {
34− .cap_id = LEVEL,
34+ .cap_id = PROFILE_HEVC,
35+ .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
36+ .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE,
37+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
38+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE),
39+ .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
40+ .hfi_id = HFI_PROP_PROFILE,
41+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
42+ .set = iris_set_u32_enum,
43+ },
44+ {
45+ .cap_id = PROFILE_VP9,
46+ .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
47+ .max = V4L2_MPEG_VIDEO_VP9_PROFILE_2,
48+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) |
49+ BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2),
50+ .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
51+ .hfi_id = HFI_PROP_PROFILE,
52+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
53+ .set = iris_set_u32_enum,
54+ },
55+ {
56+ .cap_id = LEVEL_H264,
3557 .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
3658 .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
3759 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
@@ -59,6 +81,60 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { · 21 unmodified lines
5981 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
6082 .set = iris_set_u32_enum,
6183 },
84+ {
85+ .cap_id = LEVEL_HEVC,
86+ .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
87+ .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
88+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
89+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
90+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
91+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
92+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
93+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
94+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
95+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
96+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
97+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
98+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
99+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
100+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
101+ .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
102+ .hfi_id = HFI_PROP_LEVEL,
103+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
104+ .set = iris_set_u32_enum,
105+ },
106+ {
107+ .cap_id = LEVEL_VP9,
108+ .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0,
109+ .max = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
110+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) |
111+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) |
112+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) |
113+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) |
114+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) |
115+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) |
116+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) |
117+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) |
118+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) |
119+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) |
120+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) |
121+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0),
122+ .value = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
123+ .hfi_id = HFI_PROP_LEVEL,
124+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
125+ .set = iris_set_u32_enum,
126+ },
127+ {
128+ .cap_id = TIER,
129+ .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
130+ .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
131+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) |
132+ BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH),
133+ .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
134+ .hfi_id = HFI_PROP_TIER,
135+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
136+ .set = iris_set_u32_enum,
137+ },
62138 {
63139 .cap_id = INPUT_BUF_HOST_MAX_COUNT,
64140 .min = DEFAULT_MAX_HOST_BUF_COUNT,
@@ -181,9 +257,10 @@ static struct tz_cp_config tz_cp_config_sm8550 = { · 116 unmodified lines
181257 .cp_nonpixel_size = 0x24800000,
182258 };
183259
184−static const u32 sm8550_vdec_input_config_params[] = {
260+static const u32 sm8550_vdec_input_config_params_default[] = {
185261 HFI_PROP_BITSTREAM_RESOLUTION,
186262 HFI_PROP_CROP_OFFSETS,
263+ HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
187264 HFI_PROP_CODED_FRAMES,
188265 HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
189266 HFI_PROP_PIC_ORDER_CNT_TYPE,
@@ -192,6 +269,26 @@ static const u32 sm8550_vdec_input_config_params[] = { · 2 unmodified lines
192269 HFI_PROP_SIGNAL_COLOR_INFO,
193270 };
194271
272+static const u32 sm8550_vdec_input_config_param_hevc[] = {
273+ HFI_PROP_BITSTREAM_RESOLUTION,
274+ HFI_PROP_CROP_OFFSETS,
275+ HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
276+ HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
277+ HFI_PROP_PROFILE,
278+ HFI_PROP_LEVEL,
279+ HFI_PROP_TIER,
280+ HFI_PROP_SIGNAL_COLOR_INFO,
281+};
282+
283+static const u32 sm8550_vdec_input_config_param_vp9[] = {
284+ HFI_PROP_BITSTREAM_RESOLUTION,
285+ HFI_PROP_CROP_OFFSETS,
286+ HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
287+ HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
288+ HFI_PROP_PROFILE,
289+ HFI_PROP_LEVEL,
290+};
291+
195292 static const u32 sm8550_vdec_output_config_params[] = {
196293 HFI_PROP_COLOR_FORMAT,
197294 HFI_PROP_LINEAR_STRIDE_SCANLINE,
@@ -201,11 +298,19 @@ static const u32 sm8550_vdec_subscribe_input_properties[] = { · 3 unmodified lines
201298 HFI_PROP_NO_OUTPUT,
202299 };
203300
204−static const u32 sm8550_vdec_subscribe_output_properties[] = {
301+static const u32 sm8550_vdec_subscribe_output_properties_avc[] = {
205302 HFI_PROP_PICTURE_TYPE,
206303 HFI_PROP_CABAC_SESSION,
207304 };
208305
306+static const u32 sm8550_vdec_subscribe_output_properties_hevc[] = {
307+ HFI_PROP_PICTURE_TYPE,
308+};
309+
310+static const u32 sm8550_vdec_subscribe_output_properties_vp9[] = {
311+ HFI_PROP_PICTURE_TYPE,
312+};
313+
209314 static const u32 sm8550_dec_ip_int_buf_tbl[] = {
210315 BUF_BIN,
211316 BUF_COMV,
@@ -248,19 +353,34 @@ struct iris_platform_data sm8550_data = { · 36 unmodified lines
248353 .ubwc_config = &ubwc_config_sm8550,
249354 .num_vpp_pipe = 4,
250355 .max_session_count = 16,
251− .max_core_mbpf = ((8192 * 4352) / 256) * 2,
252− .input_config_params =
253− sm8550_vdec_input_config_params,
254− .input_config_params_size =
255− ARRAY_SIZE(sm8550_vdec_input_config_params),
356+ .max_core_mbpf = NUM_MBS_8K * 2,
357+ .input_config_params_default =
358+ sm8550_vdec_input_config_params_default,
359+ .input_config_params_default_size =
360+ ARRAY_SIZE(sm8550_vdec_input_config_params_default),
361+ .input_config_params_hevc =
362+ sm8550_vdec_input_config_param_hevc,
363+ .input_config_params_hevc_size =
364+ ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
365+ .input_config_params_vp9 =
366+ sm8550_vdec_input_config_param_vp9,
367+ .input_config_params_vp9_size =
368+ ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
256369 .output_config_params =
257370 sm8550_vdec_output_config_params,
258371 .output_config_params_size =
259372 ARRAY_SIZE(sm8550_vdec_output_config_params),
260373 .dec_input_prop = sm8550_vdec_subscribe_input_properties,
261374 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
262− .dec_output_prop = sm8550_vdec_subscribe_output_properties,
263− .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),
375+ .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
376+ .dec_output_prop_avc_size =
377+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
378+ .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
379+ .dec_output_prop_hevc_size =
380+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
381+ .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
382+ .dec_output_prop_vp9_size =
383+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
264384
265385 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
266386 .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
@@ -308,19 +428,34 @@ struct iris_platform_data sm8650_data = { · 41 unmodified lines
308428 .ubwc_config = &ubwc_config_sm8550,
309429 .num_vpp_pipe = 4,
310430 .max_session_count = 16,
311− .max_core_mbpf = ((8192 * 4352) / 256) * 2,
312− .input_config_params =
313− sm8550_vdec_input_config_params,
314− .input_config_params_size =
315− ARRAY_SIZE(sm8550_vdec_input_config_params),
431+ .max_core_mbpf = NUM_MBS_8K * 2,
432+ .input_config_params_default =
433+ sm8550_vdec_input_config_params_default,
434+ .input_config_params_default_size =
435+ ARRAY_SIZE(sm8550_vdec_input_config_params_default),
436+ .input_config_params_hevc =
437+ sm8550_vdec_input_config_param_hevc,
438+ .input_config_params_hevc_size =
439+ ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
440+ .input_config_params_vp9 =
441+ sm8550_vdec_input_config_param_vp9,
442+ .input_config_params_vp9_size =
443+ ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
316444 .output_config_params =
317445 sm8550_vdec_output_config_params,
318446 .output_config_params_size =
319447 ARRAY_SIZE(sm8550_vdec_output_config_params),
320448 .dec_input_prop = sm8550_vdec_subscribe_input_properties,
321449 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
322− .dec_output_prop = sm8550_vdec_subscribe_output_properties,
323− .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),
450+ .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
451+ .dec_output_prop_avc_size =
452+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
453+ .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
454+ .dec_output_prop_hevc_size =
455+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
456+ .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
457+ .dec_output_prop_vp9_size =
458+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
324459
325460 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
326461 .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
@@ -365,18 +500,33 @@ struct iris_platform_data qcs8300_data = { · 38 unmodified lines
365500 .num_vpp_pipe = 2,
366501 .max_session_count = 16,
367502 .max_core_mbpf = ((4096 * 2176) / 256) * 4,
368− .input_config_params =
369− sm8550_vdec_input_config_params,
370− .input_config_params_size =
371− ARRAY_SIZE(sm8550_vdec_input_config_params),
503+ .input_config_params_default =
504+ sm8550_vdec_input_config_params_default,
505+ .input_config_params_default_size =
506+ ARRAY_SIZE(sm8550_vdec_input_config_params_default),
507+ .input_config_params_hevc =
508+ sm8550_vdec_input_config_param_hevc,
509+ .input_config_params_hevc_size =
510+ ARRAY_SIZE(sm8550_vdec_input_config_param_hevc),
511+ .input_config_params_vp9 =
512+ sm8550_vdec_input_config_param_vp9,
513+ .input_config_params_vp9_size =
514+ ARRAY_SIZE(sm8550_vdec_input_config_param_vp9),
372515 .output_config_params =
373516 sm8550_vdec_output_config_params,
374517 .output_config_params_size =
375518 ARRAY_SIZE(sm8550_vdec_output_config_params),
376519 .dec_input_prop = sm8550_vdec_subscribe_input_properties,
377520 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
378− .dec_output_prop = sm8550_vdec_subscribe_output_properties,
379− .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),
521+ .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
522+ .dec_output_prop_avc_size =
523+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc),
524+ .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc,
525+ .dec_output_prop_hevc_size =
526+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc),
527+ .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9,
528+ .dec_output_prop_vp9_size =
529+ ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9),
380530
381531 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
382532 .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),
drivers/media/platform/qcom/iris/iris_platform_qcs8300.h+101−25
@@ -5,48 +5,124 @@ · 4 unmodified lines
55
66 static struct platform_inst_fw_cap inst_fw_cap_qcs8300[] = {
77 {
8− .cap_id = PROFILE,
8+ .cap_id = PROFILE_H264,
99 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
1010 .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
1111 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
12− BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
13− BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
14− BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
15− BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
12+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
13+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
14+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
15+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
1616 .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
1717 .hfi_id = HFI_PROP_PROFILE,
1818 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
1919 .set = iris_set_u32_enum,
2020 },
2121 {
22− .cap_id = LEVEL,
22+ .cap_id = PROFILE_HEVC,
23+ .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
24+ .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE,
25+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
26+ BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE),
27+ .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
28+ .hfi_id = HFI_PROP_PROFILE,
29+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
30+ .set = iris_set_u32_enum,
31+ },
32+ {
33+ .cap_id = PROFILE_VP9,
34+ .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
35+ .max = V4L2_MPEG_VIDEO_VP9_PROFILE_2,
36+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) |
37+ BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2),
38+ .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
39+ .hfi_id = HFI_PROP_PROFILE,
40+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
41+ .set = iris_set_u32_enum,
42+ },
43+ {
44+ .cap_id = LEVEL_H264,
2345 .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
2446 .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
2547 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
26− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
27− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
28− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
29− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
30− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
31− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
32− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
33− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
34− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
35− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
36− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
37− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
38− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
39− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
40− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
41− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
42− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
43− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
44− BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
48+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
49+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
50+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
51+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
52+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
53+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
54+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
55+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
56+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
57+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
58+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
59+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
60+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
61+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
62+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
63+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
64+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
65+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
66+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
4567 .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
4668 .hfi_id = HFI_PROP_LEVEL,
4769 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
4870 .set = iris_set_u32_enum,
4971 },
72+ {
73+ .cap_id = LEVEL_HEVC,
74+ .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
75+ .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
76+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
77+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
78+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
79+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
80+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
81+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
82+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
83+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
84+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
85+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
86+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
87+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
88+ BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
89+ .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
90+ .hfi_id = HFI_PROP_LEVEL,
91+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
92+ .set = iris_set_u32_enum,
93+ },
94+ {
95+ .cap_id = LEVEL_VP9,
96+ .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0,
97+ .max = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
98+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) |
99+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) |
100+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) |
101+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) |
102+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) |
103+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) |
104+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) |
105+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) |
106+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) |
107+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) |
108+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) |
109+ BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0),
110+ .value = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
111+ .hfi_id = HFI_PROP_LEVEL,
112+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
113+ .set = iris_set_u32_enum,
114+ },
115+ {
116+ .cap_id = TIER,
117+ .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
118+ .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
119+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) |
120+ BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH),
121+ .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
122+ .hfi_id = HFI_PROP_TIER,
123+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
124+ .set = iris_set_u32_enum,
125+ },
50126 {
51127 .cap_id = INPUT_BUF_HOST_MAX_COUNT,
52128 .min = DEFAULT_MAX_HOST_BUF_COUNT,
drivers/media/platform/qcom/iris/iris_platform_sm8250.c+3−12
@@ -30,15 +30,6 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8250[] = { · 29 unmodified lines
3030 .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
3131 .set = iris_set_stage,
3232 },
33− {
34− .cap_id = DEBLOCK,
35− .min = 0,
36− .max = 1,
37− .step_or_mask = 1,
38− .value = 0,
39− .hfi_id = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER,
40− .set = iris_set_u32,
41− },
4233 };
4334
4435 static struct platform_inst_caps platform_inst_cap_sm8250 = {
@@ -136,10 +127,10 @@ struct iris_platform_data sm8250_data = { · 91 unmodified lines
136127 .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
137128 .num_vpp_pipe = 4,
138129 .max_session_count = 16,
139− .max_core_mbpf = (8192 * 4352) / 256,
140− .input_config_params =
130+ .max_core_mbpf = NUM_MBS_8K,
131+ .input_config_params_default =
141132 sm8250_vdec_input_config_param_default,
142− .input_config_params_size =
133+ .input_config_params_default_size =
143134 ARRAY_SIZE(sm8250_vdec_input_config_param_default),
144135
145136 .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl,
drivers/media/platform/qcom/iris/iris_probe.c+1−1
@@ -53,7 +53,7 @@ static int iris_init_power_domains(struct iris_core *core) · 52 unmodified lines
5353 struct dev_pm_domain_attach_data iris_opp_pd_data = {
5454 .pd_names = core->iris_platform_data->opp_pd_tbl,
5555 .num_pd_names = core->iris_platform_data->opp_pd_tbl_size,
56− .pd_flags = PD_FLAG_DEV_LINK_ON,
56+ .pd_flags = PD_FLAG_DEV_LINK_ON | PD_FLAG_REQUIRED_OPP,
5757 };
5858
5959 ret = devm_pm_domain_attach_list(core->dev, &iris_pd_data, &core->pmdomain_tbl);
drivers/media/platform/qcom/iris/iris_state.c+1−1
@@ -245,7 +245,7 @@ int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane) · 244 unmodified lines
245245 return iris_inst_change_sub_state(inst, 0, set_sub_state);
246246 }
247247
248−static inline bool iris_drc_pending(struct iris_inst *inst)
248+bool iris_drc_pending(struct iris_inst *inst)
249249 {
250250 return inst->sub_state & IRIS_INST_SUB_DRC &&
251251 inst->sub_state & IRIS_INST_SUB_DRC_LAST;
drivers/media/platform/qcom/iris/iris_state.h+1−0
@@ -140,5 +140,6 @@ int iris_inst_sub_state_change_drain_last(struct iris_inst *inst); · 139 unmodified lines
140140 int iris_inst_sub_state_change_drc_last(struct iris_inst *inst);
141141 int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane);
142142 bool iris_allow_cmd(struct iris_inst *inst, u32 cmd);
143+bool iris_drc_pending(struct iris_inst *inst);
143144
144145 #endif
drivers/media/platform/qcom/iris/iris_vb2.c+10−8
@@ -259,13 +259,14 @@ int iris_vb2_buf_prepare(struct vb2_buffer *vb) · 258 unmodified lines
259259 return -EINVAL;
260260 }
261261
262− if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
263− vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT))
264− return -EINVAL;
265− if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
266− vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT))
267− return -EINVAL;
268−
262+ if (!(inst->sub_state & IRIS_INST_SUB_DRC)) {
263+ if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
264+ vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT))
265+ return -EINVAL;
266+ if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
267+ vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT))
268+ return -EINVAL;
269+ }
269270 return 0;
270271 }
271272
@@ -304,7 +305,7 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) · 32 unmodified lines
304305 goto exit;
305306 }
306307
307− if (V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) {
308+ if (!inst->last_buffer_dequeued && V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) {
308309 if ((inst->sub_state & IRIS_INST_SUB_DRC &&
309310 inst->sub_state & IRIS_INST_SUB_DRC_LAST) ||
310311 (inst->sub_state & IRIS_INST_SUB_DRAIN &&
@@ -318,6 +319,7 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) · 7 unmodified lines
318319 v4l2_event_queue_fh(&inst->fh, &eos);
319320 v4l2_m2m_mark_stopped(m2m_ctx);
320321 }
322+ inst->last_buffer_dequeued = true;
321323 goto exit;
322324 }
323325 }
drivers/media/platform/qcom/iris/iris_vdec.c+72−44
@@ -32,6 +32,7 @@ int iris_vdec_inst_init(struct iris_inst *inst) · 31 unmodified lines
3232 f->fmt.pix_mp.width = DEFAULT_WIDTH;
3333 f->fmt.pix_mp.height = DEFAULT_HEIGHT;
3434 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
35+ inst->codec = f->fmt.pix_mp.pixelformat;
3536 f->fmt.pix_mp.num_planes = 1;
3637 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
3738 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
@@ -67,14 +68,67 @@ void iris_vdec_inst_deinit(struct iris_inst *inst) · 29 unmodified lines
6768 kfree(inst->fmt_src);
6869 }
6970
71+static const struct iris_fmt iris_vdec_formats[] = {
72+ [IRIS_FMT_H264] = {
73+ .pixfmt = V4L2_PIX_FMT_H264,
74+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
75+ },
76+ [IRIS_FMT_HEVC] = {
77+ .pixfmt = V4L2_PIX_FMT_HEVC,
78+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
79+ },
80+ [IRIS_FMT_VP9] = {
81+ .pixfmt = V4L2_PIX_FMT_VP9,
82+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
83+ },
84+};
85+
86+static const struct iris_fmt *
87+find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
88+{
89+ unsigned int size = ARRAY_SIZE(iris_vdec_formats);
90+ const struct iris_fmt *fmt = iris_vdec_formats;
91+ unsigned int i;
92+
93+ for (i = 0; i < size; i++) {
94+ if (fmt[i].pixfmt == pixfmt)
95+ break;
96+ }
97+
98+ if (i == size || fmt[i].type != type)
99+ return NULL;
100+
101+ return &fmt[i];
102+}
103+
104+static const struct iris_fmt *
105+find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
106+{
107+ const struct iris_fmt *fmt = iris_vdec_formats;
108+ unsigned int size = ARRAY_SIZE(iris_vdec_formats);
109+
110+ if (index >= size || fmt[index].type != type)
111+ return NULL;
112+
113+ return &fmt[index];
114+}
115+
70116 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
71117 {
118+ const struct iris_fmt *fmt;
119+
72120 switch (f->type) {
73121 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
74− f->pixelformat = V4L2_PIX_FMT_H264;
122+ fmt = find_format_by_index(inst, f->index, f->type);
123+ if (!fmt)
124+ return -EINVAL;
125+
126+ f->pixelformat = fmt->pixfmt;
75127 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
76128 break;
77129 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
130+ if (f->index)
131+ return -EINVAL;
78132 f->pixelformat = V4L2_PIX_FMT_NV12;
79133 break;
80134 default:
@@ -88,13 +142,15 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) · 7 unmodified lines
88142 {
89143 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
90144 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
145+ const struct iris_fmt *fmt;
91146 struct v4l2_format *f_inst;
92147 struct vb2_queue *src_q;
93148
94149 memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
150+ fmt = find_format(inst, pixmp->pixelformat, f->type);
95151 switch (f->type) {
96152 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
97− if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) {
153+ if (!fmt) {
98154 f_inst = inst->fmt_src;
99155 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
100156 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
@@ -102,7 +158,7 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) · 1 unmodified line
102158 }
103159 break;
104160 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
105− if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
161+ if (!fmt) {
106162 f_inst = inst->fmt_dst;
107163 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
108164 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
@@ -145,13 +201,14 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) · 36 unmodified lines
145201
146202 switch (f->type) {
147203 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
148− if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264)
204+ if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
149205 return -EINVAL;
150206
151207 fmt = inst->fmt_src;
152208 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
153−
154− codec_align = DEFAULT_CODEC_ALIGNMENT;
209+ fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
210+ inst->codec = fmt->fmt.pix_mp.pixelformat;
211+ codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
155212 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
156213 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
157214 fmt->fmt.pix_mp.num_planes = 1;
@@ -171,6 +228,11 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) · 13 unmodified lines
171228 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
172229 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
173230
231+ /* Update capture format based on new ip w/h */
232+ output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
233+ output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
234+ inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT);
235+
174236 inst->crop.left = 0;
175237 inst->crop.top = 0;
176238 inst->crop.width = f->fmt.pix_mp.width;
@@ -239,35 +301,6 @@ void iris_vdec_src_change(struct iris_inst *inst) · 62 unmodified lines
239301 v4l2_event_queue_fh(&inst->fh, &event);
240302 }
241303
242−static int iris_vdec_get_num_queued_buffers(struct iris_inst *inst,
243− enum iris_buffer_type type)
244−{
245− struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
246− struct v4l2_m2m_buffer *buffer, *n;
247− struct iris_buffer *buf;
248− u32 count = 0;
249−
250− switch (type) {
251− case BUF_INPUT:
252− v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) {
253− buf = to_iris_buffer(&buffer->vb);
254− if (!(buf->attr & BUF_ATTR_QUEUED))
255− continue;
256− count++;
257− }
258− return count;
259− case BUF_OUTPUT:
260− v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) {
261− buf = to_iris_buffer(&buffer->vb);
262− if (!(buf->attr & BUF_ATTR_QUEUED))
263− continue;
264− count++;
265− }
266− return count;
267− default:
268− return count;
269− }
270−}
271304
272305 static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst,
273306 enum iris_buffer_type type)
@@ -316,7 +349,6 @@ int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) · 42 unmodified lines
316349 {
317350 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
318351 enum iris_buffer_type buffer_type;
319− u32 count;
320352 int ret;
321353
322354 switch (plane) {
@@ -334,12 +366,6 @@ int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) · 11 unmodified lines
334366 if (ret)
335367 goto error;
336368
337− count = iris_vdec_get_num_queued_buffers(inst, buffer_type);
338− if (count) {
339− ret = -EINVAL;
340− goto error;
341− }
342−
343369 ret = iris_inst_state_change_streamoff(inst, plane);
344370 if (ret)
345371 goto error;
@@ -408,7 +434,7 @@ int iris_vdec_streamon_input(struct iris_inst *inst) · 62 unmodified lines
408434
409435 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
410436
411− ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
437+ ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
412438 if (ret)
413439 return ret;
414440
@@ -482,6 +508,8 @@ static int iris_vdec_process_streamon_output(struct iris_inst *inst) · 67 unmodified lines
482508 if (ret)
483509 return ret;
484510
511+ inst->last_buffer_dequeued = false;
512+
485513 return iris_inst_change_sub_state(inst, clear_sub_state, 0);
486514 }
487515
@@ -496,7 +524,7 @@ int iris_vdec_streamon_output(struct iris_inst *inst) · 8 unmodified lines
496524
497525 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
498526
499− ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
527+ ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
500528 if (ret)
501529 return ret;
502530
drivers/media/platform/qcom/iris/iris_vdec.h+11−0
@@ -8,6 +8,17 @@ · 7 unmodified lines
88
99 struct iris_inst;
1010
11+enum iris_fmt_type {
12+ IRIS_FMT_H264,
13+ IRIS_FMT_HEVC,
14+ IRIS_FMT_VP9,
15+};
16+
17+struct iris_fmt {
18+ u32 pixfmt;
19+ u32 type;
20+};
21+
1122 int iris_vdec_inst_init(struct iris_inst *inst);
1223 void iris_vdec_inst_deinit(struct iris_inst *inst);
1324 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
drivers/media/platform/qcom/iris/iris_vidc.c+31−5
@@ -221,6 +221,33 @@ static void iris_session_close(struct iris_inst *inst) · 220 unmodified lines
221221 iris_wait_for_session_response(inst, false);
222222 }
223223
224+static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 plane)
225+{
226+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
227+ struct iris_buffer *buf, *next;
228+ struct iris_buffers *buffers;
229+ const u32 *internal_buf_type;
230+ u32 internal_buffer_count, i;
231+ u32 count = 0;
232+
233+ if (V4L2_TYPE_IS_OUTPUT(plane)) {
234+ internal_buf_type = platform_data->dec_ip_int_buf_tbl;
235+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size;
236+ } else {
237+ internal_buf_type = platform_data->dec_op_int_buf_tbl;
238+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size;
239+ }
240+
241+ for (i = 0; i < internal_buffer_count; i++) {
242+ buffers = &inst->buffers[internal_buf_type[i]];
243+ list_for_each_entry_safe(buf, next, &buffers->list, list)
244+ count++;
245+ if (count)
246+ dev_err(inst->core->dev, "%d buffer of type %d not released",
247+ count, internal_buf_type[i]);
248+ }
249+}
250+
224251 int iris_close(struct file *filp)
225252 {
226253 struct iris_inst *inst = iris_get_inst(filp, NULL);
@@ -233,8 +260,10 @@ int iris_close(struct file *filp) · 6 unmodified lines
233260 iris_session_close(inst);
234261 iris_inst_change_state(inst, IRIS_INST_DEINIT);
235262 iris_v4l2_fh_deinit(inst);
236− iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
237− iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
263+ iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
264+ iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
265+ iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
266+ iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
238267 iris_remove_session(inst);
239268 mutex_unlock(&inst->lock);
240269 mutex_destroy(&inst->ctx_q_lock);
@@ -249,9 +278,6 @@ static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f) · 8 unmodified lines
249278 {
250279 struct iris_inst *inst = iris_get_inst(filp, NULL);
251280
252− if (f->index)
253− return -EINVAL;
254−
255281 return iris_vdec_enum_fmt(inst, f);
256282 }
257283
drivers/media/platform/qcom/iris/iris_vpu_buffer.c+386−11
@@ -31,6 +31,42 @@ static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_p · 30 unmodified lines
3131 return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes);
3232 }
3333
34+static u32 size_h265d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
35+{
36+ u32 product = frame_width * frame_height;
37+ u32 size_yuv, size_bin_hdr, size_bin_res;
38+
39+ size_yuv = (product <= BIN_BUFFER_THRESHOLD) ?
40+ ((BIN_BUFFER_THRESHOLD * 3) >> 1) : ((product * 3) >> 1);
41+ size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT;
42+ size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT;
43+ size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, DMA_ALIGNMENT) * num_vpp_pipes;
44+ size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, DMA_ALIGNMENT) * num_vpp_pipes;
45+
46+ return size_bin_hdr + size_bin_res;
47+}
48+
49+static u32 hfi_buffer_bin_vp9d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
50+{
51+ u32 _size_yuv = ALIGN(frame_width, 16) * ALIGN(frame_height, 16) * 3 / 2;
52+ u32 _size = ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) *
53+ VPX_DECODER_FRAME_BIN_HDR_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR *
54+ VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes), DMA_ALIGNMENT) +
55+ ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) *
56+ VPX_DECODER_FRAME_BIN_RES_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR *
57+ VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes), DMA_ALIGNMENT);
58+
59+ return _size * num_vpp_pipes;
60+}
61+
62+static u32 hfi_buffer_bin_h265d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
63+{
64+ u32 n_aligned_w = ALIGN(frame_width, 16);
65+ u32 n_aligned_h = ALIGN(frame_height, 16);
66+
67+ return size_h265d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes);
68+}
69+
3470 static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount)
3571 {
3672 u32 frame_height_in_mbs = DIV_ROUND_UP(frame_height, 16);
@@ -55,6 +91,17 @@ static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bu · 18 unmodified lines
5591 return (size_colloc * (_comv_bufcount)) + 512;
5692 }
5793
94+static u32 hfi_buffer_comv_h265d(u32 frame_width, u32 frame_height, u32 _comv_bufcount)
95+{
96+ u32 frame_height_in_mbs = (frame_height + 15) >> 4;
97+ u32 frame_width_in_mbs = (frame_width + 15) >> 4;
98+ u32 _size;
99+
100+ _size = ALIGN(((frame_width_in_mbs * frame_height_in_mbs) << 8), 512);
101+
102+ return (_size * (_comv_bufcount)) + 512;
103+}
104+
58105 static u32 size_h264d_bse_cmd_buf(u32 frame_height)
59106 {
60107 u32 height = ALIGN(frame_height, 32);
@@ -63,6 +110,44 @@ static u32 size_h264d_bse_cmd_buf(u32 frame_height) · 2 unmodified lines
63110 SIZE_H264D_BSE_CMD_PER_BUF;
64111 }
65112
113+static u32 size_h265d_bse_cmd_buf(u32 frame_width, u32 frame_height)
114+{
115+ u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
116+ (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) *
117+ NUM_HW_PIC_BUF, DMA_ALIGNMENT);
118+ _size = min_t(u32, _size, H265D_MAX_SLICE + 1);
119+ _size = 2 * _size * SIZE_H265D_BSE_CMD_PER_BUF;
120+
121+ return _size;
122+}
123+
124+static u32 hfi_buffer_persist_h265d(u32 rpu_enabled)
125+{
126+ return ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 +
127+ H265_NUM_FRM_INFO * H265_DISPLAY_BUF_SIZE +
128+ H265_NUM_TILE * sizeof(u32) +
129+ NUM_HW_PIC_BUF * SIZE_SEI_USERDATA +
130+ rpu_enabled * NUM_HW_PIC_BUF * SIZE_DOLBY_RPU_METADATA),
131+ DMA_ALIGNMENT);
132+}
133+
134+static inline
135+u32 hfi_iris3_vp9d_comv_size(void)
136+{
137+ return (((8192 + 63) >> 6) * ((4320 + 63) >> 6) * 8 * 8 * 2 * 8);
138+}
139+
140+static u32 hfi_buffer_persist_vp9d(void)
141+{
142+ return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) +
143+ ALIGN(hfi_iris3_vp9d_comv_size(), DMA_ALIGNMENT) +
144+ ALIGN(MAX_SUPERFRAME_HEADER_LEN, DMA_ALIGNMENT) +
145+ ALIGN(VP9_UDC_HEADER_BUF_SIZE, DMA_ALIGNMENT) +
146+ ALIGN(VP9_NUM_FRAME_INFO_BUF * CCE_TILE_OFFSET_SIZE, DMA_ALIGNMENT) +
147+ ALIGN(VP9_NUM_FRAME_INFO_BUF * VP9_FRAME_INFO_BUF_SIZE, DMA_ALIGNMENT) +
148+ HDR10_HIST_EXTRADATA_SIZE;
149+}
150+
66151 static u32 size_h264d_vpp_cmd_buf(u32 frame_height)
67152 {
68153 u32 size, height = ALIGN(frame_height, 32);
@@ -83,17 +168,45 @@ static u32 hfi_buffer_persist_h264d(void) · 14 unmodified lines
83168
84169 static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
85170 {
86− u32 size_bse, size_vpp, size;
87−
88− size_bse = size_h264d_bse_cmd_buf(frame_height);
89− size_vpp = size_h264d_vpp_cmd_buf(frame_height);
90− size = ALIGN(size_bse, DMA_ALIGNMENT) +
171+ u32 size_bse = size_h264d_bse_cmd_buf(frame_height);
172+ u32 size_vpp = size_h264d_vpp_cmd_buf(frame_height);
173+ u32 size = ALIGN(size_bse, DMA_ALIGNMENT) +
91174 ALIGN(size_vpp, DMA_ALIGNMENT) +
92175 ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT);
93176
94177 return ALIGN(size, DMA_ALIGNMENT);
95178 }
96179
180+static u32 size_h265d_vpp_cmd_buf(u32 frame_width, u32 frame_height)
181+{
182+ u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
183+ (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) *
184+ NUM_HW_PIC_BUF, DMA_ALIGNMENT);
185+ _size = min_t(u32, _size, H265D_MAX_SLICE + 1);
186+ _size = ALIGN(_size, 4);
187+ _size = 2 * _size * SIZE_H265D_VPP_CMD_PER_BUF;
188+ if (_size > VPP_CMD_MAX_SIZE)
189+ _size = VPP_CMD_MAX_SIZE;
190+
191+ return _size;
192+}
193+
194+static u32 hfi_buffer_non_comv_h265d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
195+{
196+ u32 _size_bse = size_h265d_bse_cmd_buf(frame_width, frame_height);
197+ u32 _size_vpp = size_h265d_vpp_cmd_buf(frame_width, frame_height);
198+ u32 _size = ALIGN(_size_bse, DMA_ALIGNMENT) +
199+ ALIGN(_size_vpp, DMA_ALIGNMENT) +
200+ ALIGN(NUM_HW_PIC_BUF * 20 * 22 * 4, DMA_ALIGNMENT) +
201+ ALIGN(2 * sizeof(u16) *
202+ (ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
203+ (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS), DMA_ALIGNMENT) +
204+ ALIGN(SIZE_HW_PIC(SIZE_H265D_HW_PIC_T), DMA_ALIGNMENT) +
205+ HDR10_HIST_EXTRADATA_SIZE;
206+
207+ return ALIGN(_size, DMA_ALIGNMENT);
208+}
209+
97210 static u32 size_vpss_lb(u32 frame_width, u32 frame_height)
98211 {
99212 u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size;
@@ -119,6 +232,203 @@ static u32 size_vpss_lb(u32 frame_width, u32 frame_height) · 19 unmodified lines
119232 opb_lb_wr_llb_y_buffer_size;
120233 }
121234
235+static inline
236+u32 size_h265d_lb_fe_top_data(u32 frame_width, u32 frame_height)
237+{
238+ return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE *
239+ (ALIGN(frame_width, 64) + 8) * 2;
240+}
241+
242+static inline
243+u32 size_h265d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
244+{
245+ return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE *
246+ (ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS);
247+}
248+
249+static inline
250+u32 size_h265d_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
251+{
252+ return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE *
253+ (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS);
254+}
255+
256+static inline
257+u32 size_h265d_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
258+{
259+ return (LCU_MAX_SIZE_PELS / 8 * (128 / 8)) * ((frame_width + 15) >> 4);
260+}
261+
262+static inline
263+u32 size_h265d_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
264+{
265+ return max_t(u32, ((frame_height + 16 - 1) / 8) *
266+ MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
267+ max_t(u32, ((frame_height + 32 - 1) / 8) *
268+ MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
269+ ((frame_height + 64 - 1) / 8) *
270+ MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
271+}
272+
273+static inline
274+u32 size_h265d_lb_pe_top_data(u32 frame_width, u32 frame_height)
275+{
276+ return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE *
277+ (ALIGN(frame_width, LCU_MIN_SIZE_PELS) / LCU_MIN_SIZE_PELS);
278+}
279+
280+static inline
281+u32 size_h265d_lb_vsp_top(u32 frame_width, u32 frame_height)
282+{
283+ return ((frame_width + 63) >> 6) * 128;
284+}
285+
286+static inline
287+u32 size_h265d_lb_vsp_left(u32 frame_width, u32 frame_height)
288+{
289+ return ((frame_height + 63) >> 6) * 128;
290+}
291+
292+static inline
293+u32 size_h265d_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
294+{
295+ return size_h264d_lb_recon_dma_metadata_wr(frame_height);
296+}
297+
298+static inline
299+u32 size_h265d_qp(u32 frame_width, u32 frame_height)
300+{
301+ return size_h264d_qp(frame_width, frame_height);
302+}
303+
304+static inline
305+u32 hfi_buffer_line_h265d(u32 frame_width, u32 frame_height, bool is_opb, u32 num_vpp_pipes)
306+{
307+ u32 vpss_lb_size = 0, _size;
308+
309+ _size = ALIGN(size_h265d_lb_fe_top_data(frame_width, frame_height), DMA_ALIGNMENT) +
310+ ALIGN(size_h265d_lb_fe_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
311+ ALIGN(size_h265d_lb_fe_left_ctrl(frame_width, frame_height),
312+ DMA_ALIGNMENT) * num_vpp_pipes +
313+ ALIGN(size_h265d_lb_se_left_ctrl(frame_width, frame_height),
314+ DMA_ALIGNMENT) * num_vpp_pipes +
315+ ALIGN(size_h265d_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
316+ ALIGN(size_h265d_lb_pe_top_data(frame_width, frame_height), DMA_ALIGNMENT) +
317+ ALIGN(size_h265d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) +
318+ ALIGN(size_h265d_lb_vsp_left(frame_width, frame_height),
319+ DMA_ALIGNMENT) * num_vpp_pipes +
320+ ALIGN(size_h265d_lb_recon_dma_metadata_wr(frame_width, frame_height),
321+ DMA_ALIGNMENT) * 4 +
322+ ALIGN(size_h265d_qp(frame_width, frame_height), DMA_ALIGNMENT);
323+ if (is_opb)
324+ vpss_lb_size = size_vpss_lb(frame_width, frame_height);
325+
326+ return ALIGN((_size + vpss_lb_size), DMA_ALIGNMENT);
327+}
328+
329+static inline
330+u32 size_vpxd_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
331+{
332+ return max_t(u32, ((frame_height + 15) >> 4) *
333+ MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
334+ max_t(u32, ((frame_height + 31) >> 5) *
335+ MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
336+ ((frame_height + 63) >> 6) *
337+ MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
338+}
339+
340+static inline
341+u32 size_vpxd_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
342+{
343+ return ((ALIGN(frame_width, 64) + 8) * 10 * 2);
344+}
345+
346+static inline
347+u32 size_vpxd_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
348+{
349+ return ((frame_width + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE;
350+}
351+
352+static inline
353+u32 size_vpxd_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
354+{
355+ return max_t(u32, ((frame_height + 15) >> 4) *
356+ MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
357+ max_t(u32, ((frame_height + 31) >> 5) *
358+ MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
359+ ((frame_height + 63) >> 6) *
360+ MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
361+}
362+
363+static inline
364+u32 size_vpxd_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
365+{
366+ return ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64,
367+ BUFFER_ALIGNMENT_32_BYTES);
368+}
369+
370+static inline __maybe_unused
371+u32 size_mp2d_lb_fe_top_data(u32 frame_width, u32 frame_height)
372+{
373+ return ((ALIGN(frame_width, 16) + 8) * 10 * 2);
374+}
375+
376+static inline
377+u32 size_vp9d_lb_fe_top_data(u32 frame_width, u32 frame_height)
378+{
379+ return (ALIGN(ALIGN(frame_width, 8), 64) + 8) * 10 * 2;
380+}
381+
382+static inline
383+u32 size_vp9d_lb_pe_top_data(u32 frame_width, u32 frame_height)
384+{
385+ return ((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 176);
386+}
387+
388+static inline
389+u32 size_vp9d_lb_vsp_top(u32 frame_width, u32 frame_height)
390+{
391+ return (((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 64 * 8) + 256);
392+}
393+
394+static inline
395+u32 size_vp9d_qp(u32 frame_width, u32 frame_height)
396+{
397+ return size_h264d_qp(frame_width, frame_height);
398+}
399+
400+static inline
401+u32 hfi_iris3_vp9d_lb_size(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
402+{
403+ return ALIGN(size_vpxd_lb_fe_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) *
404+ num_vpp_pipes +
405+ ALIGN(size_vpxd_lb_se_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) *
406+ num_vpp_pipes +
407+ ALIGN(size_vp9d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) +
408+ ALIGN(size_vpxd_lb_fe_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
409+ 2 * ALIGN(size_vpxd_lb_recon_dma_metadata_wr(frame_width, frame_height),
410+ DMA_ALIGNMENT) +
411+ ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) +
412+ ALIGN(size_vp9d_lb_pe_top_data(frame_width, frame_height), DMA_ALIGNMENT) +
413+ ALIGN(size_vp9d_lb_fe_top_data(frame_width, frame_height), DMA_ALIGNMENT) +
414+ ALIGN(size_vp9d_qp(frame_width, frame_height), DMA_ALIGNMENT);
415+}
416+
417+static inline
418+u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_min, bool is_opb,
419+ u32 num_vpp_pipes)
420+{
421+ u32 vpss_lb_size = 0;
422+ u32 _lb_size;
423+
424+ _lb_size = hfi_iris3_vp9d_lb_size(frame_width, frame_height, num_vpp_pipes);
425+
426+ if (is_opb)
427+ vpss_lb_size = size_vpss_lb(frame_width, frame_height);
428+
429+ return _lb_size + vpss_lb_size + 4096;
430+}
431+
122432 static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
123433 bool is_opb, u32 num_vpp_pipes)
124434 {
@@ -148,7 +458,14 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) · 23 unmodified lines
148458 u32 height = f->fmt.pix_mp.height;
149459 u32 width = f->fmt.pix_mp.width;
150460
151− return hfi_buffer_bin_h264d(width, height, num_vpp_pipes);
461+ if (inst->codec == V4L2_PIX_FMT_H264)
462+ return hfi_buffer_bin_h264d(width, height, num_vpp_pipes);
463+ else if (inst->codec == V4L2_PIX_FMT_HEVC)
464+ return hfi_buffer_bin_h265d(width, height, num_vpp_pipes);
465+ else if (inst->codec == V4L2_PIX_FMT_VP9)
466+ return hfi_buffer_bin_vp9d(width, height, num_vpp_pipes);
467+
468+ return 0;
152469 }
153470
154471 static u32 iris_vpu_dec_comv_size(struct iris_inst *inst)
@@ -158,12 +475,24 @@ static u32 iris_vpu_dec_comv_size(struct iris_inst *inst) · 3 unmodified lines
158475 u32 height = f->fmt.pix_mp.height;
159476 u32 width = f->fmt.pix_mp.width;
160477
161− return hfi_buffer_comv_h264d(width, height, num_comv);
478+ if (inst->codec == V4L2_PIX_FMT_H264)
479+ return hfi_buffer_comv_h264d(width, height, num_comv);
480+ else if (inst->codec == V4L2_PIX_FMT_HEVC)
481+ return hfi_buffer_comv_h265d(width, height, num_comv);
482+
483+ return 0;
162484 }
163485
164486 static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
165487 {
166− return hfi_buffer_persist_h264d();
488+ if (inst->codec == V4L2_PIX_FMT_H264)
489+ return hfi_buffer_persist_h264d();
490+ else if (inst->codec == V4L2_PIX_FMT_HEVC)
491+ return hfi_buffer_persist_h265d(0);
492+ else if (inst->codec == V4L2_PIX_FMT_VP9)
493+ return hfi_buffer_persist_vp9d();
494+
495+ return 0;
167496 }
168497
169498 static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)
@@ -181,7 +510,12 @@ static u32 iris_vpu_dec_non_comv_size(struct iris_inst *inst) · 11 unmodified lines
181510 u32 height = f->fmt.pix_mp.height;
182511 u32 width = f->fmt.pix_mp.width;
183512
184− return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes);
513+ if (inst->codec == V4L2_PIX_FMT_H264)
514+ return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes);
515+ else if (inst->codec == V4L2_PIX_FMT_HEVC)
516+ return hfi_buffer_non_comv_h265d(width, height, num_vpp_pipes);
517+
518+ return 0;
185519 }
186520
187521 static u32 iris_vpu_dec_line_size(struct iris_inst *inst)
@@ -191,11 +525,20 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst) · 3 unmodified lines
191525 u32 height = f->fmt.pix_mp.height;
192526 u32 width = f->fmt.pix_mp.width;
193527 bool is_opb = false;
528+ u32 out_min_count = inst->buffers[BUF_OUTPUT].min_count;
194529
195530 if (iris_split_mode_enabled(inst))
196531 is_opb = true;
197532
198− return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes);
533+ if (inst->codec == V4L2_PIX_FMT_H264)
534+ return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes);
535+ else if (inst->codec == V4L2_PIX_FMT_HEVC)
536+ return hfi_buffer_line_h265d(width, height, is_opb, num_vpp_pipes);
537+ else if (inst->codec == V4L2_PIX_FMT_VP9)
538+ return hfi_buffer_line_vp9d(width, height, out_min_count, is_opb,
539+ num_vpp_pipes);
540+
541+ return 0;
199542 }
200543
201544 static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst)
@@ -205,6 +548,24 @@ static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst) · 3 unmodified lines
205548 iris_vpu_dec_line_size(inst);
206549 }
207550
551+static int output_min_count(struct iris_inst *inst)
552+{
553+ int output_min_count = 4;
554+
555+ /* fw_min_count > 0 indicates reconfig event has already arrived */
556+ if (inst->fw_min_count) {
557+ if (iris_split_mode_enabled(inst) && inst->codec == V4L2_PIX_FMT_VP9)
558+ return min_t(u32, 4, inst->fw_min_count);
559+ else
560+ return inst->fw_min_count;
561+ }
562+
563+ if (inst->codec == V4L2_PIX_FMT_VP9)
564+ output_min_count = 9;
565+
566+ return output_min_count;
567+}
568+
208569 struct iris_vpu_buf_type_handle {
209570 enum iris_buffer_type type;
210571 u32 (*handle)(struct iris_inst *inst);
@@ -238,6 +599,19 @@ int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) · 27 unmodified lines
238599 return size;
239600 }
240601
602+static u32 internal_buffer_count(struct iris_inst *inst,
603+ enum iris_buffer_type buffer_type)
604+{
605+ if (buffer_type == BUF_BIN || buffer_type == BUF_LINE ||
606+ buffer_type == BUF_PERSIST) {
607+ return 1;
608+ } else if (buffer_type == BUF_COMV || buffer_type == BUF_NON_COMV) {
609+ if (inst->codec == V4L2_PIX_FMT_H264 || inst->codec == V4L2_PIX_FMT_HEVC)
610+ return 1;
611+ }
612+ return 0;
613+}
614+
241615 static inline int iris_vpu_dpb_count(struct iris_inst *inst)
242616 {
243617 if (iris_split_mode_enabled(inst)) {
@@ -254,12 +628,13 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type · 10 unmodified lines
254628 case BUF_INPUT:
255629 return MIN_BUFFERS;
256630 case BUF_OUTPUT:
257− return inst->fw_min_count;
631+ return output_min_count(inst);
258632 case BUF_BIN:
259633 case BUF_COMV:
260634 case BUF_NON_COMV:
261635 case BUF_LINE:
262636 case BUF_PERSIST:
637+ return internal_buffer_count(inst, buffer_type);
263638 case BUF_SCRATCH_1:
264639 return 1; /* internal buffer count needed by firmware is 1 */
265640 case BUF_DPB:
drivers/media/platform/qcom/iris/iris_vpu_buffer.h+43−3
@@ -13,6 +13,10 @@ struct iris_inst; · 12 unmodified lines
1313 #define DMA_ALIGNMENT 256
1414
1515 #define NUM_HW_PIC_BUF 32
16+#define LCU_MAX_SIZE_PELS 64
17+#define LCU_MIN_SIZE_PELS 16
18+#define HDR10_HIST_EXTRADATA_SIZE (4 * 1024)
19+
1620 #define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf))
1721
1822 #define MAX_TILE_COLUMNS 32
@@ -28,11 +32,47 @@ struct iris_inst; · 9 unmodified lines
2832 #define SIZE_SLIST_BUF_H264 512
2933 #define H264_DISPLAY_BUF_SIZE 3328
3034 #define H264_NUM_FRM_INFO 66
31−
32−#define SIZE_SEI_USERDATA 4096
33−
35+#define H265_NUM_TILE_COL 32
36+#define H265_NUM_TILE_ROW 128
37+#define H265_NUM_TILE (H265_NUM_TILE_ROW * H265_NUM_TILE_COL + 1)
38+#define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32))
39+
40+#define NUM_SLIST_BUF_H265 (80 + 20)
41+#define SIZE_SLIST_BUF_H265 (BIT(10))
42+#define H265_DISPLAY_BUF_SIZE (3072)
43+#define H265_NUM_FRM_INFO (48)
44+
45+#define VP9_NUM_FRAME_INFO_BUF 32
46+#define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4)
47+#define VP9_PROB_TABLE_SIZE (3840)
48+#define VP9_FRAME_INFO_BUF_SIZE (6144)
49+#define BUFFER_ALIGNMENT_32_BYTES 32
50+#define CCE_TILE_OFFSET_SIZE ALIGN(32 * 4 * 4, BUFFER_ALIGNMENT_32_BYTES)
51+#define MAX_SUPERFRAME_HEADER_LEN (34)
52+#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64
53+#define MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE 64
54+#define MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE 64
55+#define MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE (128 / 8)
56+#define MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE (128 / 8)
57+#define VP9_UDC_HEADER_BUF_SIZE (3 * 128)
58+
59+#define SIZE_SEI_USERDATA 4096
60+#define SIZE_DOLBY_RPU_METADATA (41 * 1024)
3461 #define H264_CABAC_HDR_RATIO_HD_TOT 1
3562 #define H264_CABAC_RES_RATIO_HD_TOT 3
63+#define H265D_MAX_SLICE 1200
64+#define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T
65+#define H265_CABAC_HDR_RATIO_HD_TOT 2
66+#define H265_CABAC_RES_RATIO_HD_TOT 2
67+#define SIZE_H265D_VPP_CMD_PER_BUF (256)
68+
69+#define VPX_DECODER_FRAME_CONCURENCY_LVL (2)
70+#define VPX_DECODER_FRAME_BIN_HDR_BUDGET 1
71+#define VPX_DECODER_FRAME_BIN_RES_BUDGET 3
72+#define VPX_DECODER_FRAME_BIN_DENOMINATOR 2
73+
74+#define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO (3 / 2)
75+
3676 #define SIZE_H264D_HW_PIC_T (BIT(11))
3777
3878 #define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64
drivers/media/platform/qcom/venus/core.c+9−9
@@ -424,13 +424,13 @@ static int venus_probe(struct platform_device *pdev) · 423 unmodified lines
424424 INIT_DELAYED_WORK(&core->work, venus_sys_error_handler);
425425 init_waitqueue_head(&core->sys_err_done);
426426
427− ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, venus_isr_thread,
428− IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
429− "venus", core);
427+ ret = hfi_create(core, &venus_core_ops);
430428 if (ret)
431429 goto err_core_put;
432430
433− ret = hfi_create(core, &venus_core_ops);
431+ ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, venus_isr_thread,
432+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
433+ "venus", core);
434434 if (ret)
435435 goto err_core_put;
436436
@@ -709,11 +709,11 @@ static const struct venus_resources msm8996_res = { · 272 unmodified lines
709709 };
710710
711711 static const struct freq_tbl msm8998_freq_table[] = {
712− { 1944000, 465000000 }, /* 4k UHD @ 60 (decode only) */
713− { 972000, 465000000 }, /* 4k UHD @ 30 */
714− { 489600, 360000000 }, /* 1080p @ 60 */
715− { 244800, 186000000 }, /* 1080p @ 30 */
716− { 108000, 100000000 }, /* 720p @ 30 */
712+ { 1728000, 533000000 }, /* 4k UHD @ 60 (decode only) */
713+ { 1036800, 444000000 }, /* 2k @ 120 */
714+ { 829440, 355200000 }, /* 4k @ 44 */
715+ { 489600, 269330000 },/* 4k @ 30 */
716+ { 108000, 200000000 }, /* 1080p @ 60 */
717717 };
718718
719719 static const struct reg_val msm8998_reg_preset[] = {
drivers/media/platform/qcom/venus/core.h+2−0
@@ -28,6 +28,8 @@ · 27 unmodified lines
2828 #define VIDC_RESETS_NUM_MAX 2
2929 #define VIDC_MAX_HIER_CODING_LAYER 6
3030
31+#define VENUS_MAX_FPS 240
32+
3133 extern int venus_fw_debug;
3234
3335 struct freq_tbl {
drivers/media/platform/qcom/venus/hfi_msgs.c+58−25
@@ -33,8 +33,9 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, · 32 unmodified lines
3333 struct hfi_buffer_requirements *bufreq;
3434 struct hfi_extradata_input_crop *crop;
3535 struct hfi_dpb_counts *dpb_count;
36+ u32 ptype, rem_bytes;
37+ u32 size_read = 0;
3638 u8 *data_ptr;
37− u32 ptype;
3839
3940 inst->error = HFI_ERR_NONE;
4041
@@ -44,86 +45,118 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, · 3 unmodified lines
4445 break;
4546 default:
4647 inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;
47− goto done;
48+ inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
49+ return;
4850 }
4951
5052 event.event_type = pkt->event_data1;
5153
5254 num_properties_changed = pkt->event_data2;
53− if (!num_properties_changed) {
54− inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
55− goto done;
56− }
55+ if (!num_properties_changed)
56+ goto error;
5757
5858 data_ptr = (u8 *)&pkt->ext_event_data[0];
59+ rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
60+
5961 do {
62+ if (rem_bytes < sizeof(u32))
63+ goto error;
6064 ptype = *((u32 *)data_ptr);
65+
66+ data_ptr += sizeof(u32);
67+ rem_bytes -= sizeof(u32);
68+
6169 switch (ptype) {
6270 case HFI_PROPERTY_PARAM_FRAME_SIZE:
63− data_ptr += sizeof(u32);
71+ if (rem_bytes < sizeof(struct hfi_framesize))
72+ goto error;
73+
6474 frame_sz = (struct hfi_framesize *)data_ptr;
6575 event.width = frame_sz->width;
6676 event.height = frame_sz->height;
67− data_ptr += sizeof(*frame_sz);
77+ size_read = sizeof(struct hfi_framesize);
6878 break;
6979 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
70− data_ptr += sizeof(u32);
80+ if (rem_bytes < sizeof(struct hfi_profile_level))
81+ goto error;
82+
7183 profile_level = (struct hfi_profile_level *)data_ptr;
7284 event.profile = profile_level->profile;
7385 event.level = profile_level->level;
74− data_ptr += sizeof(*profile_level);
86+ size_read = sizeof(struct hfi_profile_level);
7587 break;
7688 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
77− data_ptr += sizeof(u32);
89+ if (rem_bytes < sizeof(struct hfi_bit_depth))
90+ goto error;
91+
7892 pixel_depth = (struct hfi_bit_depth *)data_ptr;
7993 event.bit_depth = pixel_depth->bit_depth;
80− data_ptr += sizeof(*pixel_depth);
94+ size_read = sizeof(struct hfi_bit_depth);
8195 break;
8296 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
83− data_ptr += sizeof(u32);
97+ if (rem_bytes < sizeof(struct hfi_pic_struct))
98+ goto error;
99+
84100 pic_struct = (struct hfi_pic_struct *)data_ptr;
85101 event.pic_struct = pic_struct->progressive_only;
86− data_ptr += sizeof(*pic_struct);
102+ size_read = sizeof(struct hfi_pic_struct);
87103 break;
88104 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
89− data_ptr += sizeof(u32);
105+ if (rem_bytes < sizeof(struct hfi_colour_space))
106+ goto error;
107+
90108 colour_info = (struct hfi_colour_space *)data_ptr;
91109 event.colour_space = colour_info->colour_space;
92− data_ptr += sizeof(*colour_info);
110+ size_read = sizeof(struct hfi_colour_space);
93111 break;
94112 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
95− data_ptr += sizeof(u32);
113+ if (rem_bytes < sizeof(u32))
114+ goto error;
115+
96116 event.entropy_mode = *(u32 *)data_ptr;
97− data_ptr += sizeof(u32);
117+ size_read = sizeof(u32);
98118 break;
99119 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
100− data_ptr += sizeof(u32);
120+ if (rem_bytes < sizeof(struct hfi_buffer_requirements))
121+ goto error;
122+
101123 bufreq = (struct hfi_buffer_requirements *)data_ptr;
102124 event.buf_count = hfi_bufreq_get_count_min(bufreq, ver);
103− data_ptr += sizeof(*bufreq);
125+ size_read = sizeof(struct hfi_buffer_requirements);
104126 break;
105127 case HFI_INDEX_EXTRADATA_INPUT_CROP:
106− data_ptr += sizeof(u32);
128+ if (rem_bytes < sizeof(struct hfi_extradata_input_crop))
129+ goto error;
130+
107131 crop = (struct hfi_extradata_input_crop *)data_ptr;
108132 event.input_crop.left = crop->left;
109133 event.input_crop.top = crop->top;
110134 event.input_crop.width = crop->width;
111135 event.input_crop.height = crop->height;
112− data_ptr += sizeof(*crop);
136+ size_read = sizeof(struct hfi_extradata_input_crop);
113137 break;
114138 case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
115− data_ptr += sizeof(u32);
139+ if (rem_bytes < sizeof(struct hfi_dpb_counts))
140+ goto error;
141+
116142 dpb_count = (struct hfi_dpb_counts *)data_ptr;
117143 event.buf_count = dpb_count->fw_min_cnt;
118− data_ptr += sizeof(*dpb_count);
144+ size_read = sizeof(struct hfi_dpb_counts);
119145 break;
120146 default:
147+ size_read = 0;
121148 break;
122149 }
150+ data_ptr += size_read;
151+ rem_bytes -= size_read;
123152 num_properties_changed--;
124153 } while (num_properties_changed > 0);
125154
126−done:
155+ inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
156+ return;
157+
158+error:
159+ inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
127160 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
128161 }
129162
drivers/media/platform/qcom/venus/hfi_venus.c+5−0
@@ -239,6 +239,7 @@ static int venus_write_queue(struct venus_hfi_device *hdev, · 238 unmodified lines
239239 static int venus_read_queue(struct venus_hfi_device *hdev,
240240 struct iface_queue *queue, void *pkt, u32 *tx_req)
241241 {
242+ struct hfi_pkt_hdr *pkt_hdr = NULL;
242243 struct hfi_queue_header *qhdr;
243244 u32 dwords, new_rd_idx;
244245 u32 rd_idx, wr_idx, type, qsize;
@@ -304,6 +305,9 @@ static int venus_read_queue(struct venus_hfi_device *hdev, · 59 unmodified lines
304305 memcpy(pkt, rd_ptr, len);
305306 memcpy(pkt + len, queue->qmem.kva, new_rd_idx << 2);
306307 }
308+ pkt_hdr = (struct hfi_pkt_hdr *)(pkt);
309+ if ((pkt_hdr->size >> 2) != dwords)
310+ return -EINVAL;
307311 } else {
308312 /* bad packet received, dropping */
309313 new_rd_idx = qhdr->write_idx;
@@ -1678,6 +1682,7 @@ void venus_hfi_destroy(struct venus_core *core) · 1368 unmodified lines
16781682 venus_interface_queues_release(hdev);
16791683 mutex_destroy(&hdev->lock);
16801684 kfree(hdev);
1685+ disable_irq(core->irq);
16811686 core->ops = NULL;
16821687 }
16831688
drivers/media/platform/qcom/venus/pm_helpers.c+34−24
@@ -41,16 +41,14 @@ static int core_clks_get(struct venus_core *core) · 40 unmodified lines
4141 static int core_clks_enable(struct venus_core *core)
4242 {
4343 const struct venus_resources *res = core->res;
44− const struct freq_tbl *freq_tbl = core->res->freq_tbl;
45− unsigned int freq_tbl_size = core->res->freq_tbl_size;
46− unsigned long freq;
44+ struct device *dev = core->dev;
45+ unsigned long freq = 0;
46+ struct dev_pm_opp *opp;
4747 unsigned int i;
4848 int ret;
4949
50− if (!freq_tbl)
51− return -EINVAL;
52−
53− freq = freq_tbl[freq_tbl_size - 1].freq;
50+ opp = dev_pm_opp_find_freq_ceil(dev, &freq);
51+ dev_pm_opp_put(opp);
5452
5553 for (i = 0; i < res->clks_num; i++) {
5654 if (IS_V6(core)) {
@@ -636,7 +634,9 @@ static int decide_core(struct venus_inst *inst) · 579 unmodified lines
636634 u32 min_coreid, min_load, cur_inst_load;
637635 u32 min_lp_coreid, min_lp_load, cur_inst_lp_load;
638636 struct hfi_videocores_usage_type cu;
639− unsigned long max_freq;
637+ unsigned long max_freq = ULONG_MAX;
638+ struct device *dev = core->dev;
639+ struct dev_pm_opp *opp;
640640 int ret = 0;
641641
642642 if (legacy_binding) {
@@ -659,7 +659,8 @@ static int decide_core(struct venus_inst *inst) · 16 unmodified lines
659659 cur_inst_lp_load *= inst->clk_data.low_power_freq;
660660 /*TODO : divide this inst->load by work_route */
661661
662− max_freq = core->res->freq_tbl[0].freq;
662+ opp = dev_pm_opp_find_freq_floor(dev, &max_freq);
663+ dev_pm_opp_put(opp);
663664
664665 min_loaded_core(inst, &min_coreid, &min_load, false);
665666 min_loaded_core(inst, &min_lp_coreid, &min_lp_load, true);
@@ -949,7 +950,10 @@ static int core_resets_get(struct venus_core *core) · 283 unmodified lines
949950 static int core_get_v4(struct venus_core *core)
950951 {
951952 struct device *dev = core->dev;
953+ const struct freq_tbl *freq_tbl = core->res->freq_tbl;
954+ unsigned int num_rows = core->res->freq_tbl_size;
952955 const struct venus_resources *res = core->res;
956+ unsigned int i;
953957 int ret;
954958
955959 ret = core_clks_get(core);
@@ -986,9 +990,17 @@ static int core_get_v4(struct venus_core *core) · 30 unmodified lines
986990
987991 if (core->res->opp_pmdomain) {
988992 ret = devm_pm_opp_of_add_table(dev);
989− if (ret && ret != -ENODEV) {
990− dev_err(dev, "invalid OPP table in device tree\n");
991− return ret;
993+ if (ret) {
994+ if (ret == -ENODEV) {
995+ for (i = 0; i < num_rows; i++) {
996+ ret = dev_pm_opp_add(dev, freq_tbl[i].freq, 0);
997+ if (ret)
998+ return ret;
999+ }
1000+ } else {
1001+ dev_err(dev, "invalid OPP table in device tree\n");
1002+ return ret;
1003+ }
9921004 }
9931005 }
9941006
@@ -1078,11 +1090,11 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst, · 83 unmodified lines
10781090 static int load_scale_v4(struct venus_inst *inst)
10791091 {
10801092 struct venus_core *core = inst->core;
1081− const struct freq_tbl *table = core->res->freq_tbl;
1082− unsigned int num_rows = core->res->freq_tbl_size;
10831093 struct device *dev = core->dev;
10841094 unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
1095+ unsigned long max_freq = ULONG_MAX;
10851096 unsigned long filled_len = 0;
1097+ struct dev_pm_opp *opp;
10861098 int i, ret = 0;
10871099
10881100 for (i = 0; i < inst->num_input_bufs; i++)
@@ -1108,20 +1120,18 @@ static int load_scale_v4(struct venus_inst *inst) · 19 unmodified lines
11081120
11091121 freq = max(freq_core1, freq_core2);
11101122
1111− if (freq > table[0].freq) {
1112− dev_dbg(dev, VDBGL "requested clock rate: %lu scaling clock rate : %lu\n",
1113− freq, table[0].freq);
1123+ opp = dev_pm_opp_find_freq_floor(dev, &max_freq);
1124+ dev_pm_opp_put(opp);
11141125
1115− freq = table[0].freq;
1126+ if (freq > max_freq) {
1127+ dev_dbg(dev, VDBGL "requested clock rate: %lu scaling clock rate : %lu\n",
1128+ freq, max_freq);
1129+ freq = max_freq;
11161130 goto set_freq;
11171131 }
11181132
1119− for (i = num_rows - 1 ; i >= 0; i--) {
1120− if (freq <= table[i].freq) {
1121− freq = table[i].freq;
1122− break;
1123− }
1124− }
1133+ opp = dev_pm_opp_find_freq_ceil(dev, &freq);
1134+ dev_pm_opp_put(opp);
11251135
11261136 set_freq:
11271137
drivers/media/platform/qcom/venus/vdec.c+3−5
@@ -481,11 +481,9 @@ static int vdec_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) · 480 unmodified lines
481481 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
482482 do_div(us_per_frame, timeperframe->denominator);
483483
484− if (!us_per_frame)
485− return -EINVAL;
486−
487− fps = (u64)USEC_PER_SEC;
488− do_div(fps, us_per_frame);
484+ us_per_frame = clamp(us_per_frame, 1, USEC_PER_SEC);
485+ fps = USEC_PER_SEC / (u32)us_per_frame;
486+ fps = min(VENUS_MAX_FPS, fps);
489487
490488 inst->fps = fps;
491489 inst->timeperframe = *timeperframe;
drivers/media/platform/qcom/venus/venc.c+3−5
@@ -411,11 +411,9 @@ static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) · 410 unmodified lines
411411 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
412412 do_div(us_per_frame, timeperframe->denominator);
413413
414− if (!us_per_frame)
415− return -EINVAL;
416−
417− fps = (u64)USEC_PER_SEC;
418− do_div(fps, us_per_frame);
414+ us_per_frame = clamp(us_per_frame, 1, USEC_PER_SEC);
415+ fps = USEC_PER_SEC / (u32)us_per_frame;
416+ fps = min(VENUS_MAX_FPS, fps);
419417
420418 inst->timeperframe = *timeperframe;
421419 inst->fps = fps;
drivers/media/platform/raspberrypi/pisp_be/Kconfig+1−0
@@ -3,6 +3,7 @@ config VIDEO_RASPBERRYPI_PISP_BE · 2 unmodified lines
33 depends on V4L_PLATFORM_DRIVERS
44 depends on VIDEO_DEV
55 depends on ARCH_BCM2835 || COMPILE_TEST
6+ depends on PM
67 select VIDEO_V4L2_SUBDEV_API
78 select MEDIA_CONTROLLER
89 select VIDEOBUF2_DMA_CONTIG
drivers/media/platform/raspberrypi/pisp_be/pisp_be.c+104−103
@@ -9,9 +9,11 @@ · 8 unmodified lines
99 #include <linux/io.h>
1010 #include <linux/kernel.h>
1111 #include <linux/lockdep.h>
12+#include <linux/minmax.h>
1213 #include <linux/module.h>
1314 #include <linux/platform_device.h>
1415 #include <linux/pm_runtime.h>
16+#include <linux/slab.h>
1517 #include <media/v4l2-device.h>
1618 #include <media/v4l2-ioctl.h>
1719 #include <media/videobuf2-dma-contig.h>
@@ -161,8 +163,6 @@ struct pispbe_node { · 143 unmodified lines
161163 struct mutex node_lock;
162164 /* vb2_queue lock */
163165 struct mutex queue_lock;
164− /* Protect pispbe_node->ready_queue and pispbe_buffer->ready_list */
165− spinlock_t ready_lock;
166166 struct list_head ready_queue;
167167 struct vb2_queue queue;
168168 struct v4l2_format format;
@@ -190,6 +190,8 @@ struct pispbe_hw_enables { · 21 unmodified lines
190190
191191 /* Records a job configuration and memory addresses. */
192192 struct pispbe_job_descriptor {
193+ struct list_head queue;
194+ struct pispbe_buffer *buffers[PISPBE_NUM_NODES];
193195 dma_addr_t hw_dma_addrs[N_HW_ADDRESSES];
194196 struct pisp_be_tiles_config *config;
195197 struct pispbe_hw_enables hw_enables;
@@ -215,8 +217,10 @@ struct pispbe_dev { · 19 unmodified lines
215217 unsigned int sequence;
216218 u32 streaming_map;
217219 struct pispbe_job queued_job, running_job;
218− spinlock_t hw_lock; /* protects "hw_busy" flag and streaming_map */
220+ /* protects "hw_busy" flag, streaming_map and job_queue */
221+ spinlock_t hw_lock;
219222 bool hw_busy; /* non-zero if a job is queued or is being started */
223+ struct list_head job_queue;
220224 int irq;
221225 u32 hw_version;
222226 u8 done, started;
@@ -368,10 +372,7 @@ static void pispbe_xlate_addrs(struct pispbe_dev *pispbe, · 145 unmodified lines
368372 ret = pispbe_get_planes_addr(addrs, buf[MAIN_INPUT_NODE],
369373 &pispbe->node[MAIN_INPUT_NODE]);
370374 if (ret <= 0) {
371− /*
372− * This shouldn't happen; pispbe_schedule_internal should insist
373− * on an input.
374− */
375+ /* Shouldn't happen, we have validated an input is available. */
375376 dev_warn(pispbe->dev, "ISP-BE missing input\n");
376377 hw_en->bayer_enables = 0;
377378 hw_en->rgb_enables = 0;
@@ -443,42 +444,48 @@ static void pispbe_xlate_addrs(struct pispbe_dev *pispbe, · 65 unmodified lines
443444 * For Output0, Output1, Tdn and Stitch, a buffer only needs to be
444445 * available if the blocks are enabled in the config.
445446 *
446− * Needs to be called with hw_lock held.
447+ * If all the buffers required to form a job are available, append the
448+ * job descriptor to the job queue to be later queued to the HW.
447449 *
448450 * Returns 0 if a job has been successfully prepared, < 0 otherwise.
449451 */
450−static int pispbe_prepare_job(struct pispbe_dev *pispbe,
451− struct pispbe_job_descriptor *job)
452+static int pispbe_prepare_job(struct pispbe_dev *pispbe)
452453 {
454+ struct pispbe_job_descriptor __free(kfree) *job = NULL;
453455 struct pispbe_buffer *buf[PISPBE_NUM_NODES] = {};
456+ unsigned int streaming_map;
454457 unsigned int config_index;
455458 struct pispbe_node *node;
456− unsigned long flags;
457459
458− lockdep_assert_held(&pispbe->hw_lock);
460+ lockdep_assert_irqs_enabled();
459461
460− memset(job, 0, sizeof(struct pispbe_job_descriptor));
462+ scoped_guard(spinlock_irq, &pispbe->hw_lock) {
463+ static const u32 mask = BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE);
461464
462− if (((BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)) &
463− pispbe->streaming_map) !=
464− (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)))
465− return -ENODEV;
465+ if ((pispbe->streaming_map & mask) != mask)
466+ return -ENODEV;
467+
468+ /*
469+ * Take a copy of streaming_map: nodes activated after this
470+ * point are ignored when preparing this job.
471+ */
472+ streaming_map = pispbe->streaming_map;
473+ }
474+
475+ job = kzalloc(sizeof(*job), GFP_KERNEL);
476+ if (!job)
477+ return -ENOMEM;
466478
467479 node = &pispbe->node[CONFIG_NODE];
468− spin_lock_irqsave(&node->ready_lock, flags);
469480 buf[CONFIG_NODE] = list_first_entry_or_null(&node->ready_queue,
470481 struct pispbe_buffer,
471482 ready_list);
472− if (buf[CONFIG_NODE]) {
473− list_del(&buf[CONFIG_NODE]->ready_list);
474− pispbe->queued_job.buf[CONFIG_NODE] = buf[CONFIG_NODE];
475− }
476− spin_unlock_irqrestore(&node->ready_lock, flags);
477−
478− /* Exit early if no config buffer has been queued. */
479483 if (!buf[CONFIG_NODE])
480484 return -ENODEV;
481485
486+ list_del(&buf[CONFIG_NODE]->ready_list);
487+ job->buffers[CONFIG_NODE] = buf[CONFIG_NODE];
488+
482489 config_index = buf[CONFIG_NODE]->vb.vb2_buf.index;
483490 job->config = &pispbe->config[config_index];
484491 job->tiles = pispbe->config_dma_addr +
@@ -498,7 +505,7 @@ static int pispbe_prepare_job(struct pispbe_dev *pispbe, · 13 unmodified lines
498505 continue;
499506
500507 buf[i] = NULL;
501− if (!(pispbe->streaming_map & BIT(i)))
508+ if (!(streaming_map & BIT(i)))
502509 continue;
503510
504511 if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0) &&
@@ -525,25 +532,28 @@ static int pispbe_prepare_job(struct pispbe_dev *pispbe, · 20 unmodified lines
525532 node = &pispbe->node[i];
526533
527534 /* Pull a buffer from each V4L2 queue to form the queued job */
528− spin_lock_irqsave(&node->ready_lock, flags);
529535 buf[i] = list_first_entry_or_null(&node->ready_queue,
530536 struct pispbe_buffer,
531537 ready_list);
532538 if (buf[i]) {
533539 list_del(&buf[i]->ready_list);
534− pispbe->queued_job.buf[i] = buf[i];
540+ job->buffers[i] = buf[i];
535541 }
536− spin_unlock_irqrestore(&node->ready_lock, flags);
537542
538543 if (!buf[i] && !ignore_buffers)
539544 goto err_return_buffers;
540545 }
541546
542− pispbe->queued_job.valid = true;
543−
544547 /* Convert buffers to DMA addresses for the hardware */
545548 pispbe_xlate_addrs(pispbe, job, buf);
546549
550+ scoped_guard(spinlock_irq, &pispbe->hw_lock) {
551+ list_add_tail(&job->queue, &pispbe->job_queue);
552+ }
553+
554+ /* Set job to NULL to avoid automatic release due to __free(). */
555+ job = NULL;
556+
547557 return 0;
548558
549559 err_return_buffers:
@@ -554,33 +564,37 @@ err_return_buffers: · 4 unmodified lines
554564 continue;
555565
556566 /* Return the buffer to the ready_list queue */
557− spin_lock_irqsave(&n->ready_lock, flags);
558567 list_add(&buf[i]->ready_list, &n->ready_queue);
559− spin_unlock_irqrestore(&n->ready_lock, flags);
560568 }
561569
562− memset(&pispbe->queued_job, 0, sizeof(pispbe->queued_job));
563−
564570 return -ENODEV;
565571 }
566572
567573 static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy)
568574 {
569− struct pispbe_job_descriptor job;
570− unsigned long flags;
571− int ret;
575+ struct pispbe_job_descriptor *job;
572576
573− spin_lock_irqsave(&pispbe->hw_lock, flags);
577+ scoped_guard(spinlock_irqsave, &pispbe->hw_lock) {
578+ if (clear_hw_busy)
579+ pispbe->hw_busy = false;
574580
575− if (clear_hw_busy)
576− pispbe->hw_busy = false;
581+ if (pispbe->hw_busy)
582+ return;
577583
578− if (pispbe->hw_busy)
579− goto unlock_and_return;
584+ job = list_first_entry_or_null(&pispbe->job_queue,
585+ struct pispbe_job_descriptor,
586+ queue);
587+ if (!job)
588+ return;
580589
581− ret = pispbe_prepare_job(pispbe, &job);
582− if (ret)
583− goto unlock_and_return;
590+ list_del(&job->queue);
591+
592+ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++)
593+ pispbe->queued_job.buf[i] = job->buffers[i];
594+ pispbe->queued_job.valid = true;
595+
596+ pispbe->hw_busy = true;
597+ }
584598
585599 /*
586600 * We can kick the job off without the hw_lock, as this can
@@ -588,34 +602,8 @@ static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy) · 1 unmodified line
588602 * only when the following job has been queued and an interrupt
589603 * is rised.
590604 */
591− pispbe->hw_busy = true;
592− spin_unlock_irqrestore(&pispbe->hw_lock, flags);
593−
594− if (job.config->num_tiles <= 0 ||
595− job.config->num_tiles > PISP_BACK_END_NUM_TILES ||
596− !((job.hw_enables.bayer_enables | job.hw_enables.rgb_enables) &
597− PISP_BE_BAYER_ENABLE_INPUT)) {
598− /*
599− * Bad job. We can't let it proceed as it could lock up
600− * the hardware, or worse!
601− *
602− * For now, just force num_tiles to 0, which causes the
603− * H/W to do something bizarre but survivable. It
604− * increments (started,done) counters by more than 1,
605− * but we seem to survive...
606− */
607− dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n",
608− job.config->num_tiles);
609− job.config->num_tiles = 0;
610− }
611−
612− pispbe_queue_job(pispbe, &job);
613−
614− return;
615−
616−unlock_and_return:
617− /* No job has been queued, just release the lock and return. */
618− spin_unlock_irqrestore(&pispbe->hw_lock, flags);
605+ pispbe_queue_job(pispbe, job);
606+ kfree(job);
619607 }
620608
621609 static void pispbe_isr_jobdone(struct pispbe_dev *pispbe,
@@ -706,6 +694,13 @@ static int pisp_be_validate_config(struct pispbe_dev *pispbe, · 84 unmodified lines
706694 return -EIO;
707695 }
708696
697+ if (config->num_tiles == 0 ||
698+ config->num_tiles > PISP_BACK_END_NUM_TILES) {
699+ dev_dbg(dev, "%s: Invalid number of tiles: %d\n", __func__,
700+ config->num_tiles);
701+ return -EINVAL;
702+ }
703+
709704 /* Ensure output config strides and buffer sizes match the V4L2 formats. */
710705 fmt = &pispbe->node[TDN_OUTPUT_NODE].format;
711706 if (bayer_enables & PISP_BE_BAYER_ENABLE_TDN_OUTPUT) {
@@ -860,18 +855,16 @@ static void pispbe_node_buffer_queue(struct vb2_buffer *buf) · 148 unmodified lines
860855 container_of(vbuf, struct pispbe_buffer, vb);
861856 struct pispbe_node *node = vb2_get_drv_priv(buf->vb2_queue);
862857 struct pispbe_dev *pispbe = node->pispbe;
863− unsigned long flags;
864858
865859 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
866− spin_lock_irqsave(&node->ready_lock, flags);
867860 list_add_tail(&buffer->ready_list, &node->ready_queue);
868− spin_unlock_irqrestore(&node->ready_lock, flags);
869861
870862 /*
871863 * Every time we add a buffer, check if there's now some work for the hw
872864 * to do.
873865 */
874− pispbe_schedule(pispbe, false);
866+ if (!pispbe_prepare_job(pispbe))
867+ pispbe_schedule(pispbe, false);
875868 }
876869
877870 static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count)
@@ -879,17 +872,16 @@ static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count) · 1 unmodified line
879872 struct pispbe_node *node = vb2_get_drv_priv(q);
880873 struct pispbe_dev *pispbe = node->pispbe;
881874 struct pispbe_buffer *buf, *tmp;
882− unsigned long flags;
883875 int ret;
884876
885877 ret = pm_runtime_resume_and_get(pispbe->dev);
886878 if (ret < 0)
887879 goto err_return_buffers;
888880
889− spin_lock_irqsave(&pispbe->hw_lock, flags);
890− node->pispbe->streaming_map |= BIT(node->id);
891− node->pispbe->sequence = 0;
892− spin_unlock_irqrestore(&pispbe->hw_lock, flags);
881+ scoped_guard(spinlock_irq, &pispbe->hw_lock) {
882+ node->pispbe->streaming_map |= BIT(node->id);
883+ node->pispbe->sequence = 0;
884+ }
893885
894886 dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n",
895887 __func__, NODE_NAME(node), count);
@@ -897,17 +889,16 @@ static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count) · 1 unmodified line
897889 node->pispbe->streaming_map);
898890
899891 /* Maybe we're ready to run. */
900− pispbe_schedule(pispbe, false);
892+ if (!pispbe_prepare_job(pispbe))
893+ pispbe_schedule(pispbe, false);
901894
902895 return 0;
903896
904897 err_return_buffers:
905− spin_lock_irqsave(&pispbe->hw_lock, flags);
906898 list_for_each_entry_safe(buf, tmp, &node->ready_queue, ready_list) {
907899 list_del(&buf->ready_list);
908900 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
909901 }
910− spin_unlock_irqrestore(&pispbe->hw_lock, flags);
911902
912903 return ret;
913904 }
@@ -916,8 +907,9 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q) · 2 unmodified lines
916907 {
917908 struct pispbe_node *node = vb2_get_drv_priv(q);
918909 struct pispbe_dev *pispbe = node->pispbe;
910+ struct pispbe_job_descriptor *job, *temp;
919911 struct pispbe_buffer *buf;
920− unsigned long flags;
912+ LIST_HEAD(tmp_list);
921913
922914 /*
923915 * Now this is a bit awkward. In a simple M2M device we could just wait
@@ -929,11 +921,7 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q) · 5 unmodified lines
929921 * This may return buffers out of order.
930922 */
931923 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
932− spin_lock_irqsave(&pispbe->hw_lock, flags);
933924 do {
934− unsigned long flags1;
935−
936− spin_lock_irqsave(&node->ready_lock, flags1);
937925 buf = list_first_entry_or_null(&node->ready_queue,
938926 struct pispbe_buffer,
939927 ready_list);
@@ -941,15 +929,26 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q) · 1 unmodified line
941929 list_del(&buf->ready_list);
942930 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
943931 }
944− spin_unlock_irqrestore(&node->ready_lock, flags1);
945932 } while (buf);
946− spin_unlock_irqrestore(&pispbe->hw_lock, flags);
947933
948934 vb2_wait_for_all_buffers(&node->queue);
949935
950− spin_lock_irqsave(&pispbe->hw_lock, flags);
936+ spin_lock_irq(&pispbe->hw_lock);
951937 pispbe->streaming_map &= ~BIT(node->id);
952− spin_unlock_irqrestore(&pispbe->hw_lock, flags);
938+
939+ if (pispbe->streaming_map == 0) {
940+ /*
941+ * If all nodes have stopped streaming release all jobs
942+ * without holding the lock.
943+ */
944+ list_splice_init(&pispbe->job_queue, &tmp_list);
945+ }
946+ spin_unlock_irq(&pispbe->hw_lock);
947+
948+ list_for_each_entry_safe(job, temp, &tmp_list, queue) {
949+ list_del(&job->queue);
950+ kfree(job);
951+ }
953952
954953 pm_runtime_mark_last_busy(pispbe->dev);
955954 pm_runtime_put_autosuspend(pispbe->dev);
@@ -1114,10 +1113,12 @@ static void pispbe_try_format(struct v4l2_format *f, struct pispbe_node *node) · 158 unmodified lines
11141113 f->fmt.pix_mp.pixelformat = fmt->fourcc;
11151114 f->fmt.pix_mp.num_planes = fmt->num_planes;
11161115 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
1117− f->fmt.pix_mp.width = max(min(f->fmt.pix_mp.width, 65536u),
1118− PISP_BACK_END_MIN_TILE_WIDTH);
1119− f->fmt.pix_mp.height = max(min(f->fmt.pix_mp.height, 65536u),
1120− PISP_BACK_END_MIN_TILE_HEIGHT);
1116+ f->fmt.pix_mp.width = clamp(f->fmt.pix_mp.width,
1117+ PISP_BACK_END_MIN_TILE_WIDTH,
1118+ PISP_BACK_END_MAX_TILE_WIDTH);
1119+ f->fmt.pix_mp.height = clamp(f->fmt.pix_mp.height,
1120+ PISP_BACK_END_MIN_TILE_HEIGHT,
1121+ PISP_BACK_END_MAX_TILE_HEIGHT);
11211122
11221123 /*
11231124 * Fill in the actual colour space when the requested one was
@@ -1407,7 +1408,6 @@ static int pispbe_init_node(struct pispbe_dev *pispbe, unsigned int id) · 283 unmodified lines
14071408 mutex_init(&node->node_lock);
14081409 mutex_init(&node->queue_lock);
14091410 INIT_LIST_HEAD(&node->ready_queue);
1410− spin_lock_init(&node->ready_lock);
14111411
14121412 node->format.type = node->buf_type;
14131413 pispbe_node_def_fmt(node);
@@ -1691,6 +1691,8 @@ static int pispbe_probe(struct platform_device *pdev) · 277 unmodified lines
16911691 if (!pispbe)
16921692 return -ENOMEM;
16931693
1694+ INIT_LIST_HEAD(&pispbe->job_queue);
1695+
16941696 dev_set_drvdata(&pdev->dev, pispbe);
16951697 pispbe->dev = &pdev->dev;
16961698 platform_set_drvdata(pdev, pispbe);
@@ -1726,7 +1728,7 @@ static int pispbe_probe(struct platform_device *pdev) · 29 unmodified lines
17261728 pm_runtime_use_autosuspend(pispbe->dev);
17271729 pm_runtime_enable(pispbe->dev);
17281730
1729− ret = pispbe_runtime_resume(pispbe->dev);
1731+ ret = pm_runtime_resume_and_get(pispbe->dev);
17301732 if (ret)
17311733 goto pm_runtime_disable_err;
17321734
@@ -1748,7 +1750,7 @@ static int pispbe_probe(struct platform_device *pdev) · 15 unmodified lines
17481750 disable_devs_err:
17491751 pispbe_destroy_devices(pispbe);
17501752 pm_runtime_suspend_err:
1751− pispbe_runtime_suspend(pispbe->dev);
1753+ pm_runtime_put(pispbe->dev);
17521754 pm_runtime_disable_err:
17531755 pm_runtime_dont_use_autosuspend(pispbe->dev);
17541756 pm_runtime_disable(pispbe->dev);
@@ -1762,7 +1764,6 @@ static void pispbe_remove(struct platform_device *pdev) · 7 unmodified lines
17621764
17631765 pispbe_destroy_devices(pispbe);
17641766
1765− pispbe_runtime_suspend(pispbe->dev);
17661767 pm_runtime_dont_use_autosuspend(pispbe->dev);
17671768 pm_runtime_disable(pispbe->dev);
17681769 }
drivers/media/platform/raspberrypi/rp1-cfe/cfe.c+1−3
@@ -1024,9 +1024,6 @@ static int cfe_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, · 1023 unmodified lines
10241024 cfe_dbg(cfe, "%s: [%s] type:%u\n", __func__, node_desc[node->id].name,
10251025 node->buffer_queue.type);
10261026
1027− if (vq->max_num_buffers + *nbuffers < 3)
1028− *nbuffers = 3 - vq->max_num_buffers;
1029−
10301027 if (*nplanes) {
10311028 if (sizes[0] < size) {
10321029 cfe_err(cfe, "sizes[0] %i < size %u\n", sizes[0], size);
@@ -1998,6 +1995,7 @@ static int cfe_register_node(struct cfe_device *cfe, int id) · 965 unmodified lines
19981995 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
19991996 q->lock = &node->lock;
20001997 q->min_queued_buffers = 1;
1998+ q->min_reqbufs_allocation = 3;
20011999 q->dev = &cfe->pdev->dev;
20022000
20032001 ret = vb2_queue_init(q);
drivers/media/platform/renesas/rcar-csi2.c+290−46
@@ -172,20 +172,27 @@ struct rcar_csi2; · 171 unmodified lines
172172 #define V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG 0x21c0a
173173 #define V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG 0x21c0c
174174 #define V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG 0x21c10
175+#define V4H_PPI_RW_DDLCAL_CFG_n_REG(n) (0x21c40 + ((n) * 2)) /* n = 0 - 7 */
175176 #define V4H_PPI_RW_COMMON_CFG_REG 0x21c6c
176177 #define V4H_PPI_RW_TERMCAL_CFG_0_REG 0x21c80
177178 #define V4H_PPI_RW_OFFSETCAL_CFG_0_REG 0x21ca0
178179
179180 /* V4H CORE registers */
180−#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(n) (0x22040 + ((n) * 2)) /* n = 0 - 15 */
181−#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(n) (0x22440 + ((n) * 2)) /* n = 0 - 15 */
182−#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(n) (0x22840 + ((n) * 2)) /* n = 0 - 15 */
183−#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(n) (0x22c40 + ((n) * 2)) /* n = 0 - 15 */
184−#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(n) (0x23040 + ((n) * 2)) /* n = 0 - 15 */
181+
182+#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, n) (0x22040 + ((l) * 0x400) + ((n) * 2))
183+#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_3_REG(l, n) (0x22060 + ((l) * 0x400) + ((n) * 2))
184+#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_4_REG(l, n) (0x22080 + ((l) * 0x400) + ((n) * 2))
185+
185186 #define V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(n) (0x23840 + ((n) * 2)) /* n = 0 - 11 */
186187 #define V4H_CORE_DIG_RW_COMMON_REG(n) (0x23880 + ((n) * 2)) /* n = 0 - 15 */
187188 #define V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(n) (0x239e0 + ((n) * 2)) /* n = 0 - 3 */
188−#define V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG 0x2a60c
189+#define V4H_CORE_DIG_COMMON_RW_DESKEW_FINE_MEM_REG 0x23fe0
190+
191+#define V4H_CORE_DIG_DLANE_l_RW_CFG_n_REG(l, n) (0x26000 + ((l) * 0x400) + ((n) * 2))
192+#define V4H_CORE_DIG_DLANE_l_RW_LP_n_REG(l, n) (0x26080 + ((l) * 0x400) + ((n) * 2))
193+#define V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, n) (0x26100 + ((l) * 0x400) + ((n) * 2))
194+#define V4H_CORE_DIG_DLANE_CLK_RW_LP_n_REG(n) V4H_CORE_DIG_DLANE_l_RW_LP_n_REG(4, (n))
195+#define V4H_CORE_DIG_DLANE_CLK_RW_HS_RX_n_REG(n) V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(4, (n))
189196
190197 /* V4H C-PHY */
191198 #define V4H_CORE_DIG_RW_TRIO0_REG(n) (0x22100 + ((n) * 2)) /* n = 0 - 3 */
@@ -197,6 +204,7 @@ struct rcar_csi2; · 5 unmodified lines
197204 #define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400
198205 #define V4H_CORE_DIG_CLANE_1_RW_LP_0_REG 0x2a480
199206 #define V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(n) (0x2a500 + ((n) * 2)) /* n = 0 - 6 */
207+#define V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG 0x2a60c
200208 #define V4H_CORE_DIG_CLANE_2_RW_CFG_0_REG 0x2a800
201209 #define V4H_CORE_DIG_CLANE_2_RW_LP_0_REG 0x2a880
202210 #define V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(n) (0x2a900 + ((n) * 2)) /* n = 0 - 6 */
@@ -954,6 +962,7 @@ static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps) · 751 unmodified lines
954962 static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp,
955963 unsigned int lanes)
956964 {
965+ struct media_pad *remote_pad;
957966 struct v4l2_subdev *source;
958967 s64 freq;
959968 u64 mbps;
@@ -962,8 +971,9 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, · 2 unmodified lines
962971 return -ENODEV;
963972
964973 source = priv->remote;
974+ remote_pad = &source->entity.pads[priv->remote_pad];
965975
966− freq = v4l2_get_link_freq(source->ctrl_handler, bpp, 2 * lanes);
976+ freq = v4l2_get_link_freq(remote_pad, bpp, 2 * lanes);
967977 if (freq < 0) {
968978 int ret = (int)freq;
969979
@@ -975,10 +985,6 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, · 5 unmodified lines
975985
976986 mbps = div_u64(freq * 2, MEGA);
977987
978− /* Adjust for C-PHY, divide by 2.8. */
979− if (priv->cphy)
980− mbps = div_u64(mbps * 5, 14);
981−
982988 return mbps;
983989 }
984990
@@ -1203,9 +1209,14 @@ static int rcsi2_wait_phy_start_v4h(struct rcar_csi2 *priv, u32 match) · 218 unmodified lines
12031209 return -ETIMEDOUT;
12041210 }
12051211
1206−static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps)
1212+static const struct rcsi2_cphy_setting *
1213+rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int mbps)
12071214 {
12081215 const struct rcsi2_cphy_setting *conf;
1216+ int msps;
1217+
1218+ /* Adjust for C-PHY symbols, divide by 2.8. */
1219+ msps = div_u64(mbps * 5, 14);
12091220
12101221 for (conf = cphy_setting_table_r8a779g0; conf->msps != 0; conf++) {
12111222 if (conf->msps > msps)
@@ -1214,7 +1225,7 @@ static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) · 2 unmodified lines
12141225
12151226 if (!conf->msps) {
12161227 dev_err(priv->dev, "Unsupported PHY speed for msps setting (%u Msps)", msps);
1217− return -ERANGE;
1228+ return NULL;
12181229 }
12191230
12201231 /* C-PHY specific */
@@ -1246,11 +1257,11 @@ static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) · 25 unmodified lines
12461257 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(2), conf->rx2);
12471258 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(2), conf->rx2);
12481259
1249− rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(2), 0x0001);
1250− rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(2), 0);
1251− rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(2), 0x0001);
1252− rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(2), 0x0001);
1253− rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(2), 0);
1260+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(0, 2), 0x0001);
1261+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(1, 2), 0);
1262+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(2, 2), 0x0001);
1263+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(3, 2), 0x0001);
1264+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(4, 2), 0);
12541265
12551266 rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(0), conf->trio0);
12561267 rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(0), conf->trio0);
@@ -1267,30 +1278,198 @@ static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) · 10 unmodified lines
12671278 /* Configure data line order. */
12681279 rsci2_set_line_order(priv, priv->line_orders[0],
12691280 V4H_CORE_DIG_CLANE_0_RW_CFG_0_REG,
1270− V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(9));
1281+ V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(0, 9));
12711282 rsci2_set_line_order(priv, priv->line_orders[1],
12721283 V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG,
1273− V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(9));
1284+ V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(1, 9));
12741285 rsci2_set_line_order(priv, priv->line_orders[2],
12751286 V4H_CORE_DIG_CLANE_2_RW_CFG_0_REG,
1276− V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(9));
1287+ V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(2, 9));
12771288
12781289 /* TODO: This registers is not documented. */
12791290 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG, 0x5000);
12801291
1281− /* Leave Shutdown mode */
1282− rcsi2_write(priv, V4H_DPHY_RSTZ_REG, BIT(0));
1283− rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, BIT(0));
1292+ return conf;
1293+}
12841294
1285− /* Wait for calibration */
1286− if (rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_PHY_READY)) {
1287− dev_err(priv->dev, "PHY calibration failed\n");
1288− return -ETIMEDOUT;
1295+struct rcsi2_d_phy_setting_v4h_lut_value {
1296+ unsigned int mbps;
1297+ unsigned char cfg_1;
1298+ unsigned char cfg_5_94;
1299+ unsigned char cfg_5_30;
1300+ unsigned char lane_ctrl_2_8;
1301+ unsigned char rw_hs_rx_3_83;
1302+ unsigned char rw_hs_rx_3_20;
1303+ unsigned char rw_hs_rx_6;
1304+ unsigned char rw_hs_rx_1;
1305+};
1306+
1307+static const struct rcsi2_d_phy_setting_v4h_lut_value *
1308+rcsi2_d_phy_setting_v4h_lut_lookup(int mbps)
1309+{
1310+ static const struct rcsi2_d_phy_setting_v4h_lut_value values[] = {
1311+ { 4500, 0x3f, 0x07, 0x00, 0x01, 0x02, 0x01, 0x0d, 0x10 },
1312+ { 4000, 0x47, 0x08, 0x01, 0x01, 0x05, 0x01, 0x0f, 0x0d },
1313+ { 3600, 0x4f, 0x09, 0x01, 0x01, 0x06, 0x01, 0x10, 0x0b },
1314+ { 3230, 0x57, 0x0a, 0x01, 0x01, 0x06, 0x01, 0x12, 0x09 },
1315+ { 3000, 0x47, 0x08, 0x00, 0x00, 0x03, 0x01, 0x0f, 0x0c },
1316+ { 2700, 0x4f, 0x09, 0x01, 0x00, 0x06, 0x01, 0x10, 0x0b },
1317+ { 2455, 0x57, 0x0a, 0x01, 0x00, 0x06, 0x01, 0x12, 0x09 },
1318+ { 2250, 0x5f, 0x0b, 0x01, 0x00, 0x08, 0x01, 0x13, 0x08 },
1319+ { 2077, 0x67, 0x0c, 0x01, 0x00, 0x06, 0x02, 0x15, 0x0d },
1320+ { 1929, 0x6f, 0x0d, 0x02, 0x00, 0x06, 0x02, 0x17, 0x0d },
1321+ { 1800, 0x77, 0x0e, 0x02, 0x00, 0x06, 0x02, 0x18, 0x0d },
1322+ { 1688, 0x7f, 0x0f, 0x02, 0x00, 0x08, 0x02, 0x1a, 0x0d },
1323+ { 1588, 0x87, 0x10, 0x02, 0x00, 0x08, 0x02, 0x1b, 0x0d },
1324+ { 1500, 0x8f, 0x11, 0x03, 0x00, 0x08, 0x02, 0x1d, 0x0c },
1325+ };
1326+
1327+ for (unsigned int i = 0; i < ARRAY_SIZE(values); i++)
1328+ if (mbps >= values[i].mbps)
1329+ return &values[i];
1330+
1331+ return NULL;
1332+}
1333+
1334+static int rcsi2_d_phy_setting_v4h(struct rcar_csi2 *priv, int mbps)
1335+{
1336+ const struct rcsi2_d_phy_setting_v4h_lut_value *lut =
1337+ rcsi2_d_phy_setting_v4h_lut_lookup(mbps);
1338+ u16 val;
1339+
1340+ rcsi2_write16(priv, V4H_CORE_DIG_RW_COMMON_REG(7), 0x0000);
1341+ rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(7), mbps > 1500 ? 0x0028 : 0x0068);
1342+ rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(8), 0x0050);
1343+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(0), 0x0063);
1344+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(7), 0x1132);
1345+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(1), 0x1340);
1346+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(2), 0x4b13);
1347+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(4), 0x000a);
1348+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(6), 0x800a);
1349+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(7), 0x1109);
1350+
1351+ if (mbps > 1500) {
1352+ val = DIV_ROUND_UP(5 * mbps, 64);
1353+ rcsi2_write16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(3), val);
1354+ }
1355+
1356+ if (lut) {
1357+ rcsi2_modify16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(1),
1358+ lut->cfg_1, 0x00ff);
1359+ rcsi2_modify16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(5),
1360+ lut->cfg_5_94 << 4, 0x03f0);
1361+ rcsi2_modify16(priv, V4H_PPI_RW_DDLCAL_CFG_n_REG(5),
1362+ lut->cfg_5_30 << 0, 0x000f);
1363+
1364+ for (unsigned int l = 0; l < 5; l++)
1365+ rcsi2_modify16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, 8),
1366+ lut->lane_ctrl_2_8 << 12, 0x1000);
1367+ }
1368+
1369+ for (unsigned int l = 0; l < 4; l++)
1370+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_LP_n_REG(l, 0), 0x463c);
1371+
1372+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(0, 2), 0x0000);
1373+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(1, 2), 0x0000);
1374+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(2, 2), 0x0001);
1375+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(3, 2), 0x0000);
1376+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(4, 2), 0x0000);
1377+
1378+ rcsi2_write16(priv, V4H_CORE_DIG_RW_COMMON_REG(6), 0x0009);
1379+
1380+ val = mbps > 1500 ? 0x0800 : 0x0802;
1381+ for (unsigned int l = 0; l < 5; l++)
1382+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, 12), val);
1383+
1384+ val = mbps > 1500 ? 0x0000 : 0x0002;
1385+ for (unsigned int l = 0; l < 5; l++)
1386+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, 13), val);
1387+
1388+ if (mbps >= 80) {
1389+ /* 2560: 6, 1280: 5, 640: 4, 320: 3, 160: 2, 80: 1 */
1390+ val = ilog2(mbps / 80) + 1;
1391+ rcsi2_modify16(priv,
1392+ V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(2, 9),
1393+ val << 5, 0xe0);
1394+ }
1395+
1396+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_CLK_RW_HS_RX_n_REG(0), 0x091c);
1397+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_CLK_RW_HS_RX_n_REG(7), 0x3b06);
1398+
1399+ val = DIV_ROUND_UP(1200, mbps) + 12;
1400+ for (unsigned int l = 0; l < 4; l++)
1401+ rcsi2_modify16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 0), val << 8, 0xf0);
1402+
1403+ val = mbps > 1500 ? 0x0004 : 0x0008;
1404+ for (unsigned int l = 0; l < 4; l++)
1405+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_CFG_n_REG(l, 1), val);
1406+
1407+ val = mbps > 2500 ? 0x669a : mbps > 1500 ? 0xe69a : 0xe69b;
1408+ for (unsigned int l = 0; l < 4; l++)
1409+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 2), val);
1410+
1411+ for (unsigned int l = 0; l < 4; l++)
1412+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_LP_n_REG(l, 0), 0x163c);
1413+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_CLK_RW_LP_n_REG(0), 0x163c);
1414+
1415+ if (lut) {
1416+ for (unsigned int l = 0; l < 4; l++)
1417+ rcsi2_modify16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 1),
1418+ lut->rw_hs_rx_1, 0xff);
1419+ }
1420+
1421+ for (unsigned int l = 0; l < 4; l++)
1422+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 3), 0x9209);
1423+
1424+ for (unsigned int l = 0; l < 4; l++)
1425+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 4), 0x0096);
1426+
1427+ for (unsigned int l = 0; l < 4; l++)
1428+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 5), 0x0100);
1429+
1430+ for (unsigned int l = 0; l < 4; l++)
1431+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 6), 0x2d02);
1432+
1433+ for (unsigned int l = 0; l < 4; l++)
1434+ rcsi2_write16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 7), 0x1b06);
1435+
1436+ if (lut) {
1437+ /*
1438+ * Documentation LUT have two values but document writing both
1439+ * values in a single write.
1440+ */
1441+ for (unsigned int l = 0; l < 4; l++)
1442+ rcsi2_modify16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 3),
1443+ lut->rw_hs_rx_3_83 << 3 | lut->rw_hs_rx_3_20, 0x1ff);
1444+
1445+ for (unsigned int l = 0; l < 4; l++)
1446+ rcsi2_modify16(priv, V4H_CORE_DIG_DLANE_l_RW_HS_RX_n_REG(l, 6),
1447+ lut->rw_hs_rx_6 << 8, 0xff00);
12891448 }
12901449
1291− /* C-PHY setting - analog programing*/
1292− rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(9), conf->lane29);
1293− rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(7), conf->lane27);
1450+ static const u16 deskew_fine[] = {
1451+ 0x0404, 0x040c, 0x0414, 0x041c, 0x0423, 0x0429, 0x0430, 0x043a,
1452+ 0x0445, 0x044a, 0x0450, 0x045a, 0x0465, 0x0469, 0x0472, 0x047a,
1453+ 0x0485, 0x0489, 0x0490, 0x049a, 0x04a4, 0x04ac, 0x04b4, 0x04bc,
1454+ 0x04c4, 0x04cc, 0x04d4, 0x04dc, 0x04e4, 0x04ec, 0x04f4, 0x04fc,
1455+ 0x0504, 0x050c, 0x0514, 0x051c, 0x0523, 0x0529, 0x0530, 0x053a,
1456+ 0x0545, 0x054a, 0x0550, 0x055a, 0x0565, 0x0569, 0x0572, 0x057a,
1457+ 0x0585, 0x0589, 0x0590, 0x059a, 0x05a4, 0x05ac, 0x05b4, 0x05bc,
1458+ 0x05c4, 0x05cc, 0x05d4, 0x05dc, 0x05e4, 0x05ec, 0x05f4, 0x05fc,
1459+ 0x0604, 0x060c, 0x0614, 0x061c, 0x0623, 0x0629, 0x0632, 0x063a,
1460+ 0x0645, 0x064a, 0x0650, 0x065a, 0x0665, 0x0669, 0x0672, 0x067a,
1461+ 0x0685, 0x0689, 0x0690, 0x069a, 0x06a4, 0x06ac, 0x06b4, 0x06bc,
1462+ 0x06c4, 0x06cc, 0x06d4, 0x06dc, 0x06e4, 0x06ec, 0x06f4, 0x06fc,
1463+ 0x0704, 0x070c, 0x0714, 0x071c, 0x0723, 0x072a, 0x0730, 0x073a,
1464+ 0x0745, 0x074a, 0x0750, 0x075a, 0x0765, 0x0769, 0x0772, 0x077a,
1465+ 0x0785, 0x0789, 0x0790, 0x079a, 0x07a4, 0x07ac, 0x07b4, 0x07bc,
1466+ 0x07c4, 0x07cc, 0x07d4, 0x07dc, 0x07e4, 0x07ec, 0x07f4, 0x07fc,
1467+ };
1468+
1469+ for (unsigned int i = 0; i < ARRAY_SIZE(deskew_fine); i++) {
1470+ rcsi2_write16(priv, V4H_CORE_DIG_COMMON_RW_DESKEW_FINE_MEM_REG,
1471+ deskew_fine[i]);
1472+ }
12941473
12951474 return 0;
12961475 }
@@ -1298,10 +1477,11 @@ static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) · 1 unmodified line
12981477 static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv,
12991478 struct v4l2_subdev_state *state)
13001479 {
1480+ const struct rcsi2_cphy_setting *cphy = NULL;
13011481 const struct rcar_csi2_format *format;
13021482 const struct v4l2_mbus_framefmt *fmt;
13031483 unsigned int lanes;
1304− int msps;
1484+ int mbps;
13051485 int ret;
13061486
13071487 /* Use the format on the sink pad to compute the receiver config. */
@@ -1314,28 +1494,40 @@ static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv, · 6 unmodified lines
13141494 if (ret)
13151495 return ret;
13161496
1317− msps = rcsi2_calc_mbps(priv, format->bpp, lanes);
1318− if (msps < 0)
1319− return msps;
1497+ mbps = rcsi2_calc_mbps(priv, format->bpp, lanes);
1498+ if (mbps < 0)
1499+ return mbps;
13201500
1321− /* Reset LINK and PHY*/
1501+ /* T0: Reset LINK and PHY*/
13221502 rcsi2_write(priv, V4H_CSI2_RESETN_REG, 0);
13231503 rcsi2_write(priv, V4H_DPHY_RSTZ_REG, 0);
13241504 rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, 0);
13251505
1326− /* PHY static setting */
1327− rcsi2_write(priv, V4H_PHY_EN_REG, V4H_PHY_EN_ENABLE_CLK);
1506+ /* T1: PHY static setting */
1507+ rcsi2_write(priv, V4H_PHY_EN_REG, V4H_PHY_EN_ENABLE_CLK |
1508+ V4H_PHY_EN_ENABLE_0 | V4H_PHY_EN_ENABLE_1 |
1509+ V4H_PHY_EN_ENABLE_2 | V4H_PHY_EN_ENABLE_3);
13281510 rcsi2_write(priv, V4H_FLDC_REG, 0);
13291511 rcsi2_write(priv, V4H_FLDD_REG, 0);
13301512 rcsi2_write(priv, V4H_IDIC_REG, 0);
1331− rcsi2_write(priv, V4H_PHY_MODE_REG, V4H_PHY_MODE_CPHY);
1513+ rcsi2_write(priv, V4H_PHY_MODE_REG,
1514+ priv->cphy ? V4H_PHY_MODE_CPHY : V4H_PHY_MODE_DPHY);
13321515 rcsi2_write(priv, V4H_N_LANES_REG, lanes - 1);
13331516
1334− /* Reset CSI2 */
1517+ rcsi2_write(priv, V4M_FRXM_REG,
1518+ V4M_FRXM_FORCERXMODE_0 | V4M_FRXM_FORCERXMODE_1 |
1519+ V4M_FRXM_FORCERXMODE_2 | V4M_FRXM_FORCERXMODE_3);
1520+ rcsi2_write(priv, V4M_OVR1_REG,
1521+ V4M_OVR1_FORCERXMODE_0 | V4M_OVR1_FORCERXMODE_1 |
1522+ V4M_OVR1_FORCERXMODE_2 | V4M_OVR1_FORCERXMODE_3);
1523+
1524+ /* T2: Reset CSI2 */
13351525 rcsi2_write(priv, V4H_CSI2_RESETN_REG, BIT(0));
13361526
13371527 /* Registers static setting through APB */
13381528 /* Common setting */
1529+ rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(10), 0x0030);
1530+ rcsi2_write16(priv, V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(2), 0x1444);
13391531 rcsi2_write16(priv, V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(0), 0x1bfd);
13401532 rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG, 0x0233);
13411533 rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(6), 0x0027);
@@ -1350,20 +1542,71 @@ static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv, · 8 unmodified lines
13501542 rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG, 0x0105);
13511543 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x1000);
13521544 rcsi2_write16(priv, V4H_PPI_RW_COMMON_CFG_REG, 0x0003);
1545+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(0), 0x0000);
1546+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(1), 0x0400);
1547+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(3), 0x41f6);
1548+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(0), 0x0000);
1549+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(3), 0x43f6);
1550+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x3000);
1551+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(7), 0x0000);
1552+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x7000);
1553+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(7), 0x0000);
1554+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(5), 0x4000);
1555+
1556+ /* T3: PHY settings */
1557+ if (priv->cphy) {
1558+ cphy = rcsi2_c_phy_setting_v4h(priv, mbps);
1559+ if (!cphy)
1560+ return -ERANGE;
1561+ } else {
1562+ ret = rcsi2_d_phy_setting_v4h(priv, mbps);
1563+ if (ret)
1564+ return ret;
1565+ }
13531566
1354− /* C-PHY settings */
1355− ret = rcsi2_c_phy_setting_v4h(priv, msps);
1356− if (ret)
1357− return ret;
1567+ /* T4: Leave Shutdown mode */
1568+ rcsi2_write(priv, V4H_DPHY_RSTZ_REG, BIT(0));
1569+ rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, BIT(0));
1570+
1571+ /* T5: Wait for calibration */
1572+ if (rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_PHY_READY)) {
1573+ dev_err(priv->dev, "PHY calibration failed\n");
1574+ return -ETIMEDOUT;
1575+ }
1576+
1577+ /* T6: Analog programming */
1578+ if (priv->cphy) {
1579+ for (unsigned int l = 0; l < 3; l++) {
1580+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, 9),
1581+ cphy->lane29);
1582+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, 7),
1583+ cphy->lane27);
1584+ }
1585+ } else {
1586+ u16 val_2_9 = mbps > 2500 ? 0x14 : mbps > 1500 ? 0x04 : 0x00;
1587+ u16 val_2_15 = mbps > 1500 ? 0x03 : 0x00;
1588+
1589+ for (unsigned int l = 0; l < 5; l++) {
1590+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, 9),
1591+ val_2_9);
1592+ rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(l, 15),
1593+ val_2_15);
1594+ }
1595+ }
13581596
1597+ /* T7: Wait for stop state */
13591598 rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_STOPSTATE_0 |
13601599 V4H_ST_PHYST_ST_STOPSTATE_1 |
1361− V4H_ST_PHYST_ST_STOPSTATE_2);
1600+ V4H_ST_PHYST_ST_STOPSTATE_2 |
1601+ V4H_ST_PHYST_ST_STOPSTATE_3);
1602+
1603+ /* T8: De-assert FRXM */
1604+ rcsi2_write(priv, V4M_FRXM_REG, 0);
13621605
13631606 return 0;
13641607 }
13651608
1366−static int rcsi2_d_phy_setting_v4m(struct rcar_csi2 *priv, int data_rate)
1609+static int rcsi2_d_phy_setting_v4m(struct rcar_csi2 *priv, int mbps)
13671610 {
13681611 unsigned int timeout;
13691612 int ret;
@@ -2213,6 +2456,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a779g0 = { · 843 unmodified lines
22132456 .start_receiver = rcsi2_start_receiver_v4h,
22142457 .use_isp = true,
22152458 .support_cphy = true,
2459+ .support_dphy = true,
22162460 };
22172461
22182462 static const struct rcsi2_register_layout rcsi2_registers_v4m = {
drivers/media/platform/renesas/rcar-fcp.c+36−0
@@ -9,6 +9,8 @@ · 8 unmodified lines
99
1010 #include <linux/device.h>
1111 #include <linux/dma-mapping.h>
12+#include <linux/io.h>
13+#include <linux/iopoll.h>
1214 #include <linux/list.h>
1315 #include <linux/module.h>
1416 #include <linux/mod_devicetable.h>
@@ -19,14 +21,25 @@ · 4 unmodified lines
1921
2022 #include <media/rcar-fcp.h>
2123
24+#define RCAR_FCP_REG_RST 0x0010
25+#define RCAR_FCP_REG_RST_SOFTRST BIT(0)
26+#define RCAR_FCP_REG_STA 0x0018
27+#define RCAR_FCP_REG_STA_ACT BIT(0)
28+
2229 struct rcar_fcp_device {
2330 struct list_head list;
2431 struct device *dev;
32+ void __iomem *base;
2533 };
2634
2735 static LIST_HEAD(fcp_devices);
2836 static DEFINE_MUTEX(fcp_lock);
2937
38+static inline void rcar_fcp_write(struct rcar_fcp_device *fcp, u32 reg, u32 val)
39+{
40+ iowrite32(val, fcp->base + reg);
41+}
42+
3043 /* -----------------------------------------------------------------------------
3144 * Public API
3245 */
@@ -117,6 +130,25 @@ void rcar_fcp_disable(struct rcar_fcp_device *fcp) · 84 unmodified lines
117130 }
118131 EXPORT_SYMBOL_GPL(rcar_fcp_disable);
119132
133+int rcar_fcp_soft_reset(struct rcar_fcp_device *fcp)
134+{
135+ u32 value;
136+ int ret;
137+
138+ if (!fcp)
139+ return 0;
140+
141+ rcar_fcp_write(fcp, RCAR_FCP_REG_RST, RCAR_FCP_REG_RST_SOFTRST);
142+ ret = readl_poll_timeout(fcp->base + RCAR_FCP_REG_STA,
143+ value, !(value & RCAR_FCP_REG_STA_ACT),
144+ 1, 100);
145+ if (ret)
146+ dev_err(fcp->dev, "Failed to soft-reset\n");
147+
148+ return ret;
149+}
150+EXPORT_SYMBOL_GPL(rcar_fcp_soft_reset);
151+
120152 /* -----------------------------------------------------------------------------
121153 * Platform Driver
122154 */
@@ -131,6 +163,10 @@ static int rcar_fcp_probe(struct platform_device *pdev) · 8 unmodified lines
131163
132164 fcp->dev = &pdev->dev;
133165
166+ fcp->base = devm_platform_ioremap_resource(pdev, 0);
167+ if (IS_ERR(fcp->base))
168+ return PTR_ERR(fcp->base);
169+
134170 dma_set_max_seg_size(fcp->dev, UINT_MAX);
135171
136172 pm_runtime_enable(&pdev->dev);
drivers/media/platform/renesas/rcar-vin/rcar-core.c+269−425
@@ -2,14 +2,14 @@ · 1 unmodified line
22 /*
33 * Driver for Renesas R-Car VIN
44 *
5+ * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
56 * Copyright (C) 2016 Renesas Electronics Corp.
67 * Copyright (C) 2011-2013 Renesas Solutions Corp.
78 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
89 * Copyright (C) 2008 Magnus Damm
9− *
10− * Based on the soc-camera rcar_vin driver
1110 */
1211
12+#include <linux/idr.h>
1313 #include <linux/module.h>
1414 #include <linux/of.h>
1515 #include <linux/of_graph.h>
@@ -55,6 +55,7 @@ · 39 unmodified lines
5555 * be only one group for all instances.
5656 */
5757
58+static DEFINE_IDA(rvin_ida);
5859 static DEFINE_MUTEX(rvin_group_lock);
5960 static struct rvin_group *rvin_group_data;
6061
@@ -65,7 +66,7 @@ static void rvin_group_cleanup(struct rvin_group *group) · 4 unmodified lines
6566 }
6667
6768 static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin,
68− int (*link_setup)(struct rvin_dev *),
69+ int (*link_setup)(struct rvin_group *),
6970 const struct media_device_ops *ops)
7071 {
7172 struct media_device *mdev = &group->mdev;
@@ -115,27 +116,12 @@ static void rvin_group_release(struct kref *kref) · 43 unmodified lines
115116 }
116117
117118 static int rvin_group_get(struct rvin_dev *vin,
118− int (*link_setup)(struct rvin_dev *),
119+ int (*link_setup)(struct rvin_group *),
119120 const struct media_device_ops *ops)
120121 {
121122 struct rvin_group *group;
122− u32 id;
123123 int ret;
124124
125− /* Make sure VIN id is present and sane */
126− ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id);
127− if (ret) {
128− vin_err(vin, "%pOF: No renesas,id property found\n",
129− vin->dev->of_node);
130− return -EINVAL;
131− }
132−
133− if (id >= RCAR_VIN_NUM) {
134− vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
135− vin->dev->of_node, id);
136− return -EINVAL;
137− }
138−
139125 /* Join or create a VIN group */
140126 mutex_lock(&rvin_group_lock);
141127 if (rvin_group_data) {
@@ -156,6 +142,7 @@ static int rvin_group_get(struct rvin_dev *vin, · 14 unmodified lines
156142 }
157143
158144 kref_init(&group->refcount);
145+ group->info = vin->info;
159146
160147 rvin_group_data = group;
161148 }
@@ -164,16 +151,15 @@ static int rvin_group_get(struct rvin_dev *vin, · 2 unmodified lines
164151 /* Add VIN to group */
165152 mutex_lock(&group->lock);
166153
167− if (group->vin[id]) {
168− vin_err(vin, "Duplicate renesas,id property value %u\n", id);
154+ if (group->vin[vin->id]) {
155+ vin_err(vin, "Duplicate renesas,id property value %u\n", vin->id);
169156 mutex_unlock(&group->lock);
170157 kref_put(&group->refcount, rvin_group_release);
171158 return -EINVAL;
172159 }
173160
174− group->vin[id] = vin;
161+ group->vin[vin->id] = vin;
175162
176− vin->id = id;
177163 vin->group = group;
178164 vin->v4l2_dev.mdev = &group->mdev;
179165
@@ -213,7 +199,7 @@ static int rvin_group_entity_to_remote_id(struct rvin_group *group, · 33 unmodified lines
213199
214200 sd = media_entity_to_v4l2_subdev(entity);
215201
216− for (i = 0; i < RVIN_REMOTES_MAX; i++)
202+ for (i = 0; i < ARRAY_SIZE(group->remotes); i++)
217203 if (group->remotes[i].subdev == sd)
218204 return i;
219205
@@ -246,7 +232,7 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) · 26 unmodified lines
246232 }
247233 }
248234
249− return vin->group->link_setup(vin);
235+ return vin->group->link_setup(vin->group);
250236 }
251237
252238 static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,
@@ -254,20 +240,32 @@ static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, · 1 unmodified line
254240 struct v4l2_async_connection *asc)
255241 {
256242 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
257− unsigned int i;
243+ struct rvin_group *group = vin->group;
258244
259− for (i = 0; i < RCAR_VIN_NUM; i++)
260− if (vin->group->vin[i])
261− rvin_v4l2_unregister(vin->group->vin[i]);
245+ for (unsigned int i = 0; i < RCAR_VIN_NUM; i++) {
246+ if (group->vin[i])
247+ rvin_v4l2_unregister(group->vin[i]);
248+ }
262249
263250 mutex_lock(&vin->group->lock);
264251
265− for (i = 0; i < RVIN_CSI_MAX; i++) {
266− if (vin->group->remotes[i].asc != asc)
252+ for (unsigned int i = 0; i < RCAR_VIN_NUM; i++) {
253+ if (!group->vin[i] || group->vin[i]->parallel.asc != asc)
267254 continue;
268− vin->group->remotes[i].subdev = NULL;
255+
256+ group->vin[i]->parallel.subdev = NULL;
257+
258+ vin_dbg(group->vin[i], "Unbind parallel subdev %s\n",
259+ subdev->name);
260+ }
261+
262+ for (unsigned int i = 0; i < ARRAY_SIZE(group->remotes); i++) {
263+ if (group->remotes[i].asc != asc)
264+ continue;
265+
266+ group->remotes[i].subdev = NULL;
267+
269268 vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
270− break;
271269 }
272270
273271 mutex_unlock(&vin->group->lock);
@@ -280,21 +278,38 @@ static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, · 6 unmodified lines
280278 struct v4l2_async_connection *asc)
281279 {
282280 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
283− unsigned int i;
281+ struct rvin_group *group = vin->group;
284282
285− mutex_lock(&vin->group->lock);
283+ guard(mutex)(&group->lock);
286284
287− for (i = 0; i < RVIN_CSI_MAX; i++) {
285+ for (unsigned int i = 0; i < RCAR_VIN_NUM; i++) {
286+ struct rvin_dev *pvin = group->vin[i];
287+
288+ if (!pvin || pvin->parallel.asc != asc)
289+ continue;
290+
291+ pvin->parallel.source_pad = 0;
292+ for (unsigned int pad = 0; pad < subdev->entity.num_pads; pad++)
293+ if (subdev->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE)
294+ pvin->parallel.source_pad = pad;
295+
296+ pvin->parallel.subdev = subdev;
297+ vin_dbg(pvin, "Bound subdev %s\n", subdev->name);
298+
299+ return 0;
300+ }
301+
302+ for (unsigned int i = 0; i < ARRAY_SIZE(group->remotes); i++) {
288303 if (vin->group->remotes[i].asc != asc)
289304 continue;
305+
290306 vin->group->remotes[i].subdev = subdev;
291307 vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
292− break;
293− }
294308
295− mutex_unlock(&vin->group->lock);
309+ return 0;
310+ }
296311
297− return 0;
312+ return -ENODEV;
298313 }
299314
300315 static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
@@ -343,12 +358,49 @@ out: · 42 unmodified lines
343358 return ret;
344359 }
345360
346−static void rvin_group_notifier_cleanup(struct rvin_dev *vin)
361+static int rvin_parallel_parse_of(struct rvin_dev *vin)
347362 {
348− if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
349− v4l2_async_nf_unregister(&vin->group->notifier);
350− v4l2_async_nf_cleanup(&vin->group->notifier);
363+ struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
364+ struct fwnode_handle *ep __free(fwnode_handle) = NULL;
365+ struct v4l2_fwnode_endpoint vep = {
366+ .bus_type = V4L2_MBUS_UNKNOWN,
367+ };
368+ struct v4l2_async_connection *asc;
369+
370+ ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 0, 0, 0);
371+ if (!ep)
372+ return 0;
373+
374+ if (v4l2_fwnode_endpoint_parse(ep, &vep)) {
375+ vin_err(vin, "Failed to parse %pOF\n", to_of_node(ep));
376+ return -EINVAL;
351377 }
378+
379+ switch (vep.bus_type) {
380+ case V4L2_MBUS_PARALLEL:
381+ case V4L2_MBUS_BT656:
382+ vin_dbg(vin, "Found %s media bus\n",
383+ vep.bus_type == V4L2_MBUS_PARALLEL ?
384+ "PARALLEL" : "BT656");
385+ vin->parallel.mbus_type = vep.bus_type;
386+ vin->parallel.bus = vep.bus.parallel;
387+ break;
388+ default:
389+ vin_err(vin, "Unknown media bus type\n");
390+ return -EINVAL;
391+ }
392+
393+ fwnode = fwnode_graph_get_remote_endpoint(ep);
394+ asc = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode,
395+ struct v4l2_async_connection);
396+ if (IS_ERR(asc))
397+ return PTR_ERR(asc);
398+
399+ vin->parallel.asc = asc;
400+
401+ vin_dbg(vin, "Add parallel OF device %pOF\n", to_of_node(fwnode));
402+
403+ return 0;
352404 }
353405
354406 static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port,
@@ -385,6 +437,12 @@ static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port, · 30 unmodified lines
385437 if (!(vin_mask & BIT(i)))
386438 continue;
387439
440+ /* Parse local subdevice. */
441+ ret = rvin_parallel_parse_of(vin->group->vin[i]);
442+ if (ret)
443+ return ret;
444+
445+ /* Parse shared subdevices. */
388446 for (id = 0; id < max_id; id++) {
389447 if (vin->group->remotes[id].asc)
390448 continue;
@@ -437,11 +495,11 @@ static void rvin_free_controls(struct rvin_dev *vin) · 46 unmodified lines
437495 vin->vdev.ctrl_handler = NULL;
438496 }
439497
440−static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev)
498+static int rvin_create_controls(struct rvin_dev *vin)
441499 {
442500 int ret;
443501
444− ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
502+ ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1);
445503 if (ret < 0)
446504 return ret;
447505
@@ -455,286 +513,11 @@ static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev · 7 unmodified lines
455513 return ret;
456514 }
457515
458− /* For the non-MC mode add controls from the subdevice. */
459− if (subdev) {
460− ret = v4l2_ctrl_add_handler(&vin->ctrl_handler,
461− subdev->ctrl_handler, NULL, true);
462− if (ret < 0) {
463− rvin_free_controls(vin);
464− return ret;
465− }
466− }
467−
468516 vin->vdev.ctrl_handler = &vin->ctrl_handler;
469517
470518 return 0;
471519 }
472520
473−/* -----------------------------------------------------------------------------
474− * Async notifier
475− */
476−
477−static int rvin_find_pad(struct v4l2_subdev *sd, int direction)
478−{
479− unsigned int pad;
480−
481− if (sd->entity.num_pads <= 1)
482− return 0;
483−
484− for (pad = 0; pad < sd->entity.num_pads; pad++)
485− if (sd->entity.pads[pad].flags & direction)
486− return pad;
487−
488− return -EINVAL;
489−}
490−
491−/* -----------------------------------------------------------------------------
492− * Parallel async notifier
493− */
494−
495−/* The vin lock should be held when calling the subdevice attach and detach */
496−static int rvin_parallel_subdevice_attach(struct rvin_dev *vin,
497− struct v4l2_subdev *subdev)
498−{
499− struct v4l2_subdev_mbus_code_enum code = {
500− .which = V4L2_SUBDEV_FORMAT_ACTIVE,
501− };
502− int ret;
503−
504− /* Find source and sink pad of remote subdevice */
505− ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE);
506− if (ret < 0)
507− return ret;
508− vin->parallel.source_pad = ret;
509−
510− ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK);
511− vin->parallel.sink_pad = ret < 0 ? 0 : ret;
512−
513− if (vin->info->use_mc) {
514− vin->parallel.subdev = subdev;
515− return 0;
516− }
517−
518− /* Find compatible subdevices mbus format */
519− vin->mbus_code = 0;
520− code.index = 0;
521− code.pad = vin->parallel.source_pad;
522− while (!vin->mbus_code &&
523− !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
524− code.index++;
525− switch (code.code) {
526− case MEDIA_BUS_FMT_YUYV8_1X16:
527− case MEDIA_BUS_FMT_UYVY8_1X16:
528− case MEDIA_BUS_FMT_UYVY8_2X8:
529− case MEDIA_BUS_FMT_UYVY10_2X10:
530− case MEDIA_BUS_FMT_RGB888_1X24:
531− vin->mbus_code = code.code;
532− vin_dbg(vin, "Found media bus format for %s: %d\n",
533− subdev->name, vin->mbus_code);
534− break;
535− default:
536− break;
537− }
538− }
539−
540− if (!vin->mbus_code) {
541− vin_err(vin, "Unsupported media bus format for %s\n",
542− subdev->name);
543− return -EINVAL;
544− }
545−
546− /* Read tvnorms */
547− ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms);
548− if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
549− return ret;
550−
551− /* Read standard */
552− vin->std = V4L2_STD_UNKNOWN;
553− ret = v4l2_subdev_call(subdev, video, g_std, &vin->std);
554− if (ret < 0 && ret != -ENOIOCTLCMD)
555− return ret;
556−
557− /* Add the controls */
558− ret = rvin_create_controls(vin, subdev);
559− if (ret < 0)
560− return ret;
561−
562− vin->parallel.subdev = subdev;
563−
564− return 0;
565−}
566−
567−static void rvin_parallel_subdevice_detach(struct rvin_dev *vin)
568−{
569− rvin_v4l2_unregister(vin);
570− vin->parallel.subdev = NULL;
571−
572− if (!vin->info->use_mc)
573− rvin_free_controls(vin);
574−}
575−
576−static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier)
577−{
578− struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
579− struct media_entity *source;
580− struct media_entity *sink;
581− int ret;
582−
583− ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
584− if (ret < 0) {
585− vin_err(vin, "Failed to register subdev nodes\n");
586− return ret;
587− }
588−
589− if (!video_is_registered(&vin->vdev)) {
590− ret = rvin_v4l2_register(vin);
591− if (ret < 0)
592− return ret;
593− }
594−
595− if (!vin->info->use_mc)
596− return 0;
597−
598− /* If we're running with media-controller, link the subdevs. */
599− source = &vin->parallel.subdev->entity;
600− sink = &vin->vdev.entity;
601−
602− ret = media_create_pad_link(source, vin->parallel.source_pad,
603− sink, vin->parallel.sink_pad, 0);
604− if (ret)
605− vin_err(vin, "Error adding link from %s to %s: %d\n",
606− source->name, sink->name, ret);
607−
608− return ret;
609−}
610−
611−static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier,
612− struct v4l2_subdev *subdev,
613− struct v4l2_async_connection *asc)
614−{
615− struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
616−
617− vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name);
618−
619− mutex_lock(&vin->lock);
620− rvin_parallel_subdevice_detach(vin);
621− mutex_unlock(&vin->lock);
622−}
623−
624−static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier,
625− struct v4l2_subdev *subdev,
626− struct v4l2_async_connection *asc)
627−{
628− struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
629− int ret;
630−
631− mutex_lock(&vin->lock);
632− ret = rvin_parallel_subdevice_attach(vin, subdev);
633− mutex_unlock(&vin->lock);
634− if (ret)
635− return ret;
636−
637− v4l2_set_subdev_hostdata(subdev, vin);
638−
639− vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n",
640− subdev->name, vin->parallel.source_pad,
641− vin->parallel.sink_pad);
642−
643− return 0;
644−}
645−
646−static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops = {
647− .bound = rvin_parallel_notify_bound,
648− .unbind = rvin_parallel_notify_unbind,
649− .complete = rvin_parallel_notify_complete,
650−};
651−
652−static int rvin_parallel_parse_of(struct rvin_dev *vin)
653−{
654− struct fwnode_handle *ep, *fwnode;
655− struct v4l2_fwnode_endpoint vep = {
656− .bus_type = V4L2_MBUS_UNKNOWN,
657− };
658− struct v4l2_async_connection *asc;
659− int ret;
660−
661− ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 0, 0, 0);
662− if (!ep)
663− return 0;
664−
665− fwnode = fwnode_graph_get_remote_endpoint(ep);
666− ret = v4l2_fwnode_endpoint_parse(ep, &vep);
667− fwnode_handle_put(ep);
668− if (ret) {
669− vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode));
670− ret = -EINVAL;
671− goto out;
672− }
673−
674− switch (vep.bus_type) {
675− case V4L2_MBUS_PARALLEL:
676− case V4L2_MBUS_BT656:
677− vin_dbg(vin, "Found %s media bus\n",
678− vep.bus_type == V4L2_MBUS_PARALLEL ?
679− "PARALLEL" : "BT656");
680− vin->parallel.mbus_type = vep.bus_type;
681− vin->parallel.bus = vep.bus.parallel;
682− break;
683− default:
684− vin_err(vin, "Unknown media bus type\n");
685− ret = -EINVAL;
686− goto out;
687− }
688−
689− asc = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode,
690− struct v4l2_async_connection);
691− if (IS_ERR(asc)) {
692− ret = PTR_ERR(asc);
693− goto out;
694− }
695−
696− vin->parallel.asc = asc;
697−
698− vin_dbg(vin, "Add parallel OF device %pOF\n", to_of_node(fwnode));
699−out:
700− fwnode_handle_put(fwnode);
701−
702− return ret;
703−}
704−
705−static void rvin_parallel_cleanup(struct rvin_dev *vin)
706−{
707− v4l2_async_nf_unregister(&vin->notifier);
708− v4l2_async_nf_cleanup(&vin->notifier);
709−}
710−
711−static int rvin_parallel_init(struct rvin_dev *vin)
712−{
713− int ret;
714−
715− v4l2_async_nf_init(&vin->notifier, &vin->v4l2_dev);
716−
717− ret = rvin_parallel_parse_of(vin);
718− if (ret)
719− return ret;
720−
721− if (!vin->parallel.asc)
722− return -ENODEV;
723−
724− vin_dbg(vin, "Found parallel subdevice %pOF\n",
725− to_of_node(vin->parallel.asc->match.fwnode));
726−
727− vin->notifier.ops = &rvin_parallel_notify_ops;
728− ret = v4l2_async_nf_register(&vin->notifier);
729− if (ret < 0) {
730− vin_err(vin, "Notifier registration failed\n");
731− v4l2_async_nf_cleanup(&vin->notifier);
732− return ret;
733− }
734−
735− return 0;
736−}
737−
738521 /* -----------------------------------------------------------------------------
739522 * CSI-2
740523 */
@@ -909,80 +692,91 @@ static int rvin_csi2_create_link(struct rvin_group *group, unsigned int id, · 168 unmodified lines
909692 return 0;
910693 }
911694
912−static int rvin_csi2_setup_links(struct rvin_dev *vin)
695+static int rvin_parallel_setup_links(struct rvin_group *group)
696+{
697+ u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
698+
699+ guard(mutex)(&group->lock);
700+
701+ /* If the group also has links don't enable the link. */
702+ for (unsigned int i = 0; i < ARRAY_SIZE(group->remotes); i++) {
703+ if (group->remotes[i].subdev) {
704+ flags = 0;
705+ break;
706+ }
707+ }
708+
709+ /* Create links. */
710+ for (unsigned int i = 0; i < RCAR_VIN_NUM; i++) {
711+ struct rvin_dev *vin = group->vin[i];
712+ struct media_entity *source;
713+ struct media_entity *sink;
714+ int ret;
715+
716+ /* Nothing to do if there is no VIN or parallel subdev. */
717+ if (!vin || !vin->parallel.subdev)
718+ continue;
719+
720+ source = &vin->parallel.subdev->entity;
721+ sink = &vin->vdev.entity;
722+
723+ ret = media_create_pad_link(source, vin->parallel.source_pad,
724+ sink, 0, flags);
725+ if (ret)
726+ return ret;
727+ }
728+
729+ return 0;
730+}
731+
732+static int rvin_csi2_setup_links(struct rvin_group *group)
913733 {
914734 const struct rvin_group_route *route;
915735 unsigned int id;
916− int ret = -EINVAL;
736+ int ret;
737+
738+ ret = rvin_parallel_setup_links(group);
739+ if (ret)
740+ return ret;
917741
918742 /* Create all media device links between VINs and CSI-2's. */
919− mutex_lock(&vin->group->lock);
920− for (route = vin->info->routes; route->chsel; route++) {
743+ mutex_lock(&group->lock);
744+ for (route = group->info->routes; route->chsel; route++) {
921745 /* Check that VIN' master is part of the group. */
922− if (!vin->group->vin[route->master])
746+ if (!group->vin[route->master])
923747 continue;
924748
925749 /* Check that CSI-2 is part of the group. */
926− if (!vin->group->remotes[route->csi].subdev)
750+ if (!group->remotes[route->csi].subdev)
927751 continue;
928752
929753 for (id = route->master; id < route->master + 4; id++) {
930754 /* Check that VIN is part of the group. */
931− if (!vin->group->vin[id])
755+ if (!group->vin[id])
932756 continue;
933757
934− ret = rvin_csi2_create_link(vin->group, id, route);
758+ ret = rvin_csi2_create_link(group, id, route);
935759 if (ret)
936760 goto out;
937761 }
938762 }
939763 out:
940− mutex_unlock(&vin->group->lock);
764+ mutex_unlock(&group->lock);
941765
942766 return ret;
943767 }
944768
945−static void rvin_csi2_cleanup(struct rvin_dev *vin)
946−{
947− rvin_parallel_cleanup(vin);
948− rvin_group_notifier_cleanup(vin);
949− rvin_group_put(vin);
950− rvin_free_controls(vin);
951−}
952−
953769 static int rvin_csi2_init(struct rvin_dev *vin)
954770 {
955771 int ret;
956772
957− vin->pad.flags = MEDIA_PAD_FL_SINK;
958− ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
959− if (ret)
960− return ret;
961−
962− ret = rvin_create_controls(vin, NULL);
963− if (ret < 0)
964− return ret;
965−
966773 ret = rvin_group_get(vin, rvin_csi2_setup_links, &rvin_csi2_media_ops);
967774 if (ret)
968− goto err_controls;
969−
970− /* It's OK to not have a parallel subdevice. */
971− ret = rvin_parallel_init(vin);
972− if (ret && ret != -ENODEV)
973− goto err_group;
775+ return ret;
974776
975777 ret = rvin_group_notifier_init(vin, 1, RVIN_CSI_MAX);
976778 if (ret)
977− goto err_parallel;
978−
979− return 0;
980−err_parallel:
981− rvin_parallel_cleanup(vin);
982−err_group:
983− rvin_group_put(vin);
984−err_controls:
985− rvin_free_controls(vin);
779+ rvin_group_put(vin);
986780
987781 return ret;
988782 }
@@ -991,30 +785,31 @@ err_controls: · 2 unmodified lines
991785 * ISP
992786 */
993787
994−static int rvin_isp_setup_links(struct rvin_dev *vin)
788+static int rvin_isp_setup_links(struct rvin_group *group)
995789 {
996790 unsigned int i;
997791 int ret = -EINVAL;
998792
999793 /* Create all media device links between VINs and ISP's. */
1000− mutex_lock(&vin->group->lock);
794+ mutex_lock(&group->lock);
1001795 for (i = 0; i < RCAR_VIN_NUM; i++) {
1002796 struct media_pad *source_pad, *sink_pad;
1003797 struct media_entity *source, *sink;
1004798 unsigned int source_slot = i / 8;
1005799 unsigned int source_idx = i % 8 + 1;
800+ struct rvin_dev *vin = group->vin[i];
1006801
1007− if (!vin->group->vin[i])
802+ if (!vin)
1008803 continue;
1009804
1010805 /* Check that ISP is part of the group. */
1011− if (!vin->group->remotes[source_slot].subdev)
806+ if (!group->remotes[source_slot].subdev)
1012807 continue;
1013808
1014− source = &vin->group->remotes[source_slot].subdev->entity;
809+ source = &group->remotes[source_slot].subdev->entity;
1015810 source_pad = &source->pads[source_idx];
1016811
1017− sink = &vin->group->vin[i]->vdev.entity;
812+ sink = &vin->vdev.entity;
1018813 sink_pad = &sink->pads[0];
1019814
1020815 /* Skip if link already exists. */
@@ -1030,44 +825,22 @@ static int rvin_isp_setup_links(struct rvin_dev *vin) · 9 unmodified lines
1030825 break;
1031826 }
1032827 }
1033− mutex_unlock(&vin->group->lock);
828+ mutex_unlock(&group->lock);
1034829
1035830 return ret;
1036831 }
1037832
1038−static void rvin_isp_cleanup(struct rvin_dev *vin)
1039−{
1040− rvin_group_notifier_cleanup(vin);
1041− rvin_group_put(vin);
1042− rvin_free_controls(vin);
1043−}
1044−
1045833 static int rvin_isp_init(struct rvin_dev *vin)
1046834 {
1047835 int ret;
1048836
1049− vin->pad.flags = MEDIA_PAD_FL_SINK;
1050− ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
1051− if (ret)
1052− return ret;
1053−
1054− ret = rvin_create_controls(vin, NULL);
1055− if (ret < 0)
1056− return ret;
1057−
1058837 ret = rvin_group_get(vin, rvin_isp_setup_links, NULL);
1059838 if (ret)
1060− goto err_controls;
839+ return ret;
1061840
1062841 ret = rvin_group_notifier_init(vin, 2, RVIN_ISP_MAX);
1063842 if (ret)
1064− goto err_group;
1065−
1066− return 0;
1067−err_group:
1068− rvin_group_put(vin);
1069−err_controls:
1070− rvin_free_controls(vin);
843+ rvin_group_put(vin);
1071844
1072845 return ret;
1073846 }
@@ -1102,7 +875,7 @@ static int __maybe_unused rvin_resume(struct device *dev) · 28 unmodified lines
1102875 * as we don't know if and in which order the master VINs will
1103876 * be resumed.
1104877 */
1105− if (vin->info->use_mc) {
878+ if (vin->info->model == RCAR_GEN3) {
1106879 unsigned int master_id = rvin_group_id_to_master(vin->id);
1107880 struct rvin_dev *master = vin->group->vin[master_id];
1108881 int ret;
@@ -1124,7 +897,6 @@ static int __maybe_unused rvin_resume(struct device *dev) · 15 unmodified lines
1124897
1125898 static const struct rvin_info rcar_info_h1 = {
1126899 .model = RCAR_H1,
1127− .use_mc = false,
1128900 .max_width = 2048,
1129901 .max_height = 2048,
1130902 .scaler = rvin_scaler_gen2,
@@ -1132,7 +904,6 @@ static const struct rvin_info rcar_info_h1 = { · 1 unmodified line
1132904
1133905 static const struct rvin_info rcar_info_m1 = {
1134906 .model = RCAR_M1,
1135− .use_mc = false,
1136907 .max_width = 2048,
1137908 .max_height = 2048,
1138909 .scaler = rvin_scaler_gen2,
@@ -1140,7 +911,6 @@ static const struct rvin_info rcar_info_m1 = { · 1 unmodified line
1140911
1141912 static const struct rvin_info rcar_info_gen2 = {
1142913 .model = RCAR_GEN2,
1143− .use_mc = false,
1144914 .max_width = 2048,
1145915 .max_height = 2048,
1146916 .scaler = rvin_scaler_gen2,
@@ -1155,7 +925,6 @@ static const struct rvin_group_route rcar_info_r8a774e1_routes[] = { · 8 unmodified lines
1155925
1156926 static const struct rvin_info rcar_info_r8a774e1 = {
1157927 .model = RCAR_GEN3,
1158− .use_mc = true,
1159928 .max_width = 4096,
1160929 .max_height = 4096,
1161930 .routes = rcar_info_r8a774e1_routes,
@@ -1171,7 +940,6 @@ static const struct rvin_group_route rcar_info_r8a7795_routes[] = { · 9 unmodified lines
1171940
1172941 static const struct rvin_info rcar_info_r8a7795 = {
1173942 .model = RCAR_GEN3,
1174− .use_mc = true,
1175943 .nv12 = true,
1176944 .max_width = 4096,
1177945 .max_height = 4096,
@@ -1189,7 +957,6 @@ static const struct rvin_group_route rcar_info_r8a7796_routes[] = { · 11 unmodified lines
1189957
1190958 static const struct rvin_info rcar_info_r8a7796 = {
1191959 .model = RCAR_GEN3,
1192− .use_mc = true,
1193960 .nv12 = true,
1194961 .max_width = 4096,
1195962 .max_height = 4096,
@@ -1207,7 +974,6 @@ static const struct rvin_group_route rcar_info_r8a77965_routes[] = { · 11 unmodified lines
1207974
1208975 static const struct rvin_info rcar_info_r8a77965 = {
1209976 .model = RCAR_GEN3,
1210− .use_mc = true,
1211977 .nv12 = true,
1212978 .max_width = 4096,
1213979 .max_height = 4096,
@@ -1222,7 +988,6 @@ static const struct rvin_group_route rcar_info_r8a77970_routes[] = { · 8 unmodified lines
1222988
1223989 static const struct rvin_info rcar_info_r8a77970 = {
1224990 .model = RCAR_GEN3,
1225− .use_mc = true,
1226991 .max_width = 4096,
1227992 .max_height = 4096,
1228993 .routes = rcar_info_r8a77970_routes,
@@ -1236,7 +1001,6 @@ static const struct rvin_group_route rcar_info_r8a77980_routes[] = { · 7 unmodified lines
12361001
12371002 static const struct rvin_info rcar_info_r8a77980 = {
12381003 .model = RCAR_GEN3,
1239− .use_mc = true,
12401004 .nv12 = true,
12411005 .max_width = 4096,
12421006 .max_height = 4096,
@@ -1250,7 +1014,6 @@ static const struct rvin_group_route rcar_info_r8a77990_routes[] = { · 7 unmodified lines
12501014
12511015 static const struct rvin_info rcar_info_r8a77990 = {
12521016 .model = RCAR_GEN3,
1253− .use_mc = true,
12541017 .nv12 = true,
12551018 .max_width = 4096,
12561019 .max_height = 4096,
@@ -1264,7 +1027,6 @@ static const struct rvin_group_route rcar_info_r8a77995_routes[] = { · 7 unmodified lines
12641027
12651028 static const struct rvin_info rcar_info_r8a77995 = {
12661029 .model = RCAR_GEN3,
1267− .use_mc = true,
12681030 .nv12 = true,
12691031 .max_width = 4096,
12701032 .max_height = 4096,
@@ -1274,7 +1036,6 @@ static const struct rvin_info rcar_info_r8a77995 = { · 3 unmodified lines
12741036
12751037 static const struct rvin_info rcar_info_gen4 = {
12761038 .model = RCAR_GEN4,
1277− .use_mc = true,
12781039 .use_isp = true,
12791040 .nv12 = true,
12801041 .raw10 = true,
@@ -1361,6 +1122,56 @@ static const struct of_device_id rvin_of_id_table[] = { · 80 unmodified lines
13611122 };
13621123 MODULE_DEVICE_TABLE(of, rvin_of_id_table);
13631124
1125+static int rvin_id_get(struct rvin_dev *vin)
1126+{
1127+ u32 oid;
1128+ int id;
1129+
1130+ switch (vin->info->model) {
1131+ case RCAR_GEN3:
1132+ case RCAR_GEN4:
1133+ if (of_property_read_u32(vin->dev->of_node, "renesas,id", &oid)) {
1134+ vin_err(vin, "%pOF: No renesas,id property found\n",
1135+ vin->dev->of_node);
1136+ return -EINVAL;
1137+ }
1138+
1139+ if (oid < 0 || oid >= RCAR_VIN_NUM) {
1140+ vin_err(vin, "%pOF: Invalid renesas,id '%u'\n",
1141+ vin->dev->of_node, oid);
1142+ return -EINVAL;
1143+ }
1144+
1145+ vin->id = oid;
1146+ break;
1147+ default:
1148+ id = ida_alloc_range(&rvin_ida, 0, RCAR_VIN_NUM - 1,
1149+ GFP_KERNEL);
1150+ if (id < 0) {
1151+ vin_err(vin, "%pOF: Failed to allocate VIN group ID\n",
1152+ vin->dev->of_node);
1153+ return -EINVAL;
1154+ }
1155+
1156+ vin->id = id;
1157+ break;
1158+ }
1159+
1160+ return 0;
1161+}
1162+
1163+static void rvin_id_put(struct rvin_dev *vin)
1164+{
1165+ switch (vin->info->model) {
1166+ case RCAR_GEN3:
1167+ case RCAR_GEN4:
1168+ break;
1169+ default:
1170+ ida_free(&rvin_ida, vin->id);
1171+ break;
1172+ }
1173+}
1174+
13641175 static int rcar_vin_probe(struct platform_device *pdev)
13651176 {
13661177 struct rvin_dev *vin;
@@ -1388,30 +1199,59 @@ static int rcar_vin_probe(struct platform_device *pdev) · 21 unmodified lines
13881199
13891200 platform_set_drvdata(pdev, vin);
13901201
1391− if (vin->info->use_isp) {
1392− ret = rvin_isp_init(vin);
1393− } else if (vin->info->use_mc) {
1394− ret = rvin_csi2_init(vin);
1202+ if (rvin_id_get(vin)) {
1203+ ret = -EINVAL;
1204+ goto err_dma;
1205+ }
13951206
1396− if (vin->info->scaler &&
1397− rvin_group_id_to_master(vin->id) == vin->id)
1398− vin->scaler = vin->info->scaler;
1399− } else {
1400− ret = rvin_parallel_init(vin);
1207+ vin->pad.flags = MEDIA_PAD_FL_SINK;
1208+ ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
1209+ if (ret)
1210+ goto err_id;
1211+
1212+ ret = rvin_create_controls(vin);
1213+ if (ret < 0)
1214+ goto err_id;
1215+
1216+ switch (vin->info->model) {
1217+ case RCAR_GEN3:
1218+ case RCAR_GEN4:
1219+ if (vin->info->use_isp) {
1220+ ret = rvin_isp_init(vin);
1221+ } else {
1222+ ret = rvin_csi2_init(vin);
1223+
1224+ if (vin->info->scaler &&
1225+ rvin_group_id_to_master(vin->id) == vin->id)
1226+ vin->scaler = vin->info->scaler;
1227+ }
1228+ break;
1229+ default:
1230+ ret = rvin_group_get(vin, rvin_parallel_setup_links, NULL);
1231+ if (!ret)
1232+ ret = rvin_group_notifier_init(vin, 0, 0);
14011233
14021234 if (vin->info->scaler)
14031235 vin->scaler = vin->info->scaler;
1236+ break;
14041237 }
14051238
1406− if (ret) {
1407− rvin_dma_unregister(vin);
1408− return ret;
1409− }
1239+ if (ret)
1240+ goto err_ctrl;
14101241
14111242 pm_suspend_ignore_children(&pdev->dev, true);
14121243 pm_runtime_enable(&pdev->dev);
14131244
14141245 return 0;
1246+
1247+err_ctrl:
1248+ rvin_free_controls(vin);
1249+err_id:
1250+ rvin_id_put(vin);
1251+err_dma:
1252+ rvin_dma_unregister(vin);
1253+
1254+ return ret;
14151255 }
14161256
14171257 static void rcar_vin_remove(struct platform_device *pdev)
@@ -1422,12 +1262,16 @@ static void rcar_vin_remove(struct platform_device *pdev) · 4 unmodified lines
14221262
14231263 rvin_v4l2_unregister(vin);
14241264
1425− if (vin->info->use_isp)
1426− rvin_isp_cleanup(vin);
1427− else if (vin->info->use_mc)
1428− rvin_csi2_cleanup(vin);
1429− else
1430− rvin_parallel_cleanup(vin);
1265+ if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
1266+ v4l2_async_nf_unregister(&vin->group->notifier);
1267+ v4l2_async_nf_cleanup(&vin->group->notifier);
1268+ }
1269+
1270+ rvin_group_put(vin);
1271+
1272+ rvin_free_controls(vin);
1273+
1274+ rvin_id_put(vin);
14311275
14321276 rvin_dma_unregister(vin);
14331277 }
drivers/media/platform/renesas/rcar-vin/rcar-dma.c+33−44
@@ -2,18 +2,18 @@ · 1 unmodified line
22 /*
33 * Driver for Renesas R-Car VIN
44 *
5+ * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
56 * Copyright (C) 2016 Renesas Electronics Corp.
67 * Copyright (C) 2011-2013 Renesas Solutions Corp.
78 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
89 * Copyright (C) 2008 Magnus Damm
9− *
10− * Based on the soc-camera rcar_vin driver
1110 */
1211
1312 #include <linux/delay.h>
1413 #include <linux/interrupt.h>
1514 #include <linux/pm_runtime.h>
1615
16+#include <media/v4l2-event.h>
1717 #include <media/videobuf2-dma-contig.h>
1818
1919 #include "rcar-vin.h"
@@ -115,11 +115,16 @@ · 95 unmodified lines
115115 #define VNFC_S_FRAME (1 << 0)
116116
117117 /* Video n Interrupt Enable Register bits */
118−#define VNIE_FIE (1 << 4)
119−#define VNIE_EFE (1 << 1)
118+#define VNIE_VFE BIT(17)
119+#define VNIE_VRE BIT(16)
120+#define VNIE_FIE BIT(4)
121+#define VNIE_EFE BIT(1)
120122
121123 /* Video n Interrupt Status Register bits */
122−#define VNINTS_FIS (1 << 4)
124+#define VNINTS_VFS BIT(17)
125+#define VNINTS_VRS BIT(16)
126+#define VNINTS_FIS BIT(4)
127+#define VNINTS_EFS BIT(1)
123128
124129 /* Video n Data Mode Register bits */
125130 #define VNDMR_A8BIT(n) (((n) & 0xff) << 24)
@@ -555,17 +560,12 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs) · 429 unmodified lines
555560
556561 void rvin_scaler_gen2(struct rvin_dev *vin)
557562 {
558− unsigned int crop_height;
559563 u32 xs, ys;
560564
561565 /* Set scaling coefficient */
562− crop_height = vin->crop.height;
563− if (V4L2_FIELD_HAS_BOTH(vin->format.field))
564− crop_height *= 2;
565−
566566 ys = 0;
567− if (crop_height != vin->compose.height)
568− ys = (4096 * crop_height) / vin->compose.height;
567+ if (vin->crop.height != vin->compose.height)
568+ ys = (4096 * vin->crop.height) / vin->compose.height;
569569 rvin_write(vin, ys, VNYS_REG);
570570
571571 xs = 0;
@@ -700,9 +700,6 @@ static int rvin_setup(struct rvin_dev *vin) · 128 unmodified lines
700700 case V4L2_FIELD_INTERLACED:
701701 /* Default to TB */
702702 vnmc = VNMC_IM_FULL;
703− /* Use BT if video standard can be read and is 60 Hz format */
704− if (!vin->info->use_mc && vin->std & V4L2_STD_525_60)
705− vnmc = VNMC_IM_FULL | VNMC_FOC;
706703 break;
707704 case V4L2_FIELD_INTERLACED_TB:
708705 vnmc = VNMC_IM_FULL;
@@ -897,6 +894,8 @@ static int rvin_setup(struct rvin_dev *vin) · 188 unmodified lines
897894
898895 /* Progressive or interlaced mode */
899896 interrupts = progressive ? VNIE_FIE : VNIE_EFE;
897+ /* Enable VSYNC Rising Edge Detection. */
898+ interrupts |= VNIE_VRE;
900899
901900 /* Ack interrupts */
902901 rvin_write(vin, interrupts, VNINTS_REG);
@@ -912,21 +911,6 @@ static int rvin_setup(struct rvin_dev *vin) · 9 unmodified lines
912911 return 0;
913912 }
914913
915−static void rvin_disable_interrupts(struct rvin_dev *vin)
916−{
917− rvin_write(vin, 0, VNIE_REG);
918−}
919−
920−static u32 rvin_get_interrupt_status(struct rvin_dev *vin)
921−{
922− return rvin_read(vin, VNINTS_REG);
923−}
924−
925−static void rvin_ack_interrupt(struct rvin_dev *vin)
926−{
927− rvin_write(vin, rvin_read(vin, VNINTS_REG), VNINTS_REG);
928−}
929−
930914 static bool rvin_capture_active(struct rvin_dev *vin)
931915 {
932916 return rvin_read(vin, VNMS_REG) & VNMS_CA;
@@ -1049,22 +1033,35 @@ static void rvin_capture_stop(struct rvin_dev *vin) · 116 unmodified lines
10491033 static irqreturn_t rvin_irq(int irq, void *data)
10501034 {
10511035 struct rvin_dev *vin = data;
1052− u32 int_status, vnms;
1036+ u32 capture, status, vnms;
10531037 int slot;
10541038 unsigned int handled = 0;
10551039 unsigned long flags;
10561040
10571041 spin_lock_irqsave(&vin->qlock, flags);
10581042
1059− int_status = rvin_get_interrupt_status(vin);
1060− if (!int_status)
1043+ status = rvin_read(vin, VNINTS_REG);
1044+ if (!status)
10611045 goto done;
10621046
1063− rvin_ack_interrupt(vin);
1047+ rvin_write(vin, status, VNINTS_REG);
10641048 handled = 1;
10651049
1050+ /* Signal Start of Frame. */
1051+ if (status & VNINTS_VRS) {
1052+ struct v4l2_event event = {
1053+ .type = V4L2_EVENT_FRAME_SYNC,
1054+ .u.frame_sync.frame_sequence = vin->sequence,
1055+ };
1056+
1057+ v4l2_event_queue(&vin->vdev, &event);
1058+ }
1059+
10661060 /* Nothing to do if nothing was captured. */
1067− if (!(int_status & VNINTS_FIS))
1061+ capture = vin->format.field == V4L2_FIELD_NONE ||
1062+ vin->format.field == V4L2_FIELD_ALTERNATE ?
1063+ VNINTS_FIS : VNINTS_EFS;
1064+ if (!(status & capture))
10681065 goto done;
10691066
10701067 /* Nothing to do if not running. */
@@ -1297,14 +1294,6 @@ static int rvin_set_stream(struct rvin_dev *vin, int on) · 226 unmodified lines
12971294 struct media_pad *pad;
12981295 int ret;
12991296
1300− /* No media controller used, simply pass operation to subdevice. */
1301− if (!vin->info->use_mc) {
1302− ret = v4l2_subdev_call(vin->parallel.subdev, video, s_stream,
1303− on);
1304−
1305− return ret == -ENOIOCTLCMD ? 0 : ret;
1306− }
1307−
13081297 pad = media_pad_remote_pad_first(&vin->pad);
13091298 if (!pad)
13101299 return -EPIPE;
@@ -1417,7 +1406,7 @@ void rvin_stop_streaming(struct rvin_dev *vin) · 106 unmodified lines
14171406 rvin_set_stream(vin, 0);
14181407
14191408 /* disable interrupts */
1420− rvin_disable_interrupts(vin);
1409+ rvin_write(vin, 0, VNIE_REG);
14211410
14221411 /* Return unprocessed buffers from hardware. */
14231412 for (unsigned int i = 0; i < HW_BUFFER_NUM; i++) {
drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c+20−472
@@ -2,12 +2,11 @@ · 1 unmodified line
22 /*
33 * Driver for Renesas R-Car VIN
44 *
5+ * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
56 * Copyright (C) 2016 Renesas Electronics Corp.
67 * Copyright (C) 2011-2013 Renesas Solutions Corp.
78 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
89 * Copyright (C) 2008 Magnus Damm
9− *
10− * Based on the soc-camera rcar_vin driver
1110 */
1211
1312 #include <linux/pm_runtime.h>
@@ -230,101 +229,6 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) · 216 unmodified lines
230229 * V4L2
231230 */
232231
233−static int rvin_reset_format(struct rvin_dev *vin)
234−{
235− struct v4l2_subdev_format fmt = {
236− .which = V4L2_SUBDEV_FORMAT_ACTIVE,
237− .pad = vin->parallel.source_pad,
238− };
239− int ret;
240−
241− ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
242− if (ret)
243− return ret;
244−
245− v4l2_fill_pix_format(&vin->format, &fmt.format);
246−
247− vin->crop.top = 0;
248− vin->crop.left = 0;
249− vin->crop.width = vin->format.width;
250− vin->crop.height = vin->format.height;
251−
252− /* Make use of the hardware interlacer by default. */
253− if (vin->format.field == V4L2_FIELD_ALTERNATE) {
254− vin->format.field = V4L2_FIELD_INTERLACED;
255− vin->format.height *= 2;
256− }
257−
258− rvin_format_align(vin, &vin->format);
259−
260− vin->compose.top = 0;
261− vin->compose.left = 0;
262− vin->compose.width = vin->format.width;
263− vin->compose.height = vin->format.height;
264−
265− return 0;
266−}
267−
268−static int rvin_try_format(struct rvin_dev *vin, u32 which,
269− struct v4l2_pix_format *pix,
270− struct v4l2_rect *src_rect)
271−{
272− struct v4l2_subdev *sd = vin_to_source(vin);
273− struct v4l2_subdev_state *sd_state;
274− static struct lock_class_key key;
275− struct v4l2_subdev_format format = {
276− .which = which,
277− .pad = vin->parallel.source_pad,
278− };
279− enum v4l2_field field;
280− u32 width, height;
281− int ret;
282−
283− /*
284− * FIXME: Drop this call, drivers are not supposed to use
285− * __v4l2_subdev_state_alloc().
286− */
287− sd_state = __v4l2_subdev_state_alloc(sd, "rvin:state->lock", &key);
288− if (IS_ERR(sd_state))
289− return PTR_ERR(sd_state);
290−
291− if (!rvin_format_from_pixel(vin, pix->pixelformat))
292− pix->pixelformat = RVIN_DEFAULT_FORMAT;
293−
294− v4l2_fill_mbus_format(&format.format, pix, vin->mbus_code);
295−
296− /* Allow the video device to override field and to scale */
297− field = pix->field;
298− width = pix->width;
299− height = pix->height;
300−
301− ret = v4l2_subdev_call(sd, pad, set_fmt, sd_state, &format);
302− if (ret < 0 && ret != -ENOIOCTLCMD)
303− goto done;
304− ret = 0;
305−
306− v4l2_fill_pix_format(pix, &format.format);
307−
308− if (src_rect) {
309− src_rect->top = 0;
310− src_rect->left = 0;
311− src_rect->width = pix->width;
312− src_rect->height = pix->height;
313− }
314−
315− if (field != V4L2_FIELD_ANY)
316− pix->field = field;
317−
318− pix->width = width;
319− pix->height = height;
320−
321− rvin_format_align(vin, pix);
322−done:
323− __v4l2_subdev_state_free(sd_state);
324−
325− return ret;
326−}
327−
328232 static int rvin_querycap(struct file *file, void *priv,
329233 struct v4l2_capability *cap)
330234 {
@@ -333,42 +237,6 @@ static int rvin_querycap(struct file *file, void *priv, · 2 unmodified lines
333237 return 0;
334238 }
335239
336−static int rvin_try_fmt_vid_cap(struct file *file, void *priv,
337− struct v4l2_format *f)
338−{
339− struct rvin_dev *vin = video_drvdata(file);
340−
341− return rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f->fmt.pix, NULL);
342−}
343−
344−static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
345− struct v4l2_format *f)
346−{
347− struct rvin_dev *vin = video_drvdata(file);
348− struct v4l2_rect fmt_rect, src_rect;
349− int ret;
350−
351− if (vb2_is_busy(&vin->queue))
352− return -EBUSY;
353−
354− ret = rvin_try_format(vin, V4L2_SUBDEV_FORMAT_ACTIVE, &f->fmt.pix,
355− &src_rect);
356− if (ret)
357− return ret;
358−
359− vin->format = f->fmt.pix;
360−
361− fmt_rect.top = 0;
362− fmt_rect.left = 0;
363− fmt_rect.width = vin->format.width;
364− fmt_rect.height = vin->format.height;
365−
366− v4l2_rect_map_inside(&vin->crop, &src_rect);
367− v4l2_rect_map_inside(&vin->compose, &fmt_rect);
368−
369− return 0;
370−}
371−
372240 static int rvin_g_fmt_vid_cap(struct file *file, void *priv,
373241 struct v4l2_format *f)
374242 {
@@ -465,6 +333,7 @@ static int rvin_enum_fmt_vid_cap(struct file *file, void *priv, · 90 unmodified lines
465333
466334 static int rvin_remote_rectangle(struct rvin_dev *vin, struct v4l2_rect *rect)
467335 {
336+ struct media_pad *pad = media_pad_remote_pad_first(&vin->pad);
468337 struct v4l2_subdev_format fmt = {
469338 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
470339 };
@@ -472,18 +341,11 @@ static int rvin_remote_rectangle(struct rvin_dev *vin, struct v4l2_rect *rect) · 1 unmodified line
472341 unsigned int index;
473342 int ret;
474343
475− if (vin->info->use_mc) {
476− struct media_pad *pad = media_pad_remote_pad_first(&vin->pad);
477−
478− if (!pad)
479− return -EINVAL;
344+ if (!pad)
345+ return -EINVAL;
480346
481− sd = media_entity_to_v4l2_subdev(pad->entity);
482− index = pad->index;
483− } else {
484− sd = vin_to_source(vin);
485− index = vin->parallel.source_pad;
486− }
347+ sd = media_entity_to_v4l2_subdev(pad->entity);
348+ index = pad->index;
487349
488350 fmt.pad = index;
489351 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
@@ -623,284 +485,18 @@ static int rvin_s_selection(struct file *file, void *fh, · 133 unmodified lines
623485 return 0;
624486 }
625487
626−static int rvin_g_parm(struct file *file, void *priv,
627− struct v4l2_streamparm *parm)
628−{
629− struct rvin_dev *vin = video_drvdata(file);
630− struct v4l2_subdev *sd = vin_to_source(vin);
631−
632− return v4l2_g_parm_cap(&vin->vdev, sd, parm);
633−}
634−
635−static int rvin_s_parm(struct file *file, void *priv,
636− struct v4l2_streamparm *parm)
637−{
638− struct rvin_dev *vin = video_drvdata(file);
639− struct v4l2_subdev *sd = vin_to_source(vin);
640−
641− return v4l2_s_parm_cap(&vin->vdev, sd, parm);
642−}
643−
644−static int rvin_g_pixelaspect(struct file *file, void *priv,
645− int type, struct v4l2_fract *f)
646−{
647− struct rvin_dev *vin = video_drvdata(file);
648− struct v4l2_subdev *sd = vin_to_source(vin);
649−
650− if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
651− return -EINVAL;
652−
653− return v4l2_subdev_call(sd, video, g_pixelaspect, f);
654−}
655−
656−static int rvin_enum_input(struct file *file, void *priv,
657− struct v4l2_input *i)
658−{
659− struct rvin_dev *vin = video_drvdata(file);
660− struct v4l2_subdev *sd = vin_to_source(vin);
661− int ret;
662−
663− if (i->index != 0)
664− return -EINVAL;
665−
666− ret = v4l2_subdev_call(sd, video, g_input_status, &i->status);
667− if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
668− return ret;
669−
670− i->type = V4L2_INPUT_TYPE_CAMERA;
671−
672− if (v4l2_subdev_has_op(sd, pad, dv_timings_cap)) {
673− i->capabilities = V4L2_IN_CAP_DV_TIMINGS;
674− i->std = 0;
675− } else {
676− i->capabilities = V4L2_IN_CAP_STD;
677− i->std = vin->vdev.tvnorms;
678− }
679−
680− strscpy(i->name, "Camera", sizeof(i->name));
681−
682− return 0;
683−}
684−
685−static int rvin_g_input(struct file *file, void *priv, unsigned int *i)
686−{
687− *i = 0;
688− return 0;
689−}
690−
691−static int rvin_s_input(struct file *file, void *priv, unsigned int i)
692−{
693− if (i > 0)
694− return -EINVAL;
695− return 0;
696−}
697−
698−static int rvin_querystd(struct file *file, void *priv, v4l2_std_id *a)
699−{
700− struct rvin_dev *vin = video_drvdata(file);
701− struct v4l2_subdev *sd = vin_to_source(vin);
702−
703− return v4l2_subdev_call(sd, video, querystd, a);
704−}
705−
706−static int rvin_s_std(struct file *file, void *priv, v4l2_std_id a)
707−{
708− struct rvin_dev *vin = video_drvdata(file);
709− int ret;
710−
711− ret = v4l2_subdev_call(vin_to_source(vin), video, s_std, a);
712− if (ret < 0)
713− return ret;
714−
715− vin->std = a;
716−
717− /* Changing the standard will change the width/height */
718− return rvin_reset_format(vin);
719−}
720−
721−static int rvin_g_std(struct file *file, void *priv, v4l2_std_id *a)
722−{
723− struct rvin_dev *vin = video_drvdata(file);
724−
725− if (v4l2_subdev_has_op(vin_to_source(vin), pad, dv_timings_cap))
726− return -ENOIOCTLCMD;
727−
728− *a = vin->std;
729−
730− return 0;
731−}
732−
733488 static int rvin_subscribe_event(struct v4l2_fh *fh,
734489 const struct v4l2_event_subscription *sub)
735490 {
736491 switch (sub->type) {
492+ case V4L2_EVENT_FRAME_SYNC:
493+ return v4l2_event_subscribe(fh, sub, 2, NULL);
737494 case V4L2_EVENT_SOURCE_CHANGE:
738495 return v4l2_event_subscribe(fh, sub, 4, NULL);
739496 }
740497 return v4l2_ctrl_subscribe_event(fh, sub);
741498 }
742499
743−static int rvin_enum_dv_timings(struct file *file, void *priv_fh,
744− struct v4l2_enum_dv_timings *timings)
745−{
746− struct rvin_dev *vin = video_drvdata(file);
747− struct v4l2_subdev *sd = vin_to_source(vin);
748− int ret;
749−
750− if (timings->pad)
751− return -EINVAL;
752−
753− timings->pad = vin->parallel.sink_pad;
754−
755− ret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);
756−
757− timings->pad = 0;
758−
759− return ret;
760−}
761−
762−static int rvin_s_dv_timings(struct file *file, void *priv_fh,
763− struct v4l2_dv_timings *timings)
764−{
765− struct rvin_dev *vin = video_drvdata(file);
766− struct v4l2_subdev *sd = vin_to_source(vin);
767− int ret;
768−
769− ret = v4l2_subdev_call(sd, pad, s_dv_timings,
770− vin->parallel.sink_pad, timings);
771− if (ret)
772− return ret;
773−
774− /* Changing the timings will change the width/height */
775− return rvin_reset_format(vin);
776−}
777−
778−static int rvin_g_dv_timings(struct file *file, void *priv_fh,
779− struct v4l2_dv_timings *timings)
780−{
781− struct rvin_dev *vin = video_drvdata(file);
782− struct v4l2_subdev *sd = vin_to_source(vin);
783−
784− return v4l2_subdev_call(sd, pad, g_dv_timings,
785− vin->parallel.sink_pad, timings);
786−}
787−
788−static int rvin_query_dv_timings(struct file *file, void *priv_fh,
789− struct v4l2_dv_timings *timings)
790−{
791− struct rvin_dev *vin = video_drvdata(file);
792− struct v4l2_subdev *sd = vin_to_source(vin);
793−
794− return v4l2_subdev_call(sd, pad, query_dv_timings,
795− vin->parallel.sink_pad, timings);
796−}
797−
798−static int rvin_dv_timings_cap(struct file *file, void *priv_fh,
799− struct v4l2_dv_timings_cap *cap)
800−{
801− struct rvin_dev *vin = video_drvdata(file);
802− struct v4l2_subdev *sd = vin_to_source(vin);
803− int ret;
804−
805− if (cap->pad)
806− return -EINVAL;
807−
808− cap->pad = vin->parallel.sink_pad;
809−
810− ret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);
811−
812− cap->pad = 0;
813−
814− return ret;
815−}
816−
817−static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
818−{
819− struct rvin_dev *vin = video_drvdata(file);
820− struct v4l2_subdev *sd = vin_to_source(vin);
821− int ret;
822−
823− if (edid->pad)
824− return -EINVAL;
825−
826− edid->pad = vin->parallel.sink_pad;
827−
828− ret = v4l2_subdev_call(sd, pad, get_edid, edid);
829−
830− edid->pad = 0;
831−
832− return ret;
833−}
834−
835−static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)
836−{
837− struct rvin_dev *vin = video_drvdata(file);
838− struct v4l2_subdev *sd = vin_to_source(vin);
839− int ret;
840−
841− if (edid->pad)
842− return -EINVAL;
843−
844− edid->pad = vin->parallel.sink_pad;
845−
846− ret = v4l2_subdev_call(sd, pad, set_edid, edid);
847−
848− edid->pad = 0;
849−
850− return ret;
851−}
852−
853−static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
854− .vidioc_querycap = rvin_querycap,
855− .vidioc_try_fmt_vid_cap = rvin_try_fmt_vid_cap,
856− .vidioc_g_fmt_vid_cap = rvin_g_fmt_vid_cap,
857− .vidioc_s_fmt_vid_cap = rvin_s_fmt_vid_cap,
858− .vidioc_enum_fmt_vid_cap = rvin_enum_fmt_vid_cap,
859−
860− .vidioc_g_selection = rvin_g_selection,
861− .vidioc_s_selection = rvin_s_selection,
862−
863− .vidioc_g_parm = rvin_g_parm,
864− .vidioc_s_parm = rvin_s_parm,
865−
866− .vidioc_g_pixelaspect = rvin_g_pixelaspect,
867−
868− .vidioc_enum_input = rvin_enum_input,
869− .vidioc_g_input = rvin_g_input,
870− .vidioc_s_input = rvin_s_input,
871−
872− .vidioc_dv_timings_cap = rvin_dv_timings_cap,
873− .vidioc_enum_dv_timings = rvin_enum_dv_timings,
874− .vidioc_g_dv_timings = rvin_g_dv_timings,
875− .vidioc_s_dv_timings = rvin_s_dv_timings,
876− .vidioc_query_dv_timings = rvin_query_dv_timings,
877−
878− .vidioc_g_edid = rvin_g_edid,
879− .vidioc_s_edid = rvin_s_edid,
880−
881− .vidioc_querystd = rvin_querystd,
882− .vidioc_g_std = rvin_g_std,
883− .vidioc_s_std = rvin_s_std,
884−
885− .vidioc_reqbufs = vb2_ioctl_reqbufs,
886− .vidioc_create_bufs = vb2_ioctl_create_bufs,
887− .vidioc_querybuf = vb2_ioctl_querybuf,
888− .vidioc_qbuf = vb2_ioctl_qbuf,
889− .vidioc_dqbuf = vb2_ioctl_dqbuf,
890− .vidioc_expbuf = vb2_ioctl_expbuf,
891− .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
892− .vidioc_streamon = vb2_ioctl_streamon,
893− .vidioc_streamoff = vb2_ioctl_streamoff,
894−
895− .vidioc_log_status = v4l2_ctrl_log_status,
896− .vidioc_subscribe_event = rvin_subscribe_event,
897− .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
898−};
899−
900−/* -----------------------------------------------------------------------------
901− * V4L2 Media Controller
902− */
903−
904500 static void rvin_mc_try_format(struct rvin_dev *vin,
905501 struct v4l2_pix_format *pix)
906502 {
@@ -979,19 +575,6 @@ static const struct v4l2_ioctl_ops rvin_mc_ioctl_ops = { · 72 unmodified lines
979575 * File Operations
980576 */
981577
982−static int rvin_power_parallel(struct rvin_dev *vin, bool on)
983−{
984− struct v4l2_subdev *sd = vin_to_source(vin);
985− int power = on ? 1 : 0;
986− int ret;
987−
988− ret = v4l2_subdev_call(sd, core, s_power, power);
989− if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
990− return ret;
991−
992− return 0;
993−}
994−
995578 static int rvin_open(struct file *file)
996579 {
997580 struct rvin_dev *vin = video_drvdata(file);
@@ -1011,11 +594,7 @@ static int rvin_open(struct file *file) · 13 unmodified lines
1011594 if (ret)
1012595 goto err_unlock;
1013596
1014− if (vin->info->use_mc)
1015− ret = v4l2_pipeline_pm_get(&vin->vdev.entity);
1016− else if (v4l2_fh_is_singular_file(file))
1017− ret = rvin_power_parallel(vin, true);
1018−
597+ ret = v4l2_pipeline_pm_get(&vin->vdev.entity);
1019598 if (ret < 0)
1020599 goto err_open;
1021600
@@ -1027,10 +606,7 @@ static int rvin_open(struct file *file) · 5 unmodified lines
1027606
1028607 return 0;
1029608 err_power:
1030− if (vin->info->use_mc)
1031− v4l2_pipeline_pm_put(&vin->vdev.entity);
1032− else if (v4l2_fh_is_singular_file(file))
1033− rvin_power_parallel(vin, false);
609+ v4l2_pipeline_pm_put(&vin->vdev.entity);
1034610 err_open:
1035611 v4l2_fh_release(file);
1036612 err_unlock:
@@ -1044,23 +620,14 @@ err_pm: · 7 unmodified lines
1044620 static int rvin_release(struct file *file)
1045621 {
1046622 struct rvin_dev *vin = video_drvdata(file);
1047− bool fh_singular;
1048623 int ret;
1049624
1050625 mutex_lock(&vin->lock);
1051626
1052− /* Save the singular status before we call the clean-up helper */
1053− fh_singular = v4l2_fh_is_singular_file(file);
1054−
1055627 /* the release helper will cleanup any on-going streaming */
1056628 ret = _vb2_fop_release(file, NULL);
1057629
1058− if (vin->info->use_mc) {
1059− v4l2_pipeline_pm_put(&vin->vdev.entity);
1060− } else {
1061− if (fh_singular)
1062− rvin_power_parallel(vin, false);
1063− }
630+ v4l2_pipeline_pm_put(&vin->vdev.entity);
1064631
1065632 mutex_unlock(&vin->lock);
1066633
@@ -1091,18 +658,6 @@ void rvin_v4l2_unregister(struct rvin_dev *vin) · 24 unmodified lines
1091658 video_unregister_device(&vin->vdev);
1092659 }
1093660
1094−static void rvin_notify_video_device(struct rvin_dev *vin,
1095− unsigned int notification, void *arg)
1096−{
1097− switch (notification) {
1098− case V4L2_DEVICE_NOTIFY_EVENT:
1099− v4l2_event_queue(&vin->vdev, arg);
1100− break;
1101− default:
1102− break;
1103− }
1104−}
1105−
1106661 static void rvin_notify(struct v4l2_subdev *sd,
1107662 unsigned int notification, void *arg)
1108663 {
@@ -1113,12 +668,6 @@ static void rvin_notify(struct v4l2_subdev *sd, · 4 unmodified lines
1113668 container_of(sd->v4l2_dev, struct rvin_dev, v4l2_dev);
1114669 unsigned int i;
1115670
1116− /* If no media controller, no need to route the event. */
1117− if (!vin->info->use_mc) {
1118− rvin_notify_video_device(vin, notification, arg);
1119− return;
1120− }
1121−
1122671 group = vin->group;
1123672
1124673 for (i = 0; i < RCAR_VIN_NUM; i++) {
@@ -1134,7 +683,13 @@ static void rvin_notify(struct v4l2_subdev *sd, · 9 unmodified lines
1134683 if (remote != sd)
1135684 continue;
1136685
1137− rvin_notify_video_device(vin, notification, arg);
686+ switch (notification) {
687+ case V4L2_DEVICE_NOTIFY_EVENT:
688+ v4l2_event_queue(&vin->vdev, arg);
689+ break;
690+ default:
691+ break;
692+ }
1138693 }
1139694 }
1140695
@@ -1153,7 +708,8 @@ int rvin_v4l2_register(struct rvin_dev *vin) · 12 unmodified lines
1153708 vdev->lock = &vin->lock;
1154709 vdev->fops = &rvin_fops;
1155710 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
1156− V4L2_CAP_READWRITE;
711+ V4L2_CAP_READWRITE | V4L2_CAP_IO_MC;
712+ vdev->ioctl_ops = &rvin_mc_ioctl_ops;
1157713
1158714 /* Set a default format */
1159715 vin->format.pixelformat = RVIN_DEFAULT_FORMAT;
@@ -1162,14 +718,6 @@ int rvin_v4l2_register(struct rvin_dev *vin) · 2 unmodified lines
1162718 vin->format.field = RVIN_DEFAULT_FIELD;
1163719 vin->format.colorspace = RVIN_DEFAULT_COLORSPACE;
1164720
1165− if (vin->info->use_mc) {
1166− vdev->device_caps |= V4L2_CAP_IO_MC;
1167− vdev->ioctl_ops = &rvin_mc_ioctl_ops;
1168− } else {
1169− vdev->ioctl_ops = &rvin_ioctl_ops;
1170− rvin_reset_format(vin);
1171− }
1172−
1173721 rvin_format_align(vin, &vin->format);
1174722
1175723 ret = video_register_device(&vin->vdev, VFL_TYPE_VIDEO, -1);
drivers/media/platform/renesas/rcar-vin/rcar-vin.h+4−12
@@ -2,12 +2,11 @@ · 1 unmodified line
22 /*
33 * Driver for Renesas R-Car VIN
44 *
5+ * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
56 * Copyright (C) 2016 Renesas Electronics Corp.
67 * Copyright (C) 2011-2013 Renesas Solutions Corp.
78 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
89 * Copyright (C) 2008 Magnus Damm
9− *
10− * Based on the soc-camera rcar_vin driver
1110 */
1211
1312 #ifndef __RCAR_VIN__
@@ -79,8 +78,6 @@ struct rvin_video_format { · 65 unmodified lines
7978 * @mbus_type: media bus type
8079 * @bus: media bus parallel configuration
8180 * @source_pad: source pad of remote subdevice
82− * @sink_pad: sink pad of remote subdevice
83− *
8481 */
8582 struct rvin_parallel_entity {
8683 struct v4l2_async_connection *asc;
@@ -90,7 +87,6 @@ struct rvin_parallel_entity { · 3 unmodified lines
9087 struct v4l2_mbus_config_parallel bus;
9188
9289 unsigned int source_pad;
93− unsigned int sink_pad;
9490 };
9591
9692 /**
@@ -117,7 +113,6 @@ struct rvin_group_route { · 20 unmodified lines
117113 /**
118114 * struct rvin_info - Information about the particular VIN implementation
119115 * @model: VIN model
120− * @use_mc: use media controller instead of controlling subdevice
121116 * @use_isp: the VIN is connected to the ISP and not to the CSI-2
122117 * @nv12: support outputting NV12 pixel format
123118 * @raw10: support outputting RAW10 pixel format
@@ -129,7 +124,6 @@ struct rvin_group_route { · 5 unmodified lines
129124 */
130125 struct rvin_info {
131126 enum model_id model;
132− bool use_mc;
133127 bool use_isp;
134128 bool nv12;
135129 bool raw10;
@@ -149,7 +143,6 @@ struct rvin_info { · 13 unmodified lines
149143 * @vdev: V4L2 video device associated with VIN
150144 * @v4l2_dev: V4L2 device
151145 * @ctrl_handler: V4L2 control handler
152− * @notifier: V4L2 asynchronous subdevs notifier
153146 *
154147 * @parallel: parallel input subdevice descriptor
155148 *
@@ -177,7 +170,6 @@ struct rvin_info { · 21 unmodified lines
177170 * @crop: active cropping
178171 * @compose: active composing
179172 * @scaler: Optional scaler
180− * @std: active video standard of the video source
181173 *
182174 * @alpha: Alpha component to fill in for supported pixel formats
183175 */
@@ -189,7 +181,6 @@ struct rvin_dev { · 5 unmodified lines
189181 struct video_device vdev;
190182 struct v4l2_device v4l2_dev;
191183 struct v4l2_ctrl_handler ctrl_handler;
192− struct v4l2_async_notifier notifier;
193184
194185 struct rvin_parallel_entity parallel;
195186
@@ -220,7 +211,6 @@ struct rvin_dev { · 24 unmodified lines
220211 struct v4l2_rect crop;
221212 struct v4l2_rect compose;
222213 void (*scaler)(struct rvin_dev *vin);
223− v4l2_std_id std;
224214
225215 unsigned int alpha;
226216 };
@@ -242,6 +232,7 @@ struct rvin_dev { · 15 unmodified lines
242232 * @lock: protects the count, notifier, vin and csi members
243233 * @count: number of enabled VIN instances found in DT
244234 * @notifier: group notifier for CSI-2 async connections
235+ * @info: Platform dependent information about the VIN instances
245236 * @vin: VIN instances which are part of the group
246237 * @link_setup: Callback to create all links for the media graph
247238 * @remotes: array of pairs of async connection and subdev pointers
@@ -255,9 +246,10 @@ struct rvin_group { · 7 unmodified lines
255246 struct mutex lock;
256247 unsigned int count;
257248 struct v4l2_async_notifier notifier;
249+ const struct rvin_info *info;
258250 struct rvin_dev *vin[RCAR_VIN_NUM];
259251
260− int (*link_setup)(struct rvin_dev *vin);
252+ int (*link_setup)(struct rvin_group *group);
261253
262254 struct {
263255 struct v4l2_async_connection *asc;
drivers/media/platform/renesas/rzg2l-cru/rzg2l-core.c+3−3
@@ -366,7 +366,7 @@ static const struct rzg2l_cru_info rzg3e_cru_info = { · 365 unmodified lines
366366 .irq_handler = rzg3e_cru_irq,
367367 .enable_interrupts = rzg3e_cru_enable_interrupts,
368368 .disable_interrupts = rzg3e_cru_disable_interrupts,
369− .fifo_empty = rz3e_fifo_empty,
369+ .fifo_empty = rzg3e_fifo_empty,
370370 .csi_setup = rzg3e_cru_csi2_setup,
371371 };
372372
@@ -403,7 +403,7 @@ static const u16 rzg2l_cru_regs[] = { · 30 unmodified lines
403403 [ICnDMR] = 0x26c,
404404 };
405405
406−static const struct rzg2l_cru_info rzgl2_cru_info = {
406+static const struct rzg2l_cru_info rzg2l_cru_info = {
407407 .max_width = 2800,
408408 .max_height = 4095,
409409 .image_conv = ICnMC,
@@ -422,7 +422,7 @@ static const struct of_device_id rzg2l_cru_of_id_table[] = { · 12 unmodified lines
422422 },
423423 {
424424 .compatible = "renesas,rzg2l-cru",
425− .data = &rzgl2_cru_info,
425+ .data = &rzg2l_cru_info,
426426 },
427427 { /* sentinel */ }
428428 };
drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h+9−5
@@ -64,19 +64,21 @@ struct rzg2l_cru_ip { · 63 unmodified lines
6464
6565 /**
6666 * struct rzg2l_cru_ip_format - CRU IP format
67− * @code: Media bus code
67+ * @codes: Array of up to four media bus codes
6868 * @datatype: MIPI CSI2 data type
6969 * @format: 4CC format identifier (V4L2_PIX_FMT_*)
7070 * @icndmr: ICnDMR register value
71− * @bpp: bytes per pixel
7271 * @yuv: Flag to indicate whether the format is YUV-based.
7372 */
7473 struct rzg2l_cru_ip_format {
75− u32 code;
74+ /*
75+ * RAW output formats might be produced by RAW media codes with any one
76+ * of the 4 common bayer patterns.
77+ */
78+ u32 codes[4];
7679 u32 datatype;
7780 u32 format;
7881 u32 icndmr;
79− u8 bpp;
8082 bool yuv;
8183 };
8284
@@ -192,6 +194,8 @@ struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru); · 109 unmodified lines
192194 const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code);
193195 const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format);
194196 const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index);
197+bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt,
198+ unsigned int code);
195199
196200 void rzg2l_cru_enable_interrupts(struct rzg2l_cru_dev *cru);
197201 void rzg2l_cru_disable_interrupts(struct rzg2l_cru_dev *cru);
@@ -199,7 +203,7 @@ void rzg3e_cru_enable_interrupts(struct rzg2l_cru_dev *cru); · 1 unmodified line
199203 void rzg3e_cru_disable_interrupts(struct rzg2l_cru_dev *cru);
200204
201205 bool rzg2l_fifo_empty(struct rzg2l_cru_dev *cru);
202−bool rz3e_fifo_empty(struct rzg2l_cru_dev *cru);
206+bool rzg3e_fifo_empty(struct rzg2l_cru_dev *cru);
203207 void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru,
204208 const struct rzg2l_cru_ip_format *ip_fmt,
205209 u8 csi_vc);
drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c+32−13
@@ -232,6 +232,18 @@ static const struct rzg2l_csi2_format rzg2l_csi2_formats[] = { · 231 unmodified lines
232232 { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },
233233 { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },
234234 { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, },
235+ { .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, },
236+ { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, },
237+ { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, },
238+ { .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, },
239+ { .code = MEDIA_BUS_FMT_SBGGR12_1X12, .bpp = 12, },
240+ { .code = MEDIA_BUS_FMT_SGBRG12_1X12, .bpp = 12, },
241+ { .code = MEDIA_BUS_FMT_SGRBG12_1X12, .bpp = 12, },
242+ { .code = MEDIA_BUS_FMT_SRGGB12_1X12, .bpp = 12, },
243+ { .code = MEDIA_BUS_FMT_SBGGR14_1X14, .bpp = 14, },
244+ { .code = MEDIA_BUS_FMT_SGBRG14_1X14, .bpp = 14, },
245+ { .code = MEDIA_BUS_FMT_SGRBG14_1X14, .bpp = 14, },
246+ { .code = MEDIA_BUS_FMT_SRGGB14_1X14, .bpp = 14, },
235247 };
236248
237249 static inline struct rzg2l_csi2 *sd_to_csi2(struct v4l2_subdev *sd)
@@ -282,15 +294,18 @@ static int rzg2l_csi2_calc_mbps(struct rzg2l_csi2 *csi2) · 44 unmodified lines
282294 const struct rzg2l_csi2_format *format;
283295 const struct v4l2_mbus_framefmt *fmt;
284296 struct v4l2_subdev_state *state;
285− struct v4l2_ctrl *ctrl;
297+ struct media_pad *remote_pad;
286298 u64 mbps;
299+ s64 ret;
287300
288− /* Read the pixel rate control from remote. */
289− ctrl = v4l2_ctrl_find(source->ctrl_handler, V4L2_CID_PIXEL_RATE);
290− if (!ctrl) {
291− dev_err(csi2->dev, "no pixel rate control in subdev %s\n",
292− source->name);
293− return -EINVAL;
301+ if (!csi2->remote_source)
302+ return -ENODEV;
303+
304+ remote_pad = media_pad_remote_pad_unique(&csi2->pads[RZG2L_CSI2_SINK]);
305+ if (IS_ERR(remote_pad)) {
306+ dev_err(csi2->dev, "can't get source pad of %s (%ld)\n",
307+ csi2->remote_source->name, PTR_ERR(remote_pad));
308+ return PTR_ERR(remote_pad);
294309 }
295310
296311 state = v4l2_subdev_lock_and_get_active_state(&csi2->subdev);
@@ -298,12 +313,16 @@ static int rzg2l_csi2_calc_mbps(struct rzg2l_csi2 *csi2) · 1 unmodified line
298313 format = rzg2l_csi2_code_to_fmt(fmt->code);
299314 v4l2_subdev_unlock_state(state);
300315
301− /*
302− * Calculate hsfreq in Mbps
303− * hsfreq = (pixel_rate * bits_per_sample) / number_of_lanes
304− */
305− mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * format->bpp;
306− do_div(mbps, csi2->lanes * 1000000);
316+ /* Read the link frequency from remote subdevice. */
317+ ret = v4l2_get_link_freq(remote_pad, format->bpp, csi2->lanes * 2);
318+ if (ret < 0) {
319+ dev_err(csi2->dev, "can't retrieve link freq from subdev %s\n",
320+ source->name);
321+ return -EINVAL;
322+ }
323+
324+ mbps = ret * 2;
325+ do_div(mbps, 1000000);
307326
308327 return mbps;
309328 }
drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c+89−19
@@ -13,42 +13,83 @@ · 12 unmodified lines
1313
1414 static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = {
1515 {
16− .code = MEDIA_BUS_FMT_UYVY8_1X16,
16+ .codes = {
17+ MEDIA_BUS_FMT_UYVY8_1X16,
18+ },
1719 .datatype = MIPI_CSI2_DT_YUV422_8B,
1820 .format = V4L2_PIX_FMT_UYVY,
19− .bpp = 2,
2021 .icndmr = ICnDMR_YCMODE_UYVY,
2122 .yuv = true,
2223 },
2324 {
24− .code = MEDIA_BUS_FMT_SBGGR8_1X8,
25+ .codes = {
26+ MEDIA_BUS_FMT_SBGGR8_1X8,
27+ },
2528 .format = V4L2_PIX_FMT_SBGGR8,
2629 .datatype = MIPI_CSI2_DT_RAW8,
27− .bpp = 1,
2830 .icndmr = 0,
2931 .yuv = false,
3032 },
3133 {
32− .code = MEDIA_BUS_FMT_SGBRG8_1X8,
34+ .codes = {
35+ MEDIA_BUS_FMT_SGBRG8_1X8,
36+ },
3337 .format = V4L2_PIX_FMT_SGBRG8,
3438 .datatype = MIPI_CSI2_DT_RAW8,
35− .bpp = 1,
3639 .icndmr = 0,
3740 .yuv = false,
3841 },
3942 {
40− .code = MEDIA_BUS_FMT_SGRBG8_1X8,
43+ .codes = {
44+ MEDIA_BUS_FMT_SGRBG8_1X8,
45+ },
4146 .format = V4L2_PIX_FMT_SGRBG8,
4247 .datatype = MIPI_CSI2_DT_RAW8,
43− .bpp = 1,
4448 .icndmr = 0,
4549 .yuv = false,
4650 },
4751 {
48− .code = MEDIA_BUS_FMT_SRGGB8_1X8,
52+ .codes = {
53+ MEDIA_BUS_FMT_SRGGB8_1X8,
54+ },
4955 .format = V4L2_PIX_FMT_SRGGB8,
5056 .datatype = MIPI_CSI2_DT_RAW8,
51− .bpp = 1,
57+ .icndmr = 0,
58+ .yuv = false,
59+ },
60+ {
61+ .codes = {
62+ MEDIA_BUS_FMT_SBGGR10_1X10,
63+ MEDIA_BUS_FMT_SGBRG10_1X10,
64+ MEDIA_BUS_FMT_SGRBG10_1X10,
65+ MEDIA_BUS_FMT_SRGGB10_1X10
66+ },
67+ .format = V4L2_PIX_FMT_RAW_CRU10,
68+ .datatype = MIPI_CSI2_DT_RAW10,
69+ .icndmr = 0,
70+ .yuv = false,
71+ },
72+ {
73+ .codes = {
74+ MEDIA_BUS_FMT_SBGGR12_1X12,
75+ MEDIA_BUS_FMT_SGBRG12_1X12,
76+ MEDIA_BUS_FMT_SGRBG12_1X12,
77+ MEDIA_BUS_FMT_SRGGB12_1X12
78+ },
79+ .format = V4L2_PIX_FMT_RAW_CRU12,
80+ .datatype = MIPI_CSI2_DT_RAW12,
81+ .icndmr = 0,
82+ .yuv = false,
83+ },
84+ {
85+ .codes = {
86+ MEDIA_BUS_FMT_SBGGR14_1X14,
87+ MEDIA_BUS_FMT_SGBRG14_1X14,
88+ MEDIA_BUS_FMT_SGRBG14_1X14,
89+ MEDIA_BUS_FMT_SRGGB14_1X14
90+ },
91+ .format = V4L2_PIX_FMT_RAW_CRU14,
92+ .datatype = MIPI_CSI2_DT_RAW14,
5293 .icndmr = 0,
5394 .yuv = false,
5495 },
@@ -56,11 +97,14 @@ static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = { · 1 unmodified line
5697
5798 const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code)
5899 {
59− unsigned int i;
100+ unsigned int i, j;
60101
61− for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++)
62− if (rzg2l_cru_ip_formats[i].code == code)
63− return &rzg2l_cru_ip_formats[i];
102+ for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) {
103+ for (j = 0; j < ARRAY_SIZE(rzg2l_cru_ip_formats[i].codes); j++) {
104+ if (rzg2l_cru_ip_formats[i].codes[j] == code)
105+ return &rzg2l_cru_ip_formats[i];
106+ }
107+ }
64108
65109 return NULL;
66110 }
@@ -85,6 +129,17 @@ const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index) · 18 unmodified lines
85129 return &rzg2l_cru_ip_formats[index];
86130 }
87131
132+bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt,
133+ unsigned int code)
134+{
135+ unsigned int i;
136+
137+ for (i = 0; i < ARRAY_SIZE(fmt->codes); i++)
138+ if (fmt->codes[i] == code)
139+ return true;
140+
141+ return false;
142+}
88143 struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru)
89144 {
90145 struct v4l2_subdev_state *state;
@@ -162,7 +217,7 @@ static int rzg2l_cru_ip_set_format(struct v4l2_subdev *sd, · 71 unmodified lines
162217 sink_format = v4l2_subdev_state_get_format(state, fmt->pad);
163218
164219 if (!rzg2l_cru_ip_code_to_fmt(fmt->format.code))
165− sink_format->code = rzg2l_cru_ip_formats[0].code;
220+ sink_format->code = rzg2l_cru_ip_formats[0].codes[0];
166221 else
167222 sink_format->code = fmt->format.code;
168223
@@ -188,11 +243,26 @@ static int rzg2l_cru_ip_enum_mbus_code(struct v4l2_subdev *sd, · 19 unmodified lines
188243 struct v4l2_subdev_state *state,
189244 struct v4l2_subdev_mbus_code_enum *code)
190245 {
191− if (code->index >= ARRAY_SIZE(rzg2l_cru_ip_formats))
192− return -EINVAL;
246+ unsigned int index = code->index;
247+ unsigned int i, j;
193248
194− code->code = rzg2l_cru_ip_formats[code->index].code;
195− return 0;
249+ for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) {
250+ const struct rzg2l_cru_ip_format *fmt = &rzg2l_cru_ip_formats[i];
251+
252+ for (j = 0; j < ARRAY_SIZE(fmt->codes); j++) {
253+ if (!fmt->codes[j])
254+ continue;
255+
256+ if (!index) {
257+ code->code = fmt->codes[j];
258+ return 0;
259+ }
260+
261+ index--;
262+ }
263+ }
264+
265+ return -EINVAL;
196266 }
197267
198268 static int rzg2l_cru_ip_enum_frame_size(struct v4l2_subdev *sd,
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c+29−13
@@ -323,7 +323,7 @@ static int rzg2l_cru_initialize_image_conv(struct rzg2l_cru_dev *cru, · 322 unmodified lines
323323 return 0;
324324 }
325325
326−bool rz3e_fifo_empty(struct rzg2l_cru_dev *cru)
326+bool rzg3e_fifo_empty(struct rzg2l_cru_dev *cru)
327327 {
328328 u32 amnfifopntr = rzg2l_cru_read(cru, AMnFIFOPNTR);
329329
@@ -345,8 +345,6 @@ bool rzg2l_fifo_empty(struct rzg2l_cru_dev *cru) · 15 unmodified lines
345345 amnfifopntr_w = amnfifopntr & AMnFIFOPNTR_FIFOWPNTR;
346346 amnfifopntr_r_y =
347347 (amnfifopntr & AMnFIFOPNTR_FIFORPNTR_Y) >> 16;
348− if (amnfifopntr_w == amnfifopntr_r_y)
349− return true;
350348
351349 return amnfifopntr_w == amnfifopntr_r_y;
352350 }
@@ -941,15 +939,7 @@ static void rzg2l_cru_format_align(struct rzg2l_cru_dev *cru, · 588 unmodified lines
941939 v4l_bound_align_image(&pix->width, 320, info->max_width, 1,
942940 &pix->height, 240, info->max_height, 2, 0);
943941
944− if (info->has_stride) {
945− u32 stride = clamp(pix->bytesperline, pix->width * fmt->bpp,
946− RZG2L_CRU_STRIDE_MAX);
947− pix->bytesperline = round_up(stride, RZG2L_CRU_STRIDE_ALIGN);
948− } else {
949− pix->bytesperline = pix->width * fmt->bpp;
950− }
951−
952− pix->sizeimage = pix->bytesperline * pix->height;
942+ v4l2_fill_pixfmt(pix, pix->pixelformat, pix->width, pix->height);
953943
954944 dev_dbg(cru->dev, "Format %ux%u bpl: %u size: %u\n",
955945 pix->width, pix->height, pix->bytesperline, pix->sizeimage);
@@ -1031,6 +1021,31 @@ static int rzg2l_cru_enum_fmt_vid_cap(struct file *file, void *priv, · 75 unmodified lines
10311021 return 0;
10321022 }
10331023
1024+static int rzg2l_cru_enum_framesizes(struct file *file, void *fh,
1025+ struct v4l2_frmsizeenum *fsize)
1026+{
1027+ struct rzg2l_cru_dev *cru = video_drvdata(file);
1028+ const struct rzg2l_cru_info *info = cru->info;
1029+ const struct rzg2l_cru_ip_format *fmt;
1030+
1031+ if (fsize->index)
1032+ return -EINVAL;
1033+
1034+ fmt = rzg2l_cru_ip_format_to_fmt(fsize->pixel_format);
1035+ if (!fmt)
1036+ return -EINVAL;
1037+
1038+ fsize->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1039+ fsize->stepwise.min_width = RZG2L_CRU_MIN_INPUT_WIDTH;
1040+ fsize->stepwise.max_width = info->max_width;
1041+ fsize->stepwise.step_width = 1;
1042+ fsize->stepwise.min_height = RZG2L_CRU_MIN_INPUT_HEIGHT;
1043+ fsize->stepwise.max_height = info->max_height;
1044+ fsize->stepwise.step_height = 1;
1045+
1046+ return 0;
1047+}
1048+
10341049 static const struct v4l2_ioctl_ops rzg2l_cru_ioctl_ops = {
10351050 .vidioc_querycap = rzg2l_cru_querycap,
10361051 .vidioc_try_fmt_vid_cap = rzg2l_cru_try_fmt_vid_cap,
@@ -1047,6 +1062,7 @@ static const struct v4l2_ioctl_ops rzg2l_cru_ioctl_ops = { · 10 unmodified lines
10471062 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
10481063 .vidioc_streamon = vb2_ioctl_streamon,
10491064 .vidioc_streamoff = vb2_ioctl_streamoff,
1065+ .vidioc_enum_framesizes = rzg2l_cru_enum_framesizes,
10501066 };
10511067
10521068 /* -----------------------------------------------------------------------------
@@ -1129,7 +1145,7 @@ static int rzg2l_cru_video_link_validate(struct media_link *link) · 76 unmodified lines
11291145 if (fmt.format.width != cru->format.width ||
11301146 fmt.format.height != cru->format.height ||
11311147 fmt.format.field != cru->format.field ||
1132− video_fmt->code != fmt.format.code)
1148+ !rzg2l_cru_ip_fmt_supports_mbus_code(video_fmt, fmt.format.code))
11331149 return -EPIPE;
11341150
11351151 return 0;
drivers/media/platform/renesas/vsp1/Makefile+1−0
@@ -6,5 +6,6 @@ vsp1-y += vsp1_clu.o vsp1_hsit.o vsp1_lut.o · 5 unmodified lines
66 vsp1-y += vsp1_brx.o vsp1_sru.o vsp1_uds.o
77 vsp1-y += vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
88 vsp1-y += vsp1_iif.o vsp1_lif.o vsp1_uif.o
9+vsp1-y += vsp1_vspx.o
910
1011 obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o
drivers/media/platform/renesas/vsp1/vsp1.h+1−0
@@ -111,6 +111,7 @@ struct vsp1_device { · 110 unmodified lines
111111 struct media_entity_operations media_ops;
112112
113113 struct vsp1_drm *drm;
114+ struct vsp1_vspx *vspx;
114115 };
115116
116117 int vsp1_device_get(struct vsp1_device *vsp1);
drivers/media/platform/renesas/vsp1/vsp1_dl.c+25−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/device.h>
1111 #include <linux/dma-mapping.h>
1212 #include <linux/gfp.h>
13+#include <linux/lockdep.h>
1314 #include <linux/refcount.h>
1415 #include <linux/slab.h>
1516 #include <linux/workqueue.h>
@@ -176,6 +177,7 @@ struct vsp1_dl_cmd_pool { · 160 unmodified lines
176177 * @bodies: list of extra display list bodies
177178 * @pre_cmd: pre command to be issued through extended dl header
178179 * @post_cmd: post command to be issued through extended dl header
180+ * @allocated: flag to detect double list release
179181 * @has_chain: if true, indicates that there's a partition chain
180182 * @chain: entry in the display list partition chain
181183 * @flags: display list flags, a combination of VSP1_DL_FRAME_END_*
@@ -194,6 +196,8 @@ struct vsp1_dl_list { · 12 unmodified lines
194196 struct vsp1_dl_ext_cmd *pre_cmd;
195197 struct vsp1_dl_ext_cmd *post_cmd;
196198
199+ bool allocated;
200+
197201 bool has_chain;
198202 struct list_head chain;
199203
@@ -212,6 +216,7 @@ struct vsp1_dl_list { · 12 unmodified lines
212216 * @pending: list waiting to be queued to the hardware
213217 * @pool: body pool for the display list bodies
214218 * @cmdpool: commands pool for extended display list
219+ * @list_count: number of allocated display lists
215220 */
216221 struct vsp1_dl_manager {
217222 unsigned int index;
@@ -226,6 +231,8 @@ struct vsp1_dl_manager { · 8 unmodified lines
226231
227232 struct vsp1_dl_body_pool *pool;
228233 struct vsp1_dl_cmd_pool *cmdpool;
234+
235+ size_t list_count;
229236 };
230237
231238 /* -----------------------------------------------------------------------------
@@ -606,6 +613,8 @@ struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm) · 374 unmodified lines
606613 struct vsp1_dl_list *dl = NULL;
607614 unsigned long flags;
608615
616+ lockdep_assert_not_held(&dlm->lock);
617+
609618 spin_lock_irqsave(&dlm->lock, flags);
610619
611620 if (!list_empty(&dlm->free)) {
@@ -617,6 +626,7 @@ struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm) · 5 unmodified lines
617626 * display list can assert list_empty() if it is not in a chain.
618627 */
619628 INIT_LIST_HEAD(&dl->chain);
629+ dl->allocated = true;
620630 }
621631
622632 spin_unlock_irqrestore(&dlm->lock, flags);
@@ -632,6 +642,8 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl) · 9 unmodified lines
632642 if (!dl)
633643 return;
634644
645+ lockdep_assert_held(&dl->dlm->lock);
646+
635647 /*
636648 * Release any linked display-lists which were chained for a single
637649 * hardware operation.
@@ -657,6 +669,13 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl) · 19 unmodified lines
657669 */
658670 dl->body0->num_entries = 0;
659671
672+ /*
673+ * Return the display list to the 'free' pool. If the list had already
674+ * been returned be loud about it.
675+ */
676+ WARN_ON_ONCE(!dl->allocated);
677+ dl->allocated = false;
678+
660679 list_add_tail(&dl->list, &dl->dlm->free);
661680 }
662681
@@ -1067,6 +1086,7 @@ void vsp1_dlm_setup(struct vsp1_device *vsp1) · 404 unmodified lines
10671086 void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
10681087 {
10691088 unsigned long flags;
1089+ size_t list_count;
10701090
10711091 spin_lock_irqsave(&dlm->lock, flags);
10721092
@@ -1074,8 +1094,11 @@ void vsp1_dlm_reset(struct vsp1_dl_manager *dlm) · 1 unmodified line
10741094 __vsp1_dl_list_put(dlm->queued);
10751095 __vsp1_dl_list_put(dlm->pending);
10761096
1097+ list_count = list_count_nodes(&dlm->free);
10771098 spin_unlock_irqrestore(&dlm->lock, flags);
10781099
1100+ WARN_ON_ONCE(list_count != dlm->list_count);
1101+
10791102 dlm->active = NULL;
10801103 dlm->queued = NULL;
10811104 dlm->pending = NULL;
@@ -1145,6 +1168,8 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, · 63 unmodified lines
11451168 list_add_tail(&dl->list, &dlm->free);
11461169 }
11471170
1171+ dlm->list_count = prealloc;
1172+
11481173 if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) {
11491174 dlm->cmdpool = vsp1_dl_cmd_pool_create(vsp1,
11501175 VSP1_EXTCMD_AUTOFLD, prealloc);
drivers/media/platform/renesas/vsp1/vsp1_drm.c+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
99
1010 #include <linux/device.h>
1111 #include <linux/dma-mapping.h>
12+#include <linux/export.h>
1213 #include <linux/slab.h>
1314
1415 #include <media/media-entity.h>
drivers/media/platform/renesas/vsp1/vsp1_drv.c+20−2
@@ -33,11 +33,13 @@ · 32 unmodified lines
3333 #include "vsp1_lif.h"
3434 #include "vsp1_lut.h"
3535 #include "vsp1_pipe.h"
36+#include "vsp1_regs.h"
3637 #include "vsp1_rwpf.h"
3738 #include "vsp1_sru.h"
3839 #include "vsp1_uds.h"
3940 #include "vsp1_uif.h"
4041 #include "vsp1_video.h"
42+#include "vsp1_vspx.h"
4143
4244 /* -----------------------------------------------------------------------------
4345 * Interrupt Handling
@@ -490,7 +492,10 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) · 446 unmodified lines
490492
491493 ret = media_device_register(mdev);
492494 } else {
493− ret = vsp1_drm_init(vsp1);
495+ if (vsp1->info->version == VI6_IP_VERSION_MODEL_VSPX_GEN4)
496+ ret = vsp1_vspx_init(vsp1);
497+ else
498+ ret = vsp1_drm_init(vsp1);
494499 }
495500
496501 done:
@@ -502,7 +507,9 @@ done: · 5 unmodified lines
502507
503508 int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index)
504509 {
510+ u32 version = vsp1->version & VI6_IP_VERSION_MODEL_MASK;
505511 unsigned int timeout;
512+ int ret = 0;
506513 u32 status;
507514
508515 status = vsp1_read(vsp1, VI6_STATUS);
@@ -523,7 +530,11 @@ int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index) · 14 unmodified lines
523530 return -ETIMEDOUT;
524531 }
525532
526− return 0;
533+ if (version == VI6_IP_VERSION_MODEL_VSPD_GEN3 ||
534+ version == VI6_IP_VERSION_MODEL_VSPD_GEN4)
535+ ret = rcar_fcp_soft_reset(vsp1->fcp);
536+
537+ return ret;
527538 }
528539
529540 static int vsp1_device_init(struct vsp1_device *vsp1)
@@ -851,6 +862,13 @@ static const struct vsp1_device_info vsp1_device_infos[] = { · 321 unmodified lines
851862 .uif_count = 2,
852863 .wpf_count = 1,
853864 .num_bru_inputs = 5,
865+ }, {
866+ .version = VI6_IP_VERSION_MODEL_VSPX_GEN4,
867+ .model = "VSP2-X",
868+ .gen = 4,
869+ .features = VSP1_HAS_IIF,
870+ .rpf_count = 2,
871+ .wpf_count = 1,
854872 },
855873 };
856874
drivers/media/platform/renesas/vsp1/vsp1_pipe.c+3−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
99
1010 #include <linux/delay.h>
1111 #include <linux/list.h>
12+#include <linux/lockdep.h>
1213 #include <linux/sched.h>
1314 #include <linux/wait.h>
1415
@@ -473,6 +474,8 @@ void vsp1_pipeline_run(struct vsp1_pipeline *pipe) · 458 unmodified lines
473474 {
474475 struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
475476
477+ lockdep_assert_held(&pipe->irqlock);
478+
476479 if (pipe->state == VSP1_PIPELINE_STOPPED) {
477480 vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index),
478481 VI6_CMD_STRCMD);
drivers/media/platform/renesas/vsp1/vsp1_regs.h+1−0
@@ -799,6 +799,7 @@ · 798 unmodified lines
799799 #define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)
800800 #define VI6_IP_VERSION_MODEL_VSPBS_GEN3 (0x1a << 8)
801801 #define VI6_IP_VERSION_MODEL_VSPD_GEN4 (0x1c << 8)
802+#define VI6_IP_VERSION_MODEL_VSPX_GEN4 (0x1d << 8)
802803 /* RZ/G2L SoCs have no version register, So use 0x80 as the model version */
803804 #define VI6_IP_VERSION_MODEL_VSPD_RZG2L (0x80 << 8)
804805
drivers/media/platform/renesas/vsp1/vsp1_vspx.c+633−0
@@ -0,0 +1,633 @@
1+// SPDX-License-Identifier: GPL-2.0+
2+/*
3+ * vsp1_vspx.c -- R-Car Gen 4 VSPX
4+ *
5+ * Copyright (C) 2025 Ideas On Board Oy
6+ * Copyright (C) 2025 Renesas Electronics Corporation
7+ */
8+
9+#include "vsp1_vspx.h"
10+
11+#include <linux/cleanup.h>
12+#include <linux/container_of.h>
13+#include <linux/delay.h>
14+#include <linux/device.h>
15+#include <linux/dma-mapping.h>
16+#include <linux/export.h>
17+#include <linux/list.h>
18+#include <linux/slab.h>
19+#include <linux/spinlock.h>
20+
21+#include <media/media-entity.h>
22+#include <media/v4l2-subdev.h>
23+#include <media/vsp1.h>
24+
25+#include "vsp1_dl.h"
26+#include "vsp1_iif.h"
27+#include "vsp1_pipe.h"
28+#include "vsp1_rwpf.h"
29+
30+/*
31+ * struct vsp1_vspx_pipeline - VSPX pipeline
32+ * @pipe: the VSP1 pipeline
33+ * @partition: the pre-calculated partition used by the pipeline
34+ * @mutex: protects the streaming start/stop sequences
35+ * @lock: protect access to the enabled flag
36+ * @enabled: the enable flag
37+ * @vspx_frame_end: frame end callback
38+ * @frame_end_data: data for the frame end callback
39+ */
40+struct vsp1_vspx_pipeline {
41+ struct vsp1_pipeline pipe;
42+ struct vsp1_partition partition;
43+
44+ /*
45+ * Protects the streaming start/stop sequences.
46+ *
47+ * The start/stop sequences cannot be locked with the 'lock' spinlock
48+ * as they acquire mutexes when handling the pm runtime and the vsp1
49+ * pipe start/stop operations. Provide a dedicated mutex for this
50+ * reason.
51+ */
52+ struct mutex mutex;
53+
54+ /*
55+ * Protects the enable flag.
56+ *
57+ * The enabled flag is contended between the start/stop streaming
58+ * routines and the job_run one, which cannot take a mutex as it is
59+ * called from the ISP irq context.
60+ */
61+ spinlock_t lock;
62+ bool enabled;
63+
64+ void (*vspx_frame_end)(void *frame_end_data);
65+ void *frame_end_data;
66+};
67+
68+static inline struct vsp1_vspx_pipeline *
69+to_vsp1_vspx_pipeline(struct vsp1_pipeline *pipe)
70+{
71+ return container_of(pipe, struct vsp1_vspx_pipeline, pipe);
72+}
73+
74+/*
75+ * struct vsp1_vspx - VSPX device
76+ * @vsp1: the VSP1 device
77+ * @pipe: the VSPX pipeline
78+ */
79+struct vsp1_vspx {
80+ struct vsp1_device *vsp1;
81+ struct vsp1_vspx_pipeline pipe;
82+};
83+
84+/* Apply the given width, height and fourcc to the RWPF's subdevice */
85+static int vsp1_vspx_rwpf_set_subdev_fmt(struct vsp1_device *vsp1,
86+ struct vsp1_rwpf *rwpf,
87+ u32 isp_fourcc,
88+ unsigned int width,
89+ unsigned int height)
90+{
91+ struct vsp1_entity *ent = &rwpf->entity;
92+ struct v4l2_subdev_format format = {};
93+ u32 vspx_fourcc;
94+
95+ switch (isp_fourcc) {
96+ case V4L2_PIX_FMT_GREY:
97+ /* 8 bit RAW Bayer image. */
98+ vspx_fourcc = V4L2_PIX_FMT_RGB332;
99+ break;
100+ case V4L2_PIX_FMT_Y10:
101+ case V4L2_PIX_FMT_Y12:
102+ case V4L2_PIX_FMT_Y16:
103+ /* 10, 12 and 16 bit RAW Bayer image. */
104+ vspx_fourcc = V4L2_PIX_FMT_RGB565;
105+ break;
106+ case V4L2_META_FMT_GENERIC_8:
107+ /* ConfigDMA parameters buffer. */
108+ vspx_fourcc = V4L2_PIX_FMT_XBGR32;
109+ break;
110+ default:
111+ return -EINVAL;
112+ }
113+
114+ rwpf->fmtinfo = vsp1_get_format_info(vsp1, vspx_fourcc);
115+
116+ format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
117+ format.pad = RWPF_PAD_SINK;
118+ format.format.width = width;
119+ format.format.height = height;
120+ format.format.field = V4L2_FIELD_NONE;
121+ format.format.code = rwpf->fmtinfo->mbus;
122+
123+ return v4l2_subdev_call(&ent->subdev, pad, set_fmt, NULL, &format);
124+}
125+
126+/* Configure the RPF->IIF->WPF pipeline for ConfigDMA or RAW image transfer. */
127+static int vsp1_vspx_pipeline_configure(struct vsp1_device *vsp1,
128+ dma_addr_t addr, u32 isp_fourcc,
129+ unsigned int width, unsigned int height,
130+ unsigned int stride,
131+ unsigned int iif_sink_pad,
132+ struct vsp1_dl_list *dl,
133+ struct vsp1_dl_body *dlb)
134+{
135+ struct vsp1_vspx_pipeline *vspx_pipe = &vsp1->vspx->pipe;
136+ struct vsp1_pipeline *pipe = &vspx_pipe->pipe;
137+ struct vsp1_rwpf *rpf0 = pipe->inputs[0];
138+ int ret;
139+
140+ ret = vsp1_vspx_rwpf_set_subdev_fmt(vsp1, rpf0, isp_fourcc, width,
141+ height);
142+ if (ret)
143+ return ret;
144+
145+ ret = vsp1_vspx_rwpf_set_subdev_fmt(vsp1, pipe->output, isp_fourcc,
146+ width, height);
147+ if (ret)
148+ return ret;
149+
150+ vsp1_pipeline_calculate_partition(pipe, &pipe->part_table[0], width, 0);
151+ rpf0->format.plane_fmt[0].bytesperline = stride;
152+ rpf0->format.num_planes = 1;
153+ rpf0->mem.addr[0] = addr;
154+
155+ /*
156+ * Connect RPF0 to the IIF sink pad corresponding to the config or image
157+ * path.
158+ */
159+ rpf0->entity.sink_pad = iif_sink_pad;
160+
161+ vsp1_entity_route_setup(&rpf0->entity, pipe, dlb);
162+ vsp1_entity_configure_stream(&rpf0->entity, rpf0->entity.state, pipe,
163+ dl, dlb);
164+ vsp1_entity_configure_partition(&rpf0->entity, pipe,
165+ &pipe->part_table[0], dl, dlb);
166+
167+ return 0;
168+}
169+
170+/* -----------------------------------------------------------------------------
171+ * Interrupt handling
172+ */
173+
174+static void vsp1_vspx_pipeline_frame_end(struct vsp1_pipeline *pipe,
175+ unsigned int completion)
176+{
177+ struct vsp1_vspx_pipeline *vspx_pipe = to_vsp1_vspx_pipeline(pipe);
178+
179+ scoped_guard(spinlock_irqsave, &pipe->irqlock) {
180+ /*
181+ * Operating the vsp1_pipe in singleshot mode requires to
182+ * manually set the pipeline state to stopped when a transfer
183+ * is completed.
184+ */
185+ pipe->state = VSP1_PIPELINE_STOPPED;
186+ }
187+
188+ if (vspx_pipe->vspx_frame_end)
189+ vspx_pipe->vspx_frame_end(vspx_pipe->frame_end_data);
190+}
191+
192+/* -----------------------------------------------------------------------------
193+ * ISP Driver API (include/media/vsp1.h)
194+ */
195+
196+/**
197+ * vsp1_isp_init() - Initialize the VSPX
198+ * @dev: The VSP1 struct device
199+ *
200+ * Return: %0 on success or a negative error code on failure
201+ */
202+int vsp1_isp_init(struct device *dev)
203+{
204+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
205+
206+ if (!vsp1)
207+ return -EPROBE_DEFER;
208+
209+ return 0;
210+}
211+EXPORT_SYMBOL_GPL(vsp1_isp_init);
212+
213+/**
214+ * vsp1_isp_get_bus_master - Get VSPX bus master
215+ * @dev: The VSP1 struct device
216+ *
217+ * The VSPX accesses memory through an FCPX instance. When allocating memory
218+ * buffers that will have to be accessed by the VSPX the 'struct device' of
219+ * the FCPX should be used. Use this function to get a reference to it.
220+ *
221+ * Return: a pointer to the bus master's device
222+ */
223+struct device *vsp1_isp_get_bus_master(struct device *dev)
224+{
225+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
226+
227+ if (!vsp1)
228+ return ERR_PTR(-ENODEV);
229+
230+ return vsp1->bus_master;
231+}
232+EXPORT_SYMBOL_GPL(vsp1_isp_get_bus_master);
233+
234+/**
235+ * vsp1_isp_alloc_buffer - Allocate a buffer in the VSPX address space
236+ * @dev: The VSP1 struct device
237+ * @size: The size of the buffer to be allocated by the VSPX
238+ * @buffer_desc: The buffer descriptor. Will be filled with the buffer
239+ * CPU-mapped address, the bus address and the size of the
240+ * allocated buffer
241+ *
242+ * Allocate a buffer that will be later accessed by the VSPX. Buffers allocated
243+ * using vsp1_isp_alloc_buffer() shall be released with a call to
244+ * vsp1_isp_free_buffer(). This function is used by the ISP driver to allocate
245+ * memory for the ConfigDMA parameters buffer.
246+ *
247+ * Return: %0 on success or a negative error code on failure
248+ */
249+int vsp1_isp_alloc_buffer(struct device *dev, size_t size,
250+ struct vsp1_isp_buffer_desc *buffer_desc)
251+{
252+ struct device *bus_master = vsp1_isp_get_bus_master(dev);
253+
254+ if (IS_ERR_OR_NULL(bus_master))
255+ return -ENODEV;
256+
257+ buffer_desc->cpu_addr = dma_alloc_coherent(bus_master, size,
258+ &buffer_desc->dma_addr,
259+ GFP_KERNEL);
260+ if (!buffer_desc->cpu_addr)
261+ return -ENOMEM;
262+
263+ buffer_desc->size = size;
264+
265+ return 0;
266+}
267+EXPORT_SYMBOL_GPL(vsp1_isp_alloc_buffer);
268+
269+/**
270+ * vsp1_isp_free_buffer - Release a buffer allocated by vsp1_isp_alloc_buffer()
271+ * @dev: The VSP1 struct device
272+ * @buffer_desc: The descriptor of the buffer to release as returned by
273+ * vsp1_isp_alloc_buffer()
274+ *
275+ * Release memory in the VSPX address space allocated by
276+ * vsp1_isp_alloc_buffer().
277+ */
278+void vsp1_isp_free_buffer(struct device *dev,
279+ struct vsp1_isp_buffer_desc *buffer_desc)
280+{
281+ struct device *bus_master = vsp1_isp_get_bus_master(dev);
282+
283+ if (IS_ERR_OR_NULL(bus_master))
284+ return;
285+
286+ dma_free_coherent(bus_master, buffer_desc->size, buffer_desc->cpu_addr,
287+ buffer_desc->dma_addr);
288+}
289+
290+/**
291+ * vsp1_isp_start_streaming - Start processing VSPX jobs
292+ * @dev: The VSP1 struct device
293+ * @frame_end: The frame end callback description
294+ *
295+ * Start the VSPX and prepare for accepting buffer transfer job requests.
296+ * The caller is responsible for tracking the started state of the VSPX.
297+ * Attempting to start an already started VSPX instance is an error.
298+ *
299+ * Return: %0 on success or a negative error code on failure
300+ */
301+int vsp1_isp_start_streaming(struct device *dev,
302+ struct vsp1_vspx_frame_end *frame_end)
303+{
304+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
305+ struct vsp1_vspx_pipeline *vspx_pipe = &vsp1->vspx->pipe;
306+ struct vsp1_pipeline *pipe = &vspx_pipe->pipe;
307+ u32 value;
308+ int ret;
309+
310+ if (!frame_end)
311+ return -EINVAL;
312+
313+ guard(mutex)(&vspx_pipe->mutex);
314+
315+ scoped_guard(spinlock_irq, &vspx_pipe->lock) {
316+ if (vspx_pipe->enabled)
317+ return -EBUSY;
318+ }
319+
320+ vspx_pipe->vspx_frame_end = frame_end->vspx_frame_end;
321+ vspx_pipe->frame_end_data = frame_end->frame_end_data;
322+
323+ /* Enable the VSP1 and prepare for streaming. */
324+ vsp1_pipeline_dump(pipe, "VSPX job");
325+
326+ ret = vsp1_device_get(vsp1);
327+ if (ret < 0)
328+ return ret;
329+
330+ /*
331+ * Make sure VSPX is not active. This should never happen in normal
332+ * usage
333+ */
334+ value = vsp1_read(vsp1, VI6_CMD(0));
335+ if (value & VI6_CMD_STRCMD) {
336+ dev_err(vsp1->dev,
337+ "%s: Starting of WPF0 already reserved\n", __func__);
338+ ret = -EBUSY;
339+ goto error_put;
340+ }
341+
342+ value = vsp1_read(vsp1, VI6_STATUS);
343+ if (value & VI6_STATUS_SYS_ACT(0)) {
344+ dev_err(vsp1->dev,
345+ "%s: WPF0 has not entered idle state\n", __func__);
346+ ret = -EBUSY;
347+ goto error_put;
348+ }
349+
350+ scoped_guard(spinlock_irq, &vspx_pipe->lock) {
351+ vspx_pipe->enabled = true;
352+ }
353+
354+ return 0;
355+
356+error_put:
357+ vsp1_device_put(vsp1);
358+ return ret;
359+}
360+EXPORT_SYMBOL_GPL(vsp1_isp_start_streaming);
361+
362+/**
363+ * vsp1_isp_stop_streaming - Stop the VSPX
364+ * @dev: The VSP1 struct device
365+ *
366+ * Stop the VSPX operation by stopping the vsp1 pipeline and waiting for the
367+ * last frame in transfer, if any, to complete.
368+ *
369+ * The caller is responsible for tracking the stopped state of the VSPX.
370+ * Attempting to stop an already stopped VSPX instance is a nop.
371+ */
372+void vsp1_isp_stop_streaming(struct device *dev)
373+{
374+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
375+ struct vsp1_vspx_pipeline *vspx_pipe = &vsp1->vspx->pipe;
376+ struct vsp1_pipeline *pipe = &vspx_pipe->pipe;
377+
378+ guard(mutex)(&vspx_pipe->mutex);
379+
380+ scoped_guard(spinlock_irq, &vspx_pipe->lock) {
381+ if (!vspx_pipe->enabled)
382+ return;
383+
384+ vspx_pipe->enabled = false;
385+ }
386+
387+ WARN_ON_ONCE(vsp1_pipeline_stop(pipe));
388+
389+ vspx_pipe->vspx_frame_end = NULL;
390+ vsp1_dlm_reset(pipe->output->dlm);
391+ vsp1_device_put(vsp1);
392+}
393+EXPORT_SYMBOL_GPL(vsp1_isp_stop_streaming);
394+
395+/**
396+ * vsp1_isp_job_prepare - Prepare a new buffer transfer job
397+ * @dev: The VSP1 struct device
398+ * @job: The job description
399+ *
400+ * Prepare a new buffer transfer job by populating a display list that will be
401+ * later executed by a call to vsp1_isp_job_run(). All pending jobs must be
402+ * released after stopping the streaming operations with a call to
403+ * vsp1_isp_job_release().
404+ *
405+ * In order for the VSPX to accept new jobs to prepare the VSPX must have been
406+ * started.
407+ *
408+ * Return: %0 on success or a negative error code on failure
409+ */
410+int vsp1_isp_job_prepare(struct device *dev, struct vsp1_isp_job_desc *job)
411+{
412+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
413+ struct vsp1_vspx_pipeline *vspx_pipe = &vsp1->vspx->pipe;
414+ struct vsp1_pipeline *pipe = &vspx_pipe->pipe;
415+ const struct v4l2_pix_format_mplane *pix_mp;
416+ struct vsp1_dl_list *second_dl = NULL;
417+ struct vsp1_dl_body *dlb;
418+ struct vsp1_dl_list *dl;
419+ int ret;
420+
421+ /*
422+ * Transfer the buffers described in the job: an optional ConfigDMA
423+ * parameters buffer and a RAW image.
424+ */
425+
426+ job->dl = vsp1_dl_list_get(pipe->output->dlm);
427+ if (!job->dl)
428+ return -ENOMEM;
429+
430+ dl = job->dl;
431+ dlb = vsp1_dl_list_get_body0(dl);
432+
433+ /* Configure IIF routing and enable IIF function. */
434+ vsp1_entity_route_setup(pipe->iif, pipe, dlb);
435+ vsp1_entity_configure_stream(pipe->iif, pipe->iif->state, pipe,
436+ dl, dlb);
437+
438+ /* Configure WPF0 to enable RPF0 as source. */
439+ vsp1_entity_route_setup(&pipe->output->entity, pipe, dlb);
440+ vsp1_entity_configure_stream(&pipe->output->entity,
441+ pipe->output->entity.state, pipe,
442+ dl, dlb);
443+
444+ if (job->config.pairs) {
445+ /*
446+ * Writing less than 17 pairs corrupts the output images ( < 16
447+ * pairs) or freezes the VSPX operations (= 16 pairs). Only
448+ * allow more than 16 pairs to be written.
449+ */
450+ if (job->config.pairs <= 16) {
451+ ret = -EINVAL;
452+ goto error_put_dl;
453+ }
454+
455+ /*
456+ * Configure RPF0 for ConfigDMA data. Transfer the number of
457+ * configuration pairs plus 2 words for the header.
458+ */
459+ ret = vsp1_vspx_pipeline_configure(vsp1, job->config.mem,
460+ V4L2_META_FMT_GENERIC_8,
461+ job->config.pairs * 2 + 2, 1,
462+ job->config.pairs * 2 + 2,
463+ VSPX_IIF_SINK_PAD_CONFIG,
464+ dl, dlb);
465+ if (ret)
466+ goto error_put_dl;
467+
468+ second_dl = vsp1_dl_list_get(pipe->output->dlm);
469+ if (!second_dl) {
470+ ret = -ENOMEM;
471+ goto error_put_dl;
472+ }
473+
474+ dl = second_dl;
475+ dlb = vsp1_dl_list_get_body0(dl);
476+ }
477+
478+ /* Configure RPF0 for RAW image transfer. */
479+ pix_mp = &job->img.fmt;
480+ ret = vsp1_vspx_pipeline_configure(vsp1, job->img.mem,
481+ pix_mp->pixelformat,
482+ pix_mp->width, pix_mp->height,
483+ pix_mp->plane_fmt[0].bytesperline,
484+ VSPX_IIF_SINK_PAD_IMG, dl, dlb);
485+ if (ret)
486+ goto error_put_dl;
487+
488+ if (second_dl)
489+ vsp1_dl_list_add_chain(job->dl, second_dl);
490+
491+ return 0;
492+
493+error_put_dl:
494+ if (second_dl)
495+ vsp1_dl_list_put(second_dl);
496+ vsp1_dl_list_put(job->dl);
497+ job->dl = NULL;
498+ return ret;
499+}
500+EXPORT_SYMBOL_GPL(vsp1_isp_job_prepare);
501+
502+/**
503+ * vsp1_isp_job_run - Run a buffer transfer job
504+ * @dev: The VSP1 struct device
505+ * @job: The job to be run
506+ *
507+ * Run the display list contained in the job description provided by the caller.
508+ * The job must have been prepared with a call to vsp1_isp_job_prepare() and
509+ * the job's display list shall be valid.
510+ *
511+ * Jobs can be run only on VSPX instances which have been started. Requests
512+ * to run a job after the VSPX has been stopped return -EINVAL and the job
513+ * resources shall be released by the caller with vsp1_isp_job_release().
514+ * When a job is run successfully all the resources acquired by
515+ * vsp1_isp_job_prepare() are released by this function and no further action
516+ * is required to the caller.
517+ *
518+ * Return: %0 on success or a negative error code on failure
519+ */
520+int vsp1_isp_job_run(struct device *dev, struct vsp1_isp_job_desc *job)
521+{
522+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
523+ struct vsp1_vspx_pipeline *vspx_pipe = &vsp1->vspx->pipe;
524+ struct vsp1_pipeline *pipe = &vspx_pipe->pipe;
525+ u32 value;
526+
527+ /* Make sure VSPX is not busy processing a frame. */
528+ value = vsp1_read(vsp1, VI6_CMD(0));
529+ if (value) {
530+ dev_err(vsp1->dev,
531+ "%s: Starting of WPF0 already reserved\n", __func__);
532+ return -EBUSY;
533+ }
534+
535+ scoped_guard(spinlock_irqsave, &vspx_pipe->lock) {
536+ /*
537+ * If a new job is scheduled when the VSPX is stopped, do not
538+ * run it.
539+ */
540+ if (!vspx_pipe->enabled)
541+ return -EINVAL;
542+
543+ vsp1_dl_list_commit(job->dl, 0);
544+
545+ /*
546+ * The display list is now under control of the display list
547+ * manager and will be released automatically when the job
548+ * completes.
549+ */
550+ job->dl = NULL;
551+ }
552+
553+ scoped_guard(spinlock_irqsave, &pipe->irqlock) {
554+ vsp1_pipeline_run(pipe);
555+ }
556+
557+ return 0;
558+}
559+EXPORT_SYMBOL_GPL(vsp1_isp_job_run);
560+
561+/**
562+ * vsp1_isp_job_release - Release a non processed transfer job
563+ * @dev: The VSP1 struct device
564+ * @job: The job to release
565+ *
566+ * Release a job prepared by a call to vsp1_isp_job_prepare() and not yet
567+ * run. All pending jobs shall be released after streaming has been stopped.
568+ */
569+void vsp1_isp_job_release(struct device *dev,
570+ struct vsp1_isp_job_desc *job)
571+{
572+ vsp1_dl_list_put(job->dl);
573+}
574+EXPORT_SYMBOL_GPL(vsp1_isp_job_release);
575+
576+/* -----------------------------------------------------------------------------
577+ * Initialization and cleanup
578+ */
579+
580+int vsp1_vspx_init(struct vsp1_device *vsp1)
581+{
582+ struct vsp1_vspx_pipeline *vspx_pipe;
583+ struct vsp1_pipeline *pipe;
584+
585+ vsp1->vspx = devm_kzalloc(vsp1->dev, sizeof(*vsp1->vspx), GFP_KERNEL);
586+ if (!vsp1->vspx)
587+ return -ENOMEM;
588+
589+ vsp1->vspx->vsp1 = vsp1;
590+
591+ vspx_pipe = &vsp1->vspx->pipe;
592+ vspx_pipe->enabled = false;
593+
594+ pipe = &vspx_pipe->pipe;
595+
596+ vsp1_pipeline_init(pipe);
597+
598+ pipe->partitions = 1;
599+ pipe->part_table = &vspx_pipe->partition;
600+ pipe->interlaced = false;
601+ pipe->frame_end = vsp1_vspx_pipeline_frame_end;
602+
603+ mutex_init(&vspx_pipe->mutex);
604+ spin_lock_init(&vspx_pipe->lock);
605+
606+ /*
607+ * Initialize RPF0 as input for VSPX and use it unconditionally for
608+ * now.
609+ */
610+ pipe->inputs[0] = vsp1->rpf[0];
611+ pipe->inputs[0]->entity.pipe = pipe;
612+ pipe->inputs[0]->entity.sink = &vsp1->iif->entity;
613+ list_add_tail(&pipe->inputs[0]->entity.list_pipe, &pipe->entities);
614+
615+ pipe->iif = &vsp1->iif->entity;
616+ pipe->iif->pipe = pipe;
617+ pipe->iif->sink = &vsp1->wpf[0]->entity;
618+ pipe->iif->sink_pad = RWPF_PAD_SINK;
619+ list_add_tail(&pipe->iif->list_pipe, &pipe->entities);
620+
621+ pipe->output = vsp1->wpf[0];
622+ pipe->output->entity.pipe = pipe;
623+ list_add_tail(&pipe->output->entity.list_pipe, &pipe->entities);
624+
625+ return 0;
626+}
627+
628+void vsp1_vspx_cleanup(struct vsp1_device *vsp1)
629+{
630+ struct vsp1_vspx_pipeline *vspx_pipe = &vsp1->vspx->pipe;
631+
632+ mutex_destroy(&vspx_pipe->mutex);
633+}
drivers/media/platform/renesas/vsp1/vsp1_vspx.h+16−0
@@ -0,0 +1,16 @@
1+/* SPDX-License-Identifier: GPL-2.0+ */
2+/*
3+ * vsp1_vspx.h -- R-Car Gen 4 VSPX
4+ *
5+ * Copyright (C) 2025 Ideas On Board Oy
6+ * Copyright (C) 2025 Renesas Electronics Corporation
7+ */
8+#ifndef __VSP1_VSPX_H__
9+#define __VSP1_VSPX_H__
10+
11+#include "vsp1.h"
12+
13+int vsp1_vspx_init(struct vsp1_device *vsp1);
14+void vsp1_vspx_cleanup(struct vsp1_device *vsp1);
15+
16+#endif /* __VSP1_VSPX_H__ */
drivers/media/platform/rockchip/Kconfig+1−0
@@ -4,3 +4,4 @@ comment "Rockchip media platform drivers" · 3 unmodified lines
44
55 source "drivers/media/platform/rockchip/rga/Kconfig"
66 source "drivers/media/platform/rockchip/rkisp1/Kconfig"
7+source "drivers/media/platform/rockchip/rkvdec/Kconfig"
drivers/media/platform/rockchip/Makefile+1−0
@@ -1,3 +1,4 @@
11 # SPDX-License-Identifier: GPL-2.0-only
22 obj-y += rga/
33 obj-y += rkisp1/
4+obj-y += rkvdec/
drivers/media/platform/rockchip/rkisp1/rkisp1-common.h+2−0
@@ -415,6 +415,8 @@ struct rkisp1_params { · 414 unmodified lines
415415 spinlock_t config_lock; /* locks the buffers list 'params' */
416416 struct list_head params;
417417
418+ struct v4l2_ctrl_handler ctrls;
419+
418420 const struct v4l2_meta_format *metafmt;
419421
420422 enum v4l2_quantization quantization;
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c+146−4
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
66 */
77
8+#include <linux/bitfield.h>
89 #include <linux/math.h>
910 #include <linux/string.h>
1011
@@ -60,6 +61,7 @@ union rkisp1_ext_params_config { · 49 unmodified lines
6061 struct rkisp1_ext_params_afc_config afc;
6162 struct rkisp1_ext_params_compand_bls_config compand_bls;
6263 struct rkisp1_ext_params_compand_curve_config compand_curve;
64+ struct rkisp1_ext_params_wdr_config wdr;
6365 };
6466
6567 enum rkisp1_params_formats {
@@ -1348,6 +1350,73 @@ rkisp1_compand_compress_config(struct rkisp1_params *params, · 1282 unmodified lines
13481350 arg->x);
13491351 }
13501352
1353+static void rkisp1_wdr_config(struct rkisp1_params *params,
1354+ const struct rkisp1_cif_isp_wdr_config *arg)
1355+{
1356+ unsigned int i;
1357+ u32 value;
1358+
1359+ value = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL)
1360+ & ~(RKISP1_CIF_ISP_WDR_USE_IREF |
1361+ RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT |
1362+ RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE |
1363+ RKISP1_CIF_ISP_WDR_USE_Y9_8 |
1364+ RKISP1_CIF_ISP_WDR_USE_RGB7_8 |
1365+ RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT |
1366+ RKISP1_CIF_ISP_WDR_RGB_FACTOR_MASK);
1367+
1368+ /* Colorspace and chrominance mapping */
1369+ if (arg->use_rgb_colorspace)
1370+ value |= RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT;
1371+
1372+ if (!arg->use_rgb_colorspace && arg->bypass_chroma_mapping)
1373+ value |= RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE;
1374+
1375+ /* Illumination reference */
1376+ if (arg->use_iref) {
1377+ value |= RKISP1_CIF_ISP_WDR_USE_IREF;
1378+
1379+ if (arg->iref_config.use_y9_8)
1380+ value |= RKISP1_CIF_ISP_WDR_USE_Y9_8;
1381+
1382+ if (arg->iref_config.use_rgb7_8)
1383+ value |= RKISP1_CIF_ISP_WDR_USE_RGB7_8;
1384+
1385+ if (arg->iref_config.disable_transient)
1386+ value |= RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT;
1387+
1388+ value |= FIELD_PREP(RKISP1_CIF_ISP_WDR_RGB_FACTOR_MASK,
1389+ min(arg->iref_config.rgb_factor,
1390+ RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX));
1391+ }
1392+
1393+ rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_CTRL, value);
1394+
1395+ /* RGB and Luminance offsets */
1396+ value = FIELD_PREP(RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK,
1397+ arg->rgb_offset)
1398+ | FIELD_PREP(RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK,
1399+ arg->luma_offset);
1400+ rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_OFFSET, value);
1401+
1402+ /* DeltaMin */
1403+ value = FIELD_PREP(RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK,
1404+ arg->dmin_thresh)
1405+ | FIELD_PREP(RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MASK,
1406+ min(arg->dmin_strength,
1407+ RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX));
1408+ rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_DELTAMIN, value);
1409+
1410+ /* Tone curve */
1411+ for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_DY_REGS; i++)
1412+ rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE(i),
1413+ arg->tone_curve.dY[i]);
1414+ for (i = 0; i < RKISP1_CIF_ISP_WDR_CURVE_NUM_COEFF; i++)
1415+ rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_WDR_TONECURVE_YM(i),
1416+ arg->tone_curve.ym[i] &
1417+ RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK);
1418+}
1419+
13511420 static void
13521421 rkisp1_isp_isr_other_config(struct rkisp1_params *params,
13531422 const struct rkisp1_params_cfg *new_params)
@@ -2005,6 +2074,25 @@ static void rkisp1_ext_params_compand_compress(struct rkisp1_params *params, · 651 unmodified lines
20052074 RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);
20062075 }
20072076
2077+static void rkisp1_ext_params_wdr(struct rkisp1_params *params,
2078+ const union rkisp1_ext_params_config *block)
2079+{
2080+ const struct rkisp1_ext_params_wdr_config *wdr = &block->wdr;
2081+
2082+ if (wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) {
2083+ rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
2084+ RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
2085+ return;
2086+ }
2087+
2088+ rkisp1_wdr_config(params, &wdr->config);
2089+
2090+ if ((wdr->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) &&
2091+ !(params->enabled_blocks & BIT(wdr->header.type)))
2092+ rkisp1_param_set_bits(params, RKISP1_CIF_ISP_WDR_CTRL,
2093+ RKISP1_CIF_ISP_WDR_CTRL_ENABLE);
2094+}
2095+
20082096 typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
20092097 const union rkisp1_ext_params_config *config);
20102098
@@ -2118,6 +2206,11 @@ static const struct rkisp1_ext_params_handler { · 107 unmodified lines
21182206 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
21192207 .features = RKISP1_FEATURE_COMPAND,
21202208 },
2209+ [RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
2210+ .size = sizeof(struct rkisp1_ext_params_wdr_config),
2211+ .handler = rkisp1_ext_params_wdr,
2212+ .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
2213+ },
21212214 };
21222215
21232216 static void rkisp1_ext_params_config(struct rkisp1_params *params,
@@ -2736,6 +2829,44 @@ static int rkisp1_params_init_vb2_queue(struct vb2_queue *q, · 612 unmodified lines
27362829 return vb2_queue_init(q);
27372830 }
27382831
2832+static int rkisp1_params_ctrl_init(struct rkisp1_params *params)
2833+{
2834+ struct v4l2_ctrl_config ctrl_config = {
2835+ .id = RKISP1_CID_SUPPORTED_PARAMS_BLOCKS,
2836+ .name = "Supported Params Blocks",
2837+ .type = V4L2_CTRL_TYPE_BITMASK,
2838+ .flags = V4L2_CTRL_FLAG_READ_ONLY,
2839+ };
2840+ int ret;
2841+
2842+ v4l2_ctrl_handler_init(&params->ctrls, 1);
2843+
2844+ for (unsigned int i = 0; i < ARRAY_SIZE(rkisp1_ext_params_handlers); i++) {
2845+ const struct rkisp1_ext_params_handler *block_handler;
2846+
2847+ block_handler = &rkisp1_ext_params_handlers[i];
2848+ ctrl_config.max |= BIT(i);
2849+
2850+ if ((params->rkisp1->info->features & block_handler->features) !=
2851+ block_handler->features)
2852+ continue;
2853+
2854+ ctrl_config.def |= BIT(i);
2855+ }
2856+
2857+ v4l2_ctrl_new_custom(&params->ctrls, &ctrl_config, NULL);
2858+
2859+ params->vnode.vdev.ctrl_handler = &params->ctrls;
2860+
2861+ if (params->ctrls.error) {
2862+ ret = params->ctrls.error;
2863+ v4l2_ctrl_handler_free(&params->ctrls);
2864+ return ret;
2865+ }
2866+
2867+ return 0;
2868+}
2869+
27392870 int rkisp1_params_register(struct rkisp1_device *rkisp1)
27402871 {
27412872 struct rkisp1_params *params = &rkisp1->params;
@@ -2763,7 +2894,9 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1) · 21 unmodified lines
27632894 vdev->queue = &node->buf_queue;
27642895 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
27652896 vdev->vfl_dir = VFL_DIR_TX;
2766− rkisp1_params_init_vb2_queue(vdev->queue, params);
2897+ ret = rkisp1_params_init_vb2_queue(vdev->queue, params);
2898+ if (ret)
2899+ goto err_media;
27672900
27682901 params->metafmt = &rkisp1_params_formats[RKISP1_PARAMS_FIXED];
27692902
@@ -2777,18 +2910,26 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1) · 7 unmodified lines
27772910 node->pad.flags = MEDIA_PAD_FL_SOURCE;
27782911 ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
27792912 if (ret)
2780− goto error;
2913+ goto err_media;
2914+
2915+ ret = rkisp1_params_ctrl_init(params);
2916+ if (ret) {
2917+ dev_err(rkisp1->dev, "Control initialization error %d\n", ret);
2918+ goto err_media;
2919+ }
27812920
27822921 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
27832922 if (ret) {
27842923 dev_err(rkisp1->dev,
27852924 "failed to register %s, ret=%d\n", vdev->name, ret);
2786− goto error;
2925+ goto err_ctrl;
27872926 }
27882927
27892928 return 0;
27902929
2791−error:
2930+err_ctrl:
2931+ v4l2_ctrl_handler_free(&params->ctrls);
2932+err_media:
27922933 media_entity_cleanup(&vdev->entity);
27932934 mutex_destroy(&node->vlock);
27942935 return ret;
@@ -2804,6 +2945,7 @@ void rkisp1_params_unregister(struct rkisp1_device *rkisp1) · 9 unmodified lines
28042945 return;
28052946
28062947 vb2_video_unregister_device(vdev);
2948+ v4l2_ctrl_handler_free(&params->ctrls);
28072949 media_entity_cleanup(&vdev->entity);
28082950 mutex_destroy(&node->vlock);
28092951 }
drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h+25−74
@@ -703,6 +703,27 @@ · 702 unmodified lines
703703 #define RKISP1_CIF_ISP_COMPAND_CTRL_SOFT_RESET_FLAG BIT(2)
704704 #define RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE BIT(3)
705705
706+/* WDR */
707+/* ISP_WDR_CTRL */
708+#define RKISP1_CIF_ISP_WDR_CTRL_ENABLE BIT(0)
709+#define RKISP1_CIF_ISP_WDR_COLOR_SPACE_SELECT BIT(1)
710+#define RKISP1_CIF_ISP_WDR_CR_MAPPING_DISABLE BIT(2)
711+#define RKISP1_CIF_ISP_WDR_USE_IREF BIT(3)
712+#define RKISP1_CIF_ISP_WDR_USE_Y9_8 BIT(4)
713+#define RKISP1_CIF_ISP_WDR_USE_RGB7_8 BIT(5)
714+#define RKISP1_CIF_ISP_WDR_DISABLE_TRANSIENT BIT(6)
715+#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_MASK GENMASK(11, 8)
716+#define RKISP1_CIF_ISP_WDR_RGB_FACTOR_MAX 8U
717+/* ISP_WDR_TONE_CURVE_YM */
718+#define RKISP1_CIF_ISP_WDR_TONE_CURVE_YM_MASK GENMASK(12, 0)
719+/* ISP_WDR_OFFSET */
720+#define RKISP1_CIF_ISP_WDR_RGB_OFFSET_MASK GENMASK(11, 0)
721+#define RKISP1_CIF_ISP_WDR_LUM_OFFSET_MASK GENMASK(27, 16)
722+/* ISP_WDR_DELTAMIN */
723+#define RKISP1_CIF_ISP_WDR_DMIN_THRESH_MASK GENMASK(11, 0)
724+#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MASK GENMASK(20, 16)
725+#define RKISP1_CIF_ISP_WDR_DMIN_STRENGTH_MAX 16U
726+
706727 /* =================================================================== */
707728 /* CIF Registers */
708729 /* =================================================================== */
@@ -1295,82 +1316,12 @@ · 586 unmodified lines
12951316
12961317 #define RKISP1_CIF_ISP_WDR_BASE 0x00002a00
12971318 #define RKISP1_CIF_ISP_WDR_CTRL (RKISP1_CIF_ISP_WDR_BASE + 0x00000000)
1298−#define RKISP1_CIF_ISP_WDR_TONECURVE_1 (RKISP1_CIF_ISP_WDR_BASE + 0x00000004)
1299−#define RKISP1_CIF_ISP_WDR_TONECURVE_2 (RKISP1_CIF_ISP_WDR_BASE + 0x00000008)
1300−#define RKISP1_CIF_ISP_WDR_TONECURVE_3 (RKISP1_CIF_ISP_WDR_BASE + 0x0000000c)
1301−#define RKISP1_CIF_ISP_WDR_TONECURVE_4 (RKISP1_CIF_ISP_WDR_BASE + 0x00000010)
1302−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0 (RKISP1_CIF_ISP_WDR_BASE + 0x00000014)
1303−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1 (RKISP1_CIF_ISP_WDR_BASE + 0x00000018)
1304−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2 (RKISP1_CIF_ISP_WDR_BASE + 0x0000001c)
1305−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3 (RKISP1_CIF_ISP_WDR_BASE + 0x00000020)
1306−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4 (RKISP1_CIF_ISP_WDR_BASE + 0x00000024)
1307−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5 (RKISP1_CIF_ISP_WDR_BASE + 0x00000028)
1308−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6 (RKISP1_CIF_ISP_WDR_BASE + 0x0000002c)
1309−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7 (RKISP1_CIF_ISP_WDR_BASE + 0x00000030)
1310−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8 (RKISP1_CIF_ISP_WDR_BASE + 0x00000034)
1311−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9 (RKISP1_CIF_ISP_WDR_BASE + 0x00000038)
1312−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10 (RKISP1_CIF_ISP_WDR_BASE + 0x0000003c)
1313−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11 (RKISP1_CIF_ISP_WDR_BASE + 0x00000040)
1314−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12 (RKISP1_CIF_ISP_WDR_BASE + 0x00000044)
1315−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13 (RKISP1_CIF_ISP_WDR_BASE + 0x00000048)
1316−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14 (RKISP1_CIF_ISP_WDR_BASE + 0x0000004c)
1317−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15 (RKISP1_CIF_ISP_WDR_BASE + 0x00000050)
1318−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16 (RKISP1_CIF_ISP_WDR_BASE + 0x00000054)
1319−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17 (RKISP1_CIF_ISP_WDR_BASE + 0x00000058)
1320−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18 (RKISP1_CIF_ISP_WDR_BASE + 0x0000005c)
1321−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19 (RKISP1_CIF_ISP_WDR_BASE + 0x00000060)
1322−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20 (RKISP1_CIF_ISP_WDR_BASE + 0x00000064)
1323−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21 (RKISP1_CIF_ISP_WDR_BASE + 0x00000068)
1324−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22 (RKISP1_CIF_ISP_WDR_BASE + 0x0000006c)
1325−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23 (RKISP1_CIF_ISP_WDR_BASE + 0x00000070)
1326−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24 (RKISP1_CIF_ISP_WDR_BASE + 0x00000074)
1327−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25 (RKISP1_CIF_ISP_WDR_BASE + 0x00000078)
1328−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26 (RKISP1_CIF_ISP_WDR_BASE + 0x0000007c)
1329−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27 (RKISP1_CIF_ISP_WDR_BASE + 0x00000080)
1330−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28 (RKISP1_CIF_ISP_WDR_BASE + 0x00000084)
1331−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29 (RKISP1_CIF_ISP_WDR_BASE + 0x00000088)
1332−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30 (RKISP1_CIF_ISP_WDR_BASE + 0x0000008c)
1333−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31 (RKISP1_CIF_ISP_WDR_BASE + 0x00000090)
1334−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32 (RKISP1_CIF_ISP_WDR_BASE + 0x00000094)
1319+#define RKISP1_CIF_ISP_WDR_TONECURVE(n) (RKISP1_CIF_ISP_WDR_BASE + 0x00000004 + (n) * 4)
1320+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM(n) (RKISP1_CIF_ISP_WDR_BASE + 0x00000014 + (n) * 4)
13351321 #define RKISP1_CIF_ISP_WDR_OFFSET (RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
13361322 #define RKISP1_CIF_ISP_WDR_DELTAMIN (RKISP1_CIF_ISP_WDR_BASE + 0x0000009c)
1337−#define RKISP1_CIF_ISP_WDR_TONECURVE_1_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000a0)
1338−#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000a4)
1339−#define RKISP1_CIF_ISP_WDR_TONECURVE_3_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000a8)
1340−#define RKISP1_CIF_ISP_WDR_TONECURVE_4_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000ac)
1341−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_0_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000b0)
1342−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_1_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000b4)
1343−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_2_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000b8)
1344−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_3_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000bc)
1345−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_4_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000c0)
1346−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_5_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000c4)
1347−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_6_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000c8)
1348−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_7_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000cc)
1349−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_8_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000d0)
1350−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_9_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000d4)
1351−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_10_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000d8)
1352−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_11_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000dc)
1353−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_12_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000e0)
1354−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_13_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000e4)
1355−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_14_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000e8)
1356−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_15_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000ec)
1357−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_16_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000f0)
1358−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_17_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000f4)
1359−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_18_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000f8)
1360−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_19_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000fc)
1361−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_20_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000100)
1362−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_21_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000104)
1363−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_22_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000108)
1364−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_23_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000010c)
1365−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_24_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000110)
1366−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_25_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000114)
1367−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_26_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000118)
1368−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_27_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000011c)
1369−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_28_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000120)
1370−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_29_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000124)
1371−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_30_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000128)
1372−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_31_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x0000012c)
1373−#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_32_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x00000130)
1323+#define RKISP1_CIF_ISP_WDR_TONECURVE_SHD(n) (RKISP1_CIF_ISP_WDR_BASE + 0x000000a0 + (n) * 4)
1324+#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_SHD(n) (RKISP1_CIF_ISP_WDR_BASE + 0x000000b0 + (n) * 4)
13741325
13751326 #define RKISP1_CIF_ISP_HIST_BASE_V12 0x00002c00
13761327 #define RKISP1_CIF_ISP_HIST_CTRL_V12 (RKISP1_CIF_ISP_HIST_BASE_V12 + 0x00000000)
drivers/media/platform/rockchip/rkvdec/Kconfigrenamed from drivers/staging/media/rkvdec/Kconfig+0−0

File renamed without changes.

drivers/media/platform/rockchip/rkvdec/Makefilerenamed from drivers/staging/media/rkvdec/Makefile+0−0

File renamed without changes.

drivers/media/platform/rockchip/rkvdec/rkvdec-h264.crenamed from drivers/staging/media/rkvdec/rkvdec-h264.c+0−0

File renamed without changes.

drivers/media/platform/rockchip/rkvdec/rkvdec-regs.hrenamed from drivers/staging/media/rkvdec/rkvdec-regs.h+0−0

File renamed without changes.

drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.crenamed from drivers/staging/media/rkvdec/rkvdec-vp9.c+0−0

File renamed without changes.

drivers/media/platform/rockchip/rkvdec/rkvdec.crenamed from drivers/staging/media/rkvdec/rkvdec.c+36−7
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111
1212 #include <linux/clk.h>
1313 #include <linux/interrupt.h>
14+#include <linux/iommu.h>
1415 #include <linux/module.h>
1516 #include <linux/of.h>
1617 #include <linux/platform_device.h>
@@ -1055,24 +1056,42 @@ static void rkvdec_v4l2_cleanup(struct rkvdec_dev *rkvdec) · 1038 unmodified lines
10551056 v4l2_device_unregister(&rkvdec->v4l2_dev);
10561057 }
10571058
1059+static void rkvdec_iommu_restore(struct rkvdec_dev *rkvdec)
1060+{
1061+ if (rkvdec->empty_domain) {
1062+ /*
1063+ * To rewrite mapping into the attached IOMMU core, attach a new empty domain that
1064+ * will program an empty table, then detach it to restore the default domain and
1065+ * all cached mappings.
1066+ * This is safely done in this interrupt handler to make sure no memory get mapped
1067+ * through the IOMMU while the empty domain is attached.
1068+ */
1069+ iommu_attach_device(rkvdec->empty_domain, rkvdec->dev);
1070+ iommu_detach_device(rkvdec->empty_domain, rkvdec->dev);
1071+ }
1072+}
1073+
10581074 static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
10591075 {
10601076 struct rkvdec_dev *rkvdec = priv;
1077+ struct rkvdec_ctx *ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
10611078 enum vb2_buffer_state state;
10621079 u32 status;
10631080
10641081 status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT);
1065− state = (status & RKVDEC_RDY_STA) ?
1066− VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
1067−
10681082 writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT);
1069− if (cancel_delayed_work(&rkvdec->watchdog_work)) {
1070− struct rkvdec_ctx *ctx;
10711083
1072− ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
1073− rkvdec_job_finish(ctx, state);
1084+ if (status & RKVDEC_RDY_STA) {
1085+ state = VB2_BUF_STATE_DONE;
1086+ } else {
1087+ state = VB2_BUF_STATE_ERROR;
1088+ if (status & RKVDEC_SOFTRESET_RDY)
1089+ rkvdec_iommu_restore(rkvdec);
10741090 }
10751091
1092+ if (cancel_delayed_work(&rkvdec->watchdog_work))
1093+ rkvdec_job_finish(ctx, state);
1094+
10761095 return IRQ_HANDLED;
10771096 }
10781097
@@ -1140,6 +1159,13 @@ static int rkvdec_probe(struct platform_device *pdev) · 61 unmodified lines
11401159 return ret;
11411160 }
11421161
1162+ if (iommu_get_domain_for_dev(&pdev->dev)) {
1163+ rkvdec->empty_domain = iommu_paging_domain_alloc(rkvdec->dev);
1164+
1165+ if (!rkvdec->empty_domain)
1166+ dev_warn(rkvdec->dev, "cannot alloc new empty domain\n");
1167+ }
1168+
11431169 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
11441170
11451171 irq = platform_get_irq(pdev, 0);
@@ -1179,6 +1205,9 @@ static void rkvdec_remove(struct platform_device *pdev) · 33 unmodified lines
11791205 rkvdec_v4l2_cleanup(rkvdec);
11801206 pm_runtime_disable(&pdev->dev);
11811207 pm_runtime_dont_use_autosuspend(&pdev->dev);
1208+
1209+ if (rkvdec->empty_domain)
1210+ iommu_domain_free(rkvdec->empty_domain);
11821211 }
11831212
11841213 #ifdef CONFIG_PM
drivers/media/platform/rockchip/rkvdec/rkvdec.hrenamed from drivers/staging/media/rkvdec/rkvdec.h+1−0
@@ -110,6 +110,7 @@ struct rkvdec_dev { · 109 unmodified lines
110110 void __iomem *regs;
111111 struct mutex vdev_lock; /* serializes ioctls */
112112 struct delayed_work watchdog_work;
113+ struct iommu_domain *empty_domain;
113114 };
114115
115116 struct rkvdec_ctx {
drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.c+1−1
@@ -131,7 +131,7 @@ static const struct dev_pm_ops fimc_is_i2c_pm_ops = { · 130 unmodified lines
131131 };
132132
133133 static const struct of_device_id fimc_is_i2c_of_match[] = {
134− { .compatible = FIMC_IS_I2C_COMPATIBLE },
134+ { .compatible = "samsung,exynos4212-i2c-isp" },
135135 { },
136136 };
137137
drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.h+0−2
@@ -6,7 +6,5 @@ · 5 unmodified lines
66 * Sylwester Nawrocki <s.nawrocki@samsung.com>
77 */
88
9−#define FIMC_IS_I2C_COMPATIBLE "samsung,exynos4212-i2c-isp"
10−
119 int fimc_is_register_i2c_driver(void);
1210 void fimc_is_unregister_i2c_driver(void);
drivers/media/platform/samsung/exynos4-is/fimc-is.c+1−1
@@ -207,7 +207,7 @@ static int fimc_is_register_subdevs(struct fimc_is *is) · 206 unmodified lines
207207 if (ret < 0)
208208 return ret;
209209
210− for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) {
210+ for_each_compatible_node(i2c_bus, NULL, "samsung,exynos4212-i2c-isp") {
211211 for_each_available_child_of_node(i2c_bus, child) {
212212 ret = fimc_is_parse_sensor_config(is, index, child);
213213
drivers/media/platform/samsung/exynos4-is/media-dev.c+8−19
@@ -482,15 +482,12 @@ static int fimc_md_parse_one_endpoint(struct fimc_md *fmd, · 481 unmodified lines
482482 static int fimc_md_parse_port_node(struct fimc_md *fmd,
483483 struct device_node *port)
484484 {
485− struct device_node *ep;
486485 int ret;
487486
488− for_each_child_of_node(port, ep) {
487+ for_each_child_of_node_scoped(port, ep) {
489488 ret = fimc_md_parse_one_endpoint(fmd, ep);
490− if (ret < 0) {
491− of_node_put(ep);
489+ if (ret < 0)
492490 return ret;
493− }
494491 }
495492
496493 return 0;
@@ -501,7 +498,6 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) · 4 unmodified lines
501498 {
502499 struct device_node *parent = fmd->pdev->dev.of_node;
503500 struct device_node *ports = NULL;
504− struct device_node *node;
505501 int ret;
506502
507503 /*
@@ -518,7 +514,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) · 10 unmodified lines
518514 fmd->num_sensors = 0;
519515
520516 /* Attach sensors linked to MIPI CSI-2 receivers */
521− for_each_available_child_of_node(parent, node) {
517+ for_each_available_child_of_node_scoped(parent, node) {
522518 struct device_node *port;
523519
524520 if (!of_node_name_eq(node, "csis"))
@@ -530,10 +526,8 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) · 5 unmodified lines
530526
531527 ret = fimc_md_parse_port_node(fmd, port);
532528 of_node_put(port);
533− if (ret < 0) {
534− of_node_put(node);
529+ if (ret < 0)
535530 goto cleanup;
536− }
537531 }
538532
539533 /* Attach sensors listed in the parallel-ports node */
@@ -541,12 +535,10 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) · 1 unmodified line
541535 if (!ports)
542536 goto rpm_put;
543537
544− for_each_child_of_node(ports, node) {
538+ for_each_child_of_node_scoped(ports, node) {
545539 ret = fimc_md_parse_port_node(fmd, node);
546− if (ret < 0) {
547− of_node_put(node);
540+ if (ret < 0)
548541 goto cleanup;
549− }
550542 }
551543 of_node_put(ports);
552544
@@ -736,10 +728,9 @@ dev_unlock: · 183 unmodified lines
736728 static int fimc_md_register_platform_entities(struct fimc_md *fmd,
737729 struct device_node *parent)
738730 {
739− struct device_node *node;
740731 int ret = 0;
741732
742− for_each_available_child_of_node(parent, node) {
733+ for_each_available_child_of_node_scoped(parent, node) {
743734 struct platform_device *pdev;
744735 int plat_entity = -1;
745736
@@ -762,10 +753,8 @@ static int fimc_md_register_platform_entities(struct fimc_md *fmd, · 16 unmodified lines
762753 ret = fimc_md_register_platform_entity(fmd, pdev,
763754 plat_entity);
764755 put_device(&pdev->dev);
765− if (ret < 0) {
766− of_node_put(node);
756+ if (ret < 0)
767757 break;
768− }
769758 }
770759
771760 return ret;
drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c+12−22
@@ -658,7 +658,7 @@ static irqreturn_t c8sectpfe_error_irq_handler(int irq, void *priv) · 657 unmodified lines
658658 static int c8sectpfe_probe(struct platform_device *pdev)
659659 {
660660 struct device *dev = &pdev->dev;
661− struct device_node *child, *np = dev->of_node;
661+ struct device_node *np = dev->of_node;
662662 struct c8sectpfei *fei;
663663 struct resource *res;
664664 int ret, index = 0;
@@ -742,17 +742,15 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 77 unmodified lines
742742 return PTR_ERR(fei->pinctrl);
743743 }
744744
745− for_each_child_of_node(np, child) {
745+ for_each_child_of_node_scoped(np, child) {
746746 struct device_node *i2c_bus;
747747
748748 fei->channel_data[index] = devm_kzalloc(dev,
749749 sizeof(struct channel_info),
750750 GFP_KERNEL);
751751
752− if (!fei->channel_data[index]) {
753− ret = -ENOMEM;
754− goto err_node_put;
755− }
752+ if (!fei->channel_data[index])
753+ return -ENOMEM;
756754
757755 tsin = fei->channel_data[index];
758756
@@ -761,7 +759,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 2 unmodified lines
761759 ret = of_property_read_u32(child, "tsin-num", &tsin->tsin_id);
762760 if (ret) {
763761 dev_err(&pdev->dev, "No tsin_num found\n");
764− goto err_node_put;
762+ return ret;
765763 }
766764
767765 /* sanity check value */
@@ -769,8 +767,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 1 unmodified line
769767 dev_err(&pdev->dev,
770768 "tsin-num %d specified greater than number\n\tof input block hw in SoC! (%d)",
771769 tsin->tsin_id, fei->hw_stats.num_ib);
772− ret = -EINVAL;
773− goto err_node_put;
770+ return -EINVAL;
774771 }
775772
776773 tsin->invert_ts_clk = of_property_read_bool(child,
@@ -786,22 +783,20 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 9 unmodified lines
786783 &tsin->dvb_card);
787784 if (ret) {
788785 dev_err(&pdev->dev, "No dvb-card found\n");
789− goto err_node_put;
786+ return ret;
790787 }
791788
792789 i2c_bus = of_parse_phandle(child, "i2c-bus", 0);
793790 if (!i2c_bus) {
794791 dev_err(&pdev->dev, "No i2c-bus found\n");
795− ret = -ENODEV;
796− goto err_node_put;
792+ return -ENODEV;
797793 }
798794 tsin->i2c_adapter =
799795 of_find_i2c_adapter_by_node(i2c_bus);
800796 of_node_put(i2c_bus);
801797 if (!tsin->i2c_adapter) {
802798 dev_err(&pdev->dev, "No i2c adapter found\n");
803− ret = -ENODEV;
804− goto err_node_put;
799+ return -ENODEV;
805800 }
806801
807802 /* Acquire reset GPIO and activate it */
@@ -813,7 +808,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 5 unmodified lines
813808 if (ret && ret != -EBUSY) {
814809 dev_err(dev, "Can't request tsin%d reset gpio\n",
815810 fei->channel_data[index]->tsin_id);
816− goto err_node_put;
811+ return ret;
817812 }
818813
819814 if (!ret) {
@@ -855,10 +850,6 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 35 unmodified lines
855850 c8sectpfe_debugfs_init(fei);
856851
857852 return 0;
858−
859−err_node_put:
860− of_node_put(child);
861− return ret;
862853 }
863854
864855 static void c8sectpfe_remove(struct platform_device *pdev)
@@ -897,16 +888,15 @@ static void c8sectpfe_remove(struct platform_device *pdev) · 32 unmodified lines
897888 static int configure_channels(struct c8sectpfei *fei)
898889 {
899890 int index = 0, ret;
900− struct device_node *child, *np = fei->dev->of_node;
891+ struct device_node *np = fei->dev->of_node;
901892
902893 /* iterate round each tsin and configure memdma descriptor and IB hw */
903− for_each_child_of_node(np, child) {
894+ for_each_child_of_node_scoped(np, child) {
904895 ret = configure_memdma_and_inputblock(fei,
905896 fei->channel_data[index]);
906897 if (ret) {
907898 dev_err(fei->dev,
908899 "configure_memdma_and_inputblock failed\n");
909− of_node_put(child);
910900 goto err_unmap;
911901 }
912902 index++;
drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c+2−0
@@ -619,6 +619,7 @@ static void ti_csi2rx_dma_callback(void *param) · 618 unmodified lines
619619
620620 if (ti_csi2rx_start_dma(csi, buf)) {
621621 dev_err(csi->dev, "Failed to queue the next buffer for DMA\n");
622+ list_del(&buf->list);
622623 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
623624 } else {
624625 list_move_tail(&buf->list, &dma->submitted);
@@ -895,6 +896,7 @@ static int ti_csi2rx_init_vb2q(struct ti_csi2rx_dev *csi) · 270 unmodified lines
895896 q->dev = dmaengine_get_dma_device(csi->dma.chan);
896897 q->lock = &csi->mutex;
897898 q->min_queued_buffers = 1;
899+ q->allow_cache_hints = 1;
898900
899901 ret = vb2_queue_init(q);
900902 if (ret)
drivers/media/platform/ti/vpe/vpdma.c+0−32
@@ -552,38 +552,6 @@ EXPORT_SYMBOL(vpdma_submit_descs); · 551 unmodified lines
552552
553553 static void dump_dtd(struct vpdma_dtd *dtd);
554554
555−void vpdma_update_dma_addr(struct vpdma_data *vpdma,
556− struct vpdma_desc_list *list, dma_addr_t dma_addr,
557− void *write_dtd, int drop, int idx)
558−{
559− struct vpdma_dtd *dtd = list->buf.addr;
560− dma_addr_t write_desc_addr;
561− int offset;
562−
563− dtd += idx;
564− vpdma_unmap_desc_buf(vpdma, &list->buf);
565−
566− dtd->start_addr = dma_addr;
567−
568− /* Calculate write address from the offset of write_dtd from start
569− * of the list->buf
570− */
571− offset = (void *)write_dtd - list->buf.addr;
572− write_desc_addr = list->buf.dma_addr + offset;
573−
574− if (drop)
575− dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
576− 1, 1, 0);
577− else
578− dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
579− 1, 0, 0);
580−
581− vpdma_map_desc_buf(vpdma, &list->buf);
582−
583− dump_dtd(dtd);
584−}
585−EXPORT_SYMBOL(vpdma_update_dma_addr);
586−
587555 void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
588556 u32 width, u32 height)
589557 {
drivers/media/platform/ti/vpe/vpdma.h+0−3
@@ -222,9 +222,6 @@ void vpdma_free_desc_list(struct vpdma_desc_list *list); · 221 unmodified lines
222222 int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list,
223223 int list_num);
224224 bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num);
225−void vpdma_update_dma_addr(struct vpdma_data *vpdma,
226− struct vpdma_desc_list *list, dma_addr_t dma_addr,
227− void *write_dtd, int drop, int idx);
228225
229226 /* VPDMA hardware list funcs */
230227 int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv);
drivers/media/platform/verisilicon/hantro.h+2−0
@@ -323,6 +323,8 @@ struct hantro_postproc_regs { · 322 unmodified lines
323323 struct hantro_reg output_fmt;
324324 struct hantro_reg orig_width;
325325 struct hantro_reg display_width;
326+ struct hantro_reg input_width_ext;
327+ struct hantro_reg input_height_ext;
326328 };
327329
328330 struct hantro_vp9_decoded_buffer_info {
drivers/media/platform/verisilicon/hantro_g1_regs.h+1−1
@@ -350,7 +350,7 @@ · 349 unmodified lines
350350 #define G1_REG_PP_CONTROL_OUT_WIDTH(v) (((v) << 4) & GENMASK(14, 4))
351351 #define G1_REG_PP_MASK1_ORIG_WIDTH G1_SWREG(88)
352352 #define G1_REG_PP_ORIG_WIDTH(v) (((v) << 23) & GENMASK(31, 23))
353−#define G1_REG_PP_DISPLAY_WIDTH G1_SWREG(92)
353+#define G1_REG_PP_DISPLAY_WIDTH_IN_EXT G1_SWREG(92)
354354 #define G1_REG_PP_FUSE G1_SWREG(99)
355355
356356 #endif /* HANTRO_G1_REGS_H_ */
drivers/media/platform/verisilicon/hantro_h264.c+3−3
@@ -325,12 +325,12 @@ static void update_dpb(struct hantro_ctx *ctx) · 324 unmodified lines
325325 continue;
326326
327327 *cdpb = *ndpb;
328− set_bit(j, used);
328+ __set_bit(j, used);
329329 break;
330330 }
331331
332332 if (j == ARRAY_SIZE(ctx->h264_dec.dpb))
333− set_bit(i, new);
333+ __set_bit(i, new);
334334 }
335335
336336 /* For entries that could not be matched, use remaining free slots. */
@@ -349,7 +349,7 @@ static void update_dpb(struct hantro_ctx *ctx) · 12 unmodified lines
349349
350350 cdpb = &ctx->h264_dec.dpb[j];
351351 *cdpb = *ndpb;
352− set_bit(j, used);
352+ __set_bit(j, used);
353353 }
354354 }
355355
drivers/media/platform/verisilicon/hantro_postproc.c+5−1
@@ -49,7 +49,9 @@ static const struct hantro_postproc_regs hantro_g1_postproc_regs = { · 48 unmodified lines
4949 .input_fmt = {G1_REG_PP_CONTROL, 29, 0x7},
5050 .output_fmt = {G1_REG_PP_CONTROL, 26, 0x7},
5151 .orig_width = {G1_REG_PP_MASK1_ORIG_WIDTH, 23, 0x1ff},
52− .display_width = {G1_REG_PP_DISPLAY_WIDTH, 0, 0xfff},
52+ .display_width = {G1_REG_PP_DISPLAY_WIDTH_IN_EXT, 0, 0xfff},
53+ .input_width_ext = {G1_REG_PP_DISPLAY_WIDTH_IN_EXT, 26, 0x7},
54+ .input_height_ext = {G1_REG_PP_DISPLAY_WIDTH_IN_EXT, 29, 0x7},
5355 };
5456
5557 bool hantro_needs_postproc(const struct hantro_ctx *ctx,
@@ -103,6 +105,8 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx) · 47 unmodified lines
103105 HANTRO_PP_REG_WRITE(vpu, output_height, ctx->dst_fmt.height);
104106 HANTRO_PP_REG_WRITE(vpu, orig_width, MB_WIDTH(ctx->dst_fmt.width));
105107 HANTRO_PP_REG_WRITE(vpu, display_width, ctx->dst_fmt.width);
108+ HANTRO_PP_REG_WRITE(vpu, input_width_ext, MB_WIDTH(ctx->dst_fmt.width) >> 9);
109+ HANTRO_PP_REG_WRITE(vpu, input_height_ext, MB_HEIGHT(ctx->dst_fmt.height >> 8));
106110 }
107111
108112 static int down_scale_factor(struct hantro_ctx *ctx)
drivers/media/platform/verisilicon/rockchip_vpu_hw.c+0−9
@@ -17,7 +17,6 @@ · 16 unmodified lines
1717
1818 #define RK3066_ACLK_MAX_FREQ (300 * 1000 * 1000)
1919 #define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000)
20−#define RK3588_ACLK_MAX_FREQ (300 * 1000 * 1000)
2120
2221 #define ROCKCHIP_VPU981_MIN_SIZE 64
2322
@@ -454,13 +453,6 @@ static int rk3066_vpu_hw_init(struct hantro_dev *vpu) · 430 unmodified lines
454453 return 0;
455454 }
456455
457−static int rk3588_vpu981_hw_init(struct hantro_dev *vpu)
458−{
459− /* Bump ACLKs to max. possible freq. to improve performance. */
460− clk_set_rate(vpu->clocks[0].clk, RK3588_ACLK_MAX_FREQ);
461− return 0;
462−}
463−
464456 static int rockchip_vpu_hw_init(struct hantro_dev *vpu)
465457 {
466458 /* Bump ACLK to max. possible freq. to improve performance. */
@@ -821,7 +813,6 @@ const struct hantro_variant rk3588_vpu981_variant = { · 354 unmodified lines
821813 .codec_ops = rk3588_vpu981_codec_ops,
822814 .irqs = rk3588_vpu981_irqs,
823815 .num_irqs = ARRAY_SIZE(rk3588_vpu981_irqs),
824− .init = rk3588_vpu981_hw_init,
825816 .clk_names = rk3588_vpu981_vpu_clk_names,
826817 .num_clocks = ARRAY_SIZE(rk3588_vpu981_vpu_clk_names)
827818 };
drivers/media/platform/xilinx/xilinx-vipp.c+2−5
@@ -450,7 +450,6 @@ static int xvip_graph_dma_init_one(struct xvip_composite_device *xdev, · 449 unmodified lines
450450 static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
451451 {
452452 struct device_node *ports;
453− struct device_node *port;
454453 int ret = 0;
455454
456455 ports = of_get_child_by_name(xdev->dev->of_node, "ports");
@@ -459,12 +458,10 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev) · 2 unmodified lines
459458 return -EINVAL;
460459 }
461460
462− for_each_child_of_node(ports, port) {
461+ for_each_child_of_node_scoped(ports, port) {
463462 ret = xvip_graph_dma_init_one(xdev, port);
464− if (ret) {
465− of_node_put(port);
463+ if (ret)
466464 break;
467− }
468465 }
469466
470467 of_node_put(ports);
drivers/media/rc/ir-spi.c+26−14
@@ -21,13 +21,12 @@ · 20 unmodified lines
2121 #define IR_SPI_DRIVER_NAME "ir-spi"
2222
2323 #define IR_SPI_DEFAULT_FREQUENCY 38000
24−#define IR_SPI_MAX_BUFSIZE 4096
24+#define IR_SPI_BITS_PER_PULSE 16
2525
2626 struct ir_spi_data {
2727 u32 freq;
2828 bool negated;
2929
30− u16 tx_buf[IR_SPI_MAX_BUFSIZE];
3130 u16 pulse;
3231 u16 space;
3332
@@ -43,17 +42,23 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun · 9 unmodified lines
4342 unsigned int len = 0;
4443 struct ir_spi_data *idata = dev->priv;
4544 struct spi_transfer xfer;
45+ u16 *tx_buf;
4646
4747 /* convert the pulse/space signal to raw binary signal */
4848 for (i = 0; i < count; i++) {
49− unsigned int periods;
50− int j;
51− u16 val;
49+ buffer[i] = DIV_ROUND_CLOSEST_ULL((u64)buffer[i] * idata->freq,
50+ 1000000);
51+ len += buffer[i];
52+ }
5253
53− periods = DIV_ROUND_CLOSEST(buffer[i] * idata->freq, 1000000);
54+ tx_buf = kmalloc_array(len, sizeof(*tx_buf), GFP_KERNEL);
55+ if (!tx_buf)
56+ return -ENOMEM;
5457
55− if (len + periods >= IR_SPI_MAX_BUFSIZE)
56− return -EINVAL;
58+ len = 0;
59+ for (i = 0; i < count; i++) {
60+ int j;
61+ u16 val;
5762
5863 /*
5964 * The first value in buffer is a pulse, so that 0, 2, 4, ...
@@ -61,19 +66,19 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun · 1 unmodified line
6166 * contain a space duration.
6267 */
6368 val = (i % 2) ? idata->space : idata->pulse;
64− for (j = 0; j < periods; j++)
65− idata->tx_buf[len++] = val;
69+ for (j = 0; j < buffer[i]; j++)
70+ tx_buf[len++] = val;
6671 }
6772
6873 memset(&xfer, 0, sizeof(xfer));
6974
70− xfer.speed_hz = idata->freq * 16;
71− xfer.len = len * sizeof(*idata->tx_buf);
72− xfer.tx_buf = idata->tx_buf;
75+ xfer.speed_hz = idata->freq * IR_SPI_BITS_PER_PULSE;
76+ xfer.len = len * sizeof(*tx_buf);
77+ xfer.tx_buf = tx_buf;
7378
7479 ret = regulator_enable(idata->regulator);
7580 if (ret)
76− return ret;
81+ goto err_free_tx_buf;
7782
7883 ret = spi_sync_transfer(idata->spi, &xfer, 1);
7984 if (ret)
@@ -81,6 +86,10 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun · 1 unmodified line
8186
8287 regulator_disable(idata->regulator);
8388
89+err_free_tx_buf:
90+
91+ kfree(tx_buf);
92+
8493 return ret ? ret : count;
8594 }
8695
@@ -91,6 +100,9 @@ static int ir_spi_set_tx_carrier(struct rc_dev *dev, u32 carrier) · 4 unmodified lines
91100 if (!carrier)
92101 return -EINVAL;
93102
103+ if (carrier > idata->spi->max_speed_hz / IR_SPI_BITS_PER_PULSE)
104+ return -EINVAL;
105+
94106 idata->freq = carrier;
95107
96108 return 0;
drivers/media/test-drivers/vivid/vivid-ctrls.c+2−1
@@ -244,7 +244,8 @@ static const struct v4l2_ctrl_config vivid_ctrl_u8_pixel_array = { · 243 unmodified lines
244244 .min = 0x00,
245245 .max = 0xff,
246246 .step = 1,
247− .dims = { 640 / PIXEL_ARRAY_DIV, 360 / PIXEL_ARRAY_DIV },
247+ .dims = { DIV_ROUND_UP(360, PIXEL_ARRAY_DIV),
248+ DIV_ROUND_UP(640, PIXEL_ARRAY_DIV) },
248249 };
249250
250251 static const struct v4l2_ctrl_config vivid_ctrl_s32_array = {
drivers/media/test-drivers/vivid/vivid-vbi-gen.c+2−6
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
66 */
77
8+#include <linux/bitops.h>
89 #include <linux/errno.h>
910 #include <linux/kernel.h>
1011 #include <linux/ktime.h>
@@ -165,12 +166,7 @@ static const u8 vivid_cc_sequence2[30] = { · 154 unmodified lines
165166
166167 static u8 calc_parity(u8 val)
167168 {
168− unsigned i;
169− unsigned tot = 0;
170−
171− for (i = 0; i < 7; i++)
172− tot += (val & (1 << i)) ? 1 : 0;
173− return val | ((tot & 1) ? 0 : 0x80);
169+ return val | (parity8(val) ? 0 : 0x80);
174170 }
175171
176172 static void vivid_vbi_gen_set_time_of_day(u8 *packet)
drivers/media/test-drivers/vivid/vivid-vid-cap.c+2−2
@@ -454,8 +454,8 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls) · 453 unmodified lines
454454 if (keep_controls)
455455 return;
456456
457− dims[0] = roundup(dev->src_rect.width, PIXEL_ARRAY_DIV);
458− dims[1] = roundup(dev->src_rect.height, PIXEL_ARRAY_DIV);
457+ dims[0] = DIV_ROUND_UP(dev->src_rect.height, PIXEL_ARRAY_DIV);
458+ dims[1] = DIV_ROUND_UP(dev->src_rect.width, PIXEL_ARRAY_DIV);
459459 v4l2_ctrl_modify_dimensions(dev->pixel_array, dims);
460460 }
461461
drivers/media/usb/gspca/vicam.c+8−2
@@ -227,6 +227,7 @@ static int sd_init(struct gspca_dev *gspca_dev) · 226 unmodified lines
227227 const struct ihex_binrec *rec;
228228 const struct firmware *fw;
229229 u8 *firmware_buf;
230+ int len;
230231
231232 ret = request_ihex_firmware(&fw, VICAM_FIRMWARE,
232233 &gspca_dev->dev->dev);
@@ -241,9 +242,14 @@ static int sd_init(struct gspca_dev *gspca_dev) · 8 unmodified lines
241242 goto exit;
242243 }
243244 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
244− memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len));
245+ len = be16_to_cpu(rec->len);
246+ if (len > PAGE_SIZE) {
247+ ret = -EINVAL;
248+ break;
249+ }
250+ memcpy(firmware_buf, rec->data, len);
245251 ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,
246− be16_to_cpu(rec->len));
252+ len);
247253 if (ret < 0)
248254 break;
249255 }
drivers/media/usb/hdpvr/hdpvr-i2c.c+8−22
@@ -124,32 +124,12 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, · 123 unmodified lines
124124 else
125125 retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf,
126126 msgs[0].len);
127− } else if (num == 2) {
128− if (msgs[0].addr != msgs[1].addr) {
129− v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer with conflicting target addresses\n");
130− retval = -EINVAL;
131− goto out;
132− }
133−
134− if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) {
135− v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with r0=%d, r1=%d\n",
136− msgs[0].flags & I2C_M_RD,
137− msgs[1].flags & I2C_M_RD);
138− retval = -EINVAL;
139− goto out;
140− }
141−
142− /*
143− * Write followed by atomic read is the only complex xfer that
144− * we actually support here.
145− */
127+ } else {
128+ /* do write-then-read */
146129 retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len,
147130 msgs[1].buf, msgs[1].len);
148− } else {
149− v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num);
150131 }
151132
152−out:
153133 mutex_unlock(&dev->i2c_mutex);
154134
155135 return retval ? retval : num;
@@ -165,10 +145,16 @@ static const struct i2c_algorithm hdpvr_algo = { · 9 unmodified lines
165145 .functionality = hdpvr_functionality,
166146 };
167147
148+/* prevent invalid 0-length usb_control_msg and support only write-then-read */
149+static const struct i2c_adapter_quirks hdpvr_quirks = {
150+ .flags = I2C_AQ_NO_ZERO_LEN_READ | I2C_AQ_COMB_WRITE_THEN_READ,
151+};
152+
168153 static const struct i2c_adapter hdpvr_i2c_adapter_template = {
169154 .name = "Hauppauge HD PVR I2C",
170155 .owner = THIS_MODULE,
171156 .algo = &hdpvr_algo,
157+ .quirks = &hdpvr_quirks,
172158 };
173159
174160 static int hdpvr_activate_ir(struct hdpvr_device *dev)
drivers/media/usb/usbtv/usbtv-video.c+4−0
@@ -73,6 +73,10 @@ static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm) · 72 unmodified lines
7373 }
7474
7575 if (params) {
76+ if (vb2_is_busy(&usbtv->vb2q) &&
77+ (usbtv->width != params->cap_width ||
78+ usbtv->height != params->cap_height))
79+ return -EBUSY;
7680 usbtv->width = params->cap_width;
7781 usbtv->height = params->cap_height;
7882 usbtv->n_chunks = usbtv->width * usbtv->height
drivers/media/usb/uvc/uvc_ctrl.c+89−42
@@ -1483,14 +1483,28 @@ static u32 uvc_get_ctrl_bitmap(struct uvc_control *ctrl, · 1482 unmodified lines
14831483 return ~0;
14841484 }
14851485
1486+/*
1487+ * Maximum retry count to avoid spurious errors with controls. Increasing this
1488+ * value does no seem to produce better results in the tested hardware.
1489+ */
1490+#define MAX_QUERY_RETRIES 2
1491+
14861492 static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
14871493 struct uvc_control *ctrl,
14881494 struct uvc_control_mapping *mapping,
14891495 struct v4l2_query_ext_ctrl *v4l2_ctrl)
14901496 {
14911497 if (!ctrl->cached) {
1492− int ret = uvc_ctrl_populate_cache(chain, ctrl);
1493− if (ret < 0)
1498+ unsigned int retries;
1499+ int ret;
1500+
1501+ for (retries = 0; retries < MAX_QUERY_RETRIES; retries++) {
1502+ ret = uvc_ctrl_populate_cache(chain, ctrl);
1503+ if (ret != -EIO)
1504+ break;
1505+ }
1506+
1507+ if (ret)
14941508 return ret;
14951509 }
14961510
@@ -1567,6 +1581,7 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, · 70 unmodified lines
15671581 {
15681582 struct uvc_control_mapping *master_map = NULL;
15691583 struct uvc_control *master_ctrl = NULL;
1584+ int ret;
15701585
15711586 memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));
15721587 v4l2_ctrl->id = mapping->id;
@@ -1587,18 +1602,31 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, · 14 unmodified lines
15871602 __uvc_find_control(ctrl->entity, mapping->master_id,
15881603 &master_map, &master_ctrl, 0, 0);
15891604 if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {
1605+ unsigned int retries;
15901606 s32 val;
15911607 int ret;
15921608
15931609 if (WARN_ON(uvc_ctrl_mapping_is_compound(master_map)))
15941610 return -EIO;
15951611
1596− ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);
1597− if (ret < 0)
1598− return ret;
1612+ for (retries = 0; retries < MAX_QUERY_RETRIES; retries++) {
1613+ ret = __uvc_ctrl_get(chain, master_ctrl, master_map,
1614+ &val);
1615+ if (!ret)
1616+ break;
1617+ if (ret < 0 && ret != -EIO)
1618+ return ret;
1619+ }
15991620
1600− if (val != mapping->master_manual)
1601− v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
1621+ if (ret == -EIO) {
1622+ dev_warn_ratelimited(&chain->dev->udev->dev,
1623+ "UVC non compliance: Error %d querying master control %x (%s)\n",
1624+ ret, master_map->id,
1625+ uvc_map_get_name(master_map));
1626+ } else {
1627+ if (val != mapping->master_manual)
1628+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
1629+ }
16021630 }
16031631
16041632 v4l2_ctrl->elem_size = uvc_mapping_v4l2_size(mapping);
@@ -1613,7 +1641,18 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, · 8 unmodified lines
16131641 return 0;
16141642 }
16151643
1616− return __uvc_queryctrl_boundaries(chain, ctrl, mapping, v4l2_ctrl);
1644+ ret = __uvc_queryctrl_boundaries(chain, ctrl, mapping, v4l2_ctrl);
1645+ if (ret && !mapping->disabled) {
1646+ dev_warn(&chain->dev->udev->dev,
1647+ "UVC non compliance: permanently disabling control %x (%s), due to error %d\n",
1648+ mapping->id, uvc_map_get_name(mapping), ret);
1649+ mapping->disabled = true;
1650+ }
1651+
1652+ if (mapping->disabled)
1653+ v4l2_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
1654+
1655+ return 0;
16171656 }
16181657
16191658 int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
@@ -1812,48 +1851,48 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, · 192 unmodified lines
18121851 uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
18131852 }
18141853
1815−static int uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl,
1816− struct uvc_fh *new_handle)
1854+static int uvc_ctrl_set_handle(struct uvc_control *ctrl, struct uvc_fh *handle)
18171855 {
1818− lockdep_assert_held(&handle->chain->ctrl_mutex);
1819−
1820− if (new_handle) {
1821− int ret;
1856+ int ret;
18221857
1823− if (ctrl->handle)
1824− dev_warn_ratelimited(&handle->stream->dev->udev->dev,
1825− "UVC non compliance: Setting an async control with a pending operation.");
1858+ lockdep_assert_held(&handle->chain->ctrl_mutex);
18261859
1827− if (new_handle == ctrl->handle)
1828− return 0;
1860+ if (ctrl->handle) {
1861+ dev_warn_ratelimited(&handle->stream->dev->udev->dev,
1862+ "UVC non compliance: Setting an async control with a pending operation.");
18291863
1830− if (ctrl->handle) {
1831− WARN_ON(!ctrl->handle->pending_async_ctrls);
1832− if (ctrl->handle->pending_async_ctrls)
1833− ctrl->handle->pending_async_ctrls--;
1834− ctrl->handle = new_handle;
1835− handle->pending_async_ctrls++;
1864+ if (ctrl->handle == handle)
18361865 return 0;
1837− }
1838−
1839− ret = uvc_pm_get(handle->chain->dev);
1840− if (ret)
1841− return ret;
18421866
1843− ctrl->handle = new_handle;
1844− handle->pending_async_ctrls++;
1867+ WARN_ON(!ctrl->handle->pending_async_ctrls);
1868+ if (ctrl->handle->pending_async_ctrls)
1869+ ctrl->handle->pending_async_ctrls--;
1870+ ctrl->handle = handle;
1871+ ctrl->handle->pending_async_ctrls++;
18451872 return 0;
18461873 }
18471874
1848− /* Cannot clear the handle for a control not owned by us.*/
1849− if (WARN_ON(ctrl->handle != handle))
1875+ ret = uvc_pm_get(handle->chain->dev);
1876+ if (ret)
1877+ return ret;
1878+
1879+ ctrl->handle = handle;
1880+ ctrl->handle->pending_async_ctrls++;
1881+ return 0;
1882+}
1883+
1884+static int uvc_ctrl_clear_handle(struct uvc_control *ctrl)
1885+{
1886+ lockdep_assert_held(&ctrl->handle->chain->ctrl_mutex);
1887+
1888+ if (WARN_ON(!ctrl->handle->pending_async_ctrls)) {
1889+ ctrl->handle = NULL;
18501890 return -EINVAL;
1891+ }
18511892
1893+ ctrl->handle->pending_async_ctrls--;
1894+ uvc_pm_put(ctrl->handle->chain->dev);
18521895 ctrl->handle = NULL;
1853− if (WARN_ON(!handle->pending_async_ctrls))
1854− return -EINVAL;
1855− handle->pending_async_ctrls--;
1856− uvc_pm_put(handle->chain->dev);
18571896 return 0;
18581897 }
18591898
@@ -1871,7 +1910,7 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, · 11 unmodified lines
18711910
18721911 handle = ctrl->handle;
18731912 if (handle)
1874− uvc_ctrl_set_handle(handle, ctrl, NULL);
1913+ uvc_ctrl_clear_handle(ctrl);
18751914
18761915 list_for_each_entry(mapping, &ctrl->info.mappings, list) {
18771916 s32 value;
@@ -2033,18 +2072,24 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) · 155 unmodified lines
20332072 goto done;
20342073 }
20352074
2036− list_add_tail(&sev->node, &mapping->ev_subs);
20372075 if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) {
20382076 struct v4l2_event ev;
20392077 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
20402078 s32 val = 0;
20412079
2080+ ret = uvc_pm_get(handle->chain->dev);
2081+ if (ret)
2082+ goto done;
2083+
20422084 if (uvc_ctrl_mapping_is_compound(mapping) ||
20432085 __uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
20442086 changes |= V4L2_EVENT_CTRL_CH_VALUE;
20452087
20462088 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,
20472089 changes);
2090+
2091+ uvc_pm_put(handle->chain->dev);
2092+
20482093 /*
20492094 * Mark the queue as active, allowing this initial event to be
20502095 * accepted.
@@ -2053,6 +2098,8 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) · 2 unmodified lines
20532098 v4l2_event_queue_fh(sev->fh, &ev);
20542099 }
20552100
2101+ list_add_tail(&sev->node, &mapping->ev_subs);
2102+
20562103 done:
20572104 mutex_unlock(&handle->chain->ctrl_mutex);
20582105 return ret;
@@ -2161,7 +2208,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, · 102 unmodified lines
21612208
21622209 if (!rollback && handle && !ret &&
21632210 ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
2164− ret = uvc_ctrl_set_handle(handle, ctrl, handle);
2211+ ret = uvc_ctrl_set_handle(ctrl, handle);
21652212
21662213 if (ret < 0 && !rollback) {
21672214 if (err_ctrl)
@@ -3271,7 +3318,7 @@ void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) · 1103 unmodified lines
32713318 for (unsigned int i = 0; i < entity->ncontrols; ++i) {
32723319 if (entity->controls[i].handle != handle)
32733320 continue;
3274− uvc_ctrl_set_handle(handle, &entity->controls[i], NULL);
3321+ uvc_ctrl_clear_handle(&entity->controls[i]);
32753322 }
32763323 }
32773324
drivers/media/usb/uvc/uvc_driver.c+35−39
@@ -344,6 +344,9 @@ static int uvc_parse_format(struct uvc_device *dev, · 343 unmodified lines
344344 u8 ftype;
345345 int ret;
346346
347+ if (buflen < 4)
348+ return -EINVAL;
349+
347350 format->type = buffer[2];
348351 format->index = buffer[3];
349352 format->frames = frames;
@@ -1866,7 +1869,7 @@ static int uvc_scan_device(struct uvc_device *dev) · 1516 unmodified lines
18661869
18671870 if (list_empty(&dev->chains)) {
18681871 dev_info(&dev->udev->dev, "No valid video chain found.\n");
1869− return -1;
1872+ return -ENODEV;
18701873 }
18711874
18721875 /* Add GPIO entity to the first chain. */
@@ -1958,31 +1961,7 @@ static void uvc_unregister_video(struct uvc_device *dev) · 85 unmodified lines
19581961 if (!video_is_registered(&stream->vdev))
19591962 continue;
19601963
1961− /*
1962− * For stream->vdev we follow the same logic as:
1963− * vb2_video_unregister_device().
1964− */
1965−
1966− /* 1. Take a reference to vdev */
1967− get_device(&stream->vdev.dev);
1968−
1969− /* 2. Ensure that no new ioctls can be called. */
1970− video_unregister_device(&stream->vdev);
1971−
1972− /* 3. Wait for old ioctls to finish. */
1973− mutex_lock(&stream->mutex);
1974−
1975− /* 4. Stop streaming. */
1976− uvc_queue_release(&stream->queue);
1977−
1978− mutex_unlock(&stream->mutex);
1979−
1980− put_device(&stream->vdev.dev);
1981−
1982− /*
1983− * For stream->meta.vdev we can directly call:
1984− * vb2_video_unregister_device().
1985− */
1964+ vb2_video_unregister_device(&stream->vdev);
19861965 vb2_video_unregister_device(&stream->meta.vdev);
19871966
19881967 /*
@@ -2030,6 +2009,8 @@ int uvc_register_video_device(struct uvc_device *dev, · 41 unmodified lines
20302009 vdev->ioctl_ops = ioctl_ops;
20312010 vdev->release = uvc_release;
20322011 vdev->prio = &stream->chain->prio;
2012+ vdev->queue = &queue->queue;
2013+ vdev->lock = &queue->mutex;
20332014 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
20342015 vdev->vfl_dir = VFL_DIR_TX;
20352016 else
@@ -2239,7 +2220,6 @@ static int uvc_probe(struct usb_interface *intf, · 203 unmodified lines
22392220 /* Parse the Video Class control descriptor. */
22402221 ret = uvc_parse_control(dev);
22412222 if (ret < 0) {
2242− ret = -ENODEV;
22432223 uvc_dbg(dev, PROBE, "Unable to parse UVC descriptors\n");
22442224 goto error;
22452225 }
@@ -2275,22 +2255,19 @@ static int uvc_probe(struct usb_interface *intf, · 29 unmodified lines
22752255 goto error;
22762256
22772257 /* Scan the device for video chains. */
2278− if (uvc_scan_device(dev) < 0) {
2279− ret = -ENODEV;
2258+ ret = uvc_scan_device(dev);
2259+ if (ret < 0)
22802260 goto error;
2281− }
22822261
22832262 /* Initialize controls. */
2284− if (uvc_ctrl_init_device(dev) < 0) {
2285− ret = -ENODEV;
2263+ ret = uvc_ctrl_init_device(dev);
2264+ if (ret < 0)
22862265 goto error;
2287− }
22882266
22892267 /* Register video device nodes. */
2290− if (uvc_register_chains(dev) < 0) {
2291− ret = -ENODEV;
2268+ ret = uvc_register_chains(dev);
2269+ if (ret < 0)
22922270 goto error;
2293− }
22942271
22952272 #ifdef CONFIG_MEDIA_CONTROLLER
22962273 /* Register the media device node */
@@ -2316,6 +2293,13 @@ static int uvc_probe(struct usb_interface *intf, · 19 unmodified lines
23162293 goto error;
23172294 }
23182295
2296+ ret = uvc_meta_init(dev);
2297+ if (ret < 0) {
2298+ dev_err(&dev->udev->dev,
2299+ "Error initializing the metadata formats (%d)\n", ret);
2300+ goto error;
2301+ }
2302+
23192303 if (dev->quirks & UVC_QUIRK_NO_RESET_RESUME)
23202304 udev->quirks &= ~USB_QUIRK_RESET_RESUME;
23212305
@@ -2398,9 +2382,12 @@ static int __uvc_resume(struct usb_interface *intf, int reset) · 76 unmodified lines
23982382 list_for_each_entry(stream, &dev->streams, list) {
23992383 if (stream->intf == intf) {
24002384 ret = uvc_video_resume(stream, reset);
2401− if (ret < 0)
2402− uvc_queue_streamoff(&stream->queue,
2403− stream->queue.queue.type);
2385+ if (ret < 0) {
2386+ mutex_lock(&stream->queue.mutex);
2387+ vb2_streamoff(&stream->queue.queue,
2388+ stream->queue.queue.type);
2389+ mutex_unlock(&stream->queue.mutex);
2390+ }
24042391 return ret;
24052392 }
24062393 }
@@ -2514,6 +2501,15 @@ static const struct uvc_device_info uvc_quirk_force_y8 = { · 107 unmodified lines
25142501 * Sort these by vendor/product ID.
25152502 */
25162503 static const struct usb_device_id uvc_ids[] = {
2504+ /* HP Webcam HD 2300 */
2505+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2506+ | USB_DEVICE_ID_MATCH_INT_INFO,
2507+ .idVendor = 0x03f0,
2508+ .idProduct = 0xe207,
2509+ .bInterfaceClass = USB_CLASS_VIDEO,
2510+ .bInterfaceSubClass = 1,
2511+ .bInterfaceProtocol = 0,
2512+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
25172513 /* Quanta ACER HD User Facing */
25182514 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
25192515 | USB_DEVICE_ID_MATCH_INT_INFO,
drivers/media/usb/uvc/uvc_metadata.c+107−15
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/list.h>
1111 #include <linux/module.h>
1212 #include <linux/usb.h>
13+#include <linux/usb/uvc.h>
1314 #include <linux/videodev2.h>
1415
1516 #include <media/v4l2-ioctl.h>
@@ -63,15 +64,20 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *fh, · 47 unmodified lines
6364 struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
6465 struct uvc_device *dev = stream->dev;
6566 struct v4l2_meta_format *fmt = &format->fmt.meta;
66− u32 fmeta = fmt->dataformat;
67+ u32 fmeta = V4L2_META_FMT_UVC;
6768
6869 if (format->type != vfh->vdev->queue->type)
6970 return -EINVAL;
7071
72+ for (unsigned int i = 0; i < dev->nmeta_formats; i++)
73+ if (dev->meta_formats[i] == fmt->dataformat) {
74+ fmeta = fmt->dataformat;
75+ break;
76+ }
77+
7178 memset(fmt, 0, sizeof(*fmt));
7279
73− fmt->dataformat = fmeta == dev->info->meta_format
74− ? fmeta : V4L2_META_FMT_UVC;
80+ fmt->dataformat = fmeta;
7581 fmt->buffersize = UVC_METADATA_BUF_SIZE;
7682
7783 return 0;
@@ -96,7 +102,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *fh, · 18 unmodified lines
96102 */
97103 mutex_lock(&stream->mutex);
98104
99− if (uvc_queue_allocated(&stream->queue))
105+ if (vb2_is_busy(&stream->meta.queue.queue))
100106 ret = -EBUSY;
101107 else
102108 stream->meta.format = fmt->dataformat;
@@ -112,17 +118,19 @@ static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh, · 9 unmodified lines
112118 struct v4l2_fh *vfh = file->private_data;
113119 struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
114120 struct uvc_device *dev = stream->dev;
115− u32 index = fdesc->index;
121+ u32 i = fdesc->index;
122+
123+ if (fdesc->type != vfh->vdev->queue->type)
124+ return -EINVAL;
116125
117− if (fdesc->type != vfh->vdev->queue->type ||
118− index > 1U || (index && !dev->info->meta_format))
126+ if (i >= dev->nmeta_formats)
119127 return -EINVAL;
120128
121129 memset(fdesc, 0, sizeof(*fdesc));
122130
123131 fdesc->type = vfh->vdev->queue->type;
124− fdesc->index = index;
125− fdesc->pixelformat = index ? dev->info->meta_format : V4L2_META_FMT_UVC;
132+ fdesc->index = i;
133+ fdesc->pixelformat = dev->meta_formats[i];
126134
127135 return 0;
128136 }
@@ -156,6 +164,71 @@ static const struct v4l2_file_operations uvc_meta_fops = { · 27 unmodified lines
156164 .mmap = vb2_fop_mmap,
157165 };
158166
167+static struct uvc_entity *uvc_meta_find_msxu(struct uvc_device *dev)
168+{
169+ static const u8 uvc_msxu_guid[16] = UVC_GUID_MSXU_1_5;
170+ struct uvc_entity *entity;
171+
172+ list_for_each_entry(entity, &dev->entities, list) {
173+ if (!memcmp(entity->guid, uvc_msxu_guid, sizeof(entity->guid)))
174+ return entity;
175+ }
176+
177+ return NULL;
178+}
179+
180+#define MSXU_CONTROL_METADATA 0x9
181+static int uvc_meta_detect_msxu(struct uvc_device *dev)
182+{
183+ u32 *data __free(kfree) = NULL;
184+ struct uvc_entity *entity;
185+ int ret;
186+
187+ entity = uvc_meta_find_msxu(dev);
188+ if (!entity)
189+ return 0;
190+
191+ /*
192+ * USB requires buffers aligned in a special way, simplest way is to
193+ * make sure that query_ctrl will work is to kmalloc() them.
194+ */
195+ data = kmalloc(sizeof(*data), GFP_KERNEL);
196+ if (!data)
197+ return -ENOMEM;
198+
199+ /* Check if the metadata is already enabled. */
200+ ret = uvc_query_ctrl(dev, UVC_GET_CUR, entity->id, dev->intfnum,
201+ MSXU_CONTROL_METADATA, data, sizeof(*data));
202+ if (ret)
203+ return 0;
204+
205+ if (*data) {
206+ dev->quirks |= UVC_QUIRK_MSXU_META;
207+ return 0;
208+ }
209+
210+ /*
211+ * We have seen devices that require 1 to enable the metadata, others
212+ * requiring a value != 1 and others requiring a value >1. Luckily for
213+ * us, the value from GET_MAX seems to work all the time.
214+ */
215+ ret = uvc_query_ctrl(dev, UVC_GET_MAX, entity->id, dev->intfnum,
216+ MSXU_CONTROL_METADATA, data, sizeof(*data));
217+ if (ret || !*data)
218+ return 0;
219+
220+ /*
221+ * If we can set MSXU_CONTROL_METADATA, the device will report
222+ * metadata.
223+ */
224+ ret = uvc_query_ctrl(dev, UVC_SET_CUR, entity->id, dev->intfnum,
225+ MSXU_CONTROL_METADATA, data, sizeof(*data));
226+ if (!ret)
227+ dev->quirks |= UVC_QUIRK_MSXU_META;
228+
229+ return 0;
230+}
231+
159232 int uvc_meta_register(struct uvc_streaming *stream)
160233 {
161234 struct uvc_device *dev = stream->dev;
@@ -164,13 +237,32 @@ int uvc_meta_register(struct uvc_streaming *stream) · 2 unmodified lines
164237
165238 stream->meta.format = V4L2_META_FMT_UVC;
166239
167− /*
168− * The video interface queue uses manual locking and thus does not set
169− * the queue pointer. Set it manually here.
170− */
171− vdev->queue = &queue->queue;
172−
173240 return uvc_register_video_device(dev, stream, vdev, queue,
174241 V4L2_BUF_TYPE_META_CAPTURE,
175242 &uvc_meta_fops, &uvc_meta_ioctl_ops);
176243 }
244+
245+int uvc_meta_init(struct uvc_device *dev)
246+{
247+ unsigned int i = 0;
248+ int ret;
249+
250+ ret = uvc_meta_detect_msxu(dev);
251+ if (ret)
252+ return ret;
253+
254+ dev->meta_formats[i++] = V4L2_META_FMT_UVC;
255+
256+ if (dev->info->meta_format &&
257+ !WARN_ON(dev->info->meta_format == V4L2_META_FMT_UVC))
258+ dev->meta_formats[i++] = dev->info->meta_format;
259+
260+ if (dev->quirks & UVC_QUIRK_MSXU_META &&
261+ !WARN_ON(dev->info->meta_format == V4L2_META_FMT_UVC_MSXU_1_5))
262+ dev->meta_formats[i++] = V4L2_META_FMT_UVC_MSXU_1_5;
263+
264+ /* IMPORTANT: for new meta-formats update UVC_MAX_META_DATA_FORMATS. */
265+ dev->nmeta_formats = i;
266+
267+ return 0;
268+}
drivers/media/usb/uvc/uvc_queue.c+42−157
@@ -42,13 +42,15 @@ static inline struct uvc_buffer *uvc_vbuf_to_buffer(struct vb2_v4l2_buffer *buf) · 41 unmodified lines
4242 *
4343 * This function must be called with the queue spinlock held.
4444 */
45−static void uvc_queue_return_buffers(struct uvc_video_queue *queue,
46− enum uvc_buffer_state state)
45+static void __uvc_queue_return_buffers(struct uvc_video_queue *queue,
46+ enum uvc_buffer_state state)
4747 {
4848 enum vb2_buffer_state vb2_state = state == UVC_BUF_STATE_ERROR
4949 ? VB2_BUF_STATE_ERROR
5050 : VB2_BUF_STATE_QUEUED;
5151
52+ lockdep_assert_held(&queue->irqlock);
53+
5254 while (!list_empty(&queue->irqqueue)) {
5355 struct uvc_buffer *buf = list_first_entry(&queue->irqqueue,
5456 struct uvc_buffer,
@@ -59,6 +61,14 @@ static void uvc_queue_return_buffers(struct uvc_video_queue *queue, · 4 unmodified lines
5961 }
6062 }
6163
64+static void uvc_queue_return_buffers(struct uvc_video_queue *queue,
65+ enum uvc_buffer_state state)
66+{
67+ spin_lock_irq(&queue->irqlock);
68+ __uvc_queue_return_buffers(queue, state);
69+ spin_unlock_irq(&queue->irqlock);
70+}
71+
6272 /* -----------------------------------------------------------------------------
6373 * videobuf2 queue operations
6474 */
@@ -157,7 +167,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb) · 92 unmodified lines
157167 uvc_video_clock_update(stream, vbuf, buf);
158168 }
159169
160−static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count)
170+static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
161171 {
162172 struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
163173 struct uvc_streaming *stream = uvc_queue_to_stream(queue);
@@ -165,31 +175,44 @@ static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count) · 1 unmodified line
165175
166176 lockdep_assert_irqs_enabled();
167177
178+ ret = uvc_pm_get(stream->dev);
179+ if (ret)
180+ return ret;
181+
168182 queue->buf_used = 0;
169183
170184 ret = uvc_video_start_streaming(stream);
171185 if (ret == 0)
172186 return 0;
173187
174− spin_lock_irq(&queue->irqlock);
188+ uvc_pm_put(stream->dev);
189+
175190 uvc_queue_return_buffers(queue, UVC_BUF_STATE_QUEUED);
176− spin_unlock_irq(&queue->irqlock);
177191
178192 return ret;
179193 }
180194
181−static void uvc_stop_streaming(struct vb2_queue *vq)
195+static void uvc_stop_streaming_video(struct vb2_queue *vq)
182196 {
183197 struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
198+ struct uvc_streaming *stream = uvc_queue_to_stream(queue);
184199
185200 lockdep_assert_irqs_enabled();
186201
187− if (vq->type != V4L2_BUF_TYPE_META_CAPTURE)
188− uvc_video_stop_streaming(uvc_queue_to_stream(queue));
202+ uvc_video_stop_streaming(uvc_queue_to_stream(queue));
203+
204+ uvc_pm_put(stream->dev);
205+
206+ uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
207+}
208+
209+static void uvc_stop_streaming_meta(struct vb2_queue *vq)
210+{
211+ struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
212+
213+ lockdep_assert_irqs_enabled();
189214
190− spin_lock_irq(&queue->irqlock);
191215 uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
192− spin_unlock_irq(&queue->irqlock);
193216 }
194217
195218 static const struct vb2_ops uvc_queue_qops = {
@@ -197,15 +220,20 @@ static const struct vb2_ops uvc_queue_qops = { · 1 unmodified line
197220 .buf_prepare = uvc_buffer_prepare,
198221 .buf_queue = uvc_buffer_queue,
199222 .buf_finish = uvc_buffer_finish,
200− .start_streaming = uvc_start_streaming,
201− .stop_streaming = uvc_stop_streaming,
223+ .start_streaming = uvc_start_streaming_video,
224+ .stop_streaming = uvc_stop_streaming_video,
202225 };
203226
204227 static const struct vb2_ops uvc_meta_queue_qops = {
205228 .queue_setup = uvc_queue_setup,
206229 .buf_prepare = uvc_buffer_prepare,
207230 .buf_queue = uvc_buffer_queue,
208− .stop_streaming = uvc_stop_streaming,
231+ /*
232+ * .start_streaming is not provided here. Metadata relies on video
233+ * streaming being active. If video isn't streaming, then no metadata
234+ * will arrive either.
235+ */
236+ .stop_streaming = uvc_stop_streaming_meta,
209237 };
210238
211239 int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
@@ -242,153 +270,10 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type) · 30 unmodified lines
242270 return 0;
243271 }
244272
245−void uvc_queue_release(struct uvc_video_queue *queue)
246−{
247− mutex_lock(&queue->mutex);
248− vb2_queue_release(&queue->queue);
249− mutex_unlock(&queue->mutex);
250−}
251−
252−/* -----------------------------------------------------------------------------
253− * V4L2 queue operations
254− */
255−
256−int uvc_request_buffers(struct uvc_video_queue *queue,
257− struct v4l2_requestbuffers *rb)
258−{
259− int ret;
260−
261− mutex_lock(&queue->mutex);
262− ret = vb2_reqbufs(&queue->queue, rb);
263− mutex_unlock(&queue->mutex);
264−
265− return ret ? ret : rb->count;
266−}
267−
268−int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
269−{
270− int ret;
271−
272− mutex_lock(&queue->mutex);
273− ret = vb2_querybuf(&queue->queue, buf);
274− mutex_unlock(&queue->mutex);
275−
276− return ret;
277−}
278−
279−int uvc_create_buffers(struct uvc_video_queue *queue,
280− struct v4l2_create_buffers *cb)
281−{
282− int ret;
283−
284− mutex_lock(&queue->mutex);
285− ret = vb2_create_bufs(&queue->queue, cb);
286− mutex_unlock(&queue->mutex);
287−
288− return ret;
289−}
290−
291−int uvc_queue_buffer(struct uvc_video_queue *queue,
292− struct media_device *mdev, struct v4l2_buffer *buf)
293−{
294− int ret;
295−
296− mutex_lock(&queue->mutex);
297− ret = vb2_qbuf(&queue->queue, mdev, buf);
298− mutex_unlock(&queue->mutex);
299−
300− return ret;
301−}
302−
303−int uvc_export_buffer(struct uvc_video_queue *queue,
304− struct v4l2_exportbuffer *exp)
305−{
306− int ret;
307−
308− mutex_lock(&queue->mutex);
309− ret = vb2_expbuf(&queue->queue, exp);
310− mutex_unlock(&queue->mutex);
311−
312− return ret;
313−}
314−
315−int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf,
316− int nonblocking)
317−{
318− int ret;
319−
320− mutex_lock(&queue->mutex);
321− ret = vb2_dqbuf(&queue->queue, buf, nonblocking);
322− mutex_unlock(&queue->mutex);
323−
324− return ret;
325−}
326−
327−int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type)
328−{
329− int ret;
330−
331− mutex_lock(&queue->mutex);
332− ret = vb2_streamon(&queue->queue, type);
333− mutex_unlock(&queue->mutex);
334−
335− return ret;
336−}
337−
338−int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type)
339−{
340− int ret;
341−
342− mutex_lock(&queue->mutex);
343− ret = vb2_streamoff(&queue->queue, type);
344− mutex_unlock(&queue->mutex);
345−
346− return ret;
347−}
348−
349−int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
350−{
351− return vb2_mmap(&queue->queue, vma);
352−}
353−
354−#ifndef CONFIG_MMU
355−unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
356− unsigned long pgoff)
357−{
358− return vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0);
359−}
360−#endif
361−
362−__poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
363− poll_table *wait)
364−{
365− __poll_t ret;
366−
367− mutex_lock(&queue->mutex);
368− ret = vb2_poll(&queue->queue, file, wait);
369− mutex_unlock(&queue->mutex);
370−
371− return ret;
372−}
373−
374273 /* -----------------------------------------------------------------------------
375274 *
376275 */
377276
378−/*
379− * Check if buffers have been allocated.
380− */
381−int uvc_queue_allocated(struct uvc_video_queue *queue)
382−{
383− int allocated;
384−
385− mutex_lock(&queue->mutex);
386− allocated = vb2_is_busy(&queue->queue);
387− mutex_unlock(&queue->mutex);
388−
389− return allocated;
390−}
391−
392277 /*
393278 * Cancel the video buffers queue.
394279 *
@@ -406,7 +291,7 @@ void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) · 11 unmodified lines
406291 unsigned long flags;
407292
408293 spin_lock_irqsave(&queue->irqlock, flags);
409− uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
294+ __uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
410295 /*
411296 * This must be protected by the irqlock spinlock to avoid race
412297 * conditions between uvc_buffer_queue and the disconnection event that
drivers/media/usb/uvc/uvc_v4l2.c+53−313
@@ -47,8 +47,6 @@ void uvc_pm_put(struct uvc_device *dev) · 46 unmodified lines
4747 usb_autopm_put_interface(dev->intf);
4848 }
4949
50−static int uvc_acquire_privileges(struct uvc_fh *handle);
51−
5250 static int uvc_control_add_xu_mapping(struct uvc_video_chain *chain,
5351 struct uvc_control_mapping *map,
5452 const struct uvc_xu_control_mapping *xmap)
@@ -436,10 +434,6 @@ static int uvc_ioctl_s_fmt(struct file *file, void *fh, · 381 unmodified lines
436434 const struct uvc_frame *frame;
437435 int ret;
438436
439− ret = uvc_acquire_privileges(handle);
440− if (ret < 0)
441− return ret;
442−
443437 if (fmt->type != stream->type)
444438 return -EINVAL;
445439
@@ -448,8 +442,7 @@ static int uvc_ioctl_s_fmt(struct file *file, void *fh, · 2 unmodified lines
448442 return ret;
449443
450444 mutex_lock(&stream->mutex);
451−
452− if (uvc_queue_allocated(&stream->queue)) {
445+ if (vb2_is_busy(&stream->queue.queue)) {
453446 ret = -EBUSY;
454447 goto done;
455448 }
@@ -513,10 +506,6 @@ static int uvc_ioctl_s_parm(struct file *file, void *fh, · 57 unmodified lines
513506 unsigned int i;
514507 int ret;
515508
516− ret = uvc_acquire_privileges(handle);
517− if (ret < 0)
518− return ret;
519−
520509 if (parm->type != stream->type)
521510 return -EINVAL;
522511
@@ -593,63 +582,6 @@ static int uvc_ioctl_s_parm(struct file *file, void *fh, · 70 unmodified lines
593582 return 0;
594583 }
595584
596−/* ------------------------------------------------------------------------
597− * Privilege management
598− */
599−
600−/*
601− * Privilege management is the multiple-open implementation basis. The current
602− * implementation is completely transparent for the end-user and doesn't
603− * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls.
604− * Those ioctls enable finer control on the device (by making possible for a
605− * user to request exclusive access to a device), but are not mature yet.
606− * Switching to the V4L2 priority mechanism might be considered in the future
607− * if this situation changes.
608− *
609− * Each open instance of a UVC device can either be in a privileged or
610− * unprivileged state. Only a single instance can be in a privileged state at
611− * a given time. Trying to perform an operation that requires privileges will
612− * automatically acquire the required privileges if possible, or return -EBUSY
613− * otherwise. Privileges are dismissed when closing the instance or when
614− * freeing the video buffers using VIDIOC_REQBUFS.
615− *
616− * Operations that require privileges are:
617− *
618− * - VIDIOC_S_INPUT
619− * - VIDIOC_S_PARM
620− * - VIDIOC_S_FMT
621− * - VIDIOC_CREATE_BUFS
622− * - VIDIOC_REQBUFS
623− */
624−static int uvc_acquire_privileges(struct uvc_fh *handle)
625−{
626− /* Always succeed if the handle is already privileged. */
627− if (handle->state == UVC_HANDLE_ACTIVE)
628− return 0;
629−
630− /* Check if the device already has a privileged handle. */
631− if (atomic_inc_return(&handle->stream->active) != 1) {
632− atomic_dec(&handle->stream->active);
633− return -EBUSY;
634− }
635−
636− handle->state = UVC_HANDLE_ACTIVE;
637− return 0;
638−}
639−
640−static void uvc_dismiss_privileges(struct uvc_fh *handle)
641−{
642− if (handle->state == UVC_HANDLE_ACTIVE)
643− atomic_dec(&handle->stream->active);
644−
645− handle->state = UVC_HANDLE_PASSIVE;
646−}
647−
648−static int uvc_has_privileges(struct uvc_fh *handle)
649−{
650− return handle->state == UVC_HANDLE_ACTIVE;
651−}
652−
653585 /* ------------------------------------------------------------------------
654586 * V4L2 file operations
655587 */
@@ -671,7 +603,6 @@ static int uvc_v4l2_open(struct file *file) · 15 unmodified lines
671603 v4l2_fh_add(&handle->vfh);
672604 handle->chain = stream->chain;
673605 handle->stream = stream;
674− handle->state = UVC_HANDLE_PASSIVE;
675606 file->private_data = handle;
676607
677608 return 0;
@@ -686,19 +617,8 @@ static int uvc_v4l2_release(struct file *file) · 8 unmodified lines
686617
687618 uvc_ctrl_cleanup_fh(handle);
688619
689− /* Only free resources if this is a privileged handle. */
690− if (uvc_has_privileges(handle))
691− uvc_queue_release(&stream->queue);
692−
693− if (handle->is_streaming)
694− uvc_pm_put(stream->dev);
695−
696620 /* Release the file handle. */
697− uvc_dismiss_privileges(handle);
698− v4l2_fh_del(&handle->vfh);
699− v4l2_fh_exit(&handle->vfh);
700− kfree(handle);
701− file->private_data = NULL;
621+ vb2_fop_release(file);
702622
703623 return 0;
704624 }
@@ -753,140 +673,6 @@ static int uvc_ioctl_try_fmt(struct file *file, void *fh, · 48 unmodified lines
753673 return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
754674 }
755675
756−static int uvc_ioctl_reqbufs(struct file *file, void *fh,
757− struct v4l2_requestbuffers *rb)
758−{
759− struct uvc_fh *handle = fh;
760− struct uvc_streaming *stream = handle->stream;
761− int ret;
762−
763− ret = uvc_acquire_privileges(handle);
764− if (ret < 0)
765− return ret;
766−
767− mutex_lock(&stream->mutex);
768− ret = uvc_request_buffers(&stream->queue, rb);
769− mutex_unlock(&stream->mutex);
770− if (ret < 0)
771− return ret;
772−
773− if (ret == 0)
774− uvc_dismiss_privileges(handle);
775−
776− return 0;
777−}
778−
779−static int uvc_ioctl_querybuf(struct file *file, void *fh,
780− struct v4l2_buffer *buf)
781−{
782− struct uvc_fh *handle = fh;
783− struct uvc_streaming *stream = handle->stream;
784−
785− if (!uvc_has_privileges(handle))
786− return -EBUSY;
787−
788− return uvc_query_buffer(&stream->queue, buf);
789−}
790−
791−static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
792−{
793− struct uvc_fh *handle = fh;
794− struct uvc_streaming *stream = handle->stream;
795−
796− if (!uvc_has_privileges(handle))
797− return -EBUSY;
798−
799− return uvc_queue_buffer(&stream->queue,
800− stream->vdev.v4l2_dev->mdev, buf);
801−}
802−
803−static int uvc_ioctl_expbuf(struct file *file, void *fh,
804− struct v4l2_exportbuffer *exp)
805−{
806− struct uvc_fh *handle = fh;
807− struct uvc_streaming *stream = handle->stream;
808−
809− if (!uvc_has_privileges(handle))
810− return -EBUSY;
811−
812− return uvc_export_buffer(&stream->queue, exp);
813−}
814−
815−static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
816−{
817− struct uvc_fh *handle = fh;
818− struct uvc_streaming *stream = handle->stream;
819−
820− if (!uvc_has_privileges(handle))
821− return -EBUSY;
822−
823− return uvc_dequeue_buffer(&stream->queue, buf,
824− file->f_flags & O_NONBLOCK);
825−}
826−
827−static int uvc_ioctl_create_bufs(struct file *file, void *fh,
828− struct v4l2_create_buffers *cb)
829−{
830− struct uvc_fh *handle = fh;
831− struct uvc_streaming *stream = handle->stream;
832− int ret;
833−
834− ret = uvc_acquire_privileges(handle);
835− if (ret < 0)
836− return ret;
837−
838− return uvc_create_buffers(&stream->queue, cb);
839−}
840−
841−static int uvc_ioctl_streamon(struct file *file, void *fh,
842− enum v4l2_buf_type type)
843−{
844− struct uvc_fh *handle = fh;
845− struct uvc_streaming *stream = handle->stream;
846− int ret;
847−
848− if (!uvc_has_privileges(handle))
849− return -EBUSY;
850−
851− guard(mutex)(&stream->mutex);
852−
853− if (handle->is_streaming)
854− return 0;
855−
856− ret = uvc_queue_streamon(&stream->queue, type);
857− if (ret)
858− return ret;
859−
860− ret = uvc_pm_get(stream->dev);
861− if (ret) {
862− uvc_queue_streamoff(&stream->queue, type);
863− return ret;
864− }
865− handle->is_streaming = true;
866−
867− return 0;
868−}
869−
870−static int uvc_ioctl_streamoff(struct file *file, void *fh,
871− enum v4l2_buf_type type)
872−{
873− struct uvc_fh *handle = fh;
874− struct uvc_streaming *stream = handle->stream;
875−
876− if (!uvc_has_privileges(handle))
877− return -EBUSY;
878−
879− guard(mutex)(&stream->mutex);
880−
881− uvc_queue_streamoff(&stream->queue, type);
882− if (handle->is_streaming) {
883− handle->is_streaming = false;
884− uvc_pm_put(stream->dev);
885− }
886−
887− return 0;
888−}
889−
890676 static int uvc_ioctl_enum_input(struct file *file, void *fh,
891677 struct v4l2_input *input)
892678 {
@@ -961,13 +747,13 @@ static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input) · 68 unmodified lines
961747 static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
962748 {
963749 struct uvc_fh *handle = fh;
750+ struct uvc_streaming *stream = handle->stream;
964751 struct uvc_video_chain *chain = handle->chain;
965752 u8 *buf;
966753 int ret;
967754
968− ret = uvc_acquire_privileges(handle);
969− if (ret < 0)
970− return ret;
755+ if (vb2_is_busy(&stream->queue.queue))
756+ return -EBUSY;
971757
972758 if (chain->selector == NULL ||
973759 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
@@ -1381,11 +1167,9 @@ static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp, · 407 unmodified lines
13811167 #define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
13821168 #define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
13831169
1384−DEFINE_FREE(uvc_pm_put, struct uvc_device *, if (_T) uvc_pm_put(_T))
13851170 static long uvc_v4l2_compat_ioctl32(struct file *file,
13861171 unsigned int cmd, unsigned long arg)
13871172 {
1388− struct uvc_device *uvc_device __free(uvc_pm_put) = NULL;
13891173 struct uvc_fh *handle = file->private_data;
13901174 union {
13911175 struct uvc_xu_control_mapping xmap;
@@ -1398,38 +1182,38 @@ static long uvc_v4l2_compat_ioctl32(struct file *file, · 6 unmodified lines
13981182 if (ret)
13991183 return ret;
14001184
1401− uvc_device = handle->stream->dev;
1402−
14031185 switch (cmd) {
14041186 case UVCIOC_CTRL_MAP32:
14051187 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
14061188 if (ret)
1407− return ret;
1189+ break;
14081190 ret = uvc_ioctl_xu_ctrl_map(handle->chain, &karg.xmap);
14091191 if (ret)
1410− return ret;
1192+ break;
14111193 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
14121194 if (ret)
1413− return ret;
1414−
1195+ break;
14151196 break;
14161197
14171198 case UVCIOC_CTRL_QUERY32:
14181199 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
14191200 if (ret)
1420− return ret;
1201+ break;
14211202 ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
14221203 if (ret)
1423− return ret;
1204+ break;
14241205 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
14251206 if (ret)
1426− return ret;
1207+ break;
14271208 break;
14281209
14291210 default:
1430− return -ENOIOCTLCMD;
1211+ ret = -ENOIOCTLCMD;
1212+ break;
14311213 }
14321214
1215+ uvc_pm_put(handle->stream->dev);
1216+
14331217 return ret;
14341218 }
14351219 #endif
@@ -1438,81 +1222,37 @@ static long uvc_v4l2_unlocked_ioctl(struct file *file, · 2 unmodified lines
14381222 unsigned int cmd, unsigned long arg)
14391223 {
14401224 struct uvc_fh *handle = file->private_data;
1225+ unsigned int converted_cmd = v4l2_translate_cmd(cmd);
14411226 int ret;
14421227
1443− /* The following IOCTLs do not need to turn on the camera. */
1444− switch (cmd) {
1445− case VIDIOC_CREATE_BUFS:
1446− case VIDIOC_DQBUF:
1447− case VIDIOC_ENUM_FMT:
1448− case VIDIOC_ENUM_FRAMEINTERVALS:
1449− case VIDIOC_ENUM_FRAMESIZES:
1450− case VIDIOC_ENUMINPUT:
1451− case VIDIOC_EXPBUF:
1452− case VIDIOC_G_FMT:
1453− case VIDIOC_G_PARM:
1454− case VIDIOC_G_SELECTION:
1455− case VIDIOC_QBUF:
1456− case VIDIOC_QUERYCAP:
1457− case VIDIOC_REQBUFS:
1458− case VIDIOC_SUBSCRIBE_EVENT:
1459− case VIDIOC_UNSUBSCRIBE_EVENT:
1460− return video_ioctl2(file, cmd, arg);
1461− }
1462−
1463− ret = uvc_pm_get(handle->stream->dev);
1464− if (ret)
1228+ /* The following IOCTLs need to turn on the camera. */
1229+ switch (converted_cmd) {
1230+ case UVCIOC_CTRL_MAP:
1231+ case UVCIOC_CTRL_QUERY:
1232+ case VIDIOC_G_CTRL:
1233+ case VIDIOC_G_EXT_CTRLS:
1234+ case VIDIOC_G_INPUT:
1235+ case VIDIOC_QUERYCTRL:
1236+ case VIDIOC_QUERYMENU:
1237+ case VIDIOC_QUERY_EXT_CTRL:
1238+ case VIDIOC_S_CTRL:
1239+ case VIDIOC_S_EXT_CTRLS:
1240+ case VIDIOC_S_FMT:
1241+ case VIDIOC_S_INPUT:
1242+ case VIDIOC_S_PARM:
1243+ case VIDIOC_TRY_EXT_CTRLS:
1244+ case VIDIOC_TRY_FMT:
1245+ ret = uvc_pm_get(handle->stream->dev);
1246+ if (ret)
1247+ return ret;
1248+ ret = video_ioctl2(file, cmd, arg);
1249+ uvc_pm_put(handle->stream->dev);
14651250 return ret;
1251+ }
14661252
1467− ret = video_ioctl2(file, cmd, arg);
1468−
1469− uvc_pm_put(handle->stream->dev);
1470− return ret;
1471−}
1472−
1473−static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1474− size_t count, loff_t *ppos)
1475−{
1476− struct uvc_fh *handle = file->private_data;
1477− struct uvc_streaming *stream = handle->stream;
1478−
1479− uvc_dbg(stream->dev, CALLS, "%s: not implemented\n", __func__);
1480− return -EINVAL;
1481−}
1482−
1483−static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1484−{
1485− struct uvc_fh *handle = file->private_data;
1486− struct uvc_streaming *stream = handle->stream;
1487−
1488− uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
1489−
1490− return uvc_queue_mmap(&stream->queue, vma);
1491−}
1492−
1493−static __poll_t uvc_v4l2_poll(struct file *file, poll_table *wait)
1494−{
1495− struct uvc_fh *handle = file->private_data;
1496− struct uvc_streaming *stream = handle->stream;
1497−
1498− uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
1499−
1500− return uvc_queue_poll(&stream->queue, file, wait);
1501−}
1502−
1503−#ifndef CONFIG_MMU
1504−static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1505− unsigned long addr, unsigned long len, unsigned long pgoff,
1506− unsigned long flags)
1507−{
1508− struct uvc_fh *handle = file->private_data;
1509− struct uvc_streaming *stream = handle->stream;
1510−
1511− uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
1512−
1513− return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1253+ /* The other IOCTLs can run with the camera off. */
1254+ return video_ioctl2(file, cmd, arg);
15141255 }
1515−#endif
15161256
15171257 const struct v4l2_ioctl_ops uvc_ioctl_ops = {
15181258 .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt,
@@ -1526,14 +1266,15 @@ const struct v4l2_ioctl_ops uvc_ioctl_ops = { · 7 unmodified lines
15261266 .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt,
15271267 .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt,
15281268 .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt,
1529− .vidioc_reqbufs = uvc_ioctl_reqbufs,
1530− .vidioc_querybuf = uvc_ioctl_querybuf,
1531− .vidioc_qbuf = uvc_ioctl_qbuf,
1532− .vidioc_expbuf = uvc_ioctl_expbuf,
1533− .vidioc_dqbuf = uvc_ioctl_dqbuf,
1534− .vidioc_create_bufs = uvc_ioctl_create_bufs,
1535− .vidioc_streamon = uvc_ioctl_streamon,
1536− .vidioc_streamoff = uvc_ioctl_streamoff,
1269+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
1270+ .vidioc_querybuf = vb2_ioctl_querybuf,
1271+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1272+ .vidioc_qbuf = vb2_ioctl_qbuf,
1273+ .vidioc_expbuf = vb2_ioctl_expbuf,
1274+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
1275+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
1276+ .vidioc_streamon = vb2_ioctl_streamon,
1277+ .vidioc_streamoff = vb2_ioctl_streamoff,
15371278 .vidioc_enum_input = uvc_ioctl_enum_input,
15381279 .vidioc_g_input = uvc_ioctl_g_input,
15391280 .vidioc_s_input = uvc_ioctl_s_input,
@@ -1558,11 +1299,10 @@ const struct v4l2_file_operations uvc_fops = { · 18 unmodified lines
15581299 #ifdef CONFIG_COMPAT
15591300 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
15601301 #endif
1561− .read = uvc_v4l2_read,
1562− .mmap = uvc_v4l2_mmap,
1563− .poll = uvc_v4l2_poll,
1302+ .mmap = vb2_fop_mmap,
1303+ .poll = vb2_fop_poll,
15641304 #ifndef CONFIG_MMU
1565− .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1305+ .get_unmapped_area = vb2_fop_get_unmapped_area,
15661306 #endif
15671307 };
15681308
drivers/media/usb/uvc/uvc_video.c+15−6
@@ -262,6 +262,15 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, · 261 unmodified lines
262262
263263 ctrl->dwMaxPayloadTransferSize = bandwidth;
264264 }
265+
266+ if (stream->intf->num_altsetting > 1 &&
267+ ctrl->dwMaxPayloadTransferSize > stream->maxpsize) {
268+ dev_warn_ratelimited(&stream->intf->dev,
269+ "UVC non compliance: the max payload transmission size (%u) exceeds the size of the ep max packet (%u). Using the max size.\n",
270+ ctrl->dwMaxPayloadTransferSize,
271+ stream->maxpsize);
272+ ctrl->dwMaxPayloadTransferSize = stream->maxpsize;
273+ }
265274 }
266275
267276 static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)
@@ -1419,12 +1428,6 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, · 1151 unmodified lines
14191428 if (!meta_buf || length == 2)
14201429 return;
14211430
1422− if (meta_buf->length - meta_buf->bytesused <
1423− length + sizeof(meta->ns) + sizeof(meta->sof)) {
1424− meta_buf->error = 1;
1425− return;
1426− }
1427−
14281431 has_pts = mem[1] & UVC_STREAM_PTS;
14291432 has_scr = mem[1] & UVC_STREAM_SCR;
14301433
@@ -1445,6 +1448,12 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, · 14 unmodified lines
14451448 !memcmp(scr, stream->clock.last_scr, 6)))
14461449 return;
14471450
1451+ if (meta_buf->length - meta_buf->bytesused <
1452+ length + sizeof(meta->ns) + sizeof(meta->sof)) {
1453+ meta_buf->error = 1;
1454+ return;
1455+ }
1456+
14481457 meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused);
14491458 local_irq_save(flags);
14501459 time = uvc_video_get_time();
drivers/media/usb/uvc/uvcvideo.h+13−33
@@ -77,6 +77,7 @@ · 76 unmodified lines
7777 #define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
7878 #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
7979 #define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
80+#define UVC_QUIRK_MSXU_META 0x00040000
8081
8182 /* Format flags */
8283 #define UVC_FMT_FLAG_COMPRESSED 0x00000001
@@ -134,6 +135,8 @@ struct uvc_control_mapping { · 51 unmodified lines
134135 s32 master_manual;
135136 u32 slave_ids[2];
136137
138+ bool disabled;
139+
137140 const struct uvc_control_mapping *(*filter_mapping)
138141 (struct uvc_video_chain *chain,
139142 struct uvc_control *ctrl);
@@ -326,7 +329,10 @@ struct uvc_buffer { · 186 unmodified lines
326329
327330 struct uvc_video_queue {
328331 struct vb2_queue queue;
329− struct mutex mutex; /* Protects queue */
332+ struct mutex mutex; /*
333+ * Serializes vb2_queue and
334+ * fops
335+ */
330336
331337 unsigned int flags;
332338 unsigned int buf_used;
@@ -570,6 +576,8 @@ struct uvc_status { · 237 unmodified lines
570576 };
571577 } __packed;
572578
579+#define UVC_MAX_META_DATA_FORMATS 3
580+
573581 struct uvc_device {
574582 struct usb_device *udev;
575583 struct usb_interface *intf;
@@ -580,6 +588,9 @@ struct uvc_device { · 4 unmodified lines
580588
581589 const struct uvc_device_info *info;
582590
591+ u32 meta_formats[UVC_MAX_META_DATA_FORMATS];
592+ unsigned int nmeta_formats;
593+
583594 atomic_t nmappings;
584595
585596 /* Video control interface */
@@ -619,18 +630,11 @@ struct uvc_device { · 33 unmodified lines
619630 struct uvc_entity *gpio_unit;
620631 };
621632
622−enum uvc_handle_state {
623− UVC_HANDLE_PASSIVE = 0,
624− UVC_HANDLE_ACTIVE = 1,
625−};
626−
627633 struct uvc_fh {
628634 struct v4l2_fh vfh;
629635 struct uvc_video_chain *chain;
630636 struct uvc_streaming *stream;
631− enum uvc_handle_state state;
632637 unsigned int pending_async_ctrls;
633− bool is_streaming;
634638 };
635639
636640 /* ------------------------------------------------------------------------
@@ -687,36 +691,11 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); · 50 unmodified lines
687691
688692 /* Video buffers queue management. */
689693 int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type);
690−void uvc_queue_release(struct uvc_video_queue *queue);
691−int uvc_request_buffers(struct uvc_video_queue *queue,
692− struct v4l2_requestbuffers *rb);
693−int uvc_query_buffer(struct uvc_video_queue *queue,
694− struct v4l2_buffer *v4l2_buf);
695−int uvc_create_buffers(struct uvc_video_queue *queue,
696− struct v4l2_create_buffers *v4l2_cb);
697−int uvc_queue_buffer(struct uvc_video_queue *queue,
698− struct media_device *mdev,
699− struct v4l2_buffer *v4l2_buf);
700−int uvc_export_buffer(struct uvc_video_queue *queue,
701− struct v4l2_exportbuffer *exp);
702−int uvc_dequeue_buffer(struct uvc_video_queue *queue,
703− struct v4l2_buffer *v4l2_buf, int nonblocking);
704−int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type);
705−int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type);
706694 void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
707695 struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
708696 struct uvc_buffer *buf);
709697 struct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue);
710698 void uvc_queue_buffer_release(struct uvc_buffer *buf);
711−int uvc_queue_mmap(struct uvc_video_queue *queue,
712− struct vm_area_struct *vma);
713−__poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
714− poll_table *wait);
715−#ifndef CONFIG_MMU
716−unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
717− unsigned long pgoff);
718−#endif
719−int uvc_queue_allocated(struct uvc_video_queue *queue);
720699 static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
721700 {
722701 return vb2_is_streaming(&queue->queue);
@@ -749,6 +728,7 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, · 26 unmodified lines
749728 void uvc_video_clock_update(struct uvc_streaming *stream,
750729 struct vb2_v4l2_buffer *vbuf,
751730 struct uvc_buffer *buf);
731+int uvc_meta_init(struct uvc_device *dev);
752732 int uvc_meta_register(struct uvc_streaming *stream);
753733
754734 int uvc_register_video_device(struct uvc_device *dev,
drivers/media/v4l2-core/v4l2-common.c+36−4
@@ -323,6 +323,12 @@ const struct v4l2_format_info *v4l2_format_info(u32 format) · 322 unmodified lines
323323 { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
324324 { .format = V4L2_PIX_FMT_P012M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
325325
326+ /* Tiled YUV formats, non contiguous variant */
327+ { .format = V4L2_PIX_FMT_NV12MT, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
328+ .block_w = { 64, 32, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
329+ { .format = V4L2_PIX_FMT_NV12MT_16X16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
330+ .block_w = { 16, 8, 0, 0 }, .block_h = { 16, 8, 0, 0 }},
331+
326332 /* Bayer RGB formats */
327333 { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
328334 { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
@@ -332,6 +338,10 @@ const struct v4l2_format_info *v4l2_format_info(u32 format) · 3 unmodified lines
332338 { .format = V4L2_PIX_FMT_SGBRG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
333339 { .format = V4L2_PIX_FMT_SGRBG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
334340 { .format = V4L2_PIX_FMT_SRGGB10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
341+ { .format = V4L2_PIX_FMT_SBGGR10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
342+ { .format = V4L2_PIX_FMT_SGBRG10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
343+ { .format = V4L2_PIX_FMT_SGRBG10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
344+ { .format = V4L2_PIX_FMT_SRGGB10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
335345 { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
336346 { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
337347 { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
@@ -344,6 +354,28 @@ const struct v4l2_format_info *v4l2_format_info(u32 format) · 6 unmodified lines
344354 { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
345355 { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
346356 { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
357+ { .format = V4L2_PIX_FMT_SBGGR12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
358+ { .format = V4L2_PIX_FMT_SGBRG12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
359+ { .format = V4L2_PIX_FMT_SGRBG12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
360+ { .format = V4L2_PIX_FMT_SRGGB12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
361+ { .format = V4L2_PIX_FMT_SBGGR14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
362+ { .format = V4L2_PIX_FMT_SGBRG14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
363+ { .format = V4L2_PIX_FMT_SGRBG14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
364+ { .format = V4L2_PIX_FMT_SRGGB14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
365+ { .format = V4L2_PIX_FMT_SBGGR14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
366+ { .format = V4L2_PIX_FMT_SGBRG14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
367+ { .format = V4L2_PIX_FMT_SGRBG14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
368+ { .format = V4L2_PIX_FMT_SRGGB14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
369+ { .format = V4L2_PIX_FMT_SBGGR16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
370+ { .format = V4L2_PIX_FMT_SGBRG16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
371+ { .format = V4L2_PIX_FMT_SGRBG16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
372+ { .format = V4L2_PIX_FMT_SRGGB16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
373+
374+ /* Renesas Camera Data Receiver Unit formats, bayer order agnostic */
375+ { .format = V4L2_PIX_FMT_RAW_CRU10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 6, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
376+ { .format = V4L2_PIX_FMT_RAW_CRU12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 5, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
377+ { .format = V4L2_PIX_FMT_RAW_CRU14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
378+ { .format = V4L2_PIX_FMT_RAW_CRU20, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 3, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
347379 };
348380 unsigned int i;
349381
@@ -505,10 +537,10 @@ s64 __v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler, · 155 unmodified lines
505537
506538 freq = div_u64(v4l2_ctrl_g_ctrl_int64(ctrl) * mul, div);
507539
508− pr_warn("%s: Link frequency estimated using pixel rate: result might be inaccurate\n",
509− __func__);
510− pr_warn("%s: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver\n",
511− __func__);
540+ pr_warn_once("%s: Link frequency estimated using pixel rate: result might be inaccurate\n",
541+ __func__);
542+ pr_warn_once("%s: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver\n",
543+ __func__);
512544 }
513545
514546 return freq > 0 ? freq : -EINVAL;
drivers/media/v4l2-core/v4l2-ctrls-core.c+12−8
@@ -968,12 +968,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, · 967 unmodified lines
968968
969969 p_h264_sps->flags &=
970970 ~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS;
971−
972− if (p_h264_sps->chroma_format_idc < 3)
973− p_h264_sps->flags &=
974− ~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE;
975971 }
976972
973+ if (p_h264_sps->chroma_format_idc < 3)
974+ p_h264_sps->flags &=
975+ ~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE;
976+
977977 if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
978978 p_h264_sps->flags &=
979979 ~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD;
@@ -1631,14 +1631,17 @@ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, · 651 unmodified lines
16311631 EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
16321632
16331633 /* Free all controls and control refs */
1634−void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1634+int v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
16351635 {
16361636 struct v4l2_ctrl_ref *ref, *next_ref;
16371637 struct v4l2_ctrl *ctrl, *next_ctrl;
16381638 struct v4l2_subscribed_event *sev, *next_sev;
16391639
1640− if (hdl == NULL || hdl->buckets == NULL)
1641− return;
1640+ if (!hdl)
1641+ return 0;
1642+
1643+ if (!hdl->buckets)
1644+ return hdl->error;
16421645
16431646 v4l2_ctrl_handler_free_request(hdl);
16441647
@@ -1661,9 +1664,10 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) · 16 unmodified lines
16611664 kvfree(hdl->buckets);
16621665 hdl->buckets = NULL;
16631666 hdl->cached = NULL;
1664− hdl->error = 0;
16651667 mutex_unlock(hdl->lock);
16661668 mutex_destroy(&hdl->_lock);
1669+
1670+ return hdl->error;
16671671 }
16681672 EXPORT_SYMBOL(v4l2_ctrl_handler_free);
16691673
drivers/media/v4l2-core/v4l2-i2c.c+2−1
@@ -5,6 +5,7 @@ · 4 unmodified lines
55
66 #include <linux/i2c.h>
77 #include <linux/module.h>
8+#include <linux/property.h>
89 #include <media/v4l2-common.h>
910 #include <media/v4l2-device.h>
1011
@@ -24,7 +25,7 @@ void v4l2_i2c_subdev_unregister(struct v4l2_subdev *sd) · 13 unmodified lines
2425 * registered by us, and would not be
2526 * re-created by just probing the V4L2 driver.
2627 */
27− if (client && !client->dev.of_node && !client->dev.fwnode)
28+ if (client && !dev_fwnode(&client->dev))
2829 i2c_unregister_device(client);
2930 }
3031
drivers/media/v4l2-core/v4l2-ioctl.c+8−2
@@ -1413,6 +1413,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) · 1412 unmodified lines
14131413 case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
14141414 case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
14151415 case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;
1416+ case V4L2_PIX_FMT_RAW_CRU10: descr = "10-bit Raw CRU Packed"; break;
14161417 case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break;
14171418 case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break;
14181419 case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break;
@@ -1421,6 +1422,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) · 2 unmodified lines
14211422 case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;
14221423 case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;
14231424 case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break;
1425+ case V4L2_PIX_FMT_RAW_CRU12: descr = "12-bit Raw CRU Packed"; break;
14241426 case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break;
14251427 case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break;
14261428 case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break;
@@ -1429,10 +1431,12 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) · 2 unmodified lines
14291431 case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;
14301432 case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;
14311433 case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break;
1434+ case V4L2_PIX_FMT_RAW_CRU14: descr = "14-bit Raw CRU Packed"; break;
14321435 case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break;
14331436 case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break;
14341437 case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break;
14351438 case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break;
1439+ case V4L2_PIX_FMT_RAW_CRU20: descr = "14-bit Raw CRU Packed"; break;
14361440 case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break;
14371441 case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break;
14381442 case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break;
@@ -1459,6 +1463,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) · 20 unmodified lines
14591463 case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break;
14601464 case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break;
14611465 case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break;
1466+ case V4L2_META_FMT_UVC_MSXU_1_5: descr = "UVC MSXU Metadata"; break;
14621467 case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break;
14631468 case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break;
14641469 case V4L2_META_FMT_RK_ISP1_PARAMS: descr = "Rockchip ISP1 3A Parameters"; break;
@@ -3245,7 +3250,7 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, · 1780 unmodified lines
32453250 return ret;
32463251 }
32473252
3248−static unsigned int video_translate_cmd(unsigned int cmd)
3253+unsigned int v4l2_translate_cmd(unsigned int cmd)
32493254 {
32503255 #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
32513256 switch (cmd) {
@@ -3266,6 +3271,7 @@ static unsigned int video_translate_cmd(unsigned int cmd) · 14 unmodified lines
32663271
32673272 return cmd;
32683273 }
3274+EXPORT_SYMBOL_GPL(v4l2_translate_cmd);
32693275
32703276 static int video_get_user(void __user *arg, void *parg,
32713277 unsigned int real_cmd, unsigned int cmd,
@@ -3426,7 +3432,7 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg, · 154 unmodified lines
34263432 size_t array_size = 0;
34273433 void __user *user_ptr = NULL;
34283434 void **kernel_ptr = NULL;
3429− unsigned int cmd = video_translate_cmd(orig_cmd);
3435+ unsigned int cmd = v4l2_translate_cmd(orig_cmd);
34303436 const size_t ioc_size = _IOC_SIZE(cmd);
34313437
34323438 /* Copy arguments into temp kernel buffer */
drivers/media/v4l2-core/v4l2-jpeg.c+0−80
@@ -711,83 +711,3 @@ int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out) · 710 unmodified lines
711711 return marker;
712712 }
713713 EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_header);
714−
715−/**
716− * v4l2_jpeg_parse_frame_header - parse frame header
717− * @buf: address of the frame header, after the SOF0 marker
718− * @len: length of the frame header
719− * @frame_header: returns the parsed frame header
720− *
721− * Returns 0 or negative error if parsing failed.
722− */
723−int v4l2_jpeg_parse_frame_header(void *buf, size_t len,
724− struct v4l2_jpeg_frame_header *frame_header)
725−{
726− struct jpeg_stream stream;
727−
728− stream.curr = buf;
729− stream.end = stream.curr + len;
730− return jpeg_parse_frame_header(&stream, SOF0, frame_header);
731−}
732−EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_frame_header);
733−
734−/**
735− * v4l2_jpeg_parse_scan_header - parse scan header
736− * @buf: address of the scan header, after the SOS marker
737− * @len: length of the scan header
738− * @scan_header: returns the parsed scan header
739− *
740− * Returns 0 or negative error if parsing failed.
741− */
742−int v4l2_jpeg_parse_scan_header(void *buf, size_t len,
743− struct v4l2_jpeg_scan_header *scan_header)
744−{
745− struct jpeg_stream stream;
746−
747− stream.curr = buf;
748− stream.end = stream.curr + len;
749− return jpeg_parse_scan_header(&stream, scan_header);
750−}
751−EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_scan_header);
752−
753−/**
754− * v4l2_jpeg_parse_quantization_tables - parse quantization tables segment
755− * @buf: address of the quantization table segment, after the DQT marker
756− * @len: length of the quantization table segment
757− * @precision: sample precision (P) in bits per component
758− * @q_tables: returns four references into the buffer for the
759− * four possible quantization table destinations
760− *
761− * Returns 0 or negative error if parsing failed.
762− */
763−int v4l2_jpeg_parse_quantization_tables(void *buf, size_t len, u8 precision,
764− struct v4l2_jpeg_reference *q_tables)
765−{
766− struct jpeg_stream stream;
767−
768− stream.curr = buf;
769− stream.end = stream.curr + len;
770− return jpeg_parse_quantization_tables(&stream, precision, q_tables);
771−}
772−EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_quantization_tables);
773−
774−/**
775− * v4l2_jpeg_parse_huffman_tables - parse huffman tables segment
776− * @buf: address of the Huffman table segment, after the DHT marker
777− * @len: length of the Huffman table segment
778− * @huffman_tables: returns four references into the buffer for the
779− * four possible Huffman table destinations, in
780− * the order DC0, DC1, AC0, AC1
781− *
782− * Returns 0 or negative error if parsing failed.
783− */
784−int v4l2_jpeg_parse_huffman_tables(void *buf, size_t len,
785− struct v4l2_jpeg_reference *huffman_tables)
786−{
787− struct jpeg_stream stream;
788−
789− stream.curr = buf;
790− stream.end = stream.curr + len;
791− return jpeg_parse_huffman_tables(&stream, huffman_tables);
792−}
793−EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_huffman_tables);
drivers/media/v4l2-core/v4l2-subdev.c+27−4
@@ -1004,6 +1004,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg, · 1003 unmodified lines
10041004 struct v4l2_subdev_route *routes =
10051005 (struct v4l2_subdev_route *)(uintptr_t)routing->routes;
10061006 struct v4l2_subdev_krouting krouting = {};
1007+ unsigned int num_active_routes = 0;
10071008 unsigned int i;
10081009
10091010 if (!v4l2_subdev_enable_streams_api)
@@ -1041,8 +1042,21 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg, · 31 unmodified lines
10411042 if (!(pads[route->source_pad].flags &
10421043 MEDIA_PAD_FL_SOURCE))
10431044 return -EINVAL;
1045+
1046+ if (route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)
1047+ num_active_routes++;
10441048 }
10451049
1050+ /*
1051+ * Drivers that implement routing need to report a frame
1052+ * descriptor accordingly, with up to one entry per route. Until
1053+ * the frame descriptors entries get allocated dynamically,
1054+ * limit the number of active routes to
1055+ * V4L2_FRAME_DESC_ENTRY_MAX.
1056+ */
1057+ if (num_active_routes > V4L2_FRAME_DESC_ENTRY_MAX)
1058+ return -E2BIG;
1059+
10461060 /*
10471061 * If the driver doesn't support setting routing, just return
10481062 * the routing table.
@@ -2219,6 +2233,9 @@ static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd, · 1170 unmodified lines
22192233 *found_streams = BIT_ULL(0);
22202234 *enabled_streams =
22212235 (sd->enabled_pads & BIT_ULL(pad)) ? BIT_ULL(0) : 0;
2236+ dev_dbg(sd->dev,
2237+ "collect_streams: sub-device \"%s\" does not support streams\n",
2238+ sd->entity.name);
22222239 return;
22232240 }
22242241
@@ -2236,6 +2253,10 @@ static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd, · 11 unmodified lines
22362253 if (cfg->enabled)
22372254 *enabled_streams |= BIT_ULL(cfg->stream);
22382255 }
2256+
2257+ dev_dbg(sd->dev,
2258+ "collect_streams: \"%s\":%u: found %#llx enabled %#llx\n",
2259+ sd->entity.name, pad, *found_streams, *enabled_streams);
22392260 }
22402261
22412262 static void v4l2_subdev_set_streams_enabled(struct v4l2_subdev *sd,
@@ -2271,6 +2292,9 @@ int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad, · 29 unmodified lines
22712292 bool use_s_stream;
22722293 int ret;
22732294
2295+ dev_dbg(dev, "enable streams \"%s\":%u/%#llx\n", sd->entity.name, pad,
2296+ streams_mask);
2297+
22742298 /* A few basic sanity checks first. */
22752299 if (pad >= sd->entity.num_pads)
22762300 return -EINVAL;
@@ -2318,8 +2342,6 @@ int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad, · 41 unmodified lines
23182342 goto done;
23192343 }
23202344
2321− dev_dbg(dev, "enable streams %u:%#llx\n", pad, streams_mask);
2322−
23232345 already_streaming = v4l2_subdev_is_streaming(sd);
23242346
23252347 if (!use_s_stream) {
@@ -2371,6 +2393,9 @@ int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad, · 45 unmodified lines
23712393 bool use_s_stream;
23722394 int ret;
23732395
2396+ dev_dbg(dev, "disable streams \"%s\":%u/%#llx\n", sd->entity.name, pad,
2397+ streams_mask);
2398+
23742399 /* A few basic sanity checks first. */
23752400 if (pad >= sd->entity.num_pads)
23762401 return -EINVAL;
@@ -2418,8 +2443,6 @@ int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad, · 41 unmodified lines
24182443 goto done;
24192444 }
24202445
2421− dev_dbg(dev, "disable streams %u:%#llx\n", pad, streams_mask);
2422−
24232446 if (!use_s_stream) {
24242447 /* Call the .disable_streams() operation. */
24252448 ret = v4l2_subdev_call(sd, pad, disable_streams, state, pad,
drivers/platform/x86/intel/int3472/tps68470_board_data.c+128−0
@@ -129,6 +129,109 @@ static const struct tps68470_regulator_platform_data surface_go_tps68470_pdata = · 128 unmodified lines
129129 },
130130 };
131131
132+/* Settings for Dell 7212 Tablet */
133+
134+static struct regulator_consumer_supply int3479_vsio_consumer_supplies[] = {
135+ REGULATOR_SUPPLY("avdd", "i2c-INT3479:00"),
136+};
137+
138+static struct regulator_consumer_supply int3479_aux1_consumer_supplies[] = {
139+ REGULATOR_SUPPLY("dvdd", "i2c-INT3479:00"),
140+};
141+
142+static struct regulator_consumer_supply int3479_aux2_consumer_supplies[] = {
143+ REGULATOR_SUPPLY("dovdd", "i2c-INT3479:00"),
144+};
145+
146+static const struct regulator_init_data dell_7212_tps68470_core_reg_init_data = {
147+ .constraints = {
148+ .min_uV = 1200000,
149+ .max_uV = 1200000,
150+ .apply_uV = 1,
151+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
152+ },
153+ .num_consumer_supplies = 0,
154+ .consumer_supplies = NULL,
155+};
156+
157+static const struct regulator_init_data dell_7212_tps68470_ana_reg_init_data = {
158+ .constraints = {
159+ .min_uV = 2815200,
160+ .max_uV = 2815200,
161+ .apply_uV = 1,
162+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
163+ },
164+ .num_consumer_supplies = 0,
165+ .consumer_supplies = NULL,
166+};
167+
168+static const struct regulator_init_data dell_7212_tps68470_vcm_reg_init_data = {
169+ .constraints = {
170+ .min_uV = 2815200,
171+ .max_uV = 2815200,
172+ .apply_uV = 1,
173+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
174+ },
175+ .num_consumer_supplies = 0,
176+ .consumer_supplies = NULL,
177+};
178+
179+static const struct regulator_init_data dell_7212_tps68470_vio_reg_init_data = {
180+ .constraints = {
181+ .min_uV = 1800600,
182+ .max_uV = 1800600,
183+ .apply_uV = 1,
184+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
185+ },
186+ .num_consumer_supplies = 0,
187+ .consumer_supplies = NULL,
188+};
189+
190+static const struct regulator_init_data dell_7212_tps68470_vsio_reg_init_data = {
191+ .constraints = {
192+ .min_uV = 1800600,
193+ .max_uV = 1800600,
194+ .apply_uV = 1,
195+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
196+ },
197+ .num_consumer_supplies = ARRAY_SIZE(int3479_vsio_consumer_supplies),
198+ .consumer_supplies = int3479_vsio_consumer_supplies,
199+};
200+
201+static const struct regulator_init_data dell_7212_tps68470_aux1_reg_init_data = {
202+ .constraints = {
203+ .min_uV = 1213200,
204+ .max_uV = 1213200,
205+ .apply_uV = 1,
206+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
207+ },
208+ .num_consumer_supplies = ARRAY_SIZE(int3479_aux1_consumer_supplies),
209+ .consumer_supplies = int3479_aux1_consumer_supplies,
210+};
211+
212+static const struct regulator_init_data dell_7212_tps68470_aux2_reg_init_data = {
213+ .constraints = {
214+ .min_uV = 1800600,
215+ .max_uV = 1800600,
216+ .apply_uV = 1,
217+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
218+ },
219+ .num_consumer_supplies = ARRAY_SIZE(int3479_aux2_consumer_supplies),
220+ .consumer_supplies = int3479_aux2_consumer_supplies,
221+};
222+
223+static const struct tps68470_regulator_platform_data dell_7212_tps68470_pdata = {
224+ .reg_init_data = {
225+ [TPS68470_CORE] = &dell_7212_tps68470_core_reg_init_data,
226+ [TPS68470_ANA] = &dell_7212_tps68470_ana_reg_init_data,
227+ [TPS68470_VCM] = &dell_7212_tps68470_vcm_reg_init_data,
228+ [TPS68470_VIO] = &dell_7212_tps68470_vio_reg_init_data,
229+ [TPS68470_VSIO] = &dell_7212_tps68470_vsio_reg_init_data,
230+ [TPS68470_AUX1] = &dell_7212_tps68470_aux1_reg_init_data,
231+ [TPS68470_AUX2] = &dell_7212_tps68470_aux2_reg_init_data,
232+ },
233+};
234+
132235 static struct gpiod_lookup_table surface_go_int347a_gpios = {
133236 .dev_id = "i2c-INT347A:00",
134237 .table = {
@@ -146,6 +249,15 @@ static struct gpiod_lookup_table surface_go_int347e_gpios = { · 11 unmodified lines
146249 }
147250 };
148251
252+static struct gpiod_lookup_table dell_7212_int3479_gpios = {
253+ .dev_id = "i2c-INT3479:00",
254+ .table = {
255+ GPIO_LOOKUP("tps68470-gpio", 3, "reset", GPIO_ACTIVE_LOW),
256+ GPIO_LOOKUP("tps68470-gpio", 4, "powerdown", GPIO_ACTIVE_LOW),
257+ { }
258+ }
259+};
260+
149261 static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {
150262 .dev_name = "i2c-INT3472:05",
151263 .tps68470_regulator_pdata = &surface_go_tps68470_pdata,
@@ -166,6 +278,15 @@ static const struct int3472_tps68470_board_data surface_go3_tps68470_board_data · 14 unmodified lines
166278 },
167279 };
168280
281+static const struct int3472_tps68470_board_data dell_7212_tps68470_board_data = {
282+ .dev_name = "i2c-INT3472:05",
283+ .tps68470_regulator_pdata = &dell_7212_tps68470_pdata,
284+ .n_gpiod_lookups = 1,
285+ .tps68470_gpio_lookup_tables = {
286+ &dell_7212_int3479_gpios,
287+ },
288+};
289+
169290 static const struct dmi_system_id int3472_tps68470_board_data_table[] = {
170291 {
171292 .matches = {
@@ -188,6 +309,13 @@ static const struct dmi_system_id int3472_tps68470_board_data_table[] = { · 16 unmodified lines
188309 },
189310 .driver_data = (void *)&surface_go3_tps68470_board_data,
190311 },
312+ {
313+ .matches = {
314+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
315+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 7212 Rugged Extreme Tablet"),
316+ },
317+ .driver_data = (void *)&dell_7212_tps68470_board_data,
318+ },
191319 { }
192320 };
193321
drivers/staging/media/Kconfig+2−2
@@ -28,12 +28,12 @@ source "drivers/staging/media/imx/Kconfig" · 27 unmodified lines
2828
2929 source "drivers/staging/media/ipu3/Kconfig"
3030
31+source "drivers/staging/media/ipu7/Kconfig"
32+
3133 source "drivers/staging/media/max96712/Kconfig"
3234
3335 source "drivers/staging/media/meson/vdec/Kconfig"
3436
35−source "drivers/staging/media/rkvdec/Kconfig"
36−
3737 source "drivers/staging/media/starfive/Kconfig"
3838
3939 source "drivers/staging/media/sunxi/Kconfig"
drivers/staging/media/Makefile+1−1
@@ -4,9 +4,9 @@ obj-$(CONFIG_INTEL_ATOMISP) += atomisp/ · 3 unmodified lines
44 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
55 obj-$(CONFIG_VIDEO_MAX96712) += max96712/
66 obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
7−obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/
87 obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive/
98 obj-$(CONFIG_VIDEO_SUNXI) += sunxi/
109 obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/
1110 obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
11+obj-$(CONFIG_VIDEO_INTEL_IPU7) += ipu7/
1212 obj-$(CONFIG_DVB_AV7110) += av7110/
drivers/staging/media/atomisp/Kconfig+1−0
@@ -12,6 +12,7 @@ menuconfig INTEL_ATOMISP · 11 unmodified lines
1212 config VIDEO_ATOMISP
1313 tristate "Intel Atom Image Signal Processor Driver"
1414 depends on VIDEO_DEV && INTEL_ATOMISP
15+ depends on INTEL_SKL_INT3472
1516 depends on IPU_BRIDGE
1617 depends on MEDIA_PCI_SUPPORT
1718 depends on PMIC_OPREGION
drivers/staging/media/atomisp/Makefile+0−1
@@ -17,7 +17,6 @@ atomisp-objs += \ · 16 unmodified lines
1717 pci/atomisp_compat_css20.o \
1818 pci/atomisp_csi2.o \
1919 pci/atomisp_csi2_bridge.o \
20− pci/atomisp_drvfs.o \
2120 pci/atomisp_fops.o \
2221 pci/atomisp_ioctl.o \
2322 pci/atomisp_subdev.o \
drivers/staging/media/atomisp/TODO+0−2
@@ -7,8 +7,6 @@ TODO · 6 unmodified lines
77
88 * Remove/disable custom v4l2-ctrls
99
10−* Remove custom sysfs files created by atomisp_drvfs.c
11−
1210 * Remove unnecessary/unwanted module parameters
1311
1412 * Remove abuse of priv field in various v4l2 userspace API structs
drivers/staging/media/atomisp/i2c/Kconfig+1−0
@@ -31,6 +31,7 @@ config VIDEO_ATOMISP_GC0310 · 30 unmodified lines
3131 tristate "GC0310 sensor support"
3232 depends on ACPI
3333 depends on I2C && VIDEO_DEV
34+ select V4L2_CCI_I2C
3435 help
3536 This is a Video4Linux2 sensor-level driver for the Galaxycore
3637 GC0310 0.3MP sensor.
drivers/staging/media/atomisp/i2c/atomisp-gc0310.c+341−270
@@ -3,7 +3,7 @@ · 2 unmodified lines
33 * Support for GalaxyCore GC0310 VGA camera sensor.
44 *
55 * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
6− * Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com>
6+ * Copyright (c) 2023-2025 Hans de Goede <hansg@kernel.org>
77 */
88
99 #include <linux/delay.h>
@@ -13,77 +13,92 @@ · 3 unmodified lines
1313 #include <linux/kernel.h>
1414 #include <linux/module.h>
1515 #include <linux/pm_runtime.h>
16+#include <linux/regmap.h>
1617 #include <linux/string.h>
1718 #include <linux/types.h>
1819
20+#include <media/v4l2-cci.h>
1921 #include <media/v4l2-ctrls.h>
2022 #include <media/v4l2-device.h>
23+#include <media/v4l2-fwnode.h>
2124
2225 #define GC0310_NATIVE_WIDTH 656
2326 #define GC0310_NATIVE_HEIGHT 496
2427
28+/*
29+ * The actual PLL output rate is unknown, the datasheet
30+ * says that the formula for the frame-time in pixels is:
31+ * rowtime = win-width + hblank + sh-delay + 4
32+ * frametime = rowtime * (win-height + vblank)
33+ * Filling this in and multiplying by 30 fps gives:
34+ * pixelrate = (660 + 178 + 42 + 4) * (498 + 27) * 30 = 13923000
35+ */
36+#define GC0310_PIXELRATE 13923000
37+/* single lane, bus-format is 8 bpp, CSI-2 is double data rate */
38+#define GC0310_LINK_FREQ (GC0310_PIXELRATE * 8 / 2)
39+#define GC0310_MCLK_FREQ 19200000
2540 #define GC0310_FPS 30
2641 #define GC0310_SKIP_FRAMES 3
2742
28−#define GC0310_FOCAL_LENGTH_NUM 278 /* 2.78mm */
29−
3043 #define GC0310_ID 0xa310
3144
32−#define GC0310_RESET_RELATED 0xFE
45+#define GC0310_RESET_RELATED_REG CCI_REG8(0xfe)
3346 #define GC0310_REGISTER_PAGE_0 0x0
3447 #define GC0310_REGISTER_PAGE_3 0x3
3548
3649 /*
3750 * GC0310 System control registers
3851 */
39−#define GC0310_SW_STREAM 0x10
40−
41−#define GC0310_SC_CMMN_CHIP_ID_H 0xf0
42−#define GC0310_SC_CMMN_CHIP_ID_L 0xf1
43−
44−#define GC0310_AEC_PK_EXPO_H 0x03
45−#define GC0310_AEC_PK_EXPO_L 0x04
46−#define GC0310_AGC_ADJ 0x48
47−#define GC0310_DGC_ADJ 0x71
48−#define GC0310_GROUP_ACCESS 0x3208
49−
50−#define GC0310_H_CROP_START_H 0x09
51−#define GC0310_H_CROP_START_L 0x0A
52−#define GC0310_V_CROP_START_H 0x0B
53−#define GC0310_V_CROP_START_L 0x0C
54−#define GC0310_H_OUTSIZE_H 0x0F
55−#define GC0310_H_OUTSIZE_L 0x10
56−#define GC0310_V_OUTSIZE_H 0x0D
57−#define GC0310_V_OUTSIZE_L 0x0E
58−#define GC0310_H_BLANKING_H 0x05
59−#define GC0310_H_BLANKING_L 0x06
60−#define GC0310_V_BLANKING_H 0x07
61−#define GC0310_V_BLANKING_L 0x08
62−#define GC0310_SH_DELAY 0x11
52+#define GC0310_SW_STREAM_REG CCI_REG8(0x10)
6353
6454 #define GC0310_START_STREAMING 0x94 /* 8-bit enable */
6555 #define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */
6656
57+#define GC0310_SC_CMMN_CHIP_ID_REG CCI_REG16(0xf0)
58+
59+#define GC0310_AEC_PK_EXPO_REG CCI_REG16(0x03)
60+#define GC0310_AGC_ADJ_REG CCI_REG8(0x48)
61+#define GC0310_DGC_ADJ_REG CCI_REG8(0x71)
62+
63+#define GC0310_H_CROP_START_REG CCI_REG16(0x09)
64+#define GC0310_V_CROP_START_REG CCI_REG16(0x0b)
65+#define GC0310_H_OUTSIZE_REG CCI_REG16(0x0f)
66+#define GC0310_V_OUTSIZE_REG CCI_REG16(0x0d)
67+
68+#define GC0310_H_BLANKING_REG CCI_REG16(0x05)
69+/* Hblank-register + sh-delay + H-crop + 4 (from hw) */
70+#define GC0310_H_BLANK_DEFAULT (178 + 42 + 4 + 4)
71+
72+#define GC0310_V_BLANKING_REG CCI_REG16(0x07)
73+/* Vblank needs an offset compensate for the small V-crop done */
74+#define GC0310_V_BLANK_OFFSET 2
75+/* Vsync start time + 1 row vsync + vsync end time + offset */
76+#define GC0310_V_BLANK_MIN (9 + 1 + 4 + GC0310_V_BLANK_OFFSET)
77+#define GC0310_V_BLANK_DEFAULT (27 + GC0310_V_BLANK_OFFSET)
78+#define GC0310_V_BLANK_MAX (4095 - GC0310_NATIVE_HEIGHT)
79+
80+#define GC0310_SH_DELAY_REG CCI_REG8(0x11)
81+#define GC0310_VS_START_TIME_REG CCI_REG8(0x12)
82+#define GC0310_VS_END_TIME_REG CCI_REG8(0x13)
83+
6784 #define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd)
6885
6986 struct gc0310_device {
7087 struct v4l2_subdev sd;
7188 struct media_pad pad;
72− /* Protect against concurrent changes to controls */
73− struct mutex input_lock;
74− bool is_streaming;
7589
90+ struct regmap *regmap;
7691 struct gpio_desc *reset;
7792 struct gpio_desc *powerdown;
7893
79− struct gc0310_mode {
80− struct v4l2_mbus_framefmt fmt;
81− } mode;
82−
8394 struct gc0310_ctrls {
8495 struct v4l2_ctrl_handler handler;
8596 struct v4l2_ctrl *exposure;
8697 struct v4l2_ctrl *gain;
98+ struct v4l2_ctrl *link_freq;
99+ struct v4l2_ctrl *pixel_rate;
100+ struct v4l2_ctrl *vblank;
101+ struct v4l2_ctrl *hblank;
87102 } ctrls;
88103 };
89104
@@ -92,7 +107,7 @@ struct gc0310_reg { · 2 unmodified lines
92107 u8 val;
93108 };
94109
95−static const struct gc0310_reg gc0310_reset_register[] = {
110+static const struct reg_sequence gc0310_reset_register[] = {
96111 /* System registers */
97112 { 0xfe, 0xf0 },
98113 { 0xfe, 0xf0 },
@@ -142,8 +157,7 @@ static const struct gc0310_reg gc0310_reset_register[] = { · 43 unmodified lines
142157 { 0x04, 0xc0 }, /* 0xe8 //58 */
143158 { 0x05, 0x00 },
144159 { 0x06, 0xb2 }, /* 0x0a //HB */
145− { 0x07, 0x00 },
146− { 0x08, 0x0c }, /* 0x89 //VB */
160+ /* Vblank (reg 0x07 + 0x08) gets set by the vblank ctrl */
147161 { 0x09, 0x00 }, /* row start */
148162 { 0x0a, 0x00 },
149163 { 0x0b, 0x00 }, /* col start */
@@ -235,7 +249,7 @@ static const struct gc0310_reg gc0310_reset_register[] = { · 85 unmodified lines
235249 { 0xfe, 0x00 },
236250 };
237251
238−static const struct gc0310_reg gc0310_VGA_30fps[] = {
252+static const struct reg_sequence gc0310_VGA_30fps[] = {
239253 { 0xfe, 0x00 },
240254 { 0x0d, 0x01 }, /* height */
241255 { 0x0e, 0xf2 }, /* 0xf7 //height */
@@ -259,41 +273,14 @@ static const struct gc0310_reg gc0310_VGA_30fps[] = { · 17 unmodified lines
259273 { 0xfe, 0x00 },
260274 };
261275
262−/*
263− * gc0310_write_reg_array - Initializes a list of GC0310 registers
264− * @client: i2c driver client structure
265− * @reglist: list of registers to be written
266− * @count: number of register, value pairs in the list
267− */
268−static int gc0310_write_reg_array(struct i2c_client *client,
269− const struct gc0310_reg *reglist, int count)
270−{
271− int i, err;
272−
273− for (i = 0; i < count; i++) {
274− err = i2c_smbus_write_byte_data(client, reglist[i].reg, reglist[i].val);
275− if (err) {
276− dev_err(&client->dev, "write error: wrote 0x%x to offset 0x%x error %d",
277− reglist[i].val, reglist[i].reg, err);
278− return err;
279− }
280− }
281−
282− return 0;
283−}
284−
285−static int gc0310_exposure_set(struct gc0310_device *dev, u32 exp)
286−{
287− struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
288−
289− return i2c_smbus_write_word_swapped(client, GC0310_AEC_PK_EXPO_H, exp);
290−}
276+static const s64 link_freq_menu_items[] = {
277+ GC0310_LINK_FREQ,
278+};
291279
292−static int gc0310_gain_set(struct gc0310_device *dev, u32 gain)
280+static int gc0310_gain_set(struct gc0310_device *sensor, u32 gain)
293281 {
294− struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
295282 u8 again, dgain;
296− int ret;
283+ int ret = 0;
297284
298285 /* Taken from original driver, this never sets dgain lower then 32? */
299286
@@ -308,36 +295,55 @@ static int gc0310_gain_set(struct gc0310_device *dev, u32 gain) · 8 unmodified lines
308295 dgain = gain / 2;
309296 }
310297
311− ret = i2c_smbus_write_byte_data(client, GC0310_AGC_ADJ, again);
312− if (ret)
313− return ret;
298+ cci_write(sensor->regmap, GC0310_AGC_ADJ_REG, again, &ret);
299+ cci_write(sensor->regmap, GC0310_DGC_ADJ_REG, dgain, &ret);
300+ return ret;
301+}
302+
303+static int gc0310_exposure_update_range(struct gc0310_device *sensor)
304+{
305+ int exp_max = GC0310_NATIVE_HEIGHT + sensor->ctrls.vblank->val;
314306
315− return i2c_smbus_write_byte_data(client, GC0310_DGC_ADJ, dgain);
307+ return __v4l2_ctrl_modify_range(sensor->ctrls.exposure, 0, exp_max,
308+ 1, exp_max);
316309 }
317310
318311 static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl)
319312 {
320− struct gc0310_device *dev =
313+ struct gc0310_device *sensor =
321314 container_of(ctrl->handler, struct gc0310_device, ctrls.handler);
322315 int ret;
323316
317+ /* Update exposure range on vblank changes */
318+ if (ctrl->id == V4L2_CID_VBLANK) {
319+ ret = gc0310_exposure_update_range(sensor);
320+ if (ret)
321+ return ret;
322+ }
323+
324324 /* Only apply changes to the controls if the device is powered up */
325− if (!pm_runtime_get_if_in_use(dev->sd.dev))
325+ if (!pm_runtime_get_if_in_use(sensor->sd.dev))
326326 return 0;
327327
328328 switch (ctrl->id) {
329329 case V4L2_CID_EXPOSURE:
330− ret = gc0310_exposure_set(dev, ctrl->val);
330+ ret = cci_write(sensor->regmap, GC0310_AEC_PK_EXPO_REG,
331+ ctrl->val, NULL);
331332 break;
332− case V4L2_CID_GAIN:
333− ret = gc0310_gain_set(dev, ctrl->val);
333+ case V4L2_CID_ANALOGUE_GAIN:
334+ ret = gc0310_gain_set(sensor, ctrl->val);
335+ break;
336+ case V4L2_CID_VBLANK:
337+ ret = cci_write(sensor->regmap, GC0310_V_BLANKING_REG,
338+ ctrl->val - GC0310_V_BLANK_OFFSET,
339+ NULL);
334340 break;
335341 default:
336342 ret = -EINVAL;
337343 break;
338344 }
339345
340− pm_runtime_put(dev->sd.dev);
346+ pm_runtime_put(sensor->sd.dev);
341347 return ret;
342348 }
343349
@@ -345,17 +351,6 @@ static const struct v4l2_ctrl_ops ctrl_ops = { · 1 unmodified line
345351 .s_ctrl = gc0310_s_ctrl,
346352 };
347353
348−static struct v4l2_mbus_framefmt *
349−gc0310_get_pad_format(struct gc0310_device *dev,
350− struct v4l2_subdev_state *state,
351− unsigned int pad, enum v4l2_subdev_format_whence which)
352−{
353− if (which == V4L2_SUBDEV_FORMAT_TRY)
354− return v4l2_subdev_state_get_format(state, pad);
355−
356− return &dev->mode.fmt;
357−}
358−
359354 /* The GC0310 currently only supports 1 fixed fmt */
360355 static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt)
361356 {
@@ -366,54 +361,72 @@ static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt) · 4 unmodified lines
366361 fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
367362 }
368363
369−static int gc0310_set_fmt(struct v4l2_subdev *sd,
370− struct v4l2_subdev_state *sd_state,
371− struct v4l2_subdev_format *format)
364+static int gc0310_get_selection(struct v4l2_subdev *sd,
365+ struct v4l2_subdev_state *state,
366+ struct v4l2_subdev_selection *sel)
372367 {
373− struct gc0310_device *dev = to_gc0310_sensor(sd);
374− struct v4l2_mbus_framefmt *fmt;
368+ /* Only the single fixed 656x496 mode is supported, without croping */
369+ switch (sel->target) {
370+ case V4L2_SEL_TGT_CROP:
371+ case V4L2_SEL_TGT_CROP_BOUNDS:
372+ case V4L2_SEL_TGT_CROP_DEFAULT:
373+ case V4L2_SEL_TGT_NATIVE_SIZE:
374+ sel->r.top = 0;
375+ sel->r.left = 0;
376+ sel->r.width = GC0310_NATIVE_WIDTH;
377+ sel->r.height = GC0310_NATIVE_HEIGHT;
378+ break;
379+ default:
380+ return -EINVAL;
381+ }
382+
383+ return 0;
384+}
375385
376− fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
377− gc0310_fill_format(fmt);
386+static int gc0310_power_off(struct device *dev)
387+{
388+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
389+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
378390
379− format->format = *fmt;
391+ gpiod_set_value_cansleep(sensor->powerdown, 1);
392+ gpiod_set_value_cansleep(sensor->reset, 1);
380393 return 0;
381394 }
382395
383−static int gc0310_get_fmt(struct v4l2_subdev *sd,
384− struct v4l2_subdev_state *sd_state,
385− struct v4l2_subdev_format *format)
396+static int gc0310_power_on(struct device *dev)
386397 {
387− struct gc0310_device *dev = to_gc0310_sensor(sd);
388− struct v4l2_mbus_framefmt *fmt;
398+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
399+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
400+
401+ fsleep(10 * USEC_PER_MSEC);
402+ gpiod_set_value_cansleep(sensor->reset, 0);
403+ fsleep(10 * USEC_PER_MSEC);
404+ gpiod_set_value_cansleep(sensor->powerdown, 0);
405+ fsleep(10 * USEC_PER_MSEC);
389406
390− fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
391− format->format = *fmt;
392407 return 0;
393408 }
394409
395−static int gc0310_detect(struct i2c_client *client)
410+static int gc0310_detect(struct gc0310_device *sensor)
396411 {
397− struct i2c_adapter *adapter = client->adapter;
412+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
413+ u64 val;
398414 int ret;
399415
400− if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
416+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
401417 return -ENODEV;
402418
403− ret = pm_runtime_get_sync(&client->dev);
404− if (ret >= 0)
405− ret = i2c_smbus_read_word_swapped(client, GC0310_SC_CMMN_CHIP_ID_H);
406− pm_runtime_put(&client->dev);
419+ ret = cci_read(sensor->regmap, GC0310_SC_CMMN_CHIP_ID_REG, &val, NULL);
407420 if (ret < 0) {
408421 dev_err(&client->dev, "read sensor_id failed: %d\n", ret);
409422 return -ENODEV;
410423 }
411424
412− dev_dbg(&client->dev, "sensor ID = 0x%x\n", ret);
425+ dev_dbg(&client->dev, "sensor ID = 0x%llx\n", val);
413426
414− if (ret != GC0310_ID) {
415− dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n",
416− ret, GC0310_ID);
427+ if (val != GC0310_ID) {
428+ dev_err(&client->dev, "sensor ID error, read id = 0x%llx, target id = 0x%x\n",
429+ val, GC0310_ID);
417430 return -ENODEV;
418431 }
419432
@@ -422,85 +435,67 @@ static int gc0310_detect(struct i2c_client *client) · 2 unmodified lines
422435 return 0;
423436 }
424437
425−static int gc0310_s_stream(struct v4l2_subdev *sd, int enable)
438+static int gc0310_enable_streams(struct v4l2_subdev *sd,
439+ struct v4l2_subdev_state *state,
440+ u32 pad, u64 streams_mask)
426441 {
427− struct gc0310_device *dev = to_gc0310_sensor(sd);
442+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
428443 struct i2c_client *client = v4l2_get_subdevdata(sd);
429− int ret = 0;
430−
431− dev_dbg(&client->dev, "%s S enable=%d\n", __func__, enable);
432− mutex_lock(&dev->input_lock);
433−
434− if (enable) {
435− ret = pm_runtime_get_sync(&client->dev);
436− if (ret < 0)
437− goto error_power_down;
438−
439− msleep(100);
440−
441− ret = gc0310_write_reg_array(client, gc0310_reset_register,
442− ARRAY_SIZE(gc0310_reset_register));
443− if (ret)
444− goto error_power_down;
445−
446− ret = gc0310_write_reg_array(client, gc0310_VGA_30fps,
447− ARRAY_SIZE(gc0310_VGA_30fps));
448− if (ret)
449− goto error_power_down;
450−
451− /* restore value of all ctrls */
452− ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
453− if (ret)
454− goto error_power_down;
455−
456− /* enable per frame MIPI and sensor ctrl reset */
457− ret = i2c_smbus_write_byte_data(client, 0xFE, 0x30);
458− if (ret)
459− goto error_power_down;
460− }
444+ int ret;
461445
462− ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_3);
446+ ret = pm_runtime_resume_and_get(&client->dev);
463447 if (ret)
464− goto error_power_down;
448+ return ret;
465449
466− ret = i2c_smbus_write_byte_data(client, GC0310_SW_STREAM,
467− enable ? GC0310_START_STREAMING : GC0310_STOP_STREAMING);
450+ ret = regmap_multi_reg_write(sensor->regmap,
451+ gc0310_reset_register,
452+ ARRAY_SIZE(gc0310_reset_register));
468453 if (ret)
469454 goto error_power_down;
470455
471− ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_0);
456+ ret = regmap_multi_reg_write(sensor->regmap,
457+ gc0310_VGA_30fps,
458+ ARRAY_SIZE(gc0310_VGA_30fps));
472459 if (ret)
473460 goto error_power_down;
474461
475− if (!enable)
476− pm_runtime_put(&client->dev);
462+ /* restore value of all ctrls */
463+ ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
477464
478− dev->is_streaming = enable;
479− mutex_unlock(&dev->input_lock);
480− return 0;
465+ /* enable per frame MIPI and sensor ctrl reset */
466+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, 0x30, &ret);
467+
468+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
469+ GC0310_REGISTER_PAGE_3, &ret);
470+ cci_write(sensor->regmap, GC0310_SW_STREAM_REG,
471+ GC0310_START_STREAMING, &ret);
472+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
473+ GC0310_REGISTER_PAGE_0, &ret);
481474
482475 error_power_down:
483− pm_runtime_put(&client->dev);
484− dev->is_streaming = false;
485− mutex_unlock(&dev->input_lock);
476+ if (ret)
477+ pm_runtime_put(&client->dev);
478+
486479 return ret;
487480 }
488481
489−static int gc0310_get_frame_interval(struct v4l2_subdev *sd,
490− struct v4l2_subdev_state *sd_state,
491− struct v4l2_subdev_frame_interval *interval)
482+static int gc0310_disable_streams(struct v4l2_subdev *sd,
483+ struct v4l2_subdev_state *state,
484+ u32 pad, u64 streams_mask)
492485 {
493− /*
494− * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
495− * subdev active state API.
496− */
497− if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
498− return -EINVAL;
486+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
487+ struct i2c_client *client = v4l2_get_subdevdata(sd);
488+ int ret = 0;
499489
500− interval->interval.numerator = 1;
501− interval->interval.denominator = GC0310_FPS;
490+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
491+ GC0310_REGISTER_PAGE_3, &ret);
492+ cci_write(sensor->regmap, GC0310_SW_STREAM_REG,
493+ GC0310_STOP_STREAMING, &ret);
494+ cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
495+ GC0310_REGISTER_PAGE_0, &ret);
502496
503− return 0;
497+ pm_runtime_put(&client->dev);
498+ return ret;
504499 }
505500
506501 static int gc0310_enum_mbus_code(struct v4l2_subdev *sd,
@@ -531,164 +526,239 @@ static int gc0310_enum_frame_size(struct v4l2_subdev *sd, · 24 unmodified lines
531526 return 0;
532527 }
533528
534−static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
535−{
536− *frames = GC0310_SKIP_FRAMES;
537− return 0;
538−}
539−
540−static const struct v4l2_subdev_sensor_ops gc0310_sensor_ops = {
541− .g_skip_frames = gc0310_g_skip_frames,
542−};
543−
544529 static const struct v4l2_subdev_video_ops gc0310_video_ops = {
545− .s_stream = gc0310_s_stream,
530+ .s_stream = v4l2_subdev_s_stream_helper,
546531 };
547532
548533 static const struct v4l2_subdev_pad_ops gc0310_pad_ops = {
549534 .enum_mbus_code = gc0310_enum_mbus_code,
550535 .enum_frame_size = gc0310_enum_frame_size,
551− .get_fmt = gc0310_get_fmt,
552− .set_fmt = gc0310_set_fmt,
553− .get_frame_interval = gc0310_get_frame_interval,
536+ .get_fmt = v4l2_subdev_get_fmt,
537+ .set_fmt = v4l2_subdev_get_fmt, /* Only 1 fixed mode supported */
538+ .get_selection = gc0310_get_selection,
539+ .set_selection = gc0310_get_selection,
540+ .enable_streams = gc0310_enable_streams,
541+ .disable_streams = gc0310_disable_streams,
554542 };
555543
556544 static const struct v4l2_subdev_ops gc0310_ops = {
557545 .video = &gc0310_video_ops,
558546 .pad = &gc0310_pad_ops,
559− .sensor = &gc0310_sensor_ops,
560547 };
561548
562−static int gc0310_init_controls(struct gc0310_device *dev)
549+static int gc0310_init_state(struct v4l2_subdev *sd,
550+ struct v4l2_subdev_state *sd_state)
563551 {
564− struct v4l2_ctrl_handler *hdl = &dev->ctrls.handler;
552+ gc0310_fill_format(v4l2_subdev_state_get_format(sd_state, 0));
553+ return 0;
554+}
565555
566− v4l2_ctrl_handler_init(hdl, 2);
556+static const struct v4l2_subdev_internal_ops gc0310_internal_ops = {
557+ .init_state = gc0310_init_state,
558+};
559+
560+static int gc0310_init_controls(struct gc0310_device *sensor)
561+{
562+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
563+ struct v4l2_ctrl_handler *hdl = &sensor->ctrls.handler;
564+ struct v4l2_fwnode_device_properties props;
565+ int exp_max, ret;
566+
567+ v4l2_ctrl_handler_init(hdl, 8);
567568
568569 /* Use the same lock for controls as for everything else */
569− hdl->lock = &dev->input_lock;
570− dev->sd.ctrl_handler = hdl;
570+ sensor->sd.ctrl_handler = hdl;
571571
572− dev->ctrls.exposure =
573− v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, 4095, 1, 1023);
572+ exp_max = GC0310_NATIVE_HEIGHT + GC0310_V_BLANK_DEFAULT;
573+ sensor->ctrls.exposure =
574+ v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0,
575+ exp_max, 1, exp_max);
574576
575577 /* 32 steps at base gain 1 + 64 half steps at base gain 2 */
576− dev->ctrls.gain =
577− v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_GAIN, 0, 95, 1, 31);
578+ sensor->ctrls.gain =
579+ v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 0, 95, 1, 31);
580+
581+ sensor->ctrls.link_freq =
582+ v4l2_ctrl_new_int_menu(hdl, NULL, V4L2_CID_LINK_FREQ,
583+ 0, 0, link_freq_menu_items);
584+ sensor->ctrls.pixel_rate =
585+ v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_PIXEL_RATE, 0,
586+ GC0310_PIXELRATE, 1, GC0310_PIXELRATE);
587+
588+ sensor->ctrls.vblank =
589+ v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_VBLANK,
590+ GC0310_V_BLANK_MIN,
591+ GC0310_V_BLANK_MAX, 1,
592+ GC0310_V_BLANK_DEFAULT);
593+
594+ sensor->ctrls.hblank =
595+ v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_HBLANK,
596+ GC0310_H_BLANK_DEFAULT,
597+ GC0310_H_BLANK_DEFAULT, 1,
598+ GC0310_H_BLANK_DEFAULT);
599+
600+ ret = v4l2_fwnode_device_parse(&client->dev, &props);
601+ if (ret)
602+ return ret;
603+
604+ v4l2_ctrl_new_fwnode_properties(hdl, &ctrl_ops, &props);
578605
579− return hdl->error;
606+ if (hdl->error)
607+ return hdl->error;
608+
609+ sensor->ctrls.pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
610+ sensor->ctrls.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
611+ sensor->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
612+ return 0;
580613 }
581614
582615 static void gc0310_remove(struct i2c_client *client)
583616 {
584617 struct v4l2_subdev *sd = i2c_get_clientdata(client);
585− struct gc0310_device *dev = to_gc0310_sensor(sd);
586−
587− dev_dbg(&client->dev, "gc0310_remove...\n");
618+ struct gc0310_device *sensor = to_gc0310_sensor(sd);
588619
589620 v4l2_async_unregister_subdev(sd);
590− media_entity_cleanup(&dev->sd.entity);
591− v4l2_ctrl_handler_free(&dev->ctrls.handler);
592− mutex_destroy(&dev->input_lock);
621+ v4l2_subdev_cleanup(sd);
622+ media_entity_cleanup(&sensor->sd.entity);
623+ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
593624 pm_runtime_disable(&client->dev);
625+ if (!pm_runtime_status_suspended(&client->dev)) {
626+ gc0310_power_off(&client->dev);
627+ pm_runtime_set_suspended(&client->dev);
628+ }
594629 }
595630
596−static int gc0310_probe(struct i2c_client *client)
631+static int gc0310_check_hwcfg(struct device *dev)
597632 {
633+ struct v4l2_fwnode_endpoint bus_cfg = {
634+ .bus_type = V4L2_MBUS_CSI2_DPHY,
635+ };
598636 struct fwnode_handle *ep_fwnode;
599− struct gc0310_device *dev;
637+ unsigned long link_freq_bitmap;
638+ u32 mclk;
600639 int ret;
601640
602641 /*
603642 * Sometimes the fwnode graph is initialized by the bridge driver.
604643 * Bridge drivers doing this may also add GPIO mappings, wait for this.
605644 */
606− ep_fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
645+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
607646 if (!ep_fwnode)
608− return dev_err_probe(&client->dev, -EPROBE_DEFER, "waiting for fwnode graph endpoint\n");
647+ return dev_err_probe(dev, -EPROBE_DEFER,
648+ "waiting for fwnode graph endpoint\n");
649+
650+ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
651+ &mclk);
652+ if (ret) {
653+ fwnode_handle_put(ep_fwnode);
654+ return dev_err_probe(dev, ret,
655+ "reading clock-frequency property\n");
656+ }
657+
658+ if (mclk != GC0310_MCLK_FREQ) {
659+ fwnode_handle_put(ep_fwnode);
660+ return dev_err_probe(dev, -EINVAL,
661+ "external clock %u is not supported\n",
662+ mclk);
663+ }
609664
665+ ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &bus_cfg);
610666 fwnode_handle_put(ep_fwnode);
667+ if (ret)
668+ return dev_err_probe(dev, ret, "parsing endpoint failed\n");
669+
670+ ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
671+ bus_cfg.nr_of_link_frequencies,
672+ link_freq_menu_items,
673+ ARRAY_SIZE(link_freq_menu_items),
674+ &link_freq_bitmap);
675+
676+ if (ret == 0 && bus_cfg.bus.mipi_csi2.num_data_lanes != 1)
677+ ret = dev_err_probe(dev, -EINVAL,
678+ "number of CSI2 data lanes %u is not supported\n",
679+ bus_cfg.bus.mipi_csi2.num_data_lanes);
680+
681+ v4l2_fwnode_endpoint_free(&bus_cfg);
682+ return ret;
683+}
684+
685+static int gc0310_probe(struct i2c_client *client)
686+{
687+ struct gc0310_device *sensor;
688+ int ret;
611689
612− dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);
613− if (!dev)
690+ ret = gc0310_check_hwcfg(&client->dev);
691+ if (ret)
692+ return ret;
693+
694+ sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
695+ if (!sensor)
614696 return -ENOMEM;
615697
616− dev->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
617− if (IS_ERR(dev->reset)) {
618− return dev_err_probe(&client->dev, PTR_ERR(dev->reset),
698+ sensor->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
699+ if (IS_ERR(sensor->reset)) {
700+ return dev_err_probe(&client->dev, PTR_ERR(sensor->reset),
619701 "getting reset GPIO\n");
620702 }
621703
622− dev->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);
623− if (IS_ERR(dev->powerdown)) {
624− return dev_err_probe(&client->dev, PTR_ERR(dev->powerdown),
704+ sensor->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);
705+ if (IS_ERR(sensor->powerdown)) {
706+ return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown),
625707 "getting powerdown GPIO\n");
626708 }
627709
628− mutex_init(&dev->input_lock);
629− v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops);
630− gc0310_fill_format(&dev->mode.fmt);
710+ v4l2_i2c_subdev_init(&sensor->sd, client, &gc0310_ops);
631711
632− pm_runtime_set_suspended(&client->dev);
633− pm_runtime_enable(&client->dev);
634− pm_runtime_set_autosuspend_delay(&client->dev, 1000);
635− pm_runtime_use_autosuspend(&client->dev);
712+ sensor->regmap = devm_cci_regmap_init_i2c(client, 8);
713+ if (IS_ERR(sensor->regmap))
714+ return PTR_ERR(sensor->regmap);
636715
637− ret = gc0310_detect(client);
638− if (ret) {
639− gc0310_remove(client);
640− return ret;
641− }
716+ gc0310_power_on(&client->dev);
642717
643− dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
644− dev->pad.flags = MEDIA_PAD_FL_SOURCE;
645− dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
646−
647− ret = gc0310_init_controls(dev);
648− if (ret) {
649− gc0310_remove(client);
650− return ret;
651− }
718+ pm_runtime_set_active(&client->dev);
719+ pm_runtime_get_noresume(&client->dev);
720+ pm_runtime_enable(&client->dev);
652721
653− ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
654− if (ret) {
655− gc0310_remove(client);
656− return ret;
657− }
722+ ret = gc0310_detect(sensor);
723+ if (ret)
724+ goto err_power_down;
658725
659− ret = v4l2_async_register_subdev_sensor(&dev->sd);
660− if (ret) {
661− gc0310_remove(client);
662− return ret;
663− }
726+ sensor->sd.internal_ops = &gc0310_internal_ops;
727+ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
728+ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
729+ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
664730
665− return 0;
666−}
731+ ret = gc0310_init_controls(sensor);
732+ if (ret)
733+ goto err_power_down;
667734
668−static int gc0310_suspend(struct device *dev)
669−{
670− struct v4l2_subdev *sd = dev_get_drvdata(dev);
671− struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd);
735+ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
736+ if (ret)
737+ goto err_power_down;
672738
673− gpiod_set_value_cansleep(gc0310_dev->powerdown, 1);
674− gpiod_set_value_cansleep(gc0310_dev->reset, 1);
675− return 0;
676−}
739+ sensor->sd.state_lock = sensor->ctrls.handler.lock;
740+ ret = v4l2_subdev_init_finalize(&sensor->sd);
741+ if (ret)
742+ goto err_power_down;
677743
678−static int gc0310_resume(struct device *dev)
679−{
680− struct v4l2_subdev *sd = dev_get_drvdata(dev);
681− struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd);
744+ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
745+ if (ret)
746+ goto err_power_down;
682747
683− usleep_range(10000, 15000);
684− gpiod_set_value_cansleep(gc0310_dev->reset, 0);
685− usleep_range(10000, 15000);
686− gpiod_set_value_cansleep(gc0310_dev->powerdown, 0);
748+ pm_runtime_set_autosuspend_delay(&client->dev, 1000);
749+ pm_runtime_use_autosuspend(&client->dev);
750+ pm_runtime_put_autosuspend(&client->dev);
687751
688752 return 0;
753+
754+err_power_down:
755+ pm_runtime_put_noidle(&client->dev);
756+ gc0310_remove(client);
757+ return ret;
689758 }
690759
691−static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops, gc0310_suspend, gc0310_resume, NULL);
760+static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops,
761+ gc0310_power_off, gc0310_power_on, NULL);
692762
693763 static const struct acpi_device_id gc0310_acpi_match[] = {
694764 {"INT0310"},
@@ -708,5 +778,6 @@ static struct i2c_driver gc0310_driver = { · 13 unmodified lines
708778 module_i2c_driver(gc0310_driver);
709779
710780 MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>");
781+MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>");
711782 MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors");
712783 MODULE_LICENSE("GPL");
drivers/staging/media/atomisp/i2c/atomisp-gc2235.c+0−2
@@ -779,8 +779,6 @@ static void gc2235_remove(struct i2c_client *client) · 778 unmodified lines
779779 struct v4l2_subdev *sd = i2c_get_clientdata(client);
780780 struct gc2235_device *dev = to_gc2235_sensor(sd);
781781
782− dev_dbg(&client->dev, "gc2235_remove...\n");
783−
784782 dev->platform_data->csi_cfg(sd, 0);
785783
786784 v4l2_device_unregister_subdev(sd);
drivers/staging/media/atomisp/i2c/gc2235.h+8−8
@@ -179,21 +179,21 @@ struct gc2235_write_ctrl { · 178 unmodified lines
179179 struct gc2235_write_buffer buffer;
180180 };
181181
182−static struct gc2235_reg const gc2235_stream_on[] = {
182+static const struct gc2235_reg gc2235_stream_on[] = {
183183 { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */
184184 { GC2235_8BIT, 0x10, 0x91}, /* start mipi */
185185 { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */
186186 { GC2235_TOK_TERM, 0, 0 }
187187 };
188188
189−static struct gc2235_reg const gc2235_stream_off[] = {
189+static const struct gc2235_reg gc2235_stream_off[] = {
190190 { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */
191191 { GC2235_8BIT, 0x10, 0x01}, /* stop mipi */
192192 { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */
193193 { GC2235_TOK_TERM, 0, 0 }
194194 };
195195
196−static struct gc2235_reg const gc2235_init_settings[] = {
196+static const struct gc2235_reg gc2235_init_settings[] = {
197197 /* System */
198198 { GC2235_8BIT, 0xfe, 0x80 },
199199 { GC2235_8BIT, 0xfe, 0x80 },
@@ -268,7 +268,7 @@ static struct gc2235_reg const gc2235_init_settings[] = { · 68 unmodified lines
268268 * Register settings for various resolution
269269 */
270270 #if ENABLE_NON_PREVIEW
271−static struct gc2235_reg const gc2235_1296_736_30fps[] = {
271+static const struct gc2235_reg gc2235_1296_736_30fps[] = {
272272 { GC2235_8BIT, 0x8b, 0xa0 },
273273 { GC2235_8BIT, 0x8c, 0x02 },
274274
@@ -321,7 +321,7 @@ static struct gc2235_reg const gc2235_1296_736_30fps[] = { · 46 unmodified lines
321321 { GC2235_TOK_TERM, 0, 0 }
322322 };
323323
324−static struct gc2235_reg const gc2235_960_640_30fps[] = {
324+static const struct gc2235_reg gc2235_960_640_30fps[] = {
325325 { GC2235_8BIT, 0x8b, 0xa0 },
326326 { GC2235_8BIT, 0x8c, 0x02 },
327327
@@ -373,7 +373,7 @@ static struct gc2235_reg const gc2235_960_640_30fps[] = { · 45 unmodified lines
373373 };
374374 #endif
375375
376−static struct gc2235_reg const gc2235_1600_900_30fps[] = {
376+static const struct gc2235_reg gc2235_1600_900_30fps[] = {
377377 { GC2235_8BIT, 0x8b, 0xa0 },
378378 { GC2235_8BIT, 0x8c, 0x02 },
379379
@@ -418,7 +418,7 @@ static struct gc2235_reg const gc2235_1600_900_30fps[] = { · 38 unmodified lines
418418 { GC2235_TOK_TERM, 0, 0 }
419419 };
420420
421−static struct gc2235_reg const gc2235_1616_1082_30fps[] = {
421+static const struct gc2235_reg gc2235_1616_1082_30fps[] = {
422422 { GC2235_8BIT, 0x8b, 0xa0 },
423423 { GC2235_8BIT, 0x8c, 0x02 },
424424
@@ -463,7 +463,7 @@ static struct gc2235_reg const gc2235_1616_1082_30fps[] = { · 38 unmodified lines
463463 { GC2235_TOK_TERM, 0, 0 }
464464 };
465465
466−static struct gc2235_reg const gc2235_1616_1216_30fps[] = {
466+static const struct gc2235_reg gc2235_1616_1216_30fps[] = {
467467 { GC2235_8BIT, 0x8b, 0xa0 },
468468 { GC2235_8BIT, 0x8c, 0x02 },
469469
drivers/staging/media/atomisp/i2c/ov2722.h+8−8
@@ -236,7 +236,7 @@ struct ov2722_write_ctrl { · 235 unmodified lines
236236 * Register settings for various resolution
237237 */
238238 #if 0
239−static struct ov2722_reg const ov2722_QVGA_30fps[] = {
239+static const struct ov2722_reg ov2722_QVGA_30fps[] = {
240240 {OV2722_8BIT, 0x3718, 0x10},
241241 {OV2722_8BIT, 0x3702, 0x0c},
242242 {OV2722_8BIT, 0x373a, 0x1c},
@@ -346,7 +346,7 @@ static struct ov2722_reg const ov2722_QVGA_30fps[] = { · 103 unmodified lines
346346
347347 };
348348
349−static struct ov2722_reg const ov2722_480P_30fps[] = {
349+static const struct ov2722_reg ov2722_480P_30fps[] = {
350350 {OV2722_8BIT, 0x3718, 0x10},
351351 {OV2722_8BIT, 0x3702, 0x18},
352352 {OV2722_8BIT, 0x373a, 0x3c},
@@ -455,7 +455,7 @@ static struct ov2722_reg const ov2722_480P_30fps[] = { · 102 unmodified lines
455455 {OV2722_TOK_TERM, 0, 0},
456456 };
457457
458−static struct ov2722_reg const ov2722_VGA_30fps[] = {
458+static const struct ov2722_reg ov2722_VGA_30fps[] = {
459459 {OV2722_8BIT, 0x3718, 0x10},
460460 {OV2722_8BIT, 0x3702, 0x18},
461461 {OV2722_8BIT, 0x373a, 0x3c},
@@ -565,7 +565,7 @@ static struct ov2722_reg const ov2722_VGA_30fps[] = { · 103 unmodified lines
565565 };
566566 #endif
567567
568−static struct ov2722_reg const ov2722_1632_1092_30fps[] = {
568+static const struct ov2722_reg ov2722_1632_1092_30fps[] = {
569569 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for
570570 a whole frame complete.(vblank) */
571571 {OV2722_8BIT, 0x3718, 0x10},
@@ -667,7 +667,7 @@ static struct ov2722_reg const ov2722_1632_1092_30fps[] = { · 95 unmodified lines
667667 {OV2722_TOK_TERM, 0, 0}
668668 };
669669
670−static struct ov2722_reg const ov2722_1452_1092_30fps[] = {
670+static const struct ov2722_reg ov2722_1452_1092_30fps[] = {
671671 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for
672672 a whole frame complete.(vblank) */
673673 {OV2722_8BIT, 0x3718, 0x10},
@@ -769,7 +769,7 @@ static struct ov2722_reg const ov2722_1452_1092_30fps[] = { · 95 unmodified lines
769769 };
770770
771771 #if 0
772−static struct ov2722_reg const ov2722_1M3_30fps[] = {
772+static const struct ov2722_reg ov2722_1M3_30fps[] = {
773773 {OV2722_8BIT, 0x3718, 0x10},
774774 {OV2722_8BIT, 0x3702, 0x24},
775775 {OV2722_8BIT, 0x373a, 0x60},
@@ -877,7 +877,7 @@ static struct ov2722_reg const ov2722_1M3_30fps[] = { · 101 unmodified lines
877877 };
878878 #endif
879879
880−static struct ov2722_reg const ov2722_1080p_30fps[] = {
880+static const struct ov2722_reg ov2722_1080p_30fps[] = {
881881 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for a whole
882882 frame complete.(vblank) */
883883 {OV2722_8BIT, 0x3718, 0x10},
@@ -983,7 +983,7 @@ static struct ov2722_reg const ov2722_1080p_30fps[] = { · 99 unmodified lines
983983 };
984984
985985 #if 0 /* Currently unused */
986−static struct ov2722_reg const ov2722_720p_30fps[] = {
986+static const struct ov2722_reg ov2722_720p_30fps[] = {
987987 {OV2722_8BIT, 0x3021, 0x03},
988988 {OV2722_8BIT, 0x3718, 0x10},
989989 {OV2722_8BIT, 0x3702, 0x24},
drivers/staging/media/atomisp/pci/atomisp_compat_css20.c+1−1
@@ -387,7 +387,7 @@ static int __destroy_stream(struct atomisp_sub_device *asd, · 386 unmodified lines
387387 }
388388
389389 if (stream_env->stream_state == CSS_STREAM_STARTED) {
390− timeout = jiffies + msecs_to_jiffies(40);
390+ timeout = jiffies + msecs_to_jiffies(200);
391391 while (1) {
392392 if (ia_css_stream_has_stopped(stream_env->stream))
393393 break;
drivers/staging/media/atomisp/pci/atomisp_csi2.h+0−17
@@ -19,28 +19,11 @@ · 18 unmodified lines
1919 #define CSI2_PAD_SOURCE 1
2020 #define CSI2_PADS_NUM 2
2121
22−#define CSI2_MAX_ACPI_GPIOS 2u
23−
24−struct acpi_device;
2522 struct v4l2_device;
2623
2724 struct atomisp_device;
2825 struct atomisp_sub_device;
2926
30−struct atomisp_csi2_acpi_gpio_map {
31− struct acpi_gpio_params params[CSI2_MAX_ACPI_GPIOS];
32− struct acpi_gpio_mapping mapping[CSI2_MAX_ACPI_GPIOS + 1];
33−};
34−
35−struct atomisp_csi2_acpi_gpio_parsing_data {
36− struct acpi_device *adev;
37− struct atomisp_csi2_acpi_gpio_map *map;
38− u32 settings[CSI2_MAX_ACPI_GPIOS];
39− unsigned int settings_count;
40− unsigned int res_count;
41− unsigned int map_count;
42−};
43−
4427 struct atomisp_mipi_csi2_device {
4528 struct v4l2_subdev subdev;
4629 struct media_pad pads[CSI2_PADS_NUM];
drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c+25−208
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include <linux/clk.h>
1414 #include <linux/device.h>
1515 #include <linux/dmi.h>
16+#include <linux/platform_data/x86/int3472.h>
1617 #include <linux/property.h>
1718
1819 #include <media/ipu-bridge.h>
@@ -24,39 +25,6 @@ · 5 unmodified lines
2425
2526 #define PMC_CLK_RATE_19_2MHZ 19200000
2627
27−/*
28− * 79234640-9e10-4fea-a5c1-b5aa8b19756f
29− * This _DSM GUID returns information about the GPIO lines mapped to a sensor.
30− * Function number 1 returns a count of the GPIO lines that are mapped.
31− * Subsequent functions return 32 bit ints encoding information about the GPIO.
32− */
33−static const guid_t intel_sensor_gpio_info_guid =
34− GUID_INIT(0x79234640, 0x9e10, 0x4fea,
35− 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);
36−
37−#define INTEL_GPIO_DSM_TYPE_SHIFT 0
38−#define INTEL_GPIO_DSM_TYPE_MASK GENMASK(7, 0)
39−#define INTEL_GPIO_DSM_PIN_SHIFT 8
40−#define INTEL_GPIO_DSM_PIN_MASK GENMASK(15, 8)
41−#define INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT 24
42−#define INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK GENMASK(31, 24)
43−
44−#define INTEL_GPIO_DSM_TYPE(x) \
45− (((x) & INTEL_GPIO_DSM_TYPE_MASK) >> INTEL_GPIO_DSM_TYPE_SHIFT)
46−#define INTEL_GPIO_DSM_PIN(x) \
47− (((x) & INTEL_GPIO_DSM_PIN_MASK) >> INTEL_GPIO_DSM_PIN_SHIFT)
48−#define INTEL_GPIO_DSM_SENSOR_ON_VAL(x) \
49− (((x) & INTEL_GPIO_DSM_SENSOR_ON_VAL_MASK) >> INTEL_GPIO_DSM_SENSOR_ON_VAL_SHIFT)
50−
51−/*
52− * 822ace8f-2814-4174-a56b-5f029fe079ee
53− * This _DSM GUID returns a string from the sensor device, which acts as a
54− * module identifier.
55− */
56−static const guid_t intel_sensor_module_guid =
57− GUID_INIT(0x822ace8f, 0x2814, 0x4174,
58− 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);
59−
6028 /*
6129 * dc2f6c4f-045b-4f1d-97b9-882a6860a4be
6230 * This _DSM GUID returns a package with n*2 strings, with each set of 2 strings
@@ -323,196 +291,45 @@ static int atomisp_csi2_get_port(struct acpi_device *adev, int clock_num) · 260 unmodified lines
323291 return gmin_cfg_get_int(adev, "CsiPort", port);
324292 }
325293
326−/* Note this always returns 1 to continue looping so that res_count is accurate */
327−static int atomisp_csi2_handle_acpi_gpio_res(struct acpi_resource *ares, void *_data)
328−{
329− struct atomisp_csi2_acpi_gpio_parsing_data *data = _data;
330− struct acpi_resource_gpio *agpio;
331− const char *name;
332− bool active_low;
333− unsigned int i;
334− u32 settings = 0;
335− u16 pin;
336−
337− if (!acpi_gpio_get_io_resource(ares, &agpio))
338− return 1; /* Not a GPIO, continue the loop */
339−
340− data->res_count++;
341−
342− pin = agpio->pin_table[0];
343− for (i = 0; i < data->settings_count; i++) {
344− if (INTEL_GPIO_DSM_PIN(data->settings[i]) == pin) {
345− settings = data->settings[i];
346− break;
347− }
348− }
349−
350− if (i == data->settings_count) {
351− acpi_handle_warn(data->adev->handle,
352− "%s: Could not find DSM GPIO settings for pin %u\n",
353− dev_name(&data->adev->dev), pin);
354− return 1;
355− }
356−
357− switch (INTEL_GPIO_DSM_TYPE(settings)) {
358− case 0:
359− name = "reset-gpios";
360− break;
361− case 1:
362− name = "powerdown-gpios";
363− break;
364− default:
365− acpi_handle_warn(data->adev->handle, "%s: Unknown GPIO type 0x%02lx for pin %u\n",
366− dev_name(&data->adev->dev),
367− INTEL_GPIO_DSM_TYPE(settings), pin);
368− return 1;
369− }
370−
371− /*
372− * Both reset and power-down need to be logical false when the sensor
373− * is on (sensor should not be in reset and not be powered-down). So
374− * when the sensor-on-value (which is the physical pin value) is high,
375− * then the signal is active-low.
376− */
377− active_low = INTEL_GPIO_DSM_SENSOR_ON_VAL(settings);
378−
379− i = data->map_count;
380− if (i == CSI2_MAX_ACPI_GPIOS)
381− return 1;
382−
383− /* res_count is already incremented */
384− data->map->params[i].crs_entry_index = data->res_count - 1;
385− data->map->params[i].active_low = active_low;
386− data->map->mapping[i].name = name;
387− data->map->mapping[i].data = &data->map->params[i];
388− data->map->mapping[i].size = 1;
389− data->map_count++;
390−
391− acpi_handle_info(data->adev->handle, "%s: %s crs %d %s pin %u active-%s\n",
392− dev_name(&data->adev->dev), name,
393− data->res_count - 1, agpio->resource_source.string_ptr,
394− pin, active_low ? "low" : "high");
395−
396− return 1;
397−}
398−
399294 /*
400− * Helper function to create an ACPI GPIO lookup table for sensor reset and
401− * powerdown signals on Intel Bay Trail (BYT) and Cherry Trail (CHT) devices,
402− * including setting the correct polarity for the GPIO.
403− *
404− * This uses the "79234640-9e10-4fea-a5c1-b5aa8b19756f" DSM method directly
405− * on the sensor device's ACPI node. This is different from later Intel
406− * hardware which has a separate INT3472 acpi_device with this info.
407− *
408− * This function must be called before creating the sw-noded describing
409− * the fwnode graph endpoint. And sensor drivers used on these devices
410− * must return -EPROBE_DEFER when there is no endpoint description yet.
411− * Together this guarantees that the GPIO lookups are in place before
412− * the sensor driver tries to get GPIOs with gpiod_get().
295+ * Alloc and fill an int3472_discrete_device struct so that we can re-use
296+ * the INT3472 sensor GPIO mapping code.
413297 *
414− * Note this code uses the same DSM GUID as the int3472_gpio_guid in
415− * the INT3472 discrete.c code and there is some overlap, but there are
416− * enough differences that it is difficult to share the code.
298+ * This gets called from ipu_bridge_init() which runs only once per boot,
299+ * the created faux int3472 device is leaked on purpose to keep the created
300+ * GPIO mappings around permanently.
417301 */
418302 static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev)
419303 {
420− struct atomisp_csi2_acpi_gpio_parsing_data data = { };
421− LIST_HEAD(resource_list);
422− union acpi_object *obj;
423− unsigned int i, j;
304+ struct int3472_discrete_device *int3472;
424305 int ret;
425306
426− obj = acpi_evaluate_dsm_typed(adev->handle, &intel_sensor_module_guid,
427− 0x00, 1, NULL, ACPI_TYPE_STRING);
428− if (obj) {
429− acpi_handle_info(adev->handle, "%s: Sensor module id: '%s'\n",
430− dev_name(&adev->dev), obj->string.pointer);
431− ACPI_FREE(obj);
432− }
307+ /* Max num GPIOs we've seen plus a terminator */
308+ int3472 = kzalloc(struct_size(int3472, gpios.table, INT3472_MAX_SENSOR_GPIOS + 1),
309+ GFP_KERNEL);
310+ if (!int3472)
311+ return -ENOMEM;
433312
434313 /*
435− * First get the GPIO-settings count and then get count GPIO-settings
436− * values. Note the order of these may differ from the order in which
437− * the GPIOs are listed on the ACPI resources! So we first store them all
438− * and then enumerate the ACPI resources and match them up by pin number.
314+ * On atomisp the _DSM to get the GPIO type must be made on the sensor
315+ * adev, rather than on a separate INT3472 adev.
439316 */
440− obj = acpi_evaluate_dsm_typed(adev->handle,
441− &intel_sensor_gpio_info_guid, 0x00, 1,
442− NULL, ACPI_TYPE_INTEGER);
443− if (!obj) {
444− acpi_handle_err(adev->handle, "%s: No _DSM entry for GPIO pin count\n",
445− dev_name(&adev->dev));
446− return -EIO;
447− }
448−
449− data.settings_count = obj->integer.value;
450− ACPI_FREE(obj);
317+ int3472->adev = adev;
318+ int3472->dev = &adev->dev;
319+ int3472->sensor = adev;
451320
452− if (data.settings_count > CSI2_MAX_ACPI_GPIOS) {
453− acpi_handle_err(adev->handle, "%s: Too many GPIOs %u > %u\n",
454− dev_name(&adev->dev), data.settings_count,
455− CSI2_MAX_ACPI_GPIOS);
456− return -EOVERFLOW;
321+ int3472->sensor_name = kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev));
322+ if (!int3472->sensor_name) {
323+ kfree(int3472);
324+ return -ENOMEM;
457325 }
458326
459− for (i = 0; i < data.settings_count; i++) {
460− /*
461− * i + 2 because the index of this _DSM function is 1-based
462− * and the first function is just a count.
463− */
464− obj = acpi_evaluate_dsm_typed(adev->handle,
465− &intel_sensor_gpio_info_guid,
466− 0x00, i + 2,
467− NULL, ACPI_TYPE_INTEGER);
468− if (!obj) {
469− acpi_handle_err(adev->handle, "%s: No _DSM entry for pin %u\n",
470− dev_name(&adev->dev), i);
471− return -EIO;
472− }
473−
474− data.settings[i] = obj->integer.value;
475− ACPI_FREE(obj);
327+ ret = int3472_discrete_parse_crs(int3472);
328+ if (ret) {
329+ int3472_discrete_cleanup(int3472);
330+ kfree(int3472);
476331 }
477332
478− /* Since we match up by pin-number the pin-numbers must be unique */
479− for (i = 0; i < data.settings_count; i++) {
480− for (j = i + 1; j < data.settings_count; j++) {
481− if (INTEL_GPIO_DSM_PIN(data.settings[i]) !=
482− INTEL_GPIO_DSM_PIN(data.settings[j]))
483− continue;
484−
485− acpi_handle_err(adev->handle, "%s: Duplicate pin number %lu\n",
486− dev_name(&adev->dev),
487− INTEL_GPIO_DSM_PIN(data.settings[i]));
488− return -EIO;
489− }
490− }
491−
492− data.map = kzalloc(sizeof(*data.map), GFP_KERNEL);
493− if (!data.map)
494− return -ENOMEM;
495−
496− /* Now parse the ACPI resources and build the lookup table */
497− data.adev = adev;
498− ret = acpi_dev_get_resources(adev, &resource_list,
499− atomisp_csi2_handle_acpi_gpio_res, &data);
500− if (ret < 0)
501− return ret;
502−
503− acpi_dev_free_resource_list(&resource_list);
504−
505− if (data.map_count != data.settings_count ||
506− data.res_count != data.settings_count)
507− acpi_handle_warn(adev->handle, "%s: ACPI GPIO resources vs DSM GPIO-info count mismatch (dsm: %d res: %d map %d\n",
508− dev_name(&adev->dev), data.settings_count,
509− data.res_count, data.map_count);
510−
511− ret = acpi_dev_add_driver_gpios(adev, data.map->mapping);
512− if (ret)
513− acpi_handle_err(adev->handle, "%s: Error adding driver GPIOs: %d\n",
514− dev_name(&adev->dev), ret);
515−
516333 return ret;
517334 }
518335
drivers/staging/media/atomisp/pci/atomisp_drvfs.c+0−155
@@ -1,155 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0
2−/*
3− * Support for atomisp driver sysfs interface
4− *
5− * Copyright (c) 2014 Intel Corporation. All Rights Reserved.
6− */
7−
8−#include <linux/device.h>
9−#include <linux/err.h>
10−#include <linux/kernel.h>
11−
12−#include "atomisp_compat.h"
13−#include "atomisp_internal.h"
14−#include "atomisp_ioctl.h"
15−#include "atomisp_drvfs.h"
16−#include "hmm/hmm.h"
17−#include "ia_css_debug.h"
18−
19−#define OPTION_BIN_LIST BIT(0)
20−#define OPTION_BIN_RUN BIT(1)
21−#define OPTION_VALID (OPTION_BIN_LIST | OPTION_BIN_RUN)
22−
23−/*
24− * dbgopt: iunit debug option:
25− * bit 0: binary list
26− * bit 1: running binary
27− * bit 2: memory statistic
28− */
29−static unsigned int dbgopt = OPTION_BIN_LIST;
30−
31−static inline int iunit_dump_dbgopt(struct atomisp_device *isp,
32− unsigned int opt)
33−{
34− int ret = 0;
35−
36− if (opt & OPTION_VALID) {
37− if (opt & OPTION_BIN_LIST) {
38− ret = atomisp_css_dump_blob_infor(isp);
39− if (ret) {
40− dev_err(isp->dev, "%s dump blob infor err[ret:%d]\n",
41− __func__, ret);
42− goto opt_err;
43− }
44− }
45−
46− if (opt & OPTION_BIN_RUN) {
47− if (isp->asd.streaming) {
48− atomisp_css_dump_sp_raw_copy_linecount(true);
49− atomisp_css_debug_dump_isp_binary();
50− } else {
51− ret = -EPERM;
52− dev_err(isp->dev, "%s dump running bin err[ret:%d]\n",
53− __func__, ret);
54− goto opt_err;
55− }
56− }
57− } else {
58− ret = -EINVAL;
59− dev_err(isp->dev, "%s dump nothing[ret=%d]\n", __func__, ret);
60− }
61−
62−opt_err:
63− return ret;
64−}
65−
66−static ssize_t dbglvl_show(struct device *dev, struct device_attribute *attr,
67− char *buf)
68−{
69− unsigned int dbglvl = ia_css_debug_get_dtrace_level();
70−
71− return sysfs_emit(buf, "dtrace level:%u\n", dbglvl);
72−}
73−
74−static ssize_t dbglvl_store(struct device *dev, struct device_attribute *attr,
75− const char *buf, size_t size)
76−{
77− unsigned int dbglvl;
78− int ret;
79−
80− ret = kstrtouint(buf, 10, &dbglvl);
81− if (ret)
82− return ret;
83−
84− if (dbglvl < 1 || dbglvl > 9)
85− return -ERANGE;
86−
87− ia_css_debug_set_dtrace_level(dbglvl);
88− return size;
89−}
90−static DEVICE_ATTR_RW(dbglvl);
91−
92−static ssize_t dbgfun_show(struct device *dev, struct device_attribute *attr,
93− char *buf)
94−{
95− unsigned int dbgfun = atomisp_get_css_dbgfunc();
96−
97− return sysfs_emit(buf, "dbgfun opt:%u\n", dbgfun);
98−}
99−
100−static ssize_t dbgfun_store(struct device *dev, struct device_attribute *attr,
101− const char *buf, size_t size)
102−{
103− struct atomisp_device *isp = dev_get_drvdata(dev);
104− unsigned int opt;
105− int ret;
106−
107− ret = kstrtouint(buf, 10, &opt);
108− if (ret)
109− return ret;
110−
111− return atomisp_set_css_dbgfunc(isp, opt);
112−}
113−static DEVICE_ATTR_RW(dbgfun);
114−
115−static ssize_t dbgopt_show(struct device *dev, struct device_attribute *attr,
116− char *buf)
117−{
118− return sysfs_emit(buf, "option:0x%x\n", dbgopt);
119−}
120−
121−static ssize_t dbgopt_store(struct device *dev, struct device_attribute *attr,
122− const char *buf, size_t size)
123−{
124− struct atomisp_device *isp = dev_get_drvdata(dev);
125− unsigned int opt;
126− int ret;
127−
128− ret = kstrtouint(buf, 10, &opt);
129− if (ret)
130− return ret;
131−
132− dbgopt = opt;
133− ret = iunit_dump_dbgopt(isp, dbgopt);
134− if (ret)
135− return ret;
136−
137− return size;
138−}
139−static DEVICE_ATTR_RW(dbgopt);
140−
141−static struct attribute *dbg_attrs[] = {
142− &dev_attr_dbglvl.attr,
143− &dev_attr_dbgfun.attr,
144− &dev_attr_dbgopt.attr,
145− NULL
146−};
147−
148−static const struct attribute_group dbg_attr_group = {
149− .attrs = dbg_attrs,
150−};
151−
152−const struct attribute_group *dbg_attr_groups[] = {
153− &dbg_attr_group,
154− NULL
155−};
drivers/staging/media/atomisp/pci/atomisp_drvfs.h+0−15
@@ -1,15 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−/*
3− * Support for atomisp driver sysfs interface.
4− *
5− * Copyright (c) 2014 Intel Corporation. All Rights Reserved.
6− */
7−
8−#ifndef __ATOMISP_DRVFS_H__
9−#define __ATOMISP_DRVFS_H__
10−
11−#include <linux/sysfs.h>
12−
13−extern const struct attribute_group *dbg_attr_groups[];
14−
15−#endif /* __ATOMISP_DRVFS_H__ */
drivers/staging/media/atomisp/pci/atomisp_fops.c+1−4
@@ -234,9 +234,6 @@ static int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd, · 233 unmodified lines
234234 if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM))
235235 return -EINVAL;
236236
237− if (pipe->stopping)
238− return -EINVAL;
239−
240237 space = ATOMISP_CSS_Q_DEPTH - atomisp_buffers_in_css(pipe);
241238 while (space--) {
242239 struct ia_css_frame *frame;
@@ -367,7 +364,7 @@ static void atomisp_buf_queue(struct vb2_buffer *vb) · 124 unmodified lines
367364 mutex_lock(&asd->isp->mutex);
368365
369366 ret = atomisp_pipe_check(pipe, false);
370− if (ret || pipe->stopping) {
367+ if (ret) {
371368 spin_lock_irqsave(&pipe->irq_lock, irqflags);
372369 atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
373370 spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
drivers/staging/media/atomisp/pci/atomisp_ioctl.c+60−69
@@ -856,6 +856,62 @@ static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd) · 855 unmodified lines
856856 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00);
857857 }
858858
859+static void atomisp_stop_stream(struct atomisp_video_pipe *pipe,
860+ bool stop_sensor, enum vb2_buffer_state state)
861+{
862+ struct atomisp_sub_device *asd = pipe->asd;
863+ struct atomisp_device *isp = asd->isp;
864+ struct pci_dev *pdev = to_pci_dev(isp->dev);
865+ unsigned long flags;
866+ int ret;
867+
868+ spin_lock_irqsave(&isp->lock, flags);
869+ asd->streaming = false;
870+ spin_unlock_irqrestore(&isp->lock, flags);
871+
872+ atomisp_clear_css_buffer_counters(asd);
873+ atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
874+
875+ atomisp_css_stop(asd, false);
876+
877+ atomisp_subdev_cleanup_pending_events(asd);
878+
879+ if (stop_sensor) {
880+ ret = v4l2_subdev_call(isp->inputs[asd->input_curr].csi_remote_source,
881+ video, s_stream, 0);
882+ if (ret)
883+ dev_warn(isp->dev, "Stopping sensor stream failed: %d\n", ret);
884+ }
885+
886+ /* Disable the CSI interface on ANN B0/K0 */
887+ if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
888+ ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
889+ pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
890+ isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY);
891+ }
892+
893+ if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false))
894+ dev_warn(isp->dev, "DFS failed.\n");
895+
896+ /*
897+ * ISP work around, need to reset ISP to allow next stream on to work.
898+ * Streams have already been destroyed by atomisp_css_stop().
899+ * Disable PUNIT/ISP acknowledge/handshake - SRSE=3 and then reset.
900+ */
901+ pci_write_config_dword(pdev, PCI_I_CONTROL,
902+ isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
903+ atomisp_reset(isp);
904+
905+ atomisp_flush_video_pipe(pipe, state, false);
906+
907+ /* Streams were destroyed by atomisp_css_stop(), recreate them. */
908+ ret = atomisp_create_pipes_stream(&isp->asd);
909+ if (ret)
910+ dev_warn(isp->dev, "Recreating streams failed: %d\n", ret);
911+
912+ media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]);
913+}
914+
859915 int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)
860916 {
861917 struct atomisp_video_pipe *pipe = vq_to_pipe(vq);
@@ -910,6 +966,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) · 48 unmodified lines
910966 ret = atomisp_css_start(asd);
911967 if (ret) {
912968 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true);
969+ media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]);
913970 goto out_unlock;
914971 }
915972
@@ -949,11 +1006,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) · 33 unmodified lines
9491006 video, s_stream, 1);
9501007 if (ret) {
9511008 dev_err(isp->dev, "Starting sensor stream failed: %d\n", ret);
952− spin_lock_irqsave(&isp->lock, irqflags);
953− asd->streaming = false;
954− spin_unlock_irqrestore(&isp->lock, irqflags);
955− ret = -EINVAL;
956− goto out_unlock;
1009+ atomisp_stop_stream(pipe, false, VB2_BUF_STATE_QUEUED);
9571010 }
9581011
9591012 out_unlock:
@@ -964,74 +1017,12 @@ out_unlock: · 4 unmodified lines
9641017 void atomisp_stop_streaming(struct vb2_queue *vq)
9651018 {
9661019 struct atomisp_video_pipe *pipe = vq_to_pipe(vq);
967− struct atomisp_sub_device *asd = pipe->asd;
968− struct atomisp_device *isp = asd->isp;
969− struct pci_dev *pdev = to_pci_dev(isp->dev);
970− unsigned long flags;
971− int ret;
1020+ struct atomisp_device *isp = pipe->asd->isp;
9721021
9731022 dev_dbg(isp->dev, "Stop stream\n");
9741023
9751024 mutex_lock(&isp->mutex);
976− /*
977− * There is no guarantee that the buffers queued to / owned by the ISP
978− * will properly be returned to the queue when stopping. Set a flag to
979− * avoid new buffers getting queued and then wait for all the current
980− * buffers to finish.
981− */
982− pipe->stopping = true;
983− mutex_unlock(&isp->mutex);
984− /* wait max 1 second */
985− ret = wait_event_timeout(pipe->vb_queue.done_wq,
986− atomisp_buffers_in_css(pipe) == 0, HZ);
987− mutex_lock(&isp->mutex);
988− pipe->stopping = false;
989− if (ret == 0)
990− dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n");
991−
992− spin_lock_irqsave(&isp->lock, flags);
993− asd->streaming = false;
994− spin_unlock_irqrestore(&isp->lock, flags);
995−
996− atomisp_clear_css_buffer_counters(asd);
997− atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
998−
999− atomisp_css_stop(asd, false);
1000−
1001− atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_ERROR, true);
1002−
1003− atomisp_subdev_cleanup_pending_events(asd);
1004−
1005− ret = v4l2_subdev_call(isp->inputs[asd->input_curr].csi_remote_source,
1006− video, s_stream, 0);
1007− if (ret)
1008− dev_warn(isp->dev, "Stopping sensor stream failed: %d\n", ret);
1009−
1010− /* Disable the CSI interface on ANN B0/K0 */
1011− if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
1012− ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
1013− pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
1014− isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY);
1015− }
1016−
1017− if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false))
1018− dev_warn(isp->dev, "DFS failed.\n");
1019−
1020− /*
1021− * ISP work around, need to reset ISP to allow next stream on to work.
1022− * Streams have already been destroyed by atomisp_css_stop().
1023− * Disable PUNIT/ISP acknowledge/handshake - SRSE=3 and then reset.
1024− */
1025− pci_write_config_dword(pdev, PCI_I_CONTROL,
1026− isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
1027− atomisp_reset(isp);
1028−
1029− /* Streams were destroyed by atomisp_css_stop(), recreate them. */
1030− ret = atomisp_create_pipes_stream(&isp->asd);
1031− if (ret)
1032− dev_warn(isp->dev, "Recreating streams failed: %d\n", ret);
1033−
1034− media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]);
1025+ atomisp_stop_stream(pipe, true, VB2_BUF_STATE_ERROR);
10351026 mutex_unlock(&isp->mutex);
10361027 }
10371028
drivers/staging/media/atomisp/pci/atomisp_subdev.h+0−3
@@ -57,9 +57,6 @@ struct atomisp_video_pipe { · 56 unmodified lines
5757 /* Filled through atomisp_get_css_frame_info() on queue setup */
5858 struct ia_css_frame_info frame_info;
5959
60− /* Set from streamoff to disallow queuing further buffers in CSS */
61− bool stopping;
62−
6360 /*
6461 * irq_lock is used to protect video buffer state change operations and
6562 * also to make activeq and capq operations atomic.
drivers/staging/media/atomisp/pci/atomisp_v4l2.c+1−4
@@ -29,7 +29,6 @@ · 28 unmodified lines
2929 #include "atomisp_internal.h"
3030 #include "atomisp-regs.h"
3131 #include "atomisp_dfs_tables.h"
32−#include "atomisp_drvfs.h"
3332 #include "hmm/hmm.h"
3433 #include "atomisp_trace_event.h"
3534
@@ -1497,9 +1496,6 @@ static const struct pci_device_id atomisp_pci_tbl[] = { · 1461 unmodified lines
14971496 MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl);
14981497
14991498 static struct pci_driver atomisp_pci_driver = {
1500− .driver = {
1501− .dev_groups = dbg_attr_groups,
1502− },
15031499 .name = "atomisp-isp2",
15041500 .id_table = atomisp_pci_tbl,
15051501 .probe = atomisp_pci_probe,
@@ -1513,3 +1509,4 @@ MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>"); · 7 unmodified lines
15131509 MODULE_LICENSE("GPL");
15141510 MODULE_DESCRIPTION("Intel ATOM Platform ISP Driver");
15151511 MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
1512+MODULE_IMPORT_NS("INTEL_INT3472_DISCRETE");
drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h+0−5
@@ -10,14 +10,9 @@ · 9 unmodified lines
1010 /* Override the definition of max/min from Linux kernel */
1111 #include <linux/minmax.h>
1212
13−/* force a value to a lower even value */
14−#define EVEN_FLOOR(x) ((x) & ~1)
15−
1613 #define CEIL_DIV(a, b) (((b) != 0) ? ((a) + (b) - 1) / (b) : 0)
1714 #define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b))
18−#define CEIL_MUL2(a, b) (((a) + (b) - 1) & ~((b) - 1))
1915 #define CEIL_SHIFT(a, b) (((a) + (1 << (b)) - 1) >> (b))
20−#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b))
2116
2217 /*
2318 * For SP and ISP, SDK provides the definition of OP_std_modadd.
drivers/staging/media/atomisp/pci/hmm/hmm.c+0−91
@@ -28,88 +28,6 @@ struct hmm_bo_device bo_device; · 27 unmodified lines
2828 static ia_css_ptr dummy_ptr = mmgr_EXCEPTION;
2929 static bool hmm_initialized;
3030
31−/*
32− * p: private
33− * v: vmalloc
34− */
35−static const char hmm_bo_type_string[] = "pv";
36−
37−static ssize_t bo_show(struct device *dev, struct device_attribute *attr,
38− char *buf, struct list_head *bo_list, bool active)
39−{
40− ssize_t ret = 0;
41− struct hmm_buffer_object *bo;
42− unsigned long flags;
43− int i;
44− long total[HMM_BO_LAST] = { 0 };
45− long count[HMM_BO_LAST] = { 0 };
46− int index1 = 0;
47− int index2 = 0;
48−
49− ret = scnprintf(buf, PAGE_SIZE, "type pgnr\n");
50− if (ret <= 0)
51− return 0;
52−
53− index1 += ret;
54−
55− spin_lock_irqsave(&bo_device.list_lock, flags);
56− list_for_each_entry(bo, bo_list, list) {
57− if ((active && (bo->status & HMM_BO_ALLOCED)) ||
58− (!active && !(bo->status & HMM_BO_ALLOCED))) {
59− ret = scnprintf(buf + index1, PAGE_SIZE - index1,
60− "%c %d\n",
61− hmm_bo_type_string[bo->type], bo->pgnr);
62−
63− total[bo->type] += bo->pgnr;
64− count[bo->type]++;
65− if (ret > 0)
66− index1 += ret;
67− }
68− }
69− spin_unlock_irqrestore(&bo_device.list_lock, flags);
70−
71− for (i = 0; i < HMM_BO_LAST; i++) {
72− if (count[i]) {
73− ret = scnprintf(buf + index1 + index2,
74− PAGE_SIZE - index1 - index2,
75− "%ld %c buffer objects: %ld KB\n",
76− count[i], hmm_bo_type_string[i],
77− total[i] * 4);
78− if (ret > 0)
79− index2 += ret;
80− }
81− }
82−
83− /* Add trailing zero, not included by scnprintf */
84− return index1 + index2 + 1;
85−}
86−
87−static ssize_t active_bo_show(struct device *dev, struct device_attribute *attr,
88− char *buf)
89−{
90− return bo_show(dev, attr, buf, &bo_device.entire_bo_list, true);
91−}
92−
93−static ssize_t free_bo_show(struct device *dev, struct device_attribute *attr,
94− char *buf)
95−{
96− return bo_show(dev, attr, buf, &bo_device.entire_bo_list, false);
97−}
98−
99−
100−static DEVICE_ATTR_RO(active_bo);
101−static DEVICE_ATTR_RO(free_bo);
102−
103−static struct attribute *sysfs_attrs_ctrl[] = {
104− &dev_attr_active_bo.attr,
105− &dev_attr_free_bo.attr,
106− NULL
107−};
108−
109−static struct attribute_group atomisp_attribute_group[] = {
110− {.attrs = sysfs_attrs_ctrl },
111−};
112−
11331 int hmm_init(void)
11432 {
11533 int ret;
@@ -130,14 +48,6 @@ int hmm_init(void) · 14 unmodified lines
13048 */
13149 dummy_ptr = hmm_alloc(1);
13250
133− if (!ret) {
134− ret = sysfs_create_group(&atomisp_dev->kobj,
135− atomisp_attribute_group);
136− if (ret)
137− dev_err(atomisp_dev,
138− "%s Failed to create sysfs\n", __func__);
139− }
140−
14151 return ret;
14252 }
14353
@@ -145,7 +55,6 @@ void hmm_cleanup(void) · 1 unmodified line
14555 {
14656 if (dummy_ptr == mmgr_EXCEPTION)
14757 return;
148− sysfs_remove_group(&atomisp_dev->kobj, atomisp_attribute_group);
14958
15059 /* free dummy memory first */
15160 hmm_free(dummy_ptr);
drivers/staging/media/atomisp/pci/hmm/hmm_bo.c+2−3
@@ -37,8 +37,6 @@ static int __bo_init(struct hmm_bo_device *bdev, struct hmm_buffer_object *bo, · 36 unmodified lines
3737 unsigned int pgnr)
3838 {
3939 check_bodev_null_return(bdev, -EINVAL);
40− var_equal_return(hmm_bo_device_inited(bdev), 0, -EINVAL,
41− "hmm_bo_device not inited yet.\n");
4240 /* prevent zero size buffer object */
4341 if (pgnr == 0) {
4442 dev_err(atomisp_dev, "0 size buffer is not allowed.\n");
@@ -341,7 +339,6 @@ int hmm_bo_device_init(struct hmm_bo_device *bdev, · 296 unmodified lines
341339 spin_lock_init(&bdev->list_lock);
342340 mutex_init(&bdev->rbtree_mutex);
343341
344− bdev->flag = HMM_BO_DEVICE_INITED;
345342
346343 INIT_LIST_HEAD(&bdev->entire_bo_list);
347344 bdev->allocated_rbtree = RB_ROOT;
@@ -376,6 +373,8 @@ int hmm_bo_device_init(struct hmm_bo_device *bdev, · 28 unmodified lines
376373
377374 __bo_insert_to_free_rbtree(&bdev->free_rbtree, bo);
378375
376+ bdev->flag = HMM_BO_DEVICE_INITED;
377+
379378 return 0;
380379 }
381380
drivers/staging/media/atomisp/pci/ia_css_pipe.h+0−2
@@ -102,8 +102,6 @@ struct ia_css_yuvpp_settings { · 101 unmodified lines
102102 struct osys_object;
103103
104104 struct ia_css_pipe {
105− /* TODO: Remove stop_requested and use stop_requested in the pipeline */
106− bool stop_requested;
107105 struct ia_css_pipe_config config;
108106 struct ia_css_pipe_extra_config extra_config;
109107 struct ia_css_pipe_info info;
drivers/staging/media/atomisp/pci/isp/kernels/anr/anr_1.0/ia_css_anr_types.h+3−1
@@ -11,9 +11,11 @@ · 10 unmodified lines
1111 * CSS-API header file for Advanced Noise Reduction kernel v1
1212 */
1313
14+#include <linux/math.h>
15+
1416 /* Application specific DMA settings */
1517 #define ANR_BPP 10
16−#define ANR_ELEMENT_BITS ((CEIL_DIV(ANR_BPP, 8)) * 8)
18+#define ANR_ELEMENT_BITS round_up(ANR_BPP, 8)
1719
1820 /* Advanced Noise Reduction configuration.
1921 * This is also known as Low-Light.
drivers/staging/media/atomisp/pci/isp/kernels/dpc2/ia_css_dpc2_param.h+4−2
@@ -7,6 +7,8 @@ · 6 unmodified lines
77 #ifndef __IA_CSS_DPC2_PARAM_H
88 #define __IA_CSS_DPC2_PARAM_H
99
10+#include <linux/math.h>
11+
1012 #include "type_support.h"
1113 #include "vmem.h" /* for VMEM_ARRAY*/
1214
@@ -19,12 +21,12 @@ · 6 unmodified lines
1921 /* 3 lines state per color plane input_line_state */
2022 #define DPC2_STATE_INPUT_BUFFER_HEIGHT (3 * NUM_PLANES)
2123 /* Each plane has width equal to half frame line */
22−#define DPC2_STATE_INPUT_BUFFER_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
24+#define DPC2_STATE_INPUT_BUFFER_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
2325
2426 /* 1 line state per color plane for local deviation state*/
2527 #define DPC2_STATE_LOCAL_DEVIATION_BUFFER_HEIGHT (1 * NUM_PLANES)
2628 /* Each plane has width equal to half frame line */
27−#define DPC2_STATE_LOCAL_DEVIATION_BUFFER_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
29+#define DPC2_STATE_LOCAL_DEVIATION_BUFFER_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
2830
2931 /* MINMAX state buffer stores 1 full input line (GR-R color line) */
3032 #define DPC2_STATE_SECOND_MINMAX_BUFFER_HEIGHT 1
drivers/staging/media/atomisp/pci/isp/kernels/dvs/dvs_1.0/ia_css_dvs.host.c+2−2
@@ -141,10 +141,10 @@ convert_coords_to_ispparams( · 140 unmodified lines
141141
142142 /* similar to topleft_y calculation, but round up if ymax
143143 * has any fraction bits */
144− bottom_y = CEIL_DIV(ymax, 1 << DVS_COORD_FRAC_BITS);
144+ bottom_y = DIV_ROUND_UP(ymax, BIT(DVS_COORD_FRAC_BITS));
145145 s.in_block_height = bottom_y - topleft_y + dvs_interp_envelope;
146146
147− bottom_x = CEIL_DIV(xmax, 1 << DVS_COORD_FRAC_BITS);
147+ bottom_x = DIV_ROUND_UP(xmax, BIT(DVS_COORD_FRAC_BITS));
148148 s.in_block_width = bottom_x - topleft_x + dvs_interp_envelope;
149149
150150 topleft_x_frac = topleft_x << (DVS_COORD_FRAC_BITS);
drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h+12−10
@@ -7,6 +7,8 @@ · 6 unmodified lines
77 #ifndef __IA_CSS_EED1_8_PARAM_H
88 #define __IA_CSS_EED1_8_PARAM_H
99
10+#include <linux/math.h>
11+
1012 #include "type_support.h"
1113 #include "vmem.h" /* needed for VMEM_ARRAY */
1214
@@ -35,35 +37,35 @@ · 22 unmodified lines
3537 #define EED1_8_STATE_INPUT_BUFFER_HEIGHT (5 * NUM_PLANES)
3638
3739 /* Each plane has width equal to half frame line */
38−#define EED1_8_STATE_INPUT_BUFFER_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
40+#define EED1_8_STATE_INPUT_BUFFER_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
3941
4042 /* 1 line state per color plane LD_H state */
4143 #define EED1_8_STATE_LD_H_HEIGHT (1 * NUM_PLANES)
42−#define EED1_8_STATE_LD_H_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
44+#define EED1_8_STATE_LD_H_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
4345
4446 /* 1 line state per color plane LD_V state */
4547 #define EED1_8_STATE_LD_V_HEIGHT (1 * NUM_PLANES)
46−#define EED1_8_STATE_LD_V_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
48+#define EED1_8_STATE_LD_V_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
4749
4850 /* 1 line (single plane) state for D_Hr state */
4951 #define EED1_8_STATE_D_HR_HEIGHT 1
50−#define EED1_8_STATE_D_HR_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
52+#define EED1_8_STATE_D_HR_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
5153
5254 /* 1 line (single plane) state for D_Hb state */
5355 #define EED1_8_STATE_D_HB_HEIGHT 1
54−#define EED1_8_STATE_D_HB_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
56+#define EED1_8_STATE_D_HB_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
5557
5658 /* 2 lines (single plane) state for D_Vr state */
5759 #define EED1_8_STATE_D_VR_HEIGHT 2
58−#define EED1_8_STATE_D_VR_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
60+#define EED1_8_STATE_D_VR_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
5961
6062 /* 2 line (single plane) state for D_Vb state */
6163 #define EED1_8_STATE_D_VB_HEIGHT 2
62−#define EED1_8_STATE_D_VB_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
64+#define EED1_8_STATE_D_VB_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
6365
6466 /* 2 lines state for R and B (= 2 planes) rb_zipped_state */
6567 #define EED1_8_STATE_RB_ZIPPED_HEIGHT (2 * 2)
66−#define EED1_8_STATE_RB_ZIPPED_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
68+#define EED1_8_STATE_RB_ZIPPED_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
6769
6870 #if EED1_8_FC_ENABLE_MEDIAN
6971 /* 1 full input line (GR-R color line) for Yc state */
@@ -72,11 +74,11 @@ · 2 unmodified lines
7274
7375 /* 1 line state per color plane Cg_state */
7476 #define EED1_8_STATE_CG_HEIGHT (1 * NUM_PLANES)
75−#define EED1_8_STATE_CG_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
77+#define EED1_8_STATE_CG_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
7678
7779 /* 1 line state per color plane Co_state */
7880 #define EED1_8_STATE_CO_HEIGHT (1 * NUM_PLANES)
79−#define EED1_8_STATE_CO_WIDTH CEIL_DIV(MAX_FRAME_SIMDWIDTH, 2)
81+#define EED1_8_STATE_CO_WIDTH DIV_ROUND_UP(MAX_FRAME_SIMDWIDTH, 2)
8082
8183 /* 1 full input line (GR-R color line) for AbsK state */
8284 #define EED1_8_STATE_ABSK_HEIGHT 1
drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c+4−2
@@ -4,6 +4,8 @@ · 3 unmodified lines
44 * Copyright (c) 2015, Intel Corporation.
55 */
66
7+#include <linux/math.h>
8+
79 #include <assert_support.h>
810 #include <ia_css_frame_public.h>
911 #include <ia_css_frame.h>
@@ -71,9 +73,9 @@ int ia_css_fpn_configure(const struct ia_css_binary *binary, · 61 unmodified lines
7173 &my_info
7274 };
7375
74− my_info.res.width = CEIL_DIV(info->res.width, 2); /* Packed by 2x */
76+ my_info.res.width = DIV_ROUND_UP(info->res.width, 2); /* Packed by 2x */
7577 my_info.res.height = info->res.height;
76− my_info.padded_width = CEIL_DIV(info->padded_width, 2); /* Packed by 2x */
78+ my_info.padded_width = DIV_ROUND_UP(info->padded_width, 2); /* Packed by 2x */
7779 my_info.format = info->format;
7880 my_info.raw_bit_depth = FPN_BITS_PER_PIXEL;
7981 my_info.raw_bayer_order = info->raw_bayer_order;
drivers/staging/media/atomisp/pci/isp/kernels/sc/sc_1.0/ia_css_sc_param.h+1−1
@@ -22,7 +22,7 @@ struct sh_css_isp_sc_params { · 21 unmodified lines
2222 * vec_slice is used for 2 adjacent vectors of shading gains.
2323 * The number of shift times by vec_slice is 8.
2424 * Max grid cell bqs to support the shading table centerting: N = 32
25− * CEIL_DIV(N-1, ISP_SLICE_NELEMS) = CEIL_DIV(31, 4) = 8
25+ * DIV_ROUND_UP(N-1, ISP_SLICE_NELEMS) = DIV_ROUND_UP(31, 4) = 8
2626 */
2727 #define SH_CSS_SC_INTERPED_GAIN_HOR_SLICE_TIMES 8
2828
drivers/staging/media/atomisp/pci/isp/kernels/vf/vf_1.0/ia_css_vf.host.c+1−2
@@ -91,8 +91,7 @@ configure_kernel( · 90 unmodified lines
9191 unsigned int vf_log_ds = 0;
9292
9393 /* First compute value */
94− if (vf_info)
95− {
94+ if (vf_info) {
9695 err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);
9796 if (err)
9897 return err;
drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h+4−2
@@ -8,9 +8,10 @@ Copyright (c) 2010 - 2015, Intel Corporation. · 7 unmodified lines
88 #ifndef _INPUT_BUF_ISP_H_
99 #define _INPUT_BUF_ISP_H_
1010
11+#include <linux/math.h>
12+
1113 /* Temporary include, since IA_CSS_BINARY_MODE_COPY is still needed */
1214 #include "sh_css_defs.h"
13−#include "isp_const.h" /* MAX_VECTORS_PER_INPUT_LINE */
1415
1516 #define INPUT_BUF_HEIGHT 2 /* double buffer */
1617 #define INPUT_BUF_LINES 2
@@ -22,7 +23,8 @@ Copyright (c) 2010 - 2015, Intel Corporation. · 5 unmodified lines
2223 /* In continuous mode, the input buffer must be a fixed size for all binaries
2324 * and at a fixed address since it will be used by the SP. */
2425 #define EXTRA_INPUT_VECTORS 2 /* For left padding */
25−#define MAX_VECTORS_PER_INPUT_LINE_CONT (CEIL_DIV(SH_CSS_MAX_SENSOR_WIDTH, ISP_NWAY) + EXTRA_INPUT_VECTORS)
26+#define MAX_VECTORS_PER_INPUT_LINE_CONT \
27+ (DIV_ROUND_UP(SH_CSS_MAX_SENSOR_WIDTH, ISP_NWAY) + EXTRA_INPUT_VECTORS)
2628
2729 /* The input buffer should be on a fixed address in vmem, for continuous capture */
2830 #define INPUT_BUF_ADDR 0x0
drivers/staging/media/atomisp/pci/isp/modes/interface/isp_const.h+0−157
@@ -1,157 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−/**
3−Support for Intel Camera Imaging ISP subsystem.
4−Copyright (c) 2010 - 2015, Intel Corporation.
5−
6−*/
7−
8−#ifndef _COMMON_ISP_CONST_H_
9−#define _COMMON_ISP_CONST_H_
10−
11−/*#include "isp.h"*/ /* ISP_VEC_NELEMS */
12−
13−/* Binary independent constants */
14−
15−#ifndef NO_HOIST
16−# define NO_HOIST HIVE_ATTRIBUTE((no_hoist))
17−#endif
18−
19−#define NO_HOIST_CSE HIVE_ATTRIBUTE((no_hoist, no_cse))
20−
21−#define UNION struct /* Union constructors not allowed in C++ */
22−
23−#define XMEM_WIDTH_BITS HIVE_ISP_DDR_WORD_BITS
24−#define XMEM_SHORTS_PER_WORD (HIVE_ISP_DDR_WORD_BITS / 16)
25−#define XMEM_INTS_PER_WORD (HIVE_ISP_DDR_WORD_BITS / 32)
26−#define XMEM_POW2_BYTES_PER_WORD HIVE_ISP_DDR_WORD_BYTES
27−
28−#define BITS8_ELEMENTS_PER_XMEM_ADDR CEIL_DIV(XMEM_WIDTH_BITS, 8)
29−#define BITS16_ELEMENTS_PER_XMEM_ADDR CEIL_DIV(XMEM_WIDTH_BITS, 16)
30−
31−#define ISP_NWAY_LOG2 6
32−
33−/* *****************************
34− * ISP input/output buffer sizes
35− * ****************************/
36−/* input image */
37−#define INPUT_BUF_DMA_HEIGHT 2
38−#define INPUT_BUF_HEIGHT 2 /* double buffer */
39−#define OUTPUT_BUF_DMA_HEIGHT 2
40−#define OUTPUT_BUF_HEIGHT 2 /* double buffer */
41−#define OUTPUT_NUM_TRANSFERS 4
42−
43−/* GDC accelerator: Up/Down Scaling */
44−/* These should be moved to the gdc_defs.h in the device */
45−#define UDS_SCALING_N HRT_GDC_N
46−/* AB: This should cover the zooming up to 16MP */
47−#define UDS_MAX_OXDIM 5000
48−/* We support maximally 2 planes with different parameters
49− - luma and chroma (YUV420) */
50−#define UDS_MAX_PLANES 2
51−#define UDS_BLI_BLOCK_HEIGHT 2
52−#define UDS_BCI_BLOCK_HEIGHT 4
53−#define UDS_BLI_INTERP_ENVELOPE 1
54−#define UDS_BCI_INTERP_ENVELOPE 3
55−#define UDS_MAX_ZOOM_FAC 64
56−/* Make it always one FPGA vector.
57− Four FPGA vectors are required and
58− four of them fit in one ASIC vector.*/
59−#define UDS_MAX_CHUNKS 16
60−
61−#define ISP_LEFT_PADDING _ISP_LEFT_CROP_EXTRA(ISP_LEFT_CROPPING)
62−#define ISP_LEFT_PADDING_VECS CEIL_DIV(ISP_LEFT_PADDING, ISP_VEC_NELEMS)
63−/* in case of continuous the croppong of the current binary doesn't matter for the buffer calculation, but the cropping of the sp copy should be used */
64−#define ISP_LEFT_PADDING_CONT _ISP_LEFT_CROP_EXTRA(SH_CSS_MAX_LEFT_CROPPING)
65−#define ISP_LEFT_PADDING_VECS_CONT CEIL_DIV(ISP_LEFT_PADDING_CONT, ISP_VEC_NELEMS)
66−
67−#define CEIL_ROUND_DIV_STRIPE(width, stripe, padding) \
68− CEIL_MUL(padding + CEIL_DIV(width - padding, stripe), ((ENABLE_RAW_BINNING || ENABLE_FIXED_BAYER_DS) ? 4 : 2))
69−
70−/* output (Y,U,V) image, 4:2:0 */
71−#define MAX_VECTORS_PER_LINE \
72− CEIL_ROUND_DIV_STRIPE(CEIL_DIV(ISP_MAX_INTERNAL_WIDTH, ISP_VEC_NELEMS), \
73− ISP_NUM_STRIPES, \
74− ISP_LEFT_PADDING_VECS)
75−
76−/*
77− * ITERATOR_VECTOR_INCREMENT' explanation:
78− * when striping an even number of iterations, one of the stripes is
79− * one iteration wider than the other to account for overlap
80− * so the calc for the output buffer vmem size is:
81− * ((width[vectors]/num_of_stripes) + 2[vectors])
82− */
83−#define MAX_VECTORS_PER_OUTPUT_LINE \
84− CEIL_DIV(CEIL_DIV(ISP_MAX_OUTPUT_WIDTH, ISP_NUM_STRIPES) + ISP_LEFT_PADDING, ISP_VEC_NELEMS)
85−
86−/* Must be even due to interlaced bayer input */
87−#define MAX_VECTORS_PER_INPUT_LINE CEIL_MUL((CEIL_DIV(ISP_MAX_INPUT_WIDTH, ISP_VEC_NELEMS) + ISP_LEFT_PADDING_VECS), 2)
88−#define MAX_VECTORS_PER_INPUT_STRIPE CEIL_ROUND_DIV_STRIPE(MAX_VECTORS_PER_INPUT_LINE, \
89− ISP_NUM_STRIPES, \
90− ISP_LEFT_PADDING_VECS)
91−
92−/* Add 2 for left croppping */
93−#define MAX_SP_RAW_COPY_VECTORS_PER_INPUT_LINE (CEIL_DIV(ISP_MAX_INPUT_WIDTH, ISP_VEC_NELEMS) + 2)
94−
95−#define MAX_VECTORS_PER_BUF_LINE \
96− (MAX_VECTORS_PER_LINE + DUMMY_BUF_VECTORS)
97−#define MAX_VECTORS_PER_BUF_INPUT_LINE \
98− (MAX_VECTORS_PER_INPUT_STRIPE + DUMMY_BUF_VECTORS)
99−#define MAX_OUTPUT_Y_FRAME_WIDTH \
100− (MAX_VECTORS_PER_LINE * ISP_VEC_NELEMS)
101−#define MAX_OUTPUT_Y_FRAME_SIMDWIDTH \
102− MAX_VECTORS_PER_LINE
103−#define MAX_OUTPUT_C_FRAME_WIDTH \
104− (MAX_OUTPUT_Y_FRAME_WIDTH / 2)
105−#define MAX_OUTPUT_C_FRAME_SIMDWIDTH \
106− CEIL_DIV(MAX_OUTPUT_C_FRAME_WIDTH, ISP_VEC_NELEMS)
107−
108−/* should be even */
109−#define NO_CHUNKING (OUTPUT_NUM_CHUNKS == 1)
110−
111−#define MAX_VECTORS_PER_CHUNK \
112− (NO_CHUNKING ? MAX_VECTORS_PER_LINE \
113− : 2 * CEIL_DIV(MAX_VECTORS_PER_LINE, \
114− 2 * OUTPUT_NUM_CHUNKS))
115−
116−#define MAX_C_VECTORS_PER_CHUNK \
117− (MAX_VECTORS_PER_CHUNK / 2)
118−
119−/* should be even */
120−#define MAX_VECTORS_PER_OUTPUT_CHUNK \
121− (NO_CHUNKING ? MAX_VECTORS_PER_OUTPUT_LINE \
122− : 2 * CEIL_DIV(MAX_VECTORS_PER_OUTPUT_LINE, \
123− 2 * OUTPUT_NUM_CHUNKS))
124−
125−#define MAX_C_VECTORS_PER_OUTPUT_CHUNK \
126− (MAX_VECTORS_PER_OUTPUT_CHUNK / 2)
127−
128−/* should be even */
129−#define MAX_VECTORS_PER_INPUT_CHUNK \
130− (INPUT_NUM_CHUNKS == 1 ? MAX_VECTORS_PER_INPUT_STRIPE \
131− : 2 * CEIL_DIV(MAX_VECTORS_PER_INPUT_STRIPE, \
132− 2 * OUTPUT_NUM_CHUNKS))
133−
134−#define DEFAULT_C_SUBSAMPLING 2
135−
136−/****** DMA buffer properties */
137−
138−#define RAW_BUF_LINES ((ENABLE_RAW_BINNING || ENABLE_FIXED_BAYER_DS) ? 4 : 2)
139−
140−/* [isp vmem] table size[vectors] per line per color (GR,R,B,GB),
141− multiples of NWAY */
142−#define ISP2400_SCTBL_VECTORS_PER_LINE_PER_COLOR \
143− CEIL_DIV(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
144−#define ISP2401_SCTBL_VECTORS_PER_LINE_PER_COLOR \
145− CEIL_DIV(SH_CSS_MAX_SCTBL_WIDTH_PER_COLOR, ISP_VEC_NELEMS)
146−/* [isp vmem] table size[vectors] per line for 4colors (GR,R,B,GB),
147− multiples of NWAY */
148−#define SCTBL_VECTORS_PER_LINE \
149− (SCTBL_VECTORS_PER_LINE_PER_COLOR * IA_CSS_SC_NUM_COLORS)
150−
151−/*************/
152−
153−/* Format for fixed primaries */
154−
155−#define ISP_FIXED_PRIMARY_FORMAT IA_CSS_FRAME_FORMAT_NV12
156−
157−#endif /* _COMMON_ISP_CONST_H_ */
drivers/staging/media/atomisp/pci/runtime/debug/src/ia_css_debug.c+0−1
@@ -51,7 +51,6 @@ · 50 unmodified lines
5151 #include "sp.h"
5252 #include "isp.h"
5353 #include "type_support.h"
54−#include "math_support.h" /* CEIL_DIV */
5554 #include "input_system.h" /* input_formatter_reg_load */
5655 #include "ia_css_tagger_common.h"
5756
drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c+15−14
@@ -4,15 +4,16 @@ · 3 unmodified lines
44 * Copyright (c) 2015, Intel Corporation.
55 */
66
7−#include "hmm.h"
7+#include <linux/bitops.h>
8+#include <linux/math.h>
89
9−#include "ia_css_frame.h"
10−#include <math_support.h>
1110 #include "assert_support.h"
11+#include "atomisp_internal.h"
12+#include "hmm.h"
1213 #include "ia_css_debug.h"
14+#include "ia_css_frame.h"
1315 #include "isp.h"
1416 #include "sh_css_internal.h"
15−#include "atomisp_internal.h"
1617
1718 #define NV12_TILEY_TILE_WIDTH 128
1819 #define NV12_TILEY_TILE_HEIGHT 32
@@ -459,15 +460,16 @@ static void frame_init_single_plane(struct ia_css_frame *frame, · 440 unmodified lines
459460 unsigned int stride;
460461
461462 stride = subpixels_per_line * bytes_per_pixel;
462− /* Frame height needs to be even number - needed by hw ISYS2401
463− In case of odd number, round up to even.
464− Images won't be impacted by this round up,
465− only needed by jpeg/embedded data.
466− As long as buffer allocation and release are using data_bytes,
467− there won't be memory leak. */
468− frame->data_bytes = stride * CEIL_MUL2(height, 2);
463+ /*
464+ * Frame height needs to be even number - needed by hw ISYS2401.
465+ * In case of odd number, round up to even.
466+ * Images won't be impacted by this round up,
467+ * only needed by jpeg/embedded data.
468+ * As long as buffer allocation and release are using data_bytes,
469+ * there won't be memory leak.
470+ */
471+ frame->data_bytes = stride * round_up(height, 2);
469472 frame_init_plane(plane, subpixels_per_line, stride, height, 0);
470− return;
471473 }
472474
473475 static void frame_init_raw_single_plane(
@@ -486,7 +488,6 @@ static void frame_init_raw_single_plane( · 12 unmodified lines
486488 HIVE_ISP_DDR_WORD_BITS / bits_per_pixel);
487489 frame->data_bytes = stride * height;
488490 frame_init_plane(plane, subpixels_per_line, stride, height, 0);
489− return;
490491 }
491492
492493 static void frame_init_nv_planes(struct ia_css_frame *frame,
@@ -690,7 +691,7 @@ ia_css_elems_bytes_from_info(const struct ia_css_frame_info *info) · 197 unmodified lines
690691 if (info->format == IA_CSS_FRAME_FORMAT_RAW
691692 || (info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED)) {
692693 if (info->raw_bit_depth)
693− return CEIL_DIV(info->raw_bit_depth, 8);
694+ return BITS_TO_BYTES(info->raw_bit_depth);
694695 else
695696 return 2; /* bytes per pixel */
696697 }
drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c+5−6
@@ -4,9 +4,9 @@ · 3 unmodified lines
44 * Copyright (c) 2010 - 2015, Intel Corporation.
55 */
66
7−#include "system_global.h"
8−#include <linux/kernel.h>
7+#include <linux/math.h>
98
9+#include "system_global.h"
1010
1111 #include "ia_css_ifmtr.h"
1212 #include <math_support.h>
@@ -149,10 +149,9 @@ int ia_css_ifmtr_configure(struct ia_css_stream_config *config, · 136 unmodified lines
149149 left_padding = 2 * ISP_VEC_NELEMS - config->left_padding;
150150
151151 if (left_padding) {
152− num_vectors = CEIL_DIV(cropped_width + left_padding,
153− ISP_VEC_NELEMS);
152+ num_vectors = DIV_ROUND_UP(cropped_width + left_padding, ISP_VEC_NELEMS);
154153 } else {
155− num_vectors = CEIL_DIV(cropped_width, ISP_VEC_NELEMS);
154+ num_vectors = DIV_ROUND_UP(cropped_width, ISP_VEC_NELEMS);
156155 num_vectors *= buffer_height;
157156 /* todo: in case of left padding,
158157 num_vectors is vectors per line,
@@ -305,7 +304,7 @@ int ia_css_ifmtr_configure(struct ia_css_stream_config *config, · 146 unmodified lines
305304 if ((!binary) || config->continuous)
306305 /* !binary -> sp raw copy pipe */
307306 buffer_height *= 2;
308− vectors_per_line = CEIL_DIV(cropped_width, ISP_VEC_NELEMS);
307+ vectors_per_line = DIV_ROUND_UP(cropped_width, ISP_VEC_NELEMS);
309308 vectors_per_line = CEIL_MUL(vectors_per_line, deinterleaving);
310309 break;
311310 case ATOMISP_INPUT_FORMAT_RAW_14:
drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c+1−1
@@ -808,7 +808,7 @@ static bool calculate_isys2401_dma_port_cfg( · 807 unmodified lines
808808
809809 cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
810810 cfg->cropping = 0;
811− cfg->width = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES);
811+ cfg->width = DIV_ROUND_UP(cfg->stride, HIVE_ISP_DDR_WORD_BYTES);
812812
813813 return true;
814814 }
drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h+0−1
@@ -34,7 +34,6 @@ struct ia_css_pipeline_stage { · 33 unmodified lines
3434 struct ia_css_pipeline {
3535 enum ia_css_pipe_id pipe_id;
3636 u8 pipe_num;
37− bool stop_requested;
3837 struct ia_css_pipeline_stage *stages;
3938 struct ia_css_pipeline_stage *current_stage;
4039 unsigned int num_stages;
drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c+0−2
@@ -198,7 +198,6 @@ int ia_css_pipeline_request_stop(struct ia_css_pipeline *pipeline) · 197 unmodified lines
198198 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
199199 "ia_css_pipeline_request_stop() enter: pipeline=%p\n",
200200 pipeline);
201− pipeline->stop_requested = true;
202201
203202 /* Send stop event to the sp*/
204203 /* This needs improvement, stop on all the pipes available
@@ -663,7 +662,6 @@ static void pipeline_init_defaults( · 458 unmodified lines
663662
664663 pipeline->pipe_id = pipe_id;
665664 pipeline->stages = NULL;
666− pipeline->stop_requested = false;
667665 pipeline->current_stage = NULL;
668666
669667 memcpy(&pipeline->in_frame, &ia_css_default_frame,
drivers/staging/media/atomisp/pci/sh_css.c+0−27
@@ -2002,10 +2002,6 @@ ia_css_uninit(void) · 2001 unmodified lines
20022002
20032003 sh_css_params_free_default_gdc_lut();
20042004
2005− /* TODO: JB: implement decent check and handling of freeing mipi frames */
2006− if (!mipi_is_free())
2007− dev_warn(atomisp_dev, "mipi frames are not freed.\n");
2008−
20092005 /* cleanup generic data */
20102006 sh_css_params_uninit();
20112007 ia_css_refcount_uninit();
@@ -3743,23 +3739,6 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, · 1731 unmodified lines
37433739 case IA_CSS_BUFFER_TYPE_INPUT_FRAME:
37443740 case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:
37453741 case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
3746− if (pipe && pipe->stop_requested) {
3747− if (!IS_ISP2401) {
3748− /*
3749− * free mipi frames only for old input
3750− * system for 2401 it is done in
3751− * ia_css_stream_destroy call
3752− */
3753− return_err = free_mipi_frames(pipe);
3754− if (return_err) {
3755− IA_CSS_LOG("free_mipi_frames() failed");
3756− IA_CSS_LEAVE_ERR(return_err);
3757− return return_err;
3758− }
3759− }
3760− pipe->stop_requested = false;
3761− }
3762− fallthrough;
37633742 case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME:
37643743 case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
37653744 frame = (struct ia_css_frame *)HOST_ADDRESS(ddr_buffer.kernel_ptr);
@@ -4095,8 +4074,6 @@ sh_css_pipe_start(struct ia_css_stream *stream) · 329 unmodified lines
40954074 return err;
40964075 }
40974076
4098− pipe->stop_requested = false;
4099−
41004077 switch (pipe_id) {
41014078 case IA_CSS_PIPE_ID_PREVIEW:
41024079 err = preview_start(pipe);
@@ -4120,19 +4097,15 @@ sh_css_pipe_start(struct ia_css_stream *stream) · 17 unmodified lines
41204097 for (i = 1; i < stream->num_pipes && 0 == err ; i++) {
41214098 switch (stream->pipes[i]->mode) {
41224099 case IA_CSS_PIPE_ID_PREVIEW:
4123− stream->pipes[i]->stop_requested = false;
41244100 err = preview_start(stream->pipes[i]);
41254101 break;
41264102 case IA_CSS_PIPE_ID_VIDEO:
4127− stream->pipes[i]->stop_requested = false;
41284103 err = video_start(stream->pipes[i]);
41294104 break;
41304105 case IA_CSS_PIPE_ID_CAPTURE:
4131− stream->pipes[i]->stop_requested = false;
41324106 err = capture_start(stream->pipes[i]);
41334107 break;
41344108 case IA_CSS_PIPE_ID_YUVPP:
4135− stream->pipes[i]->stop_requested = false;
41364109 err = yuvpp_start(stream->pipes[i]);
41374110 break;
41384111 default:
drivers/staging/media/atomisp/pci/sh_css_defs.h+6−6
@@ -7,12 +7,12 @@ · 6 unmodified lines
77 #ifndef _SH_CSS_DEFS_H_
88 #define _SH_CSS_DEFS_H_
99
10+#include <linux/math.h>
11+
1012 #include "isp.h"
1113
1214 /*#include "vamem.h"*/ /* Cannot include for VAMEM properties this file is visible on ISP -> pipeline generator */
1315
14−#include "math_support.h" /* max(), min, etc etc */
15−
1616 /* ID's for refcount */
1717 #define IA_CSS_REFCOUNT_PARAM_SET_POOL 0xCAFE0001
1818 #define IA_CSS_REFCOUNT_PARAM_BUFFER 0xCAFE0002
@@ -182,7 +182,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] · 163 unmodified lines
182182 The ISP firmware needs these rules to be applied at pre-processor time,
183183 that's why these are macros, not functions. */
184184 #define _ISP_BQS(num) ((num) / 2)
185−#define _ISP_VECS(width) CEIL_DIV(width, ISP_VEC_NELEMS)
185+#define _ISP_VECS(width) DIV_ROUND_UP(width, ISP_VEC_NELEMS)
186186
187187 #define ISP_BQ_GRID_WIDTH(elements_per_line, deci_factor_log2) \
188188 CEIL_SHIFT(elements_per_line / 2, deci_factor_log2)
@@ -194,9 +194,9 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] · 5 unmodified lines
194194 /* The morphing table is similar to the shading table in the sense that we
195195 have 1 more value than we have cells in the grid. */
196196 #define _ISP_MORPH_TABLE_WIDTH(int_width) \
197− (CEIL_DIV(int_width, SH_CSS_MORPH_TABLE_GRID) + 1)
197+ (DIV_ROUND_UP(int_width, SH_CSS_MORPH_TABLE_GRID) + 1)
198198 #define _ISP_MORPH_TABLE_HEIGHT(int_height) \
199− (CEIL_DIV(int_height, SH_CSS_MORPH_TABLE_GRID) + 1)
199+ (DIV_ROUND_UP(int_height, SH_CSS_MORPH_TABLE_GRID) + 1)
200200 #define _ISP_MORPH_TABLE_ALIGNED_WIDTH(width) \
201201 CEIL_MUL(_ISP_MORPH_TABLE_WIDTH(width), \
202202 SH_CSS_MORPH_TABLE_ELEMS_PER_DDR_WORD)
@@ -298,7 +298,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] · 95 unmodified lines
298298 c_subsampling, \
299299 num_chunks, \
300300 pipelining) \
301− CEIL_MUL2(CEIL_MUL2(MAX(__ISP_PADDED_OUTPUT_WIDTH(out_width, \
301+ round_up(round_up(MAX(__ISP_PADDED_OUTPUT_WIDTH(out_width, \
302302 dvs_env_width, \
303303 left_crop), \
304304 __ISP_MIN_INTERNAL_WIDTH(num_chunks, \
drivers/staging/media/atomisp/pci/sh_css_internal.h+3−5
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #define _SH_CSS_INTERNAL_H_
99
1010 #include <linux/build_bug.h>
11+#include <linux/math.h>
1112 #include <linux/stdarg.h>
1213
1314 #include <system_global.h>
@@ -95,7 +96,6 @@ · 81 unmodified lines
9596 * the SIZE_OF_XXX macro of the corresponding struct. If they are not
9697 * equal, functionality will break.
9798 */
98−#define CALC_ALIGNMENT_MEMBER(x, y) (CEIL_MUL(x, y) - x)
9999 #define SIZE_OF_HRT_VADDRESS sizeof(hive_uint32)
100100
101101 /* Number of SP's */
@@ -704,13 +704,11 @@ struct sh_css_hmm_buffer { · 602 unmodified lines
704704
705705 /* Do not use sizeof(uint64_t) since that does not exist of SP */
706706 #define SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT \
707− (SIZE_OF_PAYLOAD_UNION + \
708− CALC_ALIGNMENT_MEMBER(SIZE_OF_PAYLOAD_UNION, 8) + \
707+ (round_up(SIZE_OF_PAYLOAD_UNION, 8) + \
709708 8 + \
710709 8 + \
711710 SIZE_OF_IA_CSS_TIME_MEAS_STRUCT + \
712− SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT + \
713− CALC_ALIGNMENT_MEMBER(SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT, 8))
711+ round_up(SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT, 8))
714712
715713 static_assert(sizeof(struct sh_css_hmm_buffer) == SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT);
716714
drivers/staging/media/atomisp/pci/sh_css_mipi.c+0−11
@@ -185,17 +185,6 @@ mipi_init(void) · 184 unmodified lines
185185 ref_count_mipi_allocation[i] = 0;
186186 }
187187
188−bool mipi_is_free(void)
189−{
190− unsigned int i;
191−
192− for (i = 0; i < N_CSI_PORTS; i++)
193− if (ref_count_mipi_allocation[i])
194− return false;
195−
196− return true;
197−}
198−
199188 /*
200189 * @brief Calculate the required MIPI buffer sizes.
201190 * Based on the stream configuration, calculate the
drivers/staging/media/atomisp/pci/sh_css_mipi.h+0−2
@@ -14,8 +14,6 @@ · 13 unmodified lines
1414 void
1515 mipi_init(void);
1616
17−bool mipi_is_free(void);
18−
1917 int
2018 allocate_mipi_frames(struct ia_css_pipe *pipe, struct ia_css_stream_info *info);
2119
drivers/staging/media/atomisp/pci/sh_css_param_dvs.h+11−11
@@ -7,6 +7,8 @@ · 6 unmodified lines
77 #ifndef _SH_CSS_PARAMS_DVS_H_
88 #define _SH_CSS_PARAMS_DVS_H_
99
10+#include <linux/math.h>
11+
1012 #include <math_support.h>
1113 #include <ia_css_types.h>
1214 #include "gdc_global.h" /* gdc_warp_param_mem_t */
@@ -20,22 +22,20 @@ · 7 unmodified lines
2022
2123 /* ISP2400 */
2224 /* horizontal 64x64 blocks round up to DVS_BLOCKDIM_X, make even */
23−#define DVS_NUM_BLOCKS_X(X) (CEIL_MUL(CEIL_DIV((X), DVS_BLOCKDIM_X), 2))
25+#define DVS_NUM_BLOCKS_X(X) round_up(DIV_ROUND_UP((X), DVS_BLOCKDIM_X), 2)
26+#define DVS_NUM_BLOCKS_X_CHROMA(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_X)
2427
2528 /* ISP2400 */
2629 /* vertical 64x64 blocks round up to DVS_BLOCKDIM_Y */
27−#define DVS_NUM_BLOCKS_Y(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_LUMA))
28−#define DVS_NUM_BLOCKS_X_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_X))
29−#define DVS_NUM_BLOCKS_Y_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_CHROMA))
30+#define DVS_NUM_BLOCKS_Y(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_Y_LUMA)
31+#define DVS_NUM_BLOCKS_Y_CHROMA(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_Y_CHROMA)
3032
31−#define DVS_TABLE_IN_BLOCKDIM_X_LUMA(X) (DVS_NUM_BLOCKS_X(X) + 1) /* N blocks have N + 1 set of coords */
32−#define DVS_TABLE_IN_BLOCKDIM_X_CHROMA(X) (DVS_NUM_BLOCKS_X_CHROMA(X) + 1)
33+/* N blocks have N + 1 set of coords */
34+#define DVS_TABLE_IN_BLOCKDIM_X_LUMA(X) (DVS_NUM_BLOCKS_X(X) + 1)
35+#define DVS_TABLE_IN_BLOCKDIM_X_CHROMA(X) (DVS_NUM_BLOCKS_X_CHROMA(X) + 1)
3336 #define DVS_TABLE_IN_BLOCKDIM_Y_LUMA(X) (DVS_NUM_BLOCKS_Y(X) + 1)
3437 #define DVS_TABLE_IN_BLOCKDIM_Y_CHROMA(X) (DVS_NUM_BLOCKS_Y_CHROMA(X) + 1)
3538
36−#define DVS_ENVELOPE_X(X) (((X) == 0) ? (DVS_ENV_MIN_X) : (X))
37−#define DVS_ENVELOPE_Y(X) (((X) == 0) ? (DVS_ENV_MIN_Y) : (X))
38−
3939 #define DVS_COORD_FRAC_BITS (10)
4040
4141 /* ISP2400 */
@@ -43,8 +43,8 @@ · 1 unmodified line
4343
4444 #define XMEM_ALIGN_LOG2 (5)
4545
46−#define DVS_6AXIS_COORDS_ELEMS CEIL_MUL(sizeof(gdc_warp_param_mem_t) \
47− , HIVE_ISP_DDR_WORD_BYTES)
46+#define DVS_6AXIS_COORDS_ELEMS \
47+ round_up(sizeof(gdc_warp_param_mem_t), HIVE_ISP_DDR_WORD_BYTES)
4848
4949 /* currently we only support two output with the same resolution, output 0 is th default one. */
5050 #define DVS_6AXIS_BYTES(binary) \
drivers/staging/media/atomisp/pci/sh_css_params.c+6−6
@@ -4,6 +4,8 @@ · 3 unmodified lines
44 * Copyright (c) 2015, Intel Corporation.
55 */
66
7+#include <linux/math.h>
8+
79 #include "gdc_device.h" /* gdc_lut_store(), ... */
810 #include "isp.h" /* ISP_VEC_ELEMBITS */
911 #include "vamem.h"
@@ -21,8 +23,6 @@ · 11 unmodified lines
2123
2224 #include "platform_support.h"
2325 #include "assert_support.h"
24−#include "misc_support.h" /* NOT_USED */
25−#include "math_support.h" /* max(), min() EVEN_FLOOR()*/
2626
2727 #include "ia_css_stream.h"
2828 #include "sh_css_params_internal.h"
@@ -4042,10 +4042,10 @@ sh_css_update_uds_and_crop_info( · 4013 unmodified lines
40424042 }
40434043
40444044 /* Must enforce that the crop position is even */
4045− crop_x = EVEN_FLOOR(crop_x);
4046− crop_y = EVEN_FLOOR(crop_y);
4047− uds_xc = EVEN_FLOOR(uds_xc);
4048− uds_yc = EVEN_FLOOR(uds_yc);
4045+ crop_x = round_down(crop_x, 2);
4046+ crop_y = round_down(crop_y, 2);
4047+ uds_xc = round_down(uds_xc, 2);
4048+ uds_yc = round_down(uds_yc, 2);
40494049
40504050 uds->xc = (uint16_t)uds_xc;
40514051 uds->yc = (uint16_t)uds_yc;
drivers/staging/media/imx/imx-media-csc-scaler.c+1−1
@@ -912,7 +912,7 @@ imx_media_csc_scaler_device_init(struct imx_media_dev *md) · 911 unmodified lines
912912 return &priv->vdev;
913913
914914 err_m2m:
915− video_set_drvdata(vfd, NULL);
915+ video_device_release(vfd);
916916 err_vfd:
917917 kfree(priv);
918918 return ERR_PTR(ret);
drivers/staging/media/ipu7/Kconfig+19−0
@@ -0,0 +1,19 @@
1+config VIDEO_INTEL_IPU7
2+ tristate "Intel IPU7 driver"
3+ depends on ACPI || COMPILE_TEST
4+ depends on VIDEO_DEV
5+ depends on X86 && HAS_DMA
6+ depends on IPU_BRIDGE || !IPU_BRIDGE
7+ depends on PCI
8+ select AUXILIARY_BUS
9+ select IOMMU_IOVA
10+ select VIDEO_V4L2_SUBDEV_API
11+ select MEDIA_CONTROLLER
12+ select VIDEOBUF2_DMA_SG
13+ select V4L2_FWNODE
14+ help
15+ This is the 7th Gen Intel Image Processing Unit, found in Intel SoCs
16+ and used for capturing images and video from camera sensors.
17+
18+ To compile this driver, say Y here! It contains 2 modules -
19+ intel_ipu7 and intel_ipu7_isys.
drivers/staging/media/ipu7/Makefile+23−0
@@ -0,0 +1,23 @@
1+# SPDX-License-Identifier: GPL-2.0
2+# Copyright (c) 2017 - 2025 Intel Corporation.
3+
4+intel-ipu7-objs += ipu7.o \
5+ ipu7-bus.o \
6+ ipu7-dma.o \
7+ ipu7-mmu.o \
8+ ipu7-buttress.o \
9+ ipu7-cpd.o \
10+ ipu7-syscom.o \
11+ ipu7-boot.o
12+
13+obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7.o
14+
15+intel-ipu7-isys-objs += ipu7-isys.o \
16+ ipu7-isys-csi2.o \
17+ ipu7-isys-csi-phy.o \
18+ ipu7-fw-isys.o \
19+ ipu7-isys-video.o \
20+ ipu7-isys-queue.o \
21+ ipu7-isys-subdev.o
22+
23+obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7-isys.o
drivers/staging/media/ipu7/TODO+28−0
@@ -0,0 +1,28 @@
1+This is a list of things that need to be done to get this driver out of the
2+staging directory.
3+
4+- ABI headers cleanup
5+ Cleanup the firmware ABI headers
6+
7+- Add metadata capture support
8+ The IPU7 hardware should support metadata capture, but it is not
9+ fully verified with IPU7 firmware ABI so far, need to add the metadata
10+ capture support.
11+
12+- Refine CSI2 PHY code
13+ Refine the ipu7-isys-csi2-phy.c, move the hardware specific variant
14+ into structure, clarify and explain the PHY registers to make it more
15+ readable.
16+
17+- Work with the common IPU module
18+ Sakari commented much of the driver code is the same than the IPU6 driver.
19+ IPU7 driver is expected to work with the common IPU module in future.
20+
21+- Register definition cleanup
22+ Cleanup the register definitions - remove some unnecessary definitions
23+ remove 'U' suffix for hexadecimal and decimal values and add IPU7 prefix
24+ for IPU7 specific registers.
25+ Some ISYS IO sub-blocks register definitions are offset values from
26+ specific sub-block base, but it is not clear and well suited for driver
27+ to use, need to update the register definitions to make it more clear
28+ and readable.
drivers/staging/media/ipu7/abi/ipu7_fw_boot_abi.h+163−0
@@ -0,0 +1,163 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 - 2025 Intel Corporation
4+ */
5+
6+#ifndef IPU7_FW_BOOT_ABI_H
7+#define IPU7_FW_BOOT_ABI_H
8+
9+#include "ipu7_fw_common_abi.h"
10+#include "ipu7_fw_syscom_abi.h"
11+
12+#define IA_GOFO_FWLOG_SEVERITY_CRIT (0U)
13+#define IA_GOFO_FWLOG_SEVERITY_ERROR (1U)
14+#define IA_GOFO_FWLOG_SEVERITY_WARNING (2U)
15+#define IA_GOFO_FWLOG_SEVERITY_INFO (3U)
16+#define IA_GOFO_FWLOG_SEVERITY_DEBUG (4U)
17+#define IA_GOFO_FWLOG_SEVERITY_VERBOSE (5U)
18+#define IA_GOFO_FWLOG_MAX_LOGGER_SOURCES (64U)
19+
20+#define LOGGER_CONFIG_CHANNEL_ENABLE_HWPRINTF_BITMASK BIT(0)
21+#define LOGGER_CONFIG_CHANNEL_ENABLE_SYSCOM_BITMASK BIT(1)
22+#define LOGGER_CONFIG_CHANNEL_ENABLE_ALL_BITMASK \
23+ (LOGGER_CONFIG_CHANNEL_ENABLE_HWPRINTF_BITMASK | \
24+ LOGGER_CONFIG_CHANNEL_ENABLE_SYSCOM_BITMASK)
25+
26+struct ia_gofo_logger_config {
27+ u8 use_source_severity;
28+ u8 source_severity[IA_GOFO_FWLOG_MAX_LOGGER_SOURCES];
29+ u8 use_channels_enable_bitmask;
30+ u8 channels_enable_bitmask;
31+ u8 padding[1];
32+ ia_gofo_addr_t hw_printf_buffer_base_addr;
33+ u32 hw_printf_buffer_size_bytes;
34+};
35+
36+#pragma pack(push, 1)
37+
38+#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP \
39+ ((u32)IA_GOFO_FW_BOOT_ID_MAX)
40+#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_IS_OFFSET (0U)
41+#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_PS_OFFSET \
42+ ((IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_IS_OFFSET) + \
43+ (u32)(IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP))
44+#define IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_PRIMARY_OFFSET (0U)
45+#define IA_GOFO_CCG_IPU_BUTTRESS_FW_BOOT_PARAMS_SECONDARY_OFFSET (0x3000U / 4U)
46+#define IA_GOFO_HKR_IPU_BUTTRESS_FW_BOOT_PARAMS_SECONDARY_OFFSET \
47+ (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP * 2U)
48+#define IA_GOFO_HKR_HIF_BUTTRESS_FW_BOOT_PARAMS_SECONDARY_OFFSET \
49+ (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP)
50+#define IA_GOFO_CCG_IPU_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX \
51+ (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP * 4U)
52+#define IA_GOFO_HKR_IPU_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX \
53+ (IA_GOFO_BUTTRESS_FW_BOOT_PARAMS_MAX_REG_IDX_PER_APP * 4U)
54+
55+#define IA_GOFO_BOOT_RESERVED_SIZE (58U)
56+#define IA_GOFO_BOOT_SECONDARY_RESERVED_SIZE (IA_GOFO_BOOT_RESERVED_SIZE)
57+#define IA_GOFO_BOOT_SECONDARY_RESERVED_FIELDS \
58+ (sizeof(ia_gofo_addr_t) + sizeof(ia_gofo_addr_t) + sizeof(u32))
59+
60+enum ia_gofo_buttress_reg_id {
61+ IA_GOFO_FW_BOOT_CONFIG_ID = 0,
62+ IA_GOFO_FW_BOOT_STATE_ID = 1,
63+ IA_GOFO_FW_BOOT_RESERVED1_ID = IA_GOFO_FW_BOOT_STATE_ID,
64+ IA_GOFO_FW_BOOT_SYSCOM_QUEUE_INDICES_BASE_ID = 2,
65+ IA_GOFO_FW_BOOT_UNTRUSTED_ADDR_MIN_ID = 3,
66+ IA_GOFO_FW_BOOT_RESERVED0_ID = IA_GOFO_FW_BOOT_UNTRUSTED_ADDR_MIN_ID,
67+ IA_GOFO_FW_BOOT_MESSAGING_VERSION_ID = 4,
68+ IA_GOFO_FW_BOOT_ID_MAX
69+};
70+
71+enum ia_gofo_boot_uc_tile_frequency_units {
72+ IA_GOFO_FW_BOOT_UC_FREQUENCY_UNITS_MHZ = 0,
73+ IA_GOFO_FW_BOOT_UC_FREQUENCY_UNITS_HZ = 1,
74+ IA_GOFO_FW_BOOT_UC_FREQUENCY_UNITS_N
75+};
76+
77+#define IA_GOFO_FW_BOOT_STATE_IS_CRITICAL(boot_state) \
78+ (0xdead0000U == ((boot_state) & 0xffff0000U))
79+
80+struct ia_gofo_boot_config {
81+ u32 length;
82+ struct ia_gofo_version_s config_version;
83+ struct ia_gofo_msg_version_list client_version_support;
84+ ia_gofo_addr_t pkg_dir;
85+ ia_gofo_addr_t subsys_config;
86+ u32 uc_tile_frequency;
87+ u16 checksum;
88+ u8 uc_tile_frequency_units;
89+ u8 padding[1];
90+ u32 reserved[IA_GOFO_BOOT_RESERVED_SIZE];
91+ struct syscom_config_s syscom_context_config;
92+};
93+
94+struct ia_gofo_secondary_boot_config {
95+ u32 length;
96+ struct ia_gofo_version_s config_version;
97+ struct ia_gofo_msg_version_list client_version_support;
98+ u8 reserved1[IA_GOFO_BOOT_SECONDARY_RESERVED_FIELDS];
99+ u16 checksum;
100+ u8 padding[2];
101+ u32 reserved2[IA_GOFO_BOOT_SECONDARY_RESERVED_SIZE];
102+ struct syscom_config_s syscom_context_config;
103+};
104+
105+#pragma pack(pop)
106+
107+#define IA_GOFO_WDT_TIMEOUT_ERR 0xdead0401U
108+#define IA_GOFO_MEM_FATAL_DME_ERR 0xdead0801U
109+#define IA_GOFO_MEM_UNCORRECTABLE_LOCAL_ERR 0xdead0802U
110+#define IA_GOFO_MEM_UNCORRECTABLE_DIRTY_ERR 0xdead0803U
111+#define IA_GOFO_MEM_UNCORRECTABLE_DTAG_ERR 0xdead0804U
112+#define IA_GOFO_MEM_UNCORRECTABLE_CACHE_ERR 0xdead0805U
113+#define IA_GOFO_DOUBLE_EXCEPTION_ERR 0xdead0806U
114+#define IA_GOFO_BIST_DMEM_FAULT_DETECTION_ERR 0xdead1000U
115+#define IA_GOFO_BIST_DATA_INTEGRITY_FAILURE 0xdead1010U
116+
117+enum ia_gofo_boot_state {
118+ IA_GOFO_FW_BOOT_STATE_SECONDARY_BOOT_CONFIG_READY = 0x57a7b000U,
119+ IA_GOFO_FW_BOOT_STATE_UNINIT = 0x57a7e000U,
120+ IA_GOFO_FW_BOOT_STATE_STARTING_0 = 0x57a7d000U,
121+ IA_GOFO_FW_BOOT_STATE_CACHE_INIT_DONE = 0x57a7d010U,
122+ IA_GOFO_FW_BOOT_STATE_MEM_INIT_DONE = 0x57a7d020U,
123+ IA_GOFO_FW_BOOT_STATE_STACK_INIT_DONE = 0x57a7d030U,
124+ IA_GOFO_FW_BOOT_STATE_EARLY_BOOT_DONE = 0x57a7d100U,
125+ IA_GOFO_FW_BOOT_STATE_BOOT_CONFIG_START = 0x57a7d200U,
126+ IA_GOFO_FW_BOOT_STATE_QUEUE_INIT_DONE = 0x57a7d300U,
127+ IA_GOFO_FW_BOOT_STATE_READY = 0x57a7e100U,
128+ IA_GOFO_FW_BOOT_STATE_CRIT_UNSPECIFIED = 0xdead0001U,
129+ IA_GOFO_FW_BOOT_STATE_CRIT_CFG_PTR = 0xdead0101U,
130+ IA_GOFO_FW_BOOT_STATE_CRIT_CFG_VERSION = 0xdead0201U,
131+ IA_GOFO_FW_BOOT_STATE_CRIT_MSG_VERSION = 0xdead0301U,
132+ IA_GOFO_FW_BOOT_STATE_CRIT_WDT_TIMEOUT = IA_GOFO_WDT_TIMEOUT_ERR,
133+ IA_GOFO_FW_BOOT_STATE_WRONG_DATA_SECTION_UNPACKING = 0xdead0501U,
134+ IA_GOFO_FW_BOOT_STATE_WRONG_RO_DATA_SECTION_UNPACKING = 0xdead0601U,
135+ IA_GOFO_FW_BOOT_STATE_INVALID_UNTRUSTED_ADDR_MIN = 0xdead0701U,
136+ IA_GOFO_FW_BOOT_STATE_CRIT_MEM_FATAL_DME = IA_GOFO_MEM_FATAL_DME_ERR,
137+ IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_LOCAL =
138+ IA_GOFO_MEM_UNCORRECTABLE_LOCAL_ERR,
139+ IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_DIRTY =
140+ IA_GOFO_MEM_UNCORRECTABLE_DIRTY_ERR,
141+ IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_DTAG =
142+ IA_GOFO_MEM_UNCORRECTABLE_DTAG_ERR,
143+ IA_GOFO_FW_BOOT_STATE_CRIT_MEM_UNCORRECTABLE_CACHE =
144+ IA_GOFO_MEM_UNCORRECTABLE_CACHE_ERR,
145+ IA_GOFO_FW_BOOT_STATE_CRIT_DOUBLE_EXCEPTION =
146+ IA_GOFO_DOUBLE_EXCEPTION_ERR,
147+ IA_GOFO_FW_BOOT_STATE_CRIT_BIST_DMEM_FAULT_DETECTION_ERR =
148+ IA_GOFO_BIST_DMEM_FAULT_DETECTION_ERR,
149+ IA_GOFO_FW_BOOT_STATE_CRIT_DATA_INTEGRITY_FAILURE = 0xdead1010U,
150+ IA_GOFO_FW_BOOT_STATE_CRIT_STACK_CHK_FAILURE = 0xdead1011U,
151+ IA_GOFO_FW_BOOT_STATE_CRIT_SYSCOM_CONTEXT_INTEGRITY_FAILURE =
152+ 0xdead1012U,
153+ IA_GOFO_FW_BOOT_STATE_CRIT_MPU_CONFIG_FAILURE = 0xdead1013U,
154+ IA_GOFO_FW_BOOT_STATE_CRIT_SHARED_BUFFER_FAILURE = 0xdead1014U,
155+ IA_GOFO_FW_BOOT_STATE_CRIT_CMEM_FAILURE = 0xdead1015U,
156+ IA_GOFO_FW_BOOT_STATE_SHUTDOWN_CMD = 0x57a7f001U,
157+ IA_GOFO_FW_BOOT_STATE_SHUTDOWN_START = 0x57a7e200U,
158+ IA_GOFO_FW_BOOT_STATE_INACTIVE = 0x57a7e300U,
159+ IA_GOFO_FW_BOOT_HW_CMD_ACK_TIMEOUT = 0x57a7e400U,
160+ IA_GOFO_FW_BOOT_SYSTEM_CYCLES_ERROR = 0x57a7e500U
161+};
162+
163+#endif
drivers/staging/media/ipu7/abi/ipu7_fw_common_abi.h+175−0
@@ -0,0 +1,175 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 - 2025 Intel Corporation
4+ */
5+
6+#ifndef IPU7_FW_COMMOM_ABI_H
7+#define IPU7_FW_COMMOM_ABI_H
8+
9+#include <linux/types.h>
10+
11+#pragma pack(push, 1)
12+typedef u32 ia_gofo_addr_t;
13+
14+#define IA_GOFO_ADDR_NULL (0U)
15+
16+struct ia_gofo_version_s {
17+ u8 patch;
18+ u8 subminor;
19+ u8 minor;
20+ u8 major;
21+};
22+
23+#define IA_GOFO_MSG_VERSION_INIT(major_val, minor_val, subminor_val, patch_val)\
24+ {.major = (major_val), .minor = (minor_val), .subminor = \
25+ (subminor_val), .patch = (patch_val)}
26+
27+#define IA_GOFO_MSG_VERSION_LIST_MAX_ENTRIES (3U)
28+#define IA_GOFO_MSG_RESERVED_SIZE (3U)
29+
30+struct ia_gofo_msg_version_list {
31+ u8 num_versions;
32+ u8 reserved[IA_GOFO_MSG_RESERVED_SIZE];
33+ struct ia_gofo_version_s versions[IA_GOFO_MSG_VERSION_LIST_MAX_ENTRIES];
34+};
35+
36+#pragma pack(pop)
37+
38+#define TLV_TYPE_PADDING (0U)
39+
40+#pragma pack(push, 1)
41+
42+#define IA_GOFO_ABI_BITS_PER_BYTE (8U)
43+
44+struct ia_gofo_tlv_header {
45+ u16 tlv_type;
46+ u16 tlv_len32;
47+};
48+
49+struct ia_gofo_tlv_list {
50+ u16 num_elems;
51+ u16 head_offset;
52+};
53+
54+#define TLV_ITEM_ALIGNMENT ((u32)sizeof(u32))
55+#define TLV_MSG_ALIGNMENT ((u32)sizeof(u64))
56+#define TLV_LIST_ALIGNMENT TLV_ITEM_ALIGNMENT
57+#pragma pack(pop)
58+
59+#define IA_GOFO_MODULO(dividend, divisor) ((dividend) % (divisor))
60+
61+#define IA_GOFO_MSG_ERR_MAX_DETAILS (4U)
62+#define IA_GOFO_MSG_ERR_OK (0U)
63+#define IA_GOFO_MSG_ERR_UNSPECIFED (0xffffffffU)
64+#define IA_GOFO_MSG_ERR_GROUP_UNSPECIFIED (0U)
65+#define IA_GOFO_MSG_ERR_IS_OK(err) (IA_GOFO_MSG_ERR_OK == (err).err_code)
66+
67+#pragma pack(push, 1)
68+struct ia_gofo_msg_err {
69+ u32 err_group;
70+ u32 err_code;
71+ u32 err_detail[IA_GOFO_MSG_ERR_MAX_DETAILS];
72+};
73+
74+#pragma pack(pop)
75+
76+#define IA_GOFO_MSG_ERR_GROUP_APP_EXT_START (16U)
77+#define IA_GOFO_MSG_ERR_GROUP_MAX (31U)
78+#define IA_GOFO_MSG_ERR_GROUP_INTERNAL_START (IA_GOFO_MSG_ERR_GROUP_MAX + 1U)
79+#define IA_GOFO_MSG_ERR_GROUP_RESERVED IA_GOFO_MSG_ERR_GROUP_UNSPECIFIED
80+#define IA_GOFO_MSG_ERR_GROUP_GENERAL 1
81+
82+enum ia_gofo_msg_err_general {
83+ IA_GOFO_MSG_ERR_GENERAL_OK = IA_GOFO_MSG_ERR_OK,
84+ IA_GOFO_MSG_ERR_GENERAL_MSG_TOO_SMALL = 1,
85+ IA_GOFO_MSG_ERR_GENERAL_MSG_TOO_LARGE = 2,
86+ IA_GOFO_MSG_ERR_GENERAL_DEVICE_STATE = 3,
87+ IA_GOFO_MSG_ERR_GENERAL_ALIGNMENT = 4,
88+ IA_GOFO_MSG_ERR_GENERAL_INDIRECT_REF_PTR_INVALID = 5,
89+ IA_GOFO_MSG_ERR_GENERAL_INVALID_MSG_TYPE = 6,
90+ IA_GOFO_MSG_ERR_GENERAL_SYSCOM_FAIL = 7,
91+ IA_GOFO_MSG_ERR_GENERAL_N
92+};
93+
94+#pragma pack(push, 1)
95+#define IA_GOFO_MSG_TYPE_RESERVED 0
96+#define IA_GOFO_MSG_TYPE_INDIRECT 1
97+#define IA_GOFO_MSG_TYPE_LOG 2
98+#define IA_GOFO_MSG_TYPE_GENERAL_ERR 3
99+
100+struct ia_gofo_msg_header {
101+ struct ia_gofo_tlv_header tlv_header;
102+ struct ia_gofo_tlv_list msg_options;
103+ u64 user_token;
104+};
105+
106+struct ia_gofo_msg_header_ack {
107+ struct ia_gofo_msg_header header;
108+ struct ia_gofo_msg_err err;
109+
110+};
111+
112+struct ia_gofo_msg_general_err {
113+ struct ia_gofo_msg_header_ack header;
114+};
115+
116+#pragma pack(pop)
117+
118+#pragma pack(push, 1)
119+enum ia_gofo_msg_link_streaming_mode {
120+ IA_GOFO_MSG_LINK_STREAMING_MODE_SOFF = 0,
121+ IA_GOFO_MSG_LINK_STREAMING_MODE_DOFF = 1,
122+ IA_GOFO_MSG_LINK_STREAMING_MODE_BCLM = 2,
123+ IA_GOFO_MSG_LINK_STREAMING_MODE_BCSM_FIX = 3,
124+ IA_GOFO_MSG_LINK_STREAMING_MODE_N
125+};
126+
127+enum ia_gofo_soc_pbk_instance_id {
128+ IA_GOFO_SOC_PBK_ID0 = 0,
129+ IA_GOFO_SOC_PBK_ID1 = 1,
130+ IA_GOFO_SOC_PBK_ID_N
131+};
132+
133+#define IA_GOFO_MSG_LINK_PBK_MAX_SLOTS (2U)
134+
135+struct ia_gofo_msg_indirect {
136+ struct ia_gofo_msg_header header;
137+ struct ia_gofo_tlv_header ref_header;
138+ ia_gofo_addr_t ref_msg_ptr;
139+};
140+
141+#pragma pack(pop)
142+
143+#pragma pack(push, 1)
144+#define IA_GOFO_MSG_LOG_MAX_PARAMS (4U)
145+#define IA_GOFO_MSG_LOG_DOC_FMT_ID_MIN (0U)
146+
147+#define IA_GOFO_MSG_LOG_DOC_FMT_ID_MAX (4095U)
148+#define IA_GOFO_MSG_LOG_FMT_ID_INVALID (0xfffffffU)
149+
150+struct ia_gofo_msg_log_info {
151+ u16 log_counter;
152+ u8 msg_parameter_types;
153+ /* [0:0] is_out_of_order, [1:3] logger_channel, [4:7] reserved */
154+ u8 logger_opts;
155+ u32 fmt_id;
156+ u32 params[IA_GOFO_MSG_LOG_MAX_PARAMS];
157+};
158+
159+struct ia_gofo_msg_log_info_ts {
160+ u64 msg_ts;
161+ struct ia_gofo_msg_log_info log_info;
162+};
163+
164+struct ia_gofo_msg_log {
165+ struct ia_gofo_msg_header header;
166+ struct ia_gofo_msg_log_info_ts log_info_ts;
167+};
168+
169+#pragma pack(pop)
170+
171+#define IA_GOFO_MSG_ABI_OUT_ACK_QUEUE_ID (0U)
172+#define IA_GOFO_MSG_ABI_OUT_LOG_QUEUE_ID (1U)
173+#define IA_GOFO_MSG_ABI_IN_DEV_QUEUE_ID (2U)
174+
175+#endif
drivers/staging/media/ipu7/abi/ipu7_fw_config_abi.h+19−0
@@ -0,0 +1,19 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2021 - 2025 Intel Corporation
4+ */
5+
6+#ifndef IPU7_FW_CONFIG_ABI_H
7+#define IPU7_FW_CONFIG_ABI_H
8+
9+#include <linux/types.h>
10+
11+#define IPU_CONFIG_ABI_WDT_TIMER_DISABLED 0U
12+#define IPU_CONFIG_ABI_CMD_TIMER_DISABLED 0U
13+
14+struct ipu7_wdt_abi {
15+ u32 wdt_timer1_us;
16+ u32 wdt_timer2_us;
17+};
18+
19+#endif
drivers/staging/media/ipu7/abi/ipu7_fw_insys_config_abi.h+19−0
@@ -0,0 +1,19 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2021 - 2025 Intel Corporation
4+ */
5+
6+#ifndef IPU7_FW_INSYS_CONFIG_ABI_H
7+#define IPU7_FW_INSYS_CONFIG_ABI_H
8+
9+#include "ipu7_fw_boot_abi.h"
10+#include "ipu7_fw_config_abi.h"
11+#include "ipu7_fw_isys_abi.h"
12+
13+struct ipu7_insys_config {
14+ u32 timeout_val_ms;
15+ struct ia_gofo_logger_config logger_config;
16+ struct ipu7_wdt_abi wdt_config;
17+};
18+
19+#endif
drivers/staging/media/ipu7/abi/ipu7_fw_isys_abi.h+412−0
@@ -0,0 +1,412 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 - 2025 Intel Corporation
4+ */
5+
6+#ifndef IPU7_FW_ISYS_ABI_H
7+#define IPU7_FW_ISYS_ABI_H
8+
9+#include "ipu7_fw_common_abi.h"
10+#include "ipu7_fw_isys_abi.h"
11+
12+#define IPU_INSYS_MAX_OUTPUT_QUEUES (3U)
13+#define IPU_INSYS_STREAM_ID_MAX (16U)
14+
15+#define IPU_INSYS_MAX_INPUT_QUEUES (IPU_INSYS_STREAM_ID_MAX + 1U)
16+#define IPU_INSYS_OUTPUT_FIRST_QUEUE (0U)
17+#define IPU_INSYS_OUTPUT_LAST_QUEUE (IPU_INSYS_MAX_OUTPUT_QUEUES - 1U)
18+#define IPU_INSYS_OUTPUT_MSG_QUEUE (IPU_INSYS_OUTPUT_FIRST_QUEUE)
19+#define IPU_INSYS_OUTPUT_LOG_QUEUE (IPU_INSYS_OUTPUT_FIRST_QUEUE + 1U)
20+#define IPU_INSYS_OUTPUT_RESERVED_QUEUE (IPU_INSYS_OUTPUT_LAST_QUEUE)
21+#define IPU_INSYS_INPUT_FIRST_QUEUE (IPU_INSYS_MAX_OUTPUT_QUEUES)
22+#define IPU_INSYS_INPUT_LAST_QUEUE \
23+ (IPU_INSYS_INPUT_FIRST_QUEUE + IPU_INSYS_MAX_INPUT_QUEUES - 1U)
24+#define IPU_INSYS_INPUT_DEV_QUEUE (IPU_INSYS_INPUT_FIRST_QUEUE)
25+#define IPU_INSYS_INPUT_MSG_QUEUE (IPU_INSYS_INPUT_FIRST_QUEUE + 1U)
26+#define IPU_INSYS_INPUT_MSG_MAX_QUEUE (IPU_INSYS_MAX_INPUT_QUEUES - 1U)
27+
28+#define MAX_OPINS_FOR_SINGLE_IPINS (3U)
29+#define DEV_SEND_QUEUE_SIZE (IPU_INSYS_STREAM_ID_MAX)
30+
31+#define PIN_PLANES_MAX (4U)
32+
33+#define INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES_INPUT \
34+ INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES
35+
36+typedef u64 ipu7_insys_return_token;
37+
38+enum ipu7_insys_resp_type {
39+ IPU_INSYS_RESP_TYPE_STREAM_OPEN_DONE = 0,
40+ IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK = 1,
41+ IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_ACK = 2,
42+ IPU_INSYS_RESP_TYPE_STREAM_ABORT_ACK = 3,
43+ IPU_INSYS_RESP_TYPE_STREAM_FLUSH_ACK = 4,
44+ IPU_INSYS_RESP_TYPE_STREAM_CLOSE_ACK = 5,
45+ IPU_INSYS_RESP_TYPE_PIN_DATA_READY = 6,
46+ IPU_INSYS_RESP_TYPE_FRAME_SOF = 7,
47+ IPU_INSYS_RESP_TYPE_FRAME_EOF = 8,
48+ IPU_INSYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE = 9,
49+ IPU_INSYS_RESP_TYPE_STREAM_CAPTURE_DONE = 10,
50+ IPU_INSYS_RESP_TYPE_PWM_IRQ = 11,
51+ N_IPU_INSYS_RESP_TYPE
52+};
53+
54+enum ipu7_insys_send_type {
55+ IPU_INSYS_SEND_TYPE_STREAM_OPEN = 0,
56+ IPU_INSYS_SEND_TYPE_STREAM_START_AND_CAPTURE = 1,
57+ IPU_INSYS_SEND_TYPE_STREAM_CAPTURE = 2,
58+ IPU_INSYS_SEND_TYPE_STREAM_ABORT = 3,
59+ IPU_INSYS_SEND_TYPE_STREAM_FLUSH = 4,
60+ IPU_INSYS_SEND_TYPE_STREAM_CLOSE = 5,
61+ N_IPU_INSYS_SEND_TYPE
62+};
63+
64+enum ipu7_insys_mipi_vc {
65+ IPU_INSYS_MIPI_VC_0 = 0,
66+ IPU_INSYS_MIPI_VC_1 = 1,
67+ IPU_INSYS_MIPI_VC_2 = 2,
68+ IPU_INSYS_MIPI_VC_3 = 3,
69+ IPU_INSYS_MIPI_VC_4 = 4,
70+ IPU_INSYS_MIPI_VC_5 = 5,
71+ IPU_INSYS_MIPI_VC_6 = 6,
72+ IPU_INSYS_MIPI_VC_7 = 7,
73+ IPU_INSYS_MIPI_VC_8 = 8,
74+ IPU_INSYS_MIPI_VC_9 = 9,
75+ IPU_INSYS_MIPI_VC_10 = 10,
76+ IPU_INSYS_MIPI_VC_11 = 11,
77+ IPU_INSYS_MIPI_VC_12 = 12,
78+ IPU_INSYS_MIPI_VC_13 = 13,
79+ IPU_INSYS_MIPI_VC_14 = 14,
80+ IPU_INSYS_MIPI_VC_15 = 15,
81+ N_IPU_INSYS_MIPI_VC
82+};
83+
84+enum ipu7_insys_mipi_port {
85+ IPU_INSYS_MIPI_PORT_0 = 0,
86+ IPU_INSYS_MIPI_PORT_1 = 1,
87+ IPU_INSYS_MIPI_PORT_2 = 2,
88+ IPU_INSYS_MIPI_PORT_3 = 3,
89+ IPU_INSYS_MIPI_PORT_4 = 4,
90+ IPU_INSYS_MIPI_PORT_5 = 5,
91+ NA_IPU_INSYS_MIPI_PORT
92+};
93+
94+enum ipu7_insys_frame_format_type {
95+ IPU_INSYS_FRAME_FORMAT_NV11 = 0,
96+ IPU_INSYS_FRAME_FORMAT_NV12 = 1,
97+ IPU_INSYS_FRAME_FORMAT_NV12_16 = 2,
98+ IPU_INSYS_FRAME_FORMAT_NV12_TILEY = 3,
99+ IPU_INSYS_FRAME_FORMAT_NV16 = 4,
100+ IPU_INSYS_FRAME_FORMAT_NV21 = 5,
101+ IPU_INSYS_FRAME_FORMAT_NV61 = 6,
102+ IPU_INSYS_FRAME_FORMAT_YV12 = 7,
103+ IPU_INSYS_FRAME_FORMAT_YV16 = 8,
104+ IPU_INSYS_FRAME_FORMAT_YUV420 = 9,
105+ IPU_INSYS_FRAME_FORMAT_YUV420_10 = 10,
106+ IPU_INSYS_FRAME_FORMAT_YUV420_12 = 11,
107+ IPU_INSYS_FRAME_FORMAT_YUV420_14 = 12,
108+ IPU_INSYS_FRAME_FORMAT_YUV420_16 = 13,
109+ IPU_INSYS_FRAME_FORMAT_YUV422 = 14,
110+ IPU_INSYS_FRAME_FORMAT_YUV422_16 = 15,
111+ IPU_INSYS_FRAME_FORMAT_UYVY = 16,
112+ IPU_INSYS_FRAME_FORMAT_YUYV = 17,
113+ IPU_INSYS_FRAME_FORMAT_YUV444 = 18,
114+ IPU_INSYS_FRAME_FORMAT_YUV_LINE = 19,
115+ IPU_INSYS_FRAME_FORMAT_RAW8 = 20,
116+ IPU_INSYS_FRAME_FORMAT_RAW10 = 21,
117+ IPU_INSYS_FRAME_FORMAT_RAW12 = 22,
118+ IPU_INSYS_FRAME_FORMAT_RAW14 = 23,
119+ IPU_INSYS_FRAME_FORMAT_RAW16 = 24,
120+ IPU_INSYS_FRAME_FORMAT_RGB565 = 25,
121+ IPU_INSYS_FRAME_FORMAT_PLANAR_RGB888 = 26,
122+ IPU_INSYS_FRAME_FORMAT_RGBA888 = 27,
123+ IPU_INSYS_FRAME_FORMAT_QPLANE6 = 28,
124+ IPU_INSYS_FRAME_FORMAT_BINARY_8 = 29,
125+ IPU_INSYS_FRAME_FORMAT_Y_8 = 30,
126+ IPU_INSYS_FRAME_FORMAT_ARGB888 = 31,
127+ IPU_INSYS_FRAME_FORMAT_BGRA888 = 32,
128+ IPU_INSYS_FRAME_FORMAT_ABGR888 = 33,
129+ N_IPU_INSYS_FRAME_FORMAT
130+};
131+
132+#define IPU_INSYS_FRAME_FORMAT_RAW (IPU_INSYS_FRAME_FORMAT_RAW16)
133+#define N_IPU_INSYS_MIPI_DATA_TYPE 0x40
134+
135+enum ipu7_insys_mipi_dt_rename_mode {
136+ IPU_INSYS_MIPI_DT_NO_RENAME = 0,
137+ IPU_INSYS_MIPI_DT_RENAMED_MODE = 1,
138+ N_IPU_INSYS_MIPI_DT_MODE
139+};
140+
141+#define IPU_INSYS_SEND_MSG_ENABLED 1U
142+#define IPU_INSYS_SEND_MSG_DISABLED 0U
143+
144+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF BIT(0)
145+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF BIT(1)
146+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF BIT(2)
147+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF BIT(3)
148+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF_DISCARDED BIT(4)
149+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF_DISCARDED BIT(5)
150+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF_DISCARDED BIT(6)
151+#define IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF_DISCARDED BIT(7)
152+#define IPU_INSYS_STREAM_SYNC_MSG_ENABLE_MSG_SEND_RESP ( \
153+ IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF | \
154+ IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF | \
155+ IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_SOF_DISCARDED | \
156+ IPU_INSYS_STREAM_SYNC_MSG_SEND_RESP_EOF_DISCARDED)
157+#define IPU_INSYS_STREAM_SYNC_MSG_ENABLE_MSG_SEND_IRQ ( \
158+ IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF | \
159+ IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF | \
160+ IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_SOF_DISCARDED | \
161+ IPU_INSYS_STREAM_SYNC_MSG_SEND_IRQ_EOF_DISCARDED)
162+
163+#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_OPEN_DONE BIT(0)
164+#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_OPEN_DONE BIT(1)
165+#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_START_ACK BIT(2)
166+#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_START_ACK BIT(3)
167+#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_CLOSE_ACK BIT(4)
168+#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_CLOSE_ACK BIT(5)
169+#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_FLUSH_ACK BIT(6)
170+#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_FLUSH_ACK BIT(7)
171+#define IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_ABORT_ACK BIT(8)
172+#define IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_ABORT_ACK BIT(9)
173+#define IPU_INSYS_STREAM_ENABLE_MSG_SEND_RESP ( \
174+ IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_OPEN_DONE | \
175+ IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_START_ACK | \
176+ IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_CLOSE_ACK | \
177+ IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_FLUSH_ACK | \
178+ IPU_INSYS_STREAM_MSG_SEND_RESP_STREAM_ABORT_ACK)
179+#define IPU_INSYS_STREAM_ENABLE_MSG_SEND_IRQ ( \
180+ IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_OPEN_DONE | \
181+ IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_START_ACK | \
182+ IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_CLOSE_ACK | \
183+ IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_FLUSH_ACK | \
184+ IPU_INSYS_STREAM_MSG_SEND_IRQ_STREAM_ABORT_ACK)
185+
186+#define IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_ACK BIT(0)
187+#define IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_ACK BIT(1)
188+#define IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_DONE BIT(2)
189+#define IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_DONE BIT(3)
190+#define IPU_INSYS_FRAME_MSG_SEND_RESP_PIN_DATA_READY BIT(4)
191+#define IPU_INSYS_FRAME_MSG_SEND_IRQ_PIN_DATA_READY BIT(5)
192+#define IPU_INSYS_FRAME_ENABLE_MSG_SEND_RESP ( \
193+ IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_ACK | \
194+ IPU_INSYS_FRAME_MSG_SEND_RESP_CAPTURE_DONE | \
195+ IPU_INSYS_FRAME_MSG_SEND_RESP_PIN_DATA_READY)
196+#define IPU_INSYS_FRAME_ENABLE_MSG_SEND_IRQ ( \
197+ IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_ACK | \
198+ IPU_INSYS_FRAME_MSG_SEND_IRQ_CAPTURE_DONE | \
199+ IPU_INSYS_FRAME_MSG_SEND_IRQ_PIN_DATA_READY)
200+
201+enum ipu7_insys_output_link_dest {
202+ IPU_INSYS_OUTPUT_LINK_DEST_MEM = 0,
203+ IPU_INSYS_OUTPUT_LINK_DEST_PSYS = 1,
204+ IPU_INSYS_OUTPUT_LINK_DEST_IPU_EXTERNAL = 2
205+};
206+
207+enum ipu7_insys_dpcm_type {
208+ IPU_INSYS_DPCM_TYPE_DISABLED = 0,
209+ IPU_INSYS_DPCM_TYPE_10_8_10 = 1,
210+ IPU_INSYS_DPCM_TYPE_12_8_12 = 2,
211+ IPU_INSYS_DPCM_TYPE_12_10_12 = 3,
212+ N_IPU_INSYS_DPCM_TYPE
213+};
214+
215+enum ipu7_insys_dpcm_predictor {
216+ IPU_INSYS_DPCM_PREDICTOR_1 = 0,
217+ IPU_INSYS_DPCM_PREDICTOR_2 = 1,
218+ N_IPU_INSYS_DPCM_PREDICTOR
219+};
220+
221+enum ipu7_insys_send_queue_token_flag {
222+ IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_NONE = 0,
223+ IPU_INSYS_SEND_QUEUE_TOKEN_FLAG_FLUSH_FORCE = 1
224+};
225+
226+#pragma pack(push, 1)
227+struct ipu7_insys_resolution {
228+ u32 width;
229+ u32 height;
230+};
231+
232+struct ipu7_insys_capture_output_pin_payload {
233+ u64 user_token;
234+ ia_gofo_addr_t addr;
235+ u8 pad[4];
236+};
237+
238+struct ipu7_insys_output_link {
239+ u32 buffer_lines;
240+ u16 foreign_key;
241+ u16 granularity_pointer_update;
242+ u8 msg_link_streaming_mode;
243+ u8 pbk_id;
244+ u8 pbk_slot_id;
245+ u8 dest;
246+ u8 use_sw_managed;
247+ u8 is_snoop;
248+ u8 pad[2];
249+};
250+
251+struct ipu7_insys_output_cropping {
252+ u16 line_top;
253+ u16 line_bottom;
254+};
255+
256+struct ipu7_insys_output_dpcm {
257+ u8 enable;
258+ u8 type;
259+ u8 predictor;
260+ u8 pad;
261+};
262+
263+struct ipu7_insys_output_pin {
264+ struct ipu7_insys_output_link link;
265+ struct ipu7_insys_output_cropping crop;
266+ struct ipu7_insys_output_dpcm dpcm;
267+ u32 stride;
268+ u16 ft;
269+ u8 send_irq;
270+ u8 input_pin_id;
271+ u8 early_ack_en;
272+ u8 pad[3];
273+};
274+
275+struct ipu7_insys_input_pin {
276+ struct ipu7_insys_resolution input_res;
277+ u16 sync_msg_map;
278+ u8 dt;
279+ u8 disable_mipi_unpacking;
280+ u8 dt_rename_mode;
281+ u8 mapped_dt;
282+ u8 pad[2];
283+};
284+
285+struct ipu7_insys_stream_cfg {
286+ struct ipu7_insys_input_pin input_pins[4];
287+ struct ipu7_insys_output_pin output_pins[4];
288+ u16 stream_msg_map;
289+ u8 port_id;
290+ u8 vc;
291+ u8 nof_input_pins;
292+ u8 nof_output_pins;
293+ u8 pad[2];
294+};
295+
296+struct ipu7_insys_buffset {
297+ struct ipu7_insys_capture_output_pin_payload output_pins[4];
298+ u8 capture_msg_map;
299+ u8 frame_id;
300+ u8 skip_frame;
301+ u8 pad[5];
302+};
303+
304+struct ipu7_insys_resp {
305+ u64 buf_id;
306+ struct ipu7_insys_capture_output_pin_payload pin;
307+ struct ia_gofo_msg_err error_info;
308+ u32 timestamp[2];
309+ u8 type;
310+ u8 msg_link_streaming_mode;
311+ u8 stream_id;
312+ u8 pin_id;
313+ u8 frame_id;
314+ u8 skip_frame;
315+ u8 pad[2];
316+};
317+
318+struct ipu7_insys_resp_queue_token {
319+ struct ipu7_insys_resp resp_info;
320+};
321+
322+struct ipu7_insys_send_queue_token {
323+ u64 buf_handle;
324+ ia_gofo_addr_t addr;
325+ u16 stream_id;
326+ u8 send_type;
327+ u8 flag;
328+};
329+
330+#pragma pack(pop)
331+
332+enum insys_msg_err_stream {
333+ INSYS_MSG_ERR_STREAM_OK = IA_GOFO_MSG_ERR_OK,
334+ INSYS_MSG_ERR_STREAM_STREAM_ID = 1,
335+ INSYS_MSG_ERR_STREAM_MAX_OPINS = 2,
336+ INSYS_MSG_ERR_STREAM_MAX_IPINS = 3,
337+ INSYS_MSG_ERR_STREAM_STREAM_MESSAGES_MAP = 4,
338+ INSYS_MSG_ERR_STREAM_SYNC_MESSAGES_MAP = 5,
339+ INSYS_MSG_ERR_STREAM_SENSOR_TYPE = 6,
340+ INSYS_MSG_ERR_STREAM_FOREIGN_KEY = 7,
341+ INSYS_MSG_ERR_STREAM_STREAMING_MODE = 8,
342+ INSYS_MSG_ERR_STREAM_DPCM_EN = 9,
343+ INSYS_MSG_ERR_STREAM_DPCM_TYPE = 10,
344+ INSYS_MSG_ERR_STREAM_DPCM_PREDICTOR = 11,
345+ INSYS_MSG_ERR_STREAM_GRANULARITY_POINTER_UPDATE = 12,
346+ INSYS_MSG_ERR_STREAM_MPF_LUT_ENTRY_RESOURCES_BUSY = 13,
347+ INSYS_MSG_ERR_STREAM_MPF_DEV_ID = 14,
348+ INSYS_MSG_ERR_STREAM_BUFFER_LINES = 15,
349+ INSYS_MSG_ERR_STREAM_IPIN_ID = 16,
350+ INSYS_MSG_ERR_STREAM_DATA_TYPE = 17,
351+ INSYS_MSG_ERR_STREAM_STREAMING_PROTOCOL_STATE = 18,
352+ INSYS_MSG_ERR_STREAM_SYSCOM_FLUSH = 19,
353+ INSYS_MSG_ERR_STREAM_MIPI_VC = 20,
354+ INSYS_MSG_ERR_STREAM_STREAM_SRC = 21,
355+ INSYS_MSG_ERR_STREAM_PBK_ID = 22,
356+ INSYS_MSG_ERR_STREAM_CMD_QUEUE_DEALLOCATE = 23,
357+ INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES = 24,
358+ INSYS_MSG_ERR_STREAM_IPIN_CONFIGURATION = 25,
359+ INSYS_MSG_ERR_STREAM_INVALID_STATE = 26,
360+ INSYS_MSG_ERR_STREAM_SW_MANAGED = 27,
361+ INSYS_MSG_ERR_STREAM_PBK_SLOT_ID = 28,
362+ INSYS_MSG_ERR_STREAM_FLUSH_TIMEOUT = 29,
363+ INSYS_MSG_ERR_STREAM_IPIN_WIDTH = 30,
364+ INSYS_MSG_ERR_STREAM_IPIN_HEIGHT = 31,
365+ INSYS_MSG_ERR_STREAM_OUTPUT_PIN_EARLY_ACK_EN = 32,
366+ INSYS_MSG_ERR_STREAM_INCONSISTENT_PARAMS = 33,
367+ INSYS_MSG_ERR_STREAM_PLANE_COUNT = 34,
368+ INSYS_MSG_ERR_STREAM_FRAME_FORMAT_TYPE = 35,
369+ INSYS_MSG_ERR_STREAM_INSUFFICIENT_RESOURCES_OUTPUT = 36,
370+ INSYS_MSG_ERR_STREAM_WIDTH_OUTPUT_SIZE = 37,
371+ INSYS_MSG_ERR_STREAM_CLOSED = 38,
372+ INSYS_MSG_ERR_STREAM_N
373+};
374+
375+enum insys_msg_err_capture {
376+ INSYS_MSG_ERR_CAPTURE_OK = IA_GOFO_MSG_ERR_OK,
377+ INSYS_MSG_ERR_CAPTURE_STREAM_ID = 1,
378+ INSYS_MSG_ERR_CAPTURE_PAYLOAD_PTR = 2,
379+ INSYS_MSG_ERR_CAPTURE_MEM_SLOT = 3,
380+ INSYS_MSG_ERR_CAPTURE_STREAMING_MODE = 4,
381+ INSYS_MSG_ERR_CAPTURE_AVAILABLE_CMD_SLOT = 5,
382+ INSYS_MSG_ERR_CAPTURE_CONSUMED_CMD_SLOT = 6,
383+ INSYS_MSG_ERR_CAPTURE_CMD_SLOT_PAYLOAD_PTR = 7,
384+ INSYS_MSG_ERR_CAPTURE_CMD_PREPARE = 8,
385+ INSYS_MSG_ERR_CAPTURE_OUTPUT_PIN = 9,
386+ INSYS_MSG_ERR_CAPTURE_SYNC_FRAME_DROP = 10,
387+ INSYS_MSG_ERR_CAPTURE_FRAME_MESSAGES_MAP = 11,
388+ INSYS_MSG_ERR_CAPTURE_TIMEOUT = 12,
389+ INSYS_MSG_ERR_CAPTURE_INVALID_STREAM_STATE = 13,
390+ INSYS_MSG_ERR_CAPTURE_HW_ERR_MULTIBIT_PH_ERROR_DETECTED = 14,
391+ INSYS_MSG_ERR_CAPTURE_HW_ERR_PAYLOAD_CRC_ERROR = 15,
392+ INSYS_MSG_ERR_CAPTURE_HW_ERR_INPUT_DATA_LOSS_ELASTIC_FIFO_OVFL = 16,
393+ INSYS_MSG_ERR_CAPTURE_HW_ERR_PIXEL_BUFFER_OVERFLOW = 17,
394+ INSYS_MSG_ERR_CAPTURE_HW_ERR_BAD_FRAME_DIM = 18,
395+ INSYS_MSG_ERR_CAPTURE_HW_ERR_PHY_SYNC_ERR = 19,
396+ INSYS_MSG_ERR_CAPTURE_HW_ERR_SECURE_TOUCH = 20,
397+ INSYS_MSG_ERR_CAPTURE_HW_ERR_MASTER_SLAVE_SYNC_ERR = 21,
398+ INSYS_MSG_ERR_CAPTURE_FRAME_SKIP_ERR = 22,
399+ INSYS_MSG_ERR_CAPTURE_FE_INPUT_FIFO_OVERFLOW_ERR = 23,
400+ INSYS_MSG_ERR_CAPTURE_CMD_SUBMIT_TO_HW = 24,
401+ INSYS_MSG_ERR_CAPTURE_N
402+};
403+
404+enum insys_msg_err_groups {
405+ INSYS_MSG_ERR_GROUP_RESERVED = IA_GOFO_MSG_ERR_GROUP_RESERVED,
406+ INSYS_MSG_ERR_GROUP_GENERAL = IA_GOFO_MSG_ERR_GROUP_GENERAL,
407+ INSYS_MSG_ERR_GROUP_STREAM = 2,
408+ INSYS_MSG_ERR_GROUP_CAPTURE = 3,
409+ INSYS_MSG_ERR_GROUP_N,
410+};
411+
412+#endif
drivers/staging/media/ipu7/abi/ipu7_fw_msg_abi.h+465−0
@@ -0,0 +1,465 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (C) 2020 - 2025 Intel Corporation
4+ */
5+
6+#ifndef IPU7_FW_MSG_ABI_H
7+#define IPU7_FW_MSG_ABI_H
8+
9+#include "ipu7_fw_common_abi.h"
10+
11+#pragma pack(push, 1)
12+enum ipu7_msg_type {
13+ IPU_MSG_TYPE_RESERVED = IA_GOFO_MSG_TYPE_RESERVED,
14+ IPU_MSG_TYPE_INDIRECT = IA_GOFO_MSG_TYPE_INDIRECT,
15+ IPU_MSG_TYPE_DEV_LOG = IA_GOFO_MSG_TYPE_LOG,
16+ IPU_MSG_TYPE_GENERAL_ERR = IA_GOFO_MSG_TYPE_GENERAL_ERR,
17+ IPU_MSG_TYPE_DEV_OPEN = 4,
18+ IPU_MSG_TYPE_DEV_OPEN_ACK = 5,
19+ IPU_MSG_TYPE_GRAPH_OPEN = 6,
20+ IPU_MSG_TYPE_GRAPH_OPEN_ACK = 7,
21+ IPU_MSG_TYPE_TASK_REQ = 8,
22+ IPU_MSG_TYPE_TASK_DONE = 9,
23+ IPU_MSG_TYPE_GRAPH_CLOSE = 10,
24+ IPU_MSG_TYPE_GRAPH_CLOSE_ACK = 11,
25+ IPU_MSG_TYPE_DEV_CLOSE = 12,
26+ IPU_MSG_TYPE_DEV_CLOSE_ACK = 13,
27+ IPU_MSG_TYPE_TERM_EVENT = 14,
28+ IPU_MSG_TYPE_N,
29+};
30+
31+#define IPU_MSG_MAX_NODE_TERMS (64U)
32+#define IPU_MSG_MAX_FRAGS (7U)
33+
34+enum ipu7_msg_node_type {
35+ IPU_MSG_NODE_TYPE_PAD = 0,
36+ IPU_MSG_NODE_TYPE_BASE,
37+ IPU_MSG_NODE_TYPE_N
38+};
39+
40+#define IPU_MSG_NODE_MAX_DEVICES (128U)
41+#define DEB_NUM_UINT32 (IPU_MSG_NODE_MAX_DEVICES / (sizeof(u32) * 8U))
42+
43+typedef u32 ipu7_msg_teb_t[2];
44+typedef u32 ipu7_msg_deb_t[DEB_NUM_UINT32];
45+
46+#define IPU_MSG_NODE_MAX_ROUTE_ENABLES (128U)
47+#define RBM_NUM_UINT32 (IPU_MSG_NODE_MAX_ROUTE_ENABLES / (sizeof(u32) * 8U))
48+
49+typedef u32 ipu7_msg_rbm_t[RBM_NUM_UINT32];
50+
51+enum ipu7_msg_node_profile_type {
52+ IPU_MSG_NODE_PROFILE_TYPE_PAD = 0,
53+ IPU_MSG_NODE_PROFILE_TYPE_BASE,
54+ IPU_MSG_NODE_PROFILE_TYPE_CB,
55+ IPU_MSG_NODE_PROFILE_TYPE_N
56+};
57+
58+struct ipu7_msg_node_profile {
59+ struct ia_gofo_tlv_header tlv_header;
60+ ipu7_msg_teb_t teb;
61+};
62+
63+struct ipu7_msg_cb_profile {
64+ struct ipu7_msg_node_profile profile_base;
65+ ipu7_msg_deb_t deb;
66+ ipu7_msg_rbm_t rbm;
67+ ipu7_msg_rbm_t reb;
68+};
69+
70+#define IPU_MSG_NODE_MAX_PROFILES (2U)
71+#define IPU_MSG_NODE_DEF_PROFILE_IDX (0U)
72+#define IPU_MSG_NODE_RSRC_ID_EXT_IP (0xffU)
73+
74+#define IPU_MSG_NODE_DONT_CARE_TEB_HI (0xffffffffU)
75+#define IPU_MSG_NODE_DONT_CARE_TEB_LO (0xffffffffU)

390 more lines aren’t shown here.

drivers/staging/media/ipu7/abi/ipu7_fw_psys_config_abi.h+24−0

This diff is large: its 25 lines aren’t shown here.

drivers/staging/media/ipu7/abi/ipu7_fw_syscom_abi.h+49−0

This diff is large: its 50 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-boot.c+430−0

This diff is large: its 431 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-boot.h+25−0

This diff is large: its 26 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-bus.c+158−0

This diff is large: its 159 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-bus.h+69−0

This diff is large: its 70 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-buttress-regs.h+461−0

This diff is large: its 462 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-buttress.c+1192−0

This diff is large: its 1193 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-buttress.h+77−0

This diff is large: its 78 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-cpd.c+276−0

This diff is large: its 277 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-cpd.h+16−0

This diff is large: its 17 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-dma.c+477−0

This diff is large: its 478 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-dma.h+46−0

This diff is large: its 47 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-fw-isys.c+301−0

This diff is large: its 302 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-fw-isys.h+39−0

This diff is large: its 40 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-csi-phy.c+1034−0

This diff is large: its 1035 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-csi-phy.h+16−0

This diff is large: its 17 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h+1197−0

This diff is large: its 1198 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-csi2.c+543−0

This diff is large: its 544 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-csi2.h+64−0

This diff is large: its 65 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-queue.c+829−0

This diff is large: its 830 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-queue.h+72−0

This diff is large: its 73 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-subdev.c+348−0

This diff is large: its 349 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-subdev.h+53−0

This diff is large: its 54 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-video.c+1112−0

This diff is large: its 1113 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys-video.h+117−0

This diff is large: its 118 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys.c+1166−0

This diff is large: its 1167 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-isys.h+140−0

This diff is large: its 141 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-mmu.c+853−0

This diff is large: its 854 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-mmu.h+414−0

This diff is large: its 415 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-platform-regs.h+82−0

This diff is large: its 83 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-syscom.c+78−0

This diff is large: its 79 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7-syscom.h+35−0

This diff is large: its 36 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7.c+2783−0

This diff is large: its 2784 lines aren’t shown here.

drivers/staging/media/ipu7/ipu7.h+242−0

This diff is large: its 243 lines aren’t shown here.

drivers/staging/media/rkvdec/TODO+0−11

This diff is large: its 12 lines aren’t shown here.

drivers/staging/media/sunxi/cedrus/cedrus_hw.c+18−1

This diff is large: its 28 lines aren’t shown here.

drivers/staging/media/sunxi/cedrus/cedrus_video.c+18−0

This diff is large: its 32 lines aren’t shown here.

include/linux/usb/uvc.h+3−0

This diff is large: its 10 lines aren’t shown here.

include/media/rcar-fcp.h+5−0

This diff is large: its 19 lines aren’t shown here.

include/media/v4l2-ctrls.h+3−1

This diff is large: its 12 lines aren’t shown here.

include/media/v4l2-dev.h+10−4

This diff is large: its 21 lines aren’t shown here.

include/media/v4l2-ioctl.h+1−0

This diff is large: its 8 lines aren’t shown here.

include/media/v4l2-jpeg.h+0−9

This diff is large: its 16 lines aren’t shown here.

include/media/v4l2-subdev.h+0−3

This diff is large: its 17 lines aren’t shown here.

include/media/vsp1.h+89−0

This diff is large: its 101 lines aren’t shown here.

include/uapi/linux/media/raspberrypi/pisp_be_config.h+5−4

This diff is large: its 16 lines aren’t shown here.

include/uapi/linux/rkisp1-config.h+105−1

This diff is large: its 160 lines aren’t shown here.

include/uapi/linux/v4l2-controls.h+6−0

This diff is large: its 13 lines aren’t shown here.

include/uapi/linux/videodev2.h+8−1

This diff is large: its 30 lines aren’t shown here.