2024-01-11 08:57:17

by Changhuang Liang

[permalink] [raw]
Subject: [PATCH v2 00/13] Add ISP 3A for StarFive

This series implements the ISP 3A function to the Camera Subsystem on StarFive
JH7110 SoC. The series has been tested on the VisionFive 2 board.

This series is based on top of the master branch of media_stage repository,
which is tested with a v4l2-compliance compiled from the git repo
(git://linuxtv.org/v4l-utils.git).

changes since v1:
- Rebsaed on top of the master branch of media_stage repository.
- Documentated ISP submodule.
- Add new ISP parameters format and document it.
- Add a meta output video device and link to ISP subdev.
- Replaced control with meta output video buffer for write ISP parameters.
- Separate buffer operation which can use for capture and output device.
- Drop ISP frame sync event.

v1: https://lore.kernel.org/all/[email protected]/


The following are the media graph for the device and the v4l2-compliance
output.

==========================================================================================

[the media graph]:

digraph board {
rankdir=TB
n00000001 [label="{{<port0> 0 | <port1> 1} | stf_isp\n/dev/v4l-subdev0 | {<port2> 2 | <port3> 3}}", shape=Mrecord, style=filled, fillcolor=green]
n00000001:port2 -> n0000000e
n00000001:port3 -> n00000012 [style=dashed]
n00000006 [label="output_params\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
n00000006 -> n00000001:port1 [style=dashed]
n0000000a [label="capture_raw\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
n0000000e [label="capture_yuv\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
n00000012 [label="capture_scd\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
n0000001c [label="{{<port0> 0} | cdns_csi2rx.19800000.csi-bridge\n/dev/v4l-subdev1 | {<port1> 1 | <port2> 2 | <port3> 3 | <port4> 4}}", shape=Mrecord, style=filled, fillcolor=green]
n0000001c:port1 -> n00000001:port0 [style=dashed]
n0000001c:port1 -> n0000000a [style=dashed]
n00000026 [label="{{} | imx219 6-0010\n/dev/v4l-subdev2 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
n00000026:port0 -> n0000001c:port0 [style=bold]
}

[v4l2-compliance test]:

# v4l2-compliance -m /dev/media0
v4l2-compliance 1.27.0, 64 bits, 64-bit time_t

Compliance test for starfive-camss device /dev/media0:

Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0

Required ioctls:
test MEDIA_IOC_DEVICE_INFO: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/media0 open: OK
test MEDIA_IOC_DEVICE_INFO: OK
test for unlimited opens: OK

Media Controller ioctls:
test MEDIA_IOC_G_TOPOLOGY: OK
Entities: 7 Interfaces: 7 Pads: 14 Links: 13
test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
test MEDIA_IOC_SETUP_LINK: OK

Total for starfive-camss device /dev/media0: 8, Succeeded: 8, Failed: 0, Warnings: 0
--------------------------------------------------------------------------------
Compliance test for starfive-camss device /dev/video0:

Driver Info:
Driver name : starfive-camss
Card type : Starfive Camera Subsystem
Bus info : platform:19840000.camss
Driver version : 6.7.0
Capabilities : 0xac200000
Metadata Output
I/O MC
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x2c200000
Metadata Output
I/O MC
Streaming
Extended Pix Format
Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0
Interface Info:
ID : 0x03000008
Type : V4L Video
Entity Info:
ID : 0x00000006 (6)
Name : output_params
Function : V4L2 I/O
Pad 0x01000007 : 0: Source
Link 0x02000016: to remote pad 0x1000003 of entity 'stf_isp' (Image Signal Processor): Data

Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/video0 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 1 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls (Output 0):
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0

Format ioctls (Output 0):
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)

Codec ioctls (Output 0):
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls (Output 0):
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)

Total for starfive-camss device /dev/video0: 47, Succeeded: 47, Failed: 0, Warnings: 0
--------------------------------------------------------------------------------
Compliance test for starfive-camss device /dev/video1:

Driver Info:
Driver name : starfive-camss
Card type : Starfive Camera Subsystem
Bus info : platform:19840000.camss
Driver version : 6.7.0
Capabilities : 0xa4200001
Video Capture
I/O MC
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x24200001
Video Capture
I/O MC
Streaming
Extended Pix Format
Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0
Interface Info:
ID : 0x0300000c
Type : V4L Video
Entity Info:
ID : 0x0000000a (10)
Name : capture_raw
Function : V4L2 I/O
Pad 0x0100000b : 0: Sink
Link 0x02000024: from remote pad 0x100001e of entity 'cdns_csi2rx.19800000.csi-bridge' (Video Interface Bridge): Data

Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/video1 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls (Input 0):
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0

Format ioctls (Input 0):
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK

Codec ioctls (Input 0):
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls (Input 0):
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)

Total for starfive-camss device /dev/video1: 47, Succeeded: 47, Failed: 0, Warnings: 0
--------------------------------------------------------------------------------
Compliance test for starfive-camss device /dev/video2:

Driver Info:
Driver name : starfive-camss
Card type : Starfive Camera Subsystem
Bus info : platform:19840000.camss
Driver version : 6.7.0
Capabilities : 0xa4200001
Video Capture
I/O MC
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x24200001
Video Capture
I/O MC
Streaming
Extended Pix Format
Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0
Interface Info:
ID : 0x03000010
Type : V4L Video
Entity Info:
ID : 0x0000000e (14)
Name : capture_yuv
Function : V4L2 I/O
Pad 0x0100000f : 0: Sink
Link 0x02000018: from remote pad 0x1000004 of entity 'stf_isp' (Image Signal Processor): Data

Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/video2 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls (Input 0):
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0

Format ioctls (Input 0):
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK

Codec ioctls (Input 0):
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls (Input 0):
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)

Total for starfive-camss device /dev/video2: 47, Succeeded: 47, Failed: 0, Warnings: 0
--------------------------------------------------------------------------------
Compliance test for starfive-camss device /dev/video3:

Driver Info:
Driver name : starfive-camss
Card type : Starfive Camera Subsystem
Bus info : platform:19840000.camss
Driver version : 6.7.0
Capabilities : 0xa4a00000
Metadata Capture
I/O MC
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x24a00000
Metadata Capture
I/O MC
Streaming
Extended Pix Format
Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0
Interface Info:
ID : 0x03000014
Type : V4L Video
Entity Info:
ID : 0x00000012 (18)
Name : capture_scd
Function : V4L2 I/O
Pad 0x01000013 : 0: Sink
Link 0x0200001a: from remote pad 0x1000005 of entity 'stf_isp' (Image Signal Processor): Data

Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/video3 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls (Input 0):
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0

Format ioctls (Input 0):
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)

Codecstf_isp: ================= START STATUS =================
ioctls (Input 0stf_isp: ================== END STATUS ==================
):
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls (Input 0):
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)

Total for starfive-camss device /dev/video3: 47, Succeeded: 47, Failed: 0, Warnings: 0
--------------------------------------------------------------------------------
Compliance test for starfive-camss device /dev/v4l-subdev0:

