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
287Hamza Mahfooz <hamzamahfooz@linux.microsoft.com> <hamza.mahfooz@amd.com>287Hamza Mahfooz <hamzamahfooz@linux.microsoft.com> <hamza.mahfooz@amd.com>
288Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org>288Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org>
289Hans de Goede <hansg@kernel.org> <hdegoede@redhat.com>289Hans de Goede <hansg@kernel.org> <hdegoede@redhat.com>
290Hans Verkuil <hverkuil@xs4all.nl> <hansverk@cisco.com>290Hans Verkuil <hverkuil@kernel.org> <hverkuil@xs4all.nl>
291Hans Verkuil <hverkuil@xs4all.nl> <hverkuil-cisco@xs4all.nl>291Hans Verkuil <hverkuil@kernel.org> <hverkuil-cisco@xs4all.nl>
292Hans Verkuil <hverkuil@kernel.org> <hansverk@cisco.com>
292Harry Yoo <harry.yoo@oracle.com> <42.hyeyoo@gmail.com>293Harry Yoo <harry.yoo@oracle.com> <42.hyeyoo@gmail.com>
293Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>294Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>
294Heiko Carstens <hca@linux.ibm.com> <heiko.carstens@de.ibm.com>295Heiko 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
24 reg:24 reg:
25 maxItems: 125 maxItems: 1
26 26
27 interrupts:
28 maxItems: 2
29
30 interrupt-names:
31 items:
32 - const: error_irq
33 - const: irq
34
27 clocks:35 clocks:
28 items:36 items:
29 - description: CSI2Rx system clock37 - 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
7title: Freescale Video Data Order Adapter
8
9description:
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
14maintainers:
15 - Frank Li <Frank.Li@nxp.com>
16
17properties:
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
30additionalProperties: false
31
32examples:
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
7title: i.MX8QM Image Sensing Interface
8
9maintainers:
10 - Frank Li <Frank.Li@nxp.com>
11
12description:
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
19properties:
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
60required:
61 - compatible
62 - reg
63 - clocks
64 - clock-names
65 - interrupts
66 - power-domains
67 - ports
68
69additionalProperties: false
70
71examples:
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
7title: i.MX8QXP Image Sensing Interface
8
9maintainers:
10 - Frank Li <Frank.Li@nxp.com>
11
12description:
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
19properties:
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
55required:
56 - compatible
57 - reg
58 - clocks
59 - clock-names
60 - interrupts
61 - power-domains
62 - ports
63
64additionalProperties: false
65
66examples:
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 @@
1Freescale Video Data Order Adapter
2==================================
3
4The Video Data Order Adapter (VDOA) is present on the i.MX6q. Its sole purpose
5is to reorder video data from the macroblock tiled order produced by the CODA
6960 VPU to the conventional raster-scan order for scanout.
7
8Required 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
14Example:
15
16vdoa@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
23 More detailed documentation can be found in23 More detailed documentation can be found in
24 Documentation/devicetree/bindings/media/video-interfaces.txt .24 Documentation/devicetree/bindings/media/video-interfaces.txt .
25 25
26allOf:
27 - $ref: /schemas/media/video-interface-devices.yaml#
28
26properties:29properties:
27 compatible:30 compatible:
28 oneOf:31 oneOf:
@@ -58,16 +61,10 @@ properties: · 29 unmodified lines
58 documentation.61 documentation.
59 maxItems: 162 maxItems: 1
60 63
61 flash-leds:64 flash-leds: true
62 description: Flash LED phandles. See ../video-interfaces.txt for details.65 lens-focus: true
63
64 lens-focus:
65 description: Lens focus controller phandles. See ../video-interfaces.txt
66 for details.
67 66
68 rotation:67 rotation:
69 description: Rotation of the sensor. See ../video-interfaces.txt for
70 details.
71 enum: [ 0, 180 ]68 enum: [ 0, 180 ]
72 69
73 port:70 port:
Documentation/devicetree/bindings/media/i2c/onnn,mt9m114.yaml+9−0
@@ -70,6 +70,15 @@ properties: · 69 unmodified lines
70 - bus-type70 - bus-type
71 - link-frequencies71 - link-frequencies
72 72
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
73required:82required:
74 - compatible83 - compatible
75 - reg84 - reg
Documentation/devicetree/bindings/media/i2c/ovti,ov8858.yaml+3−1
@@ -15,6 +15,8 @@ description: | · 14 unmodified lines
15 controlled through an I2C-compatible SCCB bus. The sensor transmits images15 controlled through an I2C-compatible SCCB bus. The sensor transmits images
16 on a MIPI CSI-2 output interface with up to 4 data lanes.16 on a MIPI CSI-2 output interface with up to 4 data lanes.
17 17
18$ref: /schemas/media/video-interface-devices.yaml#
19
18properties:20properties:
19 compatible:21 compatible:
20 const: ovti,ov885822 const: ovti,ov8858
@@ -69,7 +71,7 @@ required: · 48 unmodified lines
69 - clocks71 - clocks
70 - port72 - port
71 73
72additionalProperties: false74unevaluatedProperties: false
73 75
74examples:76examples:
75 - |77 - |
Documentation/devicetree/bindings/media/i2c/sony,imx214.yaml+16−13
@@ -33,20 +33,21 @@ properties: · 32 unmodified lines
33 33
34 clock-frequency:34 clock-frequency:
35 description: Frequency of the xclk clock in Hz.35 description: Frequency of the xclk clock in Hz.
36 deprecated: true
36 37
37 enable-gpios:38 enable-gpios:
38 description: GPIO descriptor for the enable pin.39 description: GPIO descriptor for the enable pin.
39 maxItems: 140 maxItems: 1
40 41
41 vdddo-supply:
42 description: Chip digital IO regulator (1.8V).
43
44 vdda-supply:42 vdda-supply:
45 description: Chip analog regulator (2.7V).43 description: Chip analog regulator (2.7V).
46 44
47 vddd-supply:45 vddd-supply:
48 description: Chip digital core regulator (1.12V).46 description: Chip digital core regulator (1.12V).
49 47
48 vdddo-supply:
49 description: Chip digital IO regulator (1.8V).
50
50 flash-leds: true51 flash-leds: true
51 lens-focus: true52 lens-focus: true
52 53
@@ -84,11 +85,10 @@ required: · 31 unmodified lines
84 - compatible85 - compatible
85 - reg86 - reg
86 - clocks87 - clocks
87 - clock-frequency
88 - enable-gpios88 - enable-gpios
89 - vdddo-supply
90 - vdda-supply89 - vdda-supply
91 - vddd-supply90 - vddd-supply
91 - vdddo-supply
92 - port92 - port
93 93
94unevaluatedProperties: false94unevaluatedProperties: false
@@ -104,22 +104,25 @@ examples: · 9 unmodified lines
104 camera-sensor@1a {104 camera-sensor@1a {
105 compatible = "sony,imx214";105 compatible = "sony,imx214";
106 reg = <0x1a>;106 reg = <0x1a>;
107 vdddo-supply = <&pm8994_lvs1>;107
108 vddd-supply = <&camera_vddd_1v12>;108 clocks = <&camera_clk>;
109 assigned-clocks = <&camera_clk>;
110 assigned-clock-rates = <24000000>;
111
112 enable-gpios = <&msmgpio 25 GPIO_ACTIVE_HIGH>;
113
109 vdda-supply = <&pm8994_l17>;114 vdda-supply = <&pm8994_l17>;
115 vddd-supply = <&camera_vddd_1v12>;
116 vdddo-supply = <&pm8994_lvs1>;
117
110 lens-focus = <&ad5820>;118 lens-focus = <&ad5820>;
111 enable-gpios = <&msmgpio 25 GPIO_ACTIVE_HIGH>;
112 clocks = <&camera_clk>;
113 clock-frequency = <24000000>;
114 119
115 port {120 port {
116 imx214_ep: endpoint {121 imx214_ep: endpoint {
117 data-lanes = <1 2 3 4>;122 data-lanes = <1 2 3 4>;
118 link-frequencies = /bits/ 64 <480000000>;123 link-frequencies = /bits/ 64 <600000000>;
119 remote-endpoint = <&csiphy0_ep>;124 remote-endpoint = <&csiphy0_ep>;
120 };125 };
121 };126 };
122 };127 };
123 };128 };
124
125...
Documentation/devicetree/bindings/media/i2c/sony,imx258.yaml+3−1
@@ -18,6 +18,8 @@ description: |- · 17 unmodified lines
18 The camera module does not expose the model through registers, so the18 The camera module does not expose the model through registers, so the
19 exact model needs to be specified.19 exact model needs to be specified.
20 20
21$ref: /schemas/media/video-interface-devices.yaml#
22
21properties:23properties:
22 compatible:24 compatible:
23 enum:25 enum:
@@ -81,7 +83,7 @@ required: · 57 unmodified lines
81 - reg83 - reg
82 - port84 - port
83 85
84additionalProperties: false86unevaluatedProperties: false
85 87
86examples:88examples:
87 - |89 - |
Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml+25−3
@@ -22,10 +22,14 @@ properties: · 21 unmodified lines
22 - nxp,imx8qxp-jpgdec22 - nxp,imx8qxp-jpgdec
23 - nxp,imx8qxp-jpgenc23 - nxp,imx8qxp-jpgenc
24 - items:24 - items:
25 - const: nxp,imx8qm-jpgdec25 - enum:
26 - nxp,imx8qm-jpgdec
27 - nxp,imx95-jpgdec
26 - const: nxp,imx8qxp-jpgdec28 - const: nxp,imx8qxp-jpgdec
27 - items:29 - items:
28 - const: nxp,imx8qm-jpgenc30 - enum:
31 - nxp,imx8qm-jpgenc
32 - nxp,imx95-jpgenc
29 - const: nxp,imx8qxp-jpgenc33 - const: nxp,imx8qxp-jpgenc
30 34
31 reg:35 reg:
@@ -48,7 +52,7 @@ properties: · 16 unmodified lines
48 description:52 description:
49 List of phandle and PM domain specifier as documented in53 List of phandle and PM domain specifier as documented in
50 Documentation/devicetree/bindings/power/power_domain.txt54 Documentation/devicetree/bindings/power/power_domain.txt
51 minItems: 2 # Wrapper and 1 slot55 minItems: 1 # Wrapper and all slots
52 maxItems: 5 # Wrapper and 4 slots56 maxItems: 5 # Wrapper and 4 slots
53 57
54required:58required:
@@ -58,6 +62,24 @@ required: · 3 unmodified lines
58 - interrupts62 - interrupts
59 - power-domains63 - power-domains
60 64
65allOf:
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
61additionalProperties: false83additionalProperties: false
62 84
63examples:85examples:
Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml+34−4
@@ -16,11 +16,19 @@ description: |- · 15 unmodified lines
16 16
17properties:17properties:
18 compatible:18 compatible:
19 enum:19 oneOf:
20 - fsl,imx8mq-mipi-csi220 - 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
21 26
22 reg:27 reg:
23 maxItems: 128 items:
29 - description: MIPI CSI-2 RX host controller register.
30 - description: MIPI CSI-2 control and status register (csr).
31 minItems: 1
24 32
25 clocks:33 clocks:
26 items:34 items:
@@ -46,6 +54,7 @@ properties: · 19 unmodified lines
46 - description: CORE_RESET reset register bit definition54 - description: CORE_RESET reset register bit definition
47 - description: PHY_REF_RESET reset register bit definition55 - description: PHY_REF_RESET reset register bit definition
48 - description: ESC_RESET reset register bit definition56 - description: ESC_RESET reset register bit definition
57 minItems: 1
49 58
50 fsl,mipi-phy-gpr:59 fsl,mipi-phy-gpr:
51 description: |60 description: |
@@ -113,9 +122,30 @@ required: · 61 unmodified lines
113 - clock-names122 - clock-names
114 - power-domains123 - power-domains
115 - resets124 - resets
116 - fsl,mipi-phy-gpr
117 - ports125 - ports
118 126
127allOf:
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
119additionalProperties: false149additionalProperties: false
120 150
121examples:151examples:
Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml+7−7
@@ -133,7 +133,7 @@ properties: · 132 unmodified lines
133 CSI input ports.133 CSI input ports.
134 134
135 patternProperties:135 patternProperties:
136 "^port@[0-3]+$":136 "^port@[0-3]$":
137 $ref: /schemas/graph.yaml#/$defs/port-base137 $ref: /schemas/graph.yaml#/$defs/port-base
138 unevaluatedProperties: false138 unevaluatedProperties: false
139 139
@@ -146,15 +146,16 @@ properties: · 6 unmodified lines
146 unevaluatedProperties: false146 unevaluatedProperties: false
147 147
148 properties:148 properties:
149 clock-lanes:
150 maxItems: 1
151
152 data-lanes:149 data-lanes:
153 minItems: 1150 minItems: 1
154 maxItems: 4151 maxItems: 4
155 152
153 bus-type:
154 enum:
155 - 1 # MEDIA_BUS_TYPE_CSI2_CPHY
156 - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
157
156 required:158 required:
157 - clock-lanes
158 - data-lanes159 - data-lanes
159 160
160required:161required:
@@ -189,7 +190,7 @@ examples: · 28 unmodified lines
189 #address-cells = <2>;190 #address-cells = <2>;
190 #size-cells = <2>;191 #size-cells = <2>;
191 192
192 camss: isp@acb6000 {193 camss: isp@acb7000 {
193 compatible = "qcom,x1e80100-camss";194 compatible = "qcom,x1e80100-camss";
194 195
195 reg = <0 0x0acb7000 0 0x2000>,196 reg = <0 0x0acb7000 0 0x2000>,
@@ -357,7 +358,6 @@ examples: · 161 unmodified lines
357 port@0 {358 port@0 {
358 reg = <0>;359 reg = <0>;
359 csiphy_ep0: endpoint {360 csiphy_ep0: endpoint {
360 clock-lanes = <7>;
361 data-lanes = <0 1>;361 data-lanes = <0 1>;
362 remote-endpoint = <&sensor_ep>;362 remote-endpoint = <&sensor_ep>;
363 };363 };
Documentation/devicetree/bindings/media/renesas,fcp.yaml+1−0
@@ -30,6 +30,7 @@ properties: · 29 unmodified lines
30 - renesas,r9a07g043u-fcpvd # RZ/G2UL30 - renesas,r9a07g043u-fcpvd # RZ/G2UL
31 - renesas,r9a07g044-fcpvd # RZ/G2{L,LC}31 - renesas,r9a07g044-fcpvd # RZ/G2{L,LC}
32 - renesas,r9a07g054-fcpvd # RZ/V2L32 - renesas,r9a07g054-fcpvd # RZ/V2L
33 - renesas,r9a09g056-fcpvd # RZ/V2N
33 - renesas,r9a09g057-fcpvd # RZ/V2H(P)34 - renesas,r9a09g057-fcpvd # RZ/V2H(P)
34 - const: renesas,fcpv # Generic FCP for VSP fallback35 - const: renesas,fcpv # Generic FCP for VSP fallback
35 36
Documentation/devicetree/bindings/media/renesas,vsp1.yaml+1−0
@@ -25,6 +25,7 @@ properties: · 24 unmodified lines
25 - enum:25 - enum:
26 - renesas,r9a07g043u-vsp2 # RZ/G2UL26 - renesas,r9a07g043u-vsp2 # RZ/G2UL
27 - renesas,r9a07g054-vsp2 # RZ/V2L27 - renesas,r9a07g054-vsp2 # RZ/V2L
28 - renesas,r9a09g056-vsp2 # RZ/V2N
28 - renesas,r9a09g057-vsp2 # RZ/V2H(P)29 - renesas,r9a09g057-vsp2 # RZ/V2H(P)
29 - const: renesas,r9a07g044-vsp2 # RZ/G2L fallback30 - const: renesas,r9a07g044-vsp2 # RZ/G2L fallback
30 31
Documentation/devicetree/bindings/media/rockchip,vdec.yaml+77−3
@@ -10,13 +10,15 @@ maintainers: · 9 unmodified lines
10 - Heiko Stuebner <heiko@sntech.de>10 - Heiko Stuebner <heiko@sntech.de>
11 11
12description: |-12description: |-
13 The Rockchip rk3399 has a stateless Video Decoder that can decodes H.264,13 Rockchip SoCs have variants of the same stateless Video Decoder that can
14 HEVC an VP9 streams.14 decodes H.264, HEVC, VP9 and AV1 streams, depending on the variant.
15 15
16properties:16properties:
17 compatible:17 compatible:
18 oneOf:18 oneOf:
19 - const: rockchip,rk3399-vdec19 - const: rockchip,rk3399-vdec
20 - const: rockchip,rk3576-vdec
21 - const: rockchip,rk3588-vdec
20 - items:22 - items:
21 - enum:23 - enum:
22 - rockchip,rk3228-vdec24 - rockchip,rk3228-vdec
@@ -24,35 +26,72 @@ properties: · 1 unmodified line
24 - const: rockchip,rk3399-vdec26 - const: rockchip,rk3399-vdec
25 27
26 reg:28 reg:
27 maxItems: 129 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
28 40
29 interrupts:41 interrupts:
30 maxItems: 142 maxItems: 1
31 43
32 clocks:44 clocks:
45 minItems: 4
33 items:46 items:
34 - description: The Video Decoder AXI interface clock47 - description: The Video Decoder AXI interface clock
35 - description: The Video Decoder AHB interface clock48 - description: The Video Decoder AHB interface clock
36 - description: The Video Decoded CABAC clock49 - description: The Video Decoded CABAC clock
37 - description: The Video Decoder core clock50 - description: The Video Decoder core clock
51 - description: The Video decoder HEVC CABAC clock
38 52
39 clock-names:53 clock-names:
54 minItems: 4
40 items:55 items:
41 - const: axi56 - const: axi
42 - const: ahb57 - const: ahb
43 - const: cabac58 - const: cabac
44 - const: core59 - const: core
60 - const: hevc_cabac
45 61
46 assigned-clocks: true62 assigned-clocks: true
47 63
48 assigned-clock-rates: true64 assigned-clock-rates: true
49 65
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
50 power-domains:82 power-domains:
51 maxItems: 183 maxItems: 1
52 84
53 iommus:85 iommus:
54 maxItems: 186 maxItems: 1
55 87
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
56required:95required:
57 - compatible96 - compatible
58 - reg97 - reg
@@ -61,6 +100,41 @@ required: · 2 unmodified lines
61 - clock-names100 - clock-names
62 - power-domains101 - power-domains
63 102
103allOf:
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
64additionalProperties: false138additionalProperties: false
65 139
66examples:140examples:
Documentation/driver-api/media/v4l2-controls.rst+3−6
@@ -110,6 +110,7 @@ For sub-device drivers: · 109 unmodified lines
110 110
111 v4l2_ctrl_handler_free(&foo->ctrl_handler);111 v4l2_ctrl_handler_free(&foo->ctrl_handler);
112 112
113:c:func:`v4l2_ctrl_handler_free` does not touch the handler's ``error`` field.
113 114
1142) Add controls:1152) Add controls:
115 116
@@ -191,12 +192,8 @@ These functions are typically called right after the · 75 unmodified lines
191 V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,192 V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
192 0, test_pattern);193 0, test_pattern);
193 ...194 ...
194 if (foo->ctrl_handler.error) {195 if (foo->ctrl_handler.error)
195 int err = foo->ctrl_handler.error;196 return v4l2_ctrl_handler_free(&foo->ctrl_handler);
196
197 v4l2_ctrl_handler_free(&foo->ctrl_handler);
198 return err;
199 }
200 197
201The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to198The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to
202the new control, but if you do not need to access the pointer outside the199the 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
41 # <op> rx-clear clear all rx error injections for <op>41 # <op> rx-clear clear all rx error injections for <op>
42 # <op> tx-clear clear all tx error injections for <op>42 # <op> tx-clear clear all tx error injections for <op>
43 #43 #
44 # RX error injection settings:
45 # rx-no-low-drive do not generate low-drive pulses
46 #
44 # RX error injection:47 # RX error injection:
45 # <op>[,<mode>] rx-nack NACK the message instead of sending an ACK48 # <op>[,<mode>] rx-nack NACK the message instead of sending an ACK
46 # <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position49 # <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
53 # tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse56 # tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse
54 # tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse57 # tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse
55 # tx-custom-pulse transmit the custom pulse once the bus is idle58 # 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
56 #63 #
57 # TX error injection:64 # TX error injection:
58 # <op>[,<mode>] tx-no-eom don't set the EOM bit65 # <op>[,<mode>] tx-no-eom don't set the EOM bit
@@ -193,6 +200,14 @@ Receive Messages · 134 unmodified lines
193 This does not work if the remote CEC transmitter has logical address200 This does not work if the remote CEC transmitter has logical address
194 0 ('TV') since that will always win.201 0 ('TV') since that will always win.
195 202
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
196Transmit Messages211Transmit Messages
197-----------------212-----------------
198 213
@@ -327,3 +342,30 @@ Custom Pulses · 128 unmodified lines
327 342
328``tx-custom-pulse``343``tx-custom-pulse``
329 Transmit a single custom pulse as soon as the CEC bus is idle.344 Transmit a single custom pulse as soon as the CEC bus is idle.
345
346Glitch Pulses
347-------------
348
349This emulates what happens if the signal on the CEC line is seeing spurious
350pulses. Typically this happens after the falling or rising edge where there
351is a short voltage fluctuation that, if the CEC hardware doesn't do
352deglitching, can be seen as a spurious pulse and can cause a Low Drive
353condition 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
150========150========
151 151
152 152
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"
154 154
155:author: International Telecommunication Union (http://www.itu.int)155:author: International Telecommunication Union (http://www.itu.int)
156 156
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
48The :ref:`video standard <standard>` ioctls provide information vital48The :ref:`video standard <standard>` ioctls provide information vital
49to program a sliced VBI device, therefore must be supported.49to program a sliced VBI device, therefore must be supported.
50 50
51.. _sliced-vbi-format-negotitation:51.. _sliced-vbi-format-negotiation:
52 52
53Sliced VBI Format Negotiation53Sliced VBI Format Negotiation
54=============================54=============================
@@ -377,7 +377,7 @@ Sliced VBI Data in MPEG Streams · 322 unmodified lines
377 377
378If a device can produce an MPEG output stream, it may be capable of378If a device can produce an MPEG output stream, it may be capable of
379providing379providing
380:ref:`negotiated sliced VBI services <sliced-vbi-format-negotitation>`380:ref:`negotiated sliced VBI services <sliced-vbi-format-negotiation>`
381as data embedded in the MPEG stream. Users or applications control this381as data embedded in the MPEG stream. Users or applications control this
382sliced VBI data insertion with the382sliced VBI data insertion with the
383:ref:`V4L2_CID_MPEG_STREAM_VBI_FMT <v4l2-mpeg-stream-vbi-fmt>`383: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
64 broadcasts speech. If the transmitter doesn't make this distinction,64 broadcasts speech. If the transmitter doesn't make this distinction,
65 then it will be set.65 then it will be set.
66 66
67``V4L2_CID_TUNE_DEEMPHASIS``67``V4L2_CID_TUNE_DEEMPHASIS (enum)``
68 (enum)
69
70enum v4l2_deemphasis -
71 Configures the de-emphasis value for reception. A de-emphasis filter68 Configures the de-emphasis value for reception. A de-emphasis filter
72 is applied to the broadcast to accentuate the high audio69 is applied to the broadcast to accentuate the high audio
73 frequencies. Depending on the region, a time constant of either 5070 frequencies. Depending on the region, a time constant of either 50
74 or 75 useconds is used. The enum v4l2_deemphasis defines possible71 or 75 microseconds is used. The enum v4l2_deemphasis defines possible
75 values for de-emphasis. Here they are:72 values for de-emphasis. They are:
76
77
78 73
79.. flat-table::74.. flat-table::
80 :header-rows: 075 :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
104 104
105``V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (integer)``105``V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (integer)``
106 Sets the audio deviation limiter feature release time. Unit is in106 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.
108 108
109``V4L2_CID_AUDIO_LIMITER_DEVIATION (integer)``109``V4L2_CID_AUDIO_LIMITER_DEVIATION (integer)``
110 Configures audio frequency deviation level in Hz. The range and step110 Configures audio frequency deviation level in Hz. The range and step
@@ -121,16 +121,16 @@ FM_TX Control IDs · 10 unmodified lines
121 range and step are driver-specific.121 range and step are driver-specific.
122 122
123``V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (integer)``123``V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (integer)``
124 Sets the threshold level for audio compression freature. It is a dB124 Sets the threshold level for audio compression feature. It is a dB
125 value. The range and step are driver-specific.125 value. The range and step are driver-specific.
126 126
127``V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (integer)``127``V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (integer)``
128 Sets the attack time for audio compression feature. It is a useconds128 Sets the attack time for audio compression feature. It is a microseconds
129 value. The range and step are driver-specific.129 value. The range and step are driver-specific.
130 130
131``V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (integer)``131``V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (integer)``
132 Sets the release time for audio compression feature. It is a132 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.
134 134
135``V4L2_CID_PILOT_TONE_ENABLED (boolean)``135``V4L2_CID_PILOT_TONE_ENABLED (boolean)``
136 Enables or disables the pilot tone generation feature.136 Enables or disables the pilot tone generation feature.
@@ -143,17 +143,12 @@ FM_TX Control IDs · 6 unmodified lines
143 Configures pilot tone frequency value. Unit is in Hz. The range and143 Configures pilot tone frequency value. Unit is in Hz. The range and
144 step are driver-specific.144 step are driver-specific.
145 145
146``V4L2_CID_TUNE_PREEMPHASIS``146``V4L2_CID_TUNE_PREEMPHASIS (enum)``
147 (enum)
148
149enum v4l2_preemphasis -
150 Configures the pre-emphasis value for broadcasting. A pre-emphasis147 Configures the pre-emphasis value for broadcasting. A pre-emphasis
151 filter is applied to the broadcast to accentuate the high audio148 filter is applied to the broadcast to accentuate the high audio
152 frequencies. Depending on the region, a time constant of either 50149 frequencies. Depending on the region, a time constant of either 50
153 or 75 useconds is used. The enum v4l2_preemphasis defines possible150 or 75 microseconds is used. The enum v4l2_preemphasis defines possible
154 values for pre-emphasis. Here they are:151 values for pre-emphasis. They are:
155
156
157 152
158.. flat-table::153.. flat-table::
159 :header-rows: 0154 :header-rows: 0
@@ -166,8 +161,6 @@ enum v4l2_preemphasis - · 6 unmodified lines
166 * - ``V4L2_PREEMPHASIS_75_uS``161 * - ``V4L2_PREEMPHASIS_75_uS``
167 - A pre-emphasis of 75 uS is used.162 - A pre-emphasis of 75 uS is used.
168 163
169
170
171``V4L2_CID_TUNE_POWER_LEVEL (integer)``164``V4L2_CID_TUNE_POWER_LEVEL (integer)``
172 Sets the output power level for signal transmission. Unit is in165 Sets the output power level for signal transmission. Unit is in
173 dBuV. Range and step are driver-specific.166 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
20 metafmt-pisp-fe20 metafmt-pisp-fe
21 metafmt-rkisp121 metafmt-rkisp1
22 metafmt-uvc22 metafmt-uvc
23 metafmt-uvc-msxu-1-5
23 metafmt-vivid24 metafmt-vivid
24 metafmt-vsp1-hgo25 metafmt-vsp1-hgo
25 metafmt-vsp1-hgt26 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***********************************
6V4L2_META_FMT_UVC_MSXU_1_5 ('UVCM')
7***********************************
8
9Microsoft(R)'s UVC Payload Metadata.
10
11
12Description
13===========
14
15V4L2_META_FMT_UVC_MSXU_1_5 buffers follow the metadata buffer layout of
16V4L2_META_FMT_UVC with the only difference that it includes all the UVC
17metadata in the `buffer[]` field, not just the first 2-12 bytes.
18
19The 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
44 them44 them
45 * - :cspan:`1` *The rest is an exact copy of the UVC payload header:*45 * - :cspan:`1` *The rest is an exact copy of the UVC payload header:*
46 * - __u8 length;46 * - __u8 length;
47 - length of the rest of the block, including this field47 - 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.
48 * - __u8 flags;50 * - __u8 flags;
49 - Flags, indicating presence of other standard UVC fields51 - Flags, indicating presence of other standard UVC fields
50 * - __u8 buf[];52 * - __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
19.. toctree::19.. toctree::
20 :maxdepth: 120 :maxdepth: 1
21 21
22 pixfmt-rawnn-cru
22 pixfmt-srggb823 pixfmt-srggb8
23 pixfmt-srggb8-pisp-comp24 pixfmt-srggb8-pisp-comp
24 pixfmt-srggb1025 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**********************************************************************************************************************************
9V4L2_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===============================================================
13Renesas 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
21Description
22===========
23
24These pixel formats are some of the RAW outputs for the Camera Receiver Unit in
25the Renesas RZ/V2H SoC. They are raw formats which pack pixels contiguously into
2664-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
6.. _v4l2-pix-fmt-sgrbg12p:6.. _v4l2-pix-fmt-sgrbg12p:
7 7
8*******************************************************************************************************************************8*******************************************************************************************************************************
9V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC'),9V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC')
10*******************************************************************************************************************************10*******************************************************************************************************************************
11 11
12 12
@@ -20,7 +20,7 @@ Description · 7 unmodified lines
20These four pixel formats are packed raw sRGB / Bayer formats with 1220These four pixel formats are packed raw sRGB / Bayer formats with 12
21bits per colour. Every two consecutive samples are packed into three21bits per colour. Every two consecutive samples are packed into three
22bytes. Each of the first two bytes contain the 8 high order bits of22bytes. Each of the first two bytes contain the 8 high order bits of
23the pixels, and the third byte contains the four least significants23the pixels, and the third byte contains the four least significant
24bits of each pixel, in the same order.24bits of each pixel, in the same order.
25 25
26Each n-pixel row contains n/2 green samples and n/2 blue or red26Each 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
24bits per colour. Every four consecutive samples are packed into seven24bits per colour. Every four consecutive samples are packed into seven
25bytes. Each of the first four bytes contain the eight high order bits25bytes. Each of the first four bytes contain the eight high order bits
26of the pixels, and the three following bytes contains the six least26of the pixels, and the three following bytes contains the six least
27significants bits of each pixel, in the same order.27significant bits of each pixel, in the same order.
28 28
29Each n-pixel row contains n/2 green samples and n/2 blue or red samples,29Each n-pixel row contains n/2 green samples and n/2 blue or red samples,
30with alternating green-red and green-blue rows. They are conventionally30with 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
824 824
825ALLIED VISION ALVIUM CAMERA DRIVER825ALLIED VISION ALVIUM CAMERA DRIVER
826M: Tommaso Merciai <tomm.merciai@gmail.com>826M: Tommaso Merciai <tomm.merciai@gmail.com>
827M: Martin Hecht <martin.hecht@avnet.eu>827M: Martin Hecht <mhecht73@gmail.com>
828L: linux-media@vger.kernel.org828L: linux-media@vger.kernel.org
829S: Maintained829S: Maintained
830F: Documentation/devicetree/bindings/media/i2c/alliedvision,alvium-csi2.yaml830F: Documentation/devicetree/bindings/media/i2c/alliedvision,alvium-csi2.yaml
@@ -12397,6 +12397,15 @@ T: git git://linuxtv.org/media.git · 11566 unmodified lines
12397F: Documentation/admin-guide/media/ipu6-isys.rst12397F: Documentation/admin-guide/media/ipu6-isys.rst
12398F: drivers/media/pci/intel/ipu6/12398F: drivers/media/pci/intel/ipu6/
12399 12399
12400INTEL IPU7 INPUT SYSTEM DRIVER
12401M: Sakari Ailus <sakari.ailus@linux.intel.com>
12402R: Bingbu Cao <bingbu.cao@intel.com>
12403R: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
12404L: linux-media@vger.kernel.org
12405S: Maintained
12406T: git git://linuxtv.org/media.git
12407F: drivers/staging/media/ipu7/
12408
12400INTEL ISHTP ECLITE DRIVER12409INTEL ISHTP ECLITE DRIVER
12401M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>12410M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
12402L: platform-driver-x86@vger.kernel.org12411L: platform-driver-x86@vger.kernel.org
@@ -12684,6 +12693,16 @@ W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi · 281 unmodified lines
12684T: git https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git/12693T: git https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git/
12685F: drivers/net/wireless/intel/iwlwifi/12694F: drivers/net/wireless/intel/iwlwifi/
12686 12695
12696INTEL VISION SENSING CONTROLLER DRIVER
12697M: Sakari Ailus <sakari.ailus@linux.intel.com>
12698R: Bingbu Cao <bingbu.cao@intel.com>
12699R: Lixu Zhang <lixu.zhang@intel.com>
12700R: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
12701L: linux-media@vger.kernel.org
12702S: Maintained
12703T: git git://linuxtv.org/media.git
12704F: drivers/media/pci/intel/ivsc/
12705
12687INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER12706INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER
12688S: Orphan12707S: Orphan
12689W: https://slimbootloader.github.io/security/firmware-update.html12708W: https://slimbootloader.github.io/security/firmware-update.html
@@ -18134,6 +18153,7 @@ NXP i.MX 8M ISI DRIVER · 5444 unmodified lines
18134M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>18153M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
18135L: linux-media@vger.kernel.org18154L: linux-media@vger.kernel.org
18136S: Maintained18155S: Maintained
18156F: Documentation/devicetree/bindings/media/fsl,imx8*-isi.yaml
18137F: Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml18157F: Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
18138F: drivers/media/platform/nxp/imx8-isi/18158F: drivers/media/platform/nxp/imx8-isi/
18139 18159
@@ -20548,6 +20568,7 @@ QUALCOMM CAMERA SUBSYSTEM DRIVER · 2408 unmodified lines
20548M: Robert Foss <rfoss@kernel.org>20568M: Robert Foss <rfoss@kernel.org>
20549M: Todor Tomov <todor.too@gmail.com>20569M: Todor Tomov <todor.too@gmail.com>
20550M: Bryan O'Donoghue <bryan.odonoghue@linaro.org>20570M: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
20571R: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
20551L: linux-media@vger.kernel.org20572L: linux-media@vger.kernel.org
20552S: Maintained20573S: Maintained
20553F: Documentation/admin-guide/media/qcom_camss.rst20574F: Documentation/admin-guide/media/qcom_camss.rst
@@ -21693,6 +21714,14 @@ S: Maintained · 1139 unmodified lines
21693F: Documentation/devicetree/bindings/media/rockchip-rga.yaml21714F: Documentation/devicetree/bindings/media/rockchip-rga.yaml
21694F: drivers/media/platform/rockchip/rga/21715F: drivers/media/platform/rockchip/rga/
21695 21716
21717ROCKCHIP RKVDEC VIDEO DECODER DRIVER
21718M: Detlev Casanova <detlev.casanova@collabora.com>
21719L: linux-media@vger.kernel.org
21720L: linux-rockchip@lists.infradead.org
21721S: Maintained
21722F: Documentation/devicetree/bindings/media/rockchip,vdec.yaml
21723F: drivers/media/platform/rockchip/rkvdec/
21724
21696ROCKCHIP RK3308 INTERNAL AUDIO CODEC21725ROCKCHIP RK3308 INTERNAL AUDIO CODEC
21697M: Luca Ceresoli <luca.ceresoli@bootlin.com>21726M: Luca Ceresoli <luca.ceresoli@bootlin.com>
21698S: Maintained21727S: Maintained
@@ -26081,6 +26110,7 @@ S: Maintained · 4382 unmodified lines
26081W: http://www.ideasonboard.org/uvc/26110W: http://www.ideasonboard.org/uvc/
26082T: git git://linuxtv.org/media.git26111T: git git://linuxtv.org/media.git
26083F: Documentation/userspace-api/media/drivers/uvcvideo.rst26112F: Documentation/userspace-api/media/drivers/uvcvideo.rst
26113F: Documentation/userspace-api/media/v4l/metafmt-uvc-msxu-1-5.rst
26084F: Documentation/userspace-api/media/v4l/metafmt-uvc.rst26114F: Documentation/userspace-api/media/v4l/metafmt-uvc.rst
26085F: drivers/media/common/uvc.c26115F: drivers/media/common/uvc.c
26086F: drivers/media/usb/uvc/26116F: 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
91 if (!strcmp(token, "clear")) {91 if (!strcmp(token, "clear")) {
92 memset(pin->error_inj, 0, sizeof(pin->error_inj));92 memset(pin->error_inj, 0, sizeof(pin->error_inj));
93 pin->rx_toggle = pin->tx_toggle = false;93 pin->rx_toggle = pin->tx_toggle = false;
94 pin->rx_no_low_drive = false;
94 pin->tx_ignore_nack_until_eom = false;95 pin->tx_ignore_nack_until_eom = false;
95 pin->tx_custom_pulse = false;96 pin->tx_custom_pulse = false;
96 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;97 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
97 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;98 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;
98 return true;103 return true;
99 }104 }
100 if (!strcmp(token, "rx-clear")) {105 if (!strcmp(token, "rx-clear")) {
101 for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++)106 for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++)
102 pin->error_inj[i] &= ~CEC_ERROR_INJ_RX_MASK;107 pin->error_inj[i] &= ~CEC_ERROR_INJ_RX_MASK;
103 pin->rx_toggle = false;108 pin->rx_toggle = false;
109 pin->rx_no_low_drive = false;
104 return true;110 return true;
105 }111 }
106 if (!strcmp(token, "tx-clear")) {112 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
111 pin->tx_custom_pulse = false;117 pin->tx_custom_pulse = false;
112 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;118 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
113 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;119 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;
114 return true;128 return true;
115 }129 }
116 if (!strcmp(token, "tx-ignore-nack-until-eom")) {130 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
122 cec_pin_start_timer(pin);136 cec_pin_start_timer(pin);
123 return true;137 return true;
124 }138 }
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 }
125 if (!p)147 if (!p)
126 return false;148 return false;
127 149
@@ -139,7 +161,23 @@ bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line) · 11 unmodified lines
139 161
140 if (kstrtou32(p, 0, &usecs) || usecs > 10000000)162 if (kstrtou32(p, 0, &usecs) || usecs > 10000000)
141 return false;163 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;
143 return true;181 return true;
144 }182 }
145 183
@@ -273,6 +311,9 @@ int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf) · 127 unmodified lines
273 seq_puts(sf, "# <op> rx-clear clear all rx error injections for <op>\n");311 seq_puts(sf, "# <op> rx-clear clear all rx error injections for <op>\n");
274 seq_puts(sf, "# <op> tx-clear clear all tx error injections for <op>\n");312 seq_puts(sf, "# <op> tx-clear clear all tx error injections for <op>\n");
275 seq_puts(sf, "#\n");313 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");
276 seq_puts(sf, "# RX error injection:\n");317 seq_puts(sf, "# RX error injection:\n");
277 seq_puts(sf, "# <op>[,<mode>] rx-nack NACK the message instead of sending an ACK\n");318 seq_puts(sf, "# <op>[,<mode>] rx-nack NACK the message instead of sending an ACK\n");
278 seq_puts(sf, "# <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position\n");319 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
285 seq_puts(sf, "# tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse\n");326 seq_puts(sf, "# tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse\n");
286 seq_puts(sf, "# tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse\n");327 seq_puts(sf, "# tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse\n");
287 seq_puts(sf, "# tx-custom-pulse transmit the custom pulse once the bus is idle\n");328 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");
288 seq_puts(sf, "#\n");333 seq_puts(sf, "#\n");
289 seq_puts(sf, "# TX error injection:\n");334 seq_puts(sf, "# TX error injection:\n");
290 seq_puts(sf, "# <op>[,<mode>] tx-no-eom don't set the EOM bit\n");335 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
332 }377 }
333 }378 }
334 379
380 if (pin->rx_no_low_drive)
381 seq_puts(sf, "rx-no-low-drive\n");
335 if (pin->tx_ignore_nack_until_eom)382 if (pin->tx_ignore_nack_until_eom)
336 seq_puts(sf, "tx-ignore-nack-until-eom\n");383 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");
337 if (pin->tx_custom_pulse)388 if (pin->tx_custom_pulse)
338 seq_puts(sf, "tx-custom-pulse\n");389 seq_puts(sf, "tx-custom-pulse\n");
339 if (pin->tx_custom_low_usecs != CEC_TIM_CUSTOM_DEFAULT)390 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
342 if (pin->tx_custom_high_usecs != CEC_TIM_CUSTOM_DEFAULT)393 if (pin->tx_custom_high_usecs != CEC_TIM_CUSTOM_DEFAULT)
343 seq_printf(sf, "tx-custom-high-usecs %u\n",394 seq_printf(sf, "tx-custom-high-usecs %u\n",
344 pin->tx_custom_high_usecs);395 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);
345 return 0;402 return 0;
346}403}
drivers/media/cec/core/cec-pin-priv.h+8−0
@@ -164,6 +164,9 @@ enum cec_pin_state { · 163 unmodified lines
164/* The default for the low/high time of the custom pulse */164/* The default for the low/high time of the custom pulse */
165#define CEC_TIM_CUSTOM_DEFAULT 1000165#define CEC_TIM_CUSTOM_DEFAULT 1000
166 166
167/* The default for the low/high time of the glitch pulse */
168#define CEC_TIM_GLITCH_DEFAULT 1
169
167#define CEC_NUM_PIN_EVENTS 128170#define CEC_NUM_PIN_EVENTS 128
168#define CEC_PIN_EVENT_FL_IS_HIGH (1 << 0)171#define CEC_PIN_EVENT_FL_IS_HIGH (1 << 0)
169#define CEC_PIN_EVENT_FL_DROPPED (1 << 1)172#define CEC_PIN_EVENT_FL_DROPPED (1 << 1)
@@ -225,12 +228,17 @@ struct cec_pin { · 55 unmodified lines
225 u32 timer_max_overrun;228 u32 timer_max_overrun;
226 u32 timer_sum_overrun;229 u32 timer_sum_overrun;
227 230
231 bool rx_no_low_drive;
228 u32 tx_custom_low_usecs;232 u32 tx_custom_low_usecs;
229 u32 tx_custom_high_usecs;233 u32 tx_custom_high_usecs;
234 u32 tx_glitch_low_usecs;
235 u32 tx_glitch_high_usecs;
230 bool tx_ignore_nack_until_eom;236 bool tx_ignore_nack_until_eom;
231 bool tx_custom_pulse;237 bool tx_custom_pulse;
232 bool tx_generated_poll;238 bool tx_generated_poll;
233 bool tx_post_eom;239 bool tx_post_eom;
240 bool tx_glitch_falling_edge;
241 bool tx_glitch_rising_edge;
234 u8 tx_extra_bytes;242 u8 tx_extra_bytes;
235 u32 tx_low_drive_cnt;243 u32 tx_low_drive_cnt;
236#ifdef CONFIG_CEC_PIN_ERROR_INJ244#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
142 return v;142 return v;
143}143}
144 144
145static 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
145static void cec_pin_low(struct cec_pin *pin)168static void cec_pin_low(struct cec_pin *pin)
146{169{
147 call_void_pin_op(pin, low);170 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);
148 cec_pin_update(pin, false, false);173 cec_pin_update(pin, false, false);
149}174}
150 175
151static bool cec_pin_high(struct cec_pin *pin)176static bool cec_pin_high(struct cec_pin *pin)
152{177{
153 call_void_pin_op(pin, high);178 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);
154 return cec_pin_read(pin);181 return cec_pin_read(pin);
155}182}
156 183
@@ -770,7 +797,7 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) · 613 unmodified lines
770 * Go to low drive state when the total bit time is797 * Go to low drive state when the total bit time is
771 * too short.798 * too short.
772 */799 */
773 if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) {800 if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN && !pin->rx_no_low_drive) {
774 if (!pin->rx_data_bit_too_short_cnt++) {801 if (!pin->rx_data_bit_too_short_cnt++) {
775 pin->rx_data_bit_too_short_ts = ktime_to_ns(pin->ts);802 pin->rx_data_bit_too_short_ts = ktime_to_ns(pin->ts);
776 pin->rx_data_bit_too_short_delta = delta;803 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
1350 init_waitqueue_head(&pin->kthread_waitq);1377 init_waitqueue_head(&pin->kthread_waitq);
1351 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;1378 pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT;
1352 pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT;1379 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;
1353 1382
1354 adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name,1383 adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name,
1355 caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN,1384 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
61 gpiod_set_value(cec->cec_gpio, 0);61 gpiod_set_value(cec->cec_gpio, 0);
62}62}
63 63
64static irqreturn_t cec_hpd_gpio_irq_handler_thread(int irq, void *priv)64static irqreturn_t cec_gpio_5v_irq_handler_thread(int irq, void *priv)
65{65{
66 struct cec_gpio *cec = priv;66 struct cec_gpio *cec = priv;
67 int val = gpiod_get_value_cansleep(cec->v5_gpio);
68 bool is_high = val > 0;
67 69
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);
69 return IRQ_HANDLED;75 return IRQ_HANDLED;
70}76}
71 77
72static irqreturn_t cec_5v_gpio_irq_handler(int irq, void *priv)78static irqreturn_t cec_gpio_5v_irq_handler(int irq, void *priv)
73{79{
74 struct cec_gpio *cec = priv;80 struct cec_gpio *cec = priv;
75 int val = gpiod_get_value(cec->v5_gpio);
76 bool is_high = val > 0;
77 81
78 if (val < 0 || is_high == cec->v5_is_high)
79 return IRQ_HANDLED;
80 cec->v5_ts = ktime_get();82 cec->v5_ts = ktime_get();
81 cec->v5_is_high = is_high;
82 return IRQ_WAKE_THREAD;83 return IRQ_WAKE_THREAD;
83}84}
84 85
85static irqreturn_t cec_5v_gpio_irq_handler_thread(int irq, void *priv)86static irqreturn_t cec_gpio_hpd_irq_handler_thread(int irq, void *priv)
86{87{
87 struct cec_gpio *cec = priv;88 struct cec_gpio *cec = priv;
89 int val = gpiod_get_value_cansleep(cec->hpd_gpio);
90 bool is_high = val > 0;
88 91
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);
90 return IRQ_HANDLED;97 return IRQ_HANDLED;
91}98}
92 99
93static irqreturn_t cec_hpd_gpio_irq_handler(int irq, void *priv)100static irqreturn_t cec_gpio_hpd_irq_handler(int irq, void *priv)
94{101{
95 struct cec_gpio *cec = priv;102 struct cec_gpio *cec = priv;
96 int val = gpiod_get_value(cec->hpd_gpio);
97 bool is_high = val > 0;
98 103
99 if (val < 0 || is_high == cec->hpd_is_high)
100 return IRQ_HANDLED;
101 cec->hpd_ts = ktime_get();104 cec->hpd_ts = ktime_get();
102 cec->hpd_is_high = is_high;
103 return IRQ_WAKE_THREAD;105 return IRQ_WAKE_THREAD;
104}106}
105 107
106static irqreturn_t cec_gpio_irq_handler(int irq, void *priv)108static irqreturn_t cec_gpio_cec_irq_handler(int irq, void *priv)
107{109{
108 struct cec_gpio *cec = priv;110 struct cec_gpio *cec = priv;
109 int val = gpiod_get_value(cec->cec_gpio);111 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
113 return IRQ_HANDLED;115 return IRQ_HANDLED;
114}116}
115 117
116static bool cec_gpio_enable_irq(struct cec_adapter *adap)118static bool cec_gpio_cec_enable_irq(struct cec_adapter *adap)
117{119{
118 struct cec_gpio *cec = cec_get_drvdata(adap);120 struct cec_gpio *cec = cec_get_drvdata(adap);
119 121
@@ -121,7 +123,7 @@ static bool cec_gpio_enable_irq(struct cec_adapter *adap) · 1 unmodified line
121 return true;123 return true;
122}124}
123 125
124static void cec_gpio_disable_irq(struct cec_adapter *adap)126static void cec_gpio_cec_disable_irq(struct cec_adapter *adap)
125{127{
126 struct cec_gpio *cec = cec_get_drvdata(adap);128 struct cec_gpio *cec = cec_get_drvdata(adap);
127 129
@@ -148,7 +150,7 @@ static int cec_gpio_read_hpd(struct cec_adapter *adap) · 20 unmodified lines
148 150
149 if (!cec->hpd_gpio)151 if (!cec->hpd_gpio)
150 return -ENOTTY;152 return -ENOTTY;
151 return gpiod_get_value(cec->hpd_gpio);153 return gpiod_get_value_cansleep(cec->hpd_gpio);
152}154}
153 155
154static int cec_gpio_read_5v(struct cec_adapter *adap)156static 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
157 159
158 if (!cec->v5_gpio)160 if (!cec->v5_gpio)
159 return -ENOTTY;161 return -ENOTTY;
160 return gpiod_get_value(cec->v5_gpio);162 return gpiod_get_value_cansleep(cec->v5_gpio);
161}163}
162 164
163static const struct cec_pin_ops cec_gpio_pin_ops = {165static const struct cec_pin_ops cec_gpio_pin_ops = {
164 .read = cec_gpio_read,166 .read = cec_gpio_read,
165 .low = cec_gpio_low,167 .low = cec_gpio_low,
166 .high = cec_gpio_high,168 .high = cec_gpio_high,
167 .enable_irq = cec_gpio_enable_irq,169 .enable_irq = cec_gpio_cec_enable_irq,
168 .disable_irq = cec_gpio_disable_irq,170 .disable_irq = cec_gpio_cec_disable_irq,
169 .status = cec_gpio_status,171 .status = cec_gpio_status,
170 .read_hpd = cec_gpio_read_hpd,172 .read_hpd = cec_gpio_read_hpd,
171 .read_5v = cec_gpio_read_5v,173 .read_5v = cec_gpio_read_5v,
@@ -209,7 +211,7 @@ static int cec_gpio_probe(struct platform_device *pdev) · 37 unmodified lines
209 if (IS_ERR(cec->adap))211 if (IS_ERR(cec->adap))
210 return PTR_ERR(cec->adap);212 return PTR_ERR(cec->adap);
211 213
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,
213 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,215 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,
214 cec->adap->name, cec);216 cec->adap->name, cec);
215 if (ret)217 if (ret)
@@ -218,8 +220,8 @@ static int cec_gpio_probe(struct platform_device *pdev) · 2 unmodified lines
218 if (cec->hpd_gpio) {220 if (cec->hpd_gpio) {
219 cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio);221 cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio);
220 ret = devm_request_threaded_irq(dev, cec->hpd_irq,222 ret = devm_request_threaded_irq(dev, cec->hpd_irq,
221 cec_hpd_gpio_irq_handler,223 cec_gpio_hpd_irq_handler,
222 cec_hpd_gpio_irq_handler_thread,224 cec_gpio_hpd_irq_handler_thread,
223 IRQF_ONESHOT |225 IRQF_ONESHOT |
224 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,226 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
225 "hpd-gpio", cec);227 "hpd-gpio", cec);
@@ -230,8 +232,8 @@ static int cec_gpio_probe(struct platform_device *pdev) · 4 unmodified lines
230 if (cec->v5_gpio) {232 if (cec->v5_gpio) {
231 cec->v5_irq = gpiod_to_irq(cec->v5_gpio);233 cec->v5_irq = gpiod_to_irq(cec->v5_gpio);
232 ret = devm_request_threaded_irq(dev, cec->v5_irq,234 ret = devm_request_threaded_irq(dev, cec->v5_irq,
233 cec_5v_gpio_irq_handler,235 cec_gpio_5v_irq_handler,
234 cec_5v_gpio_irq_handler_thread,236 cec_gpio_5v_irq_handler_thread,
235 IRQF_ONESHOT |237 IRQF_ONESHOT |
236 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,238 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
237 "v5-gpio", cec);239 "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
171{171{
172 struct rain *rain = serio_get_drvdata(serio);172 struct rain *rain = serio_get_drvdata(serio);
173 173
174 spin_lock(&rain->buf_lock);
174 if (rain->buf_len == DATA_SIZE) {175 if (rain->buf_len == DATA_SIZE) {
176 spin_unlock(&rain->buf_lock);
175 dev_warn_once(rain->dev, "buffer overflow\n");177 dev_warn_once(rain->dev, "buffer overflow\n");
176 return IRQ_HANDLED;178 return IRQ_HANDLED;
177 }179 }
178 spin_lock(&rain->buf_lock);
179 rain->buf_len++;180 rain->buf_len++;
180 rain->buf[rain->buf_wr_idx] = data;181 rain->buf[rain->buf_wr_idx] = data;
181 rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff;182 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
209 return I2C_FUNC_I2C;209 return I2C_FUNC_I2C;
210}210}
211 211
212static struct i2c_algorithm flexcop_algo = {212static const struct i2c_algorithm flexcop_algo = {
213 .master_xfer = flexcop_master_xfer,213 .master_xfer = flexcop_master_xfer,
214 .functionality = flexcop_i2c_func,214 .functionality = flexcop_i2c_func,
215};215};
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
433 return cxd2820r_gpio(&priv->fe, gpio);433 return cxd2820r_gpio(&priv->fe, gpio);
434}434}
435 435
436static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val)436static int cxd2820r_gpio_set(struct gpio_chip *chip, unsigned int nr, int val)
437{437{
438 struct cxd2820r_priv *priv = gpiochip_get_data(chip);438 struct cxd2820r_priv *priv = gpiochip_get_data(chip);
439 struct i2c_client *client = priv->client[0];439 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
446 446
447 (void) cxd2820r_gpio(&priv->fe, gpio);447 (void) cxd2820r_gpio(&priv->fe, gpio);
448 448
449 return;449 return 0;
450}450}
451 451
452static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr)452static 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
651 priv->gpio_chip.parent = &client->dev;651 priv->gpio_chip.parent = &client->dev;
652 priv->gpio_chip.owner = THIS_MODULE;652 priv->gpio_chip.owner = THIS_MODULE;
653 priv->gpio_chip.direction_output = cxd2820r_gpio_direction_output;653 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;
655 priv->gpio_chip.get = cxd2820r_gpio_get;655 priv->gpio_chip.get = cxd2820r_gpio_get;
656 priv->gpio_chip.base = -1; /* Dynamic allocation */656 priv->gpio_chip.base = -1; /* Dynamic allocation */
657 priv->gpio_chip.ngpio = GPIO_COUNT;657 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
2193 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);2193 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2194 u8 n_overflow = 1;2194 u8 n_overflow = 1;
2195 u16 i = 1000;2195 u16 i = 1000;
2196 if (msg[0].len < 3)
2197 return -EOPNOTSUPP;
2196 u16 serpar_num = msg[0].buf[0];2198 u16 serpar_num = msg[0].buf[0];
2197 2199
2198 while (n_overflow == 1 && i) {2200 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
2212 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);2214 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2213 u8 n_overflow = 1, n_empty = 1;2215 u8 n_overflow = 1, n_empty = 1;
2214 u16 i = 1000;2216 u16 i = 1000;
2217 if (msg[0].len < 1 || msg[1].len < 2)
2218 return -EOPNOTSUPP;
2215 u16 serpar_num = msg[0].buf[0];2219 u16 serpar_num = msg[0].buf[0];
2216 u16 read_word;2220 u16 read_word;
2217 2221
@@ -2256,8 +2260,12 @@ static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, · 38 unmodified lines
2256 u16 word;2260 u16 word;
2257 2261
2258 if (num == 1) { /* write */2262 if (num == 1) { /* write */
2263 if (msg[0].len < 3)
2264 return -EOPNOTSUPP;
2259 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));2265 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
2260 } else {2266 } else {
2267 if (msg[1].len < 2)
2268 return -EOPNOTSUPP;
2261 word = dib7000p_read_word(state, apb_address);2269 word = dib7000p_read_word(state, apb_address);
2262 msg[1].buf[0] = (word >> 8) & 0xff;2270 msg[1].buf[0] = (word >> 8) & 0xff;
2263 msg[1].buf[1] = (word) & 0xff;2271 msg[1].buf[1] = (word) & 0xff;
drivers/media/i2c/Kconfig+14−27
@@ -141,6 +141,7 @@ config VIDEO_IMX214 · 140 unmodified lines
141 depends on GPIOLIB141 depends on GPIOLIB
142 select REGMAP_I2C142 select REGMAP_I2C
143 select V4L2_CCI_I2C143 select V4L2_CCI_I2C
144 select VIDEO_CCS_PLL
144 help145 help
145 This is a Video4Linux2 sensor driver for the Sony146 This is a Video4Linux2 sensor driver for the Sony
146 IMX214 camera.147 IMX214 camera.
@@ -765,24 +766,25 @@ config VIDEO_THP7312 · 618 unmodified lines
765 766
766endmenu767endmenu
767 768
768menu "Lens drivers"769menuconfig VIDEO_CAMERA_LENS
769 visible if MEDIA_CAMERA_SUPPORT770 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
777if VIDEO_CAMERA_LENS
770 778
771config VIDEO_AD5820779config VIDEO_AD5820
772 tristate "AD5820 lens voice coil support"780 tristate "AD5820 lens voice coil support"
773 depends on GPIOLIB && I2C && VIDEO_DEV781 depends on GPIOLIB
774 select MEDIA_CONTROLLER
775 select V4L2_ASYNC
776 help782 help
777 This is a driver for the AD5820 camera lens voice coil.783 This is a driver for the AD5820 camera lens voice coil.
778 It is used for example in Nokia N900 (RX-51).784 It is used for example in Nokia N900 (RX-51).
779 785
780config VIDEO_AK7375786config VIDEO_AK7375
781 tristate "AK7375 lens voice coil support"787 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
786 help788 help
787 This is a driver for the AK7375 camera lens voice coil.789 This is a driver for the AK7375 camera lens voice coil.
788 AK7375 is a 12 bit DAC with 120mA output current sink790 AK7375 is a 12 bit DAC with 120mA output current sink
@@ -791,10 +793,7 @@ config VIDEO_AK7375 · 2 unmodified lines
791 793
792config VIDEO_DW9714794config VIDEO_DW9714
793 tristate "DW9714 lens voice coil support"795 tristate "DW9714 lens voice coil support"
794 depends on I2C && VIDEO_DEV796 depends on GPIOLIB
795 select MEDIA_CONTROLLER
796 select VIDEO_V4L2_SUBDEV_API
797 select V4L2_ASYNC
798 help797 help
799 This is a driver for the DW9714 camera lens voice coil.798 This is a driver for the DW9714 camera lens voice coil.
800 DW9714 is a 10 bit DAC with 120mA output current sink799 DW9714 is a 10 bit DAC with 120mA output current sink
@@ -803,10 +802,6 @@ config VIDEO_DW9714 · 2 unmodified lines
803 802
804config VIDEO_DW9719803config VIDEO_DW9719
805 tristate "DW9719 lens voice coil support"804 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
810 select V4L2_CCI_I2C805 select V4L2_CCI_I2C
811 help806 help
812 This is a driver for the DW9719 camera lens voice coil.807 This is a driver for the DW9719 camera lens voice coil.
@@ -815,10 +810,6 @@ config VIDEO_DW9719 · 2 unmodified lines
815 810
816config VIDEO_DW9768811config VIDEO_DW9768
817 tristate "DW9768 lens voice coil support"812 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
822 help813 help
823 This is a driver for the DW9768 camera lens voice coil.814 This is a driver for the DW9768 camera lens voice coil.
824 DW9768 is a 10 bit DAC with 100mA output current sink815 DW9768 is a 10 bit DAC with 100mA output current sink
@@ -827,17 +818,13 @@ config VIDEO_DW9768 · 2 unmodified lines
827 818
828config VIDEO_DW9807_VCM819config VIDEO_DW9807_VCM
829 tristate "DW9807 lens voice coil support"820 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
834 help821 help
835 This is a driver for the DW9807 camera lens voice coil.822 This is a driver for the DW9807 camera lens voice coil.
836 DW9807 is a 10 bit DAC with 100mA output current sink823 DW9807 is a 10 bit DAC with 100mA output current sink
837 capability. This is designed for linear control of824 capability. This is designed for linear control of
838 voice coil motors, controlled via I2C serial interface.825 voice coil motors, controlled via I2C serial interface.
839 826
840endmenu827endif
841 828
842menu "Flash devices"829menu "Flash devices"
843 visible if MEDIA_CAMERA_SUPPORT830 visible if MEDIA_CAMERA_SUPPORT
@@ -1684,7 +1671,7 @@ config VIDEO_MAX96714 · 840 unmodified lines
1684 1671
1685config VIDEO_MAX967171672config VIDEO_MAX96717
1686 tristate "Maxim MAX96717 GMSL2 Serializer support"1673 tristate "Maxim MAX96717 GMSL2 Serializer support"
1687 depends on OF && I2C && VIDEO_DEV && COMMON_CLK1674 depends on I2C && VIDEO_DEV && COMMON_CLK
1688 select I2C_MUX1675 select I2C_MUX
1689 select MEDIA_CONTROLLER1676 select MEDIA_CONTROLLER
1690 select GPIOLIB1677 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
868 return 0;868 return 0;
869}869}
870 870
871static 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
886static int adv7180_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)871static int adv7180_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
887{872{
888 *norm = V4L2_STD_ALL;873 *norm = V4L2_STD_ALL;
@@ -929,7 +914,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = { · 40 unmodified lines
929 .querystd = adv7180_querystd,914 .querystd = adv7180_querystd,
930 .g_input_status = adv7180_g_input_status,915 .g_input_status = adv7180_g_input_status,
931 .s_routing = adv7180_s_routing,916 .s_routing = adv7180_s_routing,
932 .g_pixelaspect = adv7180_g_pixelaspect,
933 .g_tvnorms = adv7180_g_tvnorms,917 .g_tvnorms = adv7180_g_tvnorms,
934 .s_stream = adv7180_s_stream,918 .s_stream = adv7180_s_stream,
935};919};
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
161 return sdp_write(state, ADV748X_SDP_INSEL, input);161 return sdp_write(state, ADV748X_SDP_INSEL, input);
162}162}
163 163
164static 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
180/* -----------------------------------------------------------------------------164/* -----------------------------------------------------------------------------
181 * v4l2_subdev_video_ops165 * v4l2_subdev_video_ops
182 */166 */
@@ -307,7 +291,6 @@ static const struct v4l2_subdev_video_ops adv748x_afe_video_ops = { · 124 unmodified lines
307 .g_tvnorms = adv748x_afe_g_tvnorms,291 .g_tvnorms = adv748x_afe_g_tvnorms,
308 .g_input_status = adv748x_afe_g_input_status,292 .g_input_status = adv748x_afe_g_input_status,
309 .s_stream = adv748x_afe_s_stream,293 .s_stream = adv748x_afe_s_stream,
310 .g_pixelaspect = adv748x_afe_g_pixelaspect,
311};294};
312 295
313/* -----------------------------------------------------------------------------296/* -----------------------------------------------------------------------------
drivers/media/i2c/adv748x/adv748x-hdmi.c+0−10
@@ -382,19 +382,9 @@ done: · 381 unmodified lines
382 return ret;382 return ret;
383}383}
384 384
385static 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
394static const struct v4l2_subdev_video_ops adv748x_video_ops_hdmi = {385static const struct v4l2_subdev_video_ops adv748x_video_ops_hdmi = {
395 .g_input_status = adv748x_hdmi_g_input_status,386 .g_input_status = adv748x_hdmi_g_input_status,
396 .s_stream = adv748x_hdmi_s_stream,387 .s_stream = adv748x_hdmi_s_stream,
397 .g_pixelaspect = adv748x_hdmi_g_pixelaspect,
398};388};
399 389
400/* -----------------------------------------------------------------------------390/* -----------------------------------------------------------------------------
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
2448 }2448 }
2449 cec_s_phys_addr(state->cec_adap, parent_pa, false);2449 cec_s_phys_addr(state->cec_adap, parent_pa, false);
2450 2450
2451 /* enable hotplug after 100 ms */2451 /* enable hotplug after 143 ms */
2452 schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 10);2452 schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 7);
2453 return 0;2453 return 0;
2454}2454}
2455 2455
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
203 0));203 0));
204}204}
205 205
206static void ub913_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)206static int ub913_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
207{207{
208 ub913_gpio_direction_out(gc, offset, value);208 return ub913_gpio_direction_out(gc, offset, value);
209}209}
210 210
211static int ub913_gpio_of_xlate(struct gpio_chip *gc,211static 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
235 gc->ngpio = UB913_NUM_GPIOS;235 gc->ngpio = UB913_NUM_GPIOS;
236 gc->get_direction = ub913_gpio_get_direction;236 gc->get_direction = ub913_gpio_get_direction;
237 gc->direction_output = ub913_gpio_direction_out;237 gc->direction_output = ub913_gpio_direction_out;
238 gc->set = ub913_gpio_set;238 gc->set_rv = ub913_gpio_set;
239 gc->of_xlate = ub913_gpio_of_xlate;239 gc->of_xlate = ub913_gpio_of_xlate;
240 gc->of_gpio_n_cells = 2;240 gc->of_gpio_n_cells = 2;
241 241
@@ -337,14 +337,6 @@ static int _ub913_set_routing(struct v4l2_subdev *sd, · 95 unmodified lines
337 unsigned int i;337 unsigned int i;
338 int ret;338 int ret;
339 339
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
348 ret = v4l2_subdev_routing_validate(sd, routing,340 ret = v4l2_subdev_routing_validate(sd, routing,
349 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);341 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
350 if (ret)342 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
317 return !!(v & UB953_REG_GPIO_PIN_STS_GPIO_STS(offset));317 return !!(v & UB953_REG_GPIO_PIN_STS_GPIO_STS(offset));
318}318}
319 319
320static void ub953_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)320static int ub953_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
321{321{
322 struct ub953_data *priv = gpiochip_get_data(gc);322 struct ub953_data *priv = gpiochip_get_data(gc);
323 323
324 regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA,324 return regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA,
325 UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset),325 UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset),
326 value ? UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset) :326 value ? UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(offset) : 0);
327 0);
328}327}
329 328
330static int ub953_gpio_of_xlate(struct gpio_chip *gc,329static 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
362 gc->direction_input = ub953_gpio_direction_in;361 gc->direction_input = ub953_gpio_direction_in;
363 gc->direction_output = ub953_gpio_direction_out;362 gc->direction_output = ub953_gpio_direction_out;
364 gc->get = ub953_gpio_get;363 gc->get = ub953_gpio_get;
365 gc->set = ub953_gpio_set;364 gc->set_rv = ub953_gpio_set;
366 gc->of_xlate = ub953_gpio_of_xlate;365 gc->of_xlate = ub953_gpio_of_xlate;
367 gc->of_gpio_n_cells = 2;366 gc->of_gpio_n_cells = 2;
368 367
@@ -400,14 +399,6 @@ static int _ub953_set_routing(struct v4l2_subdev *sd, · 31 unmodified lines
400 };399 };
401 int ret;400 int ret;
402 401
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
411 ret = v4l2_subdev_routing_validate(sd, routing,402 ret = v4l2_subdev_routing_validate(sd, routing,
412 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);403 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
413 if (ret)404 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
3861 };3861 };
3862 int ret;3862 int ret;
3863 3863
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
3872 ret = v4l2_subdev_routing_validate(sd, routing,3864 ret = v4l2_subdev_routing_validate(sd, routing,
3873 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 |3865 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1 |
3874 V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX);3866 V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX);
drivers/media/i2c/dw9714.c+45−17
@@ -2,6 +2,7 @@ · 1 unmodified line
2// Copyright (c) 2015--2017 Intel Corporation.2// Copyright (c) 2015--2017 Intel Corporation.
3 3
4#include <linux/delay.h>4#include <linux/delay.h>
5#include <linux/gpio/consumer.h>
5#include <linux/i2c.h>6#include <linux/i2c.h>
6#include <linux/module.h>7#include <linux/module.h>
7#include <linux/pm_runtime.h>8#include <linux/pm_runtime.h>
@@ -38,6 +39,7 @@ struct dw9714_device { · 30 unmodified lines
38 struct v4l2_subdev sd;39 struct v4l2_subdev sd;
39 u16 current_val;40 u16 current_val;
40 struct regulator *vcc;41 struct regulator *vcc;
42 struct gpio_desc *powerdown_gpio;
41};43};
42 44
43static inline struct dw9714_device *to_dw9714_vcm(struct v4l2_ctrl *ctrl)45static 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
137 return hdl->error;139 return hdl->error;
138}140}
139 141
142static 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
157static 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
140static int dw9714_probe(struct i2c_client *client)164static int dw9714_probe(struct i2c_client *client)
141{165{
142 struct dw9714_device *dw9714_dev;166 struct dw9714_device *dw9714_dev;
@@ -144,20 +168,25 @@ static int dw9714_probe(struct i2c_client *client) · 1 unmodified line
144 168
145 dw9714_dev = devm_kzalloc(&client->dev, sizeof(*dw9714_dev),169 dw9714_dev = devm_kzalloc(&client->dev, sizeof(*dw9714_dev),
146 GFP_KERNEL);170 GFP_KERNEL);
147 if (dw9714_dev == NULL)171 if (!dw9714_dev)
148 return -ENOMEM;172 return -ENOMEM;
149 173
150 dw9714_dev->vcc = devm_regulator_get(&client->dev, "vcc");174 dw9714_dev->vcc = devm_regulator_get(&client->dev, "vcc");
151 if (IS_ERR(dw9714_dev->vcc))175 if (IS_ERR(dw9714_dev->vcc))
152 return PTR_ERR(dw9714_dev->vcc);176 return PTR_ERR(dw9714_dev->vcc);
153 177
154 rval = regulator_enable(dw9714_dev->vcc);178 dw9714_dev->powerdown_gpio = devm_gpiod_get_optional(&client->dev,
155 if (rval < 0) {179 "powerdown",
156 dev_err(&client->dev, "failed to enable vcc: %d\n", rval);180 GPIOD_OUT_HIGH);
157 return rval;181 if (IS_ERR(dw9714_dev->powerdown_gpio))
158 }182 return dev_err_probe(&client->dev,
183 PTR_ERR(dw9714_dev->powerdown_gpio),
184 "could not get powerdown gpio\n");
159 185
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);
161 190
162 v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);191 v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
163 dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |192 dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
@@ -185,7 +214,7 @@ static int dw9714_probe(struct i2c_client *client) · 21 unmodified lines
185 return 0;214 return 0;
186 215
187err_cleanup:216err_cleanup:
188 regulator_disable(dw9714_dev->vcc);217 dw9714_power_down(dw9714_dev);
189 v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);218 v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);
190 media_entity_cleanup(&dw9714_dev->sd.entity);219 media_entity_cleanup(&dw9714_dev->sd.entity);
191 220
@@ -200,10 +229,10 @@ static void dw9714_remove(struct i2c_client *client) · 8 unmodified lines
200 229
201 pm_runtime_disable(&client->dev);230 pm_runtime_disable(&client->dev);
202 if (!pm_runtime_status_suspended(&client->dev)) {231 if (!pm_runtime_status_suspended(&client->dev)) {
203 ret = regulator_disable(dw9714_dev->vcc);232 ret = dw9714_power_down(dw9714_dev);
204 if (ret) {233 if (ret) {
205 dev_err(&client->dev,234 dev_err(&client->dev,
206 "Failed to disable vcc: %d\n", ret);235 "Failed to power down: %d\n", ret);
207 }236 }
208 }237 }
209 pm_runtime_set_suspended(&client->dev);238 pm_runtime_set_suspended(&client->dev);
@@ -234,9 +263,9 @@ static int __maybe_unused dw9714_vcm_suspend(struct device *dev) · 24 unmodified lines
234 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);263 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
235 }264 }
236 265
237 ret = regulator_disable(dw9714_dev->vcc);266 ret = dw9714_power_down(dw9714_dev);
238 if (ret)267 if (ret)
239 dev_err(dev, "Failed to disable vcc: %d\n", ret);268 dev_err(dev, "Failed to power down: %d\n", ret);
240 269
241 return ret;270 return ret;
242}271}
@@ -247,7 +276,7 @@ static int __maybe_unused dw9714_vcm_suspend(struct device *dev) · 4 unmodified lines
247 * The lens position is gradually moved in units of DW9714_CTRL_STEPS,276 * The lens position is gradually moved in units of DW9714_CTRL_STEPS,
248 * to make the movements smoothly.277 * to make the movements smoothly.
249 */278 */
250static int __maybe_unused dw9714_vcm_resume(struct device *dev)279static int __maybe_unused dw9714_vcm_resume(struct device *dev)
251{280{
252 struct i2c_client *client = to_i2c_client(dev);281 struct i2c_client *client = to_i2c_client(dev);
253 struct v4l2_subdev *sd = i2c_get_clientdata(client);282 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
257 if (pm_runtime_suspended(&client->dev))286 if (pm_runtime_suspended(&client->dev))
258 return 0;287 return 0;
259 288
260 ret = regulator_enable(dw9714_dev->vcc);289 ret = dw9714_power_up(dw9714_dev);
261 if (ret) {290 if (ret) {
262 dev_err(dev, "Failed to enable vcc: %d\n", ret);291 dev_err(dev, "Failed to power up: %d\n", ret);
263 return ret;292 return ret;
264 }293 }
265 usleep_range(1000, 2000);
266 294
267 for (val = dw9714_dev->current_val % DW9714_CTRL_STEPS;295 for (val = dw9714_dev->current_val % DW9714_CTRL_STEPS;
268 val < dw9714_dev->current_val + DW9714_CTRL_STEPS - 1;296 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
271 DW9714_VAL(val, DW9714_DEFAULT_S));299 DW9714_VAL(val, DW9714_DEFAULT_S));
272 if (ret)300 if (ret)
273 dev_err_ratelimited(dev, "%s I2C failure: %d",301 dev_err_ratelimited(dev, "%s I2C failure: %d",
274 __func__, ret);302 __func__, ret);
275 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);303 usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
276 }304 }
277 305
drivers/media/i2c/hi556.c+42−31
@@ -624,6 +624,12 @@ static const struct hi556_mode supported_modes[] = { · 623 unmodified lines
624 },624 },
625};625};
626 626
627static const char * const hi556_supply_names[] = {
628 "dovdd", /* Digital I/O power */
629 "avdd", /* Analog power */
630 "dvdd", /* Digital core power */
631};
632
627struct hi556 {633struct hi556 {
628 struct v4l2_subdev sd;634 struct v4l2_subdev sd;
629 struct media_pad pad;635 struct media_pad pad;
@@ -639,7 +645,7 @@ struct hi556 { · 9 unmodified lines
639 /* GPIOs, clocks, etc. */645 /* GPIOs, clocks, etc. */
640 struct gpio_desc *reset_gpio;646 struct gpio_desc *reset_gpio;
641 struct clk *clk;647 struct clk *clk;
642 struct regulator *avdd;648 struct regulator_bulk_data supplies[ARRAY_SIZE(hi556_supply_names)];
643 649
644 /* Current mode */650 /* Current mode */
645 const struct hi556_mode *cur_mode;651 const struct hi556_mode *cur_mode;
@@ -756,21 +762,23 @@ static int hi556_test_pattern(struct hi556 *hi556, u32 pattern) · 110 unmodified lines
756 int ret;762 int ret;
757 u32 val;763 u32 val;
758 764
759 if (pattern) {765 ret = hi556_read_reg(hi556, HI556_REG_ISP,
760 ret = hi556_read_reg(hi556, HI556_REG_ISP,766 HI556_REG_VALUE_08BIT, &val);
761 HI556_REG_VALUE_08BIT, &val);767 if (ret)
762 if (ret)768 return ret;
763 return ret;
764 769
765 ret = hi556_write_reg(hi556, HI556_REG_ISP,770 val = pattern ? (val | HI556_REG_ISP_TPG_EN) :
766 HI556_REG_VALUE_08BIT,771 (val & ~HI556_REG_ISP_TPG_EN);
767 val | HI556_REG_ISP_TPG_EN);772
768 if (ret)773 ret = hi556_write_reg(hi556, HI556_REG_ISP,
769 return ret;774 HI556_REG_VALUE_08BIT, val);
770 }775 if (ret)
776 return ret;
777
778 val = pattern ? BIT(pattern - 1) : 0;
771 779
772 return hi556_write_reg(hi556, HI556_REG_TEST_PATTERN,780 return hi556_write_reg(hi556, HI556_REG_TEST_PATTERN,
773 HI556_REG_VALUE_08BIT, pattern);781 HI556_REG_VALUE_08BIT, val);
774}782}
775 783
776static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)784static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
@@ -1289,17 +1297,10 @@ static int hi556_suspend(struct device *dev) · 512 unmodified lines
1289{1297{
1290 struct v4l2_subdev *sd = dev_get_drvdata(dev);1298 struct v4l2_subdev *sd = dev_get_drvdata(dev);
1291 struct hi556 *hi556 = to_hi556(sd);1299 struct hi556 *hi556 = to_hi556(sd);
1292 int ret;
1293 1300
1294 gpiod_set_value_cansleep(hi556->reset_gpio, 1);1301 gpiod_set_value_cansleep(hi556->reset_gpio, 1);
1295 1302 regulator_bulk_disable(ARRAY_SIZE(hi556_supply_names),
1296 ret = regulator_disable(hi556->avdd);1303 hi556->supplies);
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
1303 clk_disable_unprepare(hi556->clk);1304 clk_disable_unprepare(hi556->clk);
1304 return 0;1305 return 0;
1305}1306}
@@ -1314,14 +1315,20 @@ static int hi556_resume(struct device *dev) · 8 unmodified lines
1314 if (ret)1315 if (ret)
1315 return ret;1316 return ret;
1316 1317
1317 ret = regulator_enable(hi556->avdd);1318 ret = regulator_bulk_enable(ARRAY_SIZE(hi556_supply_names),
1319 hi556->supplies);
1318 if (ret) {1320 if (ret) {
1319 dev_err(dev, "failed to enable avdd: %d\n", ret);1321 dev_err(dev, "failed to enable regulators: %d", ret);
1320 clk_disable_unprepare(hi556->clk);1322 clk_disable_unprepare(hi556->clk);
1321 return ret;1323 return ret;
1322 }1324 }
1323 1325
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
1325 usleep_range(5000, 5500);1332 usleep_range(5000, 5500);
1326 return 0;1333 return 0;
1327}1334}
@@ -1330,7 +1337,7 @@ static int hi556_probe(struct i2c_client *client) · 2 unmodified lines
1330{1337{
1331 struct hi556 *hi556;1338 struct hi556 *hi556;
1332 bool full_power;1339 bool full_power;
1333 int ret;1340 int i, ret;
1334 1341
1335 ret = hi556_check_hwcfg(&client->dev);1342 ret = hi556_check_hwcfg(&client->dev);
1336 if (ret)1343 if (ret)
@@ -1353,11 +1360,15 @@ static int hi556_probe(struct i2c_client *client) · 16 unmodified lines
1353 return dev_err_probe(&client->dev, PTR_ERR(hi556->clk),1360 return dev_err_probe(&client->dev, PTR_ERR(hi556->clk),
1354 "failed to get clock\n");1361 "failed to get clock\n");
1355 1362
1356 /* The regulator core will provide a "dummy" regulator if necessary */1363 for (i = 0; i < ARRAY_SIZE(hi556_supply_names); i++)
1357 hi556->avdd = devm_regulator_get(&client->dev, "avdd");1364 hi556->supplies[i].supply = hi556_supply_names[i];
1358 if (IS_ERR(hi556->avdd))1365
1359 return dev_err_probe(&client->dev, PTR_ERR(hi556->avdd),1366 ret = devm_regulator_bulk_get(&client->dev,
1360 "failed to get avdd regulator\n");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");
1361 1372
1362 full_power = acpi_dev_state_d0(&client->dev);1373 full_power = acpi_dev_state_d0(&client->dev);
1363 if (full_power) {1374 if (full_power) {
drivers/media/i2c/imx214.c+200−63
@@ -20,6 +20,8 @@ · 19 unmodified lines
20#include <media/v4l2-fwnode.h>20#include <media/v4l2-fwnode.h>
21#include <media/v4l2-subdev.h>21#include <media/v4l2-subdev.h>
22 22
23#include "ccs-pll.h"
24
23/* Chip ID */25/* Chip ID */
24#define IMX214_REG_CHIP_ID CCI_REG16(0x0016)26#define IMX214_REG_CHIP_ID CCI_REG16(0x0016)
25#define IMX214_CHIP_ID 0x021427#define IMX214_CHIP_ID 0x0214
@@ -30,11 +32,9 @@ · 4 unmodified lines
30 32
31#define IMX214_REG_FAST_STANDBY_CTRL CCI_REG8(0x0106)33#define IMX214_REG_FAST_STANDBY_CTRL CCI_REG8(0x0106)
32 34
33#define IMX214_DEFAULT_CLK_FREQ 24000000
34#define IMX214_DEFAULT_LINK_FREQ 60000000035#define IMX214_DEFAULT_LINK_FREQ 600000000
35/* Keep wrong link frequency for backward compatibility */36/* Keep wrong link frequency for backward compatibility */
36#define IMX214_DEFAULT_LINK_FREQ_LEGACY 48000000037#define IMX214_DEFAULT_LINK_FREQ_LEGACY 480000000
37#define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
38#define IMX214_FPS 3038#define IMX214_FPS 30
39 39
40/* V-TIMING internal */40/* V-TIMING internal */
@@ -84,6 +84,7 @@ · 43 unmodified lines
84#define IMX214_CSI_DATA_FORMAT_RAW10 0x0A0A84#define IMX214_CSI_DATA_FORMAT_RAW10 0x0A0A
85#define IMX214_CSI_DATA_FORMAT_COMP6 0x0A0685#define IMX214_CSI_DATA_FORMAT_COMP6 0x0A06
86#define IMX214_CSI_DATA_FORMAT_COMP8 0x0A0886#define IMX214_CSI_DATA_FORMAT_COMP8 0x0A08
87#define IMX214_BITS_PER_PIXEL_MASK 0xFF
87 88
88#define IMX214_REG_CSI_LANE_MODE CCI_REG8(0x0114)89#define IMX214_REG_CSI_LANE_MODE CCI_REG8(0x0114)
89#define IMX214_CSI_2_LANE_MODE 190#define IMX214_CSI_2_LANE_MODE 1
@@ -249,6 +250,10 @@ struct imx214 { · 159 unmodified lines
249 struct clk *xclk;250 struct clk *xclk;
250 struct regmap *regmap;251 struct regmap *regmap;
251 252
253 struct ccs_pll pll;
254
255 struct v4l2_fwnode_endpoint bus_cfg;
256
252 struct v4l2_subdev sd;257 struct v4l2_subdev sd;
253 struct media_pad pad;258 struct media_pad pad;
254 259
@@ -299,16 +304,6 @@ static const struct cci_reg_sequence mode_4096x2304[] = { · 44 unmodified lines
299 { IMX214_REG_DIG_CROP_WIDTH, 4096 },304 { IMX214_REG_DIG_CROP_WIDTH, 4096 },
300 { IMX214_REG_DIG_CROP_HEIGHT, 2304 },305 { IMX214_REG_DIG_CROP_HEIGHT, 2304 },
301 306
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
312 { CCI_REG8(0x3A03), 0x09 },307 { CCI_REG8(0x3A03), 0x09 },
313 { CCI_REG8(0x3A04), 0x50 },308 { CCI_REG8(0x3A04), 0x50 },
314 { CCI_REG8(0x3A05), 0x01 },309 { CCI_REG8(0x3A05), 0x01 },
@@ -362,16 +357,6 @@ static const struct cci_reg_sequence mode_1920x1080[] = { · 47 unmodified lines
362 { IMX214_REG_DIG_CROP_WIDTH, 1920 },357 { IMX214_REG_DIG_CROP_WIDTH, 1920 },
363 { IMX214_REG_DIG_CROP_HEIGHT, 1080 },358 { IMX214_REG_DIG_CROP_HEIGHT, 1080 },
364 359
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
375 { CCI_REG8(0x3A03), 0x04 },360 { CCI_REG8(0x3A03), 0x04 },
376 { CCI_REG8(0x3A04), 0xF8 },361 { CCI_REG8(0x3A04), 0xF8 },
377 { CCI_REG8(0x3A05), 0x02 },362 { CCI_REG8(0x3A05), 0x02 },
@@ -405,9 +390,6 @@ static const struct cci_reg_sequence mode_table_common[] = { · 27 unmodified lines
405 /* ATR setting */390 /* ATR setting */
406 { IMX214_REG_ATR_FAST_MOVE, 2 },391 { IMX214_REG_ATR_FAST_MOVE, 2 },
407 392
408 /* external clock setting */
409 { IMX214_REG_EXCK_FREQ, IMX214_EXCK_FREQ(IMX214_DEFAULT_CLK_FREQ / 1000000) },
410
411 /* global setting */393 /* global setting */
412 /* basic config */394 /* basic config */
413 { IMX214_REG_MASK_CORR_FRAMES, IMX214_CORR_FRAMES_MASK },395 { 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
777 return 0;759 return 0;
778}760}
779 761
762static 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
780static int imx214_update_digital_gain(struct imx214 *imx214, u32 val)786static int imx214_update_digital_gain(struct imx214 *imx214, u32 val)
781{787{
782 int ret = 0;788 int ret = 0;
@@ -877,9 +883,6 @@ static const struct v4l2_ctrl_ops imx214_ctrl_ops = { · 94 unmodified lines
877 883
878static int imx214_ctrls_init(struct imx214 *imx214)884static int imx214_ctrls_init(struct imx214 *imx214)
879{885{
880 static const s64 link_freq[] = {
881 IMX214_DEFAULT_LINK_FREQ
882 };
883 static const struct v4l2_area unit_size = {886 static const struct v4l2_area unit_size = {
884 .width = 1120,887 .width = 1120,
885 .height = 1120,888 .height = 1120,
@@ -900,15 +903,14 @@ static int imx214_ctrls_init(struct imx214 *imx214) · 14 unmodified lines
900 if (ret)903 if (ret)
901 return ret;904 return ret;
902 905
903 imx214->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, NULL,906 imx214->pixel_rate =
904 V4L2_CID_PIXEL_RATE, 0,907 v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_PIXEL_RATE, 1,
905 IMX214_DEFAULT_PIXEL_RATE, 1,908 INT_MAX, 1, 1);
906 IMX214_DEFAULT_PIXEL_RATE);
907 909
908 imx214->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, NULL,910 imx214->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, NULL,
909 V4L2_CID_LINK_FREQ,911 V4L2_CID_LINK_FREQ,
910 ARRAY_SIZE(link_freq) - 1,912 imx214->bus_cfg.nr_of_link_frequencies - 1,
911 0, link_freq);913 0, imx214->bus_cfg.link_frequencies);
912 if (imx214->link_freq)914 if (imx214->link_freq)
913 imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;915 imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
914 916
@@ -1011,6 +1013,7 @@ static int imx214_start_streaming(struct imx214 *imx214) · 96 unmodified lines
1011 const struct v4l2_mbus_framefmt *fmt;1013 const struct v4l2_mbus_framefmt *fmt;
1012 struct v4l2_subdev_state *state;1014 struct v4l2_subdev_state *state;
1013 const struct imx214_mode *mode;1015 const struct imx214_mode *mode;
1016 int bit_rate_mbps;
1014 int ret;1017 int ret;
1015 1018
1016 ret = cci_multi_reg_write(imx214->regmap, mode_table_common,1019 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
1020 return ret;1023 return ret;
1021 }1024 }
1022 1025
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
1023 ret = cci_write(imx214->regmap, IMX214_REG_CSI_LANE_MODE,1041 ret = cci_write(imx214->regmap, IMX214_REG_CSI_LANE_MODE,
1024 IMX214_CSI_4_LANE_MODE, NULL);1042 IMX214_CSI_4_LANE_MODE, NULL);
1025 if (ret) {1043 if (ret) {
@@ -1097,6 +1115,109 @@ err_rpm_put: · 71 unmodified lines
1097 return ret;1115 return ret;
1098}1116}
1099 1117
1118static 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
1199static 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
1100static int imx214_get_frame_interval(struct v4l2_subdev *subdev,1221static int imx214_get_frame_interval(struct v4l2_subdev *subdev,
1101 struct v4l2_subdev_state *sd_state,1222 struct v4l2_subdev_state *sd_state,
1102 struct v4l2_subdev_frame_interval *fival)1223 struct v4l2_subdev_frame_interval *fival)
@@ -1203,12 +1324,10 @@ static int imx214_identify_module(struct imx214 *imx214) · 100 unmodified lines
1203 return 0;1324 return 0;
1204}1325}
1205 1326
1206static int imx214_parse_fwnode(struct device *dev)1327static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
1207{1328{
1329 struct v4l2_fwnode_endpoint *bus_cfg = &imx214->bus_cfg;
1208 struct fwnode_handle *endpoint;1330 struct fwnode_handle *endpoint;
1209 struct v4l2_fwnode_endpoint bus_cfg = {
1210 .bus_type = V4L2_MBUS_CSI2_DPHY,
1211 };
1212 unsigned int i;1331 unsigned int i;
1213 int ret;1332 int ret;
1214 1333
@@ -1216,42 +1335,52 @@ static int imx214_parse_fwnode(struct device *dev) · 1 unmodified line
1216 if (!endpoint)1335 if (!endpoint)
1217 return dev_err_probe(dev, -EINVAL, "endpoint node not found\n");1336 return dev_err_probe(dev, -EINVAL, "endpoint node not found\n");
1218 1337
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);
1220 if (ret) {1341 if (ret) {
1221 dev_err_probe(dev, ret, "parsing endpoint node failed\n");1342 dev_err_probe(dev, ret, "parsing endpoint node failed\n");
1222 goto done;1343 goto error;
1223 }1344 }
1224 1345
1225 /* Check the number of MIPI CSI2 data lanes */1346 /* 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) {
1227 ret = dev_err_probe(dev, -EINVAL,1348 ret = dev_err_probe(dev, -EINVAL,
1228 "only 4 data lanes are currently supported\n");1349 "only 4 data lanes are currently supported\n");
1229 goto done;1350 goto error;
1230 }1351 }
1231 1352
1232 if (bus_cfg.nr_of_link_frequencies != 1)1353 if (bus_cfg->nr_of_link_frequencies != 1)
1233 dev_warn(dev, "Only one link-frequency supported, please review your DT. Continuing anyway\n");1354 dev_warn(dev, "Only one link-frequency supported, please review your DT. Continuing anyway\n");
1234 1355
1235 for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {1356 for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) {
1236 if (bus_cfg.link_frequencies[i] == IMX214_DEFAULT_LINK_FREQ)1357 u64 freq = bus_cfg->link_frequencies[i];
1358 struct ccs_pll pll;
1359
1360 if (!imx214_pll_calculate(imx214, &pll, freq))
1237 break;1361 break;
1238 if (bus_cfg.link_frequencies[i] ==1362 if (freq == IMX214_DEFAULT_LINK_FREQ_LEGACY) {
1239 IMX214_DEFAULT_LINK_FREQ_LEGACY) {
1240 dev_warn(dev,1363 dev_warn(dev,
1241 "link-frequencies %d not supported, please review your DT. Continuing anyway\n",1364 "link-frequencies %d not supported, please review your DT. Continuing anyway\n",
1242 IMX214_DEFAULT_LINK_FREQ);1365 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;
1243 break;1370 break;
1244 }1371 }
1245 }1372 }
1246 1373
1247 if (i == bus_cfg.nr_of_link_frequencies)1374 if (i == bus_cfg->nr_of_link_frequencies)
1248 ret = dev_err_probe(dev, -EINVAL,1375 ret = dev_err_probe(dev, -EINVAL,
1249 "link-frequencies %d not supported, please review your DT\n",1376 "link-frequencies %lld not supported, please review your DT\n",
1250 IMX214_DEFAULT_LINK_FREQ);1377 bus_cfg->nr_of_link_frequencies ?
1378 bus_cfg->link_frequencies[0] : 0);
1251 1379
1252done:1380 return 0;
1253 v4l2_fwnode_endpoint_free(&bus_cfg);1381
1254 fwnode_handle_put(endpoint);1382error:
1383 v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1255 return ret;1384 return ret;
1256}1385}
1257 1386
@@ -1261,10 +1390,6 @@ static int imx214_probe(struct i2c_client *client) · 3 unmodified lines
1261 struct imx214 *imx214;1390 struct imx214 *imx214;
1262 int ret;1391 int ret;
1263 1392
1264 ret = imx214_parse_fwnode(dev);
1265 if (ret)
1266 return ret;
1267
1268 imx214 = devm_kzalloc(dev, sizeof(*imx214), GFP_KERNEL);1393 imx214 = devm_kzalloc(dev, sizeof(*imx214), GFP_KERNEL);
1269 if (!imx214)1394 if (!imx214)
1270 return -ENOMEM;1395 return -ENOMEM;
@@ -1276,11 +1401,6 @@ static int imx214_probe(struct i2c_client *client) · 5 unmodified lines
1276 return dev_err_probe(dev, PTR_ERR(imx214->xclk),1401 return dev_err_probe(dev, PTR_ERR(imx214->xclk),
1277 "failed to get xclk\n");1402 "failed to get xclk\n");
1278 1403
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
1284 ret = imx214_get_regulators(dev, imx214);1404 ret = imx214_get_regulators(dev, imx214);
1285 if (ret < 0)1405 if (ret < 0)
1286 return dev_err_probe(dev, ret, "failed to get regulators\n");1406 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
1295 return dev_err_probe(dev, PTR_ERR(imx214->regmap),1415 return dev_err_probe(dev, PTR_ERR(imx214->regmap),
1296 "failed to initialize CCI\n");1416 "failed to initialize CCI\n");
1297 1417
1418 ret = imx214_parse_fwnode(dev, imx214);
1419 if (ret)
1420 return ret;
1421
1298 v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);1422 v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);
1299 imx214->sd.internal_ops = &imx214_internal_ops;1423 imx214->sd.internal_ops = &imx214_internal_ops;
1300 1424
@@ -1302,7 +1426,9 @@ static int imx214_probe(struct i2c_client *client) · 1 unmodified line
1302 * Enable power initially, to avoid warnings1426 * Enable power initially, to avoid warnings
1303 * from clk_disable on power_off1427 * from clk_disable on power_off
1304 */1428 */
1305 imx214_power_on(imx214->dev);1429 ret = imx214_power_on(imx214->dev);
1430 if (ret < 0)
1431 goto error_fwnode;
1306 1432
1307 ret = imx214_identify_module(imx214);1433 ret = imx214_identify_module(imx214);
1308 if (ret)1434 if (ret)
@@ -1333,6 +1459,12 @@ static int imx214_probe(struct i2c_client *client) · 24 unmodified lines
1333 pm_runtime_set_active(imx214->dev);1459 pm_runtime_set_active(imx214->dev);
1334 pm_runtime_enable(imx214->dev);1460 pm_runtime_enable(imx214->dev);
1335 1461
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
1336 ret = v4l2_async_register_subdev_sensor(&imx214->sd);1468 ret = v4l2_async_register_subdev_sensor(&imx214->sd);
1337 if (ret < 0) {1469 if (ret < 0) {
1338 dev_err_probe(dev, ret,1470 dev_err_probe(dev, ret,
@@ -1358,6 +1490,9 @@ free_ctrl: · 19 unmodified lines
1358error_power_off:1490error_power_off:
1359 imx214_power_off(imx214->dev);1491 imx214_power_off(imx214->dev);
1360 1492
1493error_fwnode:
1494 v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1495
1361 return ret;1496 return ret;
1362}1497}
1363 1498
@@ -1370,6 +1505,8 @@ static void imx214_remove(struct i2c_client *client) · 6 unmodified lines
1370 v4l2_subdev_cleanup(sd);1505 v4l2_subdev_cleanup(sd);
1371 media_entity_cleanup(&imx214->sd.entity);1506 media_entity_cleanup(&imx214->sd.entity);
1372 v4l2_ctrl_handler_free(&imx214->ctrls);1507 v4l2_ctrl_handler_free(&imx214->ctrls);
1508 v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1509
1373 pm_runtime_disable(&client->dev);1510 pm_runtime_disable(&client->dev);
1374 if (!pm_runtime_status_suspended(&client->dev)) {1511 if (!pm_runtime_status_suspended(&client->dev)) {
1375 imx214_power_off(imx214->dev);1512 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
1294 * will already be prevented even before the delay.1294 * will already be prevented even before the delay.
1295 */1295 */
1296 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);1296 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
1297 imx290->sd.dev = imx290->dev;
1298 pm_runtime_mark_last_busy(imx290->dev);1297 pm_runtime_mark_last_busy(imx290->dev);
1299 pm_runtime_put_autosuspend(imx290->dev);1298 pm_runtime_put_autosuspend(imx290->dev);
1300 1299
drivers/media/i2c/imx415.c+1−1
@@ -1251,7 +1251,7 @@ static int imx415_parse_hw_config(struct imx415 *sensor) · 1250 unmodified lines
1251 return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),1251 return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
1252 "failed to get reset GPIO\n");1252 "failed to get reset GPIO\n");
1253 1253
1254 sensor->clk = devm_clk_get(sensor->dev, "inck");1254 sensor->clk = devm_clk_get(sensor->dev, NULL);
1255 if (IS_ERR(sensor->clk))1255 if (IS_ERR(sensor->clk))
1256 return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),1256 return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
1257 "failed to get clock\n");1257 "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
600 600
601 v4l2_i2c_subdev_init(&lt6911uxe->sd, client, &lt6911uxe_subdev_ops);601 v4l2_i2c_subdev_init(&lt6911uxe->sd, client, &lt6911uxe_subdev_ops);
602 602
603 lt6911uxe->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_IN);603 lt6911uxe->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
604 if (IS_ERR(lt6911uxe->reset_gpio))604 if (IS_ERR(lt6911uxe->reset_gpio))
605 return dev_err_probe(dev, PTR_ERR(lt6911uxe->reset_gpio),605 return dev_err_probe(dev, PTR_ERR(lt6911uxe->reset_gpio),
606 "failed to get reset gpio\n");606 "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
1193 MAX9286_0X0F_RESERVED | priv->gpio_state);1193 MAX9286_0X0F_RESERVED | priv->gpio_state);
1194}1194}
1195 1195
1196static void max9286_gpiochip_set(struct gpio_chip *chip,1196static int max9286_gpiochip_set(struct gpio_chip *chip,
1197 unsigned int offset, int value)1197 unsigned int offset, int value)
1198{1198{
1199 struct max9286_priv *priv = gpiochip_get_data(chip);1199 struct max9286_priv *priv = gpiochip_get_data(chip);
1200 1200
1201 max9286_gpio_set(priv, offset, value);1201 return max9286_gpio_set(priv, offset, value);
1202}1202}
1203 1203
1204static int max9286_gpiochip_get(struct gpio_chip *chip, unsigned int offset)1204static 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
1220 gpio->owner = THIS_MODULE;1220 gpio->owner = THIS_MODULE;
1221 gpio->ngpio = 2;1221 gpio->ngpio = 2;
1222 gpio->base = -1;1222 gpio->base = -1;
1223 gpio->set = max9286_gpiochip_set;1223 gpio->set_rv = max9286_gpiochip_set;
1224 gpio->get = max9286_gpiochip_get;1224 gpio->get = max9286_gpiochip_get;
1225 gpio->can_sleep = true;1225 gpio->can_sleep = true;
1226 1226
drivers/media/i2c/max96714.c+0−7
@@ -370,13 +370,6 @@ static int _max96714_set_routing(struct v4l2_subdev *sd, · 369 unmodified lines
370 };370 };
371 int ret;371 int ret;
372 372
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
380 ret = v4l2_subdev_routing_validate(sd, routing,373 ret = v4l2_subdev_routing_validate(sd, routing,
381 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);374 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
382 if (ret)375 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
297 return !!(val & MAX96717_GPIO_OUT);297 return !!(val & MAX96717_GPIO_OUT);
298}298}
299 299
300static void max96717_gpiochip_set(struct gpio_chip *gpiochip,300static int max96717_gpiochip_set(struct gpio_chip *gpiochip,
301 unsigned int offset, int value)301 unsigned int offset, int value)
302{302{
303 struct max96717_priv *priv = gpiochip_get_data(gpiochip);303 struct max96717_priv *priv = gpiochip_get_data(gpiochip);
304 304
305 cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),305 return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
306 MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);306 MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);
307}307}
308 308
309static int max96717_gpio_get_direction(struct gpio_chip *gpiochip,309static 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
355 gc->get_direction = max96717_gpio_get_direction;355 gc->get_direction = max96717_gpio_get_direction;
356 gc->direction_input = max96717_gpio_direction_in;356 gc->direction_input = max96717_gpio_direction_in;
357 gc->direction_output = max96717_gpio_direction_out;357 gc->direction_output = max96717_gpio_direction_out;
358 gc->set = max96717_gpiochip_set;358 gc->set_rv = max96717_gpiochip_set;
359 gc->get = max96717_gpiochip_get;359 gc->get = max96717_gpiochip_get;
360 gc->of_gpio_n_cells = 2;
361 360
362 /* Disable GPIO forwarding */361 /* Disable GPIO forwarding */
363 for (i = 0; i < gc->ngpio; i++)362 for (i = 0; i < gc->ngpio; i++)
drivers/media/i2c/mt9m114.c+103−68
@@ -261,6 +261,7 @@ · 260 unmodified lines
261#define MT9M114_CAM_PGA_PGA_CONTROL CCI_REG16(0xc95e)261#define MT9M114_CAM_PGA_PGA_CONTROL CCI_REG16(0xc95e)
262#define MT9M114_CAM_SYSCTL_PLL_ENABLE CCI_REG8(0xc97e)262#define MT9M114_CAM_SYSCTL_PLL_ENABLE CCI_REG8(0xc97e)
263#define MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE BIT(0)263#define MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE BIT(0)
264#define MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE 0x00
264#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N CCI_REG16(0xc980)265#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N CCI_REG16(0xc980)
265#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(m, n) (((n) << 8) | (m))266#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(m, n) (((n) << 8) | (m))
266#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P CCI_REG16(0xc982)267#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P CCI_REG16(0xc982)
@@ -377,6 +378,7 @@ struct mt9m114 { · 110 unmodified lines
377 struct gpio_desc *reset;378 struct gpio_desc *reset;
378 struct regulator_bulk_data supplies[3];379 struct regulator_bulk_data supplies[3];
379 struct v4l2_fwnode_endpoint bus_cfg;380 struct v4l2_fwnode_endpoint bus_cfg;
381 bool bypass_pll;
380 382
381 struct {383 struct {
382 unsigned int m;384 unsigned int m;
@@ -743,14 +745,21 @@ static int mt9m114_initialize(struct mt9m114 *sensor) · 360 unmodified lines
743 }745 }
744 746
745 /* Configure the PLL. */747 /* Configure the PLL. */
746 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,748 if (sensor->bypass_pll) {
747 MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret);749 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
748 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N,750 MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE, &ret);
749 MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m,751 } else {
750 sensor->pll.n),752 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
751 &ret);753 MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret);
752 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P,754 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N,
753 MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), &ret);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
754 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK,763 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK,
755 sensor->pixrate, &ret);764 sensor->pixrate, &ret);
756 765
@@ -781,41 +790,25 @@ static int mt9m114_initialize(struct mt9m114 *sensor) · 24 unmodified lines
781 return 0;790 return 0;
782}791}
783 792
784static int mt9m114_configure(struct mt9m114 *sensor,793static int mt9m114_configure_pa(struct mt9m114 *sensor,
785 struct v4l2_subdev_state *pa_state,794 struct v4l2_subdev_state *state)
786 struct v4l2_subdev_state *ifp_state)
787{795{
788 const struct v4l2_mbus_framefmt *pa_format;796 const struct v4l2_mbus_framefmt *format;
789 const struct v4l2_rect *pa_crop;797 const struct v4l2_rect *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;
794 unsigned int hratio, vratio;798 unsigned int hratio, vratio;
795 u64 output_format;
796 u64 read_mode;799 u64 read_mode;
797 int ret = 0;800 int ret;
798
799 pa_format = v4l2_subdev_state_get_format(pa_state, 0);
800 pa_crop = v4l2_subdev_state_get_crop(pa_state, 0);
801 801
802 ifp_format = v4l2_subdev_state_get_format(ifp_state, 1);802 format = v4l2_subdev_state_get_format(state, 0);
803 ifp_info = mt9m114_format_info(sensor, 1, ifp_format->code);803 crop = v4l2_subdev_state_get_crop(state, 0);
804 ifp_crop = v4l2_subdev_state_get_crop(ifp_state, 0);
805 ifp_compose = v4l2_subdev_state_get_compose(ifp_state, 0);
806 804
807 ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,805 ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
808 &read_mode, NULL);806 &read_mode, NULL);
809 if (ret < 0)807 if (ret < 0)
810 return ret;808 return ret;
811 809
812 ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,810 hratio = crop->width / format->width;
813 &output_format, NULL);811 vratio = crop->height / format->height;
814 if (ret < 0)
815 return ret;
816
817 hratio = pa_crop->width / pa_format->width;
818 vratio = pa_crop->height / pa_format->height;
819 812
820 /*813 /*
821 * Pixel array crop and binning. The CAM_SENSOR_CFG_CPIPE_LAST_ROW814 * 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
824 * example sensor modes.817 * example sensor modes.
825 */818 */
826 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START,819 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START,
827 pa_crop->left, &ret);820 crop->left, &ret);
828 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START,821 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START,
829 pa_crop->top, &ret);822 crop->top, &ret);
830 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END,823 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);
832 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END,825 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);
834 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW,827 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);
836 829
837 read_mode &= ~(MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK |830 read_mode &= ~(MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK |
838 MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK);831 MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK);
@@ -845,6 +838,29 @@ static int mt9m114_configure(struct mt9m114 *sensor, · 6 unmodified lines
845 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,838 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
846 read_mode, &ret);839 read_mode, &ret);
847 840
841 return ret;
842}
843
844static 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
848 /*864 /*
849 * Color pipeline (IFP) cropping and scaling. Subtract 4 from the left865 * Color pipeline (IFP) cropping and scaling. Subtract 4 from the left
850 * and top coordinates to compensate for the lines and columns removed866 * 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
852 * not in the hardware.868 * not in the hardware.
853 */869 */
854 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET,870 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET,
855 ifp_crop->left - 4, &ret);871 crop->left - 4, &ret);
856 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET,872 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET,
857 ifp_crop->top - 4, &ret);873 crop->top - 4, &ret);
858 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH,874 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH,
859 ifp_crop->width, &ret);875 crop->width, &ret);
860 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT,876 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT,
861 ifp_crop->height, &ret);877 crop->height, &ret);
862 878
863 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH,879 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH,
864 ifp_compose->width, &ret);880 compose->width, &ret);
865 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT,881 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT,
866 ifp_compose->height, &ret);882 compose->height, &ret);
867 883
868 /* AWB and AE windows, use the full frame. */884 /* AWB and AE windows, use the full frame. */
869 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART,885 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
871 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART,887 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART,
872 0, &ret);888 0, &ret);
873 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND,889 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND,
874 ifp_compose->width - 1, &ret);890 compose->width - 1, &ret);
875 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND,891 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND,
876 ifp_compose->height - 1, &ret);892 compose->height - 1, &ret);
877 893
878 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART,894 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART,
879 0, &ret);895 0, &ret);
880 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART,896 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART,
881 0, &ret);897 0, &ret);
882 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND,898 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND,
883 ifp_compose->width / 5 - 1, &ret);899 compose->width / 5 - 1, &ret);
884 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND,900 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND,
885 ifp_compose->height / 5 - 1, &ret);901 compose->height / 5 - 1, &ret);
886 902
887 cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE,903 cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE,
888 MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN |904 MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN |
@@ -894,7 +910,7 @@ static int mt9m114_configure(struct mt9m114 *sensor, · 5 unmodified lines
894 MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK |910 MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK |
895 MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES |911 MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES |
896 MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE);912 MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE);
897 output_format |= ifp_info->output_format;913 output_format |= info->output_format;
898 914
899 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,915 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,
900 output_format, &ret);916 output_format, &ret);
@@ -925,7 +941,11 @@ static int mt9m114_start_streaming(struct mt9m114 *sensor, · 24 unmodified lines
925 if (ret)941 if (ret)
926 return ret;942 return ret;
927 943
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);
929 if (ret)949 if (ret)
930 goto error;950 goto error;
931 951
@@ -1599,13 +1619,9 @@ static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev *sd, · 667 unmodified lines
1599 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)1619 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
1600 return -EINVAL;1620 return -EINVAL;
1601 1621
1602 mutex_lock(sensor->ifp.hdl.lock);
1603
1604 ival->numerator = 1;1622 ival->numerator = 1;
1605 ival->denominator = sensor->ifp.frame_rate;1623 ival->denominator = sensor->ifp.frame_rate;
1606 1624
1607 mutex_unlock(sensor->ifp.hdl.lock);
1608
1609 return 0;1625 return 0;
1610}1626}
1611 1627
@@ -1624,8 +1640,6 @@ static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd, · 12 unmodified lines
1624 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)1640 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
1625 return -EINVAL;1641 return -EINVAL;
1626 1642
1627 mutex_lock(sensor->ifp.hdl.lock);
1628
1629 if (ival->numerator != 0 && ival->denominator != 0)1643 if (ival->numerator != 0 && ival->denominator != 0)
1630 sensor->ifp.frame_rate = min_t(unsigned int,1644 sensor->ifp.frame_rate = min_t(unsigned int,
1631 ival->denominator / ival->numerator,1645 ival->denominator / ival->numerator,
@@ -1639,8 +1653,6 @@ static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd, · 7 unmodified lines
1639 if (sensor->streaming)1653 if (sensor->streaming)
1640 ret = mt9m114_set_frame_rate(sensor);1654 ret = mt9m114_set_frame_rate(sensor);
1641 1655
1642 mutex_unlock(sensor->ifp.hdl.lock);
1643
1644 return ret;1656 return ret;
1645}1657}
1646 1658
@@ -2235,9 +2247,22 @@ static const struct dev_pm_ops mt9m114_pm_ops = { · 588 unmodified lines
2235 * Probe & Remove2247 * Probe & Remove
2236 */2248 */
2237 2249
2250static 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
2238static int mt9m114_clk_init(struct mt9m114 *sensor)2263static int mt9m114_clk_init(struct mt9m114 *sensor)
2239{2264{
2240 unsigned int link_freq;2265 unsigned int pixrate;
2241 2266
2242 /* Hardcode the PLL multiplier and dividers to default settings. */2267 /* Hardcode the PLL multiplier and dividers to default settings. */
2243 sensor->pll.m = 32;2268 sensor->pll.m = 32;
@@ -2249,19 +2274,29 @@ static int mt9m114_clk_init(struct mt9m114 *sensor) · 5 unmodified lines
2249 * for 16-bit per pixel, transmitted in DDR over a single lane. For2274 * for 16-bit per pixel, transmitted in DDR over a single lane. For
2250 * parallel mode, the sensor ouputs one pixel in two PIXCLK cycles.2275 * parallel mode, the sensor ouputs one pixel in two PIXCLK cycles.
2251 */2276 */
2252 sensor->pixrate = clk_get_rate(sensor->clk) * sensor->pll.m
2253 / ((sensor->pll.n + 1) * (sensor->pll.p + 1));
2254 2277
2255 link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY2278 /*
2256 ? sensor->pixrate * 8 : sensor->pixrate * 2;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 }
2257 2288
2258 if (sensor->bus_cfg.nr_of_link_frequencies != 1 ||2289 /* Check if the PLL configuration fits the configured link frequency. */
2259 sensor->bus_cfg.link_frequencies[0] != link_freq) {2290 pixrate = clk_get_rate(sensor->clk) * sensor->pll.m
2260 dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n");2291 / ((sensor->pll.n + 1) * (sensor->pll.p + 1));
2261 return -EINVAL;2292 if (mt9m114_verify_link_frequency(sensor, pixrate) == 0) {
2293 sensor->pixrate = pixrate;
2294 sensor->bypass_pll = false;
2295 return 0;
2262 }2296 }
2263 2297
2264 return 0;2298 dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n");
2299 return -EINVAL;
2265}2300}
2266 2301
2267static int mt9m114_identify(struct mt9m114 *sensor)2302static 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
1469 V4L2_CID_TEST_PATTERN,1469 V4L2_CID_TEST_PATTERN,
1470 ARRAY_SIZE(ov2659_test_pattern_menu) - 1,1470 ARRAY_SIZE(ov2659_test_pattern_menu) - 1,
1471 0, 0, ov2659_test_pattern_menu);1471 0, 0, ov2659_test_pattern_menu);
1472 ov2659->sd.ctrl_handler = &ov2659->ctrls;
1473 1472
1474 if (ov2659->ctrls.error) {1473 if (ov2659->ctrls.error) {
1475 dev_err(&client->dev, "%s: control initialization error %d\n",1474 dev_err(&client->dev, "%s: control initialization error %d\n",
1476 __func__, ov2659->ctrls.error);1475 __func__, ov2659->ctrls.error);
1476 v4l2_ctrl_handler_free(&ov2659->ctrls);
1477 return ov2659->ctrls.error;1477 return ov2659->ctrls.error;
1478 }1478 }
1479 1479
1480 ov2659->sd.ctrl_handler = &ov2659->ctrls;
1480 sd = &ov2659->sd;1481 sd = &ov2659->sd;
1481 client->flags |= I2C_CLIENT_SCCB;1482 client->flags |= I2C_CLIENT_SCCB;
1482 1483
drivers/media/i2c/ov2740.c+7−11
@@ -766,11 +766,9 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 765 unmodified lines
766{766{
767 struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);767 struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
768 struct v4l2_ctrl_handler *ctrl_hdlr;768 struct v4l2_ctrl_handler *ctrl_hdlr;
769 const struct ov2740_mode *cur_mode;
770 s64 exposure_max, h_blank, pixel_rate;769 s64 exposure_max, h_blank, pixel_rate;
771 u32 vblank_min, vblank_max, vblank_default;770 u32 vblank_min, vblank_max, vblank_default;
772 struct v4l2_fwnode_device_properties props;771 struct v4l2_fwnode_device_properties props;
773 int size;
774 int ret;772 int ret;
775 773
776 ctrl_hdlr = &ov2740->ctrl_handler;774 ctrl_hdlr = &ov2740->ctrl_handler;
@@ -778,12 +776,10 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 1 unmodified line
778 if (ret)776 if (ret)
779 return ret;777 return ret;
780 778
781 cur_mode = ov2740->cur_mode;
782 size = ARRAY_SIZE(link_freq_menu_items);
783
784 ov2740->link_freq =779 ov2740->link_freq =
785 v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov2740_ctrl_ops,780 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,
787 ov2740->supported_modes->link_freq_index,783 ov2740->supported_modes->link_freq_index,
788 link_freq_menu_items);784 link_freq_menu_items);
789 if (ov2740->link_freq)785 if (ov2740->link_freq)
@@ -794,14 +790,14 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 4 unmodified lines
794 V4L2_CID_PIXEL_RATE, 0,790 V4L2_CID_PIXEL_RATE, 0,
795 pixel_rate, 1, pixel_rate);791 pixel_rate, 1, pixel_rate);
796 792
797 vblank_min = cur_mode->vts_min - cur_mode->height;793 vblank_min = ov2740->cur_mode->vts_min - ov2740->cur_mode->height;
798 vblank_max = cur_mode->vts_max - cur_mode->height;794 vblank_max = ov2740->cur_mode->vts_max - ov2740->cur_mode->height;
799 vblank_default = cur_mode->vts_def - cur_mode->height;795 vblank_default = ov2740->cur_mode->vts_def - ov2740->cur_mode->height;
800 ov2740->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,796 ov2740->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
801 V4L2_CID_VBLANK, vblank_min,797 V4L2_CID_VBLANK, vblank_min,
802 vblank_max, 1, vblank_default);798 vblank_max, 1, vblank_default);
803 799
804 h_blank = cur_mode->hts - cur_mode->width;800 h_blank = ov2740->cur_mode->hts - ov2740->cur_mode->width;
805 ov2740->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,801 ov2740->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
806 V4L2_CID_HBLANK, h_blank, h_blank, 1,802 V4L2_CID_HBLANK, h_blank, h_blank, 1,
807 h_blank);803 h_blank);
@@ -814,7 +810,7 @@ static int ov2740_init_controls(struct ov2740 *ov2740) · 6 unmodified lines
814 v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_DIGITAL_GAIN,810 v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
815 OV2740_DGTL_GAIN_MIN, OV2740_DGTL_GAIN_MAX,811 OV2740_DGTL_GAIN_MIN, OV2740_DGTL_GAIN_MAX,
816 OV2740_DGTL_GAIN_STEP, OV2740_DGTL_GAIN_DEFAULT);812 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;
818 ov2740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,814 ov2740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
819 V4L2_CID_EXPOSURE,815 V4L2_CID_EXPOSURE,
820 OV2740_EXPOSURE_MIN, exposure_max,816 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
2688 if (ret)2688 if (ret)
2689 return dev_err_probe(&client->dev, ret, "GPIO probe failed\n");2689 return dev_err_probe(&client->dev, ret, "GPIO probe failed\n");
2690 2690
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 */
2692 handle = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);2696 handle = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
2693 if (!handle)2697 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");
2695 2700
2696 ov5670->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;2701 ov5670->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
2697 ov5670->endpoint.bus.mipi_csi2.num_data_lanes = 2;2702 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
1222 unsigned int i;1222 unsigned int i;
1223 int ret;1223 int ret;
1224 1224
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 */
1225 endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);1229 endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
1226 if (!endpoint)1230 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");
1228 1233
1229 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);1234 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
1230 fwnode_handle_put(endpoint);1235 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
1486 unsigned int i, j;1486 unsigned int i, j;
1487 int ret;1487 int ret;
1488 1488
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 */
1489 endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);1493 endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
1490 if (!endpoint)1494 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");
1492 1497
1493 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);1498 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
1494 fwnode_handle_put(endpoint);1499 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
2991 2991
2992 handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);2992 handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
2993 if (!handle)2993 if (!handle)
2994 return -EPROBE_DEFER;2994 return dev_err_probe(dev, -EPROBE_DEFER,
2995 "waiting for fwnode graph endpoint\n");
2995 2996
2996 sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;2997 sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
2997 2998
drivers/media/i2c/saa7115.c+2−10
@@ -25,6 +25,7 @@ · 24 unmodified lines
25 25
26#include "saa711x_regs.h"26#include "saa711x_regs.h"
27 27
28#include <linux/bitops.h>
28#include <linux/kernel.h>29#include <linux/kernel.h>
29#include <linux/module.h>30#include <linux/module.h>
30#include <linux/slab.h>31#include <linux/slab.h>
@@ -664,15 +665,6 @@ static const unsigned char saa7115_init_misc[] = { · 633 unmodified lines
664 0x00, 0x00665 0x00, 0x00
665};666};
666 667
667static 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
676static int saa711x_decode_vps(u8 *dst, u8 *p)668static int saa711x_decode_vps(u8 *dst, u8 *p)
677{669{
678 static const u8 biphase_tbl[] = {670 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
1227 vbi->type = V4L2_SLICED_TELETEXT_B;1219 vbi->type = V4L2_SLICED_TELETEXT_B;
1228 break;1220 break;
1229 case 4:1221 case 4:
1230 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))1222 if (!parity8(p[0]) || !parity8(p[1]))
1231 return 0;1223 return 0;
1232 vbi->type = V4L2_SLICED_CAPTION_525;1224 vbi->type = V4L2_SLICED_CAPTION_525;
1233 break;1225 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
114 114
115/* --------------- I2C --------------- */115/* --------------- I2C --------------- */
116 116
117static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)117static int i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
118{118{
119 struct tc358743_state *state = to_state(sd);119 struct tc358743_state *state = to_state(sd);
120 struct i2c_client *client = state->i2c_client;120 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
140 v4l2_err(sd, "%s: reading register 0x%x from 0x%x failed: %d\n",140 v4l2_err(sd, "%s: reading register 0x%x from 0x%x failed: %d\n",
141 __func__, reg, client->addr, err);141 __func__, reg, client->addr, err);
142 }142 }
143 return err != ARRAY_SIZE(msgs);
143}144}
144 145
145static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)146static 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
196 }197 }
197}198}
198 199
199static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)200static noinline u32 i2c_rdreg_err(struct v4l2_subdev *sd, u16 reg, u32 n,
201 int *err)
200{202{
203 int error;
201 __le32 val = 0;204 __le32 val = 0;
202 205
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;
204 209
205 return le32_to_cpu(val);210 return le32_to_cpu(val);
206}211}
207 212
213static inline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
214{
215 return i2c_rdreg_err(sd, reg, n, NULL);
216}
217
208static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n)218static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n)
209{219{
210 __le32 raw = cpu_to_le32(val);220 __le32 raw = cpu_to_le32(val);
@@ -233,6 +243,13 @@ static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) · 22 unmodified lines
233 return i2c_rdreg(sd, reg, 2);243 return i2c_rdreg(sd, reg, 2);
234}244}
235 245
246static 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
236static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val)253static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val)
237{254{
238 i2c_wrreg(sd, reg, val, 2);255 i2c_wrreg(sd, reg, val, 2);
@@ -420,9 +437,9 @@ static void tc358743_enable_edid(struct v4l2_subdev *sd) · 181 unmodified lines
420 437
421 v4l2_dbg(2, debug, sd, "%s:\n", __func__);438 v4l2_dbg(2, debug, sd, "%s:\n", __func__);
422 439
423 /* Enable hotplug after 100 ms. DDC access to EDID is also enabled when440 /* Enable hotplug after 143 ms. DDC access to EDID is also enabled when
424 * hotplug is enabled. See register DDC_CTL */441 * 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);
426 443
427 tc358743_enable_interrupts(sd, true);444 tc358743_enable_interrupts(sd, true);
428 tc358743_s_ctrl_detect_tx_5v(sd);445 tc358743_s_ctrl_detect_tx_5v(sd);
@@ -1691,12 +1708,23 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd, · 1262 unmodified lines
1691 return 0;1708 return 0;
1692}1709}
1693 1710
1711static 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
1694static int tc358743_get_fmt(struct v4l2_subdev *sd,1723static int tc358743_get_fmt(struct v4l2_subdev *sd,
1695 struct v4l2_subdev_state *sd_state,1724 struct v4l2_subdev_state *sd_state,
1696 struct v4l2_subdev_format *format)1725 struct v4l2_subdev_format *format)
1697{1726{
1698 struct tc358743_state *state = to_state(sd);1727 struct tc358743_state *state = to_state(sd);
1699 u8 vi_rep = i2c_rd8(sd, VI_REP);
1700 1728
1701 if (format->pad != 0)1729 if (format->pad != 0)
1702 return -EINVAL;1730 return -EINVAL;
@@ -1706,23 +1734,7 @@ static int tc358743_get_fmt(struct v4l2_subdev *sd, · 3 unmodified lines
1706 format->format.height = state->timings.bt.height;1734 format->format.height = state->timings.bt.height;
1707 format->format.field = V4L2_FIELD_NONE;1735 format->format.field = V4L2_FIELD_NONE;
1708 1736
1709 switch (vi_rep & MASK_VOUT_COLOR_SEL) {1737 format->format.colorspace = tc358743_g_colorspace(format->format.code);
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 }
1726 1738
1727 return 0;1739 return 0;
1728}1740}
@@ -1736,19 +1748,14 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd, · 7 unmodified lines
1736 u32 code = format->format.code; /* is overwritten by get_fmt */1748 u32 code = format->format.code; /* is overwritten by get_fmt */
1737 int ret = tc358743_get_fmt(sd, sd_state, format);1749 int ret = tc358743_get_fmt(sd, sd_state, format);
1738 1750
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);
1740 1755
1741 if (ret)1756 if (ret)
1742 return ret;1757 return ret;
1743 1758
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
1752 if (format->which == V4L2_SUBDEV_FORMAT_TRY)1759 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
1753 return 0;1760 return 0;
1754 1761
@@ -1972,8 +1979,19 @@ static int tc358743_probe_of(struct tc358743_state *state) · 217 unmodified lines
1972 state->pdata.refclk_hz = clk_get_rate(refclk);1979 state->pdata.refclk_hz = clk_get_rate(refclk);
1973 state->pdata.ddc5v_delay = DDC5V_DELAY_100_MS;1980 state->pdata.ddc5v_delay = DDC5V_DELAY_100_MS;
1974 state->pdata.enable_hdcp = false;1981 state->pdata.enable_hdcp = false;
1975 /* A FIFO level of 16 should be enough for 2-lane 720p60 at 594 MHz. */1982 /*
1976 state->pdata.fifo_level = 16;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;
1977 /*1995 /*
1978 * The PLL input clock is obtained by dividing refclk by pll_prd.1996 * The PLL input clock is obtained by dividing refclk by pll_prd.
1979 * It must be between 6 MHz and 40 MHz, lower frequency is better.1997 * 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
1993 /*2011 /*
1994 * The CSI bps per lane must be between 62.5 Mbps and 1 Gbps.2012 * The CSI bps per lane must be between 62.5 Mbps and 1 Gbps.
1995 * The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60.2013 * The default is 594 Mbps for 4-lane 1080p60 or 2-lane 720p60.
2014 * 972 Mbps allows 1080P50 UYVY over 2-lane.
1996 */2015 */
1997 bps_pr_lane = 2 * endpoint.link_frequencies[0];2016 bps_pr_lane = 2 * endpoint.link_frequencies[0];
1998 if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) {2017 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
2006 state->pdata.refclk_hz * state->pdata.pll_prd;2025 state->pdata.refclk_hz * state->pdata.pll_prd;
2007 2026
2008 /*2027 /*
2009 * FIXME: These timings are from REF_02 for 594 Mbps per lane (297 MHz2028 * FIXME: These timings are from REF_02 for 594 or 972 Mbps per lane
2010 * link frequency). In principle it should be possible to calculate2029 * (297 MHz or 486 MHz link frequency).
2030 * In principle it should be possible to calculate
2011 * them based on link frequency and resolution.2031 * them based on link frequency and resolution.
2012 */2032 */
2013 if (bps_pr_lane != 594000000U)2033 switch (bps_pr_lane) {
2034 default:
2014 dev_warn(dev, "untested bps per lane: %u bps\n", bps_pr_lane);2035 dev_warn(dev, "untested bps per lane: %u bps\n", bps_pr_lane);
2015 state->pdata.lineinitcnt = 0xe80;2036 fallthrough;
2016 state->pdata.lptxtimecnt = 0x003;2037 case 594000000U:
2017 /* tclk-preparecnt: 3, tclk-zerocnt: 20 */2038 state->pdata.lineinitcnt = 0xe80;
2018 state->pdata.tclk_headercnt = 0x1403;2039 state->pdata.lptxtimecnt = 0x003;
2019 state->pdata.tclk_trailcnt = 0x00;2040 /* tclk-preparecnt: 3, tclk-zerocnt: 20 */
2020 /* ths-preparecnt: 3, ths-zerocnt: 1 */2041 state->pdata.tclk_headercnt = 0x1403;
2021 state->pdata.ths_headercnt = 0x0103;2042 state->pdata.tclk_trailcnt = 0x00;
2022 state->pdata.twakeup = 0x4882;2043 /* ths-preparecnt: 3, ths-zerocnt: 1 */
2023 state->pdata.tclk_postcnt = 0x008;2044 state->pdata.ths_headercnt = 0x0103;
2024 state->pdata.ths_trailcnt = 0x2;2045 state->pdata.twakeup = 0x4882;
2025 state->pdata.hstxvregcnt = 0;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 }
2026 2064
2027 state->reset_gpio = devm_gpiod_get_optional(dev, "reset",2065 state->reset_gpio = devm_gpiod_get_optional(dev, "reset",
2028 GPIOD_OUT_LOW);2066 GPIOD_OUT_LOW);
@@ -2061,6 +2099,7 @@ static int tc358743_probe(struct i2c_client *client) · 32 unmodified lines
2061 struct tc358743_platform_data *pdata = client->dev.platform_data;2099 struct tc358743_platform_data *pdata = client->dev.platform_data;
2062 struct v4l2_subdev *sd;2100 struct v4l2_subdev *sd;
2063 u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK;2101 u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK;
2102 u16 chipid;
2064 int err;2103 int err;
2065 2104
2066 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))2105 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
2092 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;2131 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
2093 2132
2094 /* i2c access */2133 /* i2c access */
2095 if ((i2c_rd16(sd, CHIPID) & MASK_CHIPID) != 0) {2134 if (i2c_rd16_err(sd, CHIPID, &chipid) ||
2135 (chipid & MASK_CHIPID) != 0) {
2096 v4l2_info(sd, "not a TC358743 on address 0x%x\n",2136 v4l2_info(sd, "not a TC358743 on address 0x%x\n",
2097 client->addr << 1);2137 client->addr << 1);
2098 return -ENODEV;2138 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
589 589
590 v4l2_dbg(1, debug, sd, "%s\n", __func__);590 v4l2_dbg(1, debug, sd, "%s\n", __func__);
591 591
592 /* Enable hotplug after 100ms */592 /* Enable hotplug after 143ms */
593 schedule_delayed_work(&state->delayed_work_enable_hpd, HZ / 10);593 schedule_delayed_work(&state->delayed_work_enable_hpd, HZ / 7);
594}594}
595 595
596/* -----------------------------------------------------------------------------596/* -----------------------------------------------------------------------------
drivers/media/i2c/vd55g1.c+16−16
@@ -111,9 +111,9 @@ · 110 unmodified lines
111 111
112#define VD55G1_WIDTH 804112#define VD55G1_WIDTH 804
113#define VD55G1_HEIGHT 704113#define VD55G1_HEIGHT 704
114#define VD55G1_DEFAULT_MODE 0114#define VD55G1_MODE_DEF 0
115#define VD55G1_NB_GPIOS 4115#define VD55G1_NB_GPIOS 4
116#define VD55G1_MEDIA_BUS_FMT_DEF MEDIA_BUS_FMT_Y8_1X8116#define VD55G1_MBUS_CODE_DEF 0
117#define VD55G1_DGAIN_DEF 256117#define VD55G1_DGAIN_DEF 256
118#define VD55G1_AGAIN_DEF 19118#define VD55G1_AGAIN_DEF 19
119#define VD55G1_EXPO_MAX_TERM 64119#define VD55G1_EXPO_MAX_TERM 64
@@ -129,8 +129,8 @@ · 9 unmodified lines
129#define VD55G1_FWPATCH_REVISION_MINOR 9129#define VD55G1_FWPATCH_REVISION_MINOR 9
130#define VD55G1_XCLK_FREQ_MIN (6 * HZ_PER_MHZ)130#define VD55G1_XCLK_FREQ_MIN (6 * HZ_PER_MHZ)
131#define VD55G1_XCLK_FREQ_MAX (27 * HZ_PER_MHZ)131#define VD55G1_XCLK_FREQ_MAX (27 * HZ_PER_MHZ)
132#define VD55G1_MIPI_RATE_MIN (250 * HZ_PER_MHZ)132#define VD55G1_MIPI_RATE_MIN (250 * MEGA)
133#define VD55G1_MIPI_RATE_MAX (1200 * HZ_PER_MHZ)133#define VD55G1_MIPI_RATE_MAX (1200 * MEGA)
134 134
135static const u8 patch_array[] = {135static const u8 patch_array[] = {
136 0x44, 0x03, 0x09, 0x02, 0xe6, 0x01, 0x42, 0x00, 0xea, 0x01, 0x42, 0x00,136 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
883 return ret;883 return ret;
884}884}
885 885
886static void vd55g1_update_img_pad_format(struct vd55g1 *sensor,886static void vd55g1_update_pad_fmt(struct vd55g1 *sensor,
887 const struct vd55g1_mode *mode,887 const struct vd55g1_mode *mode, u32 code,
888 u32 code,888 struct v4l2_mbus_framefmt *fmt)
889 struct v4l2_mbus_framefmt *fmt)
890{889{
891 fmt->code = code;890 fmt->code = code;
892 fmt->width = mode->width;891 fmt->width = mode->width;
@@ -1038,8 +1037,6 @@ static int vd55g1_enable_streams(struct v4l2_subdev *sd, · 145 unmodified lines
1038 if (ret < 0)1037 if (ret < 0)
1039 return ret;1038 return ret;
1040 1039
1041 vd55g1_write(sensor, VD55G1_REG_EXT_CLOCK, sensor->xclk_freq, &ret);
1042
1043 /* Configure output */1040 /* Configure output */
1044 vd55g1_write(sensor, VD55G1_REG_MIPI_DATA_RATE,1041 vd55g1_write(sensor, VD55G1_REG_MIPI_DATA_RATE,
1045 sensor->mipi_rate, &ret);1042 sensor->mipi_rate, &ret);
@@ -1084,7 +1081,7 @@ static int vd55g1_enable_streams(struct v4l2_subdev *sd, · 38 unmodified lines
1084 1081
1085err_rpm_put:1082err_rpm_put:
1086 pm_runtime_put(sensor->dev);1083 pm_runtime_put(sensor->dev);
1087 return 0;1084 return -EINVAL;
1088}1085}
1089 1086
1090static int vd55g1_disable_streams(struct v4l2_subdev *sd,1087static 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
1231 width, height, sd_fmt->format.width,1228 width, height, sd_fmt->format.width,
1232 sd_fmt->format.height);1229 sd_fmt->format.height);
1233 1230
1234 vd55g1_update_img_pad_format(sensor, new_mode, sd_fmt->format.code,1231 vd55g1_update_pad_fmt(sensor, new_mode, sd_fmt->format.code,
1235 &sd_fmt->format);1232 &sd_fmt->format);
1236 1233
1237 /*1234 /*
1238 * Use binning to maximize the crop rectangle size, and centre it in the1235 * 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
1262static int vd55g1_init_state(struct v4l2_subdev *sd,1259static int vd55g1_init_state(struct v4l2_subdev *sd,
1263 struct v4l2_subdev_state *sd_state)1260 struct v4l2_subdev_state *sd_state)
1264{1261{
1265 unsigned int def_mode = VD55G1_DEFAULT_MODE;
1266 struct vd55g1 *sensor = to_vd55g1(sd);1262 struct vd55g1 *sensor = to_vd55g1(sd);
1267 struct v4l2_subdev_format fmt = { 0 };1263 struct v4l2_subdev_format fmt = { 0 };
1268 struct v4l2_subdev_route routes[] = {1264 struct v4l2_subdev_route routes[] = {
@@ -1279,8 +1275,9 @@ static int vd55g1_init_state(struct v4l2_subdev *sd, · 10 unmodified lines
1279 if (ret)1275 if (ret)
1280 return ret;1276 return ret;
1281 1277
1282 vd55g1_update_img_pad_format(sensor, &vd55g1_supported_modes[def_mode],1278 vd55g1_update_pad_fmt(sensor, &vd55g1_supported_modes[VD55G1_MODE_DEF],
1283 VD55G1_MEDIA_BUS_FMT_DEF, &fmt.format);1279 vd55g1_mbus_codes[VD55G1_MBUS_CODE_DEF].code,
1280 &fmt.format);
1284 1281
1285 return vd55g1_set_pad_fmt(sd, sd_state, &fmt);1282 return vd55g1_set_pad_fmt(sd, sd_state, &fmt);
1286}1283}
@@ -1613,6 +1610,9 @@ static int vd55g1_power_on(struct device *dev) · 326 unmodified lines
1613 goto disable_clock;1610 goto disable_clock;
1614 }1611 }
1615 1612
1613 /* Setup clock now to advance through system FSM states */
1614 vd55g1_write(sensor, VD55G1_REG_EXT_CLOCK, sensor->xclk_freq, &ret);
1615
1616 ret = vd55g1_patch(sensor);1616 ret = vd55g1_patch(sensor);
1617 if (ret) {1617 if (ret) {
1618 dev_err(dev, "Sensor patch failed %d\n", ret);1618 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
8 */8 */
9 9
10 10
11#include <linux/bitops.h>
11#include "cx18-driver.h"12#include "cx18-driver.h"
12 13
13/*14/*
@@ -56,15 +57,6 @@ struct vbi_anc_data { · 42 unmodified lines
56 /* u8 fill[]; Variable number of fill bytes */57 /* u8 fill[]; Variable number of fill bytes */
57};58};
58 59
59static 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
68static int decode_vps(u8 *dst, u8 *p)60static int decode_vps(u8 *dst, u8 *p)
69{61{
70 static const u8 biphase_tbl[] = {62 static const u8 biphase_tbl[] = {
@@ -278,7 +270,7 @@ int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, · 207 unmodified lines
278 break;270 break;
279 case 6:271 case 6:
280 sdid = V4L2_SLICED_CAPTION_525;272 sdid = V4L2_SLICED_CAPTION_525;
281 err = !odd_parity(p[0]) || !odd_parity(p[1]);273 err = !parity8(p[0]) || !parity8(p[1]);
282 break;274 break;
283 case 9:275 case 9:
284 sdid = V4L2_SLICED_VPS;276 sdid = V4L2_SLICED_VPS;
drivers/media/pci/cx18/cx18-driver.h+0−12
@@ -271,18 +271,6 @@ struct cx18_options { · 270 unmodified lines
271#define CX18_SLICED_TYPE_WSS_625 (5)271#define CX18_SLICED_TYPE_WSS_625 (5)
272#define CX18_SLICED_TYPE_VPS (7)272#define CX18_SLICED_TYPE_VPS (7)
273 273
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
286struct cx18_vb2_buffer {274struct cx18_vb2_buffer {
287 /* Common video buffer sub-system struct */275 /* Common video buffer sub-system struct */
288 struct vb2_v4l2_buffer vb;276 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
371 mdl->curr_buf = list_first_entry(&mdl->buf_list,371 mdl->curr_buf = list_first_entry(&mdl->buf_list,
372 struct cx18_buffer, list);372 struct cx18_buffer, list);
373 373
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)) {
375 /*375 /*
376 * For some reason we've exhausted the buffers, but the MDL376 * For some reason we've exhausted the buffers, but the MDL
377 * object still said some data was unread.377 * 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
764 mdl->curr_buf = list_first_entry(&mdl->buf_list,764 mdl->curr_buf = list_first_entry(&mdl->buf_list,
765 struct cx18_buffer, list);765 struct cx18_buffer, list);
766 766
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)) {
768 /*768 /*
769 * For some reason we've exhausted the buffers, but the MDL769 * For some reason we've exhausted the buffers, but the MDL
770 * object still said some data was unread.770 * 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
55 /* Himax HM2172 */55 /* Himax HM2172 */
56 IPU_SENSOR_CONFIG("HIMX2172", 1, 384000000),56 IPU_SENSOR_CONFIG("HIMX2172", 1, 384000000),
57 /* GalaxyCore GC0310 */57 /* GalaxyCore GC0310 */
58 IPU_SENSOR_CONFIG("INT0310", 0),58 IPU_SENSOR_CONFIG("INT0310", 1, 55692000),
59 /* Omnivision OV5693 */59 /* Omnivision OV5693 */
60 IPU_SENSOR_CONFIG("INT33BE", 1, 419200000),60 IPU_SENSOR_CONFIG("INT33BE", 1, 419200000),
61 /* Onsemi MT9M114 */
62 IPU_SENSOR_CONFIG("INT33F0", 1, 384000000),
61 /* Omnivision OV2740 */63 /* Omnivision OV2740 */
62 IPU_SENSOR_CONFIG("INT3474", 1, 180000000),64 IPU_SENSOR_CONFIG("INT3474", 1, 180000000),
65 /* Omnivision OV5670 */
66 IPU_SENSOR_CONFIG("INT3479", 1, 422400000),
63 /* Omnivision OV8865 */67 /* Omnivision OV8865 */
64 IPU_SENSOR_CONFIG("INT347A", 1, 360000000),68 IPU_SENSOR_CONFIG("INT347A", 1, 360000000),
65 /* Omnivision OV7251 */69 /* Omnivision OV7251 */
@@ -78,7 +82,7 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { · 12 unmodified lines
78 /* Omnivision OV08A10 */82 /* Omnivision OV08A10 */
79 IPU_SENSOR_CONFIG("OVTI08A1", 1, 500000000),83 IPU_SENSOR_CONFIG("OVTI08A1", 1, 500000000),
80 /* Omnivision OV08x40 */84 /* Omnivision OV08x40 */
81 IPU_SENSOR_CONFIG("OVTI08F4", 1, 400000000),85 IPU_SENSOR_CONFIG("OVTI08F4", 3, 400000000, 749000000, 800000000),
82 /* Omnivision OV13B10 */86 /* Omnivision OV13B10 */
83 IPU_SENSOR_CONFIG("OVTI13B1", 1, 560000000),87 IPU_SENSOR_CONFIG("OVTI13B1", 1, 560000000),
84 IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),88 IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
@@ -86,6 +90,8 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { · 1 unmodified line
86 IPU_SENSOR_CONFIG("OVTI2680", 1, 331200000),90 IPU_SENSOR_CONFIG("OVTI2680", 1, 331200000),
87 /* Omnivision OV8856 */91 /* Omnivision OV8856 */
88 IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000),92 IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000),
93 /* Toshiba T4KA3 */
94 IPU_SENSOR_CONFIG("XMCC0003", 1, 321468000),
89};95};
90 96
91static const struct ipu_property_names prop_names = {97static const struct ipu_property_names prop_names = {
@@ -809,7 +815,8 @@ int ipu_bridge_init(struct device *dev, · 717 unmodified lines
809 return 0;815 return 0;
810 816
811 if (!ipu_bridge_ivsc_is_ready())817 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");
813 820
814 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);821 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
815 if (!bridge)822 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
358 static const int FBPT_WIDTH = DIV_ROUND_UP(CIO2_MAX_LOPS,358 static const int FBPT_WIDTH = DIV_ROUND_UP(CIO2_MAX_LOPS,
359 CIO2_FBPT_SUBENTRY_UNIT);359 CIO2_FBPT_SUBENTRY_UNIT);
360 const u32 num_buffers1 = CIO2_MAX_BUFFERS - 1;360 const u32 num_buffers1 = CIO2_MAX_BUFFERS - 1;
361 struct v4l2_subdev_state *state;
362 const struct v4l2_mbus_framefmt *format;
361 const struct ipu3_cio2_fmt *fmt;363 const struct ipu3_cio2_fmt *fmt;
362 void __iomem *const base = cio2->base;364 void __iomem *const base = cio2->base;
363 u8 lanes, csi2bus = q->csi2.port;365 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
365 struct cio2_csi2_timing timing = { 0 };367 struct cio2_csi2_timing timing = { 0 };
366 int i, r;368 int i, r;
367 369
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
369 if (!fmt)377 if (!fmt)
370 return -EINVAL;378 return -EINVAL;
371 379
@@ -1194,9 +1202,9 @@ static int cio2_subdev_subscribe_event(struct v4l2_subdev *sd, · 822 unmodified lines
1194 return v4l2_event_subscribe(fh, sub, 0, NULL);1202 return v4l2_event_subscribe(fh, sub, 0, NULL);
1195}1203}
1196 1204
1197static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)1205static int cio2_subdev_init_state(struct v4l2_subdev *sd,
1206 struct v4l2_subdev_state *state)
1198{1207{
1199 struct v4l2_mbus_framefmt *format;
1200 const struct v4l2_mbus_framefmt fmt_default = {1208 const struct v4l2_mbus_framefmt fmt_default = {
1201 .width = 1936,1209 .width = 1936,
1202 .height = 1096,1210 .height = 1096,
@@ -1207,42 +1215,23 @@ static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) · 4 unmodified lines
1207 .quantization = V4L2_QUANTIZATION_DEFAULT,1215 .quantization = V4L2_QUANTIZATION_DEFAULT,
1208 .xfer_func = V4L2_XFER_FUNC_DEFAULT,1216 .xfer_func = V4L2_XFER_FUNC_DEFAULT,
1209 };1217 };
1218 struct v4l2_mbus_framefmt *format;
1210 1219
1211 /* Initialize try_fmt */1220 /* Initialize the format on the sink and source pads. */
1212 format = v4l2_subdev_state_get_format(fh->state, CIO2_PAD_SINK);1221 format = v4l2_subdev_state_get_format(state, CIO2_PAD_SINK);
1213 *format = fmt_default;1222 *format = fmt_default;
1214 1223
1215 /* same as sink */1224 /* 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);
1217 *format = fmt_default;1226 *format = fmt_default;
1218 1227
1219 return 0;1228 return 0;
1220}1229}
1221 1230
1222static 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
1241static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,1231static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
1242 struct v4l2_subdev_state *sd_state,1232 struct v4l2_subdev_state *sd_state,
1243 struct v4l2_subdev_format *fmt)1233 struct v4l2_subdev_format *fmt)
1244{1234{
1245 struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
1246 struct v4l2_mbus_framefmt *mbus;1235 struct v4l2_mbus_framefmt *mbus;
1247 u32 mbus_code = fmt->format.code;1236 u32 mbus_code = fmt->format.code;
1248 unsigned int i;1237 unsigned int i;
@@ -1252,12 +1241,7 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd, · 3 unmodified lines
1252 * source always propagates from sink1241 * source always propagates from sink
1253 */1242 */
1254 if (fmt->pad == CIO2_PAD_SOURCE)1243 if (fmt->pad == CIO2_PAD_SOURCE)
1255 return cio2_subdev_get_fmt(sd, sd_state, fmt);1244 return v4l2_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;
1261 1245
1262 fmt->format.code = formats[0].mbus_code;1246 fmt->format.code = formats[0].mbus_code;
1263 1247
@@ -1272,9 +1256,12 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd, · 8 unmodified lines
1272 fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_HEIGHT);1256 fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_HEIGHT);
1273 fmt->format.field = V4L2_FIELD_NONE;1257 fmt->format.field = V4L2_FIELD_NONE;
1274 1258
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);
1276 *mbus = fmt->format;1264 *mbus = fmt->format;
1277 mutex_unlock(&q->subdev_lock);
1278 1265
1279 return 0;1266 return 0;
1280}1267}
@@ -1345,12 +1332,12 @@ static const struct v4l2_subdev_core_ops cio2_subdev_core_ops = { · 64 unmodified lines
1345};1332};
1346 1333
1347static const struct v4l2_subdev_internal_ops cio2_subdev_internal_ops = {1334static const struct v4l2_subdev_internal_ops cio2_subdev_internal_ops = {
1348 .open = cio2_subdev_open,1335 .init_state = cio2_subdev_init_state,
1349};1336};
1350 1337
1351static const struct v4l2_subdev_pad_ops cio2_subdev_pad_ops = {1338static const struct v4l2_subdev_pad_ops cio2_subdev_pad_ops = {
1352 .link_validate = v4l2_subdev_link_validate_default,1339 .link_validate = v4l2_subdev_link_validate_default,
1353 .get_fmt = cio2_subdev_get_fmt,1340 .get_fmt = v4l2_subdev_get_fmt,
1354 .set_fmt = cio2_subdev_set_fmt,1341 .set_fmt = cio2_subdev_set_fmt,
1355 .enum_mbus_code = cio2_subdev_enum_mbus_code,1342 .enum_mbus_code = cio2_subdev_enum_mbus_code,
1356};1343};
@@ -1502,28 +1489,18 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q) · 145 unmodified lines
1502{1489{
1503 static const u32 default_width = 1936;1490 static const u32 default_width = 1936;
1504 static const u32 default_height = 1096;1491 static const u32 default_height = 1096;
1505 const struct ipu3_cio2_fmt dflt_fmt = formats[0];
1506 struct device *dev = &cio2->pci_dev->dev;1492 struct device *dev = &cio2->pci_dev->dev;
1507 struct video_device *vdev = &q->vdev;1493 struct video_device *vdev = &q->vdev;
1508 struct vb2_queue *vbq = &q->vbq;1494 struct vb2_queue *vbq = &q->vbq;
1509 struct v4l2_subdev *subdev = &q->subdev;1495 struct v4l2_subdev *subdev = &q->subdev;
1510 struct v4l2_mbus_framefmt *fmt;
1511 int r;1496 int r;
1512 1497
1513 /* Initialize miscellaneous variables */1498 /* Initialize miscellaneous variables */
1514 mutex_init(&q->lock);1499 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;
1523 1500
1524 q->format.width = default_width;1501 q->format.width = default_width;
1525 q->format.height = default_height;1502 q->format.height = default_height;
1526 q->format.pixelformat = dflt_fmt.fourcc;1503 q->format.pixelformat = formats[0].fourcc;
1527 q->format.colorspace = V4L2_COLORSPACE_RAW;1504 q->format.colorspace = V4L2_COLORSPACE_RAW;
1528 q->format.field = V4L2_FIELD_NONE;1505 q->format.field = V4L2_FIELD_NONE;
1529 q->format.num_planes = 1;1506 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
1567 CIO2_ENTITY_NAME " %td", q - cio2->queue);1544 CIO2_ENTITY_NAME " %td", q - cio2->queue);
1568 subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;1545 subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
1569 v4l2_set_subdevdata(subdev, cio2);1546 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
1570 r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev);1554 r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev);
1571 if (r) {1555 if (r) {
1572 dev_err(dev, "failed initialize subdev (%d)\n", r);1556 dev_err(dev, "failed to register subdev (%d)\n", r);
1573 goto fail_subdev;1557 goto fail_subdev;
1574 }1558 }
1575 1559
@@ -1626,7 +1610,6 @@ fail_vdev_media_entity: · 50 unmodified lines
1626fail_subdev_media_entity:1610fail_subdev_media_entity:
1627 cio2_fbpt_exit(q, dev);1611 cio2_fbpt_exit(q, dev);
1628fail_fbpt:1612fail_fbpt:
1629 mutex_destroy(&q->subdev_lock);
1630 mutex_destroy(&q->lock);1613 mutex_destroy(&q->lock);
1631 1614
1632 return r;1615 return r;
@@ -1639,7 +1622,6 @@ static void cio2_queue_exit(struct cio2_device *cio2, struct cio2_queue *q) · 6 unmodified lines
1639 v4l2_device_unregister_subdev(&q->subdev);1622 v4l2_device_unregister_subdev(&q->subdev);
1640 media_entity_cleanup(&q->subdev.entity);1623 media_entity_cleanup(&q->subdev.entity);
1641 cio2_fbpt_exit(q, &cio2->pci_dev->dev);1624 cio2_fbpt_exit(q, &cio2->pci_dev->dev);
1642 mutex_destroy(&q->subdev_lock);
1643 mutex_destroy(&q->lock);1625 mutex_destroy(&q->lock);
1644}1626}
1645 1627
drivers/media/pci/intel/ipu3/ipu3-cio2.h+0−2
@@ -351,9 +351,7 @@ struct cio2_queue { · 350 unmodified lines
351 351
352 /* Subdev, /dev/v4l-subdevX */352 /* Subdev, /dev/v4l-subdevX */
353 struct v4l2_subdev subdev;353 struct v4l2_subdev subdev;
354 struct mutex subdev_lock; /* Serialise acces to subdev_fmt field */
355 struct media_pad subdev_pads[CIO2_PADS];354 struct media_pad subdev_pads[CIO2_PADS];
356 struct v4l2_mbus_framefmt subdev_fmt;
357 atomic_t frame_sequence;355 atomic_t frame_sequence;
358 356
359 /* Video device, /dev/videoX */357 /* 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
354 remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);354 remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
355 remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);355 remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
356 356
357 sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,357 sink_streams =
358 CSI2_PAD_SINK,358 v4l2_subdev_state_xlate_streams(state, pad, CSI2_PAD_SINK,
359 &streams_mask);359 &streams_mask);
360 360
361 ret = ipu6_isys_csi2_calc_timing(csi2, &timing, CSI2_ACCINV);361 ret = ipu6_isys_csi2_calc_timing(csi2, &timing, CSI2_ACCINV);
362 if (ret)362 if (ret)
@@ -384,9 +384,9 @@ static int ipu6_isys_csi2_disable_streams(struct v4l2_subdev *sd, · 21 unmodified lines
384 struct media_pad *remote_pad;384 struct media_pad *remote_pad;
385 u64 sink_streams;385 u64 sink_streams;
386 386
387 sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,387 sink_streams =
388 CSI2_PAD_SINK,388 v4l2_subdev_state_xlate_streams(state, pad, CSI2_PAD_SINK,
389 &streams_mask);389 &streams_mask);
390 390
391 remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);391 remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
392 remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);392 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
40#define IPU6_ISYS_NUM_RECV_QUEUE 140#define IPU6_ISYS_NUM_RECV_QUEUE 1
41 41
42#define IPU6_ISYS_MIN_WIDTH 2U42#define IPU6_ISYS_MIN_WIDTH 2U
43#define IPU6_ISYS_MIN_HEIGHT 2U43#define IPU6_ISYS_MIN_HEIGHT 1U
44#define IPU6_ISYS_MAX_WIDTH 4672U44#define IPU6_ISYS_MAX_WIDTH 4672U
45#define IPU6_ISYS_MAX_HEIGHT 3416U45#define IPU6_ISYS_MAX_HEIGHT 3416U
46 46
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
529 529
530 ace_set_camera_owner(ace, ACE_CAMERA_IVSC);530 ace_set_camera_owner(ace, ACE_CAMERA_IVSC);
531 531
532 mei_cldev_disable(cldev);
533
532 mutex_destroy(&ace->lock);534 mutex_destroy(&ace->lock);
533}535}
534 536
@@ -574,7 +576,7 @@ static struct mei_cl_driver mei_ace_driver = { · 39 unmodified lines
574 576
575module_mei_cl_driver(mei_ace_driver);577module_mei_cl_driver(mei_ace_driver);
576 578
577MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");579MODULE_AUTHOR("Wentong Wu");
578MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");580MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
579MODULE_DESCRIPTION("Device driver for IVSC ACE");581MODULE_DESCRIPTION("Device driver for IVSC ACE");
580MODULE_LICENSE("GPL");582MODULE_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
760 760
761 pm_runtime_disable(&cldev->dev);761 pm_runtime_disable(&cldev->dev);
762 762
763 mei_cldev_disable(cldev);
764
763 mutex_destroy(&csi->lock);765 mutex_destroy(&csi->lock);
764}766}
765 767
@@ -783,7 +785,7 @@ static struct mei_cl_driver mei_csi_driver = { · 17 unmodified lines
783module_mei_cl_driver(mei_csi_driver);785module_mei_cl_driver(mei_csi_driver);
784 786
785MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");787MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
786MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");788MODULE_AUTHOR("Wentong Wu");
787MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");789MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
788MODULE_DESCRIPTION("Device driver for IVSC CSI");790MODULE_DESCRIPTION("Device driver for IVSC CSI");
789MODULE_LICENSE("GPL");791MODULE_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
492static int vidioc_enum_dv_timings(struct file *file, void *fh,492static int vidioc_enum_dv_timings(struct file *file, void *fh,
493 struct v4l2_enum_dv_timings *timings)493 struct v4l2_enum_dv_timings *timings)
494{494{
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;
496}503}
497 504
498static int vidioc_dv_timings_cap(struct file *file, void *fh,505static 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
52 * | etc52 * | etc
53 */53 */
54 54
55void 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}
75/* Allocate a new buffer structure and associated PCI space in bytes.55/* Allocate a new buffer structure and associated PCI space in bytes.
76 * len must be a multiple of sizeof(u64)56 * len must be a multiple of sizeof(u64)
77 */57 */
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
295 return ret;295 return ret;
296}296}
297 297
298void 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
326int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,298int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
327 u16 controlselector, u16 size, void *buf)299 u16 controlselector, u16 size, void *buf)
328{300{
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
508int saa7164_cmd_send(struct saa7164_dev *dev,508int saa7164_cmd_send(struct saa7164_dev *dev,
509 u8 id, enum tmComResCmd command, u16 controlselector,509 u8 id, enum tmComResCmd command, u16 controlselector,
510 u16 size, void *buf);510 u16 size, void *buf);
511void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
512int saa7164_irq_dequeue(struct saa7164_dev *dev);511int saa7164_irq_dequeue(struct saa7164_dev *dev);
513 512
514/* ----------------------------------------------------------- */513/* ----------------------------------------------------------- */
@@ -570,7 +569,6 @@ extern int saa7164_dvb_unregister(struct saa7164_port *port); · 55 unmodified lines
570extern struct saa7164_buffer *saa7164_buffer_alloc(569extern struct saa7164_buffer *saa7164_buffer_alloc(
571 struct saa7164_port *port, u32 len);570 struct saa7164_port *port, u32 len);
572extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf);571extern int saa7164_buffer_dealloc(struct saa7164_buffer *buf);
573extern void saa7164_buffer_display(struct saa7164_buffer *buf);
574extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i);572extern int saa7164_buffer_activate(struct saa7164_buffer *buf, int i);
575extern int saa7164_buffer_cfg_port(struct saa7164_port *port);573extern int saa7164_buffer_cfg_port(struct saa7164_port *port);
576extern struct saa7164_user_buffer *saa7164_buffer_alloc_user(574extern 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
116 return -1;116 return -1;
117}117}
118 118
119static int solo_gpiochip_direction_input(struct gpio_chip *chip,
120 unsigned int offset)
121{
122 return -1;
123}
124
125static int solo_gpiochip_direction_output(struct gpio_chip *chip,
126 unsigned int offset, int value)
127{
128 return -1;
129}
130
131static int solo_gpiochip_get(struct gpio_chip *chip,119static int solo_gpiochip_get(struct gpio_chip *chip,
132 unsigned int offset)120 unsigned int offset)
133{121{
@@ -139,8 +127,8 @@ static int solo_gpiochip_get(struct gpio_chip *chip, · 5 unmodified lines
139 return 1 & (ret >> (offset + 8));127 return 1 & (ret >> (offset + 8));
140}128}
141 129
142static void solo_gpiochip_set(struct gpio_chip *chip,130static int solo_gpiochip_set(struct gpio_chip *chip,
143 unsigned int offset, int value)131 unsigned int offset, int value)
144{132{
145 struct solo_dev *solo_dev = gpiochip_get_data(chip);133 struct solo_dev *solo_dev = gpiochip_get_data(chip);
146 134
@@ -148,6 +136,8 @@ static void solo_gpiochip_set(struct gpio_chip *chip, · 1 unmodified line
148 solo_gpio_set(solo_dev, 1 << (offset + 8));136 solo_gpio_set(solo_dev, 1 << (offset + 8));
149 else137 else
150 solo_gpio_clear(solo_dev, 1 << (offset + 8));138 solo_gpio_clear(solo_dev, 1 << (offset + 8));
139
140 return 0;
151}141}
152#endif142#endif
153 143
@@ -167,10 +157,8 @@ int solo_gpio_init(struct solo_dev *solo_dev) · 13 unmodified lines
167 solo_dev->gpio_dev.can_sleep = 0;157 solo_dev->gpio_dev.can_sleep = 0;
168 158
169 solo_dev->gpio_dev.get_direction = solo_gpiochip_get_direction;159 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;
172 solo_dev->gpio_dev.get = solo_gpiochip_get;160 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;
174 162
175 ret = gpiochip_add_data(&solo_dev->gpio_dev, solo_dev);163 ret = gpiochip_add_data(&solo_dev->gpio_dev, solo_dev);
176 164
drivers/media/platform/amphion/vdec.c+249−45
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include "vpu_cmds.h"26#include "vpu_cmds.h"
27#include "vpu_rpc.h"27#include "vpu_rpc.h"
28 28
29#define VDEC_SLOT_CNT_DFT 32
29#define VDEC_MIN_BUFFER_CAP 830#define VDEC_MIN_BUFFER_CAP 8
30#define VDEC_MIN_BUFFER_OUT 831#define VDEC_MIN_BUFFER_OUT 8
31 32
@@ -41,6 +42,14 @@ struct vdec_fs_info { · 9 unmodified lines
41 u32 tag;42 u32 tag;
42};43};
43 44
45struct 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
44struct vdec_t {53struct vdec_t {
45 u32 seq_hdr_found;54 u32 seq_hdr_found;
46 struct vpu_buffer udata;55 struct vpu_buffer udata;
@@ -48,7 +57,8 @@ struct vdec_t { · 1 unmodified line
48 struct vpu_dec_codec_info codec_info;57 struct vpu_dec_codec_info codec_info;
49 enum vpu_codec_state state;58 enum vpu_codec_state state;
50 59
51 struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];60 struct vdec_frame_store_t *slots;
61 u32 slot_count;
52 u32 req_frame_count;62 u32 req_frame_count;
53 struct vdec_fs_info mbi;63 struct vdec_fs_info mbi;
54 struct vdec_fs_info dcp;64 struct vdec_fs_info dcp;
@@ -232,6 +242,35 @@ static int vdec_ctrl_init(struct vpu_inst *inst) · 177 unmodified lines
232 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,242 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,
233 0, 1, 1, 0);243 0, 1, 1, 0);
234 244
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
235 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,274 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
236 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);275 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
237 if (ctrl)276 if (ctrl)
@@ -258,6 +297,63 @@ static int vdec_ctrl_init(struct vpu_inst *inst) · 20 unmodified lines
258 return 0;297 return 0;
259}298}
260 299
300static 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
346static 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
261static void vdec_handle_resolution_change(struct vpu_inst *inst)357static void vdec_handle_resolution_change(struct vpu_inst *inst)
262{358{
263 struct vdec_t *vdec = inst->priv;359 struct vdec_t *vdec = inst->priv;
@@ -714,11 +810,11 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg) · 450 unmodified lines
714 struct vb2_v4l2_buffer *src_buf;810 struct vb2_v4l2_buffer *src_buf;
715 int ret = 0;811 int ret = 0;
716 812
717 if (!info || info->id >= ARRAY_SIZE(vdec->slots))813 if (!info || info->id >= vdec->slot_count)
718 return -EINVAL;814 return -EINVAL;
719 815
720 vpu_inst_lock(inst);816 vpu_inst_lock(inst);
721 vpu_buf = vdec->slots[info->id];817 vpu_buf = vdec->slots[info->id].curr;
722 if (!vpu_buf) {818 if (!vpu_buf) {
723 dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);819 dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
724 ret = -EINVAL;820 ret = -EINVAL;
@@ -739,11 +835,13 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg) · 14 unmodified lines
739 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)835 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
740 dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);836 dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
741 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);837 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
838 vdec->slots[info->id].state = VPU_BUF_STATE_DECODED;
742 vdec->decoded_frame_count++;839 vdec->decoded_frame_count++;
743 if (vdec->params.display_delay_enable) {840 if (vdec->params.display_delay_enable) {
744 struct vpu_format *cur_fmt;841 struct vpu_format *cur_fmt;
745 842
746 cur_fmt = vpu_get_format(inst, inst->cap_format.type);843 cur_fmt = vpu_get_format(inst, inst->cap_format.type);
844 vdec->slots[info->id].state = VPU_BUF_STATE_READY;
747 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);845 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
748 for (int i = 0; i < vbuf->vb2_buf.num_planes; i++)846 for (int i = 0; i < vbuf->vb2_buf.num_planes; i++)
749 vb2_set_plane_payload(&vbuf->vb2_buf,847 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
766 struct vdec_t *vdec = inst->priv;864 struct vdec_t *vdec = inst->priv;
767 int i;865 int i;
768 866
769 for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {867 for (i = 0; i < vdec->slot_count; i++) {
770 if (!vdec->slots[i])868 if (!vdec->slots[i].curr)
771 continue;869 continue;
772 if (luma == vdec->slots[i]->luma)870 if (luma == vdec->slots[i].addr)
773 return vdec->slots[i];871 return vdec->slots[i].curr;
774 }872 }
775 873
776 return NULL;874 return NULL;
@@ -804,11 +902,11 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame) · 27 unmodified lines
804 902
805 cur_fmt = vpu_get_format(inst, inst->cap_format.type);903 cur_fmt = vpu_get_format(inst, inst->cap_format.type);
806 vbuf = &vpu_buf->m2m_buf.vb;904 vbuf = &vpu_buf->m2m_buf.vb;
807 if (vbuf->vb2_buf.index != frame->id)905 if (vpu_buf->fs_id != frame->id)
808 dev_err(inst->dev, "[%d] buffer id(%d, %d) mismatch\n",906 dev_err(inst->dev, "[%d] buffer id(%d(%d), %d) mismatch\n",
809 inst->id, vbuf->vb2_buf.index, frame->id);907 inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index, frame->id);
810 908
811 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable)909 if (vdec->params.display_delay_enable)
812 return;910 return;
813 911
814 if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)912 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
821 vbuf->sequence = vdec->sequence;919 vbuf->sequence = vdec->sequence;
822 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);920 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
823 921
824 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
825 vpu_inst_lock(inst);922 vpu_inst_lock(inst);
923 vdec->slots[vpu_buf->fs_id].state = VPU_BUF_STATE_READY;
826 vdec->display_frame_count++;924 vdec->display_frame_count++;
827 vpu_inst_unlock(inst);925 vpu_inst_unlock(inst);
926 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
828 dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",927 dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
829 inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);928 inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
830}929}
@@ -1052,18 +1151,30 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb · 221 unmodified lines
1052 if (!vbuf)1151 if (!vbuf)
1053 return -EINVAL;1152 return -EINVAL;
1054 1153
1055 if (vdec->slots[vbuf->vb2_buf.index]) {1154 vpu_buf = to_vpu_vb2_buffer(vbuf);
1056 dev_err(inst->dev, "[%d] repeat alloc fs %d\n",1155 if (vpu_buf->fs_id < 0 || vpu_buf->fs_id >= vdec->slot_count) {
1057 inst->id, vbuf->vb2_buf.index);1156 dev_err(inst->dev, "invalid fs %d for v4l2 buffer %d\n",
1157 vpu_buf->fs_id, vbuf->vb2_buf.index);
1058 return -EINVAL;1158 return -EINVAL;
1059 }1159 }
1060 1160
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
1061 dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n",1173 dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n",
1062 inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag);1174 inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag);
1063 vpu_buf = to_vpu_vb2_buffer(vbuf);
1064 1175
1065 memset(&info, 0, sizeof(info));1176 memset(&info, 0, sizeof(info));
1066 info.id = vbuf->vb2_buf.index;1177 info.id = vpu_buf->fs_id;
1067 info.type = MEM_RES_FRAME;1178 info.type = MEM_RES_FRAME;
1068 info.tag = vdec->seq_tag;1179 info.tag = vdec->seq_tag;
1069 info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);1180 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
1078 if (ret)1189 if (ret)
1079 return ret;1190 return ret;
1080 1191
1081 vpu_buf->tag = info.tag;
1082 vpu_buf->luma = info.luma_addr;1192 vpu_buf->luma = info.luma_addr;
1083 vpu_buf->chroma_u = info.chroma_addr;1193 vpu_buf->chroma_u = info.chroma_addr;
1084 vpu_buf->chroma_v = 0;1194 vpu_buf->chroma_v = 0;
1085 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);1195 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;
1087 vdec->req_frame_count--;1199 vdec->req_frame_count--;
1088 1200
1089 return 0;1201 return 0;
@@ -1144,25 +1256,76 @@ static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *v · 54 unmodified lines
1144 v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);1256 v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
1145}1257}
1146 1258
1147static void vdec_clear_slots(struct vpu_inst *inst)1259static void vdec_release_curr_frame_store(struct vpu_inst *inst, u32 id)
1148{1260{
1149 struct vdec_t *vdec = inst->priv;1261 struct vdec_t *vdec = inst->priv;
1150 struct vpu_vb2_buffer *vpu_buf;1262 struct vpu_vb2_buffer *vpu_buf;
1151 struct vb2_v4l2_buffer *vbuf;1263 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
1289static void vdec_clear_slots(struct vpu_inst *inst)
1290{
1291 struct vdec_t *vdec = inst->priv;
1152 int i;1292 int i;
1153 1293
1154 for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {1294 for (i = 0; i < vdec->slot_count; i++) {
1155 if (!vdec->slots[i])1295 if (!vdec->slots[i].curr)
1156 continue;1296 continue;
1157 1297
1158 vpu_buf = vdec->slots[i];
1159 vbuf = &vpu_buf->m2m_buf.vb;
1160
1161 vpu_trace(inst->dev, "clear slot %d\n", i);1298 vpu_trace(inst->dev, "clear slot %d\n", i);
1162 vdec_response_fs_release(inst, i, vpu_buf->tag);1299 vdec_release_curr_frame_store(inst, i);
1163 vdec_recycle_buffer(inst, vbuf);1300 }
1164 vdec->slots[i]->state = VPU_BUF_STATE_IDLE;1301}
1165 vdec->slots[i] = NULL;1302
1303static 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
1311static 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;
1166 }1329 }
1167}1330}
1168 1331
@@ -1189,6 +1352,7 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info · 20 unmodified lines
1189 vdec_init_crop(inst);1352 vdec_init_crop(inst);
1190 vdec_init_mbi(inst);1353 vdec_init_mbi(inst);
1191 vdec_init_dcp(inst);1354 vdec_init_dcp(inst);
1355 vdec_update_v4l2_profile_level(inst, hdr);
1192 if (!vdec->seq_hdr_found) {1356 if (!vdec->seq_hdr_found) {
1193 vdec->seq_tag = vdec->codec_info.tag;1357 vdec->seq_tag = vdec->codec_info.tag;
1194 if (vdec->is_source_changed) {1358 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
1263static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)1427static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
1264{1428{
1265 struct vdec_t *vdec = inst->priv;1429 struct vdec_t *vdec = inst->priv;
1266 struct vpu_vb2_buffer *vpu_buf;
1267 struct vb2_v4l2_buffer *vbuf;
1268 1430
1269 if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))1431 if (!fs || fs->id >= vdec->slot_count)
1270 return;1432 return;
1271 if (fs->type != MEM_RES_FRAME)1433 if (fs->type != MEM_RES_FRAME)
1272 return;1434 return;
1273 1435
1274 if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {1436 if (fs->id >= vdec->slot_count) {
1275 dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);1437 dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
1276 return;1438 return;
1277 }1439 }
1278 1440
1279 vpu_inst_lock(inst);1441 vpu_inst_lock(inst);
1280 vpu_buf = vdec->slots[fs->id];1442 if (!vdec->slots[fs->id].curr) {
1281 vdec->slots[fs->id] = NULL;
1282
1283 if (!vpu_buf) {
1284 dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);1443 dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
1285 goto exit;1444 goto exit;
1286 }1445 }
1287 1446
1288 vbuf = &vpu_buf->m2m_buf.vb;1447 if (vdec->slots[fs->id].state == VPU_BUF_STATE_DECODED) {
1289 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
1290 dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);1448 dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
1291 vdec->sequence++;1449 vdec->sequence++;
1292 }1450 }
1293 1451
1294 vdec_response_fs_release(inst, fs->id, vpu_buf->tag);1452 vdec_release_curr_frame_store(inst, fs->id);
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);
1299 vpu_process_capture_buffer(inst);1453 vpu_process_capture_buffer(inst);
1300 1454
1301exit:1455exit:
@@ -1485,6 +1639,11 @@ static void vdec_cleanup(struct vpu_inst *inst) · 183 unmodified lines
1485 return;1639 return;
1486 1640
1487 vdec = inst->priv;1641 vdec = inst->priv;
1642 if (vdec) {
1643 kfree(vdec->slots);
1644 vdec->slots = NULL;
1645 vdec->slot_count = 0;
1646 }
1488 vfree(vdec);1647 vfree(vdec);
1489 inst->priv = NULL;1648 inst->priv = NULL;
1490 vfree(inst);1649 vfree(inst);
@@ -1606,11 +1765,43 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type) · 115 unmodified lines
1606 return 0;1765 return 0;
1607}1766}
1608 1767
1609static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)1768static int vdec_get_slot_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
1610{1769{
1611 struct vdec_t *vdec = inst->priv;1770 struct vdec_t *vdec = inst->priv;
1771 struct vpu_vb2_buffer *vpu_buf;
1612 int num = -1;1772 int num = -1;
1613 1773
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");
1794exit:
1795 vpu_inst_unlock(inst);
1796
1797 return num;
1798}
1799
1800static 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
1614 switch (i) {1805 switch (i) {
1615 case 0:1806 case 0:
1616 num = scnprintf(str, size,1807 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
1664 vdec->codec_info.vui_present);1855 vdec->codec_info.vui_present);
1665 break;1856 break;
1666 default:1857 default:
1858 num = vdec_get_slot_debug_info(inst, str, size, i - 10);
1667 break;1859 break;
1668 }1860 }
1669 1861
@@ -1687,6 +1879,8 @@ static struct vpu_inst_ops vdec_inst_ops = { · 17 unmodified lines
1687 .get_debug_info = vdec_get_debug_info,1879 .get_debug_info = vdec_get_debug_info,
1688 .wait_prepare = vpu_inst_unlock,1880 .wait_prepare = vpu_inst_unlock,
1689 .wait_finish = vpu_inst_lock,1881 .wait_finish = vpu_inst_lock,
1882 .attach_frame_store = vdec_attach_frame_store,
1883 .reset_frame_store = vdec_reset_frame_store,
1690};1884};
1691 1885
1692static void vdec_init(struct file *file)1886static void vdec_init(struct file *file)
@@ -1727,6 +1921,16 @@ static int vdec_open(struct file *file) · 34 unmodified lines
1727 return -ENOMEM;1921 return -ENOMEM;
1728 }1922 }
1729 1923
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
1730 inst->ops = &vdec_inst_ops;1934 inst->ops = &vdec_inst_ops;
1731 inst->formats = vdec_formats;1935 inst->formats = vdec_formats;
1732 inst->type = VPU_CORE_TYPE_DEC;1936 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
222 int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);222 int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
223 void (*wait_prepare)(struct vpu_inst *inst);223 void (*wait_prepare)(struct vpu_inst *inst);
224 void (*wait_finish)(struct vpu_inst *inst);224 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);
225};227};
226 228
227struct vpu_inst {229struct vpu_inst {
@@ -295,7 +297,8 @@ enum { · 67 unmodified lines
295 VPU_BUF_STATE_DECODED,297 VPU_BUF_STATE_DECODED,
296 VPU_BUF_STATE_READY,298 VPU_BUF_STATE_READY,
297 VPU_BUF_STATE_SKIP,299 VPU_BUF_STATE_SKIP,
298 VPU_BUF_STATE_ERROR300 VPU_BUF_STATE_ERROR,
301 VPU_BUF_STATE_CHANGED
299};302};
300 303
301struct vpu_vb2_buffer {304struct vpu_vb2_buffer {
@@ -304,8 +307,8 @@ struct vpu_vb2_buffer { · 2 unmodified lines
304 dma_addr_t chroma_u;307 dma_addr_t chroma_u;
305 dma_addr_t chroma_v;308 dma_addr_t chroma_v;
306 unsigned int state;309 unsigned int state;
307 u32 tag;
308 u32 average_qp;310 u32 average_qp;
311 s32 fs_id;
309};312};
310 313
311void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);314void 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
108 108
109 return V4L2_QUANTIZATION_LIM_RANGE;109 return V4L2_QUANTIZATION_LIM_RANGE;
110}110}
111
112int vpu_color_check_primaries(u32 primaries)
113{
114 return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
115}
116
117int vpu_color_check_transfers(u32 transfers)
118{
119 return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
120}
121
122int vpu_color_check_matrix(u32 matrix)
123{
124 return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
125}
126
127int 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
143int 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
48 [VPU_BUF_STATE_READY] = "ready",48 [VPU_BUF_STATE_READY] = "ready",
49 [VPU_BUF_STATE_SKIP] = "skip",49 [VPU_BUF_STATE_SKIP] = "skip",
50 [VPU_BUF_STATE_ERROR] = "error",50 [VPU_BUF_STATE_ERROR] = "error",
51 [VPU_BUF_STATE_CHANGED] = "changed",
51};52};
52 53
53static inline const char *to_vpu_stat_name(int state)54static 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
164 for (i = 0; i < vb2_get_num_buffers(vq); i++) {165 for (i = 0; i < vb2_get_num_buffers(vq); i++) {
165 struct vb2_buffer *vb;166 struct vb2_buffer *vb;
166 struct vb2_v4l2_buffer *vbuf;167 struct vb2_v4l2_buffer *vbuf;
168 struct vpu_vb2_buffer *vpu_buf;
167 169
168 vb = vb2_get_buffer(vq, i);170 vb = vb2_get_buffer(vq, i);
169 if (!vb)171 if (!vb)
@@ -173,13 +175,24 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) · 3 unmodified lines
173 continue;175 continue;
174 176
175 vbuf = to_vb2_v4l2_buffer(vb);177 vbuf = to_vb2_v4l2_buffer(vb);
178 vpu_buf = to_vpu_vb2_buffer(vbuf);
176 179
177 num = scnprintf(str, sizeof(str),180 num = scnprintf(str, sizeof(str),
178 "capture[%2d] state = %10s, %8s\n",181 "capture[%2d] state = %10s, %8s",
179 i, vb2_stat_name[vb->state],182 i, vb2_stat_name[vb->state],
180 to_vpu_stat_name(vpu_get_buffer_state(vbuf)));183 to_vpu_stat_name(vpu_get_buffer_state(vbuf)));
181 if (seq_write(s, str, num))184 if (seq_write(s, str, num))
182 return 0;185 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;
183 }196 }
184 197
185 num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);198 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
134 u32 decoded_height;134 u32 decoded_height;
135 struct v4l2_fract frame_rate;135 struct v4l2_fract frame_rate;
136 u32 dsp_asp_ratio;136 u32 dsp_asp_ratio;
137 u32 profile_idc;
137 u32 level_idc;138 u32 level_idc;
138 u32 bit_depth_luma;139 u32 bit_depth_luma;
139 u32 bit_depth_chroma;140 u32 bit_depth_chroma;
@@ -147,6 +148,17 @@ struct vpu_dec_codec_info { · 7 unmodified lines
147 u32 mbi_size;148 u32 mbi_size;
148 u32 dcp_size;149 u32 dcp_size;
149 u32 stride;150 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 };
150};162};
151 163
152struct vpu_dec_pic_info {164struct 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
509 }509 }
510 return "<unknown>";510 return "<unknown>";
511}511}
512
513struct codec_id_mapping {
514 u32 id;
515 u32 v4l2_id;
516};
517
518static 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
525static 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
548static 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
553static 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
569static 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
584u32 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
600u32 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
620u32 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
628u32 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
6#ifndef _AMPHION_VPU_HELPERS_H6#ifndef _AMPHION_VPU_HELPERS_H
7#define _AMPHION_VPU_HELPERS_H7#define _AMPHION_VPU_HELPERS_H
8 8
9#include "vpu_defs.h"
10
9struct vpu_pair {11struct vpu_pair {
10 u32 src;12 u32 src;
11 u32 dst;13 u32 dst;
@@ -54,10 +56,6 @@ static inline u8 vpu_helper_read_byte(struct vpu_buffer *stream_buffer, u32 pos) · 42 unmodified lines
54 return pdata[pos % stream_buffer->length];56 return pdata[pos % stream_buffer->length];
55}57}
56 58
57int vpu_color_check_primaries(u32 primaries);
58int vpu_color_check_transfers(u32 transfers);
59int vpu_color_check_matrix(u32 matrix);
60int vpu_color_check_full_range(u32 full_range);
61u32 vpu_color_cvrt_primaries_v2i(u32 primaries);59u32 vpu_color_cvrt_primaries_v2i(u32 primaries);
62u32 vpu_color_cvrt_primaries_i2v(u32 primaries);60u32 vpu_color_cvrt_primaries_i2v(u32 primaries);
63u32 vpu_color_cvrt_transfers_v2i(u32 transfers);61u32 vpu_color_cvrt_transfers_v2i(u32 transfers);
@@ -66,8 +64,12 @@ u32 vpu_color_cvrt_matrix_v2i(u32 matrix); · 2 unmodified lines
66u32 vpu_color_cvrt_matrix_i2v(u32 matrix);64u32 vpu_color_cvrt_matrix_i2v(u32 matrix);
67u32 vpu_color_cvrt_full_range_v2i(u32 full_range);65u32 vpu_color_cvrt_full_range_v2i(u32 full_range);
68u32 vpu_color_cvrt_full_range_i2v(u32 full_range);66u32 vpu_color_cvrt_full_range_i2v(u32 full_range);
69int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range);
70 67
71int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);68int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
72int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);69int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
70
71u32 vpu_get_h264_v4l2_profile(struct vpu_dec_codec_info *hdr);
72u32 vpu_get_h264_v4l2_level(struct vpu_dec_codec_info *hdr);
73u32 vpu_get_hevc_v4l2_profile(struct vpu_dec_codec_info *hdr);
74u32 vpu_get_hevc_v4l2_level(struct vpu_dec_codec_info *hdr);
73#endif75#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
908 info->frame_rate.numerator = 1000;908 info->frame_rate.numerator = 1000;
909 info->frame_rate.denominator = pkt->data[8];909 info->frame_rate.denominator = pkt->data[8];
910 info->dsp_asp_ratio = pkt->data[9];910 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;
912 info->bit_depth_luma = pkt->data[13];913 info->bit_depth_luma = pkt->data[13];
913 info->bit_depth_chroma = pkt->data[14];914 info->bit_depth_chroma = pkt->data[14];
914 info->chroma_fmt = pkt->data[15];915 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
925 info->pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128;926 info->pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128;
926 else927 else
927 info->pixfmt = V4L2_PIX_FMT_NV12M_8L128;928 info->pixfmt = V4L2_PIX_FMT_NV12M_8L128;
929 if (pkt->hdr.num > 28)
930 info->constraint_set_flags = pkt->data[28];
928 if (info->frame_rate.numerator && info->frame_rate.denominator) {931 if (info->frame_rate.numerator && info->frame_rate.denominator) {
929 unsigned long n, d;932 unsigned long n, d;
930 933
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
109 mbox_send_message(core->tx_data.ch, &data);109 mbox_send_message(core->tx_data.ch, &data);
110 mbox_send_message(core->tx_type.ch, &type);110 mbox_send_message(core->tx_type.ch, &type);
111}111}
112
113void 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
11void vpu_mbox_free(struct vpu_core *core);11void vpu_mbox_free(struct vpu_core *core);
12void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data);12void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data);
13void vpu_mbox_send_type(struct vpu_core *core, u32 type);13void vpu_mbox_send_type(struct vpu_core *core, u32 type);
14void vpu_mbox_enable_rx(struct vpu_dev *dev);
15 14
16#endif15#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
501 call_void_vop(inst, release);501 call_void_vop(inst, release);
502 }502 }
503 503
504 if (V4L2_TYPE_IS_CAPTURE(vq->type))
505 call_void_vop(inst, reset_frame_store);
506
504 return 0;507 return 0;
505}508}
506 509
507static int vpu_vb2_buf_init(struct vb2_buffer *vb)510static int vpu_vb2_buf_init(struct vb2_buffer *vb)
508{511{
509 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);512 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);
510 515
516 vpu_buf->fs_id = -1;
511 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);517 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);
512 return 0;523 return 0;
513}524}
514 525
drivers/media/platform/cadence/cdns-csi2rx.c+131−0
@@ -57,6 +57,25 @@ · 56 unmodified lines
57#define CSI2RX_LANES_MAX 457#define CSI2RX_LANES_MAX 4
58#define CSI2RX_STREAMS_MAX 458#define CSI2RX_STREAMS_MAX 4
59 59
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
60enum csi2rx_pads {79enum csi2rx_pads {
61 CSI2RX_PAD_SINK,80 CSI2RX_PAD_SINK,
62 CSI2RX_PAD_SOURCE_STREAM0,81 CSI2RX_PAD_SOURCE_STREAM0,
@@ -71,9 +90,32 @@ struct csi2rx_fmt { · 8 unmodified lines
71 u8 bpp;90 u8 bpp;
72};91};
73 92
93struct csi2rx_event {
94 u32 mask;
95 const char *name;
96};
97
98static 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
74struct csi2rx_priv {115struct csi2rx_priv {
75 struct device *dev;116 struct device *dev;
76 unsigned int count;117 unsigned int count;
118 int error_irq;
77 119
78 /*120 /*
79 * Used to prevent race conditions between multiple,121 * Used to prevent race conditions between multiple,
@@ -95,6 +137,7 @@ struct csi2rx_priv { · 15 unmodified lines
95 u8 max_lanes;137 u8 max_lanes;
96 u8 max_streams;138 u8 max_streams;
97 bool has_internal_dphy;139 bool has_internal_dphy;
140 u32 events[CSI2RX_NUM_EVENTS];
98 141
99 struct v4l2_subdev subdev;142 struct v4l2_subdev subdev;
100 struct v4l2_async_notifier notifier;143 struct v4l2_async_notifier notifier;
@@ -124,6 +167,54 @@ static const struct csi2rx_fmt formats[] = { · 23 unmodified lines
124 { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, },167 { .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, },
125};168};
126 169
170static 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
199static 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
127static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)218static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
128{219{
129 unsigned int i;220 unsigned int i;
@@ -220,6 +311,9 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx) · 90 unmodified lines
220 reset_control_deassert(csi2rx->p_rst);311 reset_control_deassert(csi2rx->p_rst);
221 csi2rx_reset(csi2rx);312 csi2rx_reset(csi2rx);
222 313
314 if (csi2rx->error_irq >= 0)
315 csi2rx_configure_error_irq_mask(csi2rx->base, csi2rx);
316
223 reg = csi2rx->num_lanes << 8;317 reg = csi2rx->num_lanes << 8;
224 for (i = 0; i < csi2rx->num_lanes; i++) {318 for (i = 0; i < csi2rx->num_lanes; i++) {
225 reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csi2rx->lanes[i]);319 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
332 reset_control_assert(csi2rx->sys_rst);426 reset_control_assert(csi2rx->sys_rst);
333 clk_disable_unprepare(csi2rx->sys_clk);427 clk_disable_unprepare(csi2rx->sys_clk);
334 428
429 writel(0, csi2rx->base + CSI2RX_ERROR_IRQS_MASK_REG);
430
335 for (i = 0; i < csi2rx->max_streams; i++) {431 for (i = 0; i < csi2rx->max_streams; i++) {
336 writel(CSI2RX_STREAM_CTRL_STOP,432 writel(CSI2RX_STREAM_CTRL_STOP,
337 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));433 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
@@ -363,6 +459,21 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx) · 25 unmodified lines
363 }459 }
364}460}
365 461
462static 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
366static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)477static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
367{478{
368 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);479 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
468 .s_stream = csi2rx_s_stream,579 .s_stream = csi2rx_s_stream,
469};580};
470 581
582static const struct v4l2_subdev_core_ops csi2rx_core_ops = {
583 .log_status = csi2rx_log_status,
584};
585
471static const struct v4l2_subdev_ops csi2rx_subdev_ops = {586static const struct v4l2_subdev_ops csi2rx_subdev_ops = {
587 .core = &csi2rx_core_ops,
472 .video = &csi2rx_video_ops,588 .video = &csi2rx_video_ops,
473 .pad = &csi2rx_pad_ops,589 .pad = &csi2rx_pad_ops,
474};590};
@@ -705,6 +821,21 @@ static int csi2rx_probe(struct platform_device *pdev) · 230 unmodified lines
705 if (ret)821 if (ret)
706 goto err_cleanup;822 goto err_cleanup;
707 823
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
708 ret = v4l2_subdev_init_finalize(&csi2rx->subdev);839 ret = v4l2_subdev_init_finalize(&csi2rx->subdev);
709 if (ret)840 if (ret)
710 goto err_cleanup;841 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
598 *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);598 *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);
599}599}
600 600
601static 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
608static 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
615static 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
601static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf,622static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf,
602 unsigned long len)623 unsigned long len)
603{624{
@@ -610,11 +631,11 @@ static void print_mxc_buf(struct mxc_jpeg_dev *jpeg, struct vb2_buffer *buf, · 6 unmodified lines
610 return;631 return;
611 632
612 for (plane_no = 0; plane_no < buf->num_planes; plane_no++) {633 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);
614 if (len == 0)635 if (len == 0)
615 len = payload;636 len = payload;
616 dma_addr = vb2_dma_contig_plane_dma_addr(buf, plane_no);637 dma_addr = mxc_jpeg_get_plane_dma_addr(buf, plane_no);
617 vaddr = vb2_plane_vaddr(buf, plane_no);638 vaddr = mxc_jpeg_get_plane_vaddr(buf, plane_no);
618 v4l2_dbg(3, debug, &jpeg->v4l2_dev,639 v4l2_dbg(3, debug, &jpeg->v4l2_dev,
619 "plane %d (vaddr=%p dma_addr=%x payload=%ld):",640 "plane %d (vaddr=%p dma_addr=%x payload=%ld):",
620 plane_no, vaddr, dma_addr, payload);641 plane_no, vaddr, dma_addr, payload);
@@ -712,16 +733,15 @@ static void mxc_jpeg_addrs(struct mxc_jpeg_desc *desc, · 91 unmodified lines
712 struct mxc_jpeg_q_data *q_data;733 struct mxc_jpeg_q_data *q_data;
713 734
714 q_data = mxc_jpeg_get_q_data(ctx, raw_buf->type);735 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);
716 desc->buf_base1 = 0;737 desc->buf_base1 = 0;
717 if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) {738 if (img_fmt == STM_CTRL_IMAGE_FORMAT(MXC_JPEG_YUV420)) {
718 if (raw_buf->num_planes == 2)739 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);
720 else741 else
721 desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0];742 desc->buf_base1 = desc->buf_base0 + q_data->sizeimage[0];
722 }743 }
723 desc->stm_bufbase = vb2_dma_contig_plane_dma_addr(jpeg_buf, 0) +744 desc->stm_bufbase = mxc_jpeg_get_plane_dma_addr(jpeg_buf, 0) + offset;
724 offset;
725}745}
726 746
727static bool mxc_jpeg_is_extended_sequential(const struct mxc_jpeg_fmt *fmt)747static 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
1029 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload);1049 vb2_set_plane_payload(&dst_buf->vb2_buf, 1, payload);
1030 }1050 }
1031 dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n",1051 dev_dbg(dev, "Decoding finished, payload size: %ld + %ld\n",
1032 vb2_get_plane_payload(&dst_buf->vb2_buf, 0),1052 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 0),
1033 vb2_get_plane_payload(&dst_buf->vb2_buf, 1));1053 mxc_jpeg_get_plane_payload(&dst_buf->vb2_buf, 1));
1034 }1054 }
1035 1055
1036 /* short preview of the results */1056 /* 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
1889 struct mxc_jpeg_sof *psof = NULL;1909 struct mxc_jpeg_sof *psof = NULL;
1890 struct mxc_jpeg_sos *psos = NULL;1910 struct mxc_jpeg_sos *psos = NULL;
1891 struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb);1911 struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb);
1892 u8 *src_addr = (u8 *)vb2_plane_vaddr(vb, 0);1912 u8 *src_addr = (u8 *)mxc_jpeg_get_plane_vaddr(vb, 0);
1893 u32 size = vb2_get_plane_payload(vb, 0);1913 u32 size = mxc_jpeg_get_plane_payload(vb, 0);
1894 int ret;1914 int ret;
1895 1915
1896 memset(&header, 0, sizeof(header));1916 memset(&header, 0, sizeof(header));
@@ -2027,6 +2047,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) · 130 unmodified lines
2027 i, vb2_plane_size(vb, i), sizeimage);2047 i, vb2_plane_size(vb, i), sizeimage);
2028 return -EINVAL;2048 return -EINVAL;
2029 }2049 }
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 }
2030 }2055 }
2031 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {2056 if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
2032 vb2_set_plane_payload(vb, 0, 0);2057 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
30#define MXC_JPEG_MAX_PLANES 230#define MXC_JPEG_MAX_PLANES 2
31#define MXC_JPEG_PATTERN_WIDTH 12831#define MXC_JPEG_PATTERN_WIDTH 128
32#define MXC_JPEG_PATTERN_HEIGHT 6432#define MXC_JPEG_PATTERN_HEIGHT 64
33#define MXC_JPEG_ADDR_ALIGNMENT 16
33 34
34enum mxc_jpeg_enc_state {35enum mxc_jpeg_enc_state {
35 MXC_JPEG_ENCODING = 0, /* jpeg encode phase */36 MXC_JPEG_ENCODING = 0, /* jpeg encode phase */
drivers/media/platform/nxp/imx-mipi-csis.c+25−43
@@ -28,6 +28,7 @@ · 27 unmodified lines
28#include <linux/reset.h>28#include <linux/reset.h>
29#include <linux/spinlock.h>29#include <linux/spinlock.h>
30 30
31#include <media/mipi-csi2.h>
31#include <media/v4l2-common.h>32#include <media/v4l2-common.h>
32#include <media/v4l2-device.h>33#include <media/v4l2-device.h>
33#include <media/v4l2-event.h>34#include <media/v4l2-event.h>
@@ -229,25 +230,6 @@ · 195 unmodified lines
229 230
230#define DEFAULT_SCLK_CSIS_FREQ 166000000UL231#define DEFAULT_SCLK_CSIS_FREQ 166000000UL
231 232
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
251struct mipi_csis_event {233struct mipi_csis_event {
252 bool debug;234 bool debug;
253 u32 mask;235 u32 mask;
@@ -357,116 +339,116 @@ static const struct csis_pix_format mipi_csis_formats[] = { · 103 unmodified lines
357 {339 {
358 .code = MEDIA_BUS_FMT_UYVY8_1X16,340 .code = MEDIA_BUS_FMT_UYVY8_1X16,
359 .output = MEDIA_BUS_FMT_UYVY8_1X16,341 .output = MEDIA_BUS_FMT_UYVY8_1X16,
360 .data_type = MIPI_CSI2_DATA_TYPE_YUV422_8,342 .data_type = MIPI_CSI2_DT_YUV422_8B,
361 .width = 16,343 .width = 16,
362 },344 },
363 /* RGB formats. */345 /* RGB formats. */
364 {346 {
365 .code = MEDIA_BUS_FMT_RGB565_1X16,347 .code = MEDIA_BUS_FMT_RGB565_1X16,
366 .output = MEDIA_BUS_FMT_RGB565_1X16,348 .output = MEDIA_BUS_FMT_RGB565_1X16,
367 .data_type = MIPI_CSI2_DATA_TYPE_RGB565,349 .data_type = MIPI_CSI2_DT_RGB565,
368 .width = 16,350 .width = 16,
369 }, {351 }, {
370 .code = MEDIA_BUS_FMT_BGR888_1X24,352 .code = MEDIA_BUS_FMT_BGR888_1X24,
371 .output = MEDIA_BUS_FMT_RGB888_1X24,353 .output = MEDIA_BUS_FMT_RGB888_1X24,
372 .data_type = MIPI_CSI2_DATA_TYPE_RGB888,354 .data_type = MIPI_CSI2_DT_RGB888,
373 .width = 24,355 .width = 24,
374 },356 },
375 /* RAW (Bayer and greyscale) formats. */357 /* RAW (Bayer and greyscale) formats. */
376 {358 {
377 .code = MEDIA_BUS_FMT_SBGGR8_1X8,359 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
378 .output = MEDIA_BUS_FMT_SBGGR8_1X8,360 .output = MEDIA_BUS_FMT_SBGGR8_1X8,
379 .data_type = MIPI_CSI2_DATA_TYPE_RAW8,361 .data_type = MIPI_CSI2_DT_RAW8,
380 .width = 8,362 .width = 8,
381 }, {363 }, {
382 .code = MEDIA_BUS_FMT_SGBRG8_1X8,364 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
383 .output = MEDIA_BUS_FMT_SGBRG8_1X8,365 .output = MEDIA_BUS_FMT_SGBRG8_1X8,
384 .data_type = MIPI_CSI2_DATA_TYPE_RAW8,366 .data_type = MIPI_CSI2_DT_RAW8,
385 .width = 8,367 .width = 8,
386 }, {368 }, {
387 .code = MEDIA_BUS_FMT_SGRBG8_1X8,369 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
388 .output = MEDIA_BUS_FMT_SGRBG8_1X8,370 .output = MEDIA_BUS_FMT_SGRBG8_1X8,
389 .data_type = MIPI_CSI2_DATA_TYPE_RAW8,371 .data_type = MIPI_CSI2_DT_RAW8,
390 .width = 8,372 .width = 8,
391 }, {373 }, {
392 .code = MEDIA_BUS_FMT_SRGGB8_1X8,374 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
393 .output = MEDIA_BUS_FMT_SRGGB8_1X8,375 .output = MEDIA_BUS_FMT_SRGGB8_1X8,
394 .data_type = MIPI_CSI2_DATA_TYPE_RAW8,376 .data_type = MIPI_CSI2_DT_RAW8,
395 .width = 8,377 .width = 8,
396 }, {378 }, {
397 .code = MEDIA_BUS_FMT_Y8_1X8,379 .code = MEDIA_BUS_FMT_Y8_1X8,
398 .output = MEDIA_BUS_FMT_Y8_1X8,380 .output = MEDIA_BUS_FMT_Y8_1X8,
399 .data_type = MIPI_CSI2_DATA_TYPE_RAW8,381 .data_type = MIPI_CSI2_DT_RAW8,
400 .width = 8,382 .width = 8,
401 }, {383 }, {
402 .code = MEDIA_BUS_FMT_SBGGR10_1X10,384 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
403 .output = MEDIA_BUS_FMT_SBGGR10_1X10,385 .output = MEDIA_BUS_FMT_SBGGR10_1X10,
404 .data_type = MIPI_CSI2_DATA_TYPE_RAW10,386 .data_type = MIPI_CSI2_DT_RAW10,
405 .width = 10,387 .width = 10,
406 }, {388 }, {
407 .code = MEDIA_BUS_FMT_SGBRG10_1X10,389 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
408 .output = MEDIA_BUS_FMT_SGBRG10_1X10,390 .output = MEDIA_BUS_FMT_SGBRG10_1X10,
409 .data_type = MIPI_CSI2_DATA_TYPE_RAW10,391 .data_type = MIPI_CSI2_DT_RAW10,
410 .width = 10,392 .width = 10,
411 }, {393 }, {
412 .code = MEDIA_BUS_FMT_SGRBG10_1X10,394 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
413 .output = MEDIA_BUS_FMT_SGRBG10_1X10,395 .output = MEDIA_BUS_FMT_SGRBG10_1X10,
414 .data_type = MIPI_CSI2_DATA_TYPE_RAW10,396 .data_type = MIPI_CSI2_DT_RAW10,
415 .width = 10,397 .width = 10,
416 }, {398 }, {
417 .code = MEDIA_BUS_FMT_SRGGB10_1X10,399 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
418 .output = MEDIA_BUS_FMT_SRGGB10_1X10,400 .output = MEDIA_BUS_FMT_SRGGB10_1X10,
419 .data_type = MIPI_CSI2_DATA_TYPE_RAW10,401 .data_type = MIPI_CSI2_DT_RAW10,
420 .width = 10,402 .width = 10,
421 }, {403 }, {
422 .code = MEDIA_BUS_FMT_Y10_1X10,404 .code = MEDIA_BUS_FMT_Y10_1X10,
423 .output = MEDIA_BUS_FMT_Y10_1X10,405 .output = MEDIA_BUS_FMT_Y10_1X10,
424 .data_type = MIPI_CSI2_DATA_TYPE_RAW10,406 .data_type = MIPI_CSI2_DT_RAW10,
425 .width = 10,407 .width = 10,
426 }, {408 }, {
427 .code = MEDIA_BUS_FMT_SBGGR12_1X12,409 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
428 .output = MEDIA_BUS_FMT_SBGGR12_1X12,410 .output = MEDIA_BUS_FMT_SBGGR12_1X12,
429 .data_type = MIPI_CSI2_DATA_TYPE_RAW12,411 .data_type = MIPI_CSI2_DT_RAW12,
430 .width = 12,412 .width = 12,
431 }, {413 }, {
432 .code = MEDIA_BUS_FMT_SGBRG12_1X12,414 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
433 .output = MEDIA_BUS_FMT_SGBRG12_1X12,415 .output = MEDIA_BUS_FMT_SGBRG12_1X12,
434 .data_type = MIPI_CSI2_DATA_TYPE_RAW12,416 .data_type = MIPI_CSI2_DT_RAW12,
435 .width = 12,417 .width = 12,
436 }, {418 }, {
437 .code = MEDIA_BUS_FMT_SGRBG12_1X12,419 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
438 .output = MEDIA_BUS_FMT_SGRBG12_1X12,420 .output = MEDIA_BUS_FMT_SGRBG12_1X12,
439 .data_type = MIPI_CSI2_DATA_TYPE_RAW12,421 .data_type = MIPI_CSI2_DT_RAW12,
440 .width = 12,422 .width = 12,
441 }, {423 }, {
442 .code = MEDIA_BUS_FMT_SRGGB12_1X12,424 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
443 .output = MEDIA_BUS_FMT_SRGGB12_1X12,425 .output = MEDIA_BUS_FMT_SRGGB12_1X12,
444 .data_type = MIPI_CSI2_DATA_TYPE_RAW12,426 .data_type = MIPI_CSI2_DT_RAW12,
445 .width = 12,427 .width = 12,
446 }, {428 }, {
447 .code = MEDIA_BUS_FMT_Y12_1X12,429 .code = MEDIA_BUS_FMT_Y12_1X12,
448 .output = MEDIA_BUS_FMT_Y12_1X12,430 .output = MEDIA_BUS_FMT_Y12_1X12,
449 .data_type = MIPI_CSI2_DATA_TYPE_RAW12,431 .data_type = MIPI_CSI2_DT_RAW12,
450 .width = 12,432 .width = 12,
451 }, {433 }, {
452 .code = MEDIA_BUS_FMT_SBGGR14_1X14,434 .code = MEDIA_BUS_FMT_SBGGR14_1X14,
453 .output = MEDIA_BUS_FMT_SBGGR14_1X14,435 .output = MEDIA_BUS_FMT_SBGGR14_1X14,
454 .data_type = MIPI_CSI2_DATA_TYPE_RAW14,436 .data_type = MIPI_CSI2_DT_RAW14,
455 .width = 14,437 .width = 14,
456 }, {438 }, {
457 .code = MEDIA_BUS_FMT_SGBRG14_1X14,439 .code = MEDIA_BUS_FMT_SGBRG14_1X14,
458 .output = MEDIA_BUS_FMT_SGBRG14_1X14,440 .output = MEDIA_BUS_FMT_SGBRG14_1X14,
459 .data_type = MIPI_CSI2_DATA_TYPE_RAW14,441 .data_type = MIPI_CSI2_DT_RAW14,
460 .width = 14,442 .width = 14,
461 }, {443 }, {
462 .code = MEDIA_BUS_FMT_SGRBG14_1X14,444 .code = MEDIA_BUS_FMT_SGRBG14_1X14,
463 .output = MEDIA_BUS_FMT_SGRBG14_1X14,445 .output = MEDIA_BUS_FMT_SGRBG14_1X14,
464 .data_type = MIPI_CSI2_DATA_TYPE_RAW14,446 .data_type = MIPI_CSI2_DT_RAW14,
465 .width = 14,447 .width = 14,
466 }, {448 }, {
467 .code = MEDIA_BUS_FMT_SRGGB14_1X14,449 .code = MEDIA_BUS_FMT_SRGGB14_1X14,
468 .output = MEDIA_BUS_FMT_SRGGB14_1X14,450 .output = MEDIA_BUS_FMT_SRGGB14_1X14,
469 .data_type = MIPI_CSI2_DATA_TYPE_RAW14,451 .data_type = MIPI_CSI2_DT_RAW14,
470 .width = 14,452 .width = 14,
471 },453 },
472 /* JPEG */454 /* JPEG */
@@ -494,7 +476,7 @@ static const struct csis_pix_format mipi_csis_formats[] = { · 21 unmodified lines
494 * SoC that can support quad pixel mode, this will have to be476 * SoC that can support quad pixel mode, this will have to be
495 * revisited.477 * revisited.
496 */478 */
497 .data_type = MIPI_CSI2_DATA_TYPE_RAW8,479 .data_type = MIPI_CSI2_DT_RAW8,
498 .width = 8,480 .width = 8,
499 }481 }
500};482};
@@ -583,7 +565,7 @@ static void __mipi_csis_set_format(struct mipi_csis_device *csis, · 82 unmodified lines
583 *565 *
584 * TODO: Verify which other formats require DUAL (or QUAD) modes.566 * TODO: Verify which other formats require DUAL (or QUAD) modes.
585 */567 */
586 if (csis_fmt->data_type == MIPI_CSI2_DATA_TYPE_YUV422_8)568 if (csis_fmt->data_type == MIPI_CSI2_DT_YUV422_8B)
587 val |= MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL;569 val |= MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL;
588 570
589 val |= MIPI_CSIS_ISPCFG_FMT(csis_fmt->data_type);571 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
3 * Copyright 2019-2020 NXP3 * Copyright 2019-2020 NXP
4 */4 */
5 5
6#include <linux/bits.h>
6#include <linux/clk.h>7#include <linux/clk.h>
7#include <linux/device.h>8#include <linux/device.h>
8#include <linux/errno.h>9#include <linux/errno.h>
@@ -245,26 +246,41 @@ static void mxc_isi_v4l2_cleanup(struct mxc_isi_dev *isi) · 236 unmodified lines
245 246
246/* Panic will assert when the buffers are 50% full */247/* Panic will assert when the buffers are 50% full */
247 248
248/* For i.MX8QXP C0 and i.MX8MN ISI IER version */249/* For i.MX8MN ISI IER version */
249static const struct mxc_isi_ier_reg mxc_imx8_isi_ier_v1 = {250static const struct mxc_isi_ier_reg mxc_imx8_isi_ier_v1 = {
250 .oflw_y_buf_en = { .offset = 19, .mask = 0x80000 },251 .oflw_y_buf_en = { .mask = BIT(19) },
251 .oflw_u_buf_en = { .offset = 21, .mask = 0x200000 },252 .oflw_u_buf_en = { .mask = BIT(21) },
252 .oflw_v_buf_en = { .offset = 23, .mask = 0x800000 },253 .oflw_v_buf_en = { .mask = BIT(23) },
253 254
254 .panic_y_buf_en = {.offset = 20, .mask = 0x100000 },255 .panic_y_buf_en = { .mask = BIT(20) },
255 .panic_u_buf_en = {.offset = 22, .mask = 0x400000 },256 .panic_u_buf_en = { .mask = BIT(22) },
256 .panic_v_buf_en = {.offset = 24, .mask = 0x1000000 },257 .panic_v_buf_en = { .mask = BIT(24) },
257};258};
258 259
259/* For i.MX8MP ISI IER version */260/* For i.MX8QXP C0 and i.MX8MP ISI IER version */
260static const struct mxc_isi_ier_reg mxc_imx8_isi_ier_v2 = {261static const struct mxc_isi_ier_reg mxc_imx8_isi_ier_v2 = {
261 .oflw_y_buf_en = { .offset = 18, .mask = 0x40000 },262 .oflw_y_buf_en = { .mask = BIT(18) },
262 .oflw_u_buf_en = { .offset = 20, .mask = 0x100000 },263 .oflw_u_buf_en = { .mask = BIT(20) },
263 .oflw_v_buf_en = { .offset = 22, .mask = 0x400000 },264 .oflw_v_buf_en = { .mask = BIT(22) },
264 265
265 .panic_y_buf_en = {.offset = 19, .mask = 0x80000 },266 .panic_y_buf_en = { .mask = BIT(19) },
266 .panic_u_buf_en = {.offset = 21, .mask = 0x200000 },267 .panic_u_buf_en = { .mask = BIT(21) },
267 .panic_v_buf_en = {.offset = 23, .mask = 0x800000 },268 .panic_v_buf_en = { .mask = BIT(23) },
269};
270
271/* For i.MX8QM ISI IER version */
272static 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) },
268};284};
269 285
270/* Panic will assert when the buffers are 50% full */286/* 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
274 .panic_set_thd_v = { .mask = 0xf0000, .offset = 16, .threshold = 0x7 },290 .panic_set_thd_v = { .mask = 0xf0000, .offset = 16, .threshold = 0x7 },
275};291};
276 292
277static const struct clk_bulk_data mxc_imx8mn_clks[] = {
278 { .id = "axi" },
279 { .id = "apb" },
280};
281
282static const struct mxc_isi_plat_data mxc_imx8mn_data = {293static const struct mxc_isi_plat_data mxc_imx8mn_data = {
283 .model = MXC_ISI_IMX8MN,294 .model = MXC_ISI_IMX8MN,
284 .num_ports = 1,295 .num_ports = 1,
@@ -286,8 +297,6 @@ static const struct mxc_isi_plat_data mxc_imx8mn_data = { · 1 unmodified line
286 .reg_offset = 0,297 .reg_offset = 0,
287 .ier_reg = &mxc_imx8_isi_ier_v1,298 .ier_reg = &mxc_imx8_isi_ier_v1,
288 .set_thd = &mxc_imx8_isi_thd_v1,299 .set_thd = &mxc_imx8_isi_thd_v1,
289 .clks = mxc_imx8mn_clks,
290 .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
291 .buf_active_reverse = false,300 .buf_active_reverse = false,
292 .gasket_ops = &mxc_imx8_gasket_ops,301 .gasket_ops = &mxc_imx8_gasket_ops,
293 .has_36bit_dma = false,302 .has_36bit_dma = false,
@@ -300,8 +309,6 @@ static const struct mxc_isi_plat_data mxc_imx8mp_data = { · 6 unmodified lines
300 .reg_offset = 0x2000,309 .reg_offset = 0x2000,
301 .ier_reg = &mxc_imx8_isi_ier_v2,310 .ier_reg = &mxc_imx8_isi_ier_v2,
302 .set_thd = &mxc_imx8_isi_thd_v1,311 .set_thd = &mxc_imx8_isi_thd_v1,
303 .clks = mxc_imx8mn_clks,
304 .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
305 .buf_active_reverse = true,312 .buf_active_reverse = true,
306 .gasket_ops = &mxc_imx8_gasket_ops,313 .gasket_ops = &mxc_imx8_gasket_ops,
307 .has_36bit_dma = true,314 .has_36bit_dma = true,
@@ -314,8 +321,6 @@ static const struct mxc_isi_plat_data mxc_imx8ulp_data = { · 6 unmodified lines
314 .reg_offset = 0x0,321 .reg_offset = 0x0,
315 .ier_reg = &mxc_imx8_isi_ier_v2,322 .ier_reg = &mxc_imx8_isi_ier_v2,
316 .set_thd = &mxc_imx8_isi_thd_v1,323 .set_thd = &mxc_imx8_isi_thd_v1,
317 .clks = mxc_imx8mn_clks,
318 .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
319 .buf_active_reverse = true,324 .buf_active_reverse = true,
320 .has_36bit_dma = false,325 .has_36bit_dma = false,
321};326};
@@ -327,13 +332,33 @@ static const struct mxc_isi_plat_data mxc_imx93_data = { · 5 unmodified lines
327 .reg_offset = 0,332 .reg_offset = 0,
328 .ier_reg = &mxc_imx8_isi_ier_v2,333 .ier_reg = &mxc_imx8_isi_ier_v2,
329 .set_thd = &mxc_imx8_isi_thd_v1,334 .set_thd = &mxc_imx8_isi_thd_v1,
330 .clks = mxc_imx8mn_clks,
331 .num_clks = ARRAY_SIZE(mxc_imx8mn_clks),
332 .buf_active_reverse = true,335 .buf_active_reverse = true,
333 .gasket_ops = &mxc_imx93_gasket_ops,336 .gasket_ops = &mxc_imx93_gasket_ops,
334 .has_36bit_dma = false,337 .has_36bit_dma = false,
335};338};
336 339
340static 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
351static 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
337/* -----------------------------------------------------------------------------362/* -----------------------------------------------------------------------------
338 * Power management363 * Power management
339 */364 */
@@ -385,7 +410,7 @@ static int mxc_isi_runtime_suspend(struct device *dev) · 45 unmodified lines
385{410{
386 struct mxc_isi_dev *isi = dev_get_drvdata(dev);411 struct mxc_isi_dev *isi = dev_get_drvdata(dev);
387 412
388 clk_bulk_disable_unprepare(isi->pdata->num_clks, isi->clks);413 clk_bulk_disable_unprepare(isi->num_clks, isi->clks);
389 414
390 return 0;415 return 0;
391}416}
@@ -395,7 +420,7 @@ static int mxc_isi_runtime_resume(struct device *dev) · 3 unmodified lines
395 struct mxc_isi_dev *isi = dev_get_drvdata(dev);420 struct mxc_isi_dev *isi = dev_get_drvdata(dev);
396 int ret;421 int ret;
397 422
398 ret = clk_bulk_prepare_enable(isi->pdata->num_clks, isi->clks);423 ret = clk_bulk_prepare_enable(isi->num_clks, isi->clks);
399 if (ret) {424 if (ret) {
400 dev_err(dev, "Failed to enable clocks (%d)\n", ret);425 dev_err(dev, "Failed to enable clocks (%d)\n", ret);
401 return ret;426 return ret;
@@ -413,27 +438,6 @@ static const struct dev_pm_ops mxc_isi_pm_ops = { · 11 unmodified lines
413 * Probe, remove & driver438 * Probe, remove & driver
414 */439 */
415 440
416static 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
437static int mxc_isi_probe(struct platform_device *pdev)441static int mxc_isi_probe(struct platform_device *pdev)
438{442{
439 struct device *dev = &pdev->dev;443 struct device *dev = &pdev->dev;
@@ -456,34 +460,25 @@ static int mxc_isi_probe(struct platform_device *pdev) · 16 unmodified lines
456 if (!isi->pipes)460 if (!isi->pipes)
457 return -ENOMEM;461 return -ENOMEM;
458 462
459 ret = mxc_isi_clk_get(isi);463 isi->num_clks = devm_clk_bulk_get_all(dev, &isi->clks);
460 if (ret < 0) {464 if (isi->num_clks < 0)
461 dev_err(dev, "Failed to get clocks\n");465 return dev_err_probe(dev, isi->num_clks, "Failed to get clocks\n");
462 return ret;
463 }
464 466
465 isi->regs = devm_platform_ioremap_resource(pdev, 0);467 isi->regs = devm_platform_ioremap_resource(pdev, 0);
466 if (IS_ERR(isi->regs)) {468 if (IS_ERR(isi->regs))
467 dev_err(dev, "Failed to get ISI register map\n");469 return dev_err_probe(dev, PTR_ERR(isi->regs),
468 return PTR_ERR(isi->regs);470 "Failed to get ISI register map\n");
469 }
470 471
471 if (isi->pdata->gasket_ops) {472 if (isi->pdata->gasket_ops) {
472 isi->gasket = syscon_regmap_lookup_by_phandle(dev->of_node,473 isi->gasket = syscon_regmap_lookup_by_phandle(dev->of_node,
473 "fsl,blk-ctrl");474 "fsl,blk-ctrl");
474 if (IS_ERR(isi->gasket)) {475 if (IS_ERR(isi->gasket))
475 ret = PTR_ERR(isi->gasket);476 return dev_err_probe(dev, PTR_ERR(isi->gasket),
476 dev_err(dev, "failed to get gasket: %d\n", ret);477 "failed to get gasket\n");
477 return ret;
478 }
479 }478 }
480 479
481 dma_size = isi->pdata->has_36bit_dma ? 36 : 32;480 dma_size = isi->pdata->has_36bit_dma ? 36 : 32;
482 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_size));481 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 }
487 482
488 pm_runtime_enable(dev);483 pm_runtime_enable(dev);
489 484
@@ -541,6 +536,8 @@ static void mxc_isi_remove(struct platform_device *pdev) · 51 unmodified lines
541static const struct of_device_id mxc_isi_of_match[] = {536static const struct of_device_id mxc_isi_of_match[] = {
542 { .compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data },537 { .compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data },
543 { .compatible = "fsl,imx8mp-isi", .data = &mxc_imx8mp_data },538 { .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 },
544 { .compatible = "fsl,imx8ulp-isi", .data = &mxc_imx8ulp_data },541 { .compatible = "fsl,imx8ulp-isi", .data = &mxc_imx8ulp_data },
545 { .compatible = "fsl,imx93-isi", .data = &mxc_imx93_data },542 { .compatible = "fsl,imx93-isi", .data = &mxc_imx93_data },
546 { /* sentinel */ },543 { /* sentinel */ },
drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h+3−3
@@ -114,7 +114,6 @@ struct mxc_isi_buffer { · 113 unmodified lines
114};114};
115 115
116struct mxc_isi_reg {116struct mxc_isi_reg {
117 u32 offset;
118 u32 mask;117 u32 mask;
119};118};
120 119
@@ -158,6 +157,8 @@ struct mxc_gasket_ops { · 37 unmodified lines
158enum model {157enum model {
159 MXC_ISI_IMX8MN,158 MXC_ISI_IMX8MN,
160 MXC_ISI_IMX8MP,159 MXC_ISI_IMX8MP,
160 MXC_ISI_IMX8QM,
161 MXC_ISI_IMX8QXP,
161 MXC_ISI_IMX8ULP,162 MXC_ISI_IMX8ULP,
162 MXC_ISI_IMX93,163 MXC_ISI_IMX93,
163};164};
@@ -170,8 +171,6 @@ struct mxc_isi_plat_data { · 6 unmodified lines
170 const struct mxc_isi_ier_reg *ier_reg;171 const struct mxc_isi_ier_reg *ier_reg;
171 const struct mxc_isi_set_thd *set_thd;172 const struct mxc_isi_set_thd *set_thd;
172 const struct mxc_gasket_ops *gasket_ops;173 const struct mxc_gasket_ops *gasket_ops;
173 const struct clk_bulk_data *clks;
174 unsigned int num_clks;
175 bool buf_active_reverse;174 bool buf_active_reverse;
176 bool has_36bit_dma;175 bool has_36bit_dma;
177};176};
@@ -283,6 +282,7 @@ struct mxc_isi_dev { · 105 unmodified lines
283 282
284 void __iomem *regs;283 void __iomem *regs;
285 struct clk_bulk_data *clks;284 struct clk_bulk_data *clks;
285 int num_clks;
286 struct regmap *gasket;286 struct regmap *gasket;
287 287
288 struct mxc_isi_crossbar crossbar;288 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
188 * Create a 1:1 mapping between pixel link inputs and outputs to188 * Create a 1:1 mapping between pixel link inputs and outputs to
189 * pipelines by default.189 * pipelines by default.
190 */190 */
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);
192 if (!routes)193 if (!routes)
193 return -ENOMEM;194 return -ENOMEM;
194 195
195 for (i = 0; i < xbar->num_sources; ++i) {196 for (i = 0; i < routing.num_routes; ++i) {
196 struct v4l2_subdev_route *route = &routes[i];197 struct v4l2_subdev_route *route = &routes[i];
197 198
198 route->sink_pad = i;199 route->sink_pad = i;
@@ -200,7 +201,6 @@ static int mxc_isi_crossbar_init_state(struct v4l2_subdev *sd, · 1 unmodified line
200 route->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;201 route->flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
201 }202 }
202 203
203 routing.num_routes = xbar->num_sources;
204 routing.routes = routes;204 routing.routes = routes;
205 205
206 ret = __mxc_isi_crossbar_set_routing(sd, state, &routing);206 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
352 sink_streams);352 sink_streams);
353 if (ret) {353 if (ret) {
354 dev_err(xbar->isi->dev,354 dev_err(xbar->isi->dev,
355 "failed to %s streams 0x%llx on '%s':%u: %d\n",355 "failed to enable streams 0x%llx on '%s':%u: %d\n",
356 "enable", sink_streams, remote_sd->name,356 sink_streams, remote_sd->name, remote_pad, ret);
357 remote_pad, ret);
358 mxc_isi_crossbar_gasket_disable(xbar, sink_pad);357 mxc_isi_crossbar_gasket_disable(xbar, sink_pad);
359 return ret;358 return ret;
360 }359 }
@@ -392,9 +391,8 @@ static int mxc_isi_crossbar_disable_streams(struct v4l2_subdev *sd, · 31 unmodified lines
392 sink_streams);391 sink_streams);
393 if (ret)392 if (ret)
394 dev_err(xbar->isi->dev,393 dev_err(xbar->isi->dev,
395 "failed to %s streams 0x%llx on '%s':%u: %d\n",394 "failed to disable streams 0x%llx on '%s':%u: %d\n",
396 "disable", sink_streams, remote_sd->name,395 sink_streams, remote_sd->name, remote_pad, ret);
397 remote_pad, ret);
398 396
399 mxc_isi_crossbar_gasket_disable(xbar, sink_pad);397 mxc_isi_crossbar_gasket_disable(xbar, sink_pad);
400 }398 }
@@ -453,7 +451,7 @@ int mxc_isi_crossbar_init(struct mxc_isi_dev *isi) · 52 unmodified lines
453 * the memory input.451 * the memory input.
454 */452 */
455 xbar->num_sinks = isi->pdata->num_ports + 1;453 xbar->num_sinks = isi->pdata->num_ports + 1;
456 xbar->num_sources = isi->pdata->num_ports;454 xbar->num_sources = isi->pdata->num_channels;
457 num_pads = xbar->num_sinks + xbar->num_sources;455 num_pads = xbar->num_sinks + xbar->num_sources;
458 456
459 xbar->pads = kcalloc(num_pads, sizeof(*xbar->pads), GFP_KERNEL);457 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
5 * Copyright (C) 2021 Purism SPC5 * Copyright (C) 2021 Purism SPC
6 */6 */
7 7
8#include <linux/bitfield.h>
8#include <linux/clk.h>9#include <linux/clk.h>
9#include <linux/clk-provider.h>10#include <linux/clk-provider.h>
10#include <linux/delay.h>11#include <linux/delay.h>
@@ -62,6 +63,8 @@ · 51 unmodified lines
62#define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x18863#define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x188
63#define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x13064#define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x130
64 65
66struct csi_state;
67
65enum {68enum {
66 ST_POWERED = 1,69 ST_POWERED = 1,
67 ST_STREAMING = 2,70 ST_STREAMING = 2,
@@ -83,11 +86,11 @@ static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = { · 15 unmodified lines
83 86
84#define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id)87#define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
85 88
86#define GPR_CSI2_1_RX_ENABLE BIT(13)89struct imx8mq_plat_data {
87#define GPR_CSI2_1_VID_INTFC_ENB BIT(12)90 int (*enable)(struct csi_state *state, u32 hs_settle);
88#define GPR_CSI2_1_HSEL BIT(10)91 void (*disable)(struct csi_state *state);
89#define GPR_CSI2_1_CONT_CLK_MODE BIT(8)92 bool use_reg_csr;
90#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)93};
91 94
92/*95/*
93 * The send level configures the number of entries that must accumulate in96 * 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
106 109
107struct csi_state {110struct csi_state {
108 struct device *dev;111 struct device *dev;
112 const struct imx8mq_plat_data *pdata;
109 void __iomem *regs;113 void __iomem *regs;
110 struct clk_bulk_data clks[CSI2_NUM_CLKS];114 struct clk_bulk_data clks[CSI2_NUM_CLKS];
111 struct reset_control *rst;115 struct reset_control *rst;
@@ -137,6 +141,123 @@ struct csi2_pix_format { · 25 unmodified lines
137 u8 width;141 u8 width;
138};142};
139 143
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
154static 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
168static 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
202static 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
243static 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
255static const struct imx8mq_plat_data imx8qxp_data = {
256 .enable = imx8qxp_gpr_enable,
257 .disable = imx8qxp_gpr_disable,
258 .use_reg_csr = true,
259};
260
140static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {261static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {
141 /* RAW (Bayer and greyscale) formats. */262 /* RAW (Bayer and greyscale) formats. */
142 {263 {
@@ -371,14 +492,9 @@ static int imx8mq_mipi_csi_start_stream(struct csi_state *state, · 228 unmodified lines
371 if (ret)492 if (ret)
372 return ret;493 return ret;
373 494
374 regmap_update_bits(state->phy_gpr,495 ret = state->pdata->enable(state, hs_settle);
375 state->phy_gpr_reg,496 if (ret)
376 0x3fff,497 return ret;
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));
382 498
383 return 0;499 return 0;
384}500}
@@ -386,6 +502,9 @@ static int imx8mq_mipi_csi_start_stream(struct csi_state *state, · 1 unmodified line
386static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)502static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)
387{503{
388 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);504 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);
505
506 if (state->pdata->disable)
507 state->pdata->disable(state);
389}508}
390 509
391/* -----------------------------------------------------------------------------510/* -----------------------------------------------------------------------------
@@ -837,6 +956,25 @@ static int imx8mq_mipi_csi_parse_dt(struct csi_state *state) · 445 unmodified lines
837 return PTR_ERR(state->rst);956 return PTR_ERR(state->rst);
838 }957 }
839 958
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
840 ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,978 ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,
841 ARRAY_SIZE(out_val));979 ARRAY_SIZE(out_val));
842 if (ret) {980 if (ret) {
@@ -876,6 +1014,8 @@ static int imx8mq_mipi_csi_probe(struct platform_device *pdev) · 33 unmodified lines
876 1014
877 state->dev = dev;1015 state->dev = dev;
878 1016
1017 state->pdata = of_device_get_match_data(dev);
1018
879 ret = imx8mq_mipi_csi_parse_dt(state);1019 ret = imx8mq_mipi_csi_parse_dt(state);
880 if (ret < 0) {1020 if (ret < 0) {
881 dev_err(dev, "Failed to parse device tree: %d\n", ret);1021 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
953}1093}
954 1094
955static const struct of_device_id imx8mq_mipi_csi_of_match[] = {1095static 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 },
957 { /* sentinel */ },1098 { /* sentinel */ },
958};1099};
959MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match);1100MODULE_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
849 regs->offset = 0x1000;849 regs->offset = 0x1000;
850 break;850 break;
851 default:851 default:
852 WARN(1, "unknown csiphy version\n");852 break;
853 return -ENODEV;
854 }853 }
855 854
856 return 0;855 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
103 .formats = formats_8x96103 .formats = formats_8x96
104};104};
105 105
106const struct csiphy_formats csiphy_formats_sc7280 = {
107 .nformats = ARRAY_SIZE(formats_sdm845),
108 .formats = formats_sdm845
109};
110
111const struct csiphy_formats csiphy_formats_sdm845 = {106const struct csiphy_formats csiphy_formats_sdm845 = {
112 .nformats = ARRAY_SIZE(formats_sdm845),107 .nformats = ARRAY_SIZE(formats_sdm845),
113 .formats = formats_sdm845108 .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
126 126
127extern const struct csiphy_formats csiphy_formats_8x16;127extern const struct csiphy_formats csiphy_formats_8x16;
128extern const struct csiphy_formats csiphy_formats_8x96;128extern const struct csiphy_formats csiphy_formats_8x96;
129extern const struct csiphy_formats csiphy_formats_sc7280;
130extern const struct csiphy_formats csiphy_formats_sdm845;129extern const struct csiphy_formats csiphy_formats_sdm845;
131 130
132extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;131extern 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
225 return 0;225 return 0;
226}226}
227 227
228static 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
228static int video_start_streaming(struct vb2_queue *q, unsigned int count)243static int video_start_streaming(struct vb2_queue *q, unsigned int count)
229{244{
230 struct camss_video *video = vb2_get_drv_priv(q);245 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
308 video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);323 video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
309}324}
310 325
326static 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
311static const struct vb2_ops msm_video_vb2_q_ops = {334static const struct vb2_ops msm_video_vb2_q_ops = {
312 .queue_setup = video_queue_setup,335 .queue_setup = video_queue_setup,
313 .buf_init = video_buf_init,336 .buf_init = video_buf_init,
314 .buf_prepare = video_buf_prepare,337 .buf_prepare = video_buf_prepare,
315 .buf_queue = video_buf_queue,338 .buf_queue = video_buf_queue,
339 .prepare_streaming = video_prepare_streaming,
316 .start_streaming = video_start_streaming,340 .start_streaming = video_start_streaming,
317 .stop_streaming = video_stop_streaming,341 .stop_streaming = video_stop_streaming,
342 .unprepare_streaming = video_unprepare_streaming,
318};343};
319 344
320/* -----------------------------------------------------------------------------345/* -----------------------------------------------------------------------------
@@ -599,20 +624,10 @@ static int video_open(struct file *file) · 278 unmodified lines
599 624
600 file->private_data = vfh;625 file->private_data = vfh;
601 626
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
609 mutex_unlock(&video->lock);627 mutex_unlock(&video->lock);
610 628
611 return 0;629 return 0;
612 630
613error_pm_use:
614 v4l2_fh_release(file);
615
616error_alloc:631error_alloc:
617 mutex_unlock(&video->lock);632 mutex_unlock(&video->lock);
618 633
@@ -621,12 +636,8 @@ error_alloc: · 2 unmodified lines
621 636
622static int video_release(struct file *file)637static int video_release(struct file *file)
623{638{
624 struct video_device *vdev = video_devdata(file);
625
626 vb2_fop_release(file);639 vb2_fop_release(file);
627 640
628 v4l2_pipeline_pm_put(&vdev->entity);
629
630 file->private_data = NULL;641 file->private_data = NULL;
631 642
632 return 0;643 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
1481 .csiphy = {1481 .csiphy = {
1482 .id = 0,1482 .id = 0,
1483 .hw_ops = &csiphy_ops_3ph_1_0,1483 .hw_ops = &csiphy_ops_3ph_1_0,
1484 .formats = &csiphy_formats_sc72801484 .formats = &csiphy_formats_sdm845,
1485 }1485 }
1486 },1486 },
1487 /* CSIPHY1 */1487 /* CSIPHY1 */
@@ -1496,7 +1496,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
1496 .csiphy = {1496 .csiphy = {
1497 .id = 1,1497 .id = 1,
1498 .hw_ops = &csiphy_ops_3ph_1_0,1498 .hw_ops = &csiphy_ops_3ph_1_0,
1499 .formats = &csiphy_formats_sc72801499 .formats = &csiphy_formats_sdm845,
1500 }1500 }
1501 },1501 },
1502 /* CSIPHY2 */1502 /* CSIPHY2 */
@@ -1511,7 +1511,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
1511 .csiphy = {1511 .csiphy = {
1512 .id = 2,1512 .id = 2,
1513 .hw_ops = &csiphy_ops_3ph_1_0,1513 .hw_ops = &csiphy_ops_3ph_1_0,
1514 .formats = &csiphy_formats_sc72801514 .formats = &csiphy_formats_sdm845,
1515 }1515 }
1516 },1516 },
1517 /* CSIPHY3 */1517 /* CSIPHY3 */
@@ -1526,7 +1526,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
1526 .csiphy = {1526 .csiphy = {
1527 .id = 3,1527 .id = 3,
1528 .hw_ops = &csiphy_ops_3ph_1_0,1528 .hw_ops = &csiphy_ops_3ph_1_0,
1529 .formats = &csiphy_formats_sc72801529 .formats = &csiphy_formats_sdm845,
1530 }1530 }
1531 },1531 },
1532 /* CSIPHY4 */1532 /* CSIPHY4 */
@@ -1541,7 +1541,7 @@ static const struct camss_subdev_resources csiphy_res_7280[] = { · 8 unmodified lines
1541 .csiphy = {1541 .csiphy = {
1542 .id = 4,1542 .id = 4,
1543 .hw_ops = &csiphy_ops_3ph_1_0,1543 .hw_ops = &csiphy_ops_3ph_1_0,
1544 .formats = &csiphy_formats_sc72801544 .formats = &csiphy_formats_sdm845,
1545 }1545 }
1546 },1546 },
1547};1547};
@@ -2486,8 +2486,8 @@ static const struct resources_icc icc_res_sm8550[] = { · 938 unmodified lines
2486static const struct camss_subdev_resources csiphy_res_x1e80100[] = {2486static const struct camss_subdev_resources csiphy_res_x1e80100[] = {
2487 /* CSIPHY0 */2487 /* CSIPHY0 */
2488 {2488 {
2489 .regulators = { "vdd-csiphy-0p8-supply",2489 .regulators = { "vdd-csiphy-0p8",
2490 "vdd-csiphy-1p2-supply" },2490 "vdd-csiphy-1p2" },
2491 .clock = { "csiphy0", "csiphy0_timer" },2491 .clock = { "csiphy0", "csiphy0_timer" },
2492 .clock_rate = { { 300000000, 400000000, 480000000 },2492 .clock_rate = { { 300000000, 400000000, 480000000 },
2493 { 266666667, 400000000 } },2493 { 266666667, 400000000 } },
@@ -2501,8 +2501,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { · 7 unmodified lines
2501 },2501 },
2502 /* CSIPHY1 */2502 /* CSIPHY1 */
2503 {2503 {
2504 .regulators = { "vdd-csiphy-0p8-supply",2504 .regulators = { "vdd-csiphy-0p8",
2505 "vdd-csiphy-1p2-supply" },2505 "vdd-csiphy-1p2" },
2506 .clock = { "csiphy1", "csiphy1_timer" },2506 .clock = { "csiphy1", "csiphy1_timer" },
2507 .clock_rate = { { 300000000, 400000000, 480000000 },2507 .clock_rate = { { 300000000, 400000000, 480000000 },
2508 { 266666667, 400000000 } },2508 { 266666667, 400000000 } },
@@ -2516,8 +2516,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { · 7 unmodified lines
2516 },2516 },
2517 /* CSIPHY2 */2517 /* CSIPHY2 */
2518 {2518 {
2519 .regulators = { "vdd-csiphy-0p8-supply",2519 .regulators = { "vdd-csiphy-0p8",
2520 "vdd-csiphy-1p2-supply" },2520 "vdd-csiphy-1p2" },
2521 .clock = { "csiphy2", "csiphy2_timer" },2521 .clock = { "csiphy2", "csiphy2_timer" },
2522 .clock_rate = { { 300000000, 400000000, 480000000 },2522 .clock_rate = { { 300000000, 400000000, 480000000 },
2523 { 266666667, 400000000 } },2523 { 266666667, 400000000 } },
@@ -2531,8 +2531,8 @@ static const struct camss_subdev_resources csiphy_res_x1e80100[] = { · 7 unmodified lines
2531 },2531 },
2532 /* CSIPHY4 */2532 /* CSIPHY4 */
2533 {2533 {
2534 .regulators = { "vdd-csiphy-0p8-supply",2534 .regulators = { "vdd-csiphy-0p8",
2535 "vdd-csiphy-1p2-supply" },2535 "vdd-csiphy-1p2" },
2536 .clock = { "csiphy4", "csiphy4_timer" },2536 .clock = { "csiphy4", "csiphy4_timer" },
2537 .clock_rate = { { 300000000, 400000000, 480000000 },2537 .clock_rate = { { 300000000, 400000000, 480000000 },
2538 { 266666667, 400000000 } },2538 { 266666667, 400000000 } },
@@ -3386,43 +3386,39 @@ static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) · 847 unmodified lines
3386 struct camss *camss = container_of(async, struct camss, notifier);3386 struct camss *camss = container_of(async, struct camss, notifier);
3387 struct v4l2_device *v4l2_dev = &camss->v4l2_dev;3387 struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
3388 struct v4l2_subdev *sd;3388 struct v4l2_subdev *sd;
3389 int ret;
3390 3389
3391 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {3390 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
3392 if (sd->host_priv) {3391 struct csiphy_device *csiphy = sd->host_priv;
3393 struct media_entity *sensor = &sd->entity;3392 struct media_entity *input, *sensor;
3394 struct csiphy_device *csiphy =3393 unsigned int i;
3395 (struct csiphy_device *) sd->host_priv;3394 int ret;
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 }
3408 3395
3409 ret = media_create_pad_link(sensor, i,3396 if (!csiphy)
3410 input, MSM_CSIPHY_PAD_SINK,3397 continue;
3411 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);3398
3412 if (ret < 0) {3399 input = &csiphy->subdev.entity;
3413 camss_link_err(camss, sensor->name,3400 sensor = &sd->entity;
3414 input->name,3401
3415 ret);3402 for (i = 0; i < sensor->num_pads; i++) {
3416 return ret;3403 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
3417 }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;
3418 }3410 }
3419 }
3420 3411
3421 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);3412 ret = media_create_pad_link(sensor, i, input,
3422 if (ret < 0)3413 MSM_CSIPHY_PAD_SINK,
3423 return ret;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 }
3424 3420
3425 return media_device_register(&camss->media_dev);3421 return v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
3426}3422}
3427 3423
3428static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = {3424static 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
3625 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);3621 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
3626 if (ret < 0) {3622 if (ret < 0) {
3627 dev_err(dev, "Failed to register V4L2 device: %d\n", ret);3623 dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
3628 goto err_genpd_cleanup;3624 goto err_media_device_cleanup;
3629 }3625 }
3630 3626
3631 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);3627 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
@@ -3646,6 +3642,12 @@ static int camss_probe(struct platform_device *pdev) · 14 unmodified lines
3646 if (ret < 0)3642 if (ret < 0)
3647 goto err_register_subdevs;3643 goto err_register_subdevs;
3648 3644
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
3649 if (num_subdevs) {3651 if (num_subdevs) {
3650 camss->notifier.ops = &camss_subdev_notifier_ops;3652 camss->notifier.ops = &camss_subdev_notifier_ops;
3651 3653
@@ -3654,32 +3656,29 @@ static int camss_probe(struct platform_device *pdev) · 2 unmodified lines
3654 dev_err(dev,3656 dev_err(dev,
3655 "Failed to register async subdev nodes: %d\n",3657 "Failed to register async subdev nodes: %d\n",
3656 ret);3658 ret);
3657 goto err_register_subdevs;3659 goto err_media_device_unregister;
3658 }3660 }
3659 } else {3661 } else {
3660 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);3662 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
3661 if (ret < 0) {3663 if (ret < 0) {
3662 dev_err(dev, "Failed to register subdev nodes: %d\n",3664 dev_err(dev, "Failed to register subdev nodes: %d\n",
3663 ret);3665 ret);
3664 goto err_register_subdevs;3666 goto err_media_device_unregister;
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;
3672 }3667 }
3673 }3668 }
3674 3669
3675 return 0;3670 return 0;
3676 3671
3672err_media_device_unregister:
3673 media_device_unregister(&camss->media_dev);
3677err_register_subdevs:3674err_register_subdevs:
3678 camss_unregister_entities(camss);3675 camss_unregister_entities(camss);
3679err_v4l2_device_unregister:3676err_v4l2_device_unregister:
3680 v4l2_device_unregister(&camss->v4l2_dev);3677 v4l2_device_unregister(&camss->v4l2_dev);
3681 v4l2_async_nf_cleanup(&camss->notifier);3678 v4l2_async_nf_cleanup(&camss->notifier);
3682 pm_runtime_disable(dev);3679 pm_runtime_disable(dev);
3680err_media_device_cleanup:
3681 media_device_cleanup(&camss->media_dev);
3683err_genpd_cleanup:3682err_genpd_cleanup:
3684 camss_genpd_cleanup(camss);3683 camss_genpd_cleanup(camss);
3685 3684
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
205 if (num_mbs > NUM_MBS_4K) {205 if (num_mbs > NUM_MBS_4K) {
206 div_factor = 4;206 div_factor = 4;
207 base_res_mbs = caps->max_mbpf;207 base_res_mbs = caps->max_mbpf;
208 } else {
209 if (inst->codec == V4L2_PIX_FMT_VP9)
210 div_factor = 1;
208 }211 }
209 212
210 /*213 /*
@@ -376,7 +379,7 @@ int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf · 165 unmodified lines
376 return 0;379 return 0;
377}380}
378 381
379int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane)382static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool force)
380{383{
381 const struct iris_platform_data *platform_data = inst->core->iris_platform_data;384 const struct iris_platform_data *platform_data = inst->core->iris_platform_data;
382 struct iris_buffer *buf, *next;385 struct iris_buffer *buf, *next;
@@ -396,6 +399,14 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) · 13 unmodified lines
396 for (i = 0; i < len; i++) {399 for (i = 0; i < len; i++) {
397 buffers = &inst->buffers[internal_buf_type[i]];400 buffers = &inst->buffers[internal_buf_type[i]];
398 list_for_each_entry_safe(buf, next, &buffers->list, list) {401 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
399 ret = iris_destroy_internal_buffer(inst, buf);410 ret = iris_destroy_internal_buffer(inst, buf);
400 if (ret)411 if (ret)
401 return ret;412 return ret;
@@ -405,6 +416,16 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) · 3 unmodified lines
405 return 0;416 return 0;
406}417}
407 418
419int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane)
420{
421 return iris_destroy_internal_buffers(inst, plane, true);
422}
423
424int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane)
425{
426 return iris_destroy_internal_buffers(inst, plane, false);
427}
428
408static int iris_release_internal_buffers(struct iris_inst *inst,429static int iris_release_internal_buffers(struct iris_inst *inst,
409 enum iris_buffer_type buffer_type)430 enum iris_buffer_type buffer_type)
410{431{
@@ -593,10 +614,13 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) · 182 unmodified lines
593 614
594 vb2 = &vbuf->vb2_buf;615 vb2 = &vbuf->vb2_buf;
595 616
596 if (buf->flags & V4L2_BUF_FLAG_ERROR)617 if (buf->flags & V4L2_BUF_FLAG_ERROR) {
597 state = VB2_BUF_STATE_ERROR;618 state = VB2_BUF_STATE_ERROR;
598 else619 vb2_set_plane_payload(vb2, 0, 0);
599 state = VB2_BUF_STATE_DONE;620 vb2->timestamp = 0;
621 v4l2_m2m_buf_done(vbuf, state);
622 return 0;
623 }
600 624
601 vbuf->flags |= buf->flags;625 vbuf->flags |= buf->flags;
602 626
@@ -615,7 +639,10 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) · 12 unmodified lines
615 v4l2_event_queue_fh(&inst->fh, &ev);639 v4l2_event_queue_fh(&inst->fh, &ev);
616 v4l2_m2m_mark_stopped(m2m_ctx);640 v4l2_m2m_mark_stopped(m2m_ctx);
617 }641 }
642 inst->last_buffer_dequeued = true;
618 }643 }
644
645 state = VB2_BUF_STATE_DONE;
619 vb2->timestamp = buf->timestamp;646 vb2->timestamp = buf->timestamp;
620 v4l2_m2m_buf_done(vbuf, state);647 v4l2_m2m_buf_done(vbuf, state);
621 648
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
106int iris_create_internal_buffers(struct iris_inst *inst, u32 plane);106int iris_create_internal_buffers(struct iris_inst *inst, u32 plane);
107int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane);107int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane);
108int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer);108int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer);
109int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane);109int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane);
110int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane);
110int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);111int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst);
111int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst);112int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst);
112int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);113int 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
17static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)17static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id)
18{18{
19 switch (id) {19 switch (id) {
20 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
21 return DEBLOCK;
22 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:20 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;
24 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:26 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;
26 default:34 default:
27 return INST_FW_CAP_MAX;35 return INST_FW_CAP_MAX;
28 }36 }
@@ -34,12 +42,20 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id) · 5 unmodified lines
34 return 0;42 return 0;
35 43
36 switch (cap_id) {44 switch (cap_id) {
37 case DEBLOCK:45 case PROFILE_H264:
38 return V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER;
39 case PROFILE:
40 return V4L2_CID_MPEG_VIDEO_H264_PROFILE;46 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:
42 return V4L2_CID_MPEG_VIDEO_H264_LEVEL;52 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;
43 default:59 default:
44 return 0;60 return 0;
45 }61 }
@@ -84,8 +100,6 @@ int iris_ctrls_init(struct iris_inst *inst) · 38 unmodified lines
84 if (iris_get_v4l2_id(cap[idx].cap_id))100 if (iris_get_v4l2_id(cap[idx].cap_id))
85 num_ctrls++;101 num_ctrls++;
86 }102 }
87 if (!num_ctrls)
88 return -EINVAL;
89 103
90 /* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */104 /* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */
91 105
@@ -163,6 +177,7 @@ void iris_session_init_caps(struct iris_core *core) · 71 unmodified lines
163 core->inst_fw_caps[cap_id].value = caps[i].value;177 core->inst_fw_caps[cap_id].value = caps[i].value;
164 core->inst_fw_caps[cap_id].flags = caps[i].flags;178 core->inst_fw_caps[cap_id].flags = caps[i].flags;
165 core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id;179 core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id;
180 core->inst_fw_caps[cap_id].set = caps[i].set;
166 }181 }
167}182}
168 183
drivers/media/platform/qcom/iris/iris_hfi_common.h+1−0
@@ -140,6 +140,7 @@ struct hfi_subscription_params { · 139 unmodified lines
140 u32 color_info;140 u32 color_info;
141 u32 profile;141 u32 profile;
142 u32 level;142 u32 level;
143 u32 tier;
143};144};
144 145
145u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries);146u32 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
88static int iris_hfi_gen1_session_open(struct iris_inst *inst)88static int iris_hfi_gen1_session_open(struct iris_inst *inst)
89{89{
90 struct hfi_session_open_pkt packet;90 struct hfi_session_open_pkt packet;
91 u32 codec = 0;
91 int ret;92 int ret;
92 93
93 if (inst->state != IRIS_INST_DEINIT)94 if (inst->state != IRIS_INST_DEINIT)
94 return -EALREADY;95 return -EALREADY;
95 96
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
96 packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);109 packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);
97 packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT;110 packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT;
98 packet.shdr.session_id = inst->session_id;111 packet.shdr.session_id = inst->session_id;
99 packet.session_domain = HFI_SESSION_TYPE_DEC;112 packet.session_domain = HFI_SESSION_TYPE_DEC;
100 packet.session_codec = HFI_VIDEO_CODEC_H264;113 packet.session_codec = codec;
101 114
102 reinit_completion(&inst->completion);115 reinit_completion(&inst->completion);
103 116
@@ -208,8 +221,10 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) · 104 unmodified lines
208 flush_pkt.flush_type = flush_type;221 flush_pkt.flush_type = flush_type;
209 222
210 ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);223 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++;
212 ret = iris_wait_for_session_response(inst, true);226 ret = iris_wait_for_session_response(inst, true);
227 }
213 }228 }
214 229
215 return ret;230 return ret;
@@ -386,6 +401,8 @@ static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane) · 170 unmodified lines
386 ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;401 ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
387 ip_pkt.shdr.session_id = inst->session_id;402 ip_pkt.shdr.session_id = inst->session_id;
388 ip_pkt.flags = HFI_BUFFERFLAG_EOS;403 ip_pkt.flags = HFI_BUFFERFLAG_EOS;
404 if (inst->codec == V4L2_PIX_FMT_VP9)
405 ip_pkt.packet_buffer = 0xdeadb000;
389 406
390 return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);407 return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
391}408}
@@ -490,14 +507,6 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p · 98 unmodified lines
490 packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm);507 packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm);
491 break;508 break;
492 }509 }
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 }
501 default:510 default:
502 return -EINVAL;511 return -EINVAL;
503 }512 }
@@ -546,14 +555,15 @@ static int iris_hfi_gen1_set_resolution(struct iris_inst *inst) · 42 unmodified lines
546 struct hfi_framesize fs;555 struct hfi_framesize fs;
547 int ret;556 int ret;
548 557
549 fs.buffer_type = HFI_BUFFER_INPUT;558 if (!iris_drc_pending(inst)) {
550 fs.width = inst->fmt_src->fmt.pix_mp.width;559 fs.buffer_type = HFI_BUFFER_INPUT;
551 fs.height = inst->fmt_src->fmt.pix_mp.height;560 fs.width = inst->fmt_src->fmt.pix_mp.width;
552 561 fs.height = inst->fmt_src->fmt.pix_mp.height;
553 ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
554 if (ret)
555 return ret;
556 562
563 ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
564 if (ret)
565 return ret;
566 }
557 fs.buffer_type = HFI_BUFFER_OUTPUT2;567 fs.buffer_type = HFI_BUFFER_OUTPUT2;
558 fs.width = inst->fmt_dst->fmt.pix_mp.width;568 fs.width = inst->fmt_dst->fmt.pix_mp.width;
559 fs.height = inst->fmt_dst->fmt.pix_mp.height;569 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
768 iris_hfi_gen1_set_bufsize},778 iris_hfi_gen1_set_bufsize},
769 };779 };
770 780
771 config_params = core->iris_platform_data->input_config_params;781 config_params = core->iris_platform_data->input_config_params_default;
772 config_params_size = core->iris_platform_data->input_config_params_size;782 config_params_size = core->iris_platform_data->input_config_params_default_size;
773 783
774 if (V4L2_TYPE_IS_OUTPUT(plane)) {784 if (V4L2_TYPE_IS_OUTPUT(plane)) {
775 for (i = 0; i < config_params_size; i++) {785 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
13#define HFI_SESSION_TYPE_DEC 213#define HFI_SESSION_TYPE_DEC 2
14 14
15#define HFI_VIDEO_CODEC_H264 0x0000000215#define HFI_VIDEO_CODEC_H264 0x00000002
16#define HFI_VIDEO_CODEC_HEVC 0x00002000
17#define HFI_VIDEO_CODEC_VP9 0x00004000
16 18
17#define HFI_ERR_NONE 0x019#define HFI_ERR_NONE 0x0
18 20
@@ -65,7 +67,6 @@ · 46 unmodified lines
65 67
66#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS 0x20200168#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS 0x202001
67 69
68#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER 0x1200001
69#define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS 0x120300e70#define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS 0x120300e
70#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY 0x120400471#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY 0x1204004
71 72
@@ -117,6 +118,8 @@ · 45 unmodified lines
117#define HFI_FRAME_NOTCODED 0x7f002000118#define HFI_FRAME_NOTCODED 0x7f002000
118#define HFI_FRAME_YUV 0x7f004000119#define HFI_FRAME_YUV 0x7f004000
119#define HFI_UNUSED_PICT 0x10000000120#define HFI_UNUSED_PICT 0x10000000
121#define HFI_BUFFERFLAG_DATACORRUPT 0x00000008
122#define HFI_BUFFERFLAG_DROP_FRAME 0x20000000
120 123
121struct hfi_pkt_hdr {124struct hfi_pkt_hdr {
122 u32 size;125 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
200 200
201 iris_hfi_gen1_read_changed_params(inst, pkt);201 iris_hfi_gen1_read_changed_params(inst, pkt);
202 202
203 if (inst->state != IRIS_INST_ERROR) {203 if (inst->state != IRIS_INST_ERROR && !(inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) {
204 reinit_completion(&inst->flush_completion);
205 204
206 flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);205 flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
207 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;206 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
208 flush_pkt.shdr.session_id = inst->session_id;207 flush_pkt.shdr.session_id = inst->session_id;
209 flush_pkt.flush_type = HFI_FLUSH_OUTPUT;208 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++;
211 }211 }
212 212
213 iris_vdec_src_change(inst);213 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
348 struct iris_buffer *buf = NULL;348 struct iris_buffer *buf = NULL;
349 bool found = false;349 bool found = false;
350 350
351 /* EOS buffer sent via drain won't be in v4l2 buffer list */
352 if (pkt->packet_buffer == 0xdeadb000)
353 return;
354
351 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) {355 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) {
352 buf = to_iris_buffer(&m2m_buffer->vb);356 buf = to_iris_buffer(&m2m_buffer->vb);
353 if (buf->index == pkt->input_tag) {357 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
408 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;412 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
409 flush_pkt.shdr.session_id = inst->session_id;413 flush_pkt.shdr.session_id = inst->session_id;
410 flush_pkt.flush_type = HFI_FLUSH_OUTPUT;414 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
412 iris_inst_sub_state_change_drain_last(inst);418 iris_inst_sub_state_change_drain_last(inst);
413 419
414 return;420 return;
@@ -455,7 +461,12 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) · 40 unmodified lines
455 timestamp_us = timestamp_hi;461 timestamp_us = timestamp_hi;
456 timestamp_us = (timestamp_us << 32) | timestamp_lo;462 timestamp_us = (timestamp_us << 32) | timestamp_lo;
457 } else {463 } 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 }
459 }470 }
460 buf->timestamp = timestamp_us;471 buf->timestamp = timestamp_us;
461 472
@@ -481,6 +492,12 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) · 19 unmodified lines
481 buf->attr |= BUF_ATTR_DEQUEUED;492 buf->attr |= BUF_ATTR_DEQUEUED;
482 buf->attr |= BUF_ATTR_BUFFER_DONE;493 buf->attr |= BUF_ATTR_BUFFER_DONE;
483 494
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
484 buf->flags |= flags;501 buf->flags |= flags;
485 502
486 iris_vb2_buffer_done(inst, buf);503 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
558 const struct iris_hfi_gen1_response_pkt_info *pkt_info;575 const struct iris_hfi_gen1_response_pkt_info *pkt_info;
559 struct device *dev = core->dev;576 struct device *dev = core->dev;
560 struct hfi_session_pkt *pkt;577 struct hfi_session_pkt *pkt;
561 struct completion *done;
562 struct iris_inst *inst;578 struct iris_inst *inst;
563 bool found = false;579 bool found = false;
564 u32 i;580 u32 i;
@@ -619,9 +635,12 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response · 54 unmodified lines
619 if (shdr->error_type != HFI_ERR_NONE)635 if (shdr->error_type != HFI_ERR_NONE)
620 iris_inst_change_state(inst, IRIS_INST_ERROR);636 iris_inst_change_state(inst, IRIS_INST_ERROR);
621 637
622 done = pkt_info->pkt == HFI_MSG_SESSION_FLUSH ?638 if (pkt_info->pkt == HFI_MSG_SESSION_FLUSH) {
623 &inst->flush_completion : &inst->completion;639 if (!(--inst->flush_responses_pending))
624 complete(done);640 complete(&inst->flush_completion);
641 } else {
642 complete(&inst->completion);
643 }
625 }644 }
626 mutex_unlock(&inst->lock);645 mutex_unlock(&inst->lock);
627 646
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
178 sizeof(u64));178 sizeof(u64));
179}179}
180 180
181static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst)181static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst)
182{182{
183 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);183 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
184 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);184 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
295{295{
296 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);296 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
297 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);297 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 }
299 311
300 inst_hfi_gen2->src_subcr_params.profile = profile;312 inst_hfi_gen2->src_subcr_params.profile = profile;
301 313
@@ -312,7 +324,19 @@ static int iris_hfi_gen2_set_level(struct iris_inst *inst) · 10 unmodified lines
312{324{
313 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);325 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
314 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);326 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 }
316 340
317 inst_hfi_gen2->src_subcr_params.level = level;341 inst_hfi_gen2->src_subcr_params.level = level;
318 342
@@ -367,18 +391,35 @@ static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst) · 48 unmodified lines
367 sizeof(u64));391 sizeof(u64));
368}392}
369 393
394static 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
370static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)411static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
371{412{
372 struct iris_core *core = inst->core;413 struct iris_core *core = inst->core;
373 u32 config_params_size, i, j;414 u32 config_params_size = 0, i, j;
374 const u32 *config_params;415 const u32 *config_params = NULL;
375 int ret;416 int ret;
376 417
377 static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {418 static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
378 {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution },419 {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution },
379 {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets },420 {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets },
380 {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames },421 {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 },
382 {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count },423 {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count },
383 {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count },424 {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count },
384 {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace },425 {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
386 {HFI_PROP_LEVEL, iris_hfi_gen2_set_level },427 {HFI_PROP_LEVEL, iris_hfi_gen2_set_level },
387 {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat },428 {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat },
388 {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline },429 {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline },
430 {HFI_PROP_TIER, iris_hfi_gen2_set_tier },
389 };431 };
390 432
391 if (V4L2_TYPE_IS_OUTPUT(plane)) {433 if (V4L2_TYPE_IS_OUTPUT(plane)) {
392 config_params = core->iris_platform_data->input_config_params;434 switch (inst->codec) {
393 config_params_size = core->iris_platform_data->input_config_params_size;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 }
394 } else {451 } else {
395 config_params = core->iris_platform_data->output_config_params;452 config_params = core->iris_platform_data->output_config_params;
396 config_params_size = core->iris_platform_data->output_config_params_size;453 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
416static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)473static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
417{474{
418 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);475 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 }
420 489
421 iris_hfi_gen2_packet_session_property(inst,490 iris_hfi_gen2_packet_session_property(inst,
422 HFI_PROP_CODEC,491 HFI_PROP_CODEC,
@@ -548,8 +617,8 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 125 unmodified lines
548 struct hfi_subscription_params subsc_params;617 struct hfi_subscription_params subsc_params;
549 u32 prop_type, payload_size, payload_type;618 u32 prop_type, payload_size, payload_type;
550 struct iris_core *core = inst->core;619 struct iris_core *core = inst->core;
551 const u32 *change_param;620 const u32 *change_param = NULL;
552 u32 change_param_size;621 u32 change_param_size = 0;
553 u32 payload[32] = {0};622 u32 payload[32] = {0};
554 u32 hfi_port = 0, i;623 u32 hfi_port = 0, i;
555 int ret;624 int ret;
@@ -560,8 +629,23 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 4 unmodified lines
560 return 0;629 return 0;
561 }630 }
562 631
563 change_param = core->iris_platform_data->input_config_params;632 switch (inst->codec) {
564 change_param_size = core->iris_platform_data->input_config_params_size;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 }
565 649
566 payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;650 payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
567 651
@@ -608,6 +692,11 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 40 unmodified lines
608 payload_size = sizeof(u32);692 payload_size = sizeof(u32);
609 payload_type = HFI_PAYLOAD_U32;693 payload_type = HFI_PAYLOAD_U32;
610 break;694 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;
611 case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:700 case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
612 payload[0] = subsc_params.fw_min_count;701 payload[0] = subsc_params.fw_min_count;
613 payload_size = sizeof(u32);702 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
633 payload_size = sizeof(u32);722 payload_size = sizeof(u32);
634 payload_type = HFI_PAYLOAD_U32;723 payload_type = HFI_PAYLOAD_U32;
635 break;724 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;
636 default:730 default:
637 prop_type = 0;731 prop_type = 0;
638 ret = -EINVAL;732 ret = -EINVAL;
@@ -659,8 +753,8 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan · 20 unmodified lines
659static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)753static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
660{754{
661 struct iris_core *core = inst->core;755 struct iris_core *core = inst->core;
662 u32 subscribe_prop_size, i;756 u32 subscribe_prop_size = 0, i;
663 const u32 *subcribe_prop;757 const u32 *subcribe_prop = NULL;
664 u32 payload[32] = {0};758 u32 payload[32] = {0};
665 759
666 payload[0] = HFI_MODE_PROPERTY;760 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
669 subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;763 subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
670 subcribe_prop = core->iris_platform_data->dec_input_prop;764 subcribe_prop = core->iris_platform_data->dec_input_prop;
671 } else {765 } else {
672 subscribe_prop_size = core->iris_platform_data->dec_output_prop_size;766 switch (inst->codec) {
673 subcribe_prop = core->iris_platform_data->dec_output_prop;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 }
674 }783 }
675 784
676 for (i = 0; i < subscribe_prop_size; i++)785 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
46#define HFI_PROP_CROP_OFFSETS 0x0300010546#define HFI_PROP_CROP_OFFSETS 0x03000105
47#define HFI_PROP_PROFILE 0x0300010747#define HFI_PROP_PROFILE 0x03000107
48#define HFI_PROP_LEVEL 0x0300010848#define HFI_PROP_LEVEL 0x03000108
49#define HFI_PROP_TIER 0x03000109
49#define HFI_PROP_STAGE 0x0300010a50#define HFI_PROP_STAGE 0x0300010a
50#define HFI_PROP_PIPE 0x0300010b51#define HFI_PROP_PIPE 0x0300010b
51#define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f52#define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f
@@ -104,6 +105,9 @@ enum hfi_color_format { · 52 unmodified lines
104enum hfi_codec_type {105enum hfi_codec_type {
105 HFI_CODEC_DECODE_AVC = 1,106 HFI_CODEC_DECODE_AVC = 1,
106 HFI_CODEC_ENCODE_AVC = 2,107 HFI_CODEC_ENCODE_AVC = 2,
108 HFI_CODEC_DECODE_HEVC = 3,
109 HFI_CODEC_ENCODE_HEVC = 4,
110 HFI_CODEC_DECODE_VP9 = 5,
107};111};
108 112
109enum hfi_picture_type {113enum hfi_picture_type {
@@ -113,6 +117,7 @@ enum hfi_picture_type { · 3 unmodified lines
113 HFI_PICTURE_I = 0x00000008,117 HFI_PICTURE_I = 0x00000008,
114 HFI_PICTURE_CRA = 0x00000010,118 HFI_PICTURE_CRA = 0x00000010,
115 HFI_PICTURE_BLA = 0x00000020,119 HFI_PICTURE_BLA = 0x00000020,
120 HFI_PICTURE_NOSHOW = 0x00000040,
116};121};
117 122
118enum hfi_buffer_type {123enum 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
91 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);91 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
92 u32 driver_flags = 0;92 u32 driver_flags = 0;
93 93
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)
95 driver_flags |= V4L2_BUF_FLAG_KEYFRAME;97 driver_flags |= V4L2_BUF_FLAG_KEYFRAME;
96 else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_P)98 else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_P)
97 driver_flags |= V4L2_BUF_FLAG_PFRAME;99 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
265{267{
266 struct iris_inst *instance;268 struct iris_inst *instance;
267 269
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);
269 272
270 core->state = IRIS_CORE_ERROR;273 core->state = IRIS_CORE_ERROR;
271 274
@@ -377,6 +380,11 @@ static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, · 105 unmodified lines
377 380
378 buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->flags);381 buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->flags);
379 382
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
380 return 0;388 return 0;
381}389}
382 390
@@ -563,9 +571,23 @@ static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) · 180 unmodified lines
563 inst->crop.width = pixmp_ip->width -571 inst->crop.width = pixmp_ip->width -
564 ((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left;572 ((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left;
565 573
566 inst->fw_caps[PROFILE].value = subsc_params.profile;574 switch (inst->codec) {
567 inst->fw_caps[LEVEL].value = subsc_params.level;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
568 inst->fw_caps[POC].value = subsc_params.pic_order_cnt;589 inst->fw_caps[POC].value = subsc_params.pic_order_cnt;
590 inst->fw_caps[TIER].value = subsc_params.tier;
569 591
570 if (subsc_params.bit_depth != BIT_DEPTH_8 ||592 if (subsc_params.bit_depth != BIT_DEPTH_8 ||
571 !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) {593 !(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
636{658{
637 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);659 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
638 660
639 if (pkt->port != HFI_PORT_BITSTREAM)
640 return 0;
641
642 if (pkt->flags & HFI_FW_FLAGS_INFORMATION)661 if (pkt->flags & HFI_FW_FLAGS_INFORMATION)
643 return 0;662 return 0;
644 663
@@ -650,6 +669,9 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, · 5 unmodified lines
650 inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0];669 inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0];
651 inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1];670 inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1];
652 break;671 break;
672 case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
673 inst_hfi_gen2->src_subcr_params.bit_depth = pkt->payload[0];
674 break;
653 case HFI_PROP_CODED_FRAMES:675 case HFI_PROP_CODED_FRAMES:
654 inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0];676 inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0];
655 break;677 break;
@@ -668,6 +690,9 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, · 12 unmodified lines
668 case HFI_PROP_LEVEL:690 case HFI_PROP_LEVEL:
669 inst_hfi_gen2->src_subcr_params.level = pkt->payload[0];691 inst_hfi_gen2->src_subcr_params.level = pkt->payload[0];
670 break;692 break;
693 case HFI_PROP_TIER:
694 inst_hfi_gen2->src_subcr_params.tier = pkt->payload[0];
695 break;
671 case HFI_PROP_PICTURE_TYPE:696 case HFI_PROP_PICTURE_TYPE:
672 inst_hfi_gen2->hfi_frame_info.picture_type = pkt->payload[0];697 inst_hfi_gen2->hfi_frame_info.picture_type = pkt->payload[0];
673 break;698 break;
@@ -791,8 +816,21 @@ static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst) · 117 unmodified lines
791 full_range, video_format,816 full_range, video_format,
792 video_signal_type_present_flag);817 video_signal_type_present_flag);
793 818
794 subsc_params->profile = inst->fw_caps[PROFILE].value;819 switch (inst->codec) {
795 subsc_params->level = inst->fw_caps[LEVEL].value;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
796 subsc_params->pic_order_cnt = inst->fw_caps[POC].value;834 subsc_params->pic_order_cnt = inst->fw_caps[POC].value;
797 subsc_params->bit_depth = inst->fw_caps[BIT_DEPTH].value;835 subsc_params->bit_depth = inst->fw_caps[BIT_DEPTH].value;
798 if (inst->fw_caps[CODED_FRAMES].value ==836 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
113{113{
114 struct iris_iface_q_info *q_info = &core->command_queue;114 struct iris_iface_q_info *q_info = &core->command_queue;
115 115
116 if (core->state == IRIS_CORE_ERROR)116 if (core->state == IRIS_CORE_ERROR || core->state == IRIS_CORE_DEINIT)
117 return -EINVAL;117 return -EINVAL;
118 118
119 if (!iris_hfi_queue_write(q_info, pkt, pkt_size)) {119 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
27 * @crop: structure of crop info27 * @crop: structure of crop info
28 * @completion: structure of signal completions28 * @completion: structure of signal completions
29 * @flush_completion: structure of signal completions for flush cmd29 * @flush_completion: structure of signal completions for flush cmd
30 * @flush_responses_pending: counter to track number of pending flush responses
30 * @fw_caps: array of supported instance firmware capabilities31 * @fw_caps: array of supported instance firmware capabilities
31 * @buffers: array of different iris buffers32 * @buffers: array of different iris buffers
32 * @fw_min_count: minimnum count of buffers needed by fw33 * @fw_min_count: minimnum count of buffers needed by fw
@@ -42,6 +43,8 @@ · 9 unmodified lines
42 * @sequence_out: a sequence counter for output queue43 * @sequence_out: a sequence counter for output queue
43 * @tss: timestamp metadata44 * @tss: timestamp metadata
44 * @metadata_idx: index for metadata buffer45 * @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
45 */48 */
46 49
47struct iris_inst {50struct iris_inst {
@@ -57,6 +60,7 @@ struct iris_inst { · 9 unmodified lines
57 struct iris_hfi_rect_desc crop;60 struct iris_hfi_rect_desc crop;
58 struct completion completion;61 struct completion completion;
59 struct completion flush_completion;62 struct completion flush_completion;
63 u32 flush_responses_pending;
60 struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX];64 struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX];
61 struct iris_buffers buffers[BUF_TYPE_MAX];65 struct iris_buffers buffers[BUF_TYPE_MAX];
62 u32 fw_min_count;66 u32 fw_min_count;
@@ -72,6 +76,8 @@ struct iris_inst { · 9 unmodified lines
72 u32 sequence_out;76 u32 sequence_out;
73 struct iris_ts_metadata tss[VIDEO_MAX_FRAME];77 struct iris_ts_metadata tss[VIDEO_MAX_FRAME];
74 u32 metadata_idx;78 u32 metadata_idx;
79 u32 codec;
80 bool last_buffer_dequeued;
75};81};
76 82
77#endif83#endif
drivers/media/platform/qcom/iris/iris_platform_common.h+21−7
@@ -21,6 +21,7 @@ struct iris_inst; · 20 unmodified lines
21#define DEFAULT_MAX_HOST_BUF_COUNT 6421#define DEFAULT_MAX_HOST_BUF_COUNT 64
22#define DEFAULT_MAX_HOST_BURST_BUF_COUNT 25622#define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256
23#define DEFAULT_FPS 3023#define DEFAULT_FPS 30
24#define NUM_MBS_8K ((8192 * 4352) / 256)
24 25
25enum stage_type {26enum stage_type {
26 STAGE_1 = 1,27 STAGE_1 = 1,
@@ -80,8 +81,12 @@ struct platform_inst_caps { · 53 unmodified lines
80};81};
81 82
82enum platform_inst_fw_cap_type {83enum platform_inst_fw_cap_type {
83 PROFILE = 1,84 PROFILE_H264 = 1,
84 LEVEL,85 PROFILE_HEVC,
86 PROFILE_VP9,
87 LEVEL_H264,
88 LEVEL_HEVC,
89 LEVEL_VP9,
85 INPUT_BUF_HOST_MAX_COUNT,90 INPUT_BUF_HOST_MAX_COUNT,
86 STAGE,91 STAGE,
87 PIPE,92 PIPE,
@@ -89,7 +94,7 @@ enum platform_inst_fw_cap_type { · 1 unmodified line
89 CODED_FRAMES,94 CODED_FRAMES,
90 BIT_DEPTH,95 BIT_DEPTH,
91 RAP_FRAME,96 RAP_FRAME,
92 DEBLOCK,97 TIER,
93 INST_FW_CAP_MAX,98 INST_FW_CAP_MAX,
94};99};
95 100
@@ -172,15 +177,24 @@ struct iris_platform_data { · 76 unmodified lines
172 struct ubwc_config_data *ubwc_config;177 struct ubwc_config_data *ubwc_config;
173 u32 num_vpp_pipe;178 u32 num_vpp_pipe;
174 u32 max_session_count;179 u32 max_session_count;
180 /* max number of macroblocks per frame supported */
175 u32 max_core_mbpf;181 u32 max_core_mbpf;
176 const u32 *input_config_params;182 const u32 *input_config_params_default;
177 unsigned int input_config_params_size;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;
178 const u32 *output_config_params;188 const u32 *output_config_params;
179 unsigned int output_config_params_size;189 unsigned int output_config_params_size;
180 const u32 *dec_input_prop;190 const u32 *dec_input_prop;
181 unsigned int dec_input_prop_size;191 unsigned int dec_input_prop_size;
182 const u32 *dec_output_prop;192 const u32 *dec_output_prop_avc;
183 unsigned int dec_output_prop_size;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;
184 const u32 *dec_ip_int_buf_tbl;198 const u32 *dec_ip_int_buf_tbl;
185 unsigned int dec_ip_int_buf_tbl_size;199 unsigned int dec_ip_int_buf_tbl_size;
186 const u32 *dec_op_int_buf_tbl;200 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
17 17
18static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = {18static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = {
19 {19 {
20 .cap_id = PROFILE,20 .cap_id = PROFILE_H264,
21 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,21 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
22 .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,22 .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
23 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |23 .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
31 .set = iris_set_u32_enum,31 .set = iris_set_u32_enum,
32 },32 },
33 {33 {
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,
35 .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,57 .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
36 .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,58 .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
37 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |59 .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
59 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,81 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
60 .set = iris_set_u32_enum,82 .set = iris_set_u32_enum,
61 },83 },
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 },
62 {138 {
63 .cap_id = INPUT_BUF_HOST_MAX_COUNT,139 .cap_id = INPUT_BUF_HOST_MAX_COUNT,
64 .min = DEFAULT_MAX_HOST_BUF_COUNT,140 .min = DEFAULT_MAX_HOST_BUF_COUNT,
@@ -181,9 +257,10 @@ static struct tz_cp_config tz_cp_config_sm8550 = { · 116 unmodified lines
181 .cp_nonpixel_size = 0x24800000,257 .cp_nonpixel_size = 0x24800000,
182};258};
183 259
184static const u32 sm8550_vdec_input_config_params[] = {260static const u32 sm8550_vdec_input_config_params_default[] = {
185 HFI_PROP_BITSTREAM_RESOLUTION,261 HFI_PROP_BITSTREAM_RESOLUTION,
186 HFI_PROP_CROP_OFFSETS,262 HFI_PROP_CROP_OFFSETS,
263 HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
187 HFI_PROP_CODED_FRAMES,264 HFI_PROP_CODED_FRAMES,
188 HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,265 HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
189 HFI_PROP_PIC_ORDER_CNT_TYPE,266 HFI_PROP_PIC_ORDER_CNT_TYPE,
@@ -192,6 +269,26 @@ static const u32 sm8550_vdec_input_config_params[] = { · 2 unmodified lines
192 HFI_PROP_SIGNAL_COLOR_INFO,269 HFI_PROP_SIGNAL_COLOR_INFO,
193};270};
194 271
272static 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
283static 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
195static const u32 sm8550_vdec_output_config_params[] = {292static const u32 sm8550_vdec_output_config_params[] = {
196 HFI_PROP_COLOR_FORMAT,293 HFI_PROP_COLOR_FORMAT,
197 HFI_PROP_LINEAR_STRIDE_SCANLINE,294 HFI_PROP_LINEAR_STRIDE_SCANLINE,
@@ -201,11 +298,19 @@ static const u32 sm8550_vdec_subscribe_input_properties[] = { · 3 unmodified lines
201 HFI_PROP_NO_OUTPUT,298 HFI_PROP_NO_OUTPUT,
202};299};
203 300
204static const u32 sm8550_vdec_subscribe_output_properties[] = {301static const u32 sm8550_vdec_subscribe_output_properties_avc[] = {
205 HFI_PROP_PICTURE_TYPE,302 HFI_PROP_PICTURE_TYPE,
206 HFI_PROP_CABAC_SESSION,303 HFI_PROP_CABAC_SESSION,
207};304};
208 305
306static const u32 sm8550_vdec_subscribe_output_properties_hevc[] = {
307 HFI_PROP_PICTURE_TYPE,
308};
309
310static const u32 sm8550_vdec_subscribe_output_properties_vp9[] = {
311 HFI_PROP_PICTURE_TYPE,
312};
313
209static const u32 sm8550_dec_ip_int_buf_tbl[] = {314static const u32 sm8550_dec_ip_int_buf_tbl[] = {
210 BUF_BIN,315 BUF_BIN,
211 BUF_COMV,316 BUF_COMV,
@@ -248,19 +353,34 @@ struct iris_platform_data sm8550_data = { · 36 unmodified lines
248 .ubwc_config = &ubwc_config_sm8550,353 .ubwc_config = &ubwc_config_sm8550,
249 .num_vpp_pipe = 4,354 .num_vpp_pipe = 4,
250 .max_session_count = 16,355 .max_session_count = 16,
251 .max_core_mbpf = ((8192 * 4352) / 256) * 2,356 .max_core_mbpf = NUM_MBS_8K * 2,
252 .input_config_params =357 .input_config_params_default =
253 sm8550_vdec_input_config_params,358 sm8550_vdec_input_config_params_default,
254 .input_config_params_size =359 .input_config_params_default_size =
255 ARRAY_SIZE(sm8550_vdec_input_config_params),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),
256 .output_config_params =369 .output_config_params =
257 sm8550_vdec_output_config_params,370 sm8550_vdec_output_config_params,
258 .output_config_params_size =371 .output_config_params_size =
259 ARRAY_SIZE(sm8550_vdec_output_config_params),372 ARRAY_SIZE(sm8550_vdec_output_config_params),
260 .dec_input_prop = sm8550_vdec_subscribe_input_properties,373 .dec_input_prop = sm8550_vdec_subscribe_input_properties,
261 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),374 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
262 .dec_output_prop = sm8550_vdec_subscribe_output_properties,375 .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
263 .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),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),
264 384
265 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,385 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
266 .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),386 .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
308 .ubwc_config = &ubwc_config_sm8550,428 .ubwc_config = &ubwc_config_sm8550,
309 .num_vpp_pipe = 4,429 .num_vpp_pipe = 4,
310 .max_session_count = 16,430 .max_session_count = 16,
311 .max_core_mbpf = ((8192 * 4352) / 256) * 2,431 .max_core_mbpf = NUM_MBS_8K * 2,
312 .input_config_params =432 .input_config_params_default =
313 sm8550_vdec_input_config_params,433 sm8550_vdec_input_config_params_default,
314 .input_config_params_size =434 .input_config_params_default_size =
315 ARRAY_SIZE(sm8550_vdec_input_config_params),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),
316 .output_config_params =444 .output_config_params =
317 sm8550_vdec_output_config_params,445 sm8550_vdec_output_config_params,
318 .output_config_params_size =446 .output_config_params_size =
319 ARRAY_SIZE(sm8550_vdec_output_config_params),447 ARRAY_SIZE(sm8550_vdec_output_config_params),
320 .dec_input_prop = sm8550_vdec_subscribe_input_properties,448 .dec_input_prop = sm8550_vdec_subscribe_input_properties,
321 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),449 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
322 .dec_output_prop = sm8550_vdec_subscribe_output_properties,450 .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
323 .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),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),
324 459
325 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,460 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
326 .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),461 .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
365 .num_vpp_pipe = 2,500 .num_vpp_pipe = 2,
366 .max_session_count = 16,501 .max_session_count = 16,
367 .max_core_mbpf = ((4096 * 2176) / 256) * 4,502 .max_core_mbpf = ((4096 * 2176) / 256) * 4,
368 .input_config_params =503 .input_config_params_default =
369 sm8550_vdec_input_config_params,504 sm8550_vdec_input_config_params_default,
370 .input_config_params_size =505 .input_config_params_default_size =
371 ARRAY_SIZE(sm8550_vdec_input_config_params),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),
372 .output_config_params =515 .output_config_params =
373 sm8550_vdec_output_config_params,516 sm8550_vdec_output_config_params,
374 .output_config_params_size =517 .output_config_params_size =
375 ARRAY_SIZE(sm8550_vdec_output_config_params),518 ARRAY_SIZE(sm8550_vdec_output_config_params),
376 .dec_input_prop = sm8550_vdec_subscribe_input_properties,519 .dec_input_prop = sm8550_vdec_subscribe_input_properties,
377 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),520 .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties),
378 .dec_output_prop = sm8550_vdec_subscribe_output_properties,521 .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc,
379 .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties),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),
380 530
381 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,531 .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl,
382 .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl),532 .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
5 5
6static struct platform_inst_fw_cap inst_fw_cap_qcs8300[] = {6static struct platform_inst_fw_cap inst_fw_cap_qcs8300[] = {
7 {7 {
8 .cap_id = PROFILE,8 .cap_id = PROFILE_H264,
9 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,9 .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
10 .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,10 .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
11 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |11 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
12 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |12 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
13 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |13 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
14 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |14 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
15 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),15 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
16 .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,16 .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
17 .hfi_id = HFI_PROP_PROFILE,17 .hfi_id = HFI_PROP_PROFILE,
18 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,18 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
19 .set = iris_set_u32_enum,19 .set = iris_set_u32_enum,
20 },20 },
21 {21 {
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,
23 .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,45 .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
24 .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,46 .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
25 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |47 .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
26 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |48 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
27 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |49 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
28 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |50 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
29 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |51 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
30 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |52 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
31 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |53 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
32 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |54 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
33 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |55 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
34 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |56 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
35 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |57 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
36 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |58 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
37 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |59 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
38 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |60 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
39 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |61 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
40 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |62 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
41 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |63 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
42 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |64 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
43 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |65 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
44 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),66 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
45 .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,67 .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
46 .hfi_id = HFI_PROP_LEVEL,68 .hfi_id = HFI_PROP_LEVEL,
47 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,69 .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
48 .set = iris_set_u32_enum,70 .set = iris_set_u32_enum,
49 },71 },
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 },
50 {126 {
51 .cap_id = INPUT_BUF_HOST_MAX_COUNT,127 .cap_id = INPUT_BUF_HOST_MAX_COUNT,
52 .min = DEFAULT_MAX_HOST_BUF_COUNT,128 .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
30 .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,30 .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE,
31 .set = iris_set_stage,31 .set = iris_set_stage,
32 },32 },
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 },
42};33};
43 34
44static struct platform_inst_caps platform_inst_cap_sm8250 = {35static struct platform_inst_caps platform_inst_cap_sm8250 = {
@@ -136,10 +127,10 @@ struct iris_platform_data sm8250_data = { · 91 unmodified lines
136 .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,127 .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
137 .num_vpp_pipe = 4,128 .num_vpp_pipe = 4,
138 .max_session_count = 16,129 .max_session_count = 16,
139 .max_core_mbpf = (8192 * 4352) / 256,130 .max_core_mbpf = NUM_MBS_8K,
140 .input_config_params =131 .input_config_params_default =
141 sm8250_vdec_input_config_param_default,132 sm8250_vdec_input_config_param_default,
142 .input_config_params_size =133 .input_config_params_default_size =
143 ARRAY_SIZE(sm8250_vdec_input_config_param_default),134 ARRAY_SIZE(sm8250_vdec_input_config_param_default),
144 135
145 .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl,136 .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
53 struct dev_pm_domain_attach_data iris_opp_pd_data = {53 struct dev_pm_domain_attach_data iris_opp_pd_data = {
54 .pd_names = core->iris_platform_data->opp_pd_tbl,54 .pd_names = core->iris_platform_data->opp_pd_tbl,
55 .num_pd_names = core->iris_platform_data->opp_pd_tbl_size,55 .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,
57 };57 };
58 58
59 ret = devm_pm_domain_attach_list(core->dev, &iris_pd_data, &core->pmdomain_tbl);59 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
245 return iris_inst_change_sub_state(inst, 0, set_sub_state);245 return iris_inst_change_sub_state(inst, 0, set_sub_state);
246}246}
247 247
248static inline bool iris_drc_pending(struct iris_inst *inst)248bool iris_drc_pending(struct iris_inst *inst)
249{249{
250 return inst->sub_state & IRIS_INST_SUB_DRC &&250 return inst->sub_state & IRIS_INST_SUB_DRC &&
251 inst->sub_state & IRIS_INST_SUB_DRC_LAST;251 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
140int iris_inst_sub_state_change_drc_last(struct iris_inst *inst);140int iris_inst_sub_state_change_drc_last(struct iris_inst *inst);
141int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane);141int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane);
142bool iris_allow_cmd(struct iris_inst *inst, u32 cmd);142bool iris_allow_cmd(struct iris_inst *inst, u32 cmd);
143bool iris_drc_pending(struct iris_inst *inst);
143 144
144#endif145#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
259 return -EINVAL;259 return -EINVAL;
260 }260 }
261 261
262 if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&262 if (!(inst->sub_state & IRIS_INST_SUB_DRC)) {
263 vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT))263 if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
264 return -EINVAL;264 vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT))
265 if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&265 return -EINVAL;
266 vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT))266 if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
267 return -EINVAL;267 vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT))
268 268 return -EINVAL;
269 }
269 return 0;270 return 0;
270}271}
271 272
@@ -304,7 +305,7 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) · 32 unmodified lines
304 goto exit;305 goto exit;
305 }306 }
306 307
307 if (V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) {308 if (!inst->last_buffer_dequeued && V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) {
308 if ((inst->sub_state & IRIS_INST_SUB_DRC &&309 if ((inst->sub_state & IRIS_INST_SUB_DRC &&
309 inst->sub_state & IRIS_INST_SUB_DRC_LAST) ||310 inst->sub_state & IRIS_INST_SUB_DRC_LAST) ||
310 (inst->sub_state & IRIS_INST_SUB_DRAIN &&311 (inst->sub_state & IRIS_INST_SUB_DRAIN &&
@@ -318,6 +319,7 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) · 7 unmodified lines
318 v4l2_event_queue_fh(&inst->fh, &eos);319 v4l2_event_queue_fh(&inst->fh, &eos);
319 v4l2_m2m_mark_stopped(m2m_ctx);320 v4l2_m2m_mark_stopped(m2m_ctx);
320 }321 }
322 inst->last_buffer_dequeued = true;
321 goto exit;323 goto exit;
322 }324 }
323 }325 }
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
32 f->fmt.pix_mp.width = DEFAULT_WIDTH;32 f->fmt.pix_mp.width = DEFAULT_WIDTH;
33 f->fmt.pix_mp.height = DEFAULT_HEIGHT;33 f->fmt.pix_mp.height = DEFAULT_HEIGHT;
34 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;34 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
35 inst->codec = f->fmt.pix_mp.pixelformat;
35 f->fmt.pix_mp.num_planes = 1;36 f->fmt.pix_mp.num_planes = 1;
36 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;37 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
37 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);38 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
67 kfree(inst->fmt_src);68 kfree(inst->fmt_src);
68}69}
69 70
71static 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
86static const struct iris_fmt *
87find_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
104static const struct iris_fmt *
105find_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
70int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)116int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
71{117{
118 const struct iris_fmt *fmt;
119
72 switch (f->type) {120 switch (f->type) {
73 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:121 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;
75 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;127 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
76 break;128 break;
77 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:129 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
130 if (f->index)
131 return -EINVAL;
78 f->pixelformat = V4L2_PIX_FMT_NV12;132 f->pixelformat = V4L2_PIX_FMT_NV12;
79 break;133 break;
80 default:134 default:
@@ -88,13 +142,15 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) · 7 unmodified lines
88{142{
89 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;143 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
90 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;144 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
145 const struct iris_fmt *fmt;
91 struct v4l2_format *f_inst;146 struct v4l2_format *f_inst;
92 struct vb2_queue *src_q;147 struct vb2_queue *src_q;
93 148
94 memset(pixmp->reserved, 0, sizeof(pixmp->reserved));149 memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
150 fmt = find_format(inst, pixmp->pixelformat, f->type);
95 switch (f->type) {151 switch (f->type) {
96 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:152 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
97 if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) {153 if (!fmt) {
98 f_inst = inst->fmt_src;154 f_inst = inst->fmt_src;
99 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;155 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
100 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;156 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
102 }158 }
103 break;159 break;
104 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:160 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
105 if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {161 if (!fmt) {
106 f_inst = inst->fmt_dst;162 f_inst = inst->fmt_dst;
107 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;163 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
108 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;164 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
145 201
146 switch (f->type) {202 switch (f->type) {
147 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:203 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)))
149 return -EINVAL;205 return -EINVAL;
150 206
151 fmt = inst->fmt_src;207 fmt = inst->fmt_src;
152 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;208 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
153 209 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
154 codec_align = DEFAULT_CODEC_ALIGNMENT;210 inst->codec = fmt->fmt.pix_mp.pixelformat;
211 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
155 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);212 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
156 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);213 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
157 fmt->fmt.pix_mp.num_planes = 1;214 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
171 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;228 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
172 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;229 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
173 230
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
174 inst->crop.left = 0;236 inst->crop.left = 0;
175 inst->crop.top = 0;237 inst->crop.top = 0;
176 inst->crop.width = f->fmt.pix_mp.width;238 inst->crop.width = f->fmt.pix_mp.width;
@@ -239,35 +301,6 @@ void iris_vdec_src_change(struct iris_inst *inst) · 62 unmodified lines
239 v4l2_event_queue_fh(&inst->fh, &event);301 v4l2_event_queue_fh(&inst->fh, &event);
240}302}
241 303
242static 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}
271 304
272static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst,305static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst,
273 enum iris_buffer_type type)306 enum iris_buffer_type type)
@@ -316,7 +349,6 @@ int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) · 42 unmodified lines
316{349{
317 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;350 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
318 enum iris_buffer_type buffer_type;351 enum iris_buffer_type buffer_type;
319 u32 count;
320 int ret;352 int ret;
321 353
322 switch (plane) {354 switch (plane) {
@@ -334,12 +366,6 @@ int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) · 11 unmodified lines
334 if (ret)366 if (ret)
335 goto error;367 goto error;
336 368
337 count = iris_vdec_get_num_queued_buffers(inst, buffer_type);
338 if (count) {
339 ret = -EINVAL;
340 goto error;
341 }
342
343 ret = iris_inst_state_change_streamoff(inst, plane);369 ret = iris_inst_state_change_streamoff(inst, plane);
344 if (ret)370 if (ret)
345 goto error;371 goto error;
@@ -408,7 +434,7 @@ int iris_vdec_streamon_input(struct iris_inst *inst) · 62 unmodified lines
408 434
409 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);435 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
410 436
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);
412 if (ret)438 if (ret)
413 return ret;439 return ret;
414 440
@@ -482,6 +508,8 @@ static int iris_vdec_process_streamon_output(struct iris_inst *inst) · 67 unmodified lines
482 if (ret)508 if (ret)
483 return ret;509 return ret;
484 510
511 inst->last_buffer_dequeued = false;
512
485 return iris_inst_change_sub_state(inst, clear_sub_state, 0);513 return iris_inst_change_sub_state(inst, clear_sub_state, 0);
486}514}
487 515
@@ -496,7 +524,7 @@ int iris_vdec_streamon_output(struct iris_inst *inst) · 8 unmodified lines
496 524
497 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);525 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
498 526
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);
500 if (ret)528 if (ret)
501 return ret;529 return ret;
502 530
drivers/media/platform/qcom/iris/iris_vdec.h+11−0
@@ -8,6 +8,17 @@ · 7 unmodified lines
8 8
9struct iris_inst;9struct iris_inst;
10 10
11enum iris_fmt_type {
12 IRIS_FMT_H264,
13 IRIS_FMT_HEVC,
14 IRIS_FMT_VP9,
15};
16
17struct iris_fmt {
18 u32 pixfmt;
19 u32 type;
20};
21
11int iris_vdec_inst_init(struct iris_inst *inst);22int iris_vdec_inst_init(struct iris_inst *inst);
12void iris_vdec_inst_deinit(struct iris_inst *inst);23void iris_vdec_inst_deinit(struct iris_inst *inst);
13int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);24int 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
221 iris_wait_for_session_response(inst, false);221 iris_wait_for_session_response(inst, false);
222}222}
223 223
224static 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
224int iris_close(struct file *filp)251int iris_close(struct file *filp)
225{252{
226 struct iris_inst *inst = iris_get_inst(filp, NULL);253 struct iris_inst *inst = iris_get_inst(filp, NULL);
@@ -233,8 +260,10 @@ int iris_close(struct file *filp) · 6 unmodified lines
233 iris_session_close(inst);260 iris_session_close(inst);
234 iris_inst_change_state(inst, IRIS_INST_DEINIT);261 iris_inst_change_state(inst, IRIS_INST_DEINIT);
235 iris_v4l2_fh_deinit(inst);262 iris_v4l2_fh_deinit(inst);
236 iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);263 iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
237 iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_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);
238 iris_remove_session(inst);267 iris_remove_session(inst);
239 mutex_unlock(&inst->lock);268 mutex_unlock(&inst->lock);
240 mutex_destroy(&inst->ctx_q_lock);269 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
249{278{
250 struct iris_inst *inst = iris_get_inst(filp, NULL);279 struct iris_inst *inst = iris_get_inst(filp, NULL);
251 280
252 if (f->index)
253 return -EINVAL;
254
255 return iris_vdec_enum_fmt(inst, f);281 return iris_vdec_enum_fmt(inst, f);
256}282}
257 283
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
31 return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes);31 return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes);
32}32}
33 33
34static 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
49static 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
62static 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
34static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount)70static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount)
35{71{
36 u32 frame_height_in_mbs = DIV_ROUND_UP(frame_height, 16);72 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
55 return (size_colloc * (_comv_bufcount)) + 512;91 return (size_colloc * (_comv_bufcount)) + 512;
56}92}
57 93
94static 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
58static u32 size_h264d_bse_cmd_buf(u32 frame_height)105static u32 size_h264d_bse_cmd_buf(u32 frame_height)
59{106{
60 u32 height = ALIGN(frame_height, 32);107 u32 height = ALIGN(frame_height, 32);
@@ -63,6 +110,44 @@ static u32 size_h264d_bse_cmd_buf(u32 frame_height) · 2 unmodified lines
63 SIZE_H264D_BSE_CMD_PER_BUF;110 SIZE_H264D_BSE_CMD_PER_BUF;
64}111}
65 112
113static 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
124static 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
134static inline
135u32 hfi_iris3_vp9d_comv_size(void)
136{
137 return (((8192 + 63) >> 6) * ((4320 + 63) >> 6) * 8 * 8 * 2 * 8);
138}
139
140static 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
66static u32 size_h264d_vpp_cmd_buf(u32 frame_height)151static u32 size_h264d_vpp_cmd_buf(u32 frame_height)
67{152{
68 u32 size, height = ALIGN(frame_height, 32);153 u32 size, height = ALIGN(frame_height, 32);
@@ -83,17 +168,45 @@ static u32 hfi_buffer_persist_h264d(void) · 14 unmodified lines
83 168
84static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)169static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
85{170{
86 u32 size_bse, size_vpp, size;171 u32 size_bse = size_h264d_bse_cmd_buf(frame_height);
87 172 u32 size_vpp = size_h264d_vpp_cmd_buf(frame_height);
88 size_bse = size_h264d_bse_cmd_buf(frame_height);173 u32 size = ALIGN(size_bse, DMA_ALIGNMENT) +
89 size_vpp = size_h264d_vpp_cmd_buf(frame_height);
90 size = ALIGN(size_bse, DMA_ALIGNMENT) +
91 ALIGN(size_vpp, DMA_ALIGNMENT) +174 ALIGN(size_vpp, DMA_ALIGNMENT) +
92 ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT);175 ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT);
93 176
94 return ALIGN(size, DMA_ALIGNMENT);177 return ALIGN(size, DMA_ALIGNMENT);
95}178}
96 179
180static 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
194static 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
97static u32 size_vpss_lb(u32 frame_width, u32 frame_height)210static u32 size_vpss_lb(u32 frame_width, u32 frame_height)
98{211{
99 u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size;212 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
119 opb_lb_wr_llb_y_buffer_size;232 opb_lb_wr_llb_y_buffer_size;
120}233}
121 234
235static inline
236u32 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
242static inline
243u32 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
249static inline
250u32 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
256static inline
257u32 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
262static inline
263u32 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
273static inline
274u32 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
280static inline
281u32 size_h265d_lb_vsp_top(u32 frame_width, u32 frame_height)
282{
283 return ((frame_width + 63) >> 6) * 128;
284}
285
286static inline
287u32 size_h265d_lb_vsp_left(u32 frame_width, u32 frame_height)
288{
289 return ((frame_height + 63) >> 6) * 128;
290}
291
292static inline
293u32 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
298static inline
299u32 size_h265d_qp(u32 frame_width, u32 frame_height)
300{
301 return size_h264d_qp(frame_width, frame_height);
302}
303
304static inline
305u32 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
329static inline
330u32 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
340static inline
341u32 size_vpxd_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
342{
343 return ((ALIGN(frame_width, 64) + 8) * 10 * 2);
344}
345
346static inline
347u32 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
352static inline
353u32 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
363static inline
364u32 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
370static inline __maybe_unused
371u32 size_mp2d_lb_fe_top_data(u32 frame_width, u32 frame_height)
372{
373 return ((ALIGN(frame_width, 16) + 8) * 10 * 2);
374}
375
376static inline
377u32 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
382static inline
383u32 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
388static inline
389u32 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
394static inline
395u32 size_vp9d_qp(u32 frame_width, u32 frame_height)
396{
397 return size_h264d_qp(frame_width, frame_height);
398}
399
400static inline
401u32 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
417static inline
418u32 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
122static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,432static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
123 bool is_opb, u32 num_vpp_pipes)433 bool is_opb, u32 num_vpp_pipes)
124{434{
@@ -148,7 +458,14 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) · 23 unmodified lines
148 u32 height = f->fmt.pix_mp.height;458 u32 height = f->fmt.pix_mp.height;
149 u32 width = f->fmt.pix_mp.width;459 u32 width = f->fmt.pix_mp.width;
150 460
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;
152}469}
153 470
154static u32 iris_vpu_dec_comv_size(struct iris_inst *inst)471static 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
158 u32 height = f->fmt.pix_mp.height;475 u32 height = f->fmt.pix_mp.height;
159 u32 width = f->fmt.pix_mp.width;476 u32 width = f->fmt.pix_mp.width;
160 477
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;
162}484}
163 485
164static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)486static u32 iris_vpu_dec_persist_size(struct iris_inst *inst)
165{487{
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;
167}496}
168 497
169static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst)498static 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
181 u32 height = f->fmt.pix_mp.height;510 u32 height = f->fmt.pix_mp.height;
182 u32 width = f->fmt.pix_mp.width;511 u32 width = f->fmt.pix_mp.width;
183 512
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;
185}519}
186 520
187static u32 iris_vpu_dec_line_size(struct iris_inst *inst)521static 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
191 u32 height = f->fmt.pix_mp.height;525 u32 height = f->fmt.pix_mp.height;
192 u32 width = f->fmt.pix_mp.width;526 u32 width = f->fmt.pix_mp.width;
193 bool is_opb = false;527 bool is_opb = false;
528 u32 out_min_count = inst->buffers[BUF_OUTPUT].min_count;
194 529
195 if (iris_split_mode_enabled(inst))530 if (iris_split_mode_enabled(inst))
196 is_opb = true;531 is_opb = true;
197 532
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;
199}542}
200 543
201static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst)544static 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
205 iris_vpu_dec_line_size(inst);548 iris_vpu_dec_line_size(inst);
206}549}
207 550
551static 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
208struct iris_vpu_buf_type_handle {569struct iris_vpu_buf_type_handle {
209 enum iris_buffer_type type;570 enum iris_buffer_type type;
210 u32 (*handle)(struct iris_inst *inst);571 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
238 return size;599 return size;
239}600}
240 601
602static 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
241static inline int iris_vpu_dpb_count(struct iris_inst *inst)615static inline int iris_vpu_dpb_count(struct iris_inst *inst)
242{616{
243 if (iris_split_mode_enabled(inst)) {617 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
254 case BUF_INPUT:628 case BUF_INPUT:
255 return MIN_BUFFERS;629 return MIN_BUFFERS;
256 case BUF_OUTPUT:630 case BUF_OUTPUT:
257 return inst->fw_min_count;631 return output_min_count(inst);
258 case BUF_BIN:632 case BUF_BIN:
259 case BUF_COMV:633 case BUF_COMV:
260 case BUF_NON_COMV:634 case BUF_NON_COMV:
261 case BUF_LINE:635 case BUF_LINE:
262 case BUF_PERSIST:636 case BUF_PERSIST:
637 return internal_buffer_count(inst, buffer_type);
263 case BUF_SCRATCH_1:638 case BUF_SCRATCH_1:
264 return 1; /* internal buffer count needed by firmware is 1 */639 return 1; /* internal buffer count needed by firmware is 1 */
265 case BUF_DPB:640 case BUF_DPB:
drivers/media/platform/qcom/iris/iris_vpu_buffer.h+43−3
@@ -13,6 +13,10 @@ struct iris_inst; · 12 unmodified lines
13#define DMA_ALIGNMENT 25613#define DMA_ALIGNMENT 256
14 14
15#define NUM_HW_PIC_BUF 3215#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
16#define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf))20#define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf))
17 21
18#define MAX_TILE_COLUMNS 3222#define MAX_TILE_COLUMNS 32
@@ -28,11 +32,47 @@ struct iris_inst; · 9 unmodified lines
28#define SIZE_SLIST_BUF_H264 51232#define SIZE_SLIST_BUF_H264 512
29#define H264_DISPLAY_BUF_SIZE 332833#define H264_DISPLAY_BUF_SIZE 3328
30#define H264_NUM_FRM_INFO 6634#define H264_NUM_FRM_INFO 66
31 35#define H265_NUM_TILE_COL 32
32#define SIZE_SEI_USERDATA 409636#define H265_NUM_TILE_ROW 128
33 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)
34#define H264_CABAC_HDR_RATIO_HD_TOT 161#define H264_CABAC_HDR_RATIO_HD_TOT 1
35#define H264_CABAC_RES_RATIO_HD_TOT 362#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
36#define SIZE_H264D_HW_PIC_T (BIT(11))76#define SIZE_H264D_HW_PIC_T (BIT(11))
37 77
38#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 6478#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
424 INIT_DELAYED_WORK(&core->work, venus_sys_error_handler);424 INIT_DELAYED_WORK(&core->work, venus_sys_error_handler);
425 init_waitqueue_head(&core->sys_err_done);425 init_waitqueue_head(&core->sys_err_done);
426 426
427 ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, venus_isr_thread,427 ret = hfi_create(core, &venus_core_ops);
428 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
429 "venus", core);
430 if (ret)428 if (ret)
431 goto err_core_put;429 goto err_core_put;
432 430
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);
434 if (ret)434 if (ret)
435 goto err_core_put;435 goto err_core_put;
436 436
@@ -709,11 +709,11 @@ static const struct venus_resources msm8996_res = { · 272 unmodified lines
709};709};
710 710
711static const struct freq_tbl msm8998_freq_table[] = {711static const struct freq_tbl msm8998_freq_table[] = {
712 { 1944000, 465000000 }, /* 4k UHD @ 60 (decode only) */712 { 1728000, 533000000 }, /* 4k UHD @ 60 (decode only) */
713 { 972000, 465000000 }, /* 4k UHD @ 30 */713 { 1036800, 444000000 }, /* 2k @ 120 */
714 { 489600, 360000000 }, /* 1080p @ 60 */714 { 829440, 355200000 }, /* 4k @ 44 */
715 { 244800, 186000000 }, /* 1080p @ 30 */715 { 489600, 269330000 },/* 4k @ 30 */
716 { 108000, 100000000 }, /* 720p @ 30 */716 { 108000, 200000000 }, /* 1080p @ 60 */
717};717};
718 718
719static const struct reg_val msm8998_reg_preset[] = {719static const struct reg_val msm8998_reg_preset[] = {
drivers/media/platform/qcom/venus/core.h+2−0
@@ -28,6 +28,8 @@ · 27 unmodified lines
28#define VIDC_RESETS_NUM_MAX 228#define VIDC_RESETS_NUM_MAX 2
29#define VIDC_MAX_HIER_CODING_LAYER 629#define VIDC_MAX_HIER_CODING_LAYER 6
30 30
31#define VENUS_MAX_FPS 240
32
31extern int venus_fw_debug;33extern int venus_fw_debug;
32 34
33struct freq_tbl {35struct 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
33 struct hfi_buffer_requirements *bufreq;33 struct hfi_buffer_requirements *bufreq;
34 struct hfi_extradata_input_crop *crop;34 struct hfi_extradata_input_crop *crop;
35 struct hfi_dpb_counts *dpb_count;35 struct hfi_dpb_counts *dpb_count;
36 u32 ptype, rem_bytes;
37 u32 size_read = 0;
36 u8 *data_ptr;38 u8 *data_ptr;
37 u32 ptype;
38 39
39 inst->error = HFI_ERR_NONE;40 inst->error = HFI_ERR_NONE;
40 41
@@ -44,86 +45,118 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst, · 3 unmodified lines
44 break;45 break;
45 default:46 default:
46 inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;47 inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;
47 goto done;48 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
49 return;
48 }50 }
49 51
50 event.event_type = pkt->event_data1;52 event.event_type = pkt->event_data1;
51 53
52 num_properties_changed = pkt->event_data2;54 num_properties_changed = pkt->event_data2;
53 if (!num_properties_changed) {55 if (!num_properties_changed)
54 inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;56 goto error;
55 goto done;
56 }
57 57
58 data_ptr = (u8 *)&pkt->ext_event_data[0];58 data_ptr = (u8 *)&pkt->ext_event_data[0];
59 rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
60
59 do {61 do {
62 if (rem_bytes < sizeof(u32))
63 goto error;
60 ptype = *((u32 *)data_ptr);64 ptype = *((u32 *)data_ptr);
65
66 data_ptr += sizeof(u32);
67 rem_bytes -= sizeof(u32);
68
61 switch (ptype) {69 switch (ptype) {
62 case HFI_PROPERTY_PARAM_FRAME_SIZE:70 case HFI_PROPERTY_PARAM_FRAME_SIZE:
63 data_ptr += sizeof(u32);71 if (rem_bytes < sizeof(struct hfi_framesize))
72 goto error;
73
64 frame_sz = (struct hfi_framesize *)data_ptr;74 frame_sz = (struct hfi_framesize *)data_ptr;
65 event.width = frame_sz->width;75 event.width = frame_sz->width;
66 event.height = frame_sz->height;76 event.height = frame_sz->height;
67 data_ptr += sizeof(*frame_sz);77 size_read = sizeof(struct hfi_framesize);
68 break;78 break;
69 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:79 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
71 profile_level = (struct hfi_profile_level *)data_ptr;83 profile_level = (struct hfi_profile_level *)data_ptr;
72 event.profile = profile_level->profile;84 event.profile = profile_level->profile;
73 event.level = profile_level->level;85 event.level = profile_level->level;
74 data_ptr += sizeof(*profile_level);86 size_read = sizeof(struct hfi_profile_level);
75 break;87 break;
76 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:88 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
78 pixel_depth = (struct hfi_bit_depth *)data_ptr;92 pixel_depth = (struct hfi_bit_depth *)data_ptr;
79 event.bit_depth = pixel_depth->bit_depth;93 event.bit_depth = pixel_depth->bit_depth;
80 data_ptr += sizeof(*pixel_depth);94 size_read = sizeof(struct hfi_bit_depth);
81 break;95 break;
82 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:96 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
84 pic_struct = (struct hfi_pic_struct *)data_ptr;100 pic_struct = (struct hfi_pic_struct *)data_ptr;
85 event.pic_struct = pic_struct->progressive_only;101 event.pic_struct = pic_struct->progressive_only;
86 data_ptr += sizeof(*pic_struct);102 size_read = sizeof(struct hfi_pic_struct);
87 break;103 break;
88 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:104 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
90 colour_info = (struct hfi_colour_space *)data_ptr;108 colour_info = (struct hfi_colour_space *)data_ptr;
91 event.colour_space = colour_info->colour_space;109 event.colour_space = colour_info->colour_space;
92 data_ptr += sizeof(*colour_info);110 size_read = sizeof(struct hfi_colour_space);
93 break;111 break;
94 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:112 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
95 data_ptr += sizeof(u32);113 if (rem_bytes < sizeof(u32))
114 goto error;
115
96 event.entropy_mode = *(u32 *)data_ptr;116 event.entropy_mode = *(u32 *)data_ptr;
97 data_ptr += sizeof(u32);117 size_read = sizeof(u32);
98 break;118 break;
99 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:119 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
100 data_ptr += sizeof(u32);120 if (rem_bytes < sizeof(struct hfi_buffer_requirements))
121 goto error;
122
101 bufreq = (struct hfi_buffer_requirements *)data_ptr;123 bufreq = (struct hfi_buffer_requirements *)data_ptr;
102 event.buf_count = hfi_bufreq_get_count_min(bufreq, ver);124 event.buf_count = hfi_bufreq_get_count_min(bufreq, ver);
103 data_ptr += sizeof(*bufreq);125 size_read = sizeof(struct hfi_buffer_requirements);
104 break;126 break;
105 case HFI_INDEX_EXTRADATA_INPUT_CROP:127 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
107 crop = (struct hfi_extradata_input_crop *)data_ptr;131 crop = (struct hfi_extradata_input_crop *)data_ptr;
108 event.input_crop.left = crop->left;132 event.input_crop.left = crop->left;
109 event.input_crop.top = crop->top;133 event.input_crop.top = crop->top;
110 event.input_crop.width = crop->width;134 event.input_crop.width = crop->width;
111 event.input_crop.height = crop->height;135 event.input_crop.height = crop->height;
112 data_ptr += sizeof(*crop);136 size_read = sizeof(struct hfi_extradata_input_crop);
113 break;137 break;
114 case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:138 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
116 dpb_count = (struct hfi_dpb_counts *)data_ptr;142 dpb_count = (struct hfi_dpb_counts *)data_ptr;
117 event.buf_count = dpb_count->fw_min_cnt;143 event.buf_count = dpb_count->fw_min_cnt;
118 data_ptr += sizeof(*dpb_count);144 size_read = sizeof(struct hfi_dpb_counts);
119 break;145 break;
120 default:146 default:
147 size_read = 0;
121 break;148 break;
122 }149 }
150 data_ptr += size_read;
151 rem_bytes -= size_read;
123 num_properties_changed--;152 num_properties_changed--;
124 } while (num_properties_changed > 0);153 } while (num_properties_changed > 0);
125 154
126done:155 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
156 return;
157
158error:
159 inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
127 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);160 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
128}161}
129 162
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
239static int venus_read_queue(struct venus_hfi_device *hdev,239static int venus_read_queue(struct venus_hfi_device *hdev,
240 struct iface_queue *queue, void *pkt, u32 *tx_req)240 struct iface_queue *queue, void *pkt, u32 *tx_req)
241{241{
242 struct hfi_pkt_hdr *pkt_hdr = NULL;
242 struct hfi_queue_header *qhdr;243 struct hfi_queue_header *qhdr;
243 u32 dwords, new_rd_idx;244 u32 dwords, new_rd_idx;
244 u32 rd_idx, wr_idx, type, qsize;245 u32 rd_idx, wr_idx, type, qsize;
@@ -304,6 +305,9 @@ static int venus_read_queue(struct venus_hfi_device *hdev, · 59 unmodified lines
304 memcpy(pkt, rd_ptr, len);305 memcpy(pkt, rd_ptr, len);
305 memcpy(pkt + len, queue->qmem.kva, new_rd_idx << 2);306 memcpy(pkt + len, queue->qmem.kva, new_rd_idx << 2);
306 }307 }
308 pkt_hdr = (struct hfi_pkt_hdr *)(pkt);
309 if ((pkt_hdr->size >> 2) != dwords)
310 return -EINVAL;
307 } else {311 } else {
308 /* bad packet received, dropping */312 /* bad packet received, dropping */
309 new_rd_idx = qhdr->write_idx;313 new_rd_idx = qhdr->write_idx;
@@ -1678,6 +1682,7 @@ void venus_hfi_destroy(struct venus_core *core) · 1368 unmodified lines
1678 venus_interface_queues_release(hdev);1682 venus_interface_queues_release(hdev);
1679 mutex_destroy(&hdev->lock);1683 mutex_destroy(&hdev->lock);
1680 kfree(hdev);1684 kfree(hdev);
1685 disable_irq(core->irq);
1681 core->ops = NULL;1686 core->ops = NULL;
1682}1687}
1683 1688
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
41static int core_clks_enable(struct venus_core *core)41static int core_clks_enable(struct venus_core *core)
42{42{
43 const struct venus_resources *res = core->res;43 const struct venus_resources *res = core->res;
44 const struct freq_tbl *freq_tbl = core->res->freq_tbl;44 struct device *dev = core->dev;
45 unsigned int freq_tbl_size = core->res->freq_tbl_size;45 unsigned long freq = 0;
46 unsigned long freq;46 struct dev_pm_opp *opp;
47 unsigned int i;47 unsigned int i;
48 int ret;48 int ret;
49 49
50 if (!freq_tbl)50 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
51 return -EINVAL;51 dev_pm_opp_put(opp);
52
53 freq = freq_tbl[freq_tbl_size - 1].freq;
54 52
55 for (i = 0; i < res->clks_num; i++) {53 for (i = 0; i < res->clks_num; i++) {
56 if (IS_V6(core)) {54 if (IS_V6(core)) {
@@ -636,7 +634,9 @@ static int decide_core(struct venus_inst *inst) · 579 unmodified lines
636 u32 min_coreid, min_load, cur_inst_load;634 u32 min_coreid, min_load, cur_inst_load;
637 u32 min_lp_coreid, min_lp_load, cur_inst_lp_load;635 u32 min_lp_coreid, min_lp_load, cur_inst_lp_load;
638 struct hfi_videocores_usage_type cu;636 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;
640 int ret = 0;640 int ret = 0;
641 641
642 if (legacy_binding) {642 if (legacy_binding) {
@@ -659,7 +659,8 @@ static int decide_core(struct venus_inst *inst) · 16 unmodified lines
659 cur_inst_lp_load *= inst->clk_data.low_power_freq;659 cur_inst_lp_load *= inst->clk_data.low_power_freq;
660 /*TODO : divide this inst->load by work_route */660 /*TODO : divide this inst->load by work_route */
661 661
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);
663 664
664 min_loaded_core(inst, &min_coreid, &min_load, false);665 min_loaded_core(inst, &min_coreid, &min_load, false);
665 min_loaded_core(inst, &min_lp_coreid, &min_lp_load, true);666 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
949static int core_get_v4(struct venus_core *core)950static int core_get_v4(struct venus_core *core)
950{951{
951 struct device *dev = core->dev;952 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;
952 const struct venus_resources *res = core->res;955 const struct venus_resources *res = core->res;
956 unsigned int i;
953 int ret;957 int ret;
954 958
955 ret = core_clks_get(core);959 ret = core_clks_get(core);
@@ -986,9 +990,17 @@ static int core_get_v4(struct venus_core *core) · 30 unmodified lines
986 990
987 if (core->res->opp_pmdomain) {991 if (core->res->opp_pmdomain) {
988 ret = devm_pm_opp_of_add_table(dev);992 ret = devm_pm_opp_of_add_table(dev);
989 if (ret && ret != -ENODEV) {993 if (ret) {
990 dev_err(dev, "invalid OPP table in device tree\n");994 if (ret == -ENODEV) {
991 return ret;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 }
992 }1004 }
993 }1005 }
994 1006
@@ -1078,11 +1090,11 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst, · 83 unmodified lines
1078static int load_scale_v4(struct venus_inst *inst)1090static int load_scale_v4(struct venus_inst *inst)
1079{1091{
1080 struct venus_core *core = inst->core;1092 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;
1083 struct device *dev = core->dev;1093 struct device *dev = core->dev;
1084 unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;1094 unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0;
1095 unsigned long max_freq = ULONG_MAX;
1085 unsigned long filled_len = 0;1096 unsigned long filled_len = 0;
1097 struct dev_pm_opp *opp;
1086 int i, ret = 0;1098 int i, ret = 0;
1087 1099
1088 for (i = 0; i < inst->num_input_bufs; i++)1100 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
1108 1120
1109 freq = max(freq_core1, freq_core2);1121 freq = max(freq_core1, freq_core2);
1110 1122
1111 if (freq > table[0].freq) {1123 opp = dev_pm_opp_find_freq_floor(dev, &max_freq);
1112 dev_dbg(dev, VDBGL "requested clock rate: %lu scaling clock rate : %lu\n",1124 dev_pm_opp_put(opp);
1113 freq, table[0].freq);
1114 1125
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;
1116 goto set_freq;1130 goto set_freq;
1117 }1131 }
1118 1132
1119 for (i = num_rows - 1 ; i >= 0; i--) {1133 opp = dev_pm_opp_find_freq_ceil(dev, &freq);
1120 if (freq <= table[i].freq) {1134 dev_pm_opp_put(opp);
1121 freq = table[i].freq;
1122 break;
1123 }
1124 }
1125 1135
1126set_freq:1136set_freq:
1127 1137
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
481 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;481 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
482 do_div(us_per_frame, timeperframe->denominator);482 do_div(us_per_frame, timeperframe->denominator);
483 483
484 if (!us_per_frame)484 us_per_frame = clamp(us_per_frame, 1, USEC_PER_SEC);
485 return -EINVAL;485 fps = USEC_PER_SEC / (u32)us_per_frame;
486 486 fps = min(VENUS_MAX_FPS, fps);
487 fps = (u64)USEC_PER_SEC;
488 do_div(fps, us_per_frame);
489 487
490 inst->fps = fps;488 inst->fps = fps;
491 inst->timeperframe = *timeperframe;489 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
411 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;411 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
412 do_div(us_per_frame, timeperframe->denominator);412 do_div(us_per_frame, timeperframe->denominator);
413 413
414 if (!us_per_frame)414 us_per_frame = clamp(us_per_frame, 1, USEC_PER_SEC);
415 return -EINVAL;415 fps = USEC_PER_SEC / (u32)us_per_frame;
416 416 fps = min(VENUS_MAX_FPS, fps);
417 fps = (u64)USEC_PER_SEC;
418 do_div(fps, us_per_frame);
419 417
420 inst->timeperframe = *timeperframe;418 inst->timeperframe = *timeperframe;
421 inst->fps = fps;419 inst->fps = fps;
drivers/media/platform/raspberrypi/pisp_be/Kconfig+1−0
@@ -3,6 +3,7 @@ config VIDEO_RASPBERRYPI_PISP_BE · 2 unmodified lines
3 depends on V4L_PLATFORM_DRIVERS3 depends on V4L_PLATFORM_DRIVERS
4 depends on VIDEO_DEV4 depends on VIDEO_DEV
5 depends on ARCH_BCM2835 || COMPILE_TEST5 depends on ARCH_BCM2835 || COMPILE_TEST
6 depends on PM
6 select VIDEO_V4L2_SUBDEV_API7 select VIDEO_V4L2_SUBDEV_API
7 select MEDIA_CONTROLLER8 select MEDIA_CONTROLLER
8 select VIDEOBUF2_DMA_CONTIG9 select VIDEOBUF2_DMA_CONTIG
drivers/media/platform/raspberrypi/pisp_be/pisp_be.c+104−103
@@ -9,9 +9,11 @@ · 8 unmodified lines
9#include <linux/io.h>9#include <linux/io.h>
10#include <linux/kernel.h>10#include <linux/kernel.h>
11#include <linux/lockdep.h>11#include <linux/lockdep.h>
12#include <linux/minmax.h>
12#include <linux/module.h>13#include <linux/module.h>
13#include <linux/platform_device.h>14#include <linux/platform_device.h>
14#include <linux/pm_runtime.h>15#include <linux/pm_runtime.h>
16#include <linux/slab.h>
15#include <media/v4l2-device.h>17#include <media/v4l2-device.h>
16#include <media/v4l2-ioctl.h>18#include <media/v4l2-ioctl.h>
17#include <media/videobuf2-dma-contig.h>19#include <media/videobuf2-dma-contig.h>
@@ -161,8 +163,6 @@ struct pispbe_node { · 143 unmodified lines
161 struct mutex node_lock;163 struct mutex node_lock;
162 /* vb2_queue lock */164 /* vb2_queue lock */
163 struct mutex queue_lock;165 struct mutex queue_lock;
164 /* Protect pispbe_node->ready_queue and pispbe_buffer->ready_list */
165 spinlock_t ready_lock;
166 struct list_head ready_queue;166 struct list_head ready_queue;
167 struct vb2_queue queue;167 struct vb2_queue queue;
168 struct v4l2_format format;168 struct v4l2_format format;
@@ -190,6 +190,8 @@ struct pispbe_hw_enables { · 21 unmodified lines
190 190
191/* Records a job configuration and memory addresses. */191/* Records a job configuration and memory addresses. */
192struct pispbe_job_descriptor {192struct pispbe_job_descriptor {
193 struct list_head queue;
194 struct pispbe_buffer *buffers[PISPBE_NUM_NODES];
193 dma_addr_t hw_dma_addrs[N_HW_ADDRESSES];195 dma_addr_t hw_dma_addrs[N_HW_ADDRESSES];
194 struct pisp_be_tiles_config *config;196 struct pisp_be_tiles_config *config;
195 struct pispbe_hw_enables hw_enables;197 struct pispbe_hw_enables hw_enables;
@@ -215,8 +217,10 @@ struct pispbe_dev { · 19 unmodified lines
215 unsigned int sequence;217 unsigned int sequence;
216 u32 streaming_map;218 u32 streaming_map;
217 struct pispbe_job queued_job, running_job;219 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;
219 bool hw_busy; /* non-zero if a job is queued or is being started */222 bool hw_busy; /* non-zero if a job is queued or is being started */
223 struct list_head job_queue;
220 int irq;224 int irq;
221 u32 hw_version;225 u32 hw_version;
222 u8 done, started;226 u8 done, started;
@@ -368,10 +372,7 @@ static void pispbe_xlate_addrs(struct pispbe_dev *pispbe, · 145 unmodified lines
368 ret = pispbe_get_planes_addr(addrs, buf[MAIN_INPUT_NODE],372 ret = pispbe_get_planes_addr(addrs, buf[MAIN_INPUT_NODE],
369 &pispbe->node[MAIN_INPUT_NODE]);373 &pispbe->node[MAIN_INPUT_NODE]);
370 if (ret <= 0) {374 if (ret <= 0) {
371 /*375 /* Shouldn't happen, we have validated an input is available. */
372 * This shouldn't happen; pispbe_schedule_internal should insist
373 * on an input.
374 */
375 dev_warn(pispbe->dev, "ISP-BE missing input\n");376 dev_warn(pispbe->dev, "ISP-BE missing input\n");
376 hw_en->bayer_enables = 0;377 hw_en->bayer_enables = 0;
377 hw_en->rgb_enables = 0;378 hw_en->rgb_enables = 0;
@@ -443,42 +444,48 @@ static void pispbe_xlate_addrs(struct pispbe_dev *pispbe, · 65 unmodified lines
443 * For Output0, Output1, Tdn and Stitch, a buffer only needs to be444 * For Output0, Output1, Tdn and Stitch, a buffer only needs to be
444 * available if the blocks are enabled in the config.445 * available if the blocks are enabled in the config.
445 *446 *
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.
447 *449 *
448 * Returns 0 if a job has been successfully prepared, < 0 otherwise.450 * Returns 0 if a job has been successfully prepared, < 0 otherwise.
449 */451 */
450static int pispbe_prepare_job(struct pispbe_dev *pispbe,452static int pispbe_prepare_job(struct pispbe_dev *pispbe)
451 struct pispbe_job_descriptor *job)
452{453{
454 struct pispbe_job_descriptor __free(kfree) *job = NULL;
453 struct pispbe_buffer *buf[PISPBE_NUM_NODES] = {};455 struct pispbe_buffer *buf[PISPBE_NUM_NODES] = {};
456 unsigned int streaming_map;
454 unsigned int config_index;457 unsigned int config_index;
455 struct pispbe_node *node;458 struct pispbe_node *node;
456 unsigned long flags;
457 459
458 lockdep_assert_held(&pispbe->hw_lock);460 lockdep_assert_irqs_enabled();
459 461
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);
461 464
462 if (((BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)) &465 if ((pispbe->streaming_map & mask) != mask)
463 pispbe->streaming_map) !=466 return -ENODEV;
464 (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)))467
465 return -ENODEV;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;
466 478
467 node = &pispbe->node[CONFIG_NODE];479 node = &pispbe->node[CONFIG_NODE];
468 spin_lock_irqsave(&node->ready_lock, flags);
469 buf[CONFIG_NODE] = list_first_entry_or_null(&node->ready_queue,480 buf[CONFIG_NODE] = list_first_entry_or_null(&node->ready_queue,
470 struct pispbe_buffer,481 struct pispbe_buffer,
471 ready_list);482 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. */
479 if (!buf[CONFIG_NODE])483 if (!buf[CONFIG_NODE])
480 return -ENODEV;484 return -ENODEV;
481 485
486 list_del(&buf[CONFIG_NODE]->ready_list);
487 job->buffers[CONFIG_NODE] = buf[CONFIG_NODE];
488
482 config_index = buf[CONFIG_NODE]->vb.vb2_buf.index;489 config_index = buf[CONFIG_NODE]->vb.vb2_buf.index;
483 job->config = &pispbe->config[config_index];490 job->config = &pispbe->config[config_index];
484 job->tiles = pispbe->config_dma_addr +491 job->tiles = pispbe->config_dma_addr +
@@ -498,7 +505,7 @@ static int pispbe_prepare_job(struct pispbe_dev *pispbe, · 13 unmodified lines
498 continue;505 continue;
499 506
500 buf[i] = NULL;507 buf[i] = NULL;
501 if (!(pispbe->streaming_map & BIT(i)))508 if (!(streaming_map & BIT(i)))
502 continue;509 continue;
503 510
504 if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0) &&511 if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0) &&
@@ -525,25 +532,28 @@ static int pispbe_prepare_job(struct pispbe_dev *pispbe, · 20 unmodified lines
525 node = &pispbe->node[i];532 node = &pispbe->node[i];
526 533
527 /* Pull a buffer from each V4L2 queue to form the queued job */534 /* Pull a buffer from each V4L2 queue to form the queued job */
528 spin_lock_irqsave(&node->ready_lock, flags);
529 buf[i] = list_first_entry_or_null(&node->ready_queue,535 buf[i] = list_first_entry_or_null(&node->ready_queue,
530 struct pispbe_buffer,536 struct pispbe_buffer,
531 ready_list);537 ready_list);
532 if (buf[i]) {538 if (buf[i]) {
533 list_del(&buf[i]->ready_list);539 list_del(&buf[i]->ready_list);
534 pispbe->queued_job.buf[i] = buf[i];540 job->buffers[i] = buf[i];
535 }541 }
536 spin_unlock_irqrestore(&node->ready_lock, flags);
537 542
538 if (!buf[i] && !ignore_buffers)543 if (!buf[i] && !ignore_buffers)
539 goto err_return_buffers;544 goto err_return_buffers;
540 }545 }
541 546
542 pispbe->queued_job.valid = true;
543
544 /* Convert buffers to DMA addresses for the hardware */547 /* Convert buffers to DMA addresses for the hardware */
545 pispbe_xlate_addrs(pispbe, job, buf);548 pispbe_xlate_addrs(pispbe, job, buf);
546 549
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
547 return 0;557 return 0;
548 558
549err_return_buffers:559err_return_buffers:
@@ -554,33 +564,37 @@ err_return_buffers: · 4 unmodified lines
554 continue;564 continue;
555 565
556 /* Return the buffer to the ready_list queue */566 /* Return the buffer to the ready_list queue */
557 spin_lock_irqsave(&n->ready_lock, flags);
558 list_add(&buf[i]->ready_list, &n->ready_queue);567 list_add(&buf[i]->ready_list, &n->ready_queue);
559 spin_unlock_irqrestore(&n->ready_lock, flags);
560 }568 }
561 569
562 memset(&pispbe->queued_job, 0, sizeof(pispbe->queued_job));
563
564 return -ENODEV;570 return -ENODEV;
565}571}
566 572
567static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy)573static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy)
568{574{
569 struct pispbe_job_descriptor job;575 struct pispbe_job_descriptor *job;
570 unsigned long flags;
571 int ret;
572 576
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;
574 580
575 if (clear_hw_busy)581 if (pispbe->hw_busy)
576 pispbe->hw_busy = false;582 return;
577 583
578 if (pispbe->hw_busy)584 job = list_first_entry_or_null(&pispbe->job_queue,
579 goto unlock_and_return;585 struct pispbe_job_descriptor,
586 queue);
587 if (!job)
588 return;
580 589
581 ret = pispbe_prepare_job(pispbe, &job);590 list_del(&job->queue);
582 if (ret)591
583 goto unlock_and_return;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 }
584 598
585 /*599 /*
586 * We can kick the job off without the hw_lock, as this can600 * 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
588 * only when the following job has been queued and an interrupt602 * only when the following job has been queued and an interrupt
589 * is rised.603 * is rised.
590 */604 */
591 pispbe->hw_busy = true;605 pispbe_queue_job(pispbe, job);
592 spin_unlock_irqrestore(&pispbe->hw_lock, flags);606 kfree(job);
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
616unlock_and_return:
617 /* No job has been queued, just release the lock and return. */
618 spin_unlock_irqrestore(&pispbe->hw_lock, flags);
619}607}
620 608
621static void pispbe_isr_jobdone(struct pispbe_dev *pispbe,609static 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
706 return -EIO;694 return -EIO;
707 }695 }
708 696
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
709 /* Ensure output config strides and buffer sizes match the V4L2 formats. */704 /* Ensure output config strides and buffer sizes match the V4L2 formats. */
710 fmt = &pispbe->node[TDN_OUTPUT_NODE].format;705 fmt = &pispbe->node[TDN_OUTPUT_NODE].format;
711 if (bayer_enables & PISP_BE_BAYER_ENABLE_TDN_OUTPUT) {706 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
860 container_of(vbuf, struct pispbe_buffer, vb);855 container_of(vbuf, struct pispbe_buffer, vb);
861 struct pispbe_node *node = vb2_get_drv_priv(buf->vb2_queue);856 struct pispbe_node *node = vb2_get_drv_priv(buf->vb2_queue);
862 struct pispbe_dev *pispbe = node->pispbe;857 struct pispbe_dev *pispbe = node->pispbe;
863 unsigned long flags;
864 858
865 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));859 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
866 spin_lock_irqsave(&node->ready_lock, flags);
867 list_add_tail(&buffer->ready_list, &node->ready_queue);860 list_add_tail(&buffer->ready_list, &node->ready_queue);
868 spin_unlock_irqrestore(&node->ready_lock, flags);
869 861
870 /*862 /*
871 * Every time we add a buffer, check if there's now some work for the hw863 * Every time we add a buffer, check if there's now some work for the hw
872 * to do.864 * to do.
873 */865 */
874 pispbe_schedule(pispbe, false);866 if (!pispbe_prepare_job(pispbe))
867 pispbe_schedule(pispbe, false);
875}868}
876 869
877static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count)870static 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
879 struct pispbe_node *node = vb2_get_drv_priv(q);872 struct pispbe_node *node = vb2_get_drv_priv(q);
880 struct pispbe_dev *pispbe = node->pispbe;873 struct pispbe_dev *pispbe = node->pispbe;
881 struct pispbe_buffer *buf, *tmp;874 struct pispbe_buffer *buf, *tmp;
882 unsigned long flags;
883 int ret;875 int ret;
884 876
885 ret = pm_runtime_resume_and_get(pispbe->dev);877 ret = pm_runtime_resume_and_get(pispbe->dev);
886 if (ret < 0)878 if (ret < 0)
887 goto err_return_buffers;879 goto err_return_buffers;
888 880
889 spin_lock_irqsave(&pispbe->hw_lock, flags);881 scoped_guard(spinlock_irq, &pispbe->hw_lock) {
890 node->pispbe->streaming_map |= BIT(node->id);882 node->pispbe->streaming_map |= BIT(node->id);
891 node->pispbe->sequence = 0;883 node->pispbe->sequence = 0;
892 spin_unlock_irqrestore(&pispbe->hw_lock, flags);884 }
893 885
894 dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n",886 dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n",
895 __func__, NODE_NAME(node), count);887 __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
897 node->pispbe->streaming_map);889 node->pispbe->streaming_map);
898 890
899 /* Maybe we're ready to run. */891 /* Maybe we're ready to run. */
900 pispbe_schedule(pispbe, false);892 if (!pispbe_prepare_job(pispbe))
893 pispbe_schedule(pispbe, false);
901 894
902 return 0;895 return 0;
903 896
904err_return_buffers:897err_return_buffers:
905 spin_lock_irqsave(&pispbe->hw_lock, flags);
906 list_for_each_entry_safe(buf, tmp, &node->ready_queue, ready_list) {898 list_for_each_entry_safe(buf, tmp, &node->ready_queue, ready_list) {
907 list_del(&buf->ready_list);899 list_del(&buf->ready_list);
908 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);900 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
909 }901 }
910 spin_unlock_irqrestore(&pispbe->hw_lock, flags);
911 902
912 return ret;903 return ret;
913}904}
@@ -916,8 +907,9 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q) · 2 unmodified lines
916{907{
917 struct pispbe_node *node = vb2_get_drv_priv(q);908 struct pispbe_node *node = vb2_get_drv_priv(q);
918 struct pispbe_dev *pispbe = node->pispbe;909 struct pispbe_dev *pispbe = node->pispbe;
910 struct pispbe_job_descriptor *job, *temp;
919 struct pispbe_buffer *buf;911 struct pispbe_buffer *buf;
920 unsigned long flags;912 LIST_HEAD(tmp_list);
921 913
922 /*914 /*
923 * Now this is a bit awkward. In a simple M2M device we could just wait915 * 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
929 * This may return buffers out of order.921 * This may return buffers out of order.
930 */922 */
931 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));923 dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
932 spin_lock_irqsave(&pispbe->hw_lock, flags);
933 do {924 do {
934 unsigned long flags1;
935
936 spin_lock_irqsave(&node->ready_lock, flags1);
937 buf = list_first_entry_or_null(&node->ready_queue,925 buf = list_first_entry_or_null(&node->ready_queue,
938 struct pispbe_buffer,926 struct pispbe_buffer,
939 ready_list);927 ready_list);
@@ -941,15 +929,26 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q) · 1 unmodified line
941 list_del(&buf->ready_list);929 list_del(&buf->ready_list);
942 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);930 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
943 }931 }
944 spin_unlock_irqrestore(&node->ready_lock, flags1);
945 } while (buf);932 } while (buf);
946 spin_unlock_irqrestore(&pispbe->hw_lock, flags);
947 933
948 vb2_wait_for_all_buffers(&node->queue);934 vb2_wait_for_all_buffers(&node->queue);
949 935
950 spin_lock_irqsave(&pispbe->hw_lock, flags);936 spin_lock_irq(&pispbe->hw_lock);
951 pispbe->streaming_map &= ~BIT(node->id);937 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 }
953 952
954 pm_runtime_mark_last_busy(pispbe->dev);953 pm_runtime_mark_last_busy(pispbe->dev);
955 pm_runtime_put_autosuspend(pispbe->dev);954 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
1114 f->fmt.pix_mp.pixelformat = fmt->fourcc;1113 f->fmt.pix_mp.pixelformat = fmt->fourcc;
1115 f->fmt.pix_mp.num_planes = fmt->num_planes;1114 f->fmt.pix_mp.num_planes = fmt->num_planes;
1116 f->fmt.pix_mp.field = V4L2_FIELD_NONE;1115 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
1117 f->fmt.pix_mp.width = max(min(f->fmt.pix_mp.width, 65536u),1116 f->fmt.pix_mp.width = clamp(f->fmt.pix_mp.width,
1118 PISP_BACK_END_MIN_TILE_WIDTH);1117 PISP_BACK_END_MIN_TILE_WIDTH,
1119 f->fmt.pix_mp.height = max(min(f->fmt.pix_mp.height, 65536u),1118 PISP_BACK_END_MAX_TILE_WIDTH);
1120 PISP_BACK_END_MIN_TILE_HEIGHT);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);
1121 1122
1122 /*1123 /*
1123 * Fill in the actual colour space when the requested one was1124 * 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
1407 mutex_init(&node->node_lock);1408 mutex_init(&node->node_lock);
1408 mutex_init(&node->queue_lock);1409 mutex_init(&node->queue_lock);
1409 INIT_LIST_HEAD(&node->ready_queue);1410 INIT_LIST_HEAD(&node->ready_queue);
1410 spin_lock_init(&node->ready_lock);
1411 1411
1412 node->format.type = node->buf_type;1412 node->format.type = node->buf_type;
1413 pispbe_node_def_fmt(node);1413 pispbe_node_def_fmt(node);
@@ -1691,6 +1691,8 @@ static int pispbe_probe(struct platform_device *pdev) · 277 unmodified lines
1691 if (!pispbe)1691 if (!pispbe)
1692 return -ENOMEM;1692 return -ENOMEM;
1693 1693
1694 INIT_LIST_HEAD(&pispbe->job_queue);
1695
1694 dev_set_drvdata(&pdev->dev, pispbe);1696 dev_set_drvdata(&pdev->dev, pispbe);
1695 pispbe->dev = &pdev->dev;1697 pispbe->dev = &pdev->dev;
1696 platform_set_drvdata(pdev, pispbe);1698 platform_set_drvdata(pdev, pispbe);
@@ -1726,7 +1728,7 @@ static int pispbe_probe(struct platform_device *pdev) · 29 unmodified lines
1726 pm_runtime_use_autosuspend(pispbe->dev);1728 pm_runtime_use_autosuspend(pispbe->dev);
1727 pm_runtime_enable(pispbe->dev);1729 pm_runtime_enable(pispbe->dev);
1728 1730
1729 ret = pispbe_runtime_resume(pispbe->dev);1731 ret = pm_runtime_resume_and_get(pispbe->dev);
1730 if (ret)1732 if (ret)
1731 goto pm_runtime_disable_err;1733 goto pm_runtime_disable_err;
1732 1734
@@ -1748,7 +1750,7 @@ static int pispbe_probe(struct platform_device *pdev) · 15 unmodified lines
1748disable_devs_err:1750disable_devs_err:
1749 pispbe_destroy_devices(pispbe);1751 pispbe_destroy_devices(pispbe);
1750pm_runtime_suspend_err:1752pm_runtime_suspend_err:
1751 pispbe_runtime_suspend(pispbe->dev);1753 pm_runtime_put(pispbe->dev);
1752pm_runtime_disable_err:1754pm_runtime_disable_err:
1753 pm_runtime_dont_use_autosuspend(pispbe->dev);1755 pm_runtime_dont_use_autosuspend(pispbe->dev);
1754 pm_runtime_disable(pispbe->dev);1756 pm_runtime_disable(pispbe->dev);
@@ -1762,7 +1764,6 @@ static void pispbe_remove(struct platform_device *pdev) · 7 unmodified lines
1762 1764
1763 pispbe_destroy_devices(pispbe);1765 pispbe_destroy_devices(pispbe);
1764 1766
1765 pispbe_runtime_suspend(pispbe->dev);
1766 pm_runtime_dont_use_autosuspend(pispbe->dev);1767 pm_runtime_dont_use_autosuspend(pispbe->dev);
1767 pm_runtime_disable(pispbe->dev);1768 pm_runtime_disable(pispbe->dev);
1768}1769}
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
1024 cfe_dbg(cfe, "%s: [%s] type:%u\n", __func__, node_desc[node->id].name,1024 cfe_dbg(cfe, "%s: [%s] type:%u\n", __func__, node_desc[node->id].name,
1025 node->buffer_queue.type);1025 node->buffer_queue.type);
1026 1026
1027 if (vq->max_num_buffers + *nbuffers < 3)
1028 *nbuffers = 3 - vq->max_num_buffers;
1029
1030 if (*nplanes) {1027 if (*nplanes) {
1031 if (sizes[0] < size) {1028 if (sizes[0] < size) {
1032 cfe_err(cfe, "sizes[0] %i < size %u\n", sizes[0], size);1029 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
1998 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;1995 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1999 q->lock = &node->lock;1996 q->lock = &node->lock;
2000 q->min_queued_buffers = 1;1997 q->min_queued_buffers = 1;
1998 q->min_reqbufs_allocation = 3;
2001 q->dev = &cfe->pdev->dev;1999 q->dev = &cfe->pdev->dev;
2002 2000
2003 ret = vb2_queue_init(q);2001 ret = vb2_queue_init(q);
drivers/media/platform/renesas/rcar-csi2.c+290−46
@@ -172,20 +172,27 @@ struct rcar_csi2; · 171 unmodified lines
172#define V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG 0x21c0a172#define V4H_PPI_RW_LPDCOCAL_TWAIT_CONFIG_REG 0x21c0a
173#define V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG 0x21c0c173#define V4H_PPI_RW_LPDCOCAL_VT_CONFIG_REG 0x21c0c
174#define V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG 0x21c10174#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 */
175#define V4H_PPI_RW_COMMON_CFG_REG 0x21c6c176#define V4H_PPI_RW_COMMON_CFG_REG 0x21c6c
176#define V4H_PPI_RW_TERMCAL_CFG_0_REG 0x21c80177#define V4H_PPI_RW_TERMCAL_CFG_0_REG 0x21c80
177#define V4H_PPI_RW_OFFSETCAL_CFG_0_REG 0x21ca0178#define V4H_PPI_RW_OFFSETCAL_CFG_0_REG 0x21ca0
178 179
179/* V4H CORE registers */180/* V4H CORE registers */
180#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(n) (0x22040 + ((n) * 2)) /* n = 0 - 15 */181
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_LANEl_CTRL_2_REG(l, n) (0x22040 + ((l) * 0x400) + ((n) * 2))
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_LANEl_CTRL_3_REG(l, n) (0x22060 + ((l) * 0x400) + ((n) * 2))
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_LANEl_CTRL_4_REG(l, n) (0x22080 + ((l) * 0x400) + ((n) * 2))
184#define V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(n) (0x23040 + ((n) * 2)) /* n = 0 - 15 */185
185#define V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(n) (0x23840 + ((n) * 2)) /* n = 0 - 11 */186#define V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(n) (0x23840 + ((n) * 2)) /* n = 0 - 11 */
186#define V4H_CORE_DIG_RW_COMMON_REG(n) (0x23880 + ((n) * 2)) /* n = 0 - 15 */187#define V4H_CORE_DIG_RW_COMMON_REG(n) (0x23880 + ((n) * 2)) /* n = 0 - 15 */
187#define V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(n) (0x239e0 + ((n) * 2)) /* n = 0 - 3 */188#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 0x2a60c189#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))
189 196
190/* V4H C-PHY */197/* V4H C-PHY */
191#define V4H_CORE_DIG_RW_TRIO0_REG(n) (0x22100 + ((n) * 2)) /* n = 0 - 3 */198#define V4H_CORE_DIG_RW_TRIO0_REG(n) (0x22100 + ((n) * 2)) /* n = 0 - 3 */
@@ -197,6 +204,7 @@ struct rcar_csi2; · 5 unmodified lines
197#define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400204#define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400
198#define V4H_CORE_DIG_CLANE_1_RW_LP_0_REG 0x2a480205#define V4H_CORE_DIG_CLANE_1_RW_LP_0_REG 0x2a480
199#define V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(n) (0x2a500 + ((n) * 2)) /* n = 0 - 6 */206#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
200#define V4H_CORE_DIG_CLANE_2_RW_CFG_0_REG 0x2a800208#define V4H_CORE_DIG_CLANE_2_RW_CFG_0_REG 0x2a800
201#define V4H_CORE_DIG_CLANE_2_RW_LP_0_REG 0x2a880209#define V4H_CORE_DIG_CLANE_2_RW_LP_0_REG 0x2a880
202#define V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(n) (0x2a900 + ((n) * 2)) /* n = 0 - 6 */210#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
954static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp,962static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp,
955 unsigned int lanes)963 unsigned int lanes)
956{964{
965 struct media_pad *remote_pad;
957 struct v4l2_subdev *source;966 struct v4l2_subdev *source;
958 s64 freq;967 s64 freq;
959 u64 mbps;968 u64 mbps;
@@ -962,8 +971,9 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, · 2 unmodified lines
962 return -ENODEV;971 return -ENODEV;
963 972
964 source = priv->remote;973 source = priv->remote;
974 remote_pad = &source->entity.pads[priv->remote_pad];
965 975
966 freq = v4l2_get_link_freq(source->ctrl_handler, bpp, 2 * lanes);976 freq = v4l2_get_link_freq(remote_pad, bpp, 2 * lanes);
967 if (freq < 0) {977 if (freq < 0) {
968 int ret = (int)freq;978 int ret = (int)freq;
969 979
@@ -975,10 +985,6 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, · 5 unmodified lines
975 985
976 mbps = div_u64(freq * 2, MEGA);986 mbps = div_u64(freq * 2, MEGA);
977 987
978 /* Adjust for C-PHY, divide by 2.8. */
979 if (priv->cphy)
980 mbps = div_u64(mbps * 5, 14);
981
982 return mbps;988 return mbps;
983}989}
984 990
@@ -1203,9 +1209,14 @@ static int rcsi2_wait_phy_start_v4h(struct rcar_csi2 *priv, u32 match) · 218 unmodified lines
1203 return -ETIMEDOUT;1209 return -ETIMEDOUT;
1204}1210}
1205 1211
1206static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps)1212static const struct rcsi2_cphy_setting *
1213rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int mbps)
1207{1214{
1208 const struct rcsi2_cphy_setting *conf;1215 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);
1209 1220
1210 for (conf = cphy_setting_table_r8a779g0; conf->msps != 0; conf++) {1221 for (conf = cphy_setting_table_r8a779g0; conf->msps != 0; conf++) {
1211 if (conf->msps > msps)1222 if (conf->msps > msps)
@@ -1214,7 +1225,7 @@ static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) · 2 unmodified lines
1214 1225
1215 if (!conf->msps) {1226 if (!conf->msps) {
1216 dev_err(priv->dev, "Unsupported PHY speed for msps setting (%u Msps)", msps);1227 dev_err(priv->dev, "Unsupported PHY speed for msps setting (%u Msps)", msps);
1217 return -ERANGE;1228 return NULL;
1218 }1229 }
1219 1230
1220 /* C-PHY specific */1231 /* C-PHY specific */
@@ -1246,11 +1257,11 @@ static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) · 25 unmodified lines
1246 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(2), conf->rx2);1257 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(2), conf->rx2);
1247 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(2), conf->rx2);1258 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(2), conf->rx2);
1248 1259
1249 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(2), 0x0001);1260 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(0, 2), 0x0001);
1250 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(2), 0);1261 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(1, 2), 0);
1251 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(2), 0x0001);1262 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(2, 2), 0x0001);
1252 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE3_CTRL_2_REG(2), 0x0001);1263 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(3, 2), 0x0001);
1253 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE4_CTRL_2_REG(2), 0);1264 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANEl_CTRL_2_REG(4, 2), 0);
1254 1265
1255 rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(0), conf->trio0);1266 rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO0_REG(0), conf->trio0);
1256 rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(0), conf->trio0);1267 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
1267 /* Configure data line order. */1278 /* Configure data line order. */
1268 rsci2_set_line_order(priv, priv->line_orders[0],1279 rsci2_set_line_order(priv, priv->line_orders[0],
1269 V4H_CORE_DIG_CLANE_0_RW_CFG_0_REG,1280 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));
1271 rsci2_set_line_order(priv, priv->line_orders[1],1282 rsci2_set_line_order(priv, priv->line_orders[1],
1272 V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG,1283 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));
1274 rsci2_set_line_order(priv, priv->line_orders[2],1285 rsci2_set_line_order(priv, priv->line_orders[2],
1275 V4H_CORE_DIG_CLANE_2_RW_CFG_0_REG,1286 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));
1277 1288
1278 /* TODO: This registers is not documented. */1289 /* TODO: This registers is not documented. */
1279 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG, 0x5000);1290 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG, 0x5000);
1280 1291
1281 /* Leave Shutdown mode */1292 return conf;
1282 rcsi2_write(priv, V4H_DPHY_RSTZ_REG, BIT(0));1293}
1283 rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, BIT(0));
1284 1294
1285 /* Wait for calibration */1295struct rcsi2_d_phy_setting_v4h_lut_value {
1286 if (rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_PHY_READY)) {1296 unsigned int mbps;
1287 dev_err(priv->dev, "PHY calibration failed\n");1297 unsigned char cfg_1;
1288 return -ETIMEDOUT;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
1307static const struct rcsi2_d_phy_setting_v4h_lut_value *
1308rcsi2_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
1334static 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);
1289 }1448 }
1290 1449
1291 /* C-PHY setting - analog programing*/1450 static const u16 deskew_fine[] = {
1292 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(9), conf->lane29);1451 0x0404, 0x040c, 0x0414, 0x041c, 0x0423, 0x0429, 0x0430, 0x043a,
1293 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(7), conf->lane27);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 }
1294 1473
1295 return 0;1474 return 0;
1296}1475}
@@ -1298,10 +1477,11 @@ static int rcsi2_c_phy_setting_v4h(struct rcar_csi2 *priv, int msps) · 1 unmodified line
1298static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv,1477static int rcsi2_start_receiver_v4h(struct rcar_csi2 *priv,
1299 struct v4l2_subdev_state *state)1478 struct v4l2_subdev_state *state)
1300{1479{
1480 const struct rcsi2_cphy_setting *cphy = NULL;
1301 const struct rcar_csi2_format *format;1481 const struct rcar_csi2_format *format;
1302 const struct v4l2_mbus_framefmt *fmt;1482 const struct v4l2_mbus_framefmt *fmt;
1303 unsigned int lanes;1483 unsigned int lanes;
1304 int msps;1484 int mbps;
1305 int ret;1485 int ret;
1306 1486
1307 /* Use the format on the sink pad to compute the receiver config. */1487 /* 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
1314 if (ret)1494 if (ret)
1315 return ret;1495 return ret;
1316 1496
1317 msps = rcsi2_calc_mbps(priv, format->bpp, lanes);1497 mbps = rcsi2_calc_mbps(priv, format->bpp, lanes);
1318 if (msps < 0)1498 if (mbps < 0)
1319 return msps;1499 return mbps;
1320 1500
1321 /* Reset LINK and PHY*/1501 /* T0: Reset LINK and PHY*/
1322 rcsi2_write(priv, V4H_CSI2_RESETN_REG, 0);1502 rcsi2_write(priv, V4H_CSI2_RESETN_REG, 0);
1323 rcsi2_write(priv, V4H_DPHY_RSTZ_REG, 0);1503 rcsi2_write(priv, V4H_DPHY_RSTZ_REG, 0);
1324 rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, 0);1504 rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, 0);
1325 1505
1326 /* PHY static setting */1506 /* T1: PHY static setting */
1327 rcsi2_write(priv, V4H_PHY_EN_REG, V4H_PHY_EN_ENABLE_CLK);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);
1328 rcsi2_write(priv, V4H_FLDC_REG, 0);1510 rcsi2_write(priv, V4H_FLDC_REG, 0);
1329 rcsi2_write(priv, V4H_FLDD_REG, 0);1511 rcsi2_write(priv, V4H_FLDD_REG, 0);
1330 rcsi2_write(priv, V4H_IDIC_REG, 0);1512 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);
1332 rcsi2_write(priv, V4H_N_LANES_REG, lanes - 1);1515 rcsi2_write(priv, V4H_N_LANES_REG, lanes - 1);
1333 1516
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 */
1335 rcsi2_write(priv, V4H_CSI2_RESETN_REG, BIT(0));1525 rcsi2_write(priv, V4H_CSI2_RESETN_REG, BIT(0));
1336 1526
1337 /* Registers static setting through APB */1527 /* Registers static setting through APB */
1338 /* Common setting */1528 /* 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);
1339 rcsi2_write16(priv, V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(0), 0x1bfd);1531 rcsi2_write16(priv, V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(0), 0x1bfd);
1340 rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG, 0x0233);1532 rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_STARTUP_1_1_REG, 0x0233);
1341 rcsi2_write16(priv, V4H_PPI_STARTUP_RW_COMMON_DPHY_REG(6), 0x0027);1533 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
1350 rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG, 0x0105);1542 rcsi2_write16(priv, V4H_PPI_RW_LPDCOCAL_COARSE_CFG_REG, 0x0105);
1351 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x1000);1543 rcsi2_write16(priv, V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(6), 0x1000);
1352 rcsi2_write16(priv, V4H_PPI_RW_COMMON_CFG_REG, 0x0003);1544 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 }
1353 1566
1354 /* C-PHY settings */1567 /* T4: Leave Shutdown mode */
1355 ret = rcsi2_c_phy_setting_v4h(priv, msps);1568 rcsi2_write(priv, V4H_DPHY_RSTZ_REG, BIT(0));
1356 if (ret)1569 rcsi2_write(priv, V4H_PHY_SHUTDOWNZ_REG, BIT(0));
1357 return ret;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 }
1358 1596
1597 /* T7: Wait for stop state */
1359 rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_STOPSTATE_0 |1598 rcsi2_wait_phy_start_v4h(priv, V4H_ST_PHYST_ST_STOPSTATE_0 |
1360 V4H_ST_PHYST_ST_STOPSTATE_1 |1599 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);
1362 1605
1363 return 0;1606 return 0;
1364}1607}
1365 1608
1366static int rcsi2_d_phy_setting_v4m(struct rcar_csi2 *priv, int data_rate)1609static int rcsi2_d_phy_setting_v4m(struct rcar_csi2 *priv, int mbps)
1367{1610{
1368 unsigned int timeout;1611 unsigned int timeout;
1369 int ret;1612 int ret;
@@ -2213,6 +2456,7 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a779g0 = { · 843 unmodified lines
2213 .start_receiver = rcsi2_start_receiver_v4h,2456 .start_receiver = rcsi2_start_receiver_v4h,
2214 .use_isp = true,2457 .use_isp = true,
2215 .support_cphy = true,2458 .support_cphy = true,
2459 .support_dphy = true,
2216};2460};
2217 2461
2218static const struct rcsi2_register_layout rcsi2_registers_v4m = {2462static const struct rcsi2_register_layout rcsi2_registers_v4m = {
drivers/media/platform/renesas/rcar-fcp.c+36−0
@@ -9,6 +9,8 @@ · 8 unmodified lines
9 9
10#include <linux/device.h>10#include <linux/device.h>
11#include <linux/dma-mapping.h>11#include <linux/dma-mapping.h>
12#include <linux/io.h>
13#include <linux/iopoll.h>
12#include <linux/list.h>14#include <linux/list.h>
13#include <linux/module.h>15#include <linux/module.h>
14#include <linux/mod_devicetable.h>16#include <linux/mod_devicetable.h>
@@ -19,14 +21,25 @@ · 4 unmodified lines
19 21
20#include <media/rcar-fcp.h>22#include <media/rcar-fcp.h>
21 23
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
22struct rcar_fcp_device {29struct rcar_fcp_device {
23 struct list_head list;30 struct list_head list;
24 struct device *dev;31 struct device *dev;
32 void __iomem *base;
25};33};
26 34
27static LIST_HEAD(fcp_devices);35static LIST_HEAD(fcp_devices);
28static DEFINE_MUTEX(fcp_lock);36static DEFINE_MUTEX(fcp_lock);
29 37
38static inline void rcar_fcp_write(struct rcar_fcp_device *fcp, u32 reg, u32 val)
39{
40 iowrite32(val, fcp->base + reg);
41}
42
30/* -----------------------------------------------------------------------------43/* -----------------------------------------------------------------------------
31 * Public API44 * Public API
32 */45 */
@@ -117,6 +130,25 @@ void rcar_fcp_disable(struct rcar_fcp_device *fcp) · 84 unmodified lines
117}130}
118EXPORT_SYMBOL_GPL(rcar_fcp_disable);131EXPORT_SYMBOL_GPL(rcar_fcp_disable);
119 132
133int 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}
150EXPORT_SYMBOL_GPL(rcar_fcp_soft_reset);
151
120/* -----------------------------------------------------------------------------152/* -----------------------------------------------------------------------------
121 * Platform Driver153 * Platform Driver
122 */154 */
@@ -131,6 +163,10 @@ static int rcar_fcp_probe(struct platform_device *pdev) · 8 unmodified lines
131 163
132 fcp->dev = &pdev->dev;164 fcp->dev = &pdev->dev;
133 165
166 fcp->base = devm_platform_ioremap_resource(pdev, 0);
167 if (IS_ERR(fcp->base))
168 return PTR_ERR(fcp->base);
169
134 dma_set_max_seg_size(fcp->dev, UINT_MAX);170 dma_set_max_seg_size(fcp->dev, UINT_MAX);
135 171
136 pm_runtime_enable(&pdev->dev);172 pm_runtime_enable(&pdev->dev);
drivers/media/platform/renesas/rcar-vin/rcar-core.c+269−425
@@ -2,14 +2,14 @@ · 1 unmodified line
2/*2/*
3 * Driver for Renesas R-Car VIN3 * Driver for Renesas R-Car VIN
4 *4 *
5 * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
5 * Copyright (C) 2016 Renesas Electronics Corp.6 * Copyright (C) 2016 Renesas Electronics Corp.
6 * Copyright (C) 2011-2013 Renesas Solutions Corp.7 * Copyright (C) 2011-2013 Renesas Solutions Corp.
7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>8 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8 * Copyright (C) 2008 Magnus Damm9 * Copyright (C) 2008 Magnus Damm
9 *
10 * Based on the soc-camera rcar_vin driver
11 */10 */
12 11
12#include <linux/idr.h>
13#include <linux/module.h>13#include <linux/module.h>
14#include <linux/of.h>14#include <linux/of.h>
15#include <linux/of_graph.h>15#include <linux/of_graph.h>
@@ -55,6 +55,7 @@ · 39 unmodified lines
55 * be only one group for all instances.55 * be only one group for all instances.
56 */56 */
57 57
58static DEFINE_IDA(rvin_ida);
58static DEFINE_MUTEX(rvin_group_lock);59static DEFINE_MUTEX(rvin_group_lock);
59static struct rvin_group *rvin_group_data;60static struct rvin_group *rvin_group_data;
60 61
@@ -65,7 +66,7 @@ static void rvin_group_cleanup(struct rvin_group *group) · 4 unmodified lines
65}66}
66 67
67static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin,68static 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 *),
69 const struct media_device_ops *ops)70 const struct media_device_ops *ops)
70{71{
71 struct media_device *mdev = &group->mdev;72 struct media_device *mdev = &group->mdev;
@@ -115,27 +116,12 @@ static void rvin_group_release(struct kref *kref) · 43 unmodified lines
115}116}
116 117
117static int rvin_group_get(struct rvin_dev *vin,118static int rvin_group_get(struct rvin_dev *vin,
118 int (*link_setup)(struct rvin_dev *),119 int (*link_setup)(struct rvin_group *),
119 const struct media_device_ops *ops)120 const struct media_device_ops *ops)
120{121{
121 struct rvin_group *group;122 struct rvin_group *group;
122 u32 id;
123 int ret;123 int ret;
124 124
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
139 /* Join or create a VIN group */125 /* Join or create a VIN group */
140 mutex_lock(&rvin_group_lock);126 mutex_lock(&rvin_group_lock);
141 if (rvin_group_data) {127 if (rvin_group_data) {
@@ -156,6 +142,7 @@ static int rvin_group_get(struct rvin_dev *vin, · 14 unmodified lines
156 }142 }
157 143
158 kref_init(&group->refcount);144 kref_init(&group->refcount);
145 group->info = vin->info;
159 146
160 rvin_group_data = group;147 rvin_group_data = group;
161 }148 }
@@ -164,16 +151,15 @@ static int rvin_group_get(struct rvin_dev *vin, · 2 unmodified lines
164 /* Add VIN to group */151 /* Add VIN to group */
165 mutex_lock(&group->lock);152 mutex_lock(&group->lock);
166 153
167 if (group->vin[id]) {154 if (group->vin[vin->id]) {
168 vin_err(vin, "Duplicate renesas,id property value %u\n", id);155 vin_err(vin, "Duplicate renesas,id property value %u\n", vin->id);
169 mutex_unlock(&group->lock);156 mutex_unlock(&group->lock);
170 kref_put(&group->refcount, rvin_group_release);157 kref_put(&group->refcount, rvin_group_release);
171 return -EINVAL;158 return -EINVAL;
172 }159 }
173 160
174 group->vin[id] = vin;161 group->vin[vin->id] = vin;
175 162
176 vin->id = id;
177 vin->group = group;163 vin->group = group;
178 vin->v4l2_dev.mdev = &group->mdev;164 vin->v4l2_dev.mdev = &group->mdev;
179 165
@@ -213,7 +199,7 @@ static int rvin_group_entity_to_remote_id(struct rvin_group *group, · 33 unmodified lines
213 199
214 sd = media_entity_to_v4l2_subdev(entity);200 sd = media_entity_to_v4l2_subdev(entity);
215 201
216 for (i = 0; i < RVIN_REMOTES_MAX; i++)202 for (i = 0; i < ARRAY_SIZE(group->remotes); i++)
217 if (group->remotes[i].subdev == sd)203 if (group->remotes[i].subdev == sd)
218 return i;204 return i;
219 205
@@ -246,7 +232,7 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) · 26 unmodified lines
246 }232 }
247 }233 }
248 234
249 return vin->group->link_setup(vin);235 return vin->group->link_setup(vin->group);
250}236}
251 237
252static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier,238static 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
254 struct v4l2_async_connection *asc)240 struct v4l2_async_connection *asc)
255{241{
256 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);242 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
257 unsigned int i;243 struct rvin_group *group = vin->group;
258 244
259 for (i = 0; i < RCAR_VIN_NUM; i++)245 for (unsigned int i = 0; i < RCAR_VIN_NUM; i++) {
260 if (vin->group->vin[i])246 if (group->vin[i])
261 rvin_v4l2_unregister(vin->group->vin[i]);247 rvin_v4l2_unregister(group->vin[i]);
248 }
262 249
263 mutex_lock(&vin->group->lock);250 mutex_lock(&vin->group->lock);
264 251
265 for (i = 0; i < RVIN_CSI_MAX; i++) {252 for (unsigned int i = 0; i < RCAR_VIN_NUM; i++) {
266 if (vin->group->remotes[i].asc != asc)253 if (!group->vin[i] || group->vin[i]->parallel.asc != asc)
267 continue;254 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
269 vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);268 vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i);
270 break;
271 }269 }
272 270
273 mutex_unlock(&vin->group->lock);271 mutex_unlock(&vin->group->lock);
@@ -280,21 +278,38 @@ static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, · 6 unmodified lines
280 struct v4l2_async_connection *asc)278 struct v4l2_async_connection *asc)
281{279{
282 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);280 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev);
283 unsigned int i;281 struct rvin_group *group = vin->group;
284 282
285 mutex_lock(&vin->group->lock);283 guard(mutex)(&group->lock);
286 284
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++) {
288 if (vin->group->remotes[i].asc != asc)303 if (vin->group->remotes[i].asc != asc)
289 continue;304 continue;
305
290 vin->group->remotes[i].subdev = subdev;306 vin->group->remotes[i].subdev = subdev;
291 vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);307 vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i);
292 break;
293 }
294 308
295 mutex_unlock(&vin->group->lock);309 return 0;
310 }
296 311
297 return 0;312 return -ENODEV;
298}313}
299 314
300static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {315static const struct v4l2_async_notifier_operations rvin_group_notify_ops = {
@@ -343,12 +358,49 @@ out: · 42 unmodified lines
343 return ret;358 return ret;
344}359}
345 360
346static void rvin_group_notifier_cleanup(struct rvin_dev *vin)361static int rvin_parallel_parse_of(struct rvin_dev *vin)
347{362{
348 if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {363 struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
349 v4l2_async_nf_unregister(&vin->group->notifier);364 struct fwnode_handle *ep __free(fwnode_handle) = NULL;
350 v4l2_async_nf_cleanup(&vin->group->notifier);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;
351 }377 }
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;
352}404}
353 405
354static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port,406static 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
385 if (!(vin_mask & BIT(i)))437 if (!(vin_mask & BIT(i)))
386 continue;438 continue;
387 439
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. */
388 for (id = 0; id < max_id; id++) {446 for (id = 0; id < max_id; id++) {
389 if (vin->group->remotes[id].asc)447 if (vin->group->remotes[id].asc)
390 continue;448 continue;
@@ -437,11 +495,11 @@ static void rvin_free_controls(struct rvin_dev *vin) · 46 unmodified lines
437 vin->vdev.ctrl_handler = NULL;495 vin->vdev.ctrl_handler = NULL;
438}496}
439 497
440static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev)498static int rvin_create_controls(struct rvin_dev *vin)
441{499{
442 int ret;500 int ret;
443 501
444 ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);502 ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1);
445 if (ret < 0)503 if (ret < 0)
446 return ret;504 return ret;
447 505
@@ -455,286 +513,11 @@ static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev · 7 unmodified lines
455 return ret;513 return ret;
456 }514 }
457 515
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
468 vin->vdev.ctrl_handler = &vin->ctrl_handler;516 vin->vdev.ctrl_handler = &vin->ctrl_handler;
469 517
470 return 0;518 return 0;
471}519}
472 520
473/* -----------------------------------------------------------------------------
474 * Async notifier
475 */
476
477static 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 */
496static 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
567static 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
576static 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
611static 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
624static 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
646static 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
652static 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));
699out:
700 fwnode_handle_put(fwnode);
701
702 return ret;
703}
704
705static 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
711static 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
738/* -----------------------------------------------------------------------------521/* -----------------------------------------------------------------------------
739 * CSI-2522 * CSI-2
740 */523 */
@@ -909,80 +692,91 @@ static int rvin_csi2_create_link(struct rvin_group *group, unsigned int id, · 168 unmodified lines
909 return 0;692 return 0;
910}693}
911 694
912static int rvin_csi2_setup_links(struct rvin_dev *vin)695static 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
732static int rvin_csi2_setup_links(struct rvin_group *group)
913{733{
914 const struct rvin_group_route *route;734 const struct rvin_group_route *route;
915 unsigned int id;735 unsigned int id;
916 int ret = -EINVAL;736 int ret;
737
738 ret = rvin_parallel_setup_links(group);
739 if (ret)
740 return ret;
917 741
918 /* Create all media device links between VINs and CSI-2's. */742 /* Create all media device links between VINs and CSI-2's. */
919 mutex_lock(&vin->group->lock);743 mutex_lock(&group->lock);
920 for (route = vin->info->routes; route->chsel; route++) {744 for (route = group->info->routes; route->chsel; route++) {
921 /* Check that VIN' master is part of the group. */745 /* Check that VIN' master is part of the group. */
922 if (!vin->group->vin[route->master])746 if (!group->vin[route->master])
923 continue;747 continue;
924 748
925 /* Check that CSI-2 is part of the group. */749 /* Check that CSI-2 is part of the group. */
926 if (!vin->group->remotes[route->csi].subdev)750 if (!group->remotes[route->csi].subdev)
927 continue;751 continue;
928 752
929 for (id = route->master; id < route->master + 4; id++) {753 for (id = route->master; id < route->master + 4; id++) {
930 /* Check that VIN is part of the group. */754 /* Check that VIN is part of the group. */
931 if (!vin->group->vin[id])755 if (!group->vin[id])
932 continue;756 continue;
933 757
934 ret = rvin_csi2_create_link(vin->group, id, route);758 ret = rvin_csi2_create_link(group, id, route);
935 if (ret)759 if (ret)
936 goto out;760 goto out;
937 }761 }
938 }762 }
939out:763out:
940 mutex_unlock(&vin->group->lock);764 mutex_unlock(&group->lock);
941 765
942 return ret;766 return ret;
943}767}
944 768
945static 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
953static int rvin_csi2_init(struct rvin_dev *vin)769static int rvin_csi2_init(struct rvin_dev *vin)
954{770{
955 int ret;771 int ret;
956 772
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
966 ret = rvin_group_get(vin, rvin_csi2_setup_links, &rvin_csi2_media_ops);773 ret = rvin_group_get(vin, rvin_csi2_setup_links, &rvin_csi2_media_ops);
967 if (ret)774 if (ret)
968 goto err_controls;775 return ret;
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;
974 776
975 ret = rvin_group_notifier_init(vin, 1, RVIN_CSI_MAX);777 ret = rvin_group_notifier_init(vin, 1, RVIN_CSI_MAX);
976 if (ret)778 if (ret)
977 goto err_parallel;779 rvin_group_put(vin);
978
979 return 0;
980err_parallel:
981 rvin_parallel_cleanup(vin);
982err_group:
983 rvin_group_put(vin);
984err_controls:
985 rvin_free_controls(vin);
986 780
987 return ret;781 return ret;
988}782}
@@ -991,30 +785,31 @@ err_controls: · 2 unmodified lines
991 * ISP785 * ISP
992 */786 */
993 787
994static int rvin_isp_setup_links(struct rvin_dev *vin)788static int rvin_isp_setup_links(struct rvin_group *group)
995{789{
996 unsigned int i;790 unsigned int i;
997 int ret = -EINVAL;791 int ret = -EINVAL;
998 792
999 /* Create all media device links between VINs and ISP's. */793 /* Create all media device links between VINs and ISP's. */
1000 mutex_lock(&vin->group->lock);794 mutex_lock(&group->lock);
1001 for (i = 0; i < RCAR_VIN_NUM; i++) {795 for (i = 0; i < RCAR_VIN_NUM; i++) {
1002 struct media_pad *source_pad, *sink_pad;796 struct media_pad *source_pad, *sink_pad;
1003 struct media_entity *source, *sink;797 struct media_entity *source, *sink;
1004 unsigned int source_slot = i / 8;798 unsigned int source_slot = i / 8;
1005 unsigned int source_idx = i % 8 + 1;799 unsigned int source_idx = i % 8 + 1;
800 struct rvin_dev *vin = group->vin[i];
1006 801
1007 if (!vin->group->vin[i])802 if (!vin)
1008 continue;803 continue;
1009 804
1010 /* Check that ISP is part of the group. */805 /* Check that ISP is part of the group. */
1011 if (!vin->group->remotes[source_slot].subdev)806 if (!group->remotes[source_slot].subdev)
1012 continue;807 continue;
1013 808
1014 source = &vin->group->remotes[source_slot].subdev->entity;809 source = &group->remotes[source_slot].subdev->entity;
1015 source_pad = &source->pads[source_idx];810 source_pad = &source->pads[source_idx];
1016 811
1017 sink = &vin->group->vin[i]->vdev.entity;812 sink = &vin->vdev.entity;
1018 sink_pad = &sink->pads[0];813 sink_pad = &sink->pads[0];
1019 814
1020 /* Skip if link already exists. */815 /* Skip if link already exists. */
@@ -1030,44 +825,22 @@ static int rvin_isp_setup_links(struct rvin_dev *vin) · 9 unmodified lines
1030 break;825 break;
1031 }826 }
1032 }827 }
1033 mutex_unlock(&vin->group->lock);828 mutex_unlock(&group->lock);
1034 829
1035 return ret;830 return ret;
1036}831}
1037 832
1038static 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
1045static int rvin_isp_init(struct rvin_dev *vin)833static int rvin_isp_init(struct rvin_dev *vin)
1046{834{
1047 int ret;835 int ret;
1048 836
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
1058 ret = rvin_group_get(vin, rvin_isp_setup_links, NULL);837 ret = rvin_group_get(vin, rvin_isp_setup_links, NULL);
1059 if (ret)838 if (ret)
1060 goto err_controls;839 return ret;
1061 840
1062 ret = rvin_group_notifier_init(vin, 2, RVIN_ISP_MAX);841 ret = rvin_group_notifier_init(vin, 2, RVIN_ISP_MAX);
1063 if (ret)842 if (ret)
1064 goto err_group;843 rvin_group_put(vin);
1065
1066 return 0;
1067err_group:
1068 rvin_group_put(vin);
1069err_controls:
1070 rvin_free_controls(vin);
1071 844
1072 return ret;845 return ret;
1073}846}
@@ -1102,7 +875,7 @@ static int __maybe_unused rvin_resume(struct device *dev) · 28 unmodified lines
1102 * as we don't know if and in which order the master VINs will875 * as we don't know if and in which order the master VINs will
1103 * be resumed.876 * be resumed.
1104 */877 */
1105 if (vin->info->use_mc) {878 if (vin->info->model == RCAR_GEN3) {
1106 unsigned int master_id = rvin_group_id_to_master(vin->id);879 unsigned int master_id = rvin_group_id_to_master(vin->id);
1107 struct rvin_dev *master = vin->group->vin[master_id];880 struct rvin_dev *master = vin->group->vin[master_id];
1108 int ret;881 int ret;
@@ -1124,7 +897,6 @@ static int __maybe_unused rvin_resume(struct device *dev) · 15 unmodified lines
1124 897
1125static const struct rvin_info rcar_info_h1 = {898static const struct rvin_info rcar_info_h1 = {
1126 .model = RCAR_H1,899 .model = RCAR_H1,
1127 .use_mc = false,
1128 .max_width = 2048,900 .max_width = 2048,
1129 .max_height = 2048,901 .max_height = 2048,
1130 .scaler = rvin_scaler_gen2,902 .scaler = rvin_scaler_gen2,
@@ -1132,7 +904,6 @@ static const struct rvin_info rcar_info_h1 = { · 1 unmodified line
1132 904
1133static const struct rvin_info rcar_info_m1 = {905static const struct rvin_info rcar_info_m1 = {
1134 .model = RCAR_M1,906 .model = RCAR_M1,
1135 .use_mc = false,
1136 .max_width = 2048,907 .max_width = 2048,
1137 .max_height = 2048,908 .max_height = 2048,
1138 .scaler = rvin_scaler_gen2,909 .scaler = rvin_scaler_gen2,
@@ -1140,7 +911,6 @@ static const struct rvin_info rcar_info_m1 = { · 1 unmodified line
1140 911
1141static const struct rvin_info rcar_info_gen2 = {912static const struct rvin_info rcar_info_gen2 = {
1142 .model = RCAR_GEN2,913 .model = RCAR_GEN2,
1143 .use_mc = false,
1144 .max_width = 2048,914 .max_width = 2048,
1145 .max_height = 2048,915 .max_height = 2048,
1146 .scaler = rvin_scaler_gen2,916 .scaler = rvin_scaler_gen2,
@@ -1155,7 +925,6 @@ static const struct rvin_group_route rcar_info_r8a774e1_routes[] = { · 8 unmodified lines
1155 925
1156static const struct rvin_info rcar_info_r8a774e1 = {926static const struct rvin_info rcar_info_r8a774e1 = {
1157 .model = RCAR_GEN3,927 .model = RCAR_GEN3,
1158 .use_mc = true,
1159 .max_width = 4096,928 .max_width = 4096,
1160 .max_height = 4096,929 .max_height = 4096,
1161 .routes = rcar_info_r8a774e1_routes,930 .routes = rcar_info_r8a774e1_routes,
@@ -1171,7 +940,6 @@ static const struct rvin_group_route rcar_info_r8a7795_routes[] = { · 9 unmodified lines
1171 940
1172static const struct rvin_info rcar_info_r8a7795 = {941static const struct rvin_info rcar_info_r8a7795 = {
1173 .model = RCAR_GEN3,942 .model = RCAR_GEN3,
1174 .use_mc = true,
1175 .nv12 = true,943 .nv12 = true,
1176 .max_width = 4096,944 .max_width = 4096,
1177 .max_height = 4096,945 .max_height = 4096,
@@ -1189,7 +957,6 @@ static const struct rvin_group_route rcar_info_r8a7796_routes[] = { · 11 unmodified lines
1189 957
1190static const struct rvin_info rcar_info_r8a7796 = {958static const struct rvin_info rcar_info_r8a7796 = {
1191 .model = RCAR_GEN3,959 .model = RCAR_GEN3,
1192 .use_mc = true,
1193 .nv12 = true,960 .nv12 = true,
1194 .max_width = 4096,961 .max_width = 4096,
1195 .max_height = 4096,962 .max_height = 4096,
@@ -1207,7 +974,6 @@ static const struct rvin_group_route rcar_info_r8a77965_routes[] = { · 11 unmodified lines
1207 974
1208static const struct rvin_info rcar_info_r8a77965 = {975static const struct rvin_info rcar_info_r8a77965 = {
1209 .model = RCAR_GEN3,976 .model = RCAR_GEN3,
1210 .use_mc = true,
1211 .nv12 = true,977 .nv12 = true,
1212 .max_width = 4096,978 .max_width = 4096,
1213 .max_height = 4096,979 .max_height = 4096,
@@ -1222,7 +988,6 @@ static const struct rvin_group_route rcar_info_r8a77970_routes[] = { · 8 unmodified lines
1222 988
1223static const struct rvin_info rcar_info_r8a77970 = {989static const struct rvin_info rcar_info_r8a77970 = {
1224 .model = RCAR_GEN3,990 .model = RCAR_GEN3,
1225 .use_mc = true,
1226 .max_width = 4096,991 .max_width = 4096,
1227 .max_height = 4096,992 .max_height = 4096,
1228 .routes = rcar_info_r8a77970_routes,993 .routes = rcar_info_r8a77970_routes,
@@ -1236,7 +1001,6 @@ static const struct rvin_group_route rcar_info_r8a77980_routes[] = { · 7 unmodified lines
1236 1001
1237static const struct rvin_info rcar_info_r8a77980 = {1002static const struct rvin_info rcar_info_r8a77980 = {
1238 .model = RCAR_GEN3,1003 .model = RCAR_GEN3,
1239 .use_mc = true,
1240 .nv12 = true,1004 .nv12 = true,
1241 .max_width = 4096,1005 .max_width = 4096,
1242 .max_height = 4096,1006 .max_height = 4096,
@@ -1250,7 +1014,6 @@ static const struct rvin_group_route rcar_info_r8a77990_routes[] = { · 7 unmodified lines
1250 1014
1251static const struct rvin_info rcar_info_r8a77990 = {1015static const struct rvin_info rcar_info_r8a77990 = {
1252 .model = RCAR_GEN3,1016 .model = RCAR_GEN3,
1253 .use_mc = true,
1254 .nv12 = true,1017 .nv12 = true,
1255 .max_width = 4096,1018 .max_width = 4096,
1256 .max_height = 4096,1019 .max_height = 4096,
@@ -1264,7 +1027,6 @@ static const struct rvin_group_route rcar_info_r8a77995_routes[] = { · 7 unmodified lines
1264 1027
1265static const struct rvin_info rcar_info_r8a77995 = {1028static const struct rvin_info rcar_info_r8a77995 = {
1266 .model = RCAR_GEN3,1029 .model = RCAR_GEN3,
1267 .use_mc = true,
1268 .nv12 = true,1030 .nv12 = true,
1269 .max_width = 4096,1031 .max_width = 4096,
1270 .max_height = 4096,1032 .max_height = 4096,
@@ -1274,7 +1036,6 @@ static const struct rvin_info rcar_info_r8a77995 = { · 3 unmodified lines
1274 1036
1275static const struct rvin_info rcar_info_gen4 = {1037static const struct rvin_info rcar_info_gen4 = {
1276 .model = RCAR_GEN4,1038 .model = RCAR_GEN4,
1277 .use_mc = true,
1278 .use_isp = true,1039 .use_isp = true,
1279 .nv12 = true,1040 .nv12 = true,
1280 .raw10 = true,1041 .raw10 = true,
@@ -1361,6 +1122,56 @@ static const struct of_device_id rvin_of_id_table[] = { · 80 unmodified lines
1361};1122};
1362MODULE_DEVICE_TABLE(of, rvin_of_id_table);1123MODULE_DEVICE_TABLE(of, rvin_of_id_table);
1363 1124
1125static 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
1163static 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
1364static int rcar_vin_probe(struct platform_device *pdev)1175static int rcar_vin_probe(struct platform_device *pdev)
1365{1176{
1366 struct rvin_dev *vin;1177 struct rvin_dev *vin;
@@ -1388,30 +1199,59 @@ static int rcar_vin_probe(struct platform_device *pdev) · 21 unmodified lines
1388 1199
1389 platform_set_drvdata(pdev, vin);1200 platform_set_drvdata(pdev, vin);
1390 1201
1391 if (vin->info->use_isp) {1202 if (rvin_id_get(vin)) {
1392 ret = rvin_isp_init(vin);1203 ret = -EINVAL;
1393 } else if (vin->info->use_mc) {1204 goto err_dma;
1394 ret = rvin_csi2_init(vin);1205 }
1395 1206
1396 if (vin->info->scaler &&1207 vin->pad.flags = MEDIA_PAD_FL_SINK;
1397 rvin_group_id_to_master(vin->id) == vin->id)1208 ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad);
1398 vin->scaler = vin->info->scaler;1209 if (ret)
1399 } else {1210 goto err_id;
1400 ret = rvin_parallel_init(vin);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);
1401 1233
1402 if (vin->info->scaler)1234 if (vin->info->scaler)
1403 vin->scaler = vin->info->scaler;1235 vin->scaler = vin->info->scaler;
1236 break;
1404 }1237 }
1405 1238
1406 if (ret) {1239 if (ret)
1407 rvin_dma_unregister(vin);1240 goto err_ctrl;
1408 return ret;
1409 }
1410 1241
1411 pm_suspend_ignore_children(&pdev->dev, true);1242 pm_suspend_ignore_children(&pdev->dev, true);
1412 pm_runtime_enable(&pdev->dev);1243 pm_runtime_enable(&pdev->dev);
1413 1244
1414 return 0;1245 return 0;
1246
1247err_ctrl:
1248 rvin_free_controls(vin);
1249err_id:
1250 rvin_id_put(vin);
1251err_dma:
1252 rvin_dma_unregister(vin);
1253
1254 return ret;
1415}1255}
1416 1256
1417static void rcar_vin_remove(struct platform_device *pdev)1257static void rcar_vin_remove(struct platform_device *pdev)
@@ -1422,12 +1262,16 @@ static void rcar_vin_remove(struct platform_device *pdev) · 4 unmodified lines
1422 1262
1423 rvin_v4l2_unregister(vin);1263 rvin_v4l2_unregister(vin);
1424 1264
1425 if (vin->info->use_isp)1265 if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
1426 rvin_isp_cleanup(vin);1266 v4l2_async_nf_unregister(&vin->group->notifier);
1427 else if (vin->info->use_mc)1267 v4l2_async_nf_cleanup(&vin->group->notifier);
1428 rvin_csi2_cleanup(vin);1268 }
1429 else1269
1430 rvin_parallel_cleanup(vin);1270 rvin_group_put(vin);
1271
1272 rvin_free_controls(vin);
1273
1274 rvin_id_put(vin);
1431 1275
1432 rvin_dma_unregister(vin);1276 rvin_dma_unregister(vin);
1433}1277}
drivers/media/platform/renesas/rcar-vin/rcar-dma.c+33−44
@@ -2,18 +2,18 @@ · 1 unmodified line
2/*2/*
3 * Driver for Renesas R-Car VIN3 * Driver for Renesas R-Car VIN
4 *4 *
5 * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
5 * Copyright (C) 2016 Renesas Electronics Corp.6 * Copyright (C) 2016 Renesas Electronics Corp.
6 * Copyright (C) 2011-2013 Renesas Solutions Corp.7 * Copyright (C) 2011-2013 Renesas Solutions Corp.
7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>8 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8 * Copyright (C) 2008 Magnus Damm9 * Copyright (C) 2008 Magnus Damm
9 *
10 * Based on the soc-camera rcar_vin driver
11 */10 */
12 11
13#include <linux/delay.h>12#include <linux/delay.h>
14#include <linux/interrupt.h>13#include <linux/interrupt.h>
15#include <linux/pm_runtime.h>14#include <linux/pm_runtime.h>
16 15
16#include <media/v4l2-event.h>
17#include <media/videobuf2-dma-contig.h>17#include <media/videobuf2-dma-contig.h>
18 18
19#include "rcar-vin.h"19#include "rcar-vin.h"
@@ -115,11 +115,16 @@ · 95 unmodified lines
115#define VNFC_S_FRAME (1 << 0)115#define VNFC_S_FRAME (1 << 0)
116 116
117/* Video n Interrupt Enable Register bits */117/* Video n Interrupt Enable Register bits */
118#define VNIE_FIE (1 << 4)118#define VNIE_VFE BIT(17)
119#define VNIE_EFE (1 << 1)119#define VNIE_VRE BIT(16)
120#define VNIE_FIE BIT(4)
121#define VNIE_EFE BIT(1)
120 122
121/* Video n Interrupt Status Register bits */123/* 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)
123 128
124/* Video n Data Mode Register bits */129/* Video n Data Mode Register bits */
125#define VNDMR_A8BIT(n) (((n) & 0xff) << 24)130#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
555 560
556void rvin_scaler_gen2(struct rvin_dev *vin)561void rvin_scaler_gen2(struct rvin_dev *vin)
557{562{
558 unsigned int crop_height;
559 u32 xs, ys;563 u32 xs, ys;
560 564
561 /* Set scaling coefficient */565 /* Set scaling coefficient */
562 crop_height = vin->crop.height;
563 if (V4L2_FIELD_HAS_BOTH(vin->format.field))
564 crop_height *= 2;
565
566 ys = 0;566 ys = 0;
567 if (crop_height != vin->compose.height)567 if (vin->crop.height != vin->compose.height)
568 ys = (4096 * crop_height) / vin->compose.height;568 ys = (4096 * vin->crop.height) / vin->compose.height;
569 rvin_write(vin, ys, VNYS_REG);569 rvin_write(vin, ys, VNYS_REG);
570 570
571 xs = 0;571 xs = 0;
@@ -700,9 +700,6 @@ static int rvin_setup(struct rvin_dev *vin) · 128 unmodified lines
700 case V4L2_FIELD_INTERLACED:700 case V4L2_FIELD_INTERLACED:
701 /* Default to TB */701 /* Default to TB */
702 vnmc = VNMC_IM_FULL;702 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;
706 break;703 break;
707 case V4L2_FIELD_INTERLACED_TB:704 case V4L2_FIELD_INTERLACED_TB:
708 vnmc = VNMC_IM_FULL;705 vnmc = VNMC_IM_FULL;
@@ -897,6 +894,8 @@ static int rvin_setup(struct rvin_dev *vin) · 188 unmodified lines
897 894
898 /* Progressive or interlaced mode */895 /* Progressive or interlaced mode */
899 interrupts = progressive ? VNIE_FIE : VNIE_EFE;896 interrupts = progressive ? VNIE_FIE : VNIE_EFE;
897 /* Enable VSYNC Rising Edge Detection. */
898 interrupts |= VNIE_VRE;
900 899
901 /* Ack interrupts */900 /* Ack interrupts */
902 rvin_write(vin, interrupts, VNINTS_REG);901 rvin_write(vin, interrupts, VNINTS_REG);
@@ -912,21 +911,6 @@ static int rvin_setup(struct rvin_dev *vin) · 9 unmodified lines
912 return 0;911 return 0;
913}912}
914 913
915static void rvin_disable_interrupts(struct rvin_dev *vin)
916{
917 rvin_write(vin, 0, VNIE_REG);
918}
919
920static u32 rvin_get_interrupt_status(struct rvin_dev *vin)
921{
922 return rvin_read(vin, VNINTS_REG);
923}
924
925static void rvin_ack_interrupt(struct rvin_dev *vin)
926{
927 rvin_write(vin, rvin_read(vin, VNINTS_REG), VNINTS_REG);
928}
929
930static bool rvin_capture_active(struct rvin_dev *vin)914static bool rvin_capture_active(struct rvin_dev *vin)
931{915{
932 return rvin_read(vin, VNMS_REG) & VNMS_CA;916 return rvin_read(vin, VNMS_REG) & VNMS_CA;
@@ -1049,22 +1033,35 @@ static void rvin_capture_stop(struct rvin_dev *vin) · 116 unmodified lines
1049static irqreturn_t rvin_irq(int irq, void *data)1033static irqreturn_t rvin_irq(int irq, void *data)
1050{1034{
1051 struct rvin_dev *vin = data;1035 struct rvin_dev *vin = data;
1052 u32 int_status, vnms;1036 u32 capture, status, vnms;
1053 int slot;1037 int slot;
1054 unsigned int handled = 0;1038 unsigned int handled = 0;
1055 unsigned long flags;1039 unsigned long flags;
1056 1040
1057 spin_lock_irqsave(&vin->qlock, flags);1041 spin_lock_irqsave(&vin->qlock, flags);
1058 1042
1059 int_status = rvin_get_interrupt_status(vin);1043 status = rvin_read(vin, VNINTS_REG);
1060 if (!int_status)1044 if (!status)
1061 goto done;1045 goto done;
1062 1046
1063 rvin_ack_interrupt(vin);1047 rvin_write(vin, status, VNINTS_REG);
1064 handled = 1;1048 handled = 1;
1065 1049
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
1066 /* Nothing to do if nothing was captured. */1060 /* 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))
1068 goto done;1065 goto done;
1069 1066
1070 /* Nothing to do if not running. */1067 /* Nothing to do if not running. */
@@ -1297,14 +1294,6 @@ static int rvin_set_stream(struct rvin_dev *vin, int on) · 226 unmodified lines
1297 struct media_pad *pad;1294 struct media_pad *pad;
1298 int ret;1295 int ret;
1299 1296
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
1308 pad = media_pad_remote_pad_first(&vin->pad);1297 pad = media_pad_remote_pad_first(&vin->pad);
1309 if (!pad)1298 if (!pad)
1310 return -EPIPE;1299 return -EPIPE;
@@ -1417,7 +1406,7 @@ void rvin_stop_streaming(struct rvin_dev *vin) · 106 unmodified lines
1417 rvin_set_stream(vin, 0);1406 rvin_set_stream(vin, 0);
1418 1407
1419 /* disable interrupts */1408 /* disable interrupts */
1420 rvin_disable_interrupts(vin);1409 rvin_write(vin, 0, VNIE_REG);
1421 1410
1422 /* Return unprocessed buffers from hardware. */1411 /* Return unprocessed buffers from hardware. */
1423 for (unsigned int i = 0; i < HW_BUFFER_NUM; i++) {1412 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
2/*2/*
3 * Driver for Renesas R-Car VIN3 * Driver for Renesas R-Car VIN
4 *4 *
5 * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
5 * Copyright (C) 2016 Renesas Electronics Corp.6 * Copyright (C) 2016 Renesas Electronics Corp.
6 * Copyright (C) 2011-2013 Renesas Solutions Corp.7 * Copyright (C) 2011-2013 Renesas Solutions Corp.
7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>8 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8 * Copyright (C) 2008 Magnus Damm9 * Copyright (C) 2008 Magnus Damm
9 *
10 * Based on the soc-camera rcar_vin driver
11 */10 */
12 11
13#include <linux/pm_runtime.h>12#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
230 * V4L2229 * V4L2
231 */230 */
232 231
233static 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
268static 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);
322done:
323 __v4l2_subdev_state_free(sd_state);
324
325 return ret;
326}
327
328static int rvin_querycap(struct file *file, void *priv,232static int rvin_querycap(struct file *file, void *priv,
329 struct v4l2_capability *cap)233 struct v4l2_capability *cap)
330{234{
@@ -333,42 +237,6 @@ static int rvin_querycap(struct file *file, void *priv, · 2 unmodified lines
333 return 0;237 return 0;
334}238}
335 239
336static 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
344static 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
372static int rvin_g_fmt_vid_cap(struct file *file, void *priv,240static int rvin_g_fmt_vid_cap(struct file *file, void *priv,
373 struct v4l2_format *f)241 struct v4l2_format *f)
374{242{
@@ -465,6 +333,7 @@ static int rvin_enum_fmt_vid_cap(struct file *file, void *priv, · 90 unmodified lines
465 333
466static int rvin_remote_rectangle(struct rvin_dev *vin, struct v4l2_rect *rect)334static int rvin_remote_rectangle(struct rvin_dev *vin, struct v4l2_rect *rect)
467{335{
336 struct media_pad *pad = media_pad_remote_pad_first(&vin->pad);
468 struct v4l2_subdev_format fmt = {337 struct v4l2_subdev_format fmt = {
469 .which = V4L2_SUBDEV_FORMAT_ACTIVE,338 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
470 };339 };
@@ -472,18 +341,11 @@ static int rvin_remote_rectangle(struct rvin_dev *vin, struct v4l2_rect *rect) · 1 unmodified line
472 unsigned int index;341 unsigned int index;
473 int ret;342 int ret;
474 343
475 if (vin->info->use_mc) {344 if (!pad)
476 struct media_pad *pad = media_pad_remote_pad_first(&vin->pad);345 return -EINVAL;
477
478 if (!pad)
479 return -EINVAL;
480 346
481 sd = media_entity_to_v4l2_subdev(pad->entity);347 sd = media_entity_to_v4l2_subdev(pad->entity);
482 index = pad->index;348 index = pad->index;
483 } else {
484 sd = vin_to_source(vin);
485 index = vin->parallel.source_pad;
486 }
487 349
488 fmt.pad = index;350 fmt.pad = index;
489 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);351 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
623 return 0;485 return 0;
624}486}
625 487
626static 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
635static 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
644static 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
656static 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
685static int rvin_g_input(struct file *file, void *priv, unsigned int *i)
686{
687 *i = 0;
688 return 0;
689}
690
691static 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
698static 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
706static 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
721static 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
733static int rvin_subscribe_event(struct v4l2_fh *fh,488static int rvin_subscribe_event(struct v4l2_fh *fh,
734 const struct v4l2_event_subscription *sub)489 const struct v4l2_event_subscription *sub)
735{490{
736 switch (sub->type) {491 switch (sub->type) {
492 case V4L2_EVENT_FRAME_SYNC:
493 return v4l2_event_subscribe(fh, sub, 2, NULL);
737 case V4L2_EVENT_SOURCE_CHANGE:494 case V4L2_EVENT_SOURCE_CHANGE:
738 return v4l2_event_subscribe(fh, sub, 4, NULL);495 return v4l2_event_subscribe(fh, sub, 4, NULL);
739 }496 }
740 return v4l2_ctrl_subscribe_event(fh, sub);497 return v4l2_ctrl_subscribe_event(fh, sub);
741}498}
742 499
743static 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
762static 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
778static 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
788static 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
798static 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
817static 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
835static 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
853static 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
904static void rvin_mc_try_format(struct rvin_dev *vin,500static void rvin_mc_try_format(struct rvin_dev *vin,
905 struct v4l2_pix_format *pix)501 struct v4l2_pix_format *pix)
906{502{
@@ -979,19 +575,6 @@ static const struct v4l2_ioctl_ops rvin_mc_ioctl_ops = { · 72 unmodified lines
979 * File Operations575 * File Operations
980 */576 */
981 577
982static 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
995static int rvin_open(struct file *file)578static int rvin_open(struct file *file)
996{579{
997 struct rvin_dev *vin = video_drvdata(file);580 struct rvin_dev *vin = video_drvdata(file);
@@ -1011,11 +594,7 @@ static int rvin_open(struct file *file) · 13 unmodified lines
1011 if (ret)594 if (ret)
1012 goto err_unlock;595 goto err_unlock;
1013 596
1014 if (vin->info->use_mc)597 ret = v4l2_pipeline_pm_get(&vin->vdev.entity);
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
1019 if (ret < 0)598 if (ret < 0)
1020 goto err_open;599 goto err_open;
1021 600
@@ -1027,10 +606,7 @@ static int rvin_open(struct file *file) · 5 unmodified lines
1027 606
1028 return 0;607 return 0;
1029err_power:608err_power:
1030 if (vin->info->use_mc)609 v4l2_pipeline_pm_put(&vin->vdev.entity);
1031 v4l2_pipeline_pm_put(&vin->vdev.entity);
1032 else if (v4l2_fh_is_singular_file(file))
1033 rvin_power_parallel(vin, false);
1034err_open:610err_open:
1035 v4l2_fh_release(file);611 v4l2_fh_release(file);
1036err_unlock:612err_unlock:
@@ -1044,23 +620,14 @@ err_pm: · 7 unmodified lines
1044static int rvin_release(struct file *file)620static int rvin_release(struct file *file)
1045{621{
1046 struct rvin_dev *vin = video_drvdata(file);622 struct rvin_dev *vin = video_drvdata(file);
1047 bool fh_singular;
1048 int ret;623 int ret;
1049 624
1050 mutex_lock(&vin->lock);625 mutex_lock(&vin->lock);
1051 626
1052 /* Save the singular status before we call the clean-up helper */
1053 fh_singular = v4l2_fh_is_singular_file(file);
1054
1055 /* the release helper will cleanup any on-going streaming */627 /* the release helper will cleanup any on-going streaming */
1056 ret = _vb2_fop_release(file, NULL);628 ret = _vb2_fop_release(file, NULL);
1057 629
1058 if (vin->info->use_mc) {630 v4l2_pipeline_pm_put(&vin->vdev.entity);
1059 v4l2_pipeline_pm_put(&vin->vdev.entity);
1060 } else {
1061 if (fh_singular)
1062 rvin_power_parallel(vin, false);
1063 }
1064 631
1065 mutex_unlock(&vin->lock);632 mutex_unlock(&vin->lock);
1066 633
@@ -1091,18 +658,6 @@ void rvin_v4l2_unregister(struct rvin_dev *vin) · 24 unmodified lines
1091 video_unregister_device(&vin->vdev);658 video_unregister_device(&vin->vdev);
1092}659}
1093 660
1094static 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
1106static void rvin_notify(struct v4l2_subdev *sd,661static void rvin_notify(struct v4l2_subdev *sd,
1107 unsigned int notification, void *arg)662 unsigned int notification, void *arg)
1108{663{
@@ -1113,12 +668,6 @@ static void rvin_notify(struct v4l2_subdev *sd, · 4 unmodified lines
1113 container_of(sd->v4l2_dev, struct rvin_dev, v4l2_dev);668 container_of(sd->v4l2_dev, struct rvin_dev, v4l2_dev);
1114 unsigned int i;669 unsigned int i;
1115 670
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
1122 group = vin->group;671 group = vin->group;
1123 672
1124 for (i = 0; i < RCAR_VIN_NUM; i++) {673 for (i = 0; i < RCAR_VIN_NUM; i++) {
@@ -1134,7 +683,13 @@ static void rvin_notify(struct v4l2_subdev *sd, · 9 unmodified lines
1134 if (remote != sd)683 if (remote != sd)
1135 continue;684 continue;
1136 685
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 }
1138 }693 }
1139}694}
1140 695
@@ -1153,7 +708,8 @@ int rvin_v4l2_register(struct rvin_dev *vin) · 12 unmodified lines
1153 vdev->lock = &vin->lock;708 vdev->lock = &vin->lock;
1154 vdev->fops = &rvin_fops;709 vdev->fops = &rvin_fops;
1155 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |710 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;
1157 713
1158 /* Set a default format */714 /* Set a default format */
1159 vin->format.pixelformat = RVIN_DEFAULT_FORMAT;715 vin->format.pixelformat = RVIN_DEFAULT_FORMAT;
@@ -1162,14 +718,6 @@ int rvin_v4l2_register(struct rvin_dev *vin) · 2 unmodified lines
1162 vin->format.field = RVIN_DEFAULT_FIELD;718 vin->format.field = RVIN_DEFAULT_FIELD;
1163 vin->format.colorspace = RVIN_DEFAULT_COLORSPACE;719 vin->format.colorspace = RVIN_DEFAULT_COLORSPACE;
1164 720
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
1173 rvin_format_align(vin, &vin->format);721 rvin_format_align(vin, &vin->format);
1174 722
1175 ret = video_register_device(&vin->vdev, VFL_TYPE_VIDEO, -1);723 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
2/*2/*
3 * Driver for Renesas R-Car VIN3 * Driver for Renesas R-Car VIN
4 *4 *
5 * Copyright (C) 2025 Niklas Söderlund <niklas.soderlund@ragnatech.se>
5 * Copyright (C) 2016 Renesas Electronics Corp.6 * Copyright (C) 2016 Renesas Electronics Corp.
6 * Copyright (C) 2011-2013 Renesas Solutions Corp.7 * Copyright (C) 2011-2013 Renesas Solutions Corp.
7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>8 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
8 * Copyright (C) 2008 Magnus Damm9 * Copyright (C) 2008 Magnus Damm
9 *
10 * Based on the soc-camera rcar_vin driver
11 */10 */
12 11
13#ifndef __RCAR_VIN__12#ifndef __RCAR_VIN__
@@ -79,8 +78,6 @@ struct rvin_video_format { · 65 unmodified lines
79 * @mbus_type: media bus type78 * @mbus_type: media bus type
80 * @bus: media bus parallel configuration79 * @bus: media bus parallel configuration
81 * @source_pad: source pad of remote subdevice80 * @source_pad: source pad of remote subdevice
82 * @sink_pad: sink pad of remote subdevice
83 *
84 */81 */
85struct rvin_parallel_entity {82struct rvin_parallel_entity {
86 struct v4l2_async_connection *asc;83 struct v4l2_async_connection *asc;
@@ -90,7 +87,6 @@ struct rvin_parallel_entity { · 3 unmodified lines
90 struct v4l2_mbus_config_parallel bus;87 struct v4l2_mbus_config_parallel bus;
91 88
92 unsigned int source_pad;89 unsigned int source_pad;
93 unsigned int sink_pad;
94};90};
95 91
96/**92/**
@@ -117,7 +113,6 @@ struct rvin_group_route { · 20 unmodified lines
117/**113/**
118 * struct rvin_info - Information about the particular VIN implementation114 * struct rvin_info - Information about the particular VIN implementation
119 * @model: VIN model115 * @model: VIN model
120 * @use_mc: use media controller instead of controlling subdevice
121 * @use_isp: the VIN is connected to the ISP and not to the CSI-2116 * @use_isp: the VIN is connected to the ISP and not to the CSI-2
122 * @nv12: support outputting NV12 pixel format117 * @nv12: support outputting NV12 pixel format
123 * @raw10: support outputting RAW10 pixel format118 * @raw10: support outputting RAW10 pixel format
@@ -129,7 +124,6 @@ struct rvin_group_route { · 5 unmodified lines
129 */124 */
130struct rvin_info {125struct rvin_info {
131 enum model_id model;126 enum model_id model;
132 bool use_mc;
133 bool use_isp;127 bool use_isp;
134 bool nv12;128 bool nv12;
135 bool raw10;129 bool raw10;
@@ -149,7 +143,6 @@ struct rvin_info { · 13 unmodified lines
149 * @vdev: V4L2 video device associated with VIN143 * @vdev: V4L2 video device associated with VIN
150 * @v4l2_dev: V4L2 device144 * @v4l2_dev: V4L2 device
151 * @ctrl_handler: V4L2 control handler145 * @ctrl_handler: V4L2 control handler
152 * @notifier: V4L2 asynchronous subdevs notifier
153 *146 *
154 * @parallel: parallel input subdevice descriptor147 * @parallel: parallel input subdevice descriptor
155 *148 *
@@ -177,7 +170,6 @@ struct rvin_info { · 21 unmodified lines
177 * @crop: active cropping170 * @crop: active cropping
178 * @compose: active composing171 * @compose: active composing
179 * @scaler: Optional scaler172 * @scaler: Optional scaler
180 * @std: active video standard of the video source
181 *173 *
182 * @alpha: Alpha component to fill in for supported pixel formats174 * @alpha: Alpha component to fill in for supported pixel formats
183 */175 */
@@ -189,7 +181,6 @@ struct rvin_dev { · 5 unmodified lines
189 struct video_device vdev;181 struct video_device vdev;
190 struct v4l2_device v4l2_dev;182 struct v4l2_device v4l2_dev;
191 struct v4l2_ctrl_handler ctrl_handler;183 struct v4l2_ctrl_handler ctrl_handler;
192 struct v4l2_async_notifier notifier;
193 184
194 struct rvin_parallel_entity parallel;185 struct rvin_parallel_entity parallel;
195 186
@@ -220,7 +211,6 @@ struct rvin_dev { · 24 unmodified lines
220 struct v4l2_rect crop;211 struct v4l2_rect crop;
221 struct v4l2_rect compose;212 struct v4l2_rect compose;
222 void (*scaler)(struct rvin_dev *vin);213 void (*scaler)(struct rvin_dev *vin);
223 v4l2_std_id std;
224 214
225 unsigned int alpha;215 unsigned int alpha;
226};216};
@@ -242,6 +232,7 @@ struct rvin_dev { · 15 unmodified lines
242 * @lock: protects the count, notifier, vin and csi members232 * @lock: protects the count, notifier, vin and csi members
243 * @count: number of enabled VIN instances found in DT233 * @count: number of enabled VIN instances found in DT
244 * @notifier: group notifier for CSI-2 async connections234 * @notifier: group notifier for CSI-2 async connections
235 * @info: Platform dependent information about the VIN instances
245 * @vin: VIN instances which are part of the group236 * @vin: VIN instances which are part of the group
246 * @link_setup: Callback to create all links for the media graph237 * @link_setup: Callback to create all links for the media graph
247 * @remotes: array of pairs of async connection and subdev pointers238 * @remotes: array of pairs of async connection and subdev pointers
@@ -255,9 +246,10 @@ struct rvin_group { · 7 unmodified lines
255 struct mutex lock;246 struct mutex lock;
256 unsigned int count;247 unsigned int count;
257 struct v4l2_async_notifier notifier;248 struct v4l2_async_notifier notifier;
249 const struct rvin_info *info;
258 struct rvin_dev *vin[RCAR_VIN_NUM];250 struct rvin_dev *vin[RCAR_VIN_NUM];
259 251
260 int (*link_setup)(struct rvin_dev *vin);252 int (*link_setup)(struct rvin_group *group);
261 253
262 struct {254 struct {
263 struct v4l2_async_connection *asc;255 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
366 .irq_handler = rzg3e_cru_irq,366 .irq_handler = rzg3e_cru_irq,
367 .enable_interrupts = rzg3e_cru_enable_interrupts,367 .enable_interrupts = rzg3e_cru_enable_interrupts,
368 .disable_interrupts = rzg3e_cru_disable_interrupts,368 .disable_interrupts = rzg3e_cru_disable_interrupts,
369 .fifo_empty = rz3e_fifo_empty,369 .fifo_empty = rzg3e_fifo_empty,
370 .csi_setup = rzg3e_cru_csi2_setup,370 .csi_setup = rzg3e_cru_csi2_setup,
371};371};
372 372
@@ -403,7 +403,7 @@ static const u16 rzg2l_cru_regs[] = { · 30 unmodified lines
403 [ICnDMR] = 0x26c,403 [ICnDMR] = 0x26c,
404};404};
405 405
406static const struct rzg2l_cru_info rzgl2_cru_info = {406static const struct rzg2l_cru_info rzg2l_cru_info = {
407 .max_width = 2800,407 .max_width = 2800,
408 .max_height = 4095,408 .max_height = 4095,
409 .image_conv = ICnMC,409 .image_conv = ICnMC,
@@ -422,7 +422,7 @@ static const struct of_device_id rzg2l_cru_of_id_table[] = { · 12 unmodified lines
422 },422 },
423 {423 {
424 .compatible = "renesas,rzg2l-cru",424 .compatible = "renesas,rzg2l-cru",
425 .data = &rzgl2_cru_info,425 .data = &rzg2l_cru_info,
426 },426 },
427 { /* sentinel */ }427 { /* sentinel */ }
428};428};
drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h+9−5
@@ -64,19 +64,21 @@ struct rzg2l_cru_ip { · 63 unmodified lines
64 64
65/**65/**
66 * struct rzg2l_cru_ip_format - CRU IP format66 * struct rzg2l_cru_ip_format - CRU IP format
67 * @code: Media bus code67 * @codes: Array of up to four media bus codes
68 * @datatype: MIPI CSI2 data type68 * @datatype: MIPI CSI2 data type
69 * @format: 4CC format identifier (V4L2_PIX_FMT_*)69 * @format: 4CC format identifier (V4L2_PIX_FMT_*)
70 * @icndmr: ICnDMR register value70 * @icndmr: ICnDMR register value
71 * @bpp: bytes per pixel
72 * @yuv: Flag to indicate whether the format is YUV-based.71 * @yuv: Flag to indicate whether the format is YUV-based.
73 */72 */
74struct rzg2l_cru_ip_format {73struct 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];
76 u32 datatype;79 u32 datatype;
77 u32 format;80 u32 format;
78 u32 icndmr;81 u32 icndmr;
79 u8 bpp;
80 bool yuv;82 bool yuv;
81};83};
82 84
@@ -192,6 +194,8 @@ struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru); · 109 unmodified lines
192const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code);194const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code);
193const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format);195const struct rzg2l_cru_ip_format *rzg2l_cru_ip_format_to_fmt(u32 format);
194const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index);196const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index);
197bool rzg2l_cru_ip_fmt_supports_mbus_code(const struct rzg2l_cru_ip_format *fmt,
198 unsigned int code);
195 199
196void rzg2l_cru_enable_interrupts(struct rzg2l_cru_dev *cru);200void rzg2l_cru_enable_interrupts(struct rzg2l_cru_dev *cru);
197void rzg2l_cru_disable_interrupts(struct rzg2l_cru_dev *cru);201void 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
199void rzg3e_cru_disable_interrupts(struct rzg2l_cru_dev *cru);203void rzg3e_cru_disable_interrupts(struct rzg2l_cru_dev *cru);
200 204
201bool rzg2l_fifo_empty(struct rzg2l_cru_dev *cru);205bool rzg2l_fifo_empty(struct rzg2l_cru_dev *cru);
202bool rz3e_fifo_empty(struct rzg2l_cru_dev *cru);206bool rzg3e_fifo_empty(struct rzg2l_cru_dev *cru);
203void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru,207void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru,
204 const struct rzg2l_cru_ip_format *ip_fmt,208 const struct rzg2l_cru_ip_format *ip_fmt,
205 u8 csi_vc);209 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
232 { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },232 { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },
233 { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },233 { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },
234 { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, },234 { .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, },
235};247};
236 248
237static inline struct rzg2l_csi2 *sd_to_csi2(struct v4l2_subdev *sd)249static 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
282 const struct rzg2l_csi2_format *format;294 const struct rzg2l_csi2_format *format;
283 const struct v4l2_mbus_framefmt *fmt;295 const struct v4l2_mbus_framefmt *fmt;
284 struct v4l2_subdev_state *state;296 struct v4l2_subdev_state *state;
285 struct v4l2_ctrl *ctrl;297 struct media_pad *remote_pad;
286 u64 mbps;298 u64 mbps;
299 s64 ret;
287 300
288 /* Read the pixel rate control from remote. */301 if (!csi2->remote_source)
289 ctrl = v4l2_ctrl_find(source->ctrl_handler, V4L2_CID_PIXEL_RATE);302 return -ENODEV;
290 if (!ctrl) {303
291 dev_err(csi2->dev, "no pixel rate control in subdev %s\n",304 remote_pad = media_pad_remote_pad_unique(&csi2->pads[RZG2L_CSI2_SINK]);
292 source->name);305 if (IS_ERR(remote_pad)) {
293 return -EINVAL;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);
294 }309 }
295 310
296 state = v4l2_subdev_lock_and_get_active_state(&csi2->subdev);311 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
298 format = rzg2l_csi2_code_to_fmt(fmt->code);313 format = rzg2l_csi2_code_to_fmt(fmt->code);
299 v4l2_subdev_unlock_state(state);314 v4l2_subdev_unlock_state(state);
300 315
301 /*316 /* Read the link frequency from remote subdevice. */
302 * Calculate hsfreq in Mbps317 ret = v4l2_get_link_freq(remote_pad, format->bpp, csi2->lanes * 2);
303 * hsfreq = (pixel_rate * bits_per_sample) / number_of_lanes318 if (ret < 0) {
304 */319 dev_err(csi2->dev, "can't retrieve link freq from subdev %s\n",
305 mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * format->bpp;320 source->name);
306 do_div(mbps, csi2->lanes * 1000000);321 return -EINVAL;
322 }
323
324 mbps = ret * 2;
325 do_div(mbps, 1000000);
307 326
308 return mbps;327 return mbps;
309}328}
drivers/media/platform/renesas/rzg2l-cru/rzg2l-ip.c+89−19
@@ -13,42 +13,83 @@ · 12 unmodified lines
13 13
14static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = {14static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = {
15 {15 {
16 .code = MEDIA_BUS_FMT_UYVY8_1X16,16 .codes = {
17 MEDIA_BUS_FMT_UYVY8_1X16,
18 },
17 .datatype = MIPI_CSI2_DT_YUV422_8B,19 .datatype = MIPI_CSI2_DT_YUV422_8B,
18 .format = V4L2_PIX_FMT_UYVY,20 .format = V4L2_PIX_FMT_UYVY,
19 .bpp = 2,
20 .icndmr = ICnDMR_YCMODE_UYVY,21 .icndmr = ICnDMR_YCMODE_UYVY,
21 .yuv = true,22 .yuv = true,
22 },23 },
23 {24 {
24 .code = MEDIA_BUS_FMT_SBGGR8_1X8,25 .codes = {
26 MEDIA_BUS_FMT_SBGGR8_1X8,
27 },
25 .format = V4L2_PIX_FMT_SBGGR8,28 .format = V4L2_PIX_FMT_SBGGR8,
26 .datatype = MIPI_CSI2_DT_RAW8,29 .datatype = MIPI_CSI2_DT_RAW8,
27 .bpp = 1,
28 .icndmr = 0,30 .icndmr = 0,
29 .yuv = false,31 .yuv = false,
30 },32 },
31 {33 {
32 .code = MEDIA_BUS_FMT_SGBRG8_1X8,34 .codes = {
35 MEDIA_BUS_FMT_SGBRG8_1X8,
36 },
33 .format = V4L2_PIX_FMT_SGBRG8,37 .format = V4L2_PIX_FMT_SGBRG8,
34 .datatype = MIPI_CSI2_DT_RAW8,38 .datatype = MIPI_CSI2_DT_RAW8,
35 .bpp = 1,
36 .icndmr = 0,39 .icndmr = 0,
37 .yuv = false,40 .yuv = false,
38 },41 },
39 {42 {
40 .code = MEDIA_BUS_FMT_SGRBG8_1X8,43 .codes = {
44 MEDIA_BUS_FMT_SGRBG8_1X8,
45 },
41 .format = V4L2_PIX_FMT_SGRBG8,46 .format = V4L2_PIX_FMT_SGRBG8,
42 .datatype = MIPI_CSI2_DT_RAW8,47 .datatype = MIPI_CSI2_DT_RAW8,
43 .bpp = 1,
44 .icndmr = 0,48 .icndmr = 0,
45 .yuv = false,49 .yuv = false,
46 },50 },
47 {51 {
48 .code = MEDIA_BUS_FMT_SRGGB8_1X8,52 .codes = {
53 MEDIA_BUS_FMT_SRGGB8_1X8,
54 },
49 .format = V4L2_PIX_FMT_SRGGB8,55 .format = V4L2_PIX_FMT_SRGGB8,
50 .datatype = MIPI_CSI2_DT_RAW8,56 .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,
52 .icndmr = 0,93 .icndmr = 0,
53 .yuv = false,94 .yuv = false,
54 },95 },
@@ -56,11 +97,14 @@ static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = { · 1 unmodified line
56 97
57const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code)98const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code)
58{99{
59 unsigned int i;100 unsigned int i, j;
60 101
61 for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++)102 for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) {
62 if (rzg2l_cru_ip_formats[i].code == code)103 for (j = 0; j < ARRAY_SIZE(rzg2l_cru_ip_formats[i].codes); j++) {
63 return &rzg2l_cru_ip_formats[i];104 if (rzg2l_cru_ip_formats[i].codes[j] == code)
105 return &rzg2l_cru_ip_formats[i];
106 }
107 }
64 108
65 return NULL;109 return NULL;
66}110}
@@ -85,6 +129,17 @@ const struct rzg2l_cru_ip_format *rzg2l_cru_ip_index_to_fmt(u32 index) · 18 unmodified lines
85 return &rzg2l_cru_ip_formats[index];129 return &rzg2l_cru_ip_formats[index];
86}130}
87 131
132bool 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}
88struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru)143struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru)
89{144{
90 struct v4l2_subdev_state *state;145 struct v4l2_subdev_state *state;
@@ -162,7 +217,7 @@ static int rzg2l_cru_ip_set_format(struct v4l2_subdev *sd, · 71 unmodified lines
162 sink_format = v4l2_subdev_state_get_format(state, fmt->pad);217 sink_format = v4l2_subdev_state_get_format(state, fmt->pad);
163 218
164 if (!rzg2l_cru_ip_code_to_fmt(fmt->format.code))219 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];
166 else221 else
167 sink_format->code = fmt->format.code;222 sink_format->code = fmt->format.code;
168 223
@@ -188,11 +243,26 @@ static int rzg2l_cru_ip_enum_mbus_code(struct v4l2_subdev *sd, · 19 unmodified lines
188 struct v4l2_subdev_state *state,243 struct v4l2_subdev_state *state,
189 struct v4l2_subdev_mbus_code_enum *code)244 struct v4l2_subdev_mbus_code_enum *code)
190{245{
191 if (code->index >= ARRAY_SIZE(rzg2l_cru_ip_formats))246 unsigned int index = code->index;
192 return -EINVAL;247 unsigned int i, j;
193 248
194 code->code = rzg2l_cru_ip_formats[code->index].code;249 for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++) {
195 return 0;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;
196}266}
197 267
198static int rzg2l_cru_ip_enum_frame_size(struct v4l2_subdev *sd,268static 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
323 return 0;323 return 0;
324}324}
325 325
326bool rz3e_fifo_empty(struct rzg2l_cru_dev *cru)326bool rzg3e_fifo_empty(struct rzg2l_cru_dev *cru)
327{327{
328 u32 amnfifopntr = rzg2l_cru_read(cru, AMnFIFOPNTR);328 u32 amnfifopntr = rzg2l_cru_read(cru, AMnFIFOPNTR);
329 329
@@ -345,8 +345,6 @@ bool rzg2l_fifo_empty(struct rzg2l_cru_dev *cru) · 15 unmodified lines
345 amnfifopntr_w = amnfifopntr & AMnFIFOPNTR_FIFOWPNTR;345 amnfifopntr_w = amnfifopntr & AMnFIFOPNTR_FIFOWPNTR;
346 amnfifopntr_r_y =346 amnfifopntr_r_y =
347 (amnfifopntr & AMnFIFOPNTR_FIFORPNTR_Y) >> 16;347 (amnfifopntr & AMnFIFOPNTR_FIFORPNTR_Y) >> 16;
348 if (amnfifopntr_w == amnfifopntr_r_y)
349 return true;
350 348
351 return amnfifopntr_w == amnfifopntr_r_y;349 return amnfifopntr_w == amnfifopntr_r_y;
352}350}
@@ -941,15 +939,7 @@ static void rzg2l_cru_format_align(struct rzg2l_cru_dev *cru, · 588 unmodified lines
941 v4l_bound_align_image(&pix->width, 320, info->max_width, 1,939 v4l_bound_align_image(&pix->width, 320, info->max_width, 1,
942 &pix->height, 240, info->max_height, 2, 0);940 &pix->height, 240, info->max_height, 2, 0);
943 941
944 if (info->has_stride) {942 v4l2_fill_pixfmt(pix, pix->pixelformat, pix->width, pix->height);
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;
953 943
954 dev_dbg(cru->dev, "Format %ux%u bpl: %u size: %u\n",944 dev_dbg(cru->dev, "Format %ux%u bpl: %u size: %u\n",
955 pix->width, pix->height, pix->bytesperline, pix->sizeimage);945 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
1031 return 0;1021 return 0;
1032}1022}
1033 1023
1024static 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
1034static const struct v4l2_ioctl_ops rzg2l_cru_ioctl_ops = {1049static const struct v4l2_ioctl_ops rzg2l_cru_ioctl_ops = {
1035 .vidioc_querycap = rzg2l_cru_querycap,1050 .vidioc_querycap = rzg2l_cru_querycap,
1036 .vidioc_try_fmt_vid_cap = rzg2l_cru_try_fmt_vid_cap,1051 .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
1047 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,1062 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1048 .vidioc_streamon = vb2_ioctl_streamon,1063 .vidioc_streamon = vb2_ioctl_streamon,
1049 .vidioc_streamoff = vb2_ioctl_streamoff,1064 .vidioc_streamoff = vb2_ioctl_streamoff,
1065 .vidioc_enum_framesizes = rzg2l_cru_enum_framesizes,
1050};1066};
1051 1067
1052/* -----------------------------------------------------------------------------1068/* -----------------------------------------------------------------------------
@@ -1129,7 +1145,7 @@ static int rzg2l_cru_video_link_validate(struct media_link *link) · 76 unmodified lines
1129 if (fmt.format.width != cru->format.width ||1145 if (fmt.format.width != cru->format.width ||
1130 fmt.format.height != cru->format.height ||1146 fmt.format.height != cru->format.height ||
1131 fmt.format.field != cru->format.field ||1147 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))
1133 return -EPIPE;1149 return -EPIPE;
1134 1150
1135 return 0;1151 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
6vsp1-y += vsp1_brx.o vsp1_sru.o vsp1_uds.o6vsp1-y += vsp1_brx.o vsp1_sru.o vsp1_uds.o
7vsp1-y += vsp1_hgo.o vsp1_hgt.o vsp1_histo.o7vsp1-y += vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
8vsp1-y += vsp1_iif.o vsp1_lif.o vsp1_uif.o8vsp1-y += vsp1_iif.o vsp1_lif.o vsp1_uif.o
9vsp1-y += vsp1_vspx.o
9 10
10obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o11obj-$(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
111 struct media_entity_operations media_ops;111 struct media_entity_operations media_ops;
112 112
113 struct vsp1_drm *drm;113 struct vsp1_drm *drm;
114 struct vsp1_vspx *vspx;
114};115};
115 116
116int vsp1_device_get(struct vsp1_device *vsp1);117int vsp1_device_get(struct vsp1_device *vsp1);
drivers/media/platform/renesas/vsp1/vsp1_dl.c+25−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/device.h>10#include <linux/device.h>
11#include <linux/dma-mapping.h>11#include <linux/dma-mapping.h>
12#include <linux/gfp.h>12#include <linux/gfp.h>
13#include <linux/lockdep.h>
13#include <linux/refcount.h>14#include <linux/refcount.h>
14#include <linux/slab.h>15#include <linux/slab.h>
15#include <linux/workqueue.h>16#include <linux/workqueue.h>
@@ -176,6 +177,7 @@ struct vsp1_dl_cmd_pool { · 160 unmodified lines
176 * @bodies: list of extra display list bodies177 * @bodies: list of extra display list bodies
177 * @pre_cmd: pre command to be issued through extended dl header178 * @pre_cmd: pre command to be issued through extended dl header
178 * @post_cmd: post command to be issued through extended dl header179 * @post_cmd: post command to be issued through extended dl header
180 * @allocated: flag to detect double list release
179 * @has_chain: if true, indicates that there's a partition chain181 * @has_chain: if true, indicates that there's a partition chain
180 * @chain: entry in the display list partition chain182 * @chain: entry in the display list partition chain
181 * @flags: display list flags, a combination of VSP1_DL_FRAME_END_*183 * @flags: display list flags, a combination of VSP1_DL_FRAME_END_*
@@ -194,6 +196,8 @@ struct vsp1_dl_list { · 12 unmodified lines
194 struct vsp1_dl_ext_cmd *pre_cmd;196 struct vsp1_dl_ext_cmd *pre_cmd;
195 struct vsp1_dl_ext_cmd *post_cmd;197 struct vsp1_dl_ext_cmd *post_cmd;
196 198
199 bool allocated;
200
197 bool has_chain;201 bool has_chain;
198 struct list_head chain;202 struct list_head chain;
199 203
@@ -212,6 +216,7 @@ struct vsp1_dl_list { · 12 unmodified lines
212 * @pending: list waiting to be queued to the hardware216 * @pending: list waiting to be queued to the hardware
213 * @pool: body pool for the display list bodies217 * @pool: body pool for the display list bodies
214 * @cmdpool: commands pool for extended display list218 * @cmdpool: commands pool for extended display list
219 * @list_count: number of allocated display lists
215 */220 */
216struct vsp1_dl_manager {221struct vsp1_dl_manager {
217 unsigned int index;222 unsigned int index;
@@ -226,6 +231,8 @@ struct vsp1_dl_manager { · 8 unmodified lines
226 231
227 struct vsp1_dl_body_pool *pool;232 struct vsp1_dl_body_pool *pool;
228 struct vsp1_dl_cmd_pool *cmdpool;233 struct vsp1_dl_cmd_pool *cmdpool;
234
235 size_t list_count;
229};236};
230 237
231/* -----------------------------------------------------------------------------238/* -----------------------------------------------------------------------------
@@ -606,6 +613,8 @@ struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm) · 374 unmodified lines
606 struct vsp1_dl_list *dl = NULL;613 struct vsp1_dl_list *dl = NULL;
607 unsigned long flags;614 unsigned long flags;
608 615
616 lockdep_assert_not_held(&dlm->lock);
617
609 spin_lock_irqsave(&dlm->lock, flags);618 spin_lock_irqsave(&dlm->lock, flags);
610 619
611 if (!list_empty(&dlm->free)) {620 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
617 * display list can assert list_empty() if it is not in a chain.626 * display list can assert list_empty() if it is not in a chain.
618 */627 */
619 INIT_LIST_HEAD(&dl->chain);628 INIT_LIST_HEAD(&dl->chain);
629 dl->allocated = true;
620 }630 }
621 631
622 spin_unlock_irqrestore(&dlm->lock, flags);632 spin_unlock_irqrestore(&dlm->lock, flags);
@@ -632,6 +642,8 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl) · 9 unmodified lines
632 if (!dl)642 if (!dl)
633 return;643 return;
634 644
645 lockdep_assert_held(&dl->dlm->lock);
646
635 /*647 /*
636 * Release any linked display-lists which were chained for a single648 * Release any linked display-lists which were chained for a single
637 * hardware operation.649 * hardware operation.
@@ -657,6 +669,13 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl) · 19 unmodified lines
657 */669 */
658 dl->body0->num_entries = 0;670 dl->body0->num_entries = 0;
659 671
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
660 list_add_tail(&dl->list, &dl->dlm->free);679 list_add_tail(&dl->list, &dl->dlm->free);
661}680}
662 681
@@ -1067,6 +1086,7 @@ void vsp1_dlm_setup(struct vsp1_device *vsp1) · 404 unmodified lines
1067void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)1086void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
1068{1087{
1069 unsigned long flags;1088 unsigned long flags;
1089 size_t list_count;
1070 1090
1071 spin_lock_irqsave(&dlm->lock, flags);1091 spin_lock_irqsave(&dlm->lock, flags);
1072 1092
@@ -1074,8 +1094,11 @@ void vsp1_dlm_reset(struct vsp1_dl_manager *dlm) · 1 unmodified line
1074 __vsp1_dl_list_put(dlm->queued);1094 __vsp1_dl_list_put(dlm->queued);
1075 __vsp1_dl_list_put(dlm->pending);1095 __vsp1_dl_list_put(dlm->pending);
1076 1096
1097 list_count = list_count_nodes(&dlm->free);
1077 spin_unlock_irqrestore(&dlm->lock, flags);1098 spin_unlock_irqrestore(&dlm->lock, flags);
1078 1099
1100 WARN_ON_ONCE(list_count != dlm->list_count);
1101
1079 dlm->active = NULL;1102 dlm->active = NULL;
1080 dlm->queued = NULL;1103 dlm->queued = NULL;
1081 dlm->pending = NULL;1104 dlm->pending = NULL;
@@ -1145,6 +1168,8 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, · 63 unmodified lines
1145 list_add_tail(&dl->list, &dlm->free);1168 list_add_tail(&dl->list, &dlm->free);
1146 }1169 }
1147 1170
1171 dlm->list_count = prealloc;
1172
1148 if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) {1173 if (vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) {
1149 dlm->cmdpool = vsp1_dl_cmd_pool_create(vsp1,1174 dlm->cmdpool = vsp1_dl_cmd_pool_create(vsp1,
1150 VSP1_EXTCMD_AUTOFLD, prealloc);1175 VSP1_EXTCMD_AUTOFLD, prealloc);
drivers/media/platform/renesas/vsp1/vsp1_drm.c+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9 9
10#include <linux/device.h>10#include <linux/device.h>
11#include <linux/dma-mapping.h>11#include <linux/dma-mapping.h>
12#include <linux/export.h>
12#include <linux/slab.h>13#include <linux/slab.h>
13 14
14#include <media/media-entity.h>15#include <media/media-entity.h>
drivers/media/platform/renesas/vsp1/vsp1_drv.c+20−2
@@ -33,11 +33,13 @@ · 32 unmodified lines
33#include "vsp1_lif.h"33#include "vsp1_lif.h"
34#include "vsp1_lut.h"34#include "vsp1_lut.h"
35#include "vsp1_pipe.h"35#include "vsp1_pipe.h"
36#include "vsp1_regs.h"
36#include "vsp1_rwpf.h"37#include "vsp1_rwpf.h"
37#include "vsp1_sru.h"38#include "vsp1_sru.h"
38#include "vsp1_uds.h"39#include "vsp1_uds.h"
39#include "vsp1_uif.h"40#include "vsp1_uif.h"
40#include "vsp1_video.h"41#include "vsp1_video.h"
42#include "vsp1_vspx.h"
41 43
42/* -----------------------------------------------------------------------------44/* -----------------------------------------------------------------------------
43 * Interrupt Handling45 * Interrupt Handling
@@ -490,7 +492,10 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) · 446 unmodified lines
490 492
491 ret = media_device_register(mdev);493 ret = media_device_register(mdev);
492 } else {494 } 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);
494 }499 }
495 500
496done:501done:
@@ -502,7 +507,9 @@ done: · 5 unmodified lines
502 507
503int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index)508int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index)
504{509{
510 u32 version = vsp1->version & VI6_IP_VERSION_MODEL_MASK;
505 unsigned int timeout;511 unsigned int timeout;
512 int ret = 0;
506 u32 status;513 u32 status;
507 514
508 status = vsp1_read(vsp1, VI6_STATUS);515 status = vsp1_read(vsp1, VI6_STATUS);
@@ -523,7 +530,11 @@ int vsp1_reset_wpf(struct vsp1_device *vsp1, unsigned int index) · 14 unmodified lines
523 return -ETIMEDOUT;530 return -ETIMEDOUT;
524 }531 }
525 532
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;
527}538}
528 539
529static int vsp1_device_init(struct vsp1_device *vsp1)540static int vsp1_device_init(struct vsp1_device *vsp1)
@@ -851,6 +862,13 @@ static const struct vsp1_device_info vsp1_device_infos[] = { · 321 unmodified lines
851 .uif_count = 2,862 .uif_count = 2,
852 .wpf_count = 1,863 .wpf_count = 1,
853 .num_bru_inputs = 5,864 .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,
854 },872 },
855};873};
856 874
drivers/media/platform/renesas/vsp1/vsp1_pipe.c+3−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9 9
10#include <linux/delay.h>10#include <linux/delay.h>
11#include <linux/list.h>11#include <linux/list.h>
12#include <linux/lockdep.h>
12#include <linux/sched.h>13#include <linux/sched.h>
13#include <linux/wait.h>14#include <linux/wait.h>
14 15
@@ -473,6 +474,8 @@ void vsp1_pipeline_run(struct vsp1_pipeline *pipe) · 458 unmodified lines
473{474{
474 struct vsp1_device *vsp1 = pipe->output->entity.vsp1;475 struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
475 476
477 lockdep_assert_held(&pipe->irqlock);
478
476 if (pipe->state == VSP1_PIPELINE_STOPPED) {479 if (pipe->state == VSP1_PIPELINE_STOPPED) {
477 vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index),480 vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index),
478 VI6_CMD_STRCMD);481 VI6_CMD_STRCMD);
drivers/media/platform/renesas/vsp1/vsp1_regs.h+1−0
@@ -799,6 +799,7 @@ · 798 unmodified lines
799#define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)799#define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)
800#define VI6_IP_VERSION_MODEL_VSPBS_GEN3 (0x1a << 8)800#define VI6_IP_VERSION_MODEL_VSPBS_GEN3 (0x1a << 8)
801#define VI6_IP_VERSION_MODEL_VSPD_GEN4 (0x1c << 8)801#define VI6_IP_VERSION_MODEL_VSPD_GEN4 (0x1c << 8)
802#define VI6_IP_VERSION_MODEL_VSPX_GEN4 (0x1d << 8)
802/* RZ/G2L SoCs have no version register, So use 0x80 as the model version */803/* RZ/G2L SoCs have no version register, So use 0x80 as the model version */
803#define VI6_IP_VERSION_MODEL_VSPD_RZG2L (0x80 << 8)804#define VI6_IP_VERSION_MODEL_VSPD_RZG2L (0x80 << 8)
804 805
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 */
40struct 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
68static inline struct vsp1_vspx_pipeline *
69to_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 */
79struct 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 */
85static 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. */
127static 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
174static 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 */
202int 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}
211EXPORT_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 */
223struct 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}
232EXPORT_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 */
249int 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}
267EXPORT_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 */
278void 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 */
301int 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
356error_put:
357 vsp1_device_put(vsp1);
358 return ret;
359}
360EXPORT_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 */
372void 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}
393EXPORT_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 */
410int 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
493error_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}
500EXPORT_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 */
520int 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}
559EXPORT_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 */
569void vsp1_isp_job_release(struct device *dev,
570 struct vsp1_isp_job_desc *job)
571{
572 vsp1_dl_list_put(job->dl);
573}
574EXPORT_SYMBOL_GPL(vsp1_isp_job_release);
575
576/* -----------------------------------------------------------------------------
577 * Initialization and cleanup
578 */
579
580int 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
628void 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
13int vsp1_vspx_init(struct vsp1_device *vsp1);
14void 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
4 4
5source "drivers/media/platform/rockchip/rga/Kconfig"5source "drivers/media/platform/rockchip/rga/Kconfig"
6source "drivers/media/platform/rockchip/rkisp1/Kconfig"6source "drivers/media/platform/rockchip/rkisp1/Kconfig"
7source "drivers/media/platform/rockchip/rkvdec/Kconfig"
drivers/media/platform/rockchip/Makefile+1−0
@@ -1,3 +1,4 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2obj-y += rga/2obj-y += rga/
3obj-y += rkisp1/3obj-y += rkisp1/
4obj-y += rkvdec/
drivers/media/platform/rockchip/rkisp1/rkisp1-common.h+2−0
@@ -415,6 +415,8 @@ struct rkisp1_params { · 414 unmodified lines
415 spinlock_t config_lock; /* locks the buffers list 'params' */415 spinlock_t config_lock; /* locks the buffers list 'params' */
416 struct list_head params;416 struct list_head params;
417 417
418 struct v4l2_ctrl_handler ctrls;
419
418 const struct v4l2_meta_format *metafmt;420 const struct v4l2_meta_format *metafmt;
419 421
420 enum v4l2_quantization quantization;422 enum v4l2_quantization quantization;
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c+146−4
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 * Copyright (C) 2017 Rockchip Electronics Co., Ltd.5 * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
6 */6 */
7 7
8#include <linux/bitfield.h>
8#include <linux/math.h>9#include <linux/math.h>
9#include <linux/string.h>10#include <linux/string.h>
10 11
@@ -60,6 +61,7 @@ union rkisp1_ext_params_config { · 49 unmodified lines
60 struct rkisp1_ext_params_afc_config afc;61 struct rkisp1_ext_params_afc_config afc;
61 struct rkisp1_ext_params_compand_bls_config compand_bls;62 struct rkisp1_ext_params_compand_bls_config compand_bls;
62 struct rkisp1_ext_params_compand_curve_config compand_curve;63 struct rkisp1_ext_params_compand_curve_config compand_curve;
64 struct rkisp1_ext_params_wdr_config wdr;
63};65};
64 66
65enum rkisp1_params_formats {67enum rkisp1_params_formats {
@@ -1348,6 +1350,73 @@ rkisp1_compand_compress_config(struct rkisp1_params *params, · 1282 unmodified lines
1348 arg->x);1350 arg->x);
1349}1351}
1350 1352
1353static 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
1351static void1420static void
1352rkisp1_isp_isr_other_config(struct rkisp1_params *params,1421rkisp1_isp_isr_other_config(struct rkisp1_params *params,
1353 const struct rkisp1_params_cfg *new_params)1422 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
2005 RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);2074 RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE);
2006}2075}
2007 2076
2077static 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
2008typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,2096typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
2009 const union rkisp1_ext_params_config *config);2097 const union rkisp1_ext_params_config *config);
2010 2098
@@ -2118,6 +2206,11 @@ static const struct rkisp1_ext_params_handler { · 107 unmodified lines
2118 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,2206 .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
2119 .features = RKISP1_FEATURE_COMPAND,2207 .features = RKISP1_FEATURE_COMPAND,
2120 },2208 },
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 },
2121};2214};
2122 2215
2123static void rkisp1_ext_params_config(struct rkisp1_params *params,2216static 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
2736 return vb2_queue_init(q);2829 return vb2_queue_init(q);
2737}2830}
2738 2831
2832static 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
2739int rkisp1_params_register(struct rkisp1_device *rkisp1)2870int rkisp1_params_register(struct rkisp1_device *rkisp1)
2740{2871{
2741 struct rkisp1_params *params = &rkisp1->params;2872 struct rkisp1_params *params = &rkisp1->params;
@@ -2763,7 +2894,9 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1) · 21 unmodified lines
2763 vdev->queue = &node->buf_queue;2894 vdev->queue = &node->buf_queue;
2764 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;2895 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;
2765 vdev->vfl_dir = VFL_DIR_TX;2896 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;
2767 2900
2768 params->metafmt = &rkisp1_params_formats[RKISP1_PARAMS_FIXED];2901 params->metafmt = &rkisp1_params_formats[RKISP1_PARAMS_FIXED];
2769 2902
@@ -2777,18 +2910,26 @@ int rkisp1_params_register(struct rkisp1_device *rkisp1) · 7 unmodified lines
2777 node->pad.flags = MEDIA_PAD_FL_SOURCE;2910 node->pad.flags = MEDIA_PAD_FL_SOURCE;
2778 ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);2911 ret = media_entity_pads_init(&vdev->entity, 1, &node->pad);
2779 if (ret)2912 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 }
2781 2920
2782 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);2921 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
2783 if (ret) {2922 if (ret) {
2784 dev_err(rkisp1->dev,2923 dev_err(rkisp1->dev,
2785 "failed to register %s, ret=%d\n", vdev->name, ret);2924 "failed to register %s, ret=%d\n", vdev->name, ret);
2786 goto error;2925 goto err_ctrl;
2787 }2926 }
2788 2927
2789 return 0;2928 return 0;
2790 2929
2791error:2930err_ctrl:
2931 v4l2_ctrl_handler_free(&params->ctrls);
2932err_media:
2792 media_entity_cleanup(&vdev->entity);2933 media_entity_cleanup(&vdev->entity);
2793 mutex_destroy(&node->vlock);2934 mutex_destroy(&node->vlock);
2794 return ret;2935 return ret;
@@ -2804,6 +2945,7 @@ void rkisp1_params_unregister(struct rkisp1_device *rkisp1) · 9 unmodified lines
2804 return;2945 return;
2805 2946
2806 vb2_video_unregister_device(vdev);2947 vb2_video_unregister_device(vdev);
2948 v4l2_ctrl_handler_free(&params->ctrls);
2807 media_entity_cleanup(&vdev->entity);2949 media_entity_cleanup(&vdev->entity);
2808 mutex_destroy(&node->vlock);2950 mutex_destroy(&node->vlock);
2809}2951}
drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h+25−74
@@ -703,6 +703,27 @@ · 702 unmodified lines
703#define RKISP1_CIF_ISP_COMPAND_CTRL_SOFT_RESET_FLAG BIT(2)703#define RKISP1_CIF_ISP_COMPAND_CTRL_SOFT_RESET_FLAG BIT(2)
704#define RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE BIT(3)704#define RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE BIT(3)
705 705
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
706/* =================================================================== */727/* =================================================================== */
707/* CIF Registers */728/* CIF Registers */
708/* =================================================================== */729/* =================================================================== */
@@ -1295,82 +1316,12 @@ · 586 unmodified lines
1295 1316
1296#define RKISP1_CIF_ISP_WDR_BASE 0x00002a001317#define RKISP1_CIF_ISP_WDR_BASE 0x00002a00
1297#define RKISP1_CIF_ISP_WDR_CTRL (RKISP1_CIF_ISP_WDR_BASE + 0x00000000)1318#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)1319#define RKISP1_CIF_ISP_WDR_TONECURVE(n) (RKISP1_CIF_ISP_WDR_BASE + 0x00000004 + (n) * 4)
1299#define RKISP1_CIF_ISP_WDR_TONECURVE_2 (RKISP1_CIF_ISP_WDR_BASE + 0x00000008)1320#define RKISP1_CIF_ISP_WDR_TONECURVE_YM(n) (RKISP1_CIF_ISP_WDR_BASE + 0x00000014 + (n) * 4)
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)
1335#define RKISP1_CIF_ISP_WDR_OFFSET (RKISP1_CIF_ISP_WDR_BASE + 0x00000098)1321#define RKISP1_CIF_ISP_WDR_OFFSET (RKISP1_CIF_ISP_WDR_BASE + 0x00000098)
1336#define RKISP1_CIF_ISP_WDR_DELTAMIN (RKISP1_CIF_ISP_WDR_BASE + 0x0000009c)1322#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)1323#define RKISP1_CIF_ISP_WDR_TONECURVE_SHD(n) (RKISP1_CIF_ISP_WDR_BASE + 0x000000a0 + (n) * 4)
1338#define RKISP1_CIF_ISP_WDR_TONECURVE_2_SHD (RKISP1_CIF_ISP_WDR_BASE + 0x000000a4)1324#define RKISP1_CIF_ISP_WDR_TONECURVE_YM_SHD(n) (RKISP1_CIF_ISP_WDR_BASE + 0x000000b0 + (n) * 4)
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)
1374 1325
1375#define RKISP1_CIF_ISP_HIST_BASE_V12 0x00002c001326#define RKISP1_CIF_ISP_HIST_BASE_V12 0x00002c00
1376#define RKISP1_CIF_ISP_HIST_CTRL_V12 (RKISP1_CIF_ISP_HIST_BASE_V12 + 0x00000000)1327#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
11 11
12#include <linux/clk.h>12#include <linux/clk.h>
13#include <linux/interrupt.h>13#include <linux/interrupt.h>
14#include <linux/iommu.h>
14#include <linux/module.h>15#include <linux/module.h>
15#include <linux/of.h>16#include <linux/of.h>
16#include <linux/platform_device.h>17#include <linux/platform_device.h>
@@ -1055,24 +1056,42 @@ static void rkvdec_v4l2_cleanup(struct rkvdec_dev *rkvdec) · 1038 unmodified lines
1055 v4l2_device_unregister(&rkvdec->v4l2_dev);1056 v4l2_device_unregister(&rkvdec->v4l2_dev);
1056}1057}
1057 1058
1059static 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
1058static irqreturn_t rkvdec_irq_handler(int irq, void *priv)1074static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
1059{1075{
1060 struct rkvdec_dev *rkvdec = priv;1076 struct rkvdec_dev *rkvdec = priv;
1077 struct rkvdec_ctx *ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
1061 enum vb2_buffer_state state;1078 enum vb2_buffer_state state;
1062 u32 status;1079 u32 status;
1063 1080
1064 status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT);1081 status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT);
1065 state = (status & RKVDEC_RDY_STA) ?
1066 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
1067
1068 writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT);1082 writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT);
1069 if (cancel_delayed_work(&rkvdec->watchdog_work)) {
1070 struct rkvdec_ctx *ctx;
1071 1083
1072 ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);1084 if (status & RKVDEC_RDY_STA) {
1073 rkvdec_job_finish(ctx, state);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);
1074 }1090 }
1075 1091
1092 if (cancel_delayed_work(&rkvdec->watchdog_work))
1093 rkvdec_job_finish(ctx, state);
1094
1076 return IRQ_HANDLED;1095 return IRQ_HANDLED;
1077}1096}
1078 1097
@@ -1140,6 +1159,13 @@ static int rkvdec_probe(struct platform_device *pdev) · 61 unmodified lines
1140 return ret;1159 return ret;
1141 }1160 }
1142 1161
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
1143 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));1169 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
1144 1170
1145 irq = platform_get_irq(pdev, 0);1171 irq = platform_get_irq(pdev, 0);
@@ -1179,6 +1205,9 @@ static void rkvdec_remove(struct platform_device *pdev) · 33 unmodified lines
1179 rkvdec_v4l2_cleanup(rkvdec);1205 rkvdec_v4l2_cleanup(rkvdec);
1180 pm_runtime_disable(&pdev->dev);1206 pm_runtime_disable(&pdev->dev);
1181 pm_runtime_dont_use_autosuspend(&pdev->dev);1207 pm_runtime_dont_use_autosuspend(&pdev->dev);
1208
1209 if (rkvdec->empty_domain)
1210 iommu_domain_free(rkvdec->empty_domain);
1182}1211}
1183 1212
1184#ifdef CONFIG_PM1213#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
110 void __iomem *regs;110 void __iomem *regs;
111 struct mutex vdev_lock; /* serializes ioctls */111 struct mutex vdev_lock; /* serializes ioctls */
112 struct delayed_work watchdog_work;112 struct delayed_work watchdog_work;
113 struct iommu_domain *empty_domain;
113};114};
114 115
115struct rkvdec_ctx {116struct 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
131};131};
132 132
133static const struct of_device_id fimc_is_i2c_of_match[] = {133static const struct of_device_id fimc_is_i2c_of_match[] = {
134 { .compatible = FIMC_IS_I2C_COMPATIBLE },134 { .compatible = "samsung,exynos4212-i2c-isp" },
135 { },135 { },
136};136};
137 137
drivers/media/platform/samsung/exynos4-is/fimc-is-i2c.h+0−2
@@ -6,7 +6,5 @@ · 5 unmodified lines
6 * Sylwester Nawrocki <s.nawrocki@samsung.com>6 * Sylwester Nawrocki <s.nawrocki@samsung.com>
7 */7 */
8 8
9#define FIMC_IS_I2C_COMPATIBLE "samsung,exynos4212-i2c-isp"
10
11int fimc_is_register_i2c_driver(void);9int fimc_is_register_i2c_driver(void);
12void fimc_is_unregister_i2c_driver(void);10void 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
207 if (ret < 0)207 if (ret < 0)
208 return ret;208 return ret;
209 209
210 for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) {210 for_each_compatible_node(i2c_bus, NULL, "samsung,exynos4212-i2c-isp") {
211 for_each_available_child_of_node(i2c_bus, child) {211 for_each_available_child_of_node(i2c_bus, child) {
212 ret = fimc_is_parse_sensor_config(is, index, child);212 ret = fimc_is_parse_sensor_config(is, index, child);
213 213
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
482static int fimc_md_parse_port_node(struct fimc_md *fmd,482static int fimc_md_parse_port_node(struct fimc_md *fmd,
483 struct device_node *port)483 struct device_node *port)
484{484{
485 struct device_node *ep;
486 int ret;485 int ret;
487 486
488 for_each_child_of_node(port, ep) {487 for_each_child_of_node_scoped(port, ep) {
489 ret = fimc_md_parse_one_endpoint(fmd, ep);488 ret = fimc_md_parse_one_endpoint(fmd, ep);
490 if (ret < 0) {489 if (ret < 0)
491 of_node_put(ep);
492 return ret;490 return ret;
493 }
494 }491 }
495 492
496 return 0;493 return 0;
@@ -501,7 +498,6 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) · 4 unmodified lines
501{498{
502 struct device_node *parent = fmd->pdev->dev.of_node;499 struct device_node *parent = fmd->pdev->dev.of_node;
503 struct device_node *ports = NULL;500 struct device_node *ports = NULL;
504 struct device_node *node;
505 int ret;501 int ret;
506 502
507 /*503 /*
@@ -518,7 +514,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) · 10 unmodified lines
518 fmd->num_sensors = 0;514 fmd->num_sensors = 0;
519 515
520 /* Attach sensors linked to MIPI CSI-2 receivers */516 /* 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) {
522 struct device_node *port;518 struct device_node *port;
523 519
524 if (!of_node_name_eq(node, "csis"))520 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
530 526
531 ret = fimc_md_parse_port_node(fmd, port);527 ret = fimc_md_parse_port_node(fmd, port);
532 of_node_put(port);528 of_node_put(port);
533 if (ret < 0) {529 if (ret < 0)
534 of_node_put(node);
535 goto cleanup;530 goto cleanup;
536 }
537 }531 }
538 532
539 /* Attach sensors listed in the parallel-ports node */533 /* 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
541 if (!ports)535 if (!ports)
542 goto rpm_put;536 goto rpm_put;
543 537
544 for_each_child_of_node(ports, node) {538 for_each_child_of_node_scoped(ports, node) {
545 ret = fimc_md_parse_port_node(fmd, node);539 ret = fimc_md_parse_port_node(fmd, node);
546 if (ret < 0) {540 if (ret < 0)
547 of_node_put(node);
548 goto cleanup;541 goto cleanup;
549 }
550 }542 }
551 of_node_put(ports);543 of_node_put(ports);
552 544
@@ -736,10 +728,9 @@ dev_unlock: · 183 unmodified lines
736static int fimc_md_register_platform_entities(struct fimc_md *fmd,728static int fimc_md_register_platform_entities(struct fimc_md *fmd,
737 struct device_node *parent)729 struct device_node *parent)
738{730{
739 struct device_node *node;
740 int ret = 0;731 int ret = 0;
741 732
742 for_each_available_child_of_node(parent, node) {733 for_each_available_child_of_node_scoped(parent, node) {
743 struct platform_device *pdev;734 struct platform_device *pdev;
744 int plat_entity = -1;735 int plat_entity = -1;
745 736
@@ -762,10 +753,8 @@ static int fimc_md_register_platform_entities(struct fimc_md *fmd, · 16 unmodified lines
762 ret = fimc_md_register_platform_entity(fmd, pdev,753 ret = fimc_md_register_platform_entity(fmd, pdev,
763 plat_entity);754 plat_entity);
764 put_device(&pdev->dev);755 put_device(&pdev->dev);
765 if (ret < 0) {756 if (ret < 0)
766 of_node_put(node);
767 break;757 break;
768 }
769 }758 }
770 759
771 return ret;760 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
658static int c8sectpfe_probe(struct platform_device *pdev)658static int c8sectpfe_probe(struct platform_device *pdev)
659{659{
660 struct device *dev = &pdev->dev;660 struct device *dev = &pdev->dev;
661 struct device_node *child, *np = dev->of_node;661 struct device_node *np = dev->of_node;
662 struct c8sectpfei *fei;662 struct c8sectpfei *fei;
663 struct resource *res;663 struct resource *res;
664 int ret, index = 0;664 int ret, index = 0;
@@ -742,17 +742,15 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 77 unmodified lines
742 return PTR_ERR(fei->pinctrl);742 return PTR_ERR(fei->pinctrl);
743 }743 }
744 744
745 for_each_child_of_node(np, child) {745 for_each_child_of_node_scoped(np, child) {
746 struct device_node *i2c_bus;746 struct device_node *i2c_bus;
747 747
748 fei->channel_data[index] = devm_kzalloc(dev,748 fei->channel_data[index] = devm_kzalloc(dev,
749 sizeof(struct channel_info),749 sizeof(struct channel_info),
750 GFP_KERNEL);750 GFP_KERNEL);
751 751
752 if (!fei->channel_data[index]) {752 if (!fei->channel_data[index])
753 ret = -ENOMEM;753 return -ENOMEM;
754 goto err_node_put;
755 }
756 754
757 tsin = fei->channel_data[index];755 tsin = fei->channel_data[index];
758 756
@@ -761,7 +759,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 2 unmodified lines
761 ret = of_property_read_u32(child, "tsin-num", &tsin->tsin_id);759 ret = of_property_read_u32(child, "tsin-num", &tsin->tsin_id);
762 if (ret) {760 if (ret) {
763 dev_err(&pdev->dev, "No tsin_num found\n");761 dev_err(&pdev->dev, "No tsin_num found\n");
764 goto err_node_put;762 return ret;
765 }763 }
766 764
767 /* sanity check value */765 /* sanity check value */
@@ -769,8 +767,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 1 unmodified line
769 dev_err(&pdev->dev,767 dev_err(&pdev->dev,
770 "tsin-num %d specified greater than number\n\tof input block hw in SoC! (%d)",768 "tsin-num %d specified greater than number\n\tof input block hw in SoC! (%d)",
771 tsin->tsin_id, fei->hw_stats.num_ib);769 tsin->tsin_id, fei->hw_stats.num_ib);
772 ret = -EINVAL;770 return -EINVAL;
773 goto err_node_put;
774 }771 }
775 772
776 tsin->invert_ts_clk = of_property_read_bool(child,773 tsin->invert_ts_clk = of_property_read_bool(child,
@@ -786,22 +783,20 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 9 unmodified lines
786 &tsin->dvb_card);783 &tsin->dvb_card);
787 if (ret) {784 if (ret) {
788 dev_err(&pdev->dev, "No dvb-card found\n");785 dev_err(&pdev->dev, "No dvb-card found\n");
789 goto err_node_put;786 return ret;
790 }787 }
791 788
792 i2c_bus = of_parse_phandle(child, "i2c-bus", 0);789 i2c_bus = of_parse_phandle(child, "i2c-bus", 0);
793 if (!i2c_bus) {790 if (!i2c_bus) {
794 dev_err(&pdev->dev, "No i2c-bus found\n");791 dev_err(&pdev->dev, "No i2c-bus found\n");
795 ret = -ENODEV;792 return -ENODEV;
796 goto err_node_put;
797 }793 }
798 tsin->i2c_adapter =794 tsin->i2c_adapter =
799 of_find_i2c_adapter_by_node(i2c_bus);795 of_find_i2c_adapter_by_node(i2c_bus);
800 of_node_put(i2c_bus);796 of_node_put(i2c_bus);
801 if (!tsin->i2c_adapter) {797 if (!tsin->i2c_adapter) {
802 dev_err(&pdev->dev, "No i2c adapter found\n");798 dev_err(&pdev->dev, "No i2c adapter found\n");
803 ret = -ENODEV;799 return -ENODEV;
804 goto err_node_put;
805 }800 }
806 801
807 /* Acquire reset GPIO and activate it */802 /* Acquire reset GPIO and activate it */
@@ -813,7 +808,7 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 5 unmodified lines
813 if (ret && ret != -EBUSY) {808 if (ret && ret != -EBUSY) {
814 dev_err(dev, "Can't request tsin%d reset gpio\n",809 dev_err(dev, "Can't request tsin%d reset gpio\n",
815 fei->channel_data[index]->tsin_id);810 fei->channel_data[index]->tsin_id);
816 goto err_node_put;811 return ret;
817 }812 }
818 813
819 if (!ret) {814 if (!ret) {
@@ -855,10 +850,6 @@ static int c8sectpfe_probe(struct platform_device *pdev) · 35 unmodified lines
855 c8sectpfe_debugfs_init(fei);850 c8sectpfe_debugfs_init(fei);
856 851
857 return 0;852 return 0;
858
859err_node_put:
860 of_node_put(child);
861 return ret;
862}853}
863 854
864static void c8sectpfe_remove(struct platform_device *pdev)855static void c8sectpfe_remove(struct platform_device *pdev)
@@ -897,16 +888,15 @@ static void c8sectpfe_remove(struct platform_device *pdev) · 32 unmodified lines
897static int configure_channels(struct c8sectpfei *fei)888static int configure_channels(struct c8sectpfei *fei)
898{889{
899 int index = 0, ret;890 int index = 0, ret;
900 struct device_node *child, *np = fei->dev->of_node;891 struct device_node *np = fei->dev->of_node;
901 892
902 /* iterate round each tsin and configure memdma descriptor and IB hw */893 /* 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) {
904 ret = configure_memdma_and_inputblock(fei,895 ret = configure_memdma_and_inputblock(fei,
905 fei->channel_data[index]);896 fei->channel_data[index]);
906 if (ret) {897 if (ret) {
907 dev_err(fei->dev,898 dev_err(fei->dev,
908 "configure_memdma_and_inputblock failed\n");899 "configure_memdma_and_inputblock failed\n");
909 of_node_put(child);
910 goto err_unmap;900 goto err_unmap;
911 }901 }
912 index++;902 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
619 619
620 if (ti_csi2rx_start_dma(csi, buf)) {620 if (ti_csi2rx_start_dma(csi, buf)) {
621 dev_err(csi->dev, "Failed to queue the next buffer for DMA\n");621 dev_err(csi->dev, "Failed to queue the next buffer for DMA\n");
622 list_del(&buf->list);
622 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);623 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
623 } else {624 } else {
624 list_move_tail(&buf->list, &dma->submitted);625 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
895 q->dev = dmaengine_get_dma_device(csi->dma.chan);896 q->dev = dmaengine_get_dma_device(csi->dma.chan);
896 q->lock = &csi->mutex;897 q->lock = &csi->mutex;
897 q->min_queued_buffers = 1;898 q->min_queued_buffers = 1;
899 q->allow_cache_hints = 1;
898 900
899 ret = vb2_queue_init(q);901 ret = vb2_queue_init(q);
900 if (ret)902 if (ret)
drivers/media/platform/ti/vpe/vpdma.c+0−32
@@ -552,38 +552,6 @@ EXPORT_SYMBOL(vpdma_submit_descs); · 551 unmodified lines
552 552
553static void dump_dtd(struct vpdma_dtd *dtd);553static void dump_dtd(struct vpdma_dtd *dtd);
554 554
555void 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}
585EXPORT_SYMBOL(vpdma_update_dma_addr);
586
587void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,555void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
588 u32 width, u32 height)556 u32 width, u32 height)
589{557{
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
222int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list,222int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list,
223 int list_num);223 int list_num);
224bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num);224bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num);
225void 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);
228 225
229/* VPDMA hardware list funcs */226/* VPDMA hardware list funcs */
230int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv);227int 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
323 struct hantro_reg output_fmt;323 struct hantro_reg output_fmt;
324 struct hantro_reg orig_width;324 struct hantro_reg orig_width;
325 struct hantro_reg display_width;325 struct hantro_reg display_width;
326 struct hantro_reg input_width_ext;
327 struct hantro_reg input_height_ext;
326};328};
327 329
328struct hantro_vp9_decoded_buffer_info {330struct hantro_vp9_decoded_buffer_info {
drivers/media/platform/verisilicon/hantro_g1_regs.h+1−1
@@ -350,7 +350,7 @@ · 349 unmodified lines
350#define G1_REG_PP_CONTROL_OUT_WIDTH(v) (((v) << 4) & GENMASK(14, 4))350#define G1_REG_PP_CONTROL_OUT_WIDTH(v) (((v) << 4) & GENMASK(14, 4))
351#define G1_REG_PP_MASK1_ORIG_WIDTH G1_SWREG(88)351#define G1_REG_PP_MASK1_ORIG_WIDTH G1_SWREG(88)
352#define G1_REG_PP_ORIG_WIDTH(v) (((v) << 23) & GENMASK(31, 23))352#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)
354#define G1_REG_PP_FUSE G1_SWREG(99)354#define G1_REG_PP_FUSE G1_SWREG(99)
355 355
356#endif /* HANTRO_G1_REGS_H_ */356#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
325 continue;325 continue;
326 326
327 *cdpb = *ndpb;327 *cdpb = *ndpb;
328 set_bit(j, used);328 __set_bit(j, used);
329 break;329 break;
330 }330 }
331 331
332 if (j == ARRAY_SIZE(ctx->h264_dec.dpb))332 if (j == ARRAY_SIZE(ctx->h264_dec.dpb))
333 set_bit(i, new);333 __set_bit(i, new);
334 }334 }
335 335
336 /* For entries that could not be matched, use remaining free slots. */336 /* 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
349 349
350 cdpb = &ctx->h264_dec.dpb[j];350 cdpb = &ctx->h264_dec.dpb[j];
351 *cdpb = *ndpb;351 *cdpb = *ndpb;
352 set_bit(j, used);352 __set_bit(j, used);
353 }353 }
354}354}
355 355
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
49 .input_fmt = {G1_REG_PP_CONTROL, 29, 0x7},49 .input_fmt = {G1_REG_PP_CONTROL, 29, 0x7},
50 .output_fmt = {G1_REG_PP_CONTROL, 26, 0x7},50 .output_fmt = {G1_REG_PP_CONTROL, 26, 0x7},
51 .orig_width = {G1_REG_PP_MASK1_ORIG_WIDTH, 23, 0x1ff},51 .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},
53};55};
54 56
55bool hantro_needs_postproc(const struct hantro_ctx *ctx,57bool 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
103 HANTRO_PP_REG_WRITE(vpu, output_height, ctx->dst_fmt.height);105 HANTRO_PP_REG_WRITE(vpu, output_height, ctx->dst_fmt.height);
104 HANTRO_PP_REG_WRITE(vpu, orig_width, MB_WIDTH(ctx->dst_fmt.width));106 HANTRO_PP_REG_WRITE(vpu, orig_width, MB_WIDTH(ctx->dst_fmt.width));
105 HANTRO_PP_REG_WRITE(vpu, display_width, ctx->dst_fmt.width);107 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));
106}110}
107 111
108static int down_scale_factor(struct hantro_ctx *ctx)112static 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
17 17
18#define RK3066_ACLK_MAX_FREQ (300 * 1000 * 1000)18#define RK3066_ACLK_MAX_FREQ (300 * 1000 * 1000)
19#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000)19#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000)
20#define RK3588_ACLK_MAX_FREQ (300 * 1000 * 1000)
21 20
22#define ROCKCHIP_VPU981_MIN_SIZE 6421#define ROCKCHIP_VPU981_MIN_SIZE 64
23 22
@@ -454,13 +453,6 @@ static int rk3066_vpu_hw_init(struct hantro_dev *vpu) · 430 unmodified lines
454 return 0;453 return 0;
455}454}
456 455
457static 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
464static int rockchip_vpu_hw_init(struct hantro_dev *vpu)456static int rockchip_vpu_hw_init(struct hantro_dev *vpu)
465{457{
466 /* Bump ACLK to max. possible freq. to improve performance. */458 /* Bump ACLK to max. possible freq. to improve performance. */
@@ -821,7 +813,6 @@ const struct hantro_variant rk3588_vpu981_variant = { · 354 unmodified lines
821 .codec_ops = rk3588_vpu981_codec_ops,813 .codec_ops = rk3588_vpu981_codec_ops,
822 .irqs = rk3588_vpu981_irqs,814 .irqs = rk3588_vpu981_irqs,
823 .num_irqs = ARRAY_SIZE(rk3588_vpu981_irqs),815 .num_irqs = ARRAY_SIZE(rk3588_vpu981_irqs),
824 .init = rk3588_vpu981_hw_init,
825 .clk_names = rk3588_vpu981_vpu_clk_names,816 .clk_names = rk3588_vpu981_vpu_clk_names,
826 .num_clocks = ARRAY_SIZE(rk3588_vpu981_vpu_clk_names)817 .num_clocks = ARRAY_SIZE(rk3588_vpu981_vpu_clk_names)
827};818};
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
450static int xvip_graph_dma_init(struct xvip_composite_device *xdev)450static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
451{451{
452 struct device_node *ports;452 struct device_node *ports;
453 struct device_node *port;
454 int ret = 0;453 int ret = 0;
455 454
456 ports = of_get_child_by_name(xdev->dev->of_node, "ports");455 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
459 return -EINVAL;458 return -EINVAL;
460 }459 }
461 460
462 for_each_child_of_node(ports, port) {461 for_each_child_of_node_scoped(ports, port) {
463 ret = xvip_graph_dma_init_one(xdev, port);462 ret = xvip_graph_dma_init_one(xdev, port);
464 if (ret) {463 if (ret)
465 of_node_put(port);
466 break;464 break;
467 }
468 }465 }
469 466
470 of_node_put(ports);467 of_node_put(ports);
drivers/media/rc/ir-spi.c+26−14
@@ -21,13 +21,12 @@ · 20 unmodified lines
21#define IR_SPI_DRIVER_NAME "ir-spi"21#define IR_SPI_DRIVER_NAME "ir-spi"
22 22
23#define IR_SPI_DEFAULT_FREQUENCY 3800023#define IR_SPI_DEFAULT_FREQUENCY 38000
24#define IR_SPI_MAX_BUFSIZE 409624#define IR_SPI_BITS_PER_PULSE 16
25 25
26struct ir_spi_data {26struct ir_spi_data {
27 u32 freq;27 u32 freq;
28 bool negated;28 bool negated;
29 29
30 u16 tx_buf[IR_SPI_MAX_BUFSIZE];
31 u16 pulse;30 u16 pulse;
32 u16 space;31 u16 space;
33 32
@@ -43,17 +42,23 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun · 9 unmodified lines
43 unsigned int len = 0;42 unsigned int len = 0;
44 struct ir_spi_data *idata = dev->priv;43 struct ir_spi_data *idata = dev->priv;
45 struct spi_transfer xfer;44 struct spi_transfer xfer;
45 u16 *tx_buf;
46 46
47 /* convert the pulse/space signal to raw binary signal */47 /* convert the pulse/space signal to raw binary signal */
48 for (i = 0; i < count; i++) {48 for (i = 0; i < count; i++) {
49 unsigned int periods;49 buffer[i] = DIV_ROUND_CLOSEST_ULL((u64)buffer[i] * idata->freq,
50 int j;50 1000000);
51 u16 val;51 len += buffer[i];
52 }
52 53
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;
54 57
55 if (len + periods >= IR_SPI_MAX_BUFSIZE)58 len = 0;
56 return -EINVAL;59 for (i = 0; i < count; i++) {
60 int j;
61 u16 val;
57 62
58 /*63 /*
59 * The first value in buffer is a pulse, so that 0, 2, 4, ...64 * 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
61 * contain a space duration.66 * contain a space duration.
62 */67 */
63 val = (i % 2) ? idata->space : idata->pulse;68 val = (i % 2) ? idata->space : idata->pulse;
64 for (j = 0; j < periods; j++)69 for (j = 0; j < buffer[i]; j++)
65 idata->tx_buf[len++] = val;70 tx_buf[len++] = val;
66 }71 }
67 72
68 memset(&xfer, 0, sizeof(xfer));73 memset(&xfer, 0, sizeof(xfer));
69 74
70 xfer.speed_hz = idata->freq * 16;75 xfer.speed_hz = idata->freq * IR_SPI_BITS_PER_PULSE;
71 xfer.len = len * sizeof(*idata->tx_buf);76 xfer.len = len * sizeof(*tx_buf);
72 xfer.tx_buf = idata->tx_buf;77 xfer.tx_buf = tx_buf;
73 78
74 ret = regulator_enable(idata->regulator);79 ret = regulator_enable(idata->regulator);
75 if (ret)80 if (ret)
76 return ret;81 goto err_free_tx_buf;
77 82
78 ret = spi_sync_transfer(idata->spi, &xfer, 1);83 ret = spi_sync_transfer(idata->spi, &xfer, 1);
79 if (ret)84 if (ret)
@@ -81,6 +86,10 @@ static int ir_spi_tx(struct rc_dev *dev, unsigned int *buffer, unsigned int coun · 1 unmodified line
81 86
82 regulator_disable(idata->regulator);87 regulator_disable(idata->regulator);
83 88
89err_free_tx_buf:
90
91 kfree(tx_buf);
92
84 return ret ? ret : count;93 return ret ? ret : count;
85}94}
86 95
@@ -91,6 +100,9 @@ static int ir_spi_set_tx_carrier(struct rc_dev *dev, u32 carrier) · 4 unmodified lines
91 if (!carrier)100 if (!carrier)
92 return -EINVAL;101 return -EINVAL;
93 102
103 if (carrier > idata->spi->max_speed_hz / IR_SPI_BITS_PER_PULSE)
104 return -EINVAL;
105
94 idata->freq = carrier;106 idata->freq = carrier;
95 107
96 return 0;108 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
244 .min = 0x00,244 .min = 0x00,
245 .max = 0xff,245 .max = 0xff,
246 .step = 1,246 .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) },
248};249};
249 250
250static const struct v4l2_ctrl_config vivid_ctrl_s32_array = {251static 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
5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 */6 */
7 7
8#include <linux/bitops.h>
8#include <linux/errno.h>9#include <linux/errno.h>
9#include <linux/kernel.h>10#include <linux/kernel.h>
10#include <linux/ktime.h>11#include <linux/ktime.h>
@@ -165,12 +166,7 @@ static const u8 vivid_cc_sequence2[30] = { · 154 unmodified lines
165 166
166static u8 calc_parity(u8 val)167static u8 calc_parity(u8 val)
167{168{
168 unsigned i;169 return val | (parity8(val) ? 0 : 0x80);
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);
174}170}
175 171
176static void vivid_vbi_gen_set_time_of_day(u8 *packet)172static 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
454 if (keep_controls)454 if (keep_controls)
455 return;455 return;
456 456
457 dims[0] = roundup(dev->src_rect.width, PIXEL_ARRAY_DIV);457 dims[0] = DIV_ROUND_UP(dev->src_rect.height, PIXEL_ARRAY_DIV);
458 dims[1] = roundup(dev->src_rect.height, PIXEL_ARRAY_DIV);458 dims[1] = DIV_ROUND_UP(dev->src_rect.width, PIXEL_ARRAY_DIV);
459 v4l2_ctrl_modify_dimensions(dev->pixel_array, dims);459 v4l2_ctrl_modify_dimensions(dev->pixel_array, dims);
460}460}
461 461
drivers/media/usb/gspca/vicam.c+8−2
@@ -227,6 +227,7 @@ static int sd_init(struct gspca_dev *gspca_dev) · 226 unmodified lines
227 const struct ihex_binrec *rec;227 const struct ihex_binrec *rec;
228 const struct firmware *fw;228 const struct firmware *fw;
229 u8 *firmware_buf;229 u8 *firmware_buf;
230 int len;
230 231
231 ret = request_ihex_firmware(&fw, VICAM_FIRMWARE,232 ret = request_ihex_firmware(&fw, VICAM_FIRMWARE,
232 &gspca_dev->dev->dev);233 &gspca_dev->dev->dev);
@@ -241,9 +242,14 @@ static int sd_init(struct gspca_dev *gspca_dev) · 8 unmodified lines
241 goto exit;242 goto exit;
242 }243 }
243 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {244 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);
245 ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,251 ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,
246 be16_to_cpu(rec->len));252 len);
247 if (ret < 0)253 if (ret < 0)
248 break;254 break;
249 }255 }
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
124 else124 else
125 retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf,125 retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf,
126 msgs[0].len);126 msgs[0].len);
127 } else if (num == 2) {127 } else {
128 if (msgs[0].addr != msgs[1].addr) {128 /* do write-then-read */
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 */
146 retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len,129 retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len,
147 msgs[1].buf, msgs[1].len);130 msgs[1].buf, msgs[1].len);
148 } else {
149 v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num);
150 }131 }
151 132
152out:
153 mutex_unlock(&dev->i2c_mutex);133 mutex_unlock(&dev->i2c_mutex);
154 134
155 return retval ? retval : num;135 return retval ? retval : num;
@@ -165,10 +145,16 @@ static const struct i2c_algorithm hdpvr_algo = { · 9 unmodified lines
165 .functionality = hdpvr_functionality,145 .functionality = hdpvr_functionality,
166};146};
167 147
148/* prevent invalid 0-length usb_control_msg and support only write-then-read */
149static const struct i2c_adapter_quirks hdpvr_quirks = {
150 .flags = I2C_AQ_NO_ZERO_LEN_READ | I2C_AQ_COMB_WRITE_THEN_READ,
151};
152
168static const struct i2c_adapter hdpvr_i2c_adapter_template = {153static const struct i2c_adapter hdpvr_i2c_adapter_template = {
169 .name = "Hauppauge HD PVR I2C",154 .name = "Hauppauge HD PVR I2C",
170 .owner = THIS_MODULE,155 .owner = THIS_MODULE,
171 .algo = &hdpvr_algo,156 .algo = &hdpvr_algo,
157 .quirks = &hdpvr_quirks,
172};158};
173 159
174static int hdpvr_activate_ir(struct hdpvr_device *dev)160static 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
73 }73 }
74 74
75 if (params) {75 if (params) {
76 if (vb2_is_busy(&usbtv->vb2q) &&
77 (usbtv->width != params->cap_width ||
78 usbtv->height != params->cap_height))
79 return -EBUSY;
76 usbtv->width = params->cap_width;80 usbtv->width = params->cap_width;
77 usbtv->height = params->cap_height;81 usbtv->height = params->cap_height;
78 usbtv->n_chunks = usbtv->width * usbtv->height82 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
1483 return ~0;1483 return ~0;
1484}1484}
1485 1485
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
1486static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,1492static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,
1487 struct uvc_control *ctrl,1493 struct uvc_control *ctrl,
1488 struct uvc_control_mapping *mapping,1494 struct uvc_control_mapping *mapping,
1489 struct v4l2_query_ext_ctrl *v4l2_ctrl)1495 struct v4l2_query_ext_ctrl *v4l2_ctrl)
1490{1496{
1491 if (!ctrl->cached) {1497 if (!ctrl->cached) {
1492 int ret = uvc_ctrl_populate_cache(chain, ctrl);1498 unsigned int retries;
1493 if (ret < 0)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)
1494 return ret;1508 return ret;
1495 }1509 }
1496 1510
@@ -1567,6 +1581,7 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, · 70 unmodified lines
1567{1581{
1568 struct uvc_control_mapping *master_map = NULL;1582 struct uvc_control_mapping *master_map = NULL;
1569 struct uvc_control *master_ctrl = NULL;1583 struct uvc_control *master_ctrl = NULL;
1584 int ret;
1570 1585
1571 memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));1586 memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));
1572 v4l2_ctrl->id = mapping->id;1587 v4l2_ctrl->id = mapping->id;
@@ -1587,18 +1602,31 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, · 14 unmodified lines
1587 __uvc_find_control(ctrl->entity, mapping->master_id,1602 __uvc_find_control(ctrl->entity, mapping->master_id,
1588 &master_map, &master_ctrl, 0, 0);1603 &master_map, &master_ctrl, 0, 0);
1589 if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {1604 if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {
1605 unsigned int retries;
1590 s32 val;1606 s32 val;
1591 int ret;1607 int ret;
1592 1608
1593 if (WARN_ON(uvc_ctrl_mapping_is_compound(master_map)))1609 if (WARN_ON(uvc_ctrl_mapping_is_compound(master_map)))
1594 return -EIO;1610 return -EIO;
1595 1611
1596 ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);1612 for (retries = 0; retries < MAX_QUERY_RETRIES; retries++) {
1597 if (ret < 0)1613 ret = __uvc_ctrl_get(chain, master_ctrl, master_map,
1598 return ret;1614 &val);
1615 if (!ret)
1616 break;
1617 if (ret < 0 && ret != -EIO)
1618 return ret;
1619 }
1599 1620
1600 if (val != mapping->master_manual)1621 if (ret == -EIO) {
1601 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;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 }
1602 }1630 }
1603 1631
1604 v4l2_ctrl->elem_size = uvc_mapping_v4l2_size(mapping);1632 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
1613 return 0;1641 return 0;
1614 }1642 }
1615 1643
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;
1617}1656}
1618 1657
1619int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,1658int 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
1812 uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);1851 uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
1813}1852}
1814 1853
1815static int uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl,1854static int uvc_ctrl_set_handle(struct uvc_control *ctrl, struct uvc_fh *handle)
1816 struct uvc_fh *new_handle)
1817{1855{
1818 lockdep_assert_held(&handle->chain->ctrl_mutex);1856 int ret;
1819
1820 if (new_handle) {
1821 int ret;
1822 1857
1823 if (ctrl->handle)1858 lockdep_assert_held(&handle->chain->ctrl_mutex);
1824 dev_warn_ratelimited(&handle->stream->dev->udev->dev,
1825 "UVC non compliance: Setting an async control with a pending operation.");
1826 1859
1827 if (new_handle == ctrl->handle)1860 if (ctrl->handle) {
1828 return 0;1861 dev_warn_ratelimited(&handle->stream->dev->udev->dev,
1862 "UVC non compliance: Setting an async control with a pending operation.");
1829 1863
1830 if (ctrl->handle) {1864 if (ctrl->handle == 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++;
1836 return 0;1865 return 0;
1837 }
1838
1839 ret = uvc_pm_get(handle->chain->dev);
1840 if (ret)
1841 return ret;
1842 1866
1843 ctrl->handle = new_handle;1867 WARN_ON(!ctrl->handle->pending_async_ctrls);
1844 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++;
1845 return 0;1872 return 0;
1846 }1873 }
1847 1874
1848 /* Cannot clear the handle for a control not owned by us.*/1875 ret = uvc_pm_get(handle->chain->dev);
1849 if (WARN_ON(ctrl->handle != handle))1876 if (ret)
1877 return ret;
1878
1879 ctrl->handle = handle;
1880 ctrl->handle->pending_async_ctrls++;
1881 return 0;
1882}
1883
1884static 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;
1850 return -EINVAL;1890 return -EINVAL;
1891 }
1851 1892
1893 ctrl->handle->pending_async_ctrls--;
1894 uvc_pm_put(ctrl->handle->chain->dev);
1852 ctrl->handle = NULL;1895 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);
1857 return 0;1896 return 0;
1858}1897}
1859 1898
@@ -1871,7 +1910,7 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, · 11 unmodified lines
1871 1910
1872 handle = ctrl->handle;1911 handle = ctrl->handle;
1873 if (handle)1912 if (handle)
1874 uvc_ctrl_set_handle(handle, ctrl, NULL);1913 uvc_ctrl_clear_handle(ctrl);
1875 1914
1876 list_for_each_entry(mapping, &ctrl->info.mappings, list) {1915 list_for_each_entry(mapping, &ctrl->info.mappings, list) {
1877 s32 value;1916 s32 value;
@@ -2033,18 +2072,24 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) · 155 unmodified lines
2033 goto done;2072 goto done;
2034 }2073 }
2035 2074
2036 list_add_tail(&sev->node, &mapping->ev_subs);
2037 if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) {2075 if (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) {
2038 struct v4l2_event ev;2076 struct v4l2_event ev;
2039 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;2077 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
2040 s32 val = 0;2078 s32 val = 0;
2041 2079
2080 ret = uvc_pm_get(handle->chain->dev);
2081 if (ret)
2082 goto done;
2083
2042 if (uvc_ctrl_mapping_is_compound(mapping) ||2084 if (uvc_ctrl_mapping_is_compound(mapping) ||
2043 __uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)2085 __uvc_ctrl_get(handle->chain, ctrl, mapping, &val) == 0)
2044 changes |= V4L2_EVENT_CTRL_CH_VALUE;2086 changes |= V4L2_EVENT_CTRL_CH_VALUE;
2045 2087
2046 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,2088 uvc_ctrl_fill_event(handle->chain, &ev, ctrl, mapping, val,
2047 changes);2089 changes);
2090
2091 uvc_pm_put(handle->chain->dev);
2092
2048 /*2093 /*
2049 * Mark the queue as active, allowing this initial event to be2094 * Mark the queue as active, allowing this initial event to be
2050 * accepted.2095 * accepted.
@@ -2053,6 +2098,8 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) · 2 unmodified lines
2053 v4l2_event_queue_fh(sev->fh, &ev);2098 v4l2_event_queue_fh(sev->fh, &ev);
2054 }2099 }
2055 2100
2101 list_add_tail(&sev->node, &mapping->ev_subs);
2102
2056done:2103done:
2057 mutex_unlock(&handle->chain->ctrl_mutex);2104 mutex_unlock(&handle->chain->ctrl_mutex);
2058 return ret;2105 return ret;
@@ -2161,7 +2208,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, · 102 unmodified lines
2161 2208
2162 if (!rollback && handle && !ret &&2209 if (!rollback && handle && !ret &&
2163 ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)2210 ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
2164 ret = uvc_ctrl_set_handle(handle, ctrl, handle);2211 ret = uvc_ctrl_set_handle(ctrl, handle);
2165 2212
2166 if (ret < 0 && !rollback) {2213 if (ret < 0 && !rollback) {
2167 if (err_ctrl)2214 if (err_ctrl)
@@ -3271,7 +3318,7 @@ void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) · 1103 unmodified lines
3271 for (unsigned int i = 0; i < entity->ncontrols; ++i) {3318 for (unsigned int i = 0; i < entity->ncontrols; ++i) {
3272 if (entity->controls[i].handle != handle)3319 if (entity->controls[i].handle != handle)
3273 continue;3320 continue;
3274 uvc_ctrl_set_handle(handle, &entity->controls[i], NULL);3321 uvc_ctrl_clear_handle(&entity->controls[i]);
3275 }3322 }
3276 }3323 }
3277 3324
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
344 u8 ftype;344 u8 ftype;
345 int ret;345 int ret;
346 346
347 if (buflen < 4)
348 return -EINVAL;
349
347 format->type = buffer[2];350 format->type = buffer[2];
348 format->index = buffer[3];351 format->index = buffer[3];
349 format->frames = frames;352 format->frames = frames;
@@ -1866,7 +1869,7 @@ static int uvc_scan_device(struct uvc_device *dev) · 1516 unmodified lines
1866 1869
1867 if (list_empty(&dev->chains)) {1870 if (list_empty(&dev->chains)) {
1868 dev_info(&dev->udev->dev, "No valid video chain found.\n");1871 dev_info(&dev->udev->dev, "No valid video chain found.\n");
1869 return -1;1872 return -ENODEV;
1870 }1873 }
1871 1874
1872 /* Add GPIO entity to the first chain. */1875 /* Add GPIO entity to the first chain. */
@@ -1958,31 +1961,7 @@ static void uvc_unregister_video(struct uvc_device *dev) · 85 unmodified lines
1958 if (!video_is_registered(&stream->vdev))1961 if (!video_is_registered(&stream->vdev))
1959 continue;1962 continue;
1960 1963
1961 /*1964 vb2_video_unregister_device(&stream->vdev);
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 */
1986 vb2_video_unregister_device(&stream->meta.vdev);1965 vb2_video_unregister_device(&stream->meta.vdev);
1987 1966
1988 /*1967 /*
@@ -2030,6 +2009,8 @@ int uvc_register_video_device(struct uvc_device *dev, · 41 unmodified lines
2030 vdev->ioctl_ops = ioctl_ops;2009 vdev->ioctl_ops = ioctl_ops;
2031 vdev->release = uvc_release;2010 vdev->release = uvc_release;
2032 vdev->prio = &stream->chain->prio;2011 vdev->prio = &stream->chain->prio;
2012 vdev->queue = &queue->queue;
2013 vdev->lock = &queue->mutex;
2033 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)2014 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2034 vdev->vfl_dir = VFL_DIR_TX;2015 vdev->vfl_dir = VFL_DIR_TX;
2035 else2016 else
@@ -2239,7 +2220,6 @@ static int uvc_probe(struct usb_interface *intf, · 203 unmodified lines
2239 /* Parse the Video Class control descriptor. */2220 /* Parse the Video Class control descriptor. */
2240 ret = uvc_parse_control(dev);2221 ret = uvc_parse_control(dev);
2241 if (ret < 0) {2222 if (ret < 0) {
2242 ret = -ENODEV;
2243 uvc_dbg(dev, PROBE, "Unable to parse UVC descriptors\n");2223 uvc_dbg(dev, PROBE, "Unable to parse UVC descriptors\n");
2244 goto error;2224 goto error;
2245 }2225 }
@@ -2275,22 +2255,19 @@ static int uvc_probe(struct usb_interface *intf, · 29 unmodified lines
2275 goto error;2255 goto error;
2276 2256
2277 /* Scan the device for video chains. */2257 /* Scan the device for video chains. */
2278 if (uvc_scan_device(dev) < 0) {2258 ret = uvc_scan_device(dev);
2279 ret = -ENODEV;2259 if (ret < 0)
2280 goto error;2260 goto error;
2281 }
2282 2261
2283 /* Initialize controls. */2262 /* Initialize controls. */
2284 if (uvc_ctrl_init_device(dev) < 0) {2263 ret = uvc_ctrl_init_device(dev);
2285 ret = -ENODEV;2264 if (ret < 0)
2286 goto error;2265 goto error;
2287 }
2288 2266
2289 /* Register video device nodes. */2267 /* Register video device nodes. */
2290 if (uvc_register_chains(dev) < 0) {2268 ret = uvc_register_chains(dev);
2291 ret = -ENODEV;2269 if (ret < 0)
2292 goto error;2270 goto error;
2293 }
2294 2271
2295#ifdef CONFIG_MEDIA_CONTROLLER2272#ifdef CONFIG_MEDIA_CONTROLLER
2296 /* Register the media device node */2273 /* Register the media device node */
@@ -2316,6 +2293,13 @@ static int uvc_probe(struct usb_interface *intf, · 19 unmodified lines
2316 goto error;2293 goto error;
2317 }2294 }
2318 2295
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
2319 if (dev->quirks & UVC_QUIRK_NO_RESET_RESUME)2303 if (dev->quirks & UVC_QUIRK_NO_RESET_RESUME)
2320 udev->quirks &= ~USB_QUIRK_RESET_RESUME;2304 udev->quirks &= ~USB_QUIRK_RESET_RESUME;
2321 2305
@@ -2398,9 +2382,12 @@ static int __uvc_resume(struct usb_interface *intf, int reset) · 76 unmodified lines
2398 list_for_each_entry(stream, &dev->streams, list) {2382 list_for_each_entry(stream, &dev->streams, list) {
2399 if (stream->intf == intf) {2383 if (stream->intf == intf) {
2400 ret = uvc_video_resume(stream, reset);2384 ret = uvc_video_resume(stream, reset);
2401 if (ret < 0)2385 if (ret < 0) {
2402 uvc_queue_streamoff(&stream->queue,2386 mutex_lock(&stream->queue.mutex);
2403 stream->queue.queue.type);2387 vb2_streamoff(&stream->queue.queue,
2388 stream->queue.queue.type);
2389 mutex_unlock(&stream->queue.mutex);
2390 }
2404 return ret;2391 return ret;
2405 }2392 }
2406 }2393 }
@@ -2514,6 +2501,15 @@ static const struct uvc_device_info uvc_quirk_force_y8 = { · 107 unmodified lines
2514 * Sort these by vendor/product ID.2501 * Sort these by vendor/product ID.
2515 */2502 */
2516static const struct usb_device_id uvc_ids[] = {2503static 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 },
2517 /* Quanta ACER HD User Facing */2513 /* Quanta ACER HD User Facing */
2518 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE2514 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2519 | USB_DEVICE_ID_MATCH_INT_INFO,2515 | USB_DEVICE_ID_MATCH_INT_INFO,
drivers/media/usb/uvc/uvc_metadata.c+107−15
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/list.h>10#include <linux/list.h>
11#include <linux/module.h>11#include <linux/module.h>
12#include <linux/usb.h>12#include <linux/usb.h>
13#include <linux/usb/uvc.h>
13#include <linux/videodev2.h>14#include <linux/videodev2.h>
14 15
15#include <media/v4l2-ioctl.h>16#include <media/v4l2-ioctl.h>
@@ -63,15 +64,20 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *fh, · 47 unmodified lines
63 struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);64 struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
64 struct uvc_device *dev = stream->dev;65 struct uvc_device *dev = stream->dev;
65 struct v4l2_meta_format *fmt = &format->fmt.meta;66 struct v4l2_meta_format *fmt = &format->fmt.meta;
66 u32 fmeta = fmt->dataformat;67 u32 fmeta = V4L2_META_FMT_UVC;
67 68
68 if (format->type != vfh->vdev->queue->type)69 if (format->type != vfh->vdev->queue->type)
69 return -EINVAL;70 return -EINVAL;
70 71
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
71 memset(fmt, 0, sizeof(*fmt));78 memset(fmt, 0, sizeof(*fmt));
72 79
73 fmt->dataformat = fmeta == dev->info->meta_format80 fmt->dataformat = fmeta;
74 ? fmeta : V4L2_META_FMT_UVC;
75 fmt->buffersize = UVC_METADATA_BUF_SIZE;81 fmt->buffersize = UVC_METADATA_BUF_SIZE;
76 82
77 return 0;83 return 0;
@@ -96,7 +102,7 @@ static int uvc_meta_v4l2_set_format(struct file *file, void *fh, · 18 unmodified lines
96 */102 */
97 mutex_lock(&stream->mutex);103 mutex_lock(&stream->mutex);
98 104
99 if (uvc_queue_allocated(&stream->queue))105 if (vb2_is_busy(&stream->meta.queue.queue))
100 ret = -EBUSY;106 ret = -EBUSY;
101 else107 else
102 stream->meta.format = fmt->dataformat;108 stream->meta.format = fmt->dataformat;
@@ -112,17 +118,19 @@ static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh, · 9 unmodified lines
112 struct v4l2_fh *vfh = file->private_data;118 struct v4l2_fh *vfh = file->private_data;
113 struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);119 struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
114 struct uvc_device *dev = stream->dev;120 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;
116 125
117 if (fdesc->type != vfh->vdev->queue->type ||126 if (i >= dev->nmeta_formats)
118 index > 1U || (index && !dev->info->meta_format))
119 return -EINVAL;127 return -EINVAL;
120 128
121 memset(fdesc, 0, sizeof(*fdesc));129 memset(fdesc, 0, sizeof(*fdesc));
122 130
123 fdesc->type = vfh->vdev->queue->type;131 fdesc->type = vfh->vdev->queue->type;
124 fdesc->index = index;132 fdesc->index = i;
125 fdesc->pixelformat = index ? dev->info->meta_format : V4L2_META_FMT_UVC;133 fdesc->pixelformat = dev->meta_formats[i];
126 134
127 return 0;135 return 0;
128}136}
@@ -156,6 +164,71 @@ static const struct v4l2_file_operations uvc_meta_fops = { · 27 unmodified lines
156 .mmap = vb2_fop_mmap,164 .mmap = vb2_fop_mmap,
157};165};
158 166
167static 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
181static 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
159int uvc_meta_register(struct uvc_streaming *stream)232int uvc_meta_register(struct uvc_streaming *stream)
160{233{
161 struct uvc_device *dev = stream->dev;234 struct uvc_device *dev = stream->dev;
@@ -164,13 +237,32 @@ int uvc_meta_register(struct uvc_streaming *stream) · 2 unmodified lines
164 237
165 stream->meta.format = V4L2_META_FMT_UVC;238 stream->meta.format = V4L2_META_FMT_UVC;
166 239
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
173 return uvc_register_video_device(dev, stream, vdev, queue,240 return uvc_register_video_device(dev, stream, vdev, queue,
174 V4L2_BUF_TYPE_META_CAPTURE,241 V4L2_BUF_TYPE_META_CAPTURE,
175 &uvc_meta_fops, &uvc_meta_ioctl_ops);242 &uvc_meta_fops, &uvc_meta_ioctl_ops);
176}243}
244
245int 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
42 *42 *
43 * This function must be called with the queue spinlock held.43 * This function must be called with the queue spinlock held.
44 */44 */
45static void uvc_queue_return_buffers(struct uvc_video_queue *queue,45static void __uvc_queue_return_buffers(struct uvc_video_queue *queue,
46 enum uvc_buffer_state state)46 enum uvc_buffer_state state)
47{47{
48 enum vb2_buffer_state vb2_state = state == UVC_BUF_STATE_ERROR48 enum vb2_buffer_state vb2_state = state == UVC_BUF_STATE_ERROR
49 ? VB2_BUF_STATE_ERROR49 ? VB2_BUF_STATE_ERROR
50 : VB2_BUF_STATE_QUEUED;50 : VB2_BUF_STATE_QUEUED;
51 51
52 lockdep_assert_held(&queue->irqlock);
53
52 while (!list_empty(&queue->irqqueue)) {54 while (!list_empty(&queue->irqqueue)) {
53 struct uvc_buffer *buf = list_first_entry(&queue->irqqueue,55 struct uvc_buffer *buf = list_first_entry(&queue->irqqueue,
54 struct uvc_buffer,56 struct uvc_buffer,
@@ -59,6 +61,14 @@ static void uvc_queue_return_buffers(struct uvc_video_queue *queue, · 4 unmodified lines
59 }61 }
60}62}
61 63
64static 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
62/* -----------------------------------------------------------------------------72/* -----------------------------------------------------------------------------
63 * videobuf2 queue operations73 * videobuf2 queue operations
64 */74 */
@@ -157,7 +167,7 @@ static void uvc_buffer_finish(struct vb2_buffer *vb) · 92 unmodified lines
157 uvc_video_clock_update(stream, vbuf, buf);167 uvc_video_clock_update(stream, vbuf, buf);
158}168}
159 169
160static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count)170static int uvc_start_streaming_video(struct vb2_queue *vq, unsigned int count)
161{171{
162 struct uvc_video_queue *queue = vb2_get_drv_priv(vq);172 struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
163 struct uvc_streaming *stream = uvc_queue_to_stream(queue);173 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
165 175
166 lockdep_assert_irqs_enabled();176 lockdep_assert_irqs_enabled();
167 177
178 ret = uvc_pm_get(stream->dev);
179 if (ret)
180 return ret;
181
168 queue->buf_used = 0;182 queue->buf_used = 0;
169 183
170 ret = uvc_video_start_streaming(stream);184 ret = uvc_video_start_streaming(stream);
171 if (ret == 0)185 if (ret == 0)
172 return 0;186 return 0;
173 187
174 spin_lock_irq(&queue->irqlock);188 uvc_pm_put(stream->dev);
189
175 uvc_queue_return_buffers(queue, UVC_BUF_STATE_QUEUED);190 uvc_queue_return_buffers(queue, UVC_BUF_STATE_QUEUED);
176 spin_unlock_irq(&queue->irqlock);
177 191
178 return ret;192 return ret;
179}193}
180 194
181static void uvc_stop_streaming(struct vb2_queue *vq)195static void uvc_stop_streaming_video(struct vb2_queue *vq)
182{196{
183 struct uvc_video_queue *queue = vb2_get_drv_priv(vq);197 struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
198 struct uvc_streaming *stream = uvc_queue_to_stream(queue);
184 199
185 lockdep_assert_irqs_enabled();200 lockdep_assert_irqs_enabled();
186 201
187 if (vq->type != V4L2_BUF_TYPE_META_CAPTURE)202 uvc_video_stop_streaming(uvc_queue_to_stream(queue));
188 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
209static 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();
189 214
190 spin_lock_irq(&queue->irqlock);
191 uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);215 uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
192 spin_unlock_irq(&queue->irqlock);
193}216}
194 217
195static const struct vb2_ops uvc_queue_qops = {218static const struct vb2_ops uvc_queue_qops = {
@@ -197,15 +220,20 @@ static const struct vb2_ops uvc_queue_qops = { · 1 unmodified line
197 .buf_prepare = uvc_buffer_prepare,220 .buf_prepare = uvc_buffer_prepare,
198 .buf_queue = uvc_buffer_queue,221 .buf_queue = uvc_buffer_queue,
199 .buf_finish = uvc_buffer_finish,222 .buf_finish = uvc_buffer_finish,
200 .start_streaming = uvc_start_streaming,223 .start_streaming = uvc_start_streaming_video,
201 .stop_streaming = uvc_stop_streaming,224 .stop_streaming = uvc_stop_streaming_video,
202};225};
203 226
204static const struct vb2_ops uvc_meta_queue_qops = {227static const struct vb2_ops uvc_meta_queue_qops = {
205 .queue_setup = uvc_queue_setup,228 .queue_setup = uvc_queue_setup,
206 .buf_prepare = uvc_buffer_prepare,229 .buf_prepare = uvc_buffer_prepare,
207 .buf_queue = uvc_buffer_queue,230 .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,
209};237};
210 238
211int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)239int 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
242 return 0;270 return 0;
243}271}
244 272
245void 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
256int 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
268int 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
279int 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
291int 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
303int 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
315int 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
327int 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
338int 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
349int 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
355unsigned 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
374/* -----------------------------------------------------------------------------273/* -----------------------------------------------------------------------------
375 *274 *
376 */275 */
377 276
378/*
379 * Check if buffers have been allocated.
380 */
381int 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
392/*277/*
393 * Cancel the video buffers queue.278 * Cancel the video buffers queue.
394 *279 *
@@ -406,7 +291,7 @@ void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) · 11 unmodified lines
406 unsigned long flags;291 unsigned long flags;
407 292
408 spin_lock_irqsave(&queue->irqlock, flags);293 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);
410 /*295 /*
411 * This must be protected by the irqlock spinlock to avoid race296 * This must be protected by the irqlock spinlock to avoid race
412 * conditions between uvc_buffer_queue and the disconnection event that297 * 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
47 usb_autopm_put_interface(dev->intf);47 usb_autopm_put_interface(dev->intf);
48}48}
49 49
50static int uvc_acquire_privileges(struct uvc_fh *handle);
51
52static int uvc_control_add_xu_mapping(struct uvc_video_chain *chain,50static int uvc_control_add_xu_mapping(struct uvc_video_chain *chain,
53 struct uvc_control_mapping *map,51 struct uvc_control_mapping *map,
54 const struct uvc_xu_control_mapping *xmap)52 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
436 const struct uvc_frame *frame;434 const struct uvc_frame *frame;
437 int ret;435 int ret;
438 436
439 ret = uvc_acquire_privileges(handle);
440 if (ret < 0)
441 return ret;
442
443 if (fmt->type != stream->type)437 if (fmt->type != stream->type)
444 return -EINVAL;438 return -EINVAL;
445 439
@@ -448,8 +442,7 @@ static int uvc_ioctl_s_fmt(struct file *file, void *fh, · 2 unmodified lines
448 return ret;442 return ret;
449 443
450 mutex_lock(&stream->mutex);444 mutex_lock(&stream->mutex);
451 445 if (vb2_is_busy(&stream->queue.queue)) {
452 if (uvc_queue_allocated(&stream->queue)) {
453 ret = -EBUSY;446 ret = -EBUSY;
454 goto done;447 goto done;
455 }448 }
@@ -513,10 +506,6 @@ static int uvc_ioctl_s_parm(struct file *file, void *fh, · 57 unmodified lines
513 unsigned int i;506 unsigned int i;
514 int ret;507 int ret;
515 508
516 ret = uvc_acquire_privileges(handle);
517 if (ret < 0)
518 return ret;
519
520 if (parm->type != stream->type)509 if (parm->type != stream->type)
521 return -EINVAL;510 return -EINVAL;
522 511
@@ -593,63 +582,6 @@ static int uvc_ioctl_s_parm(struct file *file, void *fh, · 70 unmodified lines
593 return 0;582 return 0;
594}583}
595 584
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 */
624static 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
640static 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
648static int uvc_has_privileges(struct uvc_fh *handle)
649{
650 return handle->state == UVC_HANDLE_ACTIVE;
651}
652
653/* ------------------------------------------------------------------------585/* ------------------------------------------------------------------------
654 * V4L2 file operations586 * V4L2 file operations
655 */587 */
@@ -671,7 +603,6 @@ static int uvc_v4l2_open(struct file *file) · 15 unmodified lines
671 v4l2_fh_add(&handle->vfh);603 v4l2_fh_add(&handle->vfh);
672 handle->chain = stream->chain;604 handle->chain = stream->chain;
673 handle->stream = stream;605 handle->stream = stream;
674 handle->state = UVC_HANDLE_PASSIVE;
675 file->private_data = handle;606 file->private_data = handle;
676 607
677 return 0;608 return 0;
@@ -686,19 +617,8 @@ static int uvc_v4l2_release(struct file *file) · 8 unmodified lines
686 617
687 uvc_ctrl_cleanup_fh(handle);618 uvc_ctrl_cleanup_fh(handle);
688 619
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
696 /* Release the file handle. */620 /* Release the file handle. */
697 uvc_dismiss_privileges(handle);621 vb2_fop_release(file);
698 v4l2_fh_del(&handle->vfh);
699 v4l2_fh_exit(&handle->vfh);
700 kfree(handle);
701 file->private_data = NULL;
702 622
703 return 0;623 return 0;
704}624}
@@ -753,140 +673,6 @@ static int uvc_ioctl_try_fmt(struct file *file, void *fh, · 48 unmodified lines
753 return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);673 return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
754}674}
755 675
756static 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
779static 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
791static 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
803static 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
815static 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
827static 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
841static 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
870static 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
890static int uvc_ioctl_enum_input(struct file *file, void *fh,676static int uvc_ioctl_enum_input(struct file *file, void *fh,
891 struct v4l2_input *input)677 struct v4l2_input *input)
892{678{
@@ -961,13 +747,13 @@ static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input) · 68 unmodified lines
961static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)747static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
962{748{
963 struct uvc_fh *handle = fh;749 struct uvc_fh *handle = fh;
750 struct uvc_streaming *stream = handle->stream;
964 struct uvc_video_chain *chain = handle->chain;751 struct uvc_video_chain *chain = handle->chain;
965 u8 *buf;752 u8 *buf;
966 int ret;753 int ret;
967 754
968 ret = uvc_acquire_privileges(handle);755 if (vb2_is_busy(&stream->queue.queue))
969 if (ret < 0)756 return -EBUSY;
970 return ret;
971 757
972 if (chain->selector == NULL ||758 if (chain->selector == NULL ||
973 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {759 (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
1381#define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)1167#define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
1382#define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)1168#define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
1383 1169
1384DEFINE_FREE(uvc_pm_put, struct uvc_device *, if (_T) uvc_pm_put(_T))
1385static long uvc_v4l2_compat_ioctl32(struct file *file,1170static long uvc_v4l2_compat_ioctl32(struct file *file,
1386 unsigned int cmd, unsigned long arg)1171 unsigned int cmd, unsigned long arg)
1387{1172{
1388 struct uvc_device *uvc_device __free(uvc_pm_put) = NULL;
1389 struct uvc_fh *handle = file->private_data;1173 struct uvc_fh *handle = file->private_data;
1390 union {1174 union {
1391 struct uvc_xu_control_mapping xmap;1175 struct uvc_xu_control_mapping xmap;
@@ -1398,38 +1182,38 @@ static long uvc_v4l2_compat_ioctl32(struct file *file, · 6 unmodified lines
1398 if (ret)1182 if (ret)
1399 return ret;1183 return ret;
1400 1184
1401 uvc_device = handle->stream->dev;
1402
1403 switch (cmd) {1185 switch (cmd) {
1404 case UVCIOC_CTRL_MAP32:1186 case UVCIOC_CTRL_MAP32:
1405 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);1187 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1406 if (ret)1188 if (ret)
1407 return ret;1189 break;
1408 ret = uvc_ioctl_xu_ctrl_map(handle->chain, &karg.xmap);1190 ret = uvc_ioctl_xu_ctrl_map(handle->chain, &karg.xmap);
1409 if (ret)1191 if (ret)
1410 return ret;1192 break;
1411 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);1193 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1412 if (ret)1194 if (ret)
1413 return ret;1195 break;
1414
1415 break;1196 break;
1416 1197
1417 case UVCIOC_CTRL_QUERY32:1198 case UVCIOC_CTRL_QUERY32:
1418 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);1199 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1419 if (ret)1200 if (ret)
1420 return ret;1201 break;
1421 ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);1202 ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
1422 if (ret)1203 if (ret)
1423 return ret;1204 break;
1424 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);1205 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1425 if (ret)1206 if (ret)
1426 return ret;1207 break;
1427 break;1208 break;
1428 1209
1429 default:1210 default:
1430 return -ENOIOCTLCMD;1211 ret = -ENOIOCTLCMD;
1212 break;
1431 }1213 }
1432 1214
1215 uvc_pm_put(handle->stream->dev);
1216
1433 return ret;1217 return ret;
1434}1218}
1435#endif1219#endif
@@ -1438,81 +1222,37 @@ static long uvc_v4l2_unlocked_ioctl(struct file *file, · 2 unmodified lines
1438 unsigned int cmd, unsigned long arg)1222 unsigned int cmd, unsigned long arg)
1439{1223{
1440 struct uvc_fh *handle = file->private_data;1224 struct uvc_fh *handle = file->private_data;
1225 unsigned int converted_cmd = v4l2_translate_cmd(cmd);
1441 int ret;1226 int ret;
1442 1227
1443 /* The following IOCTLs do not need to turn on the camera. */1228 /* The following IOCTLs need to turn on the camera. */
1444 switch (cmd) {1229 switch (converted_cmd) {
1445 case VIDIOC_CREATE_BUFS:1230 case UVCIOC_CTRL_MAP:
1446 case VIDIOC_DQBUF:1231 case UVCIOC_CTRL_QUERY:
1447 case VIDIOC_ENUM_FMT:1232 case VIDIOC_G_CTRL:
1448 case VIDIOC_ENUM_FRAMEINTERVALS:1233 case VIDIOC_G_EXT_CTRLS:
1449 case VIDIOC_ENUM_FRAMESIZES:1234 case VIDIOC_G_INPUT:
1450 case VIDIOC_ENUMINPUT:1235 case VIDIOC_QUERYCTRL:
1451 case VIDIOC_EXPBUF:1236 case VIDIOC_QUERYMENU:
1452 case VIDIOC_G_FMT:1237 case VIDIOC_QUERY_EXT_CTRL:
1453 case VIDIOC_G_PARM:1238 case VIDIOC_S_CTRL:
1454 case VIDIOC_G_SELECTION:1239 case VIDIOC_S_EXT_CTRLS:
1455 case VIDIOC_QBUF:1240 case VIDIOC_S_FMT:
1456 case VIDIOC_QUERYCAP:1241 case VIDIOC_S_INPUT:
1457 case VIDIOC_REQBUFS:1242 case VIDIOC_S_PARM:
1458 case VIDIOC_SUBSCRIBE_EVENT:1243 case VIDIOC_TRY_EXT_CTRLS:
1459 case VIDIOC_UNSUBSCRIBE_EVENT:1244 case VIDIOC_TRY_FMT:
1460 return video_ioctl2(file, cmd, arg);1245 ret = uvc_pm_get(handle->stream->dev);
1461 }1246 if (ret)
1462 1247 return ret;
1463 ret = uvc_pm_get(handle->stream->dev);1248 ret = video_ioctl2(file, cmd, arg);
1464 if (ret)1249 uvc_pm_put(handle->stream->dev);
1465 return ret;1250 return ret;
1251 }
1466 1252
1467 ret = video_ioctl2(file, cmd, arg);1253 /* The other IOCTLs can run with the camera off. */
1468 1254 return video_ioctl2(file, cmd, arg);
1469 uvc_pm_put(handle->stream->dev);
1470 return ret;
1471}
1472
1473static 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
1483static 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
1493static __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
1504static 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);
1514}1255}
1515#endif
1516 1256
1517const struct v4l2_ioctl_ops uvc_ioctl_ops = {1257const struct v4l2_ioctl_ops uvc_ioctl_ops = {
1518 .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt,1258 .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt,
@@ -1526,14 +1266,15 @@ const struct v4l2_ioctl_ops uvc_ioctl_ops = { · 7 unmodified lines
1526 .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt,1266 .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt,
1527 .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt,1267 .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt,
1528 .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt,1268 .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt,
1529 .vidioc_reqbufs = uvc_ioctl_reqbufs,1269 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1530 .vidioc_querybuf = uvc_ioctl_querybuf,1270 .vidioc_querybuf = vb2_ioctl_querybuf,
1531 .vidioc_qbuf = uvc_ioctl_qbuf,1271 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1532 .vidioc_expbuf = uvc_ioctl_expbuf,1272 .vidioc_qbuf = vb2_ioctl_qbuf,
1533 .vidioc_dqbuf = uvc_ioctl_dqbuf,1273 .vidioc_expbuf = vb2_ioctl_expbuf,
1534 .vidioc_create_bufs = uvc_ioctl_create_bufs,1274 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1535 .vidioc_streamon = uvc_ioctl_streamon,1275 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1536 .vidioc_streamoff = uvc_ioctl_streamoff,1276 .vidioc_streamon = vb2_ioctl_streamon,
1277 .vidioc_streamoff = vb2_ioctl_streamoff,
1537 .vidioc_enum_input = uvc_ioctl_enum_input,1278 .vidioc_enum_input = uvc_ioctl_enum_input,
1538 .vidioc_g_input = uvc_ioctl_g_input,1279 .vidioc_g_input = uvc_ioctl_g_input,
1539 .vidioc_s_input = uvc_ioctl_s_input,1280 .vidioc_s_input = uvc_ioctl_s_input,
@@ -1558,11 +1299,10 @@ const struct v4l2_file_operations uvc_fops = { · 18 unmodified lines
1558#ifdef CONFIG_COMPAT1299#ifdef CONFIG_COMPAT
1559 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,1300 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
1560#endif1301#endif
1561 .read = uvc_v4l2_read,1302 .mmap = vb2_fop_mmap,
1562 .mmap = uvc_v4l2_mmap,1303 .poll = vb2_fop_poll,
1563 .poll = uvc_v4l2_poll,
1564#ifndef CONFIG_MMU1304#ifndef CONFIG_MMU
1565 .get_unmapped_area = uvc_v4l2_get_unmapped_area,1305 .get_unmapped_area = vb2_fop_get_unmapped_area,
1566#endif1306#endif
1567};1307};
1568 1308
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
262 262
263 ctrl->dwMaxPayloadTransferSize = bandwidth;263 ctrl->dwMaxPayloadTransferSize = bandwidth;
264 }264 }
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 }
265}274}
266 275
267static size_t uvc_video_ctrl_size(struct uvc_streaming *stream)276static 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
1419 if (!meta_buf || length == 2)1428 if (!meta_buf || length == 2)
1420 return;1429 return;
1421 1430
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
1428 has_pts = mem[1] & UVC_STREAM_PTS;1431 has_pts = mem[1] & UVC_STREAM_PTS;
1429 has_scr = mem[1] & UVC_STREAM_SCR;1432 has_scr = mem[1] & UVC_STREAM_SCR;
1430 1433
@@ -1445,6 +1448,12 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, · 14 unmodified lines
1445 !memcmp(scr, stream->clock.last_scr, 6)))1448 !memcmp(scr, stream->clock.last_scr, 6)))
1446 return;1449 return;
1447 1450
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
1448 meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused);1457 meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused);
1449 local_irq_save(flags);1458 local_irq_save(flags);
1450 time = uvc_video_get_time();1459 time = uvc_video_get_time();
drivers/media/usb/uvc/uvcvideo.h+13−33
@@ -77,6 +77,7 @@ · 76 unmodified lines
77#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x0000800077#define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
78#define UVC_QUIRK_INVALID_DEVICE_SOF 0x0001000078#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
79#define UVC_QUIRK_MJPEG_NO_EOF 0x0002000079#define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
80#define UVC_QUIRK_MSXU_META 0x00040000
80 81
81/* Format flags */82/* Format flags */
82#define UVC_FMT_FLAG_COMPRESSED 0x0000000183#define UVC_FMT_FLAG_COMPRESSED 0x00000001
@@ -134,6 +135,8 @@ struct uvc_control_mapping { · 51 unmodified lines
134 s32 master_manual;135 s32 master_manual;
135 u32 slave_ids[2];136 u32 slave_ids[2];
136 137
138 bool disabled;
139
137 const struct uvc_control_mapping *(*filter_mapping)140 const struct uvc_control_mapping *(*filter_mapping)
138 (struct uvc_video_chain *chain,141 (struct uvc_video_chain *chain,
139 struct uvc_control *ctrl);142 struct uvc_control *ctrl);
@@ -326,7 +329,10 @@ struct uvc_buffer { · 186 unmodified lines
326 329
327struct uvc_video_queue {330struct uvc_video_queue {
328 struct vb2_queue queue;331 struct vb2_queue queue;
329 struct mutex mutex; /* Protects queue */332 struct mutex mutex; /*
333 * Serializes vb2_queue and
334 * fops
335 */
330 336
331 unsigned int flags;337 unsigned int flags;
332 unsigned int buf_used;338 unsigned int buf_used;
@@ -570,6 +576,8 @@ struct uvc_status { · 237 unmodified lines
570 };576 };
571} __packed;577} __packed;
572 578
579#define UVC_MAX_META_DATA_FORMATS 3
580
573struct uvc_device {581struct uvc_device {
574 struct usb_device *udev;582 struct usb_device *udev;
575 struct usb_interface *intf;583 struct usb_interface *intf;
@@ -580,6 +588,9 @@ struct uvc_device { · 4 unmodified lines
580 588
581 const struct uvc_device_info *info;589 const struct uvc_device_info *info;
582 590
591 u32 meta_formats[UVC_MAX_META_DATA_FORMATS];
592 unsigned int nmeta_formats;
593
583 atomic_t nmappings;594 atomic_t nmappings;
584 595
585 /* Video control interface */596 /* Video control interface */
@@ -619,18 +630,11 @@ struct uvc_device { · 33 unmodified lines
619 struct uvc_entity *gpio_unit;630 struct uvc_entity *gpio_unit;
620};631};
621 632
622enum uvc_handle_state {
623 UVC_HANDLE_PASSIVE = 0,
624 UVC_HANDLE_ACTIVE = 1,
625};
626
627struct uvc_fh {633struct uvc_fh {
628 struct v4l2_fh vfh;634 struct v4l2_fh vfh;
629 struct uvc_video_chain *chain;635 struct uvc_video_chain *chain;
630 struct uvc_streaming *stream;636 struct uvc_streaming *stream;
631 enum uvc_handle_state state;
632 unsigned int pending_async_ctrls;637 unsigned int pending_async_ctrls;
633 bool is_streaming;
634};638};
635 639
636/* ------------------------------------------------------------------------640/* ------------------------------------------------------------------------
@@ -687,36 +691,11 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); · 50 unmodified lines
687 691
688/* Video buffers queue management. */692/* Video buffers queue management. */
689int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type);693int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type);
690void uvc_queue_release(struct uvc_video_queue *queue);
691int uvc_request_buffers(struct uvc_video_queue *queue,
692 struct v4l2_requestbuffers *rb);
693int uvc_query_buffer(struct uvc_video_queue *queue,
694 struct v4l2_buffer *v4l2_buf);
695int uvc_create_buffers(struct uvc_video_queue *queue,
696 struct v4l2_create_buffers *v4l2_cb);
697int uvc_queue_buffer(struct uvc_video_queue *queue,
698 struct media_device *mdev,
699 struct v4l2_buffer *v4l2_buf);
700int uvc_export_buffer(struct uvc_video_queue *queue,
701 struct v4l2_exportbuffer *exp);
702int uvc_dequeue_buffer(struct uvc_video_queue *queue,
703 struct v4l2_buffer *v4l2_buf, int nonblocking);
704int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type);
705int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type);
706void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);694void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
707struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,695struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
708 struct uvc_buffer *buf);696 struct uvc_buffer *buf);
709struct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue);697struct uvc_buffer *uvc_queue_get_current_buffer(struct uvc_video_queue *queue);
710void uvc_queue_buffer_release(struct uvc_buffer *buf);698void uvc_queue_buffer_release(struct uvc_buffer *buf);
711int 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
716unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
717 unsigned long pgoff);
718#endif
719int uvc_queue_allocated(struct uvc_video_queue *queue);
720static inline int uvc_queue_streaming(struct uvc_video_queue *queue)699static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
721{700{
722 return vb2_is_streaming(&queue->queue);701 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
749void uvc_video_clock_update(struct uvc_streaming *stream,728void uvc_video_clock_update(struct uvc_streaming *stream,
750 struct vb2_v4l2_buffer *vbuf,729 struct vb2_v4l2_buffer *vbuf,
751 struct uvc_buffer *buf);730 struct uvc_buffer *buf);
731int uvc_meta_init(struct uvc_device *dev);
752int uvc_meta_register(struct uvc_streaming *stream);732int uvc_meta_register(struct uvc_streaming *stream);
753 733
754int uvc_register_video_device(struct uvc_device *dev,734int 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
323 { .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 },323 { .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 },
324 { .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 },324 { .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 },
325 325
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
326 /* Bayer RGB formats */332 /* Bayer RGB formats */
327 { .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 },333 { .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 },
328 { .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 },334 { .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
332 { .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 },338 { .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 },
333 { .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 },339 { .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 },
334 { .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 },340 { .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 },
335 { .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 },345 { .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 },
336 { .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 },346 { .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 },
337 { .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 },347 { .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
344 { .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 },354 { .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 },
345 { .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 },355 { .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 },
346 { .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 },356 { .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 },
347 };379 };
348 unsigned int i;380 unsigned int i;
349 381
@@ -505,10 +537,10 @@ s64 __v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler, · 155 unmodified lines
505 537
506 freq = div_u64(v4l2_ctrl_g_ctrl_int64(ctrl) * mul, div);538 freq = div_u64(v4l2_ctrl_g_ctrl_int64(ctrl) * mul, div);
507 539
508 pr_warn("%s: Link frequency estimated using pixel rate: result might be inaccurate\n",540 pr_warn_once("%s: Link frequency estimated using pixel rate: result might be inaccurate\n",
509 __func__);541 __func__);
510 pr_warn("%s: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver\n",542 pr_warn_once("%s: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver\n",
511 __func__);543 __func__);
512 }544 }
513 545
514 return freq > 0 ? freq : -EINVAL;546 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
968 968
969 p_h264_sps->flags &=969 p_h264_sps->flags &=
970 ~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS;970 ~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;
975 }971 }
976 972
973 if (p_h264_sps->chroma_format_idc < 3)
974 p_h264_sps->flags &=
975 ~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE;
976
977 if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)977 if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
978 p_h264_sps->flags &=978 p_h264_sps->flags &=
979 ~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD;979 ~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
1631EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);1631EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
1632 1632
1633/* Free all controls and control refs */1633/* Free all controls and control refs */
1634void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)1634int v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1635{1635{
1636 struct v4l2_ctrl_ref *ref, *next_ref;1636 struct v4l2_ctrl_ref *ref, *next_ref;
1637 struct v4l2_ctrl *ctrl, *next_ctrl;1637 struct v4l2_ctrl *ctrl, *next_ctrl;
1638 struct v4l2_subscribed_event *sev, *next_sev;1638 struct v4l2_subscribed_event *sev, *next_sev;
1639 1639
1640 if (hdl == NULL || hdl->buckets == NULL)1640 if (!hdl)
1641 return;1641 return 0;
1642
1643 if (!hdl->buckets)
1644 return hdl->error;
1642 1645
1643 v4l2_ctrl_handler_free_request(hdl);1646 v4l2_ctrl_handler_free_request(hdl);
1644 1647
@@ -1661,9 +1664,10 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) · 16 unmodified lines
1661 kvfree(hdl->buckets);1664 kvfree(hdl->buckets);
1662 hdl->buckets = NULL;1665 hdl->buckets = NULL;
1663 hdl->cached = NULL;1666 hdl->cached = NULL;
1664 hdl->error = 0;
1665 mutex_unlock(hdl->lock);1667 mutex_unlock(hdl->lock);
1666 mutex_destroy(&hdl->_lock);1668 mutex_destroy(&hdl->_lock);
1669
1670 return hdl->error;
1667}1671}
1668EXPORT_SYMBOL(v4l2_ctrl_handler_free);1672EXPORT_SYMBOL(v4l2_ctrl_handler_free);
1669 1673
drivers/media/v4l2-core/v4l2-i2c.c+2−1
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 5
6#include <linux/i2c.h>6#include <linux/i2c.h>
7#include <linux/module.h>7#include <linux/module.h>
8#include <linux/property.h>
8#include <media/v4l2-common.h>9#include <media/v4l2-common.h>
9#include <media/v4l2-device.h>10#include <media/v4l2-device.h>
10 11
@@ -24,7 +25,7 @@ void v4l2_i2c_subdev_unregister(struct v4l2_subdev *sd) · 13 unmodified lines
24 * registered by us, and would not be25 * registered by us, and would not be
25 * re-created by just probing the V4L2 driver.26 * re-created by just probing the V4L2 driver.
26 */27 */
27 if (client && !client->dev.of_node && !client->dev.fwnode)28 if (client && !dev_fwnode(&client->dev))
28 i2c_unregister_device(client);29 i2c_unregister_device(client);
29}30}
30 31
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
1413 case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;1413 case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break;
1414 case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;1414 case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break;
1415 case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break;1415 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;
1416 case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break;1417 case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break;
1417 case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break;1418 case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break;
1418 case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break;1419 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
1421 case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;1422 case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;
1422 case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;1423 case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;
1423 case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break;1424 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;
1424 case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break;1426 case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break;
1425 case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break;1427 case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break;
1426 case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break;1428 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
1429 case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;1431 case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;
1430 case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;1432 case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;
1431 case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break;1433 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;
1432 case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break;1435 case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break;
1433 case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break;1436 case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break;
1434 case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break;1437 case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break;
1435 case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break;1438 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;
1436 case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break;1440 case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break;
1437 case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break;1441 case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break;
1438 case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break;1442 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
1459 case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break;1463 case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break;
1460 case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break;1464 case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break;
1461 case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break;1465 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;
1462 case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break;1467 case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break;
1463 case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break;1468 case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break;
1464 case V4L2_META_FMT_RK_ISP1_PARAMS: descr = "Rockchip ISP1 3A Parameters"; break;1469 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
3245 return ret;3250 return ret;
3246}3251}
3247 3252
3248static unsigned int video_translate_cmd(unsigned int cmd)3253unsigned int v4l2_translate_cmd(unsigned int cmd)
3249{3254{
3250#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)3255#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME)
3251 switch (cmd) {3256 switch (cmd) {
@@ -3266,6 +3271,7 @@ static unsigned int video_translate_cmd(unsigned int cmd) · 14 unmodified lines
3266 3271
3267 return cmd;3272 return cmd;
3268}3273}
3274EXPORT_SYMBOL_GPL(v4l2_translate_cmd);
3269 3275
3270static int video_get_user(void __user *arg, void *parg,3276static int video_get_user(void __user *arg, void *parg,
3271 unsigned int real_cmd, unsigned int cmd,3277 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
3426 size_t array_size = 0;3432 size_t array_size = 0;
3427 void __user *user_ptr = NULL;3433 void __user *user_ptr = NULL;
3428 void **kernel_ptr = NULL;3434 void **kernel_ptr = NULL;
3429 unsigned int cmd = video_translate_cmd(orig_cmd);3435 unsigned int cmd = v4l2_translate_cmd(orig_cmd);
3430 const size_t ioc_size = _IOC_SIZE(cmd);3436 const size_t ioc_size = _IOC_SIZE(cmd);
3431 3437
3432 /* Copy arguments into temp kernel buffer */3438 /* 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
711 return marker;711 return marker;
712}712}
713EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_header);713EXPORT_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 */
723int 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}
732EXPORT_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 */
742int 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}
751EXPORT_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 */
763int 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}
772EXPORT_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 */
784int 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}
793EXPORT_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
1004 struct v4l2_subdev_route *routes =1004 struct v4l2_subdev_route *routes =
1005 (struct v4l2_subdev_route *)(uintptr_t)routing->routes;1005 (struct v4l2_subdev_route *)(uintptr_t)routing->routes;
1006 struct v4l2_subdev_krouting krouting = {};1006 struct v4l2_subdev_krouting krouting = {};
1007 unsigned int num_active_routes = 0;
1007 unsigned int i;1008 unsigned int i;
1008 1009
1009 if (!v4l2_subdev_enable_streams_api)1010 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
1041 if (!(pads[route->source_pad].flags &1042 if (!(pads[route->source_pad].flags &
1042 MEDIA_PAD_FL_SOURCE))1043 MEDIA_PAD_FL_SOURCE))
1043 return -EINVAL;1044 return -EINVAL;
1045
1046 if (route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)
1047 num_active_routes++;
1044 }1048 }
1045 1049
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
1046 /*1060 /*
1047 * If the driver doesn't support setting routing, just return1061 * If the driver doesn't support setting routing, just return
1048 * the routing table.1062 * the routing table.
@@ -2219,6 +2233,9 @@ static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd, · 1170 unmodified lines
2219 *found_streams = BIT_ULL(0);2233 *found_streams = BIT_ULL(0);
2220 *enabled_streams =2234 *enabled_streams =
2221 (sd->enabled_pads & BIT_ULL(pad)) ? BIT_ULL(0) : 0;2235 (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);
2222 return;2239 return;
2223 }2240 }
2224 2241
@@ -2236,6 +2253,10 @@ static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd, · 11 unmodified lines
2236 if (cfg->enabled)2253 if (cfg->enabled)
2237 *enabled_streams |= BIT_ULL(cfg->stream);2254 *enabled_streams |= BIT_ULL(cfg->stream);
2238 }2255 }
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);
2239}2260}
2240 2261
2241static void v4l2_subdev_set_streams_enabled(struct v4l2_subdev *sd,2262static 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
2271 bool use_s_stream;2292 bool use_s_stream;
2272 int ret;2293 int ret;
2273 2294
2295 dev_dbg(dev, "enable streams \"%s\":%u/%#llx\n", sd->entity.name, pad,
2296 streams_mask);
2297
2274 /* A few basic sanity checks first. */2298 /* A few basic sanity checks first. */
2275 if (pad >= sd->entity.num_pads)2299 if (pad >= sd->entity.num_pads)
2276 return -EINVAL;2300 return -EINVAL;
@@ -2318,8 +2342,6 @@ int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad, · 41 unmodified lines
2318 goto done;2342 goto done;
2319 }2343 }
2320 2344
2321 dev_dbg(dev, "enable streams %u:%#llx\n", pad, streams_mask);
2322
2323 already_streaming = v4l2_subdev_is_streaming(sd);2345 already_streaming = v4l2_subdev_is_streaming(sd);
2324 2346
2325 if (!use_s_stream) {2347 if (!use_s_stream) {
@@ -2371,6 +2393,9 @@ int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad, · 45 unmodified lines
2371 bool use_s_stream;2393 bool use_s_stream;
2372 int ret;2394 int ret;
2373 2395
2396 dev_dbg(dev, "disable streams \"%s\":%u/%#llx\n", sd->entity.name, pad,
2397 streams_mask);
2398
2374 /* A few basic sanity checks first. */2399 /* A few basic sanity checks first. */
2375 if (pad >= sd->entity.num_pads)2400 if (pad >= sd->entity.num_pads)
2376 return -EINVAL;2401 return -EINVAL;
@@ -2418,8 +2443,6 @@ int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad, · 41 unmodified lines
2418 goto done;2443 goto done;
2419 }2444 }
2420 2445
2421 dev_dbg(dev, "disable streams %u:%#llx\n", pad, streams_mask);
2422
2423 if (!use_s_stream) {2446 if (!use_s_stream) {
2424 /* Call the .disable_streams() operation. */2447 /* Call the .disable_streams() operation. */
2425 ret = v4l2_subdev_call(sd, pad, disable_streams, state, pad,2448 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
129 },129 },
130};130};
131 131
132/* Settings for Dell 7212 Tablet */
133
134static struct regulator_consumer_supply int3479_vsio_consumer_supplies[] = {
135 REGULATOR_SUPPLY("avdd", "i2c-INT3479:00"),
136};
137
138static struct regulator_consumer_supply int3479_aux1_consumer_supplies[] = {
139 REGULATOR_SUPPLY("dvdd", "i2c-INT3479:00"),
140};
141
142static struct regulator_consumer_supply int3479_aux2_consumer_supplies[] = {
143 REGULATOR_SUPPLY("dovdd", "i2c-INT3479:00"),
144};
145
146static 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
157static 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
168static 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
179static 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
190static 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
201static 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
212static 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
223static 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
132static struct gpiod_lookup_table surface_go_int347a_gpios = {235static struct gpiod_lookup_table surface_go_int347a_gpios = {
133 .dev_id = "i2c-INT347A:00",236 .dev_id = "i2c-INT347A:00",
134 .table = {237 .table = {
@@ -146,6 +249,15 @@ static struct gpiod_lookup_table surface_go_int347e_gpios = { · 11 unmodified lines
146 }249 }
147};250};
148 251
252static 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
149static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {261static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {
150 .dev_name = "i2c-INT3472:05",262 .dev_name = "i2c-INT3472:05",
151 .tps68470_regulator_pdata = &surface_go_tps68470_pdata,263 .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
166 },278 },
167};279};
168 280
281static 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
169static const struct dmi_system_id int3472_tps68470_board_data_table[] = {290static const struct dmi_system_id int3472_tps68470_board_data_table[] = {
170 {291 {
171 .matches = {292 .matches = {
@@ -188,6 +309,13 @@ static const struct dmi_system_id int3472_tps68470_board_data_table[] = { · 16 unmodified lines
188 },309 },
189 .driver_data = (void *)&surface_go3_tps68470_board_data,310 .driver_data = (void *)&surface_go3_tps68470_board_data,
190 },311 },
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 },
191 { }319 { }
192};320};
193 321
drivers/staging/media/Kconfig+2−2
@@ -28,12 +28,12 @@ source "drivers/staging/media/imx/Kconfig" · 27 unmodified lines
28 28
29source "drivers/staging/media/ipu3/Kconfig"29source "drivers/staging/media/ipu3/Kconfig"
30 30
31source "drivers/staging/media/ipu7/Kconfig"
32
31source "drivers/staging/media/max96712/Kconfig"33source "drivers/staging/media/max96712/Kconfig"
32 34
33source "drivers/staging/media/meson/vdec/Kconfig"35source "drivers/staging/media/meson/vdec/Kconfig"
34 36
35source "drivers/staging/media/rkvdec/Kconfig"
36
37source "drivers/staging/media/starfive/Kconfig"37source "drivers/staging/media/starfive/Kconfig"
38 38
39source "drivers/staging/media/sunxi/Kconfig"39source "drivers/staging/media/sunxi/Kconfig"
drivers/staging/media/Makefile+1−1
@@ -4,9 +4,9 @@ obj-$(CONFIG_INTEL_ATOMISP) += atomisp/ · 3 unmodified lines
4obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/4obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
5obj-$(CONFIG_VIDEO_MAX96712) += max96712/5obj-$(CONFIG_VIDEO_MAX96712) += max96712/
6obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/6obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
7obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/
8obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive/7obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive/
9obj-$(CONFIG_VIDEO_SUNXI) += sunxi/8obj-$(CONFIG_VIDEO_SUNXI) += sunxi/
10obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/9obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/
11obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/10obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
11obj-$(CONFIG_VIDEO_INTEL_IPU7) += ipu7/
12obj-$(CONFIG_DVB_AV7110) += av7110/12obj-$(CONFIG_DVB_AV7110) += av7110/
drivers/staging/media/atomisp/Kconfig+1−0
@@ -12,6 +12,7 @@ menuconfig INTEL_ATOMISP · 11 unmodified lines
12config VIDEO_ATOMISP12config VIDEO_ATOMISP
13 tristate "Intel Atom Image Signal Processor Driver"13 tristate "Intel Atom Image Signal Processor Driver"
14 depends on VIDEO_DEV && INTEL_ATOMISP14 depends on VIDEO_DEV && INTEL_ATOMISP
15 depends on INTEL_SKL_INT3472
15 depends on IPU_BRIDGE16 depends on IPU_BRIDGE
16 depends on MEDIA_PCI_SUPPORT17 depends on MEDIA_PCI_SUPPORT
17 depends on PMIC_OPREGION18 depends on PMIC_OPREGION
drivers/staging/media/atomisp/Makefile+0−1
@@ -17,7 +17,6 @@ atomisp-objs += \ · 16 unmodified lines
17 pci/atomisp_compat_css20.o \17 pci/atomisp_compat_css20.o \
18 pci/atomisp_csi2.o \18 pci/atomisp_csi2.o \
19 pci/atomisp_csi2_bridge.o \19 pci/atomisp_csi2_bridge.o \
20 pci/atomisp_drvfs.o \
21 pci/atomisp_fops.o \20 pci/atomisp_fops.o \
22 pci/atomisp_ioctl.o \21 pci/atomisp_ioctl.o \
23 pci/atomisp_subdev.o \22 pci/atomisp_subdev.o \
drivers/staging/media/atomisp/TODO+0−2
@@ -7,8 +7,6 @@ TODO · 6 unmodified lines
7 7
8* Remove/disable custom v4l2-ctrls8* Remove/disable custom v4l2-ctrls
9 9
10* Remove custom sysfs files created by atomisp_drvfs.c
11
12* Remove unnecessary/unwanted module parameters10* Remove unnecessary/unwanted module parameters
13 11
14* Remove abuse of priv field in various v4l2 userspace API structs12* 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
31 tristate "GC0310 sensor support"31 tristate "GC0310 sensor support"
32 depends on ACPI32 depends on ACPI
33 depends on I2C && VIDEO_DEV33 depends on I2C && VIDEO_DEV
34 select V4L2_CCI_I2C
34 help35 help
35 This is a Video4Linux2 sensor-level driver for the Galaxycore36 This is a Video4Linux2 sensor-level driver for the Galaxycore
36 GC0310 0.3MP sensor.37 GC0310 0.3MP sensor.
drivers/staging/media/atomisp/i2c/atomisp-gc0310.c+341−270
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 * Support for GalaxyCore GC0310 VGA camera sensor.3 * Support for GalaxyCore GC0310 VGA camera sensor.
4 *4 *
5 * Copyright (c) 2013 Intel Corporation. All Rights Reserved.5 * 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>
7 */7 */
8 8
9#include <linux/delay.h>9#include <linux/delay.h>
@@ -13,77 +13,92 @@ · 3 unmodified lines
13#include <linux/kernel.h>13#include <linux/kernel.h>
14#include <linux/module.h>14#include <linux/module.h>
15#include <linux/pm_runtime.h>15#include <linux/pm_runtime.h>
16#include <linux/regmap.h>
16#include <linux/string.h>17#include <linux/string.h>
17#include <linux/types.h>18#include <linux/types.h>
18 19
20#include <media/v4l2-cci.h>
19#include <media/v4l2-ctrls.h>21#include <media/v4l2-ctrls.h>
20#include <media/v4l2-device.h>22#include <media/v4l2-device.h>
23#include <media/v4l2-fwnode.h>
21 24
22#define GC0310_NATIVE_WIDTH 65625#define GC0310_NATIVE_WIDTH 656
23#define GC0310_NATIVE_HEIGHT 49626#define GC0310_NATIVE_HEIGHT 496
24 27
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
25#define GC0310_FPS 3040#define GC0310_FPS 30
26#define GC0310_SKIP_FRAMES 341#define GC0310_SKIP_FRAMES 3
27 42
28#define GC0310_FOCAL_LENGTH_NUM 278 /* 2.78mm */
29
30#define GC0310_ID 0xa31043#define GC0310_ID 0xa310
31 44
32#define GC0310_RESET_RELATED 0xFE45#define GC0310_RESET_RELATED_REG CCI_REG8(0xfe)
33#define GC0310_REGISTER_PAGE_0 0x046#define GC0310_REGISTER_PAGE_0 0x0
34#define GC0310_REGISTER_PAGE_3 0x347#define GC0310_REGISTER_PAGE_3 0x3
35 48
36/*49/*
37 * GC0310 System control registers50 * GC0310 System control registers
38 */51 */
39#define GC0310_SW_STREAM 0x1052#define GC0310_SW_STREAM_REG CCI_REG8(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
63 53
64#define GC0310_START_STREAMING 0x94 /* 8-bit enable */54#define GC0310_START_STREAMING 0x94 /* 8-bit enable */
65#define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */55#define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */
66 56
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
67#define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd)84#define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd)
68 85
69struct gc0310_device {86struct gc0310_device {
70 struct v4l2_subdev sd;87 struct v4l2_subdev sd;
71 struct media_pad pad;88 struct media_pad pad;
72 /* Protect against concurrent changes to controls */
73 struct mutex input_lock;
74 bool is_streaming;
75 89
90 struct regmap *regmap;
76 struct gpio_desc *reset;91 struct gpio_desc *reset;
77 struct gpio_desc *powerdown;92 struct gpio_desc *powerdown;
78 93
79 struct gc0310_mode {
80 struct v4l2_mbus_framefmt fmt;
81 } mode;
82
83 struct gc0310_ctrls {94 struct gc0310_ctrls {
84 struct v4l2_ctrl_handler handler;95 struct v4l2_ctrl_handler handler;
85 struct v4l2_ctrl *exposure;96 struct v4l2_ctrl *exposure;
86 struct v4l2_ctrl *gain;97 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;
87 } ctrls;102 } ctrls;
88};103};
89 104
@@ -92,7 +107,7 @@ struct gc0310_reg { · 2 unmodified lines
92 u8 val;107 u8 val;
93};108};
94 109
95static const struct gc0310_reg gc0310_reset_register[] = {110static const struct reg_sequence gc0310_reset_register[] = {
96 /* System registers */111 /* System registers */
97 { 0xfe, 0xf0 },112 { 0xfe, 0xf0 },
98 { 0xfe, 0xf0 },113 { 0xfe, 0xf0 },
@@ -142,8 +157,7 @@ static const struct gc0310_reg gc0310_reset_register[] = { · 43 unmodified lines
142 { 0x04, 0xc0 }, /* 0xe8 //58 */157 { 0x04, 0xc0 }, /* 0xe8 //58 */
143 { 0x05, 0x00 },158 { 0x05, 0x00 },
144 { 0x06, 0xb2 }, /* 0x0a //HB */159 { 0x06, 0xb2 }, /* 0x0a //HB */
145 { 0x07, 0x00 },160 /* Vblank (reg 0x07 + 0x08) gets set by the vblank ctrl */
146 { 0x08, 0x0c }, /* 0x89 //VB */
147 { 0x09, 0x00 }, /* row start */161 { 0x09, 0x00 }, /* row start */
148 { 0x0a, 0x00 },162 { 0x0a, 0x00 },
149 { 0x0b, 0x00 }, /* col start */163 { 0x0b, 0x00 }, /* col start */
@@ -235,7 +249,7 @@ static const struct gc0310_reg gc0310_reset_register[] = { · 85 unmodified lines
235 { 0xfe, 0x00 },249 { 0xfe, 0x00 },
236};250};
237 251
238static const struct gc0310_reg gc0310_VGA_30fps[] = {252static const struct reg_sequence gc0310_VGA_30fps[] = {
239 { 0xfe, 0x00 },253 { 0xfe, 0x00 },
240 { 0x0d, 0x01 }, /* height */254 { 0x0d, 0x01 }, /* height */
241 { 0x0e, 0xf2 }, /* 0xf7 //height */255 { 0x0e, 0xf2 }, /* 0xf7 //height */
@@ -259,41 +273,14 @@ static const struct gc0310_reg gc0310_VGA_30fps[] = { · 17 unmodified lines
259 { 0xfe, 0x00 },273 { 0xfe, 0x00 },
260};274};
261 275
262/*276static const s64 link_freq_menu_items[] = {
263 * gc0310_write_reg_array - Initializes a list of GC0310 registers277 GC0310_LINK_FREQ,
264 * @client: i2c driver client structure278};
265 * @reglist: list of registers to be written
266 * @count: number of register, value pairs in the list
267 */
268static 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
285static 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}
291 279
292static int gc0310_gain_set(struct gc0310_device *dev, u32 gain)280static int gc0310_gain_set(struct gc0310_device *sensor, u32 gain)
293{281{
294 struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
295 u8 again, dgain;282 u8 again, dgain;
296 int ret;283 int ret = 0;
297 284
298 /* Taken from original driver, this never sets dgain lower then 32? */285 /* Taken from original driver, this never sets dgain lower then 32? */
299 286
@@ -308,36 +295,55 @@ static int gc0310_gain_set(struct gc0310_device *dev, u32 gain) · 8 unmodified lines
308 dgain = gain / 2;295 dgain = gain / 2;
309 }296 }
310 297
311 ret = i2c_smbus_write_byte_data(client, GC0310_AGC_ADJ, again);298 cci_write(sensor->regmap, GC0310_AGC_ADJ_REG, again, &ret);
312 if (ret)299 cci_write(sensor->regmap, GC0310_DGC_ADJ_REG, dgain, &ret);
313 return ret;300 return ret;
301}
302
303static int gc0310_exposure_update_range(struct gc0310_device *sensor)
304{
305 int exp_max = GC0310_NATIVE_HEIGHT + sensor->ctrls.vblank->val;
314 306
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);
316}309}
317 310
318static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl)311static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl)
319{312{
320 struct gc0310_device *dev =313 struct gc0310_device *sensor =
321 container_of(ctrl->handler, struct gc0310_device, ctrls.handler);314 container_of(ctrl->handler, struct gc0310_device, ctrls.handler);
322 int ret;315 int ret;
323 316
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
324 /* Only apply changes to the controls if the device is powered up */324 /* 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))
326 return 0;326 return 0;
327 327
328 switch (ctrl->id) {328 switch (ctrl->id) {
329 case V4L2_CID_EXPOSURE:329 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);
331 break;332 break;
332 case V4L2_CID_GAIN:333 case V4L2_CID_ANALOGUE_GAIN:
333 ret = gc0310_gain_set(dev, ctrl->val);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);
334 break;340 break;
335 default:341 default:
336 ret = -EINVAL;342 ret = -EINVAL;
337 break;343 break;
338 }344 }
339 345
340 pm_runtime_put(dev->sd.dev);346 pm_runtime_put(sensor->sd.dev);
341 return ret;347 return ret;
342}348}
343 349
@@ -345,17 +351,6 @@ static const struct v4l2_ctrl_ops ctrl_ops = { · 1 unmodified line
345 .s_ctrl = gc0310_s_ctrl,351 .s_ctrl = gc0310_s_ctrl,
346};352};
347 353
348static struct v4l2_mbus_framefmt *
349gc0310_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
359/* The GC0310 currently only supports 1 fixed fmt */354/* The GC0310 currently only supports 1 fixed fmt */
360static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt)355static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt)
361{356{
@@ -366,54 +361,72 @@ static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt) · 4 unmodified lines
366 fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;361 fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
367}362}
368 363
369static int gc0310_set_fmt(struct v4l2_subdev *sd,364static int gc0310_get_selection(struct v4l2_subdev *sd,
370 struct v4l2_subdev_state *sd_state,365 struct v4l2_subdev_state *state,
371 struct v4l2_subdev_format *format)366 struct v4l2_subdev_selection *sel)
372{367{
373 struct gc0310_device *dev = to_gc0310_sensor(sd);368 /* Only the single fixed 656x496 mode is supported, without croping */
374 struct v4l2_mbus_framefmt *fmt;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}
375 385
376 fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);386static int gc0310_power_off(struct device *dev)
377 gc0310_fill_format(fmt);387{
388 struct v4l2_subdev *sd = dev_get_drvdata(dev);
389 struct gc0310_device *sensor = to_gc0310_sensor(sd);
378 390
379 format->format = *fmt;391 gpiod_set_value_cansleep(sensor->powerdown, 1);
392 gpiod_set_value_cansleep(sensor->reset, 1);
380 return 0;393 return 0;
381}394}
382 395
383static int gc0310_get_fmt(struct v4l2_subdev *sd,396static int gc0310_power_on(struct device *dev)
384 struct v4l2_subdev_state *sd_state,
385 struct v4l2_subdev_format *format)
386{397{
387 struct gc0310_device *dev = to_gc0310_sensor(sd);398 struct v4l2_subdev *sd = dev_get_drvdata(dev);
388 struct v4l2_mbus_framefmt *fmt;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);
389 406
390 fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
391 format->format = *fmt;
392 return 0;407 return 0;
393}408}
394 409
395static int gc0310_detect(struct i2c_client *client)410static int gc0310_detect(struct gc0310_device *sensor)
396{411{
397 struct i2c_adapter *adapter = client->adapter;412 struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
413 u64 val;
398 int ret;414 int ret;
399 415
400 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))416 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
401 return -ENODEV;417 return -ENODEV;
402 418
403 ret = pm_runtime_get_sync(&client->dev);419 ret = cci_read(sensor->regmap, GC0310_SC_CMMN_CHIP_ID_REG, &val, NULL);
404 if (ret >= 0)
405 ret = i2c_smbus_read_word_swapped(client, GC0310_SC_CMMN_CHIP_ID_H);
406 pm_runtime_put(&client->dev);
407 if (ret < 0) {420 if (ret < 0) {
408 dev_err(&client->dev, "read sensor_id failed: %d\n", ret);421 dev_err(&client->dev, "read sensor_id failed: %d\n", ret);
409 return -ENODEV;422 return -ENODEV;
410 }423 }
411 424
412 dev_dbg(&client->dev, "sensor ID = 0x%x\n", ret);425 dev_dbg(&client->dev, "sensor ID = 0x%llx\n", val);
413 426
414 if (ret != GC0310_ID) {427 if (val != GC0310_ID) {
415 dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n",428 dev_err(&client->dev, "sensor ID error, read id = 0x%llx, target id = 0x%x\n",
416 ret, GC0310_ID);429 val, GC0310_ID);
417 return -ENODEV;430 return -ENODEV;
418 }431 }
419 432
@@ -422,85 +435,67 @@ static int gc0310_detect(struct i2c_client *client) · 2 unmodified lines
422 return 0;435 return 0;
423}436}
424 437
425static int gc0310_s_stream(struct v4l2_subdev *sd, int enable)438static int gc0310_enable_streams(struct v4l2_subdev *sd,
439 struct v4l2_subdev_state *state,
440 u32 pad, u64 streams_mask)
426{441{
427 struct gc0310_device *dev = to_gc0310_sensor(sd);442 struct gc0310_device *sensor = to_gc0310_sensor(sd);
428 struct i2c_client *client = v4l2_get_subdevdata(sd);443 struct i2c_client *client = v4l2_get_subdevdata(sd);
429 int ret = 0;444 int ret;
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 }
461 445
462 ret = i2c_smbus_write_byte_data(client, GC0310_RESET_RELATED, GC0310_REGISTER_PAGE_3);446 ret = pm_runtime_resume_and_get(&client->dev);
463 if (ret)447 if (ret)
464 goto error_power_down;448 return ret;
465 449
466 ret = i2c_smbus_write_byte_data(client, GC0310_SW_STREAM,450 ret = regmap_multi_reg_write(sensor->regmap,
467 enable ? GC0310_START_STREAMING : GC0310_STOP_STREAMING);451 gc0310_reset_register,
452 ARRAY_SIZE(gc0310_reset_register));
468 if (ret)453 if (ret)
469 goto error_power_down;454 goto error_power_down;
470 455
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));
472 if (ret)459 if (ret)
473 goto error_power_down;460 goto error_power_down;
474 461
475 if (!enable)462 /* restore value of all ctrls */
476 pm_runtime_put(&client->dev);463 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
477 464
478 dev->is_streaming = enable;465 /* enable per frame MIPI and sensor ctrl reset */
479 mutex_unlock(&dev->input_lock);466 cci_write(sensor->regmap, GC0310_RESET_RELATED_REG, 0x30, &ret);
480 return 0;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);
481 474
482error_power_down:475error_power_down:
483 pm_runtime_put(&client->dev);476 if (ret)
484 dev->is_streaming = false;477 pm_runtime_put(&client->dev);
485 mutex_unlock(&dev->input_lock);478
486 return ret;479 return ret;
487}480}
488 481
489static int gc0310_get_frame_interval(struct v4l2_subdev *sd,482static int gc0310_disable_streams(struct v4l2_subdev *sd,
490 struct v4l2_subdev_state *sd_state,483 struct v4l2_subdev_state *state,
491 struct v4l2_subdev_frame_interval *interval)484 u32 pad, u64 streams_mask)
492{485{
493 /*486 struct gc0310_device *sensor = to_gc0310_sensor(sd);
494 * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2487 struct i2c_client *client = v4l2_get_subdevdata(sd);
495 * subdev active state API.488 int ret = 0;
496 */
497 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
498 return -EINVAL;
499 489
500 interval->interval.numerator = 1;490 cci_write(sensor->regmap, GC0310_RESET_RELATED_REG,
501 interval->interval.denominator = GC0310_FPS;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);
502 496
503 return 0;497 pm_runtime_put(&client->dev);
498 return ret;
504}499}
505 500
506static int gc0310_enum_mbus_code(struct v4l2_subdev *sd,501static 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
531 return 0;526 return 0;
532}527}
533 528
534static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
535{
536 *frames = GC0310_SKIP_FRAMES;
537 return 0;
538}
539
540static const struct v4l2_subdev_sensor_ops gc0310_sensor_ops = {
541 .g_skip_frames = gc0310_g_skip_frames,
542};
543
544static const struct v4l2_subdev_video_ops gc0310_video_ops = {529static const struct v4l2_subdev_video_ops gc0310_video_ops = {
545 .s_stream = gc0310_s_stream,530 .s_stream = v4l2_subdev_s_stream_helper,
546};531};
547 532
548static const struct v4l2_subdev_pad_ops gc0310_pad_ops = {533static const struct v4l2_subdev_pad_ops gc0310_pad_ops = {
549 .enum_mbus_code = gc0310_enum_mbus_code,534 .enum_mbus_code = gc0310_enum_mbus_code,
550 .enum_frame_size = gc0310_enum_frame_size,535 .enum_frame_size = gc0310_enum_frame_size,
551 .get_fmt = gc0310_get_fmt,536 .get_fmt = v4l2_subdev_get_fmt,
552 .set_fmt = gc0310_set_fmt,537 .set_fmt = v4l2_subdev_get_fmt, /* Only 1 fixed mode supported */
553 .get_frame_interval = gc0310_get_frame_interval,538 .get_selection = gc0310_get_selection,
539 .set_selection = gc0310_get_selection,
540 .enable_streams = gc0310_enable_streams,
541 .disable_streams = gc0310_disable_streams,
554};542};
555 543
556static const struct v4l2_subdev_ops gc0310_ops = {544static const struct v4l2_subdev_ops gc0310_ops = {
557 .video = &gc0310_video_ops,545 .video = &gc0310_video_ops,
558 .pad = &gc0310_pad_ops,546 .pad = &gc0310_pad_ops,
559 .sensor = &gc0310_sensor_ops,
560};547};
561 548
562static int gc0310_init_controls(struct gc0310_device *dev)549static int gc0310_init_state(struct v4l2_subdev *sd,
550 struct v4l2_subdev_state *sd_state)
563{551{
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}
565 555
566 v4l2_ctrl_handler_init(hdl, 2);556static const struct v4l2_subdev_internal_ops gc0310_internal_ops = {
557 .init_state = gc0310_init_state,
558};
559
560static 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);
567 568
568 /* Use the same lock for controls as for everything else */569 /* Use the same lock for controls as for everything else */
569 hdl->lock = &dev->input_lock;570 sensor->sd.ctrl_handler = hdl;
570 dev->sd.ctrl_handler = hdl;
571 571
572 dev->ctrls.exposure =572 exp_max = GC0310_NATIVE_HEIGHT + GC0310_V_BLANK_DEFAULT;
573 v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, 4095, 1, 1023);573 sensor->ctrls.exposure =
574 v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0,
575 exp_max, 1, exp_max);
574 576
575 /* 32 steps at base gain 1 + 64 half steps at base gain 2 */577 /* 32 steps at base gain 1 + 64 half steps at base gain 2 */
576 dev->ctrls.gain =578 sensor->ctrls.gain =
577 v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_GAIN, 0, 95, 1, 31);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);
578 605
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;
580}613}
581 614
582static void gc0310_remove(struct i2c_client *client)615static void gc0310_remove(struct i2c_client *client)
583{616{
584 struct v4l2_subdev *sd = i2c_get_clientdata(client);617 struct v4l2_subdev *sd = i2c_get_clientdata(client);
585 struct gc0310_device *dev = to_gc0310_sensor(sd);618 struct gc0310_device *sensor = to_gc0310_sensor(sd);
586
587 dev_dbg(&client->dev, "gc0310_remove...\n");
588 619
589 v4l2_async_unregister_subdev(sd);620 v4l2_async_unregister_subdev(sd);
590 media_entity_cleanup(&dev->sd.entity);621 v4l2_subdev_cleanup(sd);
591 v4l2_ctrl_handler_free(&dev->ctrls.handler);622 media_entity_cleanup(&sensor->sd.entity);
592 mutex_destroy(&dev->input_lock);623 v4l2_ctrl_handler_free(&sensor->ctrls.handler);
593 pm_runtime_disable(&client->dev);624 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 }
594}629}
595 630
596static int gc0310_probe(struct i2c_client *client)631static int gc0310_check_hwcfg(struct device *dev)
597{632{
633 struct v4l2_fwnode_endpoint bus_cfg = {
634 .bus_type = V4L2_MBUS_CSI2_DPHY,
635 };
598 struct fwnode_handle *ep_fwnode;636 struct fwnode_handle *ep_fwnode;
599 struct gc0310_device *dev;637 unsigned long link_freq_bitmap;
638 u32 mclk;
600 int ret;639 int ret;
601 640
602 /*641 /*
603 * Sometimes the fwnode graph is initialized by the bridge driver.642 * Sometimes the fwnode graph is initialized by the bridge driver.
604 * Bridge drivers doing this may also add GPIO mappings, wait for this.643 * Bridge drivers doing this may also add GPIO mappings, wait for this.
605 */644 */
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);
607 if (!ep_fwnode)646 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 }
609 664
665 ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &bus_cfg);
610 fwnode_handle_put(ep_fwnode);666 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
685static int gc0310_probe(struct i2c_client *client)
686{
687 struct gc0310_device *sensor;
688 int ret;
611 689
612 dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);690 ret = gc0310_check_hwcfg(&client->dev);
613 if (!dev)691 if (ret)
692 return ret;
693
694 sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
695 if (!sensor)
614 return -ENOMEM;696 return -ENOMEM;
615 697
616 dev->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);698 sensor->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
617 if (IS_ERR(dev->reset)) {699 if (IS_ERR(sensor->reset)) {
618 return dev_err_probe(&client->dev, PTR_ERR(dev->reset),700 return dev_err_probe(&client->dev, PTR_ERR(sensor->reset),
619 "getting reset GPIO\n");701 "getting reset GPIO\n");
620 }702 }
621 703
622 dev->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);704 sensor->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);
623 if (IS_ERR(dev->powerdown)) {705 if (IS_ERR(sensor->powerdown)) {
624 return dev_err_probe(&client->dev, PTR_ERR(dev->powerdown),706 return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown),
625 "getting powerdown GPIO\n");707 "getting powerdown GPIO\n");
626 }708 }
627 709
628 mutex_init(&dev->input_lock);710 v4l2_i2c_subdev_init(&sensor->sd, client, &gc0310_ops);
629 v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops);
630 gc0310_fill_format(&dev->mode.fmt);
631 711
632 pm_runtime_set_suspended(&client->dev);712 sensor->regmap = devm_cci_regmap_init_i2c(client, 8);
633 pm_runtime_enable(&client->dev);713 if (IS_ERR(sensor->regmap))
634 pm_runtime_set_autosuspend_delay(&client->dev, 1000);714 return PTR_ERR(sensor->regmap);
635 pm_runtime_use_autosuspend(&client->dev);
636 715
637 ret = gc0310_detect(client);716 gc0310_power_on(&client->dev);
638 if (ret) {
639 gc0310_remove(client);
640 return ret;
641 }
642 717
643 dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;718 pm_runtime_set_active(&client->dev);
644 dev->pad.flags = MEDIA_PAD_FL_SOURCE;719 pm_runtime_get_noresume(&client->dev);
645 dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;720 pm_runtime_enable(&client->dev);
646
647 ret = gc0310_init_controls(dev);
648 if (ret) {
649 gc0310_remove(client);
650 return ret;
651 }
652 721
653 ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);722 ret = gc0310_detect(sensor);
654 if (ret) {723 if (ret)
655 gc0310_remove(client);724 goto err_power_down;
656 return ret;
657 }
658 725
659 ret = v4l2_async_register_subdev_sensor(&dev->sd);726 sensor->sd.internal_ops = &gc0310_internal_ops;
660 if (ret) {727 sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
661 gc0310_remove(client);728 sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
662 return ret;729 sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
663 }
664 730
665 return 0;731 ret = gc0310_init_controls(sensor);
666}732 if (ret)
733 goto err_power_down;
667 734
668static int gc0310_suspend(struct device *dev)735 ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
669{736 if (ret)
670 struct v4l2_subdev *sd = dev_get_drvdata(dev);737 goto err_power_down;
671 struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd);
672 738
673 gpiod_set_value_cansleep(gc0310_dev->powerdown, 1);739 sensor->sd.state_lock = sensor->ctrls.handler.lock;
674 gpiod_set_value_cansleep(gc0310_dev->reset, 1);740 ret = v4l2_subdev_init_finalize(&sensor->sd);
675 return 0;741 if (ret)
676}742 goto err_power_down;
677 743
678static int gc0310_resume(struct device *dev)744 ret = v4l2_async_register_subdev_sensor(&sensor->sd);
679{745 if (ret)
680 struct v4l2_subdev *sd = dev_get_drvdata(dev);746 goto err_power_down;
681 struct gc0310_device *gc0310_dev = to_gc0310_sensor(sd);
682 747
683 usleep_range(10000, 15000);748 pm_runtime_set_autosuspend_delay(&client->dev, 1000);
684 gpiod_set_value_cansleep(gc0310_dev->reset, 0);749 pm_runtime_use_autosuspend(&client->dev);
685 usleep_range(10000, 15000);750 pm_runtime_put_autosuspend(&client->dev);
686 gpiod_set_value_cansleep(gc0310_dev->powerdown, 0);
687 751
688 return 0;752 return 0;
753
754err_power_down:
755 pm_runtime_put_noidle(&client->dev);
756 gc0310_remove(client);
757 return ret;
689}758}
690 759
691static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops, gc0310_suspend, gc0310_resume, NULL);760static DEFINE_RUNTIME_DEV_PM_OPS(gc0310_pm_ops,
761 gc0310_power_off, gc0310_power_on, NULL);
692 762
693static const struct acpi_device_id gc0310_acpi_match[] = {763static const struct acpi_device_id gc0310_acpi_match[] = {
694 {"INT0310"},764 {"INT0310"},
@@ -708,5 +778,6 @@ static struct i2c_driver gc0310_driver = { · 13 unmodified lines
708module_i2c_driver(gc0310_driver);778module_i2c_driver(gc0310_driver);
709 779
710MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>");780MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>");
781MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>");
711MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors");782MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors");
712MODULE_LICENSE("GPL");783MODULE_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
779 struct v4l2_subdev *sd = i2c_get_clientdata(client);779 struct v4l2_subdev *sd = i2c_get_clientdata(client);
780 struct gc2235_device *dev = to_gc2235_sensor(sd);780 struct gc2235_device *dev = to_gc2235_sensor(sd);
781 781
782 dev_dbg(&client->dev, "gc2235_remove...\n");
783
784 dev->platform_data->csi_cfg(sd, 0);782 dev->platform_data->csi_cfg(sd, 0);
785 783
786 v4l2_device_unregister_subdev(sd);784 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
179 struct gc2235_write_buffer buffer;179 struct gc2235_write_buffer buffer;
180};180};
181 181
182static struct gc2235_reg const gc2235_stream_on[] = {182static const struct gc2235_reg gc2235_stream_on[] = {
183 { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */183 { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */
184 { GC2235_8BIT, 0x10, 0x91}, /* start mipi */184 { GC2235_8BIT, 0x10, 0x91}, /* start mipi */
185 { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */185 { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */
186 { GC2235_TOK_TERM, 0, 0 }186 { GC2235_TOK_TERM, 0, 0 }
187};187};
188 188
189static struct gc2235_reg const gc2235_stream_off[] = {189static const struct gc2235_reg gc2235_stream_off[] = {
190 { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */190 { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */
191 { GC2235_8BIT, 0x10, 0x01}, /* stop mipi */191 { GC2235_8BIT, 0x10, 0x01}, /* stop mipi */
192 { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */192 { GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */
193 { GC2235_TOK_TERM, 0, 0 }193 { GC2235_TOK_TERM, 0, 0 }
194};194};
195 195
196static struct gc2235_reg const gc2235_init_settings[] = {196static const struct gc2235_reg gc2235_init_settings[] = {
197 /* System */197 /* System */
198 { GC2235_8BIT, 0xfe, 0x80 },198 { GC2235_8BIT, 0xfe, 0x80 },
199 { GC2235_8BIT, 0xfe, 0x80 },199 { GC2235_8BIT, 0xfe, 0x80 },
@@ -268,7 +268,7 @@ static struct gc2235_reg const gc2235_init_settings[] = { · 68 unmodified lines
268 * Register settings for various resolution268 * Register settings for various resolution
269 */269 */
270#if ENABLE_NON_PREVIEW270#if ENABLE_NON_PREVIEW
271static struct gc2235_reg const gc2235_1296_736_30fps[] = {271static const struct gc2235_reg gc2235_1296_736_30fps[] = {
272 { GC2235_8BIT, 0x8b, 0xa0 },272 { GC2235_8BIT, 0x8b, 0xa0 },
273 { GC2235_8BIT, 0x8c, 0x02 },273 { GC2235_8BIT, 0x8c, 0x02 },
274 274
@@ -321,7 +321,7 @@ static struct gc2235_reg const gc2235_1296_736_30fps[] = { · 46 unmodified lines
321 { GC2235_TOK_TERM, 0, 0 }321 { GC2235_TOK_TERM, 0, 0 }
322};322};
323 323
324static struct gc2235_reg const gc2235_960_640_30fps[] = {324static const struct gc2235_reg gc2235_960_640_30fps[] = {
325 { GC2235_8BIT, 0x8b, 0xa0 },325 { GC2235_8BIT, 0x8b, 0xa0 },
326 { GC2235_8BIT, 0x8c, 0x02 },326 { GC2235_8BIT, 0x8c, 0x02 },
327 327
@@ -373,7 +373,7 @@ static struct gc2235_reg const gc2235_960_640_30fps[] = { · 45 unmodified lines
373};373};
374#endif374#endif
375 375
376static struct gc2235_reg const gc2235_1600_900_30fps[] = {376static const struct gc2235_reg gc2235_1600_900_30fps[] = {
377 { GC2235_8BIT, 0x8b, 0xa0 },377 { GC2235_8BIT, 0x8b, 0xa0 },
378 { GC2235_8BIT, 0x8c, 0x02 },378 { GC2235_8BIT, 0x8c, 0x02 },
379 379
@@ -418,7 +418,7 @@ static struct gc2235_reg const gc2235_1600_900_30fps[] = { · 38 unmodified lines
418 { GC2235_TOK_TERM, 0, 0 }418 { GC2235_TOK_TERM, 0, 0 }
419};419};
420 420
421static struct gc2235_reg const gc2235_1616_1082_30fps[] = {421static const struct gc2235_reg gc2235_1616_1082_30fps[] = {
422 { GC2235_8BIT, 0x8b, 0xa0 },422 { GC2235_8BIT, 0x8b, 0xa0 },
423 { GC2235_8BIT, 0x8c, 0x02 },423 { GC2235_8BIT, 0x8c, 0x02 },
424 424
@@ -463,7 +463,7 @@ static struct gc2235_reg const gc2235_1616_1082_30fps[] = { · 38 unmodified lines
463 { GC2235_TOK_TERM, 0, 0 }463 { GC2235_TOK_TERM, 0, 0 }
464};464};
465 465
466static struct gc2235_reg const gc2235_1616_1216_30fps[] = {466static const struct gc2235_reg gc2235_1616_1216_30fps[] = {
467 { GC2235_8BIT, 0x8b, 0xa0 },467 { GC2235_8BIT, 0x8b, 0xa0 },
468 { GC2235_8BIT, 0x8c, 0x02 },468 { GC2235_8BIT, 0x8c, 0x02 },
469 469
drivers/staging/media/atomisp/i2c/ov2722.h+8−8
@@ -236,7 +236,7 @@ struct ov2722_write_ctrl { · 235 unmodified lines
236 * Register settings for various resolution236 * Register settings for various resolution
237 */237 */
238#if 0238#if 0
239static struct ov2722_reg const ov2722_QVGA_30fps[] = {239static const struct ov2722_reg ov2722_QVGA_30fps[] = {
240 {OV2722_8BIT, 0x3718, 0x10},240 {OV2722_8BIT, 0x3718, 0x10},
241 {OV2722_8BIT, 0x3702, 0x0c},241 {OV2722_8BIT, 0x3702, 0x0c},
242 {OV2722_8BIT, 0x373a, 0x1c},242 {OV2722_8BIT, 0x373a, 0x1c},
@@ -346,7 +346,7 @@ static struct ov2722_reg const ov2722_QVGA_30fps[] = { · 103 unmodified lines
346 346
347};347};
348 348
349static struct ov2722_reg const ov2722_480P_30fps[] = {349static const struct ov2722_reg ov2722_480P_30fps[] = {
350 {OV2722_8BIT, 0x3718, 0x10},350 {OV2722_8BIT, 0x3718, 0x10},
351 {OV2722_8BIT, 0x3702, 0x18},351 {OV2722_8BIT, 0x3702, 0x18},
352 {OV2722_8BIT, 0x373a, 0x3c},352 {OV2722_8BIT, 0x373a, 0x3c},
@@ -455,7 +455,7 @@ static struct ov2722_reg const ov2722_480P_30fps[] = { · 102 unmodified lines
455 {OV2722_TOK_TERM, 0, 0},455 {OV2722_TOK_TERM, 0, 0},
456};456};
457 457
458static struct ov2722_reg const ov2722_VGA_30fps[] = {458static const struct ov2722_reg ov2722_VGA_30fps[] = {
459 {OV2722_8BIT, 0x3718, 0x10},459 {OV2722_8BIT, 0x3718, 0x10},
460 {OV2722_8BIT, 0x3702, 0x18},460 {OV2722_8BIT, 0x3702, 0x18},
461 {OV2722_8BIT, 0x373a, 0x3c},461 {OV2722_8BIT, 0x373a, 0x3c},
@@ -565,7 +565,7 @@ static struct ov2722_reg const ov2722_VGA_30fps[] = { · 103 unmodified lines
565};565};
566#endif566#endif
567 567
568static struct ov2722_reg const ov2722_1632_1092_30fps[] = {568static const struct ov2722_reg ov2722_1632_1092_30fps[] = {
569 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for569 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for
570 a whole frame complete.(vblank) */570 a whole frame complete.(vblank) */
571 {OV2722_8BIT, 0x3718, 0x10},571 {OV2722_8BIT, 0x3718, 0x10},
@@ -667,7 +667,7 @@ static struct ov2722_reg const ov2722_1632_1092_30fps[] = { · 95 unmodified lines
667 {OV2722_TOK_TERM, 0, 0}667 {OV2722_TOK_TERM, 0, 0}
668};668};
669 669
670static struct ov2722_reg const ov2722_1452_1092_30fps[] = {670static const struct ov2722_reg ov2722_1452_1092_30fps[] = {
671 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for671 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for
672 a whole frame complete.(vblank) */672 a whole frame complete.(vblank) */
673 {OV2722_8BIT, 0x3718, 0x10},673 {OV2722_8BIT, 0x3718, 0x10},
@@ -769,7 +769,7 @@ static struct ov2722_reg const ov2722_1452_1092_30fps[] = { · 95 unmodified lines
769};769};
770 770
771#if 0771#if 0
772static struct ov2722_reg const ov2722_1M3_30fps[] = {772static const struct ov2722_reg ov2722_1M3_30fps[] = {
773 {OV2722_8BIT, 0x3718, 0x10},773 {OV2722_8BIT, 0x3718, 0x10},
774 {OV2722_8BIT, 0x3702, 0x24},774 {OV2722_8BIT, 0x3702, 0x24},
775 {OV2722_8BIT, 0x373a, 0x60},775 {OV2722_8BIT, 0x373a, 0x60},
@@ -877,7 +877,7 @@ static struct ov2722_reg const ov2722_1M3_30fps[] = { · 101 unmodified lines
877};877};
878#endif878#endif
879 879
880static struct ov2722_reg const ov2722_1080p_30fps[] = {880static const struct ov2722_reg ov2722_1080p_30fps[] = {
881 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for a whole881 {OV2722_8BIT, 0x3021, 0x03}, /* For stand wait for a whole
882 frame complete.(vblank) */882 frame complete.(vblank) */
883 {OV2722_8BIT, 0x3718, 0x10},883 {OV2722_8BIT, 0x3718, 0x10},
@@ -983,7 +983,7 @@ static struct ov2722_reg const ov2722_1080p_30fps[] = { · 99 unmodified lines
983};983};
984 984
985#if 0 /* Currently unused */985#if 0 /* Currently unused */
986static struct ov2722_reg const ov2722_720p_30fps[] = {986static const struct ov2722_reg ov2722_720p_30fps[] = {
987 {OV2722_8BIT, 0x3021, 0x03},987 {OV2722_8BIT, 0x3021, 0x03},
988 {OV2722_8BIT, 0x3718, 0x10},988 {OV2722_8BIT, 0x3718, 0x10},
989 {OV2722_8BIT, 0x3702, 0x24},989 {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
387 }387 }
388 388
389 if (stream_env->stream_state == CSS_STREAM_STARTED) {389 if (stream_env->stream_state == CSS_STREAM_STARTED) {
390 timeout = jiffies + msecs_to_jiffies(40);390 timeout = jiffies + msecs_to_jiffies(200);
391 while (1) {391 while (1) {
392 if (ia_css_stream_has_stopped(stream_env->stream))392 if (ia_css_stream_has_stopped(stream_env->stream))
393 break;393 break;
drivers/staging/media/atomisp/pci/atomisp_csi2.h+0−17
@@ -19,28 +19,11 @@ · 18 unmodified lines
19#define CSI2_PAD_SOURCE 119#define CSI2_PAD_SOURCE 1
20#define CSI2_PADS_NUM 220#define CSI2_PADS_NUM 2
21 21
22#define CSI2_MAX_ACPI_GPIOS 2u
23
24struct acpi_device;
25struct v4l2_device;22struct v4l2_device;
26 23
27struct atomisp_device;24struct atomisp_device;
28struct atomisp_sub_device;25struct atomisp_sub_device;
29 26
30struct 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
35struct 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
44struct atomisp_mipi_csi2_device {27struct atomisp_mipi_csi2_device {
45 struct v4l2_subdev subdev;28 struct v4l2_subdev subdev;
46 struct media_pad pads[CSI2_PADS_NUM];29 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
13#include <linux/clk.h>13#include <linux/clk.h>
14#include <linux/device.h>14#include <linux/device.h>
15#include <linux/dmi.h>15#include <linux/dmi.h>
16#include <linux/platform_data/x86/int3472.h>
16#include <linux/property.h>17#include <linux/property.h>
17 18
18#include <media/ipu-bridge.h>19#include <media/ipu-bridge.h>
@@ -24,39 +25,6 @@ · 5 unmodified lines
24 25
25#define PMC_CLK_RATE_19_2MHZ 1920000026#define PMC_CLK_RATE_19_2MHZ 19200000
26 27
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 */
33static 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 */
56static const guid_t intel_sensor_module_guid =
57 GUID_INIT(0x822ace8f, 0x2814, 0x4174,
58 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);
59
60/*28/*
61 * dc2f6c4f-045b-4f1d-97b9-882a6860a4be29 * dc2f6c4f-045b-4f1d-97b9-882a6860a4be
62 * This _DSM GUID returns a package with n*2 strings, with each set of 2 strings30 * 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
323 return gmin_cfg_get_int(adev, "CsiPort", port);291 return gmin_cfg_get_int(adev, "CsiPort", port);
324}292}
325 293
326/* Note this always returns 1 to continue looping so that res_count is accurate */
327static 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
399/*294/*
400 * Helper function to create an ACPI GPIO lookup table for sensor reset and295 * Alloc and fill an int3472_discrete_device struct so that we can re-use
401 * powerdown signals on Intel Bay Trail (BYT) and Cherry Trail (CHT) devices,296 * the INT3472 sensor GPIO mapping code.
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().
413 *297 *
414 * Note this code uses the same DSM GUID as the int3472_gpio_guid in298 * This gets called from ipu_bridge_init() which runs only once per boot,
415 * the INT3472 discrete.c code and there is some overlap, but there are299 * the created faux int3472 device is leaked on purpose to keep the created
416 * enough differences that it is difficult to share the code.300 * GPIO mappings around permanently.
417 */301 */
418static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev)302static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev)
419{303{
420 struct atomisp_csi2_acpi_gpio_parsing_data data = { };304 struct int3472_discrete_device *int3472;
421 LIST_HEAD(resource_list);
422 union acpi_object *obj;
423 unsigned int i, j;
424 int ret;305 int ret;
425 306
426 obj = acpi_evaluate_dsm_typed(adev->handle, &intel_sensor_module_guid,307 /* Max num GPIOs we've seen plus a terminator */
427 0x00, 1, NULL, ACPI_TYPE_STRING);308 int3472 = kzalloc(struct_size(int3472, gpios.table, INT3472_MAX_SENSOR_GPIOS + 1),
428 if (obj) {309 GFP_KERNEL);
429 acpi_handle_info(adev->handle, "%s: Sensor module id: '%s'\n",310 if (!int3472)
430 dev_name(&adev->dev), obj->string.pointer);311 return -ENOMEM;
431 ACPI_FREE(obj);
432 }
433 312
434 /*313 /*
435 * First get the GPIO-settings count and then get count GPIO-settings314 * On atomisp the _DSM to get the GPIO type must be made on the sensor
436 * values. Note the order of these may differ from the order in which315 * adev, rather than on a separate INT3472 adev.
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.
439 */316 */
440 obj = acpi_evaluate_dsm_typed(adev->handle,317 int3472->adev = adev;
441 &intel_sensor_gpio_info_guid, 0x00, 1,318 int3472->dev = &adev->dev;
442 NULL, ACPI_TYPE_INTEGER);319 int3472->sensor = adev;
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);
451 320
452 if (data.settings_count > CSI2_MAX_ACPI_GPIOS) {321 int3472->sensor_name = kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(adev));
453 acpi_handle_err(adev->handle, "%s: Too many GPIOs %u > %u\n",322 if (!int3472->sensor_name) {
454 dev_name(&adev->dev), data.settings_count,323 kfree(int3472);
455 CSI2_MAX_ACPI_GPIOS);324 return -ENOMEM;
456 return -EOVERFLOW;
457 }325 }
458 326
459 for (i = 0; i < data.settings_count; i++) {327 ret = int3472_discrete_parse_crs(int3472);
460 /*328 if (ret) {
461 * i + 2 because the index of this _DSM function is 1-based329 int3472_discrete_cleanup(int3472);
462 * and the first function is just a count.330 kfree(int3472);
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);
476 }331 }
477 332
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
516 return ret;333 return ret;
517}334}
518 335
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 */
29static unsigned int dbgopt = OPTION_BIN_LIST;
30
31static 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
62opt_err:
63 return ret;
64}
65
66static 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
74static 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}
90static DEVICE_ATTR_RW(dbglvl);
91
92static 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
100static 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}
113static DEVICE_ATTR_RW(dbgfun);
114
115static 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
121static 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}
139static DEVICE_ATTR_RW(dbgopt);
140
141static struct attribute *dbg_attrs[] = {
142 &dev_attr_dbglvl.attr,
143 &dev_attr_dbgfun.attr,
144 &dev_attr_dbgopt.attr,
145 NULL
146};
147
148static const struct attribute_group dbg_attr_group = {
149 .attrs = dbg_attrs,
150};
151
152const 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
13extern 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
234 if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM))234 if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM))
235 return -EINVAL;235 return -EINVAL;
236 236
237 if (pipe->stopping)
238 return -EINVAL;
239
240 space = ATOMISP_CSS_Q_DEPTH - atomisp_buffers_in_css(pipe);237 space = ATOMISP_CSS_Q_DEPTH - atomisp_buffers_in_css(pipe);
241 while (space--) {238 while (space--) {
242 struct ia_css_frame *frame;239 struct ia_css_frame *frame;
@@ -367,7 +364,7 @@ static void atomisp_buf_queue(struct vb2_buffer *vb) · 124 unmodified lines
367 mutex_lock(&asd->isp->mutex);364 mutex_lock(&asd->isp->mutex);
368 365
369 ret = atomisp_pipe_check(pipe, false);366 ret = atomisp_pipe_check(pipe, false);
370 if (ret || pipe->stopping) {367 if (ret) {
371 spin_lock_irqsave(&pipe->irq_lock, irqflags);368 spin_lock_irqsave(&pipe->irq_lock, irqflags);
372 atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);369 atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
373 spin_unlock_irqrestore(&pipe->irq_lock, irqflags);370 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
856 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00);856 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00);
857}857}
858 858
859static 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
859int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)915int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)
860{916{
861 struct atomisp_video_pipe *pipe = vq_to_pipe(vq);917 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
910 ret = atomisp_css_start(asd);966 ret = atomisp_css_start(asd);
911 if (ret) {967 if (ret) {
912 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true);968 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true);
969 media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]);
913 goto out_unlock;970 goto out_unlock;
914 }971 }
915 972
@@ -949,11 +1006,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) · 33 unmodified lines
949 video, s_stream, 1);1006 video, s_stream, 1);
950 if (ret) {1007 if (ret) {
951 dev_err(isp->dev, "Starting sensor stream failed: %d\n", ret);1008 dev_err(isp->dev, "Starting sensor stream failed: %d\n", ret);
952 spin_lock_irqsave(&isp->lock, irqflags);1009 atomisp_stop_stream(pipe, false, VB2_BUF_STATE_QUEUED);
953 asd->streaming = false;
954 spin_unlock_irqrestore(&isp->lock, irqflags);
955 ret = -EINVAL;
956 goto out_unlock;
957 }1010 }
958 1011
959out_unlock:1012out_unlock:
@@ -964,74 +1017,12 @@ out_unlock: · 4 unmodified lines
964void atomisp_stop_streaming(struct vb2_queue *vq)1017void atomisp_stop_streaming(struct vb2_queue *vq)
965{1018{
966 struct atomisp_video_pipe *pipe = vq_to_pipe(vq);1019 struct atomisp_video_pipe *pipe = vq_to_pipe(vq);
967 struct atomisp_sub_device *asd = pipe->asd;1020 struct atomisp_device *isp = pipe->asd->isp;
968 struct atomisp_device *isp = asd->isp;
969 struct pci_dev *pdev = to_pci_dev(isp->dev);
970 unsigned long flags;
971 int ret;
972 1021
973 dev_dbg(isp->dev, "Stop stream\n");1022 dev_dbg(isp->dev, "Stop stream\n");
974 1023
975 mutex_lock(&isp->mutex);1024 mutex_lock(&isp->mutex);
976 /*1025 atomisp_stop_stream(pipe, true, VB2_BUF_STATE_ERROR);
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]);
1035 mutex_unlock(&isp->mutex);1026 mutex_unlock(&isp->mutex);
1036}1027}
1037 1028
drivers/staging/media/atomisp/pci/atomisp_subdev.h+0−3
@@ -57,9 +57,6 @@ struct atomisp_video_pipe { · 56 unmodified lines
57 /* Filled through atomisp_get_css_frame_info() on queue setup */57 /* Filled through atomisp_get_css_frame_info() on queue setup */
58 struct ia_css_frame_info frame_info;58 struct ia_css_frame_info frame_info;
59 59
60 /* Set from streamoff to disallow queuing further buffers in CSS */
61 bool stopping;
62
63 /*60 /*
64 * irq_lock is used to protect video buffer state change operations and61 * irq_lock is used to protect video buffer state change operations and
65 * also to make activeq and capq operations atomic.62 * 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
29#include "atomisp_internal.h"29#include "atomisp_internal.h"
30#include "atomisp-regs.h"30#include "atomisp-regs.h"
31#include "atomisp_dfs_tables.h"31#include "atomisp_dfs_tables.h"
32#include "atomisp_drvfs.h"
33#include "hmm/hmm.h"32#include "hmm/hmm.h"
34#include "atomisp_trace_event.h"33#include "atomisp_trace_event.h"
35 34
@@ -1497,9 +1496,6 @@ static const struct pci_device_id atomisp_pci_tbl[] = { · 1461 unmodified lines
1497MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl);1496MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl);
1498 1497
1499static struct pci_driver atomisp_pci_driver = {1498static struct pci_driver atomisp_pci_driver = {
1500 .driver = {
1501 .dev_groups = dbg_attr_groups,
1502 },
1503 .name = "atomisp-isp2",1499 .name = "atomisp-isp2",
1504 .id_table = atomisp_pci_tbl,1500 .id_table = atomisp_pci_tbl,
1505 .probe = atomisp_pci_probe,1501 .probe = atomisp_pci_probe,
@@ -1513,3 +1509,4 @@ MODULE_AUTHOR("Xiaolin Zhang <xiaolin.zhang@intel.com>"); · 7 unmodified lines
1513MODULE_LICENSE("GPL");1509MODULE_LICENSE("GPL");
1514MODULE_DESCRIPTION("Intel ATOM Platform ISP Driver");1510MODULE_DESCRIPTION("Intel ATOM Platform ISP Driver");
1515MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");1511MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
1512MODULE_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
10/* Override the definition of max/min from Linux kernel */10/* Override the definition of max/min from Linux kernel */
11#include <linux/minmax.h>11#include <linux/minmax.h>
12 12
13/* force a value to a lower even value */
14#define EVEN_FLOOR(x) ((x) & ~1)
15
16#define CEIL_DIV(a, b) (((b) != 0) ? ((a) + (b) - 1) / (b) : 0)13#define CEIL_DIV(a, b) (((b) != 0) ? ((a) + (b) - 1) / (b) : 0)
17#define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b))14#define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b))
18#define CEIL_MUL2(a, b) (((a) + (b) - 1) & ~((b) - 1))
19#define CEIL_SHIFT(a, b) (((a) + (1 << (b)) - 1) >> (b))15#define CEIL_SHIFT(a, b) (((a) + (1 << (b)) - 1) >> (b))
20#define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b))
21 16
22/*17/*
23 * For SP and ISP, SDK provides the definition of OP_std_modadd.18 * 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
28static ia_css_ptr dummy_ptr = mmgr_EXCEPTION;28static ia_css_ptr dummy_ptr = mmgr_EXCEPTION;
29static bool hmm_initialized;29static bool hmm_initialized;
30 30
31/*
32 * p: private
33 * v: vmalloc
34 */
35static const char hmm_bo_type_string[] = "pv";
36
37static 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
87static 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
93static 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
100static DEVICE_ATTR_RO(active_bo);
101static DEVICE_ATTR_RO(free_bo);
102
103static struct attribute *sysfs_attrs_ctrl[] = {
104 &dev_attr_active_bo.attr,
105 &dev_attr_free_bo.attr,
106 NULL
107};
108
109static struct attribute_group atomisp_attribute_group[] = {
110 {.attrs = sysfs_attrs_ctrl },
111};
112
113int hmm_init(void)31int hmm_init(void)
114{32{
115 int ret;33 int ret;
@@ -130,14 +48,6 @@ int hmm_init(void) · 14 unmodified lines
130 */48 */
131 dummy_ptr = hmm_alloc(1);49 dummy_ptr = hmm_alloc(1);
132 50
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
141 return ret;51 return ret;
142}52}
143 53
@@ -145,7 +55,6 @@ void hmm_cleanup(void) · 1 unmodified line
145{55{
146 if (dummy_ptr == mmgr_EXCEPTION)56 if (dummy_ptr == mmgr_EXCEPTION)
147 return;57 return;
148 sysfs_remove_group(&atomisp_dev->kobj, atomisp_attribute_group);
149 58
150 /* free dummy memory first */59 /* free dummy memory first */
151 hmm_free(dummy_ptr);60 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
37 unsigned int pgnr)37 unsigned int pgnr)
38{38{
39 check_bodev_null_return(bdev, -EINVAL);39 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");
42 /* prevent zero size buffer object */40 /* prevent zero size buffer object */
43 if (pgnr == 0) {41 if (pgnr == 0) {
44 dev_err(atomisp_dev, "0 size buffer is not allowed.\n");42 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
341 spin_lock_init(&bdev->list_lock);339 spin_lock_init(&bdev->list_lock);
342 mutex_init(&bdev->rbtree_mutex);340 mutex_init(&bdev->rbtree_mutex);
343 341
344 bdev->flag = HMM_BO_DEVICE_INITED;
345 342
346 INIT_LIST_HEAD(&bdev->entire_bo_list);343 INIT_LIST_HEAD(&bdev->entire_bo_list);
347 bdev->allocated_rbtree = RB_ROOT;344 bdev->allocated_rbtree = RB_ROOT;
@@ -376,6 +373,8 @@ int hmm_bo_device_init(struct hmm_bo_device *bdev, · 28 unmodified lines
376 373
377 __bo_insert_to_free_rbtree(&bdev->free_rbtree, bo);374 __bo_insert_to_free_rbtree(&bdev->free_rbtree, bo);
378 375
376 bdev->flag = HMM_BO_DEVICE_INITED;
377
379 return 0;378 return 0;
380}379}
381 380
drivers/staging/media/atomisp/pci/ia_css_pipe.h+0−2
@@ -102,8 +102,6 @@ struct ia_css_yuvpp_settings { · 101 unmodified lines
102struct osys_object;102struct osys_object;
103 103
104struct ia_css_pipe {104struct ia_css_pipe {
105 /* TODO: Remove stop_requested and use stop_requested in the pipeline */
106 bool stop_requested;
107 struct ia_css_pipe_config config;105 struct ia_css_pipe_config config;
108 struct ia_css_pipe_extra_config extra_config;106 struct ia_css_pipe_extra_config extra_config;
109 struct ia_css_pipe_info info;107 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
11 * CSS-API header file for Advanced Noise Reduction kernel v111 * CSS-API header file for Advanced Noise Reduction kernel v1
12 */12 */
13 13
14#include <linux/math.h>
15
14/* Application specific DMA settings */16/* Application specific DMA settings */
15#define ANR_BPP 1017#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)
17 19
18/* Advanced Noise Reduction configuration.20/* Advanced Noise Reduction configuration.
19 * This is also known as Low-Light.21 * 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
7#ifndef __IA_CSS_DPC2_PARAM_H7#ifndef __IA_CSS_DPC2_PARAM_H
8#define __IA_CSS_DPC2_PARAM_H8#define __IA_CSS_DPC2_PARAM_H
9 9
10#include <linux/math.h>
11
10#include "type_support.h"12#include "type_support.h"
11#include "vmem.h" /* for VMEM_ARRAY*/13#include "vmem.h" /* for VMEM_ARRAY*/
12 14
@@ -19,12 +21,12 @@ · 6 unmodified lines
19/* 3 lines state per color plane input_line_state */21/* 3 lines state per color plane input_line_state */
20#define DPC2_STATE_INPUT_BUFFER_HEIGHT (3 * NUM_PLANES)22#define DPC2_STATE_INPUT_BUFFER_HEIGHT (3 * NUM_PLANES)
21/* Each plane has width equal to half frame line */23/* 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)
23 25
24/* 1 line state per color plane for local deviation state*/26/* 1 line state per color plane for local deviation state*/
25#define DPC2_STATE_LOCAL_DEVIATION_BUFFER_HEIGHT (1 * NUM_PLANES)27#define DPC2_STATE_LOCAL_DEVIATION_BUFFER_HEIGHT (1 * NUM_PLANES)
26/* Each plane has width equal to half frame line */28/* 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)
28 30
29/* MINMAX state buffer stores 1 full input line (GR-R color line) */31/* MINMAX state buffer stores 1 full input line (GR-R color line) */
30#define DPC2_STATE_SECOND_MINMAX_BUFFER_HEIGHT 132#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
141 141
142 /* similar to topleft_y calculation, but round up if ymax142 /* similar to topleft_y calculation, but round up if ymax
143 * has any fraction bits */143 * 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));
145 s.in_block_height = bottom_y - topleft_y + dvs_interp_envelope;145 s.in_block_height = bottom_y - topleft_y + dvs_interp_envelope;
146 146
147 bottom_x = CEIL_DIV(xmax, 1 << DVS_COORD_FRAC_BITS);147 bottom_x = DIV_ROUND_UP(xmax, BIT(DVS_COORD_FRAC_BITS));
148 s.in_block_width = bottom_x - topleft_x + dvs_interp_envelope;148 s.in_block_width = bottom_x - topleft_x + dvs_interp_envelope;
149 149
150 topleft_x_frac = topleft_x << (DVS_COORD_FRAC_BITS);150 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
7#ifndef __IA_CSS_EED1_8_PARAM_H7#ifndef __IA_CSS_EED1_8_PARAM_H
8#define __IA_CSS_EED1_8_PARAM_H8#define __IA_CSS_EED1_8_PARAM_H
9 9
10#include <linux/math.h>
11
10#include "type_support.h"12#include "type_support.h"
11#include "vmem.h" /* needed for VMEM_ARRAY */13#include "vmem.h" /* needed for VMEM_ARRAY */
12 14
@@ -35,35 +37,35 @@ · 22 unmodified lines
35#define EED1_8_STATE_INPUT_BUFFER_HEIGHT (5 * NUM_PLANES)37#define EED1_8_STATE_INPUT_BUFFER_HEIGHT (5 * NUM_PLANES)
36 38
37/* Each plane has width equal to half frame line */39/* 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)
39 41
40/* 1 line state per color plane LD_H state */42/* 1 line state per color plane LD_H state */
41#define EED1_8_STATE_LD_H_HEIGHT (1 * NUM_PLANES)43#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)
43 45
44/* 1 line state per color plane LD_V state */46/* 1 line state per color plane LD_V state */
45#define EED1_8_STATE_LD_V_HEIGHT (1 * NUM_PLANES)47#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)
47 49
48/* 1 line (single plane) state for D_Hr state */50/* 1 line (single plane) state for D_Hr state */
49#define EED1_8_STATE_D_HR_HEIGHT 151#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)
51 53
52/* 1 line (single plane) state for D_Hb state */54/* 1 line (single plane) state for D_Hb state */
53#define EED1_8_STATE_D_HB_HEIGHT 155#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)
55 57
56/* 2 lines (single plane) state for D_Vr state */58/* 2 lines (single plane) state for D_Vr state */
57#define EED1_8_STATE_D_VR_HEIGHT 259#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)
59 61
60/* 2 line (single plane) state for D_Vb state */62/* 2 line (single plane) state for D_Vb state */
61#define EED1_8_STATE_D_VB_HEIGHT 263#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)
63 65
64/* 2 lines state for R and B (= 2 planes) rb_zipped_state */66/* 2 lines state for R and B (= 2 planes) rb_zipped_state */
65#define EED1_8_STATE_RB_ZIPPED_HEIGHT (2 * 2)67#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)
67 69
68#if EED1_8_FC_ENABLE_MEDIAN70#if EED1_8_FC_ENABLE_MEDIAN
69/* 1 full input line (GR-R color line) for Yc state */71/* 1 full input line (GR-R color line) for Yc state */
@@ -72,11 +74,11 @@ · 2 unmodified lines
72 74
73/* 1 line state per color plane Cg_state */75/* 1 line state per color plane Cg_state */
74#define EED1_8_STATE_CG_HEIGHT (1 * NUM_PLANES)76#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)
76 78
77/* 1 line state per color plane Co_state */79/* 1 line state per color plane Co_state */
78#define EED1_8_STATE_CO_HEIGHT (1 * NUM_PLANES)80#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)
80 82
81/* 1 full input line (GR-R color line) for AbsK state */83/* 1 full input line (GR-R color line) for AbsK state */
82#define EED1_8_STATE_ABSK_HEIGHT 184#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
4 * Copyright (c) 2015, Intel Corporation.4 * Copyright (c) 2015, Intel Corporation.
5 */5 */
6 6
7#include <linux/math.h>
8
7#include <assert_support.h>9#include <assert_support.h>
8#include <ia_css_frame_public.h>10#include <ia_css_frame_public.h>
9#include <ia_css_frame.h>11#include <ia_css_frame.h>
@@ -71,9 +73,9 @@ int ia_css_fpn_configure(const struct ia_css_binary *binary, · 61 unmodified lines
71 &my_info73 &my_info
72 };74 };
73 75
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 */
75 my_info.res.height = info->res.height;77 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 */
77 my_info.format = info->format;79 my_info.format = info->format;
78 my_info.raw_bit_depth = FPN_BITS_PER_PIXEL;80 my_info.raw_bit_depth = FPN_BITS_PER_PIXEL;
79 my_info.raw_bayer_order = info->raw_bayer_order;81 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
22 * vec_slice is used for 2 adjacent vectors of shading gains.22 * vec_slice is used for 2 adjacent vectors of shading gains.
23 * The number of shift times by vec_slice is 8.23 * The number of shift times by vec_slice is 8.
24 * Max grid cell bqs to support the shading table centerting: N = 3224 * Max grid cell bqs to support the shading table centerting: N = 32
25 * CEIL_DIV(N-1, ISP_SLICE_NELEMS) = CEIL_DIV(31, 4) = 825 * DIV_ROUND_UP(N-1, ISP_SLICE_NELEMS) = DIV_ROUND_UP(31, 4) = 8
26 */26 */
27#define SH_CSS_SC_INTERPED_GAIN_HOR_SLICE_TIMES 827#define SH_CSS_SC_INTERPED_GAIN_HOR_SLICE_TIMES 8
28 28
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
91 unsigned int vf_log_ds = 0;91 unsigned int vf_log_ds = 0;
92 92
93 /* First compute value */93 /* First compute value */
94 if (vf_info)94 if (vf_info) {
95 {
96 err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);95 err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);
97 if (err)96 if (err)
98 return err;97 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
8#ifndef _INPUT_BUF_ISP_H_8#ifndef _INPUT_BUF_ISP_H_
9#define _INPUT_BUF_ISP_H_9#define _INPUT_BUF_ISP_H_
10 10
11#include <linux/math.h>
12
11/* Temporary include, since IA_CSS_BINARY_MODE_COPY is still needed */13/* Temporary include, since IA_CSS_BINARY_MODE_COPY is still needed */
12#include "sh_css_defs.h"14#include "sh_css_defs.h"
13#include "isp_const.h" /* MAX_VECTORS_PER_INPUT_LINE */
14 15
15#define INPUT_BUF_HEIGHT 2 /* double buffer */16#define INPUT_BUF_HEIGHT 2 /* double buffer */
16#define INPUT_BUF_LINES 217#define INPUT_BUF_LINES 2
@@ -22,7 +23,8 @@ Copyright (c) 2010 - 2015, Intel Corporation. · 5 unmodified lines
22/* In continuous mode, the input buffer must be a fixed size for all binaries23/* In continuous mode, the input buffer must be a fixed size for all binaries
23 * and at a fixed address since it will be used by the SP. */24 * and at a fixed address since it will be used by the SP. */
24#define EXTRA_INPUT_VECTORS 2 /* For left padding */25#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)
26 28
27/* The input buffer should be on a fixed address in vmem, for continuous capture */29/* The input buffer should be on a fixed address in vmem, for continuous capture */
28#define INPUT_BUF_ADDR 0x030#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/**
3Support for Intel Camera Imaging ISP subsystem.
4Copyright (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
51#include "sp.h"51#include "sp.h"
52#include "isp.h"52#include "isp.h"
53#include "type_support.h"53#include "type_support.h"
54#include "math_support.h" /* CEIL_DIV */
55#include "input_system.h" /* input_formatter_reg_load */54#include "input_system.h" /* input_formatter_reg_load */
56#include "ia_css_tagger_common.h"55#include "ia_css_tagger_common.h"
57 56
drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c+15−14
@@ -4,15 +4,16 @@ · 3 unmodified lines
4 * Copyright (c) 2015, Intel Corporation.4 * Copyright (c) 2015, Intel Corporation.
5 */5 */
6 6
7#include "hmm.h"7#include <linux/bitops.h>
8#include <linux/math.h>
8 9
9#include "ia_css_frame.h"
10#include <math_support.h>
11#include "assert_support.h"10#include "assert_support.h"
11#include "atomisp_internal.h"
12#include "hmm.h"
12#include "ia_css_debug.h"13#include "ia_css_debug.h"
14#include "ia_css_frame.h"
13#include "isp.h"15#include "isp.h"
14#include "sh_css_internal.h"16#include "sh_css_internal.h"
15#include "atomisp_internal.h"
16 17
17#define NV12_TILEY_TILE_WIDTH 12818#define NV12_TILEY_TILE_WIDTH 128
18#define NV12_TILEY_TILE_HEIGHT 3219#define NV12_TILEY_TILE_HEIGHT 32
@@ -459,15 +460,16 @@ static void frame_init_single_plane(struct ia_css_frame *frame, · 440 unmodified lines
459 unsigned int stride;460 unsigned int stride;
460 461
461 stride = subpixels_per_line * bytes_per_pixel;462 stride = subpixels_per_line * bytes_per_pixel;
462 /* Frame height needs to be even number - needed by hw ISYS2401463 /*
463 In case of odd number, round up to even.464 * Frame height needs to be even number - needed by hw ISYS2401.
464 Images won't be impacted by this round up,465 * In case of odd number, round up to even.
465 only needed by jpeg/embedded data.466 * Images won't be impacted by this round up,
466 As long as buffer allocation and release are using data_bytes,467 * only needed by jpeg/embedded data.
467 there won't be memory leak. */468 * As long as buffer allocation and release are using data_bytes,
468 frame->data_bytes = stride * CEIL_MUL2(height, 2);469 * there won't be memory leak.
470 */
471 frame->data_bytes = stride * round_up(height, 2);
469 frame_init_plane(plane, subpixels_per_line, stride, height, 0);472 frame_init_plane(plane, subpixels_per_line, stride, height, 0);
470 return;
471}473}
472 474
473static void frame_init_raw_single_plane(475static void frame_init_raw_single_plane(
@@ -486,7 +488,6 @@ static void frame_init_raw_single_plane( · 12 unmodified lines
486 HIVE_ISP_DDR_WORD_BITS / bits_per_pixel);488 HIVE_ISP_DDR_WORD_BITS / bits_per_pixel);
487 frame->data_bytes = stride * height;489 frame->data_bytes = stride * height;
488 frame_init_plane(plane, subpixels_per_line, stride, height, 0);490 frame_init_plane(plane, subpixels_per_line, stride, height, 0);
489 return;
490}491}
491 492
492static void frame_init_nv_planes(struct ia_css_frame *frame,493static 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
690 if (info->format == IA_CSS_FRAME_FORMAT_RAW691 if (info->format == IA_CSS_FRAME_FORMAT_RAW
691 || (info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED)) {692 || (info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED)) {
692 if (info->raw_bit_depth)693 if (info->raw_bit_depth)
693 return CEIL_DIV(info->raw_bit_depth, 8);694 return BITS_TO_BYTES(info->raw_bit_depth);
694 else695 else
695 return 2; /* bytes per pixel */696 return 2; /* bytes per pixel */
696 }697 }
drivers/staging/media/atomisp/pci/runtime/ifmtr/src/ifmtr.c+5−6
@@ -4,9 +4,9 @@ · 3 unmodified lines
4 * Copyright (c) 2010 - 2015, Intel Corporation.4 * Copyright (c) 2010 - 2015, Intel Corporation.
5 */5 */
6 6
7#include "system_global.h"7#include <linux/math.h>
8#include <linux/kernel.h>
9 8
9#include "system_global.h"
10 10
11#include "ia_css_ifmtr.h"11#include "ia_css_ifmtr.h"
12#include <math_support.h>12#include <math_support.h>
@@ -149,10 +149,9 @@ int ia_css_ifmtr_configure(struct ia_css_stream_config *config, · 136 unmodified lines
149 left_padding = 2 * ISP_VEC_NELEMS - config->left_padding;149 left_padding = 2 * ISP_VEC_NELEMS - config->left_padding;
150 150
151 if (left_padding) {151 if (left_padding) {
152 num_vectors = CEIL_DIV(cropped_width + left_padding,152 num_vectors = DIV_ROUND_UP(cropped_width + left_padding, ISP_VEC_NELEMS);
153 ISP_VEC_NELEMS);
154 } else {153 } else {
155 num_vectors = CEIL_DIV(cropped_width, ISP_VEC_NELEMS);154 num_vectors = DIV_ROUND_UP(cropped_width, ISP_VEC_NELEMS);
156 num_vectors *= buffer_height;155 num_vectors *= buffer_height;
157 /* todo: in case of left padding,156 /* todo: in case of left padding,
158 num_vectors is vectors per line,157 num_vectors is vectors per line,
@@ -305,7 +304,7 @@ int ia_css_ifmtr_configure(struct ia_css_stream_config *config, · 146 unmodified lines
305 if ((!binary) || config->continuous)304 if ((!binary) || config->continuous)
306 /* !binary -> sp raw copy pipe */305 /* !binary -> sp raw copy pipe */
307 buffer_height *= 2;306 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);
309 vectors_per_line = CEIL_MUL(vectors_per_line, deinterleaving);308 vectors_per_line = CEIL_MUL(vectors_per_line, deinterleaving);
310 break;309 break;
311 case ATOMISP_INPUT_FORMAT_RAW_14:310 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
808 808
809 cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;809 cfg->elements = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
810 cfg->cropping = 0;810 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);
812 812
813 return true;813 return true;
814}814}
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
34struct ia_css_pipeline {34struct ia_css_pipeline {
35 enum ia_css_pipe_id pipe_id;35 enum ia_css_pipe_id pipe_id;
36 u8 pipe_num;36 u8 pipe_num;
37 bool stop_requested;
38 struct ia_css_pipeline_stage *stages;37 struct ia_css_pipeline_stage *stages;
39 struct ia_css_pipeline_stage *current_stage;38 struct ia_css_pipeline_stage *current_stage;
40 unsigned int num_stages;39 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
198 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,198 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
199 "ia_css_pipeline_request_stop() enter: pipeline=%p\n",199 "ia_css_pipeline_request_stop() enter: pipeline=%p\n",
200 pipeline);200 pipeline);
201 pipeline->stop_requested = true;
202 201
203 /* Send stop event to the sp*/202 /* Send stop event to the sp*/
204 /* This needs improvement, stop on all the pipes available203 /* This needs improvement, stop on all the pipes available
@@ -663,7 +662,6 @@ static void pipeline_init_defaults( · 458 unmodified lines
663 662
664 pipeline->pipe_id = pipe_id;663 pipeline->pipe_id = pipe_id;
665 pipeline->stages = NULL;664 pipeline->stages = NULL;
666 pipeline->stop_requested = false;
667 pipeline->current_stage = NULL;665 pipeline->current_stage = NULL;
668 666
669 memcpy(&pipeline->in_frame, &ia_css_default_frame,667 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
2002 2002
2003 sh_css_params_free_default_gdc_lut();2003 sh_css_params_free_default_gdc_lut();
2004 2004
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
2009 /* cleanup generic data */2005 /* cleanup generic data */
2010 sh_css_params_uninit();2006 sh_css_params_uninit();
2011 ia_css_refcount_uninit();2007 ia_css_refcount_uninit();
@@ -3743,23 +3739,6 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, · 1731 unmodified lines
3743 case IA_CSS_BUFFER_TYPE_INPUT_FRAME:3739 case IA_CSS_BUFFER_TYPE_INPUT_FRAME:
3744 case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:3740 case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:
3745 case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:3741 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;
3763 case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME:3742 case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME:
3764 case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:3743 case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
3765 frame = (struct ia_css_frame *)HOST_ADDRESS(ddr_buffer.kernel_ptr);3744 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
4095 return err;4074 return err;
4096 }4075 }
4097 4076
4098 pipe->stop_requested = false;
4099
4100 switch (pipe_id) {4077 switch (pipe_id) {
4101 case IA_CSS_PIPE_ID_PREVIEW:4078 case IA_CSS_PIPE_ID_PREVIEW:
4102 err = preview_start(pipe);4079 err = preview_start(pipe);
@@ -4120,19 +4097,15 @@ sh_css_pipe_start(struct ia_css_stream *stream) · 17 unmodified lines
4120 for (i = 1; i < stream->num_pipes && 0 == err ; i++) {4097 for (i = 1; i < stream->num_pipes && 0 == err ; i++) {
4121 switch (stream->pipes[i]->mode) {4098 switch (stream->pipes[i]->mode) {
4122 case IA_CSS_PIPE_ID_PREVIEW:4099 case IA_CSS_PIPE_ID_PREVIEW:
4123 stream->pipes[i]->stop_requested = false;
4124 err = preview_start(stream->pipes[i]);4100 err = preview_start(stream->pipes[i]);
4125 break;4101 break;
4126 case IA_CSS_PIPE_ID_VIDEO:4102 case IA_CSS_PIPE_ID_VIDEO:
4127 stream->pipes[i]->stop_requested = false;
4128 err = video_start(stream->pipes[i]);4103 err = video_start(stream->pipes[i]);
4129 break;4104 break;
4130 case IA_CSS_PIPE_ID_CAPTURE:4105 case IA_CSS_PIPE_ID_CAPTURE:
4131 stream->pipes[i]->stop_requested = false;
4132 err = capture_start(stream->pipes[i]);4106 err = capture_start(stream->pipes[i]);
4133 break;4107 break;
4134 case IA_CSS_PIPE_ID_YUVPP:4108 case IA_CSS_PIPE_ID_YUVPP:
4135 stream->pipes[i]->stop_requested = false;
4136 err = yuvpp_start(stream->pipes[i]);4109 err = yuvpp_start(stream->pipes[i]);
4137 break;4110 break;
4138 default:4111 default:
drivers/staging/media/atomisp/pci/sh_css_defs.h+6−6
@@ -7,12 +7,12 @@ · 6 unmodified lines
7#ifndef _SH_CSS_DEFS_H_7#ifndef _SH_CSS_DEFS_H_
8#define _SH_CSS_DEFS_H_8#define _SH_CSS_DEFS_H_
9 9
10#include <linux/math.h>
11
10#include "isp.h"12#include "isp.h"
11 13
12/*#include "vamem.h"*/ /* Cannot include for VAMEM properties this file is visible on ISP -> pipeline generator */14/*#include "vamem.h"*/ /* Cannot include for VAMEM properties this file is visible on ISP -> pipeline generator */
13 15
14#include "math_support.h" /* max(), min, etc etc */
15
16/* ID's for refcount */16/* ID's for refcount */
17#define IA_CSS_REFCOUNT_PARAM_SET_POOL 0xCAFE000117#define IA_CSS_REFCOUNT_PARAM_SET_POOL 0xCAFE0001
18#define IA_CSS_REFCOUNT_PARAM_BUFFER 0xCAFE000218#define IA_CSS_REFCOUNT_PARAM_BUFFER 0xCAFE0002
@@ -182,7 +182,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] · 163 unmodified lines
182 The ISP firmware needs these rules to be applied at pre-processor time,182 The ISP firmware needs these rules to be applied at pre-processor time,
183 that's why these are macros, not functions. */183 that's why these are macros, not functions. */
184#define _ISP_BQS(num) ((num) / 2)184#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)
186 186
187#define ISP_BQ_GRID_WIDTH(elements_per_line, deci_factor_log2) \187#define ISP_BQ_GRID_WIDTH(elements_per_line, deci_factor_log2) \
188 CEIL_SHIFT(elements_per_line / 2, deci_factor_log2)188 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
194/* The morphing table is similar to the shading table in the sense that we194/* The morphing table is similar to the shading table in the sense that we
195 have 1 more value than we have cells in the grid. */195 have 1 more value than we have cells in the grid. */
196#define _ISP_MORPH_TABLE_WIDTH(int_width) \196#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)
198#define _ISP_MORPH_TABLE_HEIGHT(int_height) \198#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)
200#define _ISP_MORPH_TABLE_ALIGNED_WIDTH(width) \200#define _ISP_MORPH_TABLE_ALIGNED_WIDTH(width) \
201 CEIL_MUL(_ISP_MORPH_TABLE_WIDTH(width), \201 CEIL_MUL(_ISP_MORPH_TABLE_WIDTH(width), \
202 SH_CSS_MORPH_TABLE_ELEMS_PER_DDR_WORD)202 SH_CSS_MORPH_TABLE_ELEMS_PER_DDR_WORD)
@@ -298,7 +298,7 @@ RGB[0,8191],coef[-8192,8191] -> RGB[0,8191] · 95 unmodified lines
298 c_subsampling, \298 c_subsampling, \
299 num_chunks, \299 num_chunks, \
300 pipelining) \300 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, \
302 dvs_env_width, \302 dvs_env_width, \
303 left_crop), \303 left_crop), \
304 __ISP_MIN_INTERNAL_WIDTH(num_chunks, \304 __ISP_MIN_INTERNAL_WIDTH(num_chunks, \
drivers/staging/media/atomisp/pci/sh_css_internal.h+3−5
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#define _SH_CSS_INTERNAL_H_8#define _SH_CSS_INTERNAL_H_
9 9
10#include <linux/build_bug.h>10#include <linux/build_bug.h>
11#include <linux/math.h>
11#include <linux/stdarg.h>12#include <linux/stdarg.h>
12 13
13#include <system_global.h>14#include <system_global.h>
@@ -95,7 +96,6 @@ · 81 unmodified lines
95 * the SIZE_OF_XXX macro of the corresponding struct. If they are not96 * the SIZE_OF_XXX macro of the corresponding struct. If they are not
96 * equal, functionality will break.97 * equal, functionality will break.
97 */98 */
98#define CALC_ALIGNMENT_MEMBER(x, y) (CEIL_MUL(x, y) - x)
99#define SIZE_OF_HRT_VADDRESS sizeof(hive_uint32)99#define SIZE_OF_HRT_VADDRESS sizeof(hive_uint32)
100 100
101/* Number of SP's */101/* Number of SP's */
@@ -704,13 +704,11 @@ struct sh_css_hmm_buffer { · 602 unmodified lines
704 704
705/* Do not use sizeof(uint64_t) since that does not exist of SP */705/* Do not use sizeof(uint64_t) since that does not exist of SP */
706#define SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT \706#define SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT \
707 (SIZE_OF_PAYLOAD_UNION + \707 (round_up(SIZE_OF_PAYLOAD_UNION, 8) + \
708 CALC_ALIGNMENT_MEMBER(SIZE_OF_PAYLOAD_UNION, 8) + \
709 8 + \708 8 + \
710 8 + \709 8 + \
711 SIZE_OF_IA_CSS_TIME_MEAS_STRUCT + \710 SIZE_OF_IA_CSS_TIME_MEAS_STRUCT + \
712 SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT + \711 round_up(SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT, 8))
713 CALC_ALIGNMENT_MEMBER(SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT, 8))
714 712
715static_assert(sizeof(struct sh_css_hmm_buffer) == SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT);713static_assert(sizeof(struct sh_css_hmm_buffer) == SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT);
716 714
drivers/staging/media/atomisp/pci/sh_css_mipi.c+0−11
@@ -185,17 +185,6 @@ mipi_init(void) · 184 unmodified lines
185 ref_count_mipi_allocation[i] = 0;185 ref_count_mipi_allocation[i] = 0;
186}186}
187 187
188bool 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
199/*188/*
200 * @brief Calculate the required MIPI buffer sizes.189 * @brief Calculate the required MIPI buffer sizes.
201 * Based on the stream configuration, calculate the190 * 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
14void14void
15mipi_init(void);15mipi_init(void);
16 16
17bool mipi_is_free(void);
18
19int17int
20allocate_mipi_frames(struct ia_css_pipe *pipe, struct ia_css_stream_info *info);18allocate_mipi_frames(struct ia_css_pipe *pipe, struct ia_css_stream_info *info);
21 19
drivers/staging/media/atomisp/pci/sh_css_param_dvs.h+11−11
@@ -7,6 +7,8 @@ · 6 unmodified lines
7#ifndef _SH_CSS_PARAMS_DVS_H_7#ifndef _SH_CSS_PARAMS_DVS_H_
8#define _SH_CSS_PARAMS_DVS_H_8#define _SH_CSS_PARAMS_DVS_H_
9 9
10#include <linux/math.h>
11
10#include <math_support.h>12#include <math_support.h>
11#include <ia_css_types.h>13#include <ia_css_types.h>
12#include "gdc_global.h" /* gdc_warp_param_mem_t */14#include "gdc_global.h" /* gdc_warp_param_mem_t */
@@ -20,22 +22,20 @@ · 7 unmodified lines
20 22
21/* ISP2400 */23/* ISP2400 */
22/* horizontal 64x64 blocks round up to DVS_BLOCKDIM_X, make even */24/* 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)
24 27
25/* ISP2400 */28/* ISP2400 */
26/* vertical 64x64 blocks round up to DVS_BLOCKDIM_Y */29/* vertical 64x64 blocks round up to DVS_BLOCKDIM_Y */
27#define DVS_NUM_BLOCKS_Y(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_LUMA))30#define DVS_NUM_BLOCKS_Y(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_Y_LUMA)
28#define DVS_NUM_BLOCKS_X_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_X))31#define DVS_NUM_BLOCKS_Y_CHROMA(X) DIV_ROUND_UP((X), DVS_BLOCKDIM_Y_CHROMA)
29#define DVS_NUM_BLOCKS_Y_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_CHROMA))
30 32
31#define DVS_TABLE_IN_BLOCKDIM_X_LUMA(X) (DVS_NUM_BLOCKS_X(X) + 1) /* N blocks have N + 1 set of coords */33/* N blocks have N + 1 set of coords */
32#define DVS_TABLE_IN_BLOCKDIM_X_CHROMA(X) (DVS_NUM_BLOCKS_X_CHROMA(X) + 1)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)
33#define DVS_TABLE_IN_BLOCKDIM_Y_LUMA(X) (DVS_NUM_BLOCKS_Y(X) + 1)36#define DVS_TABLE_IN_BLOCKDIM_Y_LUMA(X) (DVS_NUM_BLOCKS_Y(X) + 1)
34#define DVS_TABLE_IN_BLOCKDIM_Y_CHROMA(X) (DVS_NUM_BLOCKS_Y_CHROMA(X) + 1)37#define DVS_TABLE_IN_BLOCKDIM_Y_CHROMA(X) (DVS_NUM_BLOCKS_Y_CHROMA(X) + 1)
35 38
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
39#define DVS_COORD_FRAC_BITS (10)39#define DVS_COORD_FRAC_BITS (10)
40 40
41/* ISP2400 */41/* ISP2400 */
@@ -43,8 +43,8 @@ · 1 unmodified line
43 43
44#define XMEM_ALIGN_LOG2 (5)44#define XMEM_ALIGN_LOG2 (5)
45 45
46#define DVS_6AXIS_COORDS_ELEMS CEIL_MUL(sizeof(gdc_warp_param_mem_t) \46#define DVS_6AXIS_COORDS_ELEMS \
47 , HIVE_ISP_DDR_WORD_BYTES)47 round_up(sizeof(gdc_warp_param_mem_t), HIVE_ISP_DDR_WORD_BYTES)
48 48
49/* currently we only support two output with the same resolution, output 0 is th default one. */49/* currently we only support two output with the same resolution, output 0 is th default one. */
50#define DVS_6AXIS_BYTES(binary) \50#define DVS_6AXIS_BYTES(binary) \
drivers/staging/media/atomisp/pci/sh_css_params.c+6−6
@@ -4,6 +4,8 @@ · 3 unmodified lines
4 * Copyright (c) 2015, Intel Corporation.4 * Copyright (c) 2015, Intel Corporation.
5 */5 */
6 6
7#include <linux/math.h>
8
7#include "gdc_device.h" /* gdc_lut_store(), ... */9#include "gdc_device.h" /* gdc_lut_store(), ... */
8#include "isp.h" /* ISP_VEC_ELEMBITS */10#include "isp.h" /* ISP_VEC_ELEMBITS */
9#include "vamem.h"11#include "vamem.h"
@@ -21,8 +23,6 @@ · 11 unmodified lines
21 23
22#include "platform_support.h"24#include "platform_support.h"
23#include "assert_support.h"25#include "assert_support.h"
24#include "misc_support.h" /* NOT_USED */
25#include "math_support.h" /* max(), min() EVEN_FLOOR()*/
26 26
27#include "ia_css_stream.h"27#include "ia_css_stream.h"
28#include "sh_css_params_internal.h"28#include "sh_css_params_internal.h"
@@ -4042,10 +4042,10 @@ sh_css_update_uds_and_crop_info( · 4013 unmodified lines
4042 }4042 }
4043 4043
4044 /* Must enforce that the crop position is even */4044 /* Must enforce that the crop position is even */
4045 crop_x = EVEN_FLOOR(crop_x);4045 crop_x = round_down(crop_x, 2);
4046 crop_y = EVEN_FLOOR(crop_y);4046 crop_y = round_down(crop_y, 2);
4047 uds_xc = EVEN_FLOOR(uds_xc);4047 uds_xc = round_down(uds_xc, 2);
4048 uds_yc = EVEN_FLOOR(uds_yc);4048 uds_yc = round_down(uds_yc, 2);
4049 4049
4050 uds->xc = (uint16_t)uds_xc;4050 uds->xc = (uint16_t)uds_xc;
4051 uds->yc = (uint16_t)uds_yc;4051 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
912 return &priv->vdev;912 return &priv->vdev;
913 913
914err_m2m:914err_m2m:
915 video_set_drvdata(vfd, NULL);915 video_device_release(vfd);
916err_vfd:916err_vfd:
917 kfree(priv);917 kfree(priv);
918 return ERR_PTR(ret);918 return ERR_PTR(ret);
drivers/staging/media/ipu7/Kconfig+19−0
@@ -0,0 +1,19 @@
1config 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
4intel-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
13obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7.o
14
15intel-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
23obj-$(CONFIG_VIDEO_INTEL_IPU7) += intel-ipu7-isys.o
drivers/staging/media/ipu7/TODO+28−0
@@ -0,0 +1,28 @@
1This is a list of things that need to be done to get this driver out of the
2staging 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
26struct 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
60enum 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
71enum 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
80struct 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
94struct 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
117enum 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)
12typedef u32 ia_gofo_addr_t;
13
14#define IA_GOFO_ADDR_NULL (0U)
15
16struct 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
30struct 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
44struct ia_gofo_tlv_header {
45 u16 tlv_type;
46 u16 tlv_len32;
47};
48
49struct 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)
68struct 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
82enum 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
100struct 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
106struct ia_gofo_msg_header_ack {
107 struct ia_gofo_msg_header header;
108 struct ia_gofo_msg_err err;
109
110};
111
112struct 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)
119enum 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
127enum 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
135struct 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
150struct 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
159struct ia_gofo_msg_log_info_ts {
160 u64 msg_ts;
161 struct ia_gofo_msg_log_info log_info;
162};
163
164struct 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
14struct 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
13struct 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
36typedef u64 ipu7_insys_return_token;
37
38enum 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
54enum 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
64enum 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
84enum 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
94enum 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
135enum 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
201enum 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
207enum 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
215enum 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
221enum 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)
227struct ipu7_insys_resolution {
228 u32 width;
229 u32 height;
230};
231
232struct ipu7_insys_capture_output_pin_payload {
233 u64 user_token;
234 ia_gofo_addr_t addr;
235 u8 pad[4];
236};
237
238struct 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
251struct ipu7_insys_output_cropping {
252 u16 line_top;
253 u16 line_bottom;
254};
255
256struct ipu7_insys_output_dpcm {
257 u8 enable;
258 u8 type;
259 u8 predictor;
260 u8 pad;
261};
262
263struct 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
275struct 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
285struct 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
296struct 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
304struct 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
318struct ipu7_insys_resp_queue_token {
319 struct ipu7_insys_resp resp_info;
320};
321
322struct 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
332enum 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
375enum 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
404enum 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)
12enum 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
34enum 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
43typedef u32 ipu7_msg_teb_t[2];
44typedef 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
49typedef u32 ipu7_msg_rbm_t[RBM_NUM_UINT32];
50
51enum 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
58struct ipu7_msg_node_profile {
59 struct ia_gofo_tlv_header tlv_header;
60 ipu7_msg_teb_t teb;
61};
62
63struct 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.