Driver Info:
Driver version : 6.7.0
Capabilities : 0x00000000
Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0
Interface Info:
ID : 0x0300002a
Type : V4L Sub-Device
Entity Info:
ID : 0x00000001 (1)
Name : stf_isp
Function : Image Signal Processor
Pad 0x01000002 : 0: Sink
Link 0x02000022: from remote pad 0x100001e of entity 'cdns_csi2rx.19800000.csi-bridge' (Video Interface Bridge): Data
Pad 0x01000003 : 1: Sink
Link 0x02000016: from remote pad 0x1000007 of entity 'output_params' (V4L2 I/O): Data
Pad 0x01000004 : 2: Source
Link 0x02000018: to remote pad 0x100000f of entity 'capture_yuv' (V4L2 I/O): Data
Pad 0x01000005 : 3: Source
Link 0x0200001a: to remote pad 0x1000013 of entity 'capture_scd' (V4L2 I/O): Data

Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_SUDBEV_QUERYCAP: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/v4l-subdev0 open: OK
test VIDIOC_SUBDEV_QUERYCAP: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Sub-Device ioctls (Sink Pad 0):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Sub-Device ioctls (Sink Pad 1):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Sub-Device ioctls (Source Pad 2):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Sub-Device ioctls (Source Pad 3):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0

Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK (Not Supported)
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK (Not Supported)
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)

Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK (Not Supported)
test Requests: OK (Not Supported)

Total for starfive-camss device /dev/v4l-subdev0: 73, Succeeded: 73, Failed: 0, Warnings: 0
--------------------------------------------------------------------------------
Compliance test for starfive-camss device /dev/v4l-subdev1:

Driver Info:
Driver version : 6.7.0
Capabilities : 0x00000000
Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0
Interface Info:
ID : 0x0300002c
Type : V4L Sub-Device
Entity Info:
ID : 0x0000001c (28)
Name : cdns_csi2rx.19800000.csi-bridge
Function : Video Interface Bridge
Pad 0x0100001d : 0: Sink
Link 0x02000028: from remote pad 0x1000027 of entity 'imx219 6-0010' (Camera Sensor): Data, Enabled, Immutable
Pad 0x0100001e : 1: Source
Link 0x02000022: to remote pad 0x1000002 of entity 'stf_isp' (Image Signal Processor): Data
Link 0x02000024: to remote pad 0x100000b of entity 'captcdns_csi2rx.19800000.csi-bridge: ================= START STATUS =================
ure_raw' (V4L2 Icdns_csi2rx.19800000.csi-bridge: ================== END STATUS ==================
/O): Data
Pad 0x0100001f : 2: Source
Pad 0x01000020 : 3: Source
Pad 0x01000021 : 4: Source

Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_SUDBEV_QUERYCAP: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/v4l-subdev1 open: OK
test VIDIOC_SUBDEV_QUERYCAP: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Sub-Device ioctls (Sink Pad 0):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Sub-Device ioctls (Source Pad 1):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Sub-Device ioctls (Source Pad 2):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Sub-Device ioctls (Source Pad 3):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Sub-Device ioctls (Source Pad 4):
Try Stream 0
test Try VIDIOC_SUBDEV_ENimx219 6-0010: ================= START STATUS =================
UM_MBUS_CODE/FRAimx219 6-0010: ================== END STATUS ==================
ME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Try VIDIOC_SUBDEV_G/S_FMT: OK
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK (Not Supported)
test Active VIDIOC_SUBDEV_G/S_FMT: OK
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK (Not Supported)
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0

Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK (Not Supported)
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK (Not Supported)
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)

Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK (Not Supported)
test Requests: OK (Not Supported)

Total for starfive-camss device /dev/v4l-subdev1: 80, Succeeded: 80, Failed: 0, Warnings: 0
--------------------------------------------------------------------------------
Compliance test for starfive-camss device /dev/v4l-subdev2:

Driver Info:
Driver version : 6.7.0
Capabilities : 0x00000000
Media Driver Info:
Driver name : starfive-camss
Model : Starfive Camera Subsystem
Serial :
Bus info : platform:19840000.camss
Media version : 6.7.0
Hardware revision: 0x00000000 (0)
Driver version : 6.7.0
Interface Info:
ID : 0x0300002e
Type : V4L Sub-Device
Entity Info:
ID : 0x00000026 (38)
Name : imx219 6-0010
Function : Camera Sensor
Pad 0x01000027 : 0: Source
Link 0x02000028: to remote pad 0x100001d of entity 'cdns_csi2rx.19800000.csi-bridge' (Video Interface Bridge): Data, Enabled, Immutable

Required ioctls:
test MC information (see 'Media Driver Info' above): OK
test VIDIOC_SUDBEV_QUERYCAP: OK
test invalid ioctls: OK

Allow for multiple opens:
test second /dev/v4l-subdev2 open: OK
test VIDIOC_SUBDEV_QUERYCAP: OK
test for unlimited opens: OK

Debug ioctls:
test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)

Sub-Device ioctls (Source Pad 0):
Try Stream 0
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Try VIDIOC_SUBDEV_G/S_FMT: OK
warn: v4l2-test-subdevs.cpp(541): VIDIOC_SUBDEV_G_SELECTION is supported for target 0 but not VIDIOC_SUBDEV_S_SELECTION
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
Active Stream 0
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
test Active VIDIOC_SUBDEV_G/S_FMT: OK
warn: v4l2-test-subdevs.cpp(541): VIDIOC_SUBDEV_G_SELECTION is supported for target 0 but not VIDIOC_SUBDEV_S_SELECTION
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)

Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 20 Private Controls: 0

Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK (Not Supported)
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK (Not Supported)
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)

Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK (Not Supported)
test Requests: OK (Not Supported)

Total for starfive-camss device /dev/v4l-subdev2: 52, Succeeded: 52, Failed: 0, Warnings: 2

Grand Total for starfive-camss device /dev/media0: 401, Succeeded: 401, Failed: 0, Warnings: 2

Two warnings are from the imx219, can ignore them.

Changhuang Liang (13):
media: starfive: Add JH7110 ISP module definitions
media: Documentation: Add description for StarFive ISP metadata
formats
media: videodev2.h, v4l2-ioctl: Add StarFive ISP meta buffer format
staging: media: starfive: Add a params sink pad and a scd source pad
for ISP
staging: media: starfive: Separate buffer from ISP hardware operation
staging: media: starfive: Separate buffer be a common file
staging: media: starfive: Separate ISP hardware from capture device
staging: media: starfive: Add for StarFive ISP 3A SC
staging: media: starfive: Update ISP initialise config for 3A
staging: media: starfive: Add V4L2_CAP_IO_MC capability
staging: media: starfive: Add ISP params video device
staging: media: starfive: Add ISP parameters hardware configure
admin-guide: media: Update documents for StarFive Camera Subsystem

.../admin-guide/media/starfive_camss.rst | 11 +-
.../media/starfive_camss_graph.dot | 22 +-
.../media/v4l/metafmt-starfive-isp.rst | 75 ++
MAINTAINERS | 2 +
drivers/media/v4l2-core/v4l2-ioctl.c | 2 +
drivers/staging/media/starfive/camss/Makefile | 3 +
.../staging/media/starfive/camss/stf-buffer.c | 166 ++++
.../staging/media/starfive/camss/stf-buffer.h | 53 ++
.../staging/media/starfive/camss/stf-camss.c | 27 +-
.../staging/media/starfive/camss/stf-camss.h | 12 +
.../media/starfive/camss/stf-capture.c | 248 +-----
.../media/starfive/camss/stf-capture.h | 22 -
.../media/starfive/camss/stf-isp-hw-ops.c | 720 +++++++++++++++++
.../media/starfive/camss/stf-isp-params.c | 238 ++++++
.../staging/media/starfive/camss/stf-isp.c | 87 ++-
.../staging/media/starfive/camss/stf-isp.h | 188 +++++
.../staging/media/starfive/camss/stf-output.c | 83 ++
.../staging/media/starfive/camss/stf-output.h | 22 +
.../staging/media/starfive/camss/stf-video.c | 143 +++-
.../staging/media/starfive/camss/stf-video.h | 11 +-
include/uapi/linux/jh7110-isp.h | 739 ++++++++++++++++++
include/uapi/linux/videodev2.h | 4 +
22 files changed, 2592 insertions(+), 286 deletions(-)
create mode 100644 Documentation/userspace-api/media/v4l/metafmt-starfive-isp.rst
create mode 100644 drivers/staging/media/starfive/camss/stf-buffer.c
create mode 100644 drivers/staging/media/starfive/camss/stf-buffer.h
create mode 100644 drivers/staging/media/starfive/camss/stf-isp-params.c
create mode 100644 drivers/staging/media/starfive/camss/stf-output.c
create mode 100644 drivers/staging/media/starfive/camss/stf-output.h
create mode 100644 include/uapi/linux/jh7110-isp.h

--
2.25.1


2024-01-11 09:01:14

by Changhuang Liang

[permalink] [raw]
Subject: [PATCH v2 05/13] staging: media: starfive: Separate buffer from ISP hardware operation

Separate buffer from ISP hardware operation. Convenient to extract the
buffer be a common file.
Replace "while" with "if" in stf_buf_done helper function because one
interrupt signal only handle one video buffer.

Signed-off-by: Changhuang Liang <[email protected]>
---
.../media/starfive/camss/stf-capture.c | 63 +++++++++++--------
1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/staging/media/starfive/camss/stf-capture.c
index 70c24b050a1b..367bdc924fb7 100644
--- a/drivers/staging/media/starfive/camss/stf-capture.c
+++ b/drivers/staging/media/starfive/camss/stf-capture.c
@@ -368,7 +368,7 @@ static void stf_buf_flush(struct stf_v_buf *output, enum vb2_buffer_state state)
}
}

-static void stf_buf_done(struct stf_v_buf *output)
+static struct stfcamss_buffer *stf_buf_done(struct stf_v_buf *output)
{
struct stfcamss_buffer *ready_buf;
u64 ts = ktime_get_ns();
@@ -376,27 +376,27 @@ static void stf_buf_done(struct stf_v_buf *output)

if (output->state == STF_OUTPUT_OFF ||
output->state == STF_OUTPUT_RESERVED)
- return;
+ return NULL;

spin_lock_irqsave(&output->lock, flags);

- while ((ready_buf = stf_buf_get_ready(output))) {
+ ready_buf = stf_buf_get_ready(output);
+ if (ready_buf) {
ready_buf->vb.vb2_buf.timestamp = ts;
ready_buf->vb.sequence = output->sequence++;
-
- vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}

spin_unlock_irqrestore(&output->lock, flags);
+
+ return ready_buf;
}

-static void stf_change_buffer(struct stf_v_buf *output)
+static struct stfcamss_buffer *stf_change_buffer(struct stf_v_buf *output)
{
struct stf_capture *cap = container_of(output, struct stf_capture,
buffers);
struct stfcamss *stfcamss = cap->video.stfcamss;
struct stfcamss_buffer *ready_buf;
- dma_addr_t *new_addr;
unsigned long flags;
u32 active_index;

@@ -404,7 +404,7 @@ static void stf_change_buffer(struct stf_v_buf *output)
output->state == STF_OUTPUT_STOPPING ||
output->state == STF_OUTPUT_RESERVED ||
output->state == STF_OUTPUT_IDLE)
- return;
+ return NULL;

spin_lock_irqsave(&output->lock, flags);

@@ -426,37 +426,37 @@ static void stf_change_buffer(struct stf_v_buf *output)

/* Get next buffer */
output->buf[active_index] = stf_buf_get_pending(output);
- if (!output->buf[active_index]) {
- new_addr = ready_buf->addr;
+ if (!output->buf[active_index])
stf_buf_update_on_last(output);
- } else {
- new_addr = output->buf[active_index]->addr;
+ else
stf_buf_update_on_next(output);
- }

- if (output->state == STF_OUTPUT_STOPPING) {
+ if (output->state == STF_OUTPUT_STOPPING)
output->last_buffer = ready_buf;
- } else {
- if (cap->type == STF_CAPTURE_RAW)
- stf_set_raw_addr(stfcamss, new_addr[0]);
- else if (cap->type == STF_CAPTURE_YUV)
- stf_set_yuv_addr(stfcamss, new_addr[0], new_addr[1]);
-
+ else
stf_buf_add_ready(output, ready_buf);
- }

out_unlock:
spin_unlock_irqrestore(&output->lock, flags);
+
+ return output->buf[active_index];
}

irqreturn_t stf_wr_irq_handler(int irq, void *priv)
{
struct stfcamss *stfcamss = priv;
struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_RAW];
+ struct stfcamss_buffer *change_buf;
+ struct stfcamss_buffer *ready_buf;

if (atomic_dec_if_positive(&cap->buffers.frame_skip) < 0) {
- stf_change_buffer(&cap->buffers);
- stf_buf_done(&cap->buffers);
+ change_buf = stf_change_buffer(&cap->buffers);
+ if (change_buf)
+ stf_set_raw_addr(stfcamss, change_buf->addr[0]);
+
+ ready_buf = stf_buf_done(&cap->buffers);
+ if (ready_buf)
+ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}

stf_syscon_reg_set_bit(stfcamss, VIN_INRT_PIX_CFG, U0_VIN_INTR_CLEAN);
@@ -469,12 +469,16 @@ irqreturn_t stf_isp_irq_handler(int irq, void *priv)
{
struct stfcamss *stfcamss = priv;
struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
+ struct stfcamss_buffer *ready_buf;
u32 status;

status = stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0);
if (status & ISPC_ISP) {
- if (status & ISPC_ENUO)
- stf_buf_done(&cap->buffers);
+ if (status & ISPC_ENUO) {
+ ready_buf = stf_buf_done(&cap->buffers);
+ if (ready_buf)
+ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+ }

stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0,
(status & ~ISPC_INT_ALL_MASK) |
@@ -488,13 +492,18 @@ irqreturn_t stf_line_irq_handler(int irq, void *priv)
{
struct stfcamss *stfcamss = priv;
struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
+ struct stfcamss_buffer *change_buf;
u32 status;

status = stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0);
if (status & ISPC_LINE) {
if (atomic_dec_if_positive(&cap->buffers.frame_skip) < 0) {
- if ((status & ISPC_ENUO))
- stf_change_buffer(&cap->buffers);
+ if ((status & ISPC_ENUO)) {
+ change_buf = stf_change_buffer(&cap->buffers);
+ if (change_buf)
+ stf_set_yuv_addr(stfcamss, change_buf->addr[0],
+ change_buf->addr[1]);
+ }
}

stf_isp_reg_set_bit(stfcamss, ISP_REG_CSIINTS,
--
2.25.1


2024-01-11 09:01:43

by Changhuang Liang

[permalink] [raw]
Subject: [PATCH v2 04/13] staging: media: starfive: Add a params sink pad and a scd source pad for ISP

StarFive ISP can use params sink pad to transmit ISP parameters and use
scd source pad to capture statistics collection data.

Signed-off-by: Changhuang Liang <[email protected]>
---
.../staging/media/starfive/camss/stf-isp.c | 87 +++++++++++++++----
.../staging/media/starfive/camss/stf-isp.h | 2 +
2 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/media/starfive/camss/stf-isp.c b/drivers/staging/media/starfive/camss/stf-isp.c
index d50616ef351e..0ebffd09842a 100644
--- a/drivers/staging/media/starfive/camss/stf-isp.c
+++ b/drivers/staging/media/starfive/camss/stf-isp.c
@@ -10,9 +10,6 @@

#include "stf-camss.h"

-#define SINK_FORMATS_INDEX 0
-#define SOURCE_FORMATS_INDEX 1
-
static int isp_set_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel);
@@ -24,13 +21,23 @@ static const struct stf_isp_format isp_formats_sink[] = {
{ MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
};

+static const struct stf_isp_format isp_formats_sink_params[] = {
+ { MEDIA_BUS_FMT_METADATA_FIXED },
+};
+
static const struct stf_isp_format isp_formats_source[] = {
{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8 },
};

+static const struct stf_isp_format isp_formats_source_scd[] = {
+ { MEDIA_BUS_FMT_METADATA_FIXED },
+};
+
static const struct stf_isp_format_table isp_formats_st7110[] = {
{ isp_formats_sink, ARRAY_SIZE(isp_formats_sink) },
+ { isp_formats_sink_params, ARRAY_SIZE(isp_formats_sink_params) },
{ isp_formats_source, ARRAY_SIZE(isp_formats_source) },
+ { isp_formats_source_scd, ARRAY_SIZE(isp_formats_source_scd) },
};

static const struct stf_isp_format *
@@ -94,18 +101,21 @@ static void isp_try_format(struct stf_isp_dev *isp_dev,
return;
}

- if (pad == STF_ISP_PAD_SINK)
- formats = &isp_dev->formats[SINK_FORMATS_INDEX];
- else if (pad == STF_ISP_PAD_SRC)
- formats = &isp_dev->formats[SOURCE_FORMATS_INDEX];
+ formats = &isp_dev->formats[pad];
+
+ if (pad != STF_ISP_PAD_SRC_SCD && pad != STF_ISP_PAD_SINK_PARAMS) {
+ fmt->width = clamp_t(u32, fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
+ STFCAMSS_FRAME_MAX_WIDTH);
+ fmt->height = clamp_t(u32, fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
+ STFCAMSS_FRAME_MAX_HEIGHT);
+ fmt->height &= ~0x1;
+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
+ } else {
+ fmt->width = 1;
+ fmt->height = 1;
+ }

- fmt->width = clamp_t(u32, fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
- STFCAMSS_FRAME_MAX_WIDTH);
- fmt->height = clamp_t(u32, fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
- STFCAMSS_FRAME_MAX_HEIGHT);
- fmt->height &= ~0x1;
fmt->field = V4L2_FIELD_NONE;
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
fmt->flags = 0;

if (!stf_g_fmt_by_mcode(formats, fmt->code))
@@ -123,9 +133,9 @@ static int isp_enum_mbus_code(struct v4l2_subdev *sd,
if (code->index >= ARRAY_SIZE(isp_formats_sink))
return -EINVAL;

- formats = &isp_dev->formats[SINK_FORMATS_INDEX];
+ formats = &isp_dev->formats[code->pad];
code->code = formats->fmts[code->index].code;
- } else {
+ } else if (code->pad == STF_ISP_PAD_SRC) {
struct v4l2_mbus_framefmt *sink_fmt;

if (code->index >= ARRAY_SIZE(isp_formats_source))
@@ -137,6 +147,10 @@ static int isp_enum_mbus_code(struct v4l2_subdev *sd,
code->code = sink_fmt->code;
if (!code->code)
return -EINVAL;
+ } else {
+ if (code->index > 0)
+ return -EINVAL;
+ code->code = MEDIA_BUS_FMT_METADATA_FIXED;
}
code->flags = 0;

@@ -157,6 +171,9 @@ static int isp_set_format(struct v4l2_subdev *sd,
isp_try_format(isp_dev, state, fmt->pad, &fmt->format);
*format = fmt->format;

+ if (fmt->pad == STF_ISP_PAD_SRC_SCD || fmt->pad == STF_ISP_PAD_SINK_PARAMS)
+ return 0;
+
isp_dev->current_fmt = stf_g_fmt_by_mcode(&isp_dev->formats[fmt->pad],
fmt->format.code);

@@ -208,6 +225,9 @@ static int isp_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_format fmt = { 0 };
struct v4l2_rect *rect;

+ if (sel->pad == STF_ISP_PAD_SRC_SCD || sel->pad == STF_ISP_PAD_SINK_PARAMS)
+ return -EINVAL;
+
switch (sel->target) {
case V4L2_SEL_TGT_CROP_BOUNDS:
if (sel->pad == STF_ISP_PAD_SINK) {
@@ -245,6 +265,9 @@ static int isp_set_selection(struct v4l2_subdev *sd,
struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
struct v4l2_rect *rect;

+ if (sel->pad == STF_ISP_PAD_SRC_SCD || sel->pad == STF_ISP_PAD_SINK_PARAMS)
+ return -EINVAL;
+
if (sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;

@@ -302,8 +325,38 @@ static int isp_init_formats(struct v4l2_subdev *sd,
.height = 1080
}
};
+ struct v4l2_subdev_format format_params = {
+ .pad = STF_ISP_PAD_SINK_PARAMS,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .format = {
+ .code = MEDIA_BUS_FMT_METADATA_FIXED,
+ .width = 1,
+ .height = 1
+ }
+ };
+ struct v4l2_subdev_format format_scd = {
+ .pad = STF_ISP_PAD_SRC_SCD,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .format = {
+ .code = MEDIA_BUS_FMT_METADATA_FIXED,
+ .width = 1,
+ .height = 1
+ }
+ };
+ int ret;
+
+ /* Init for STF_ISP_PAD_SINK and STF_ISP_PAD_SRC pad */
+ ret = isp_set_format(sd, sd_state, &format);
+ if (ret < 0)
+ return ret;
+
+ /* Init for STF_ISP_PAD_SINK_PARAMS pad */
+ ret = isp_set_format(sd, sd_state, &format_params);
+ if (ret < 0)
+ return ret;

- return isp_set_format(sd, sd_state, &format);
+ /* Init for STF_ISP_PAD_SRC_SCD pad */
+ return isp_set_format(sd, sd_state, &format_scd);
}

static const struct v4l2_subdev_video_ops isp_video_ops = {
@@ -344,7 +397,9 @@ int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2_dev)
v4l2_set_subdevdata(sd, isp_dev);

pads[STF_ISP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ pads[STF_ISP_PAD_SINK_PARAMS].flags = MEDIA_PAD_FL_SINK;
pads[STF_ISP_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
+ pads[STF_ISP_PAD_SRC_SCD].flags = MEDIA_PAD_FL_SOURCE;

sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_ISP;
sd->entity.ops = &isp_media_ops;
diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/staging/media/starfive/camss/stf-isp.h
index 955cbb048363..bc7e7b0736fa 100644
--- a/drivers/staging/media/starfive/camss/stf-isp.h
+++ b/drivers/staging/media/starfive/camss/stf-isp.h
@@ -392,7 +392,9 @@
/* pad id for media framework */
enum stf_isp_pad_id {
STF_ISP_PAD_SINK = 0,
+ STF_ISP_PAD_SINK_PARAMS,
STF_ISP_PAD_SRC,
+ STF_ISP_PAD_SRC_SCD,
STF_ISP_PAD_MAX
};

--
2.25.1


2024-01-11 09:02:43

by Changhuang Liang

[permalink] [raw]
Subject: [PATCH v2 11/13] staging: media: starfive: Add ISP params video device

Add ISP params video device to write ISP parameters for 3A.

Signed-off-by: Changhuang Liang <[email protected]>
---
drivers/staging/media/starfive/camss/Makefile | 2 +
.../staging/media/starfive/camss/stf-camss.c | 19 +-
.../staging/media/starfive/camss/stf-camss.h | 3 +
.../media/starfive/camss/stf-isp-params.c | 238 ++++++++++++++++++
.../staging/media/starfive/camss/stf-isp.h | 4 +
.../staging/media/starfive/camss/stf-output.c | 83 ++++++
.../staging/media/starfive/camss/stf-output.h | 22 ++
7 files changed, 370 insertions(+), 1 deletion(-)
create mode 100644 drivers/staging/media/starfive/camss/stf-isp-params.c
create mode 100644 drivers/staging/media/starfive/camss/stf-output.c
create mode 100644 drivers/staging/media/starfive/camss/stf-output.h

diff --git a/drivers/staging/media/starfive/camss/Makefile b/drivers/staging/media/starfive/camss/Makefile
index 411b45f3fb52..077165cbba7a 100644
--- a/drivers/staging/media/starfive/camss/Makefile
+++ b/drivers/staging/media/starfive/camss/Makefile
@@ -9,6 +9,8 @@ starfive-camss-objs += \
stf-capture.o \
stf-isp.o \
stf-isp-hw-ops.o \
+ stf-isp-params.o \
+ stf-output.o \
stf-video.o

obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o
diff --git a/drivers/staging/media/starfive/camss/stf-camss.c b/drivers/staging/media/starfive/camss/stf-camss.c
index 3175d0d9a05c..51357f905a42 100644
--- a/drivers/staging/media/starfive/camss/stf-camss.c
+++ b/drivers/staging/media/starfive/camss/stf-camss.c
@@ -127,6 +127,7 @@ static int stfcamss_register_devs(struct stfcamss *stfcamss)
{
struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
struct stf_capture *cap_scd = &stfcamss->captures[STF_CAPTURE_SCD];
+ struct stf_output *output = &stfcamss->output;
struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
int ret;

@@ -137,13 +138,26 @@ static int stfcamss_register_devs(struct stfcamss *stfcamss)
return ret;
}

- ret = stf_capture_register(stfcamss, &stfcamss->v4l2_dev);
+ ret = stf_output_register(stfcamss, &stfcamss->v4l2_dev);
if (ret < 0) {
dev_err(stfcamss->dev,
"failed to register capture: %d\n", ret);
goto err_isp_unregister;
}

+ ret = stf_capture_register(stfcamss, &stfcamss->v4l2_dev);
+ if (ret < 0) {
+ dev_err(stfcamss->dev,
+ "failed to register capture: %d\n", ret);
+ goto err_out_unregister;
+ }
+
+ ret = media_create_pad_link(&output->video.vdev.entity, 0,
+ &isp_dev->subdev.entity, STF_ISP_PAD_SINK_PARAMS,
+ 0);
+ if (ret)
+ goto err_cap_unregister;
+
ret = media_create_pad_link(&isp_dev->subdev.entity, STF_ISP_PAD_SRC,
&cap_yuv->video.vdev.entity, 0, 0);
if (ret)
@@ -162,6 +176,8 @@ static int stfcamss_register_devs(struct stfcamss *stfcamss)

err_cap_unregister:
stf_capture_unregister(stfcamss);
+err_out_unregister:
+ stf_output_unregister(stfcamss);
err_isp_unregister:
stf_isp_unregister(&stfcamss->isp_dev);

@@ -172,6 +188,7 @@ static void stfcamss_unregister_devs(struct stfcamss *stfcamss)
{
stf_isp_unregister(&stfcamss->isp_dev);
stf_capture_unregister(stfcamss);
+ stf_output_unregister(stfcamss);
}

static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
diff --git a/drivers/staging/media/starfive/camss/stf-camss.h b/drivers/staging/media/starfive/camss/stf-camss.h
index ae49c7031ab7..3f84f1a1e997 100644
--- a/drivers/staging/media/starfive/camss/stf-camss.h
+++ b/drivers/staging/media/starfive/camss/stf-camss.h
@@ -21,6 +21,7 @@
#include "stf-buffer.h"
#include "stf-isp.h"
#include "stf-capture.h"
+#include "stf-output.h"

enum stf_port_num {
STF_PORT_DVP = 0,
@@ -55,6 +56,7 @@ struct stfcamss {
struct device *dev;
struct stf_isp_dev isp_dev;
struct stf_capture captures[STF_CAPTURE_NUM];
+ struct stf_output output;
struct v4l2_async_notifier notifier;
void __iomem *syscon_base;
void __iomem *isp_base;
@@ -132,4 +134,5 @@ static inline void stf_syscon_reg_clear_bit(struct stfcamss *stfcamss,
value = ioread32(stfcamss->syscon_base + reg);
iowrite32(value & ~bit_mask, stfcamss->syscon_base + reg);
}
+
#endif /* STF_CAMSS_H */
diff --git a/drivers/staging/media/starfive/camss/stf-isp-params.c b/drivers/staging/media/starfive/camss/stf-isp-params.c
new file mode 100644
index 000000000000..dbf50f31709e
--- /dev/null
+++ b/drivers/staging/media/starfive/camss/stf-isp-params.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * stf-isp-params.c
+ *
+ * StarFive Camera Subsystem - V4L2 device node
+ *
+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
+ */
+
+#include <media/videobuf2-dma-contig.h>
+
+#include "stf-camss.h"
+#include "stf-video.h"
+
+static inline struct stfcamss_buffer *
+to_stfcamss_buffer(struct vb2_v4l2_buffer *vbuf)
+{
+ return container_of(vbuf, struct stfcamss_buffer, vb);
+}
+
+static int stf_isp_params_queue_setup(struct vb2_queue *q,
+ unsigned int *num_buffers,
+ unsigned int *num_planes,
+ unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ *num_planes = 1;
+ sizes[0] = sizeof(struct jh7110_isp_params_buffer);
+
+ return 0;
+}
+
+static int stf_isp_params_buf_init(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct stfcamss_buffer *buffer = to_stfcamss_buffer(vbuf);
+ dma_addr_t *paddr;
+
+ paddr = vb2_plane_cookie(vb, 0);
+ buffer->addr[0] = *paddr;
+ buffer->vaddr = vb2_plane_vaddr(vb, 0);
+
+ return 0;
+}
+
+static int stf_isp_params_buf_prepare(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+ if (sizeof(struct jh7110_isp_params_buffer) > vb2_plane_size(vb, 0))
+ return -EINVAL;
+
+ vb2_set_plane_payload(vb, 0, sizeof(struct jh7110_isp_params_buffer));
+
+ vbuf->field = V4L2_FIELD_NONE;
+
+ return 0;
+}
+
+static void stf_isp_params_buf_queue(struct vb2_buffer *vb)
+{
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
+ struct stfcamss_buffer *buffer = to_stfcamss_buffer(vbuf);
+
+ video->ops->queue_buffer(video, buffer);
+}
+
+static void stf_isp_params_stop_streaming(struct vb2_queue *q)
+{
+ struct stfcamss_video *video = vb2_get_drv_priv(q);
+
+ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
+}
+
+static const struct vb2_ops stf_isp_params_vb2_q_ops = {
+ .queue_setup = stf_isp_params_queue_setup,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .buf_init = stf_isp_params_buf_init,
+ .buf_prepare = stf_isp_params_buf_prepare,
+ .buf_queue = stf_isp_params_buf_queue,
+ .stop_streaming = stf_isp_params_stop_streaming,
+};
+
+static int stf_isp_params_init_format(struct stfcamss_video *video)
+{
+ video->active_fmt.fmt.meta.dataformat = V4L2_META_FMT_STF_ISP_PARAMS;
+ video->active_fmt.fmt.meta.buffersize = sizeof(struct jh7110_isp_params_buffer);
+
+ return 0;
+}
+
+static int stf_isp_params_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ strscpy(cap->driver, "starfive-camss", sizeof(cap->driver));
+ strscpy(cap->card, "Starfive Camera Subsystem", sizeof(cap->card));
+
+ return 0;
+}
+
+static int stf_isp_params_enum_fmt(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct stfcamss_video *video = video_drvdata(file);
+
+ if (f->index > 0 || f->type != video->type)
+ return -EINVAL;
+
+ f->pixelformat = video->active_fmt.fmt.meta.dataformat;
+ return 0;
+}
+
+static int stf_isp_params_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct stfcamss_video *video = video_drvdata(file);
+ struct v4l2_meta_format *meta = &f->fmt.meta;
+
+ if (f->type != video->type)
+ return -EINVAL;
+
+ meta->dataformat = video->active_fmt.fmt.meta.dataformat;
+ meta->buffersize = video->active_fmt.fmt.meta.buffersize;
+
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops stf_isp_params_ioctl_ops = {
+ .vidioc_querycap = stf_isp_params_querycap,
+ .vidioc_enum_fmt_meta_out = stf_isp_params_enum_fmt,
+ .vidioc_g_fmt_meta_out = stf_isp_params_g_fmt,
+ .vidioc_s_fmt_meta_out = stf_isp_params_g_fmt,
+ .vidioc_try_fmt_meta_out = stf_isp_params_g_fmt,
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+};
+
+static const struct v4l2_file_operations stf_isp_params_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = video_ioctl2,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .mmap = vb2_fop_mmap,
+ .read = vb2_fop_read,
+};
+
+static void stf_isp_params_release(struct video_device *vdev)
+{
+ struct stfcamss_video *video = video_get_drvdata(vdev);
+
+ media_entity_cleanup(&vdev->entity);
+
+ mutex_destroy(&video->q_lock);
+ mutex_destroy(&video->lock);
+}
+
+int stf_isp_params_register(struct stfcamss_video *video,
+ struct v4l2_device *v4l2_dev,
+ const char *name)
+{
+ struct video_device *vdev = &video->vdev;
+ struct vb2_queue *q;
+ struct media_pad *pad = &video->pad;
+ int ret;
+
+ mutex_init(&video->q_lock);
+ mutex_init(&video->lock);
+
+ q = &video->vb2_q;
+ q->drv_priv = video;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->ops = &stf_isp_params_vb2_q_ops;
+ q->type = video->type;
+ q->io_modes = VB2_DMABUF | VB2_MMAP;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->buf_struct_size = sizeof(struct stfcamss_buffer);
+ q->dev = video->stfcamss->dev;
+ q->lock = &video->q_lock;
+ q->min_queued_buffers = STFCAMSS_MIN_BUFFERS;
+ ret = vb2_queue_init(q);
+ if (ret < 0) {
+ dev_err(video->stfcamss->dev,
+ "Failed to init vb2 queue: %d\n", ret);
+ goto err_mutex_destroy;
+ }
+
+ pad->flags = MEDIA_PAD_FL_SOURCE;
+ ret = media_entity_pads_init(&vdev->entity, 1, pad);
+ if (ret < 0) {
+ dev_err(video->stfcamss->dev,
+ "Failed to init video entity: %d\n", ret);
+ goto err_mutex_destroy;
+ }
+
+ ret = stf_isp_params_init_format(video);
+ if (ret < 0) {
+ dev_err(video->stfcamss->dev,
+ "Failed to init format: %d\n", ret);
+ goto err_media_cleanup;
+ }
+ vdev->ioctl_ops = &stf_isp_params_ioctl_ops;
+ vdev->device_caps = V4L2_CAP_META_OUTPUT;
+ vdev->fops = &stf_isp_params_fops;
+ vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
+ vdev->vfl_dir = VFL_DIR_TX;
+ vdev->release = stf_isp_params_release;
+ vdev->v4l2_dev = v4l2_dev;
+ vdev->queue = &video->vb2_q;
+ vdev->lock = &video->lock;
+ strscpy(vdev->name, name, sizeof(vdev->name));
+
+ video_set_drvdata(vdev, video);
+
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret < 0) {
+ dev_err(video->stfcamss->dev,
+ "Failed to register video device: %d\n", ret);
+ goto err_media_cleanup;
+ }
+
+ return 0;
+
+err_media_cleanup:
+ media_entity_cleanup(&vdev->entity);
+err_mutex_destroy:
+ mutex_destroy(&video->lock);
+ mutex_destroy(&video->q_lock);
+ return ret;
+}
diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/staging/media/starfive/camss/stf-isp.h
index eca3ba1ade75..76ea943bfe98 100644
--- a/drivers/staging/media/starfive/camss/stf-isp.h
+++ b/drivers/staging/media/starfive/camss/stf-isp.h
@@ -474,4 +474,8 @@ void stf_set_scd_addr(struct stfcamss *stfcamss,
dma_addr_t yhist_addr, dma_addr_t scd_addr,
enum stf_isp_type_scd type_scd);

+int stf_isp_params_register(struct stfcamss_video *video,
+ struct v4l2_device *v4l2_dev,
+ const char *name);
+
#endif /* STF_ISP_H */
diff --git a/drivers/staging/media/starfive/camss/stf-output.c b/drivers/staging/media/starfive/camss/stf-output.c
new file mode 100644
index 000000000000..8eaf4979cafa
--- /dev/null
+++ b/drivers/staging/media/starfive/camss/stf-output.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * StarFive Camera Subsystem - output device
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ */
+
+#include "stf-camss.h"
+
+static inline struct stf_output *to_stf_output(struct stfcamss_video *video)
+{
+ return container_of(video, struct stf_output, video);
+}
+
+static int stf_output_queue_buffer(struct stfcamss_video *video,
+ struct stfcamss_buffer *buf)
+{
+ struct stf_output *output = to_stf_output(video);
+ struct stf_v_buf *v_bufs = &output->buffers;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v_bufs->lock, flags);
+ stf_buf_add_ready(v_bufs, buf);
+ spin_unlock_irqrestore(&v_bufs->lock, flags);
+
+ return 0;
+}
+
+static int stf_output_flush_buffers(struct stfcamss_video *video,
+ enum vb2_buffer_state state)
+{
+ struct stf_output *output = to_stf_output(video);
+ struct stf_v_buf *v_bufs = &output->buffers;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v_bufs->lock, flags);
+ stf_buf_flush(v_bufs, state);
+ spin_unlock_irqrestore(&v_bufs->lock, flags);
+
+ return 0;
+}
+
+static const struct stfcamss_video_ops stf_output_ops = {
+ .queue_buffer = stf_output_queue_buffer,
+ .flush_buffers = stf_output_flush_buffers,
+};
+
+static void stf_output_init(struct stfcamss *stfcamss, struct stf_output *out)
+{
+ out->buffers.state = STF_OUTPUT_OFF;
+ out->buffers.buf[0] = NULL;
+ out->buffers.buf[1] = NULL;
+ out->buffers.active_buf = 0;
+ INIT_LIST_HEAD(&out->buffers.pending_bufs);
+ INIT_LIST_HEAD(&out->buffers.ready_bufs);
+ spin_lock_init(&out->buffers.lock);
+
+ out->video.stfcamss = stfcamss;
+ out->video.type = V4L2_BUF_TYPE_META_OUTPUT;
+}
+
+void stf_output_unregister(struct stfcamss *stfcamss)
+{
+ struct stf_output *output = &stfcamss->output;
+
+ if (!video_is_registered(&output->video.vdev))
+ return;
+
+ media_entity_cleanup(&output->video.vdev.entity);
+ vb2_video_unregister_device(&output->video.vdev);
+}
+
+int stf_output_register(struct stfcamss *stfcamss,
+ struct v4l2_device *v4l2_dev)
+{
+ struct stf_output *output = &stfcamss->output;
+
+ output->video.ops = &stf_output_ops;
+ stf_output_init(stfcamss, output);
+ stf_isp_params_register(&output->video, v4l2_dev, "output_params");
+
+ return 0;
+}
diff --git a/drivers/staging/media/starfive/camss/stf-output.h b/drivers/staging/media/starfive/camss/stf-output.h
new file mode 100644
index 000000000000..d3591a0b609b
--- /dev/null
+++ b/drivers/staging/media/starfive/camss/stf-output.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Starfive Camera Subsystem driver
+ *
+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
+ */
+
+#ifndef STF_OUTPUT_H
+#define STF_OUTPUT_H
+
+#include "stf-video.h"
+
+struct stf_output {
+ struct stfcamss_video video;
+ struct stf_v_buf buffers;
+};
+
+int stf_output_register(struct stfcamss *stfcamss,
+ struct v4l2_device *v4l2_dev);
+void stf_output_unregister(struct stfcamss *stfcamss);
+
+#endif
--
2.25.1


2024-01-11 09:03:06

by Changhuang Liang

[permalink] [raw]
Subject: [PATCH v2 09/13] staging: media: starfive: Update ISP initialise config for 3A

Upadte ISP initialise for 3A statistics collection data.

Signed-off-by: Changhuang Liang <[email protected]>
---
.../media/starfive/camss/stf-isp-hw-ops.c | 23 +++++++++++++++++++
.../staging/media/starfive/camss/stf-isp.h | 21 +++++++++++++++++
2 files changed, 44 insertions(+)

diff --git a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
index ae88668e5798..c778251e0024 100644
--- a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
+++ b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
@@ -300,6 +300,25 @@ static void stf_isp_config_sat(struct stfcamss *stfcamss)
stf_isp_reg_write(stfcamss, ISP_REG_YADJ1, YOMAX(0x3ff) | YOMIN(0x1));
}

+static void stf_isp_config_sc(struct stfcamss *stfcamss)
+{
+ stf_isp_reg_write(stfcamss, ISP_REG_SCD_CFG_1, AXI_ID(0));
+ stf_isp_reg_write(stfcamss, ISP_REG_SC_CFG_0, HSTART(0) | VSTART(0xc));
+ stf_isp_reg_write(stfcamss, ISP_REG_SC_CFG_1,
+ SC_WIDTH(0x1d) | SC_HEIGHT(0x15) |
+ AWB_PS_GRB_BA(0x10) | SEL_TYPE(0x3));
+}
+
+static void stf_isp_config_yhist(struct stfcamss *stfcamss)
+{
+ stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_0, 0);
+ stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_1,
+ YH_WIDTH(0x77f) | YH_HEIGHT(0x437));
+ stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_2,
+ YH_DEC_ETW(2) | YH_DEC_ETH(1));
+ stf_isp_reg_write(stfcamss, ISP_REG_YHIST_CFG_3, 0);
+}
+
int stf_isp_reset(struct stf_isp_dev *isp_dev)
{
stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_ISP_CTRL_0,
@@ -332,7 +351,11 @@ void stf_isp_init_cfg(struct stf_isp_dev *isp_dev)
stf_isp_config_sharpen(isp_dev->stfcamss);
stf_isp_config_dnyuv(isp_dev->stfcamss);
stf_isp_config_sat(isp_dev->stfcamss);
+ stf_isp_config_sc(isp_dev->stfcamss);
+ stf_isp_config_yhist(isp_dev->stfcamss);

+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_DUMP_CFG_1,
+ DUMP_BURST_LEN(3) | DUMP_SD(0xb80));
stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_CSI_MODULE_CFG,
CSI_DUMP_EN | CSI_SC_EN | CSI_AWB_EN |
CSI_LCCF_EN | CSI_OECF_EN | CSI_OBC_EN | CSI_DEC_EN);
diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/staging/media/starfive/camss/stf-isp.h
index 0af7b367e57a..eca3ba1ade75 100644
--- a/drivers/staging/media/starfive/camss/stf-isp.h
+++ b/drivers/staging/media/starfive/camss/stf-isp.h
@@ -110,9 +110,19 @@

#define ISP_REG_SCD_CFG_0 0x098

+#define ISP_REG_SCD_CFG_1 0x09c
+#define AXI_ID(n) ((n) << 24)
+
+#define ISP_REG_SC_CFG_0 0x0b8
+#define VSTART(n) ((n) << 16)
+#define HSTART(n) ((n) << 0)
+
#define ISP_REG_SC_CFG_1 0x0bc
#define ISP_SC_SEL_MASK GENMASK(31, 30)
#define SEL_TYPE(n) ((n) << 30)
+#define AWB_PS_GRB_BA(n) ((n) << 16)
+#define SC_HEIGHT(n) ((n) << 8)
+#define SC_WIDTH(n) ((n) << 0)

#define ISP_REG_LCCF_CFG_2 0x0e0
#define ISP_REG_LCCF_CFG_3 0x0e4
@@ -312,6 +322,17 @@
#define DNRM_F(n) ((n) << 16)
#define CCM_M_DAT(n) ((n) << 0)

+#define ISP_REG_YHIST_CFG_0 0xcc8
+
+#define ISP_REG_YHIST_CFG_1 0xccc
+#define YH_HEIGHT(n) ((n) << 16)
+#define YH_WIDTH(n) ((n) << 0)
+
+#define ISP_REG_YHIST_CFG_2 0xcd0
+#define YH_DEC_ETH(n) ((n) << 16)
+#define YH_DEC_ETW(n) ((n) << 0)
+
+#define ISP_REG_YHIST_CFG_3 0xcd4
#define ISP_REG_YHIST_CFG_4 0xcd8

#define ISP_REG_YHIST_ACC_0 0xd00
--
2.25.1


2024-01-11 09:03:16

by Changhuang Liang

[permalink] [raw]
Subject: [PATCH v2 10/13] staging: media: starfive: Add V4L2_CAP_IO_MC capability

Add V4L2_CAP_IO_MC capabality for video device. User space can enumerate
formats by mbus code.

Signed-off-by: Changhuang Liang <[email protected]>
---
drivers/staging/media/starfive/camss/stf-video.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/media/starfive/camss/stf-video.c b/drivers/staging/media/starfive/camss/stf-video.c
index d9e51d4e2004..4ca889a7b757 100644
--- a/drivers/staging/media/starfive/camss/stf-video.c
+++ b/drivers/staging/media/starfive/camss/stf-video.c
@@ -665,7 +665,7 @@ int stf_video_register(struct stfcamss_video *video,
}

vdev->fops = &stf_vid_fops;
- vdev->device_caps |= V4L2_CAP_STREAMING;
+ vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
vdev->entity.ops = &stf_media_ops;
vdev->vfl_dir = VFL_DIR_RX;
vdev->release = stf_video_release;
--
2.25.1


2024-01-11 09:05:53

by Changhuang Liang

[permalink] [raw]
Subject: [PATCH v2 07/13] staging: media: starfive: Separate ISP hardware from capture device

Some ISP hardware operations also use for output device, so separate it
from capture device, move them to ISP common file.

Signed-off-by: Changhuang Liang <[email protected]>
---
.../media/starfive/camss/stf-capture.c | 60 -------------------
.../media/starfive/camss/stf-isp-hw-ops.c | 60 +++++++++++++++++++
.../staging/media/starfive/camss/stf-isp.h | 3 +
3 files changed, 63 insertions(+), 60 deletions(-)

diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/staging/media/starfive/camss/stf-capture.c
index 5cbafac46ee6..e91e726a1462 100644
--- a/drivers/staging/media/starfive/camss/stf-capture.c
+++ b/drivers/staging/media/starfive/camss/stf-capture.c
@@ -66,13 +66,6 @@ static void stf_set_raw_addr(struct stfcamss *stfcamss, dma_addr_t addr)
stf_syscon_reg_write(stfcamss, VIN_START_ADDR_N, (long)addr);
}

-static void stf_set_yuv_addr(struct stfcamss *stfcamss,
- dma_addr_t y_addr, dma_addr_t uv_addr)
-{
- stf_isp_reg_write(stfcamss, ISP_REG_Y_PLANE_START_ADDR, y_addr);
- stf_isp_reg_write(stfcamss, ISP_REG_UV_PLANE_START_ADDR, uv_addr);
-}
-
static void stf_init_addrs(struct stfcamss_video *video)
{
struct stf_capture *cap = to_stf_capture(video);
@@ -307,59 +300,6 @@ irqreturn_t stf_wr_irq_handler(int irq, void *priv)
return IRQ_HANDLED;
}

-irqreturn_t stf_isp_irq_handler(int irq, void *priv)
-{
- struct stfcamss *stfcamss = priv;
- struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
- struct stfcamss_buffer *ready_buf;
- u32 status;
-
- status = stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0);
- if (status & ISPC_ISP) {
- if (status & ISPC_ENUO) {
- ready_buf = stf_buf_done(&cap->buffers);
- if (ready_buf)
- vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
- }
-
- stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0,
- (status & ~ISPC_INT_ALL_MASK) |
- ISPC_ISP | ISPC_CSI | ISPC_SC);
- }
-
- return IRQ_HANDLED;
-}
-
-irqreturn_t stf_line_irq_handler(int irq, void *priv)
-{
- struct stfcamss *stfcamss = priv;
- struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
- struct stfcamss_buffer *change_buf;
- u32 status;
-
- status = stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0);
- if (status & ISPC_LINE) {
- if (atomic_dec_if_positive(&cap->buffers.frame_skip) < 0) {
- if ((status & ISPC_ENUO)) {
- change_buf = stf_change_buffer(&cap->buffers);
- if (change_buf)
- stf_set_yuv_addr(stfcamss, change_buf->addr[0],
- change_buf->addr[1]);
- }
- }
-
- stf_isp_reg_set_bit(stfcamss, ISP_REG_CSIINTS,
- CSI_INTS_MASK, CSI_INTS(0x3));
- stf_isp_reg_set_bit(stfcamss, ISP_REG_IESHD,
- SHAD_UP_M | SHAD_UP_EN, 0x3);
-
- stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0,
- (status & ~ISPC_INT_ALL_MASK) | ISPC_LINE);
- }
-
- return IRQ_HANDLED;
-}
-
static int stf_queue_buffer(struct stfcamss_video *video,
struct stfcamss_buffer *buf)
{
diff --git a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
index c34631ff9422..6b3966ca18bf 100644
--- a/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
+++ b/drivers/staging/media/starfive/camss/stf-isp-hw-ops.c
@@ -443,3 +443,63 @@ void stf_isp_stream_set(struct stf_isp_dev *isp_dev)
stf_isp_reg_write_delay(stfcamss, ISP_REG_CSI_INPUT_EN_AND_STATUS,
CSI_EN_S, 10);
}
+
+void stf_set_yuv_addr(struct stfcamss *stfcamss,
+ dma_addr_t y_addr, dma_addr_t uv_addr)
+{
+ stf_isp_reg_write(stfcamss, ISP_REG_Y_PLANE_START_ADDR, y_addr);
+ stf_isp_reg_write(stfcamss, ISP_REG_UV_PLANE_START_ADDR, uv_addr);
+}
+
+irqreturn_t stf_line_irq_handler(int irq, void *priv)
+{
+ struct stfcamss *stfcamss = priv;
+ struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
+ struct stfcamss_buffer *change_buf;
+ u32 status;
+
+ status = stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0);
+ if (status & ISPC_LINE) {
+ if (atomic_dec_if_positive(&cap->buffers.frame_skip) < 0) {
+ if ((status & ISPC_ENUO)) {
+ change_buf = stf_change_buffer(&cap->buffers);
+ if (change_buf)
+ stf_set_yuv_addr(stfcamss, change_buf->addr[0],
+ change_buf->addr[1]);
+ }
+ }
+
+ stf_isp_reg_set_bit(stfcamss, ISP_REG_CSIINTS,
+ CSI_INTS_MASK, CSI_INTS(0x3));
+ stf_isp_reg_set_bit(stfcamss, ISP_REG_IESHD,
+ SHAD_UP_M | SHAD_UP_EN, 0x3);
+
+ stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0,
+ (status & ~ISPC_INT_ALL_MASK) | ISPC_LINE);
+ }
+
+ return IRQ_HANDLED;
+}
+
+irqreturn_t stf_isp_irq_handler(int irq, void *priv)
+{
+ struct stfcamss *stfcamss = priv;
+ struct stf_capture *cap = &stfcamss->captures[STF_CAPTURE_YUV];
+ struct stfcamss_buffer *ready_buf;
+ u32 status;
+
+ status = stf_isp_reg_read(stfcamss, ISP_REG_ISP_CTRL_0);
+ if (status & ISPC_ISP) {
+ if (status & ISPC_ENUO) {
+ ready_buf = stf_buf_done(&cap->buffers);
+ if (ready_buf)
+ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+ }
+
+ stf_isp_reg_write(stfcamss, ISP_REG_ISP_CTRL_0,
+ (status & ~ISPC_INT_ALL_MASK) |
+ ISPC_ISP | ISPC_CSI | ISPC_SC);
+ }
+
+ return IRQ_HANDLED;
+}
diff --git a/drivers/staging/media/starfive/camss/stf-isp.h b/drivers/staging/media/starfive/camss/stf-isp.h
index bc7e7b0736fa..fcda0502e3b0 100644
--- a/drivers/staging/media/starfive/camss/stf-isp.h
+++ b/drivers/staging/media/starfive/camss/stf-isp.h
@@ -427,4 +427,7 @@ int stf_isp_init(struct stfcamss *stfcamss);
int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2_dev);
int stf_isp_unregister(struct stf_isp_dev *isp_dev);

+void stf_set_yuv_addr(struct stfcamss *stfcamss,
+ dma_addr_t y_addr, dma_addr_t uv_addr);
+
#endif /* STF_ISP_H */
--
2.25.1


2024-01-29 03:52:04

by Changhuang Liang

[permalink] [raw]
Subject: 回复: [PATCH v2 00/13] Add ISP 3A for StarFiv e


> This series implements the ISP 3A function to the Camera Subsystem on
> StarFive
> JH7110 SoC. The series has been tested on the VisionFive 2 board.
>
> This series is based on top of the master branch of media_stage repository,
> which is tested with a v4l2-compliance compiled from the git repo
> (git://linuxtv.org/v4l-utils.git).
>

Hi Laurent,

Could you please help to review and give your comments?
Thanks a lot!

Best regards,
Changhunag