Re: [PATCH RESEND v2 05/19] media: vivid: Include in vivid-vid-cap.c

2024-09-09 Thread Hans Verkuil
On 09/09/2024 09:53, Uros Bizjak wrote:
> Substitute the inclusion of  header with
>  to allow the removal of legacy inclusion
> of  from .
> 
> Signed-off-by: Uros Bizjak 

Acked-by: Hans Verkuil 

Regards,

    Hans

> Cc: Hans Verkuil 
> Cc: Mauro Carvalho Chehab 
> Cc: linux-me...@vger.kernel.org
> ---
>  drivers/media/test-drivers/vivid/vivid-vid-cap.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c 
> b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
> index 69620e0a35a0..184460eb356e 100644
> --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
> +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
> @@ -10,6 +10,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 



Re: [Letux-kernel] [PATCHv2 0/6] drm/omap: hdmi: improve hdmi4 CEC, add CEC for hdmi5

2024-08-29 Thread Hans Verkuil
On 28/08/2024 21:41, H. Nikolaus Schaller wrote:
> Hi all,
> 
>> Am 28.08.2024 um 16:14 schrieb Hans Verkuil :
>>
>> On 28/08/2024 15:57, Tomi Valkeinen wrote:
>>> Hi,
>>>
>>> On 25/08/2024 23:31, H. Nikolaus Schaller wrote:
>>>> Hi,
>>>> CEC features are useful to e.g. control HDMI monitor standby.
>>>>
>>>> But I wonder what happened to this series?
>>>>
>>>> I could find some reviewed-by: and acked-by: in [1] but it wasn't merged 
>>>> upstream
>>>> for unidentifiable reasons.
>>>>
>>>> We apparently had merged this series some years ago into our LetuxOS 
>>>> distro kernel
>>>> and now we found it to be broken (NULL dereference) at least for omap5uevm
>>>> (and likely Pyra Handheld) after rebasing to v6.11-rc (it was already 
>>>> broken
>>>> since v6.9-rc1). Fixes were not difficult, but it would be better if it 
>>>> were
>>>> part of upstream.
>>>
>>> There was a v3:
>>>
>>> 20210428132545.1205162-1-hverkuil-ci...@xs4all.nl
> 
> [A clickable link is here: 
> https://lore.kernel.org/linux-media/20210428132545.1205162-1-hverkuil-ci...@xs4all.nl/
>  ]
> 
> Ah, I see. It wasn't sent to linux-omap so I didn't recognise/find it in my 
> mails
> or omap-patchwork.
> 
> 
>>> I see there was a concern from Laurent in:
>>>
>>> yljmzix71mcqn...@pendragon.ideasonboard.com
> 
> Well, he didn't reject it although he had concerns, but I am not experienced 
> with what
> he is talking about for a proper solution...
> 
>>>
>>> And we need an ack from the bridge maintainers for the drm_bridge parts. 
>>> But the series is three years old, so I think someone would have to rebase 
>>> on top of mainline and re-test and re-send first.
>>
>> I never really followed up with this. I still have the hardware, it is 
>> primarily
>> time. And also that for me this is quite low priority since I don't use 
>> omap5.
>>
>> If someone wants to refresh this series and post it, then I would have no 
>> problem
>> with it.
> 
> A far as I see it just needs a rebase - I guess on linux-next (or drm-misc?) 
> and some
> compile fixes I already have implemented for our distro kernel.
> 
> So if you agree I could work on it, test on omap4&5 and submit a v4 and hope 
> that you
> can jump in and support for the discussion. I would keep you (Hans) as commit 
> author
> and just add a signed-off: and tested-by:

That would be fine.

For what it is worth, the last version I have is this one from 3 years ago:

https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=omap-bridge-cec

I haven't looked at it since.

Regards,

Hans

> 
> But I will also need some time...
> 
> BR and thanks,
> Nikolaus
> 



Re: [PATCH 2/7] media: v4l2-core: add v4l2_debugfs_if_alloc/free()

2024-08-28 Thread Hans Verkuil
On 28/08/2024 17:08, Jani Nikula wrote:
> On Wed, 28 Aug 2024, Hans Verkuil  wrote:
>> Add new helpers to export received or transmitted HDMI InfoFrames to
>> debugfs.
>>
>> This complements similar code in drm where the transmitted HDMI infoframes
>> are exported to debugfs.
>>
>> The same names have been used as in drm, so this is consistent.
>>
>> The exported infoframes can be parsed with the edid-decode utility.
>>
>> Signed-off-by: Hans Verkuil 
>> ---
>>  drivers/media/v4l2-core/v4l2-dv-timings.c | 63 +++
>>  include/media/v4l2-dv-timings.h   | 48 +
>>  2 files changed, 111 insertions(+)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c 
>> b/drivers/media/v4l2-core/v4l2-dv-timings.c
>> index 942d0005c55e..86a8627f4bcc 100644
>> --- a/drivers/media/v4l2-core/v4l2-dv-timings.c
>> +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
>> @@ -1154,3 +1154,66 @@ int v4l2_phys_addr_validate(u16 phys_addr, u16 
>> *parent, u16 *port)
>>  return 0;
>>  }
>>  EXPORT_SYMBOL_GPL(v4l2_phys_addr_validate);
>> +
>> +#ifdef CONFIG_DEBUG_FS
>> +
>> +#define DEBUGFS_FOPS(type, flag)\
>> +static ssize_t  
>> \
>> +infoframe_read_##type(struct file *filp,\
>> +  char __user *ubuf, size_t count, loff_t *ppos)\
>> +{   \
>> +struct v4l2_debugfs_if *infoframes = filp->private_data;\
>> +\
>> +return infoframes->if_read((flag), infoframes->priv, filp,  \
>> +   ubuf, count, ppos);  \
>> +}   \
>> +\
>> +static const struct file_operations infoframe_##type##_fops = { 
>> \
>> +.owner   = THIS_MODULE, \
>> +.open= simple_open, \
>> +.read= infoframe_read_##type,   \
>> +}
>> +
>> +DEBUGFS_FOPS(avi, V4L2_DEBUGFS_IF_AVI);
>> +DEBUGFS_FOPS(audio, V4L2_DEBUGFS_IF_AUDIO);
>> +DEBUGFS_FOPS(spd, V4L2_DEBUGFS_IF_SPD);
>> +DEBUGFS_FOPS(hdmi, V4L2_DEBUGFS_IF_HDMI);
>> +
>> +struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 
>> if_types,
>> +  void *priv,
>> +  v4l2_debugfs_if_read_t if_read)
>> +{
>> +struct v4l2_debugfs_if *infoframes;
>> +
>> +if (IS_ERR_OR_NULL(root) || !if_types || !if_read)
>> +return NULL;
>> +
>> +infoframes = kzalloc(sizeof(*infoframes), GFP_KERNEL);
>> +if (!infoframes)
>> +return NULL;
>> +
>> +infoframes->if_dir = debugfs_create_dir("infoframes", root);
>> +infoframes->priv = priv;
>> +infoframes->if_read = if_read;
>> +if (if_types & V4L2_DEBUGFS_IF_AVI)
>> +debugfs_create_file("avi", 0400, infoframes->if_dir, 
>> infoframes, &infoframe_avi_fops);
>> +if (if_types & V4L2_DEBUGFS_IF_AUDIO)
>> +debugfs_create_file("audio", 0400, infoframes->if_dir, 
>> infoframes, &infoframe_audio_fops);
>> +if (if_types & V4L2_DEBUGFS_IF_SPD)
>> +debugfs_create_file("spd", 0400, infoframes->if_dir, 
>> infoframes, &infoframe_spd_fops);
>> +if (if_types & V4L2_DEBUGFS_IF_HDMI)
>> +debugfs_create_file("hdmi", 0400, infoframes->if_dir, 
>> infoframes, &infoframe_hdmi_fops);
>> +return infoframes;
>> +}
>> +EXPORT_SYMBOL_GPL(v4l2_debugfs_if_alloc);
>> +
>> +void v4l2_debugfs_if_free(struct v4l2_debugfs_if *infoframes)
>> +{
>> +if (infoframes) {
>> +debugfs_remove_recursive(infoframes->if_dir);
>> +kfree(infoframes);
>> +}
>> +}
>> +EXPORT_SYMBOL_GPL(v4l2_debugfs_if_free);
>> +
>> +#endif
>> diff --git a/include/media/v4l2-dv-timings.h 
>> b/include/media/v4l2-dv-timings.h
>> index 8fa963326bf6..13830411bd6c 100644
>> --- a/include/media/v4l2-dv-timings.h
>> +++ b/include/media/v4l2-dv-timings.h
>> @@ -8,6 +8,

Re: [PATCHv2 0/6] drm/omap: hdmi: improve hdmi4 CEC, add CEC for hdmi5

2024-08-28 Thread Hans Verkuil
On 28/08/2024 15:57, Tomi Valkeinen wrote:
> Hi,
> 
> On 25/08/2024 23:31, H. Nikolaus Schaller wrote:
>> Hi,
>> CEC features are useful to e.g. control HDMI monitor standby.
>>
>> But I wonder what happened to this series?
>>
>> I could find some reviewed-by: and acked-by: in [1] but it wasn't merged 
>> upstream
>> for unidentifiable reasons.
>>
>> We apparently had merged this series some years ago into our LetuxOS distro 
>> kernel
>> and now we found it to be broken (NULL dereference) at least for omap5uevm
>> (and likely Pyra Handheld) after rebasing to v6.11-rc (it was already broken
>> since v6.9-rc1). Fixes were not difficult, but it would be better if it were
>> part of upstream.
> 
> There was a v3:
> 
> 20210428132545.1205162-1-hverkuil-ci...@xs4all.nl
> 
> I see there was a concern from Laurent in:
> 
> yljmzix71mcqn...@pendragon.ideasonboard.com
> 
> And we need an ack from the bridge maintainers for the drm_bridge parts. But 
> the series is three years old, so I think someone would have to rebase on top 
> of mainline and re-test and re-send first.

I never really followed up with this. I still have the hardware, it is primarily
time. And also that for me this is quite low priority since I don't use omap5.

If someone wants to refresh this series and post it, then I would have no 
problem
with it.

Regards,

Hans

> 
>  Tomi
> 
>> BR and thanks,
>> Nikolaus
>>
>> [1] 
>> https://lore.kernel.org/r/all/20210302162403.983585-4-hverkuil-ci...@xs4all.nl/T/
>>
>>> Am 02.03.2021 um 17:23 schrieb Hans Verkuil :
>>>
>>> This series improves the drm_bridge support for CEC by introducing two
>>> new bridge ops in the first patch, and using those in the second patch.
>>>
>>> This makes it possible to call cec_s_conn_info() and set
>>> CEC_CAP_CONNECTOR_INFO for the CEC adapter, so userspace can associate
>>> the CEC adapter with the corresponding DRM connector.
>>>
>>> The third patch simplifies CEC physical address handling by using the
>>> cec_s_phys_addr_from_edid helper function that didn't exist when this
>>> code was originally written.
>>>
>>> The fourth patch adds the cec clock to ti,omap5-dss.txt.
>>>
>>> The fifth patch the missing cec clock to the dra7 and omap5 device tree,
>>> and the last patch adds CEC support to the OMAP5 driver.
>>>
>>> Tested with a Pandaboard and a Beagle X15 board.
>>>
>>> Regards,
>>>
>>> Hans
>>>
>>> Changes since v1:
>>>
>>> - as per suggestion from Laurent, changed cec_init/exit to
>>>   connector_attach/_detach which are just called for all
>>>   bridges. The DRM_BRIDGE_OP_CEC was dropped.
>>>
>>> - added patch to add the cec clock to ti,omap5-dss.txt
>>>
>>> - swapped the order of the last two patches
>>>
>>> - incorporated Tomi's suggestions for the hdmi5 CEC support.
>>>
>>> Hans Verkuil (6):
>>>   drm: drm_bridge: add connector_attach/detach bridge ops
>>>   drm/omapdrm/dss/hdmi4: switch to the connector bridge ops
>>>   drm/omapdrm/dss/hdmi4: simplify CEC Phys Addr handling
>>>   dt-bindings: display: ti: ti,omap5-dss.txt: add cec clock
>>>   dra7.dtsi/omap5.dtsi: add cec clock
>>>   drm/omapdrm/dss/hdmi5: add CEC support
>>>
>>> .../bindings/display/ti/ti,omap5-dss.txt  |   4 +-
>>> arch/arm/boot/dts/dra7.dtsi   |   5 +-
>>> arch/arm/boot/dts/omap5.dtsi  |   5 +-
>>> drivers/gpu/drm/drm_bridge_connector.c    |   9 +
>>> drivers/gpu/drm/omapdrm/Kconfig   |   8 +
>>> drivers/gpu/drm/omapdrm/Makefile  |   1 +
>>> drivers/gpu/drm/omapdrm/dss/hdmi.h    |   1 +
>>> drivers/gpu/drm/omapdrm/dss/hdmi4.c   |  40 ++--
>>> drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c   |  13 +-
>>> drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h   |  12 +-
>>> drivers/gpu/drm/omapdrm/dss/hdmi5.c   |  63 +-
>>> drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c   | 209 ++
>>> drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h   |  42 
>>> drivers/gpu/drm/omapdrm/dss/hdmi5_core.c  |  35 ++-
>>> drivers/gpu/drm/omapdrm/dss/hdmi5_core.h  |  33 ++-
>>> include/drm/drm_bridge.h  |  27 +++
>>> 16 files changed, 453 insertions(+), 54 deletions(-)
>>> create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.c
>>> create mode 100644 drivers/gpu/drm/omapdrm/dss/hdmi5_cec.h
>>>
>>> -- 
>>> 2.30.1
>>>
>>
> 



[PATCH 0/7] media: export InfoFrames to debugfs

2024-08-28 Thread Hans Verkuil
Maxime added support for exporting InfoFrames to debugfs for drm,
and this series does the same for the media subsystem.

I used the same names for the InfoFrames as the drm implementation
does, and the format is the same as well. And edid-decode can be
used to parse the InfoFrames and do conformity checking.

The first two patches add helpers for this to the core framework,
and the next 5 patches add support for this to the HDMI drivers.

I tested the three adv drivers, and Dave Stevenson tested the tc358743
driver.

I don't have a tda1997x available for testing, so I might decide
to just drop that patch.

This is very useful for debugging received InfoFrames.

Regards,

Hans

Hans Verkuil (7):
  media: v4l2-core: add v4l2_debugfs_root()
  media: v4l2-core: add v4l2_debugfs_if_alloc/free()
  media: i2c: adv7511-v4l2: export InfoFrames to debugfs
  media: i2c: adv7604: export InfoFrames to debugfs
  media: i2c: adv7842: export InfoFrames to debugfs
  media: i2c: tc358743: export InfoFrames to debugfs
  media: i2c: tda1997x: export InfoFrames to debugfs

 drivers/media/i2c/adv7511-v4l2.c  |  91 +---
 drivers/media/i2c/adv7604.c   |  90 
 drivers/media/i2c/adv7842.c   | 120 --
 drivers/media/i2c/tc358743.c  |  36 ++-
 drivers/media/i2c/tda1997x.c  |  50 -
 drivers/media/v4l2-core/v4l2-dev.c|  14 +++
 drivers/media/v4l2-core/v4l2-dv-timings.c |  63 
 include/media/v4l2-dev.h  |  15 +++
 include/media/v4l2-dv-timings.h   |  48 +
 9 files changed, 455 insertions(+), 72 deletions(-)

-- 
2.43.0



[PATCH 7/7] media: i2c: tda1997x: export InfoFrames to debugfs

2024-08-28 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
---
 drivers/media/i2c/tda1997x.c | 50 ++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 3b7e5ff5b010..2b33fdecb2d2 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -259,6 +259,10 @@ struct tda1997x_state {
struct v4l2_ctrl *detect_tx_5v_ctrl;
struct v4l2_ctrl *rgb_quantization_range_ctrl;
 
+   /* debugfs */
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* audio */
u8  audio_ch_alloc;
int audio_samplerate;
@@ -1263,7 +1267,7 @@ tda1997x_parse_infoframe(struct tda1997x_state *state, 
u16 addr)
 {
struct v4l2_subdev *sd = &state->sd;
union hdmi_infoframe frame;
-   u8 buffer[40] = { 0 };
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = { 0 };
u8 reg;
int len, err;
 
@@ -1938,11 +1942,44 @@ static const struct v4l2_subdev_pad_ops 
tda1997x_pad_ops = {
  * v4l2_subdev_core_ops
  */
 
+static ssize_t
+tda1997x_debugfs_if_read(u32 type, void *priv, struct file *filp, char __user 
*ubuf, size_t count, loff_t *ppos)
+{
+   struct v4l2_subdev *sd = priv;
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   int addr, len;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   addr = AVI_IF;
+   break;
+   case V4L2_DEBUGFS_IF_AUDIO:
+   addr = AUD_IF;
+   break;
+   case V4L2_DEBUGFS_IF_SPD:
+   addr = SPD_IF;
+   break;
+   default:
+   return 0;
+   }
+
+   /* read data */
+   len = io_readn(sd, addr, sizeof(buffer), buffer);
+   if (len > 0) {
+   len = buffer[2] + 4;
+   if (len > V4L2_DEBUGFS_IF_MAX_LEN)
+   len = -EIO;
+   }
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buffer, len);
+   return len < 0 ? 0 : len;
+}
+
 static int tda1997x_log_infoframe(struct v4l2_subdev *sd, int addr)
 {
struct tda1997x_state *state = to_state(sd);
union hdmi_infoframe frame;
-   u8 buffer[40] = { 0 };
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
int len, err;
 
/* read data */
@@ -2791,6 +2828,12 @@ static int tda1997x_probe(struct i2c_client *client)
goto err_free_media;
}
 
+   state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+   state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+   V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
+   V4L2_DEBUGFS_IF_SPD, sd,
+   tda1997x_debugfs_if_read);
+
return 0;
 
 err_free_media:
@@ -2815,6 +2858,9 @@ static void tda1997x_remove(struct i2c_client *client)
struct tda1997x_state *state = to_state(sd);
struct tda1997x_platform_data *pdata = &state->pdata;
 
+   v4l2_debugfs_if_free(state->infoframes);
+   debugfs_remove_recursive(state->debugfs_dir);
+
if (pdata->audout_format) {
mutex_destroy(&state->audio_lock);
}
-- 
2.43.0



[PATCH 2/7] media: v4l2-core: add v4l2_debugfs_if_alloc/free()

2024-08-28 Thread Hans Verkuil
Add new helpers to export received or transmitted HDMI InfoFrames to
debugfs.

This complements similar code in drm where the transmitted HDMI infoframes
are exported to debugfs.

The same names have been used as in drm, so this is consistent.

The exported infoframes can be parsed with the edid-decode utility.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-dv-timings.c | 63 +++
 include/media/v4l2-dv-timings.h   | 48 +
 2 files changed, 111 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c 
b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 942d0005c55e..86a8627f4bcc 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -1154,3 +1154,66 @@ int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, 
u16 *port)
return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_phys_addr_validate);
+
+#ifdef CONFIG_DEBUG_FS
+
+#define DEBUGFS_FOPS(type, flag)   \
+static ssize_t \
+infoframe_read_##type(struct file *filp,   \
+ char __user *ubuf, size_t count, loff_t *ppos)\
+{  \
+   struct v4l2_debugfs_if *infoframes = filp->private_data;\
+   \
+   return infoframes->if_read((flag), infoframes->priv, filp,  \
+  ubuf, count, ppos);  \
+}  \
+   \
+static const struct file_operations infoframe_##type##_fops = {
\
+   .owner   = THIS_MODULE, \
+   .open= simple_open, \
+   .read= infoframe_read_##type,   \
+}
+
+DEBUGFS_FOPS(avi, V4L2_DEBUGFS_IF_AVI);
+DEBUGFS_FOPS(audio, V4L2_DEBUGFS_IF_AUDIO);
+DEBUGFS_FOPS(spd, V4L2_DEBUGFS_IF_SPD);
+DEBUGFS_FOPS(hdmi, V4L2_DEBUGFS_IF_HDMI);
+
+struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 
if_types,
+ void *priv,
+ v4l2_debugfs_if_read_t if_read)
+{
+   struct v4l2_debugfs_if *infoframes;
+
+   if (IS_ERR_OR_NULL(root) || !if_types || !if_read)
+   return NULL;
+
+   infoframes = kzalloc(sizeof(*infoframes), GFP_KERNEL);
+   if (!infoframes)
+   return NULL;
+
+   infoframes->if_dir = debugfs_create_dir("infoframes", root);
+   infoframes->priv = priv;
+   infoframes->if_read = if_read;
+   if (if_types & V4L2_DEBUGFS_IF_AVI)
+   debugfs_create_file("avi", 0400, infoframes->if_dir, 
infoframes, &infoframe_avi_fops);
+   if (if_types & V4L2_DEBUGFS_IF_AUDIO)
+   debugfs_create_file("audio", 0400, infoframes->if_dir, 
infoframes, &infoframe_audio_fops);
+   if (if_types & V4L2_DEBUGFS_IF_SPD)
+   debugfs_create_file("spd", 0400, infoframes->if_dir, 
infoframes, &infoframe_spd_fops);
+   if (if_types & V4L2_DEBUGFS_IF_HDMI)
+   debugfs_create_file("hdmi", 0400, infoframes->if_dir, 
infoframes, &infoframe_hdmi_fops);
+   return infoframes;
+}
+EXPORT_SYMBOL_GPL(v4l2_debugfs_if_alloc);
+
+void v4l2_debugfs_if_free(struct v4l2_debugfs_if *infoframes)
+{
+   if (infoframes) {
+   debugfs_remove_recursive(infoframes->if_dir);
+   kfree(infoframes);
+   }
+}
+EXPORT_SYMBOL_GPL(v4l2_debugfs_if_free);
+
+#endif
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 8fa963326bf6..13830411bd6c 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -8,6 +8,7 @@
 #ifndef __V4L2_DV_TIMINGS_H
 #define __V4L2_DV_TIMINGS_H
 
+#include 
 #include 
 
 /**
@@ -251,4 +252,51 @@ void v4l2_set_edid_phys_addr(u8 *edid, unsigned int size, 
u16 phys_addr);
 u16 v4l2_phys_addr_for_input(u16 phys_addr, u8 input);
 int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
 
+/* Add support for exporting InfoFrames to debugfs */
+
+/*
+ * HDMI InfoFrames start with a 3 byte header, then a checksum,
+ * followed by the actual IF payload.
+ *
+ * The payload length is limited to 30 bytes according to the HDMI spec,
+ * but since the length is encoded in 5 bits, it can be 31 bytes theoretically.
+ * So set the max length as 31 + 3 (header) + 1 (checksum) = 35.
+ */
+#define V4L2_DEBUGFS_IF_MAX_LEN (35)
+
+#define V4L2_DEBUGFS_IF_AVIBIT(0)
+#define V4L2_DEBUGFS_IF_AUDIO  BIT(1)
+#define V4L2_DEBUGFS_IF_SPD

[PATCH 6/7] media: i2c: tc358743: export InfoFrames to debugfs

2024-08-28 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
Tested-by: Dave Stevenson 
---
 drivers/media/i2c/tc358743.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 65d58ddf0287..fd49bf824051 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -87,6 +87,10 @@ struct tc358743_state {
struct timer_list timer;
struct work_struct work_i2c_poll;
 
+   /* debugfs */
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* edid  */
u8 edid_blocks_written;
 
@@ -430,12 +434,35 @@ static void tc358743_erase_bksv(struct v4l2_subdev *sd)
 
 /* --- AVI infoframe --- */
 
+static ssize_t
+tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
+char __user *ubuf, size_t count, loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int len;
+
+   if (!is_hdmi(sd))
+   return 0;
+
+   if (type != V4L2_DEBUGFS_IF_AVI)
+   return 0;
+
+   i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_16BYTE - PK_AVI_0HEAD + 1);
+   len = buf[2] + 4;
+   if (len > V4L2_DEBUGFS_IF_MAX_LEN)
+   len = -ENOENT;
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+   return len < 0 ? 0 : len;
+}
+
 static void print_avi_infoframe(struct v4l2_subdev *sd)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct device *dev = &client->dev;
union hdmi_infoframe frame;
-   u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
+   u8 buffer[HDMI_INFOFRAME_SIZE(AVI)] = {};
 
if (!is_hdmi(sd)) {
v4l2_info(sd, "DVI-D signal - AVI infoframe not supported\n");
@@ -2161,6 +2188,11 @@ static int tc358743_probe(struct i2c_client *client)
if (err < 0)
goto err_work_queues;
 
+   state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+   state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+ V4L2_DEBUGFS_IF_AVI, sd,
+ tc358743_debugfs_if_read);
+
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
  client->addr << 1, client->adapter->name);
 
@@ -2188,6 +2220,8 @@ static void tc358743_remove(struct i2c_client *client)
flush_work(&state->work_i2c_poll);
}
cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+   v4l2_debugfs_if_free(state->infoframes);
+   debugfs_remove_recursive(state->debugfs_dir);
cec_unregister_adapter(state->cec_adap);
v4l2_async_unregister_subdev(sd);
v4l2_device_unregister_subdev(sd);
-- 
2.43.0



[PATCH 5/7] media: i2c: adv7842: export InfoFrames to debugfs

2024-08-28 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/media/i2c/adv7842.c | 120 ++--
 1 file changed, 88 insertions(+), 32 deletions(-)

diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 014fc913225c..e445699da85b 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -114,6 +114,9 @@ struct adv7842_state {
bool restart_stdi_once;
bool hdmi_port_a;
 
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* i2c clients */
struct i2c_client *i2c_sdp_io;
struct i2c_client *i2c_sdp;
@@ -2565,58 +2568,65 @@ struct adv7842_cfg_read_infoframe {
u8 payload_addr;
 };
 
-static void log_infoframe(struct v4l2_subdev *sd, const struct 
adv7842_cfg_read_infoframe *cri)
+static const struct adv7842_cfg_read_infoframe adv7842_cri[] = {
+   { "AVI", 0x01, 0xe0, 0x00 },
+   { "Audio", 0x02, 0xe3, 0x1c },
+   { "SDP", 0x04, 0xe6, 0x2a },
+   { "Vendor", 0x10, 0xec, 0x54 }
+};
+
+static int adv7842_read_infoframe_buf(struct v4l2_subdev *sd, int index,
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN])
 {
-   int i;
-   u8 buffer[32];
-   union hdmi_infoframe frame;
-   u8 len;
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
-   struct device *dev = &client->dev;
+   const struct adv7842_cfg_read_infoframe *cri = &adv7842_cri[index];
+   int len, i;
 
if (!(io_read(sd, 0x60) & cri->present_mask)) {
-   v4l2_info(sd, "%s infoframe not received\n", cri->desc);
-   return;
+   v4l2_dbg(1, debug, sd,
+"%s infoframe not received\n", cri->desc);
+   return -ENOENT;
}
 
for (i = 0; i < 3; i++)
-   buffer[i] = infoframe_read(sd, cri->head_addr + i);
+   buf[i] = infoframe_read(sd, cri->head_addr + i);
 
-   len = buffer[2] + 1;
+   len = buf[2] + 1;
 
-   if (len + 3 > sizeof(buffer)) {
-   v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, 
cri->desc, len);
-   return;
+   if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) {
+   v4l2_err(sd, "%s: invalid %s infoframe length %d\n",
+__func__, cri->desc, len);
+   return -ENOENT;
}
 
for (i = 0; i < len; i++)
-   buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i);
-
-   if (hdmi_infoframe_unpack(&frame, buffer, len + 3) < 0) {
-   v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, 
cri->desc);
-   return;
-   }
-
-   hdmi_infoframe_log(KERN_INFO, dev, &frame);
+   buf[i + 3] = infoframe_read(sd, cri->payload_addr + i);
+   return len + 3;
 }
 
 static void adv7842_log_infoframes(struct v4l2_subdev *sd)
 {
-   int i;
-   static const struct adv7842_cfg_read_infoframe cri[] = {
-   { "AVI", 0x01, 0xe0, 0x00 },
-   { "Audio", 0x02, 0xe3, 0x1c },
-   { "SDP", 0x04, 0xe6, 0x2a },
-   { "Vendor", 0x10, 0xec, 0x54 }
-   };
+   struct i2c_client *client = v4l2_get_subdevdata(sd);
+   struct device *dev = &client->dev;
+   union hdmi_infoframe frame;
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   int len, i;
 
if (!(hdmi_read(sd, 0x05) & 0x80)) {
v4l2_info(sd, "receive DVI-D signal, no infoframes\n");
return;
}
 
-   for (i = 0; i < ARRAY_SIZE(cri); i++)
-   log_infoframe(sd, &cri[i]);
+   for (i = 0; i < ARRAY_SIZE(adv7842_cri); i++) {
+   len = adv7842_read_infoframe_buf(sd, i, buffer);
+   if (len < 0)
+   continue;
+
+   if (hdmi_infoframe_unpack(&frame, buffer, len) < 0)
+   v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+__func__, adv7842_cri[i].desc);
+   else
+   hdmi_infoframe_log(KERN_INFO, dev, &frame);
+   }
 }
 
 #if 0
@@ -3263,6 +3273,41 @@ static int adv7842_subscribe_event(struct v4l2_subdev 
*sd,
}
 }
 
+static ssize_t
+adv7842_debugfs_if_read(u32 type, void *priv, struct file *filp,
+   char __user *ubuf, size_t count, loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int index;
+   int len;
+
+   if (!is_hdmi(sd))
+   return 0;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   index = 0;
+   break;
+   case V4L2

[PATCH 4/7] media: i2c: adv7604: export InfoFrames to debugfs

2024-08-28 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/media/i2c/adv7604.c | 90 -
 1 file changed, 70 insertions(+), 20 deletions(-)

diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 48230d5109f0..3184a2fa1532 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -193,6 +193,9 @@ struct adv76xx_state {
struct delayed_work delayed_work_enable_hotplug;
bool restart_stdi_once;
 
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* CEC */
struct cec_adapter *cec_adap;
u8   cec_addr[ADV76XX_MAX_ADDRS];
@@ -2458,10 +2461,9 @@ static const struct adv76xx_cfg_read_infoframe 
adv76xx_cri[] = {
{ "Vendor", 0x10, 0xec, 0x54 }
 };
 
-static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index,
- union hdmi_infoframe *frame)
+static int adv76xx_read_infoframe_buf(struct v4l2_subdev *sd, int index,
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN])
 {
-   uint8_t buffer[32];
u8 len;
int i;
 
@@ -2472,27 +2474,20 @@ static int adv76xx_read_infoframe(struct v4l2_subdev 
*sd, int index,
}
 
for (i = 0; i < 3; i++)
-   buffer[i] = infoframe_read(sd,
-  adv76xx_cri[index].head_addr + i);
+   buf[i] = infoframe_read(sd, adv76xx_cri[index].head_addr + i);
 
-   len = buffer[2] + 1;
+   len = buf[2] + 1;
 
-   if (len + 3 > sizeof(buffer)) {
+   if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) {
v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__,
 adv76xx_cri[index].desc, len);
return -ENOENT;
}
 
for (i = 0; i < len; i++)
-   buffer[i + 3] = infoframe_read(sd,
-  adv76xx_cri[index].payload_addr + i);
-
-   if (hdmi_infoframe_unpack(frame, buffer, len + 3) < 0) {
-   v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__,
-adv76xx_cri[index].desc);
-   return -ENOENT;
-   }
-   return 0;
+   buf[i + 3] = infoframe_read(sd,
+   adv76xx_cri[index].payload_addr + 
i);
+   return len + 3;
 }
 
 static void adv76xx_log_infoframes(struct v4l2_subdev *sd)
@@ -2505,10 +2500,19 @@ static void adv76xx_log_infoframes(struct v4l2_subdev 
*sd)
}
 
for (i = 0; i < ARRAY_SIZE(adv76xx_cri); i++) {
-   union hdmi_infoframe frame;
struct i2c_client *client = v4l2_get_subdevdata(sd);
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   union hdmi_infoframe frame;
+   int len;
 
-   if (!adv76xx_read_infoframe(sd, i, &frame))
+   len = adv76xx_read_infoframe_buf(sd, i, buffer);
+   if (len < 0)
+   continue;
+
+   if (hdmi_infoframe_unpack(&frame, buffer, len) < 0)
+   v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+__func__, adv76xx_cri[i].desc);
+   else
hdmi_infoframe_log(KERN_INFO, &client->dev, &frame);
}
 }
@@ -2686,6 +2690,41 @@ static int adv76xx_subscribe_event(struct v4l2_subdev 
*sd,
}
 }
 
+static ssize_t
+adv76xx_debugfs_if_read(u32 type, void *priv, struct file *filp,
+   char __user *ubuf, size_t count, loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int index;
+   int len;
+
+   if (!is_hdmi(sd))
+   return 0;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   index = 0;
+   break;
+   case V4L2_DEBUGFS_IF_AUDIO:
+   index = 1;
+   break;
+   case V4L2_DEBUGFS_IF_SPD:
+   index = 2;
+   break;
+   case V4L2_DEBUGFS_IF_HDMI:
+   index = 3;
+   break;
+   default:
+   return 0;
+   }
+
+   len = adv76xx_read_infoframe_buf(sd, index, buf);
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+   return len < 0 ? 0 : len;
+}
+
 static int adv76xx_registered(struct v4l2_subdev *sd)
 {
struct adv76xx_state *state = to_state(sd);
@@ -2693,9 +2732,16 @@ static int adv76xx_registered(struct v4l2_subdev *sd)
int err;
 
err = cec_register_adapter(state->cec_adap, &client->dev);
-   if (err)
+   if (err) {
cec_delete_adapter(state->cec_adap);
-   return err;
+   return err;
+   }
+   state->debugfs_dir = d

[PATCH 3/7] media: i2c: adv7511-v4l2: export InfoFrames to debugfs

2024-08-28 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/media/i2c/adv7511-v4l2.c | 91 ++--
 1 file changed, 74 insertions(+), 17 deletions(-)

diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
index e9406d552699..4036972af3a6 100644
--- a/drivers/media/i2c/adv7511-v4l2.c
+++ b/drivers/media/i2c/adv7511-v4l2.c
@@ -116,6 +116,9 @@ struct adv7511_state {
unsigned edid_detect_counter;
struct workqueue_struct *work_queue;
struct delayed_work edid_handler; /* work entry */
+
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
 };
 
 static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd);
@@ -483,27 +486,25 @@ static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
return 256 - csum;
 }
 
-static void log_infoframe(struct v4l2_subdev *sd, const struct 
adv7511_cfg_read_infoframe *cri)
+static int read_infoframe(struct v4l2_subdev *sd,
+ const struct adv7511_cfg_read_infoframe *cri,
+ u8 *buffer)
 {
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
-   struct device *dev = &client->dev;
-   union hdmi_infoframe frame;
-   u8 buffer[32];
u8 len;
int i;
 
if (!(adv7511_rd(sd, cri->present_reg) & cri->present_mask)) {
v4l2_info(sd, "%s infoframe not transmitted\n", cri->desc);
-   return;
+   return 0;
}
 
memcpy(buffer, cri->header, sizeof(cri->header));
 
len = buffer[2];
 
-   if (len + 4 > sizeof(buffer)) {
+   if (len + 4 > V4L2_DEBUGFS_IF_MAX_LEN) {
v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, 
cri->desc, len);
-   return;
+   return 0;
}
 
if (cri->payload_addr >= 0x100) {
@@ -516,21 +517,38 @@ static void log_infoframe(struct v4l2_subdev *sd, const 
struct adv7511_cfg_read_
buffer[3] = 0;
buffer[3] = hdmi_infoframe_checksum(buffer, len + 4);
 
-   if (hdmi_infoframe_unpack(&frame, buffer, len + 4) < 0) {
-   v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, 
cri->desc);
+   return len + 4;
+}
+
+static void log_infoframe(struct v4l2_subdev *sd,
+ const struct adv7511_cfg_read_infoframe *cri)
+{
+   union hdmi_infoframe frame;
+   struct i2c_client *client = v4l2_get_subdevdata(sd);
+   struct device *dev = &client->dev;
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   int len = read_infoframe(sd, cri, buffer);
+
+   if (len <= 0)
+   return;
+
+   if (hdmi_infoframe_unpack(&frame, buffer, len) < 0) {
+   v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+__func__, cri->desc);
return;
}
 
hdmi_infoframe_log(KERN_INFO, dev, &frame);
 }
 
+static const struct adv7511_cfg_read_infoframe cri[] = {
+   { "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
+   { "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
+   { "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
+};
+
 static void adv7511_log_infoframes(struct v4l2_subdev *sd)
 {
-   static const struct adv7511_cfg_read_infoframe cri[] = {
-   { "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
-   { "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
-   { "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
-   };
int i;
 
for (i = 0; i < ARRAY_SIZE(cri); i++)
@@ -1693,6 +1711,34 @@ static bool adv7511_check_edid_status(struct v4l2_subdev 
*sd)
return false;
 }
 
+static ssize_t
+adv7511_debugfs_if_read(u32 type, void *priv,
+   struct file *filp, char __user *ubuf, size_t count, 
loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int index;
+   int len;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   index = 0;
+   break;
+   case V4L2_DEBUGFS_IF_AUDIO:
+   index = 1;
+   break;
+   case V4L2_DEBUGFS_IF_SPD:
+   index = 2;
+   break;
+   default:
+   return 0;
+   }
+   len = read_infoframe(sd, &cri[index], buf);
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+   return len < 0 ? 0 : len;
+}
+
 static int adv7511_registered(struct v4l2_subdev *sd)
 {
struct adv7511_state *state = get_adv7511_state(sd);
@@ -1700,9 +1746,16 @@ static int adv7511_registered(struct v4l2_subdev *sd)
int err;
 
err = cec_register_adapter(state->cec_adap, &client->dev);
-  

[PATCH 1/7] media: v4l2-core: add v4l2_debugfs_root()

2024-08-28 Thread Hans Verkuil
This new function returns the dentry of the top-level debugfs "v4l2"
directory. If it does not exist yet, then it is created first.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-dev.c | 14 ++
 include/media/v4l2-dev.h   | 15 +++
 2 files changed, 29 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index be2ba7ca5de2..4bbf279a0c8b 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -93,6 +93,8 @@ static struct attribute *video_device_attrs[] = {
 };
 ATTRIBUTE_GROUPS(video_device);
 
+static struct dentry *v4l2_debugfs_root_dir;
+
 /*
  * Active devices
  */
@@ -1104,6 +1106,16 @@ void video_unregister_device(struct video_device *vdev)
 }
 EXPORT_SYMBOL(video_unregister_device);
 
+#ifdef CONFIG_DEBUG_FS
+struct dentry *v4l2_debugfs_root(void)
+{
+   if (!v4l2_debugfs_root_dir)
+   v4l2_debugfs_root_dir = debugfs_create_dir("v4l2", NULL);
+   return v4l2_debugfs_root_dir;
+}
+EXPORT_SYMBOL_GPL(v4l2_debugfs_root);
+#endif
+
 #if defined(CONFIG_MEDIA_CONTROLLER)
 
 __must_check int video_device_pipeline_start(struct video_device *vdev,
@@ -1208,6 +1220,8 @@ static void __exit videodev_exit(void)
 
class_unregister(&video_class);
unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
+   debugfs_remove_recursive(v4l2_debugfs_root_dir);
+   v4l2_debugfs_root_dir = NULL;
 }
 
 subsys_initcall(videodev_init);
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index d82dfdbf6e58..1b6222fab24e 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -62,6 +62,7 @@ struct v4l2_ioctl_callbacks;
 struct video_device;
 struct v4l2_device;
 struct v4l2_ctrl_handler;
+struct dentry;
 
 /**
  * enum v4l2_video_device_flags - Flags used by &struct video_device
@@ -539,6 +540,20 @@ static inline int video_is_registered(struct video_device 
*vdev)
return test_bit(V4L2_FL_REGISTERED, &vdev->flags);
 }
 
+/**
+ * v4l2_debugfs_root - returns the dentry of the top-level "v4l2" debugfs dir
+ *
+ * If this directory does not yet exist, then it will be created.
+ */
+#ifdef CONFIG_DEBUG_FS
+struct dentry *v4l2_debugfs_root(void);
+#else
+static inline struct dentry *v4l2_debugfs_root(void)
+{
+   return NULL;
+}
+#endif
+
 #if defined(CONFIG_MEDIA_CONTROLLER)
 
 /**
-- 
2.43.0



Re: [RFC PATCH 7/7] media: i2c: tc358743: export InfoFrames to debugfs

2024-08-21 Thread Hans Verkuil
On 21/08/2024 18:12, Dave Stevenson wrote:
> Hi Hans
> 
> This is a very useful little series - thanks.
> 
> On Wed, 21 Aug 2024 at 15:16, Hans Verkuil  wrote:
>>
>> Export InfoFrames to debugfs.
> 
> I had a tc358743 to hand, so thought this warranted a quick test.
> I think you have an off-by-one on the length that this exposes.
> 
> log_status is giving me state
>[  428.600874] tc358743 10-000f: -HDMI status-
>[  428.600881] tc358743 10-000f: HDCP encrypted content: no
>[  428.600887] tc358743 10-000f: Input color space: RGB limited range
>[  428.601404] tc358743 10-000f: AV Mute: off
>[  428.601921] tc358743 10-000f: Deep color mode: 8-bits per channel
>[  428.604407] tc358743 10-000f: HDMI infoframe: Auxiliary Video
> Information (AVI), version 2, length 13
>[  428.604425] tc358743 10-000f: colorspace: RGB
>[  428.604433] tc358743 10-000f: scan mode: Underscan
>[  428.604441] tc358743 10-000f: colorimetry: No Data
>[  428.604449] tc358743 10-000f: picture aspect: 16:9
>[  428.604456] tc358743 10-000f: active aspect: Same as Picture
>[  428.604463] tc358743 10-000f: itc: No Data
>[  428.604469] tc358743 10-000f: extended colorimetry: xvYCC 601
>[  428.604476] tc358743 10-000f: quantization range: Limited
>[  428.604483] tc358743 10-000f: nups: Unknown Non-uniform Scaling
>[  428.604490] tc358743 10-000f: video code: 4
>[  428.604497] tc358743 10-000f: ycc quantization range: Limited
>[  428.604505] tc358743 10-000f: hdmi content type: Graphics
>[  428.604511] tc358743 10-000f: pixel repeat: 0
>[  428.604519] tc358743 10-000f: bar top 0, bottom 0, left 0, right 0
> 
> pi@bookworm64:~/edid-decode $ xxd /sys/kernel/debug/v4l2/tc358743\
> 10-000f/infoframes/avi
> : 8202 0d2d 1228 0404      ...-.(..
> 
> At the transmitting end I've got
> pi@bookworm64:~/edid-decode $ sudo xxd
> /sys/kernel/debug/dri/1/HDMI-A-1/infoframes/avi
> : 8202 0d2d 1228 0404      ...-.(..
> 0010: 00
> 
> edid-decode -I decodes the latter fine, but aborts on the former.
> Oddly the "fail" message from parse_if_hdr [1] doesn't get printed, it
> just stops with

I fixed this in edid-decode.

> pi@bookworm64:~/edid-decode $ ./build/edid-decode -I
> /sys/kernel/debug/v4l2/tc358743\ 10-000f/infoframes/avi
> edid-decode InfoFrame (hex):
> 
> 82 02 0d 2d 12 28 04 04 00 00 00 00 00 00 00 00
> 
> ----
> 
> HDMI InfoFrame Checksum: 0x2d
> 
> AVI InfoFrame
>   Version: 2
>   Length: 13
> 
> 
> [1] https://git.linuxtv.org/edid-decode.git/tree/parse-if.cpp#n21
> 
>> Signed-off-by: Hans Verkuil 
>> ---
>>  drivers/media/i2c/tc358743.c | 36 +++-
>>  1 file changed, 35 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
>> index 65d58ddf0287..c7652c0dbaeb 100644
>> --- a/drivers/media/i2c/tc358743.c
>> +++ b/drivers/media/i2c/tc358743.c
>> @@ -87,6 +87,10 @@ struct tc358743_state {
>> struct timer_list timer;
>> struct work_struct work_i2c_poll;
>>
>> +   /* debugfs */
>> +   struct dentry *debugfs_dir;
>> +   struct v4l2_debugfs_if *infoframes;
>> +
>> /* edid  */
>> u8 edid_blocks_written;
>>
>> @@ -430,12 +434,35 @@ static void tc358743_erase_bksv(struct v4l2_subdev *sd)
>>
>>  /* --- AVI infoframe --- */
>>
>> +static ssize_t
>> +tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
>> +char __user *ubuf, size_t count, loff_t *ppos)
>> +{
>> +   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
>> +   struct v4l2_subdev *sd = priv;
>> +   int len;
>> +
>> +   if (!is_hdmi(sd))
>> +   return 0;
>> +
>> +   if (type != V4L2_DEBUGFS_IF_AVI)
>> +   return 0;
>> +
>> +   i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_16BYTE - PK_AVI_0HEAD + 1);
>> +   len = buf[2] + 3;
> 
> tda1997x has len = buffer[2] + 4;
> adv7842 and adv7604 have len = buf[2] + 1; and then return len + 3;
> adv7511 has len = buffer[2]; and return len + 4;
> 
> So I think this should be len = buf[2] + 4;

Yes, that's correct. I forgot about the extra checksum byte that HDMI
inserts in InfoFrames.

Thank you, I've updated the patch and added a Tested-by with your email.

Regards,

Hans

> 
> Doing so makes edid-decode happy.
> pi@bookworm64:~/edi

[RFC PATCH 4/7] media: i2c: adv7604: export InfoFrames to debugfs

2024-08-21 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/media/i2c/adv7604.c | 90 -
 1 file changed, 70 insertions(+), 20 deletions(-)

diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 48230d5109f0..3184a2fa1532 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -193,6 +193,9 @@ struct adv76xx_state {
struct delayed_work delayed_work_enable_hotplug;
bool restart_stdi_once;
 
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* CEC */
struct cec_adapter *cec_adap;
u8   cec_addr[ADV76XX_MAX_ADDRS];
@@ -2458,10 +2461,9 @@ static const struct adv76xx_cfg_read_infoframe 
adv76xx_cri[] = {
{ "Vendor", 0x10, 0xec, 0x54 }
 };
 
-static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index,
- union hdmi_infoframe *frame)
+static int adv76xx_read_infoframe_buf(struct v4l2_subdev *sd, int index,
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN])
 {
-   uint8_t buffer[32];
u8 len;
int i;
 
@@ -2472,27 +2474,20 @@ static int adv76xx_read_infoframe(struct v4l2_subdev 
*sd, int index,
}
 
for (i = 0; i < 3; i++)
-   buffer[i] = infoframe_read(sd,
-  adv76xx_cri[index].head_addr + i);
+   buf[i] = infoframe_read(sd, adv76xx_cri[index].head_addr + i);
 
-   len = buffer[2] + 1;
+   len = buf[2] + 1;
 
-   if (len + 3 > sizeof(buffer)) {
+   if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) {
v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__,
 adv76xx_cri[index].desc, len);
return -ENOENT;
}
 
for (i = 0; i < len; i++)
-   buffer[i + 3] = infoframe_read(sd,
-  adv76xx_cri[index].payload_addr + i);
-
-   if (hdmi_infoframe_unpack(frame, buffer, len + 3) < 0) {
-   v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__,
-adv76xx_cri[index].desc);
-   return -ENOENT;
-   }
-   return 0;
+   buf[i + 3] = infoframe_read(sd,
+   adv76xx_cri[index].payload_addr + 
i);
+   return len + 3;
 }
 
 static void adv76xx_log_infoframes(struct v4l2_subdev *sd)
@@ -2505,10 +2500,19 @@ static void adv76xx_log_infoframes(struct v4l2_subdev 
*sd)
}
 
for (i = 0; i < ARRAY_SIZE(adv76xx_cri); i++) {
-   union hdmi_infoframe frame;
struct i2c_client *client = v4l2_get_subdevdata(sd);
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   union hdmi_infoframe frame;
+   int len;
 
-   if (!adv76xx_read_infoframe(sd, i, &frame))
+   len = adv76xx_read_infoframe_buf(sd, i, buffer);
+   if (len < 0)
+   continue;
+
+   if (hdmi_infoframe_unpack(&frame, buffer, len) < 0)
+   v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+__func__, adv76xx_cri[i].desc);
+   else
hdmi_infoframe_log(KERN_INFO, &client->dev, &frame);
}
 }
@@ -2686,6 +2690,41 @@ static int adv76xx_subscribe_event(struct v4l2_subdev 
*sd,
}
 }
 
+static ssize_t
+adv76xx_debugfs_if_read(u32 type, void *priv, struct file *filp,
+   char __user *ubuf, size_t count, loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int index;
+   int len;
+
+   if (!is_hdmi(sd))
+   return 0;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   index = 0;
+   break;
+   case V4L2_DEBUGFS_IF_AUDIO:
+   index = 1;
+   break;
+   case V4L2_DEBUGFS_IF_SPD:
+   index = 2;
+   break;
+   case V4L2_DEBUGFS_IF_HDMI:
+   index = 3;
+   break;
+   default:
+   return 0;
+   }
+
+   len = adv76xx_read_infoframe_buf(sd, index, buf);
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+   return len < 0 ? 0 : len;
+}
+
 static int adv76xx_registered(struct v4l2_subdev *sd)
 {
struct adv76xx_state *state = to_state(sd);
@@ -2693,9 +2732,16 @@ static int adv76xx_registered(struct v4l2_subdev *sd)
int err;
 
err = cec_register_adapter(state->cec_adap, &client->dev);
-   if (err)
+   if (err) {
cec_delete_adapter(state->cec_adap);
-   return err;
+   return err;
+   }
+   state->debugfs_dir = d

[RFC PATCH 6/7] media: i2c: tda1997x: export InfoFrames to debugfs

2024-08-21 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
---
 drivers/media/i2c/tda1997x.c | 50 ++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 3b7e5ff5b010..2b33fdecb2d2 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -259,6 +259,10 @@ struct tda1997x_state {
struct v4l2_ctrl *detect_tx_5v_ctrl;
struct v4l2_ctrl *rgb_quantization_range_ctrl;
 
+   /* debugfs */
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* audio */
u8  audio_ch_alloc;
int audio_samplerate;
@@ -1263,7 +1267,7 @@ tda1997x_parse_infoframe(struct tda1997x_state *state, 
u16 addr)
 {
struct v4l2_subdev *sd = &state->sd;
union hdmi_infoframe frame;
-   u8 buffer[40] = { 0 };
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = { 0 };
u8 reg;
int len, err;
 
@@ -1938,11 +1942,44 @@ static const struct v4l2_subdev_pad_ops 
tda1997x_pad_ops = {
  * v4l2_subdev_core_ops
  */
 
+static ssize_t
+tda1997x_debugfs_if_read(u32 type, void *priv, struct file *filp, char __user 
*ubuf, size_t count, loff_t *ppos)
+{
+   struct v4l2_subdev *sd = priv;
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   int addr, len;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   addr = AVI_IF;
+   break;
+   case V4L2_DEBUGFS_IF_AUDIO:
+   addr = AUD_IF;
+   break;
+   case V4L2_DEBUGFS_IF_SPD:
+   addr = SPD_IF;
+   break;
+   default:
+   return 0;
+   }
+
+   /* read data */
+   len = io_readn(sd, addr, sizeof(buffer), buffer);
+   if (len > 0) {
+   len = buffer[2] + 4;
+   if (len > V4L2_DEBUGFS_IF_MAX_LEN)
+   len = -EIO;
+   }
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buffer, len);
+   return len < 0 ? 0 : len;
+}
+
 static int tda1997x_log_infoframe(struct v4l2_subdev *sd, int addr)
 {
struct tda1997x_state *state = to_state(sd);
union hdmi_infoframe frame;
-   u8 buffer[40] = { 0 };
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
int len, err;
 
/* read data */
@@ -2791,6 +2828,12 @@ static int tda1997x_probe(struct i2c_client *client)
goto err_free_media;
}
 
+   state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+   state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+   V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
+   V4L2_DEBUGFS_IF_SPD, sd,
+   tda1997x_debugfs_if_read);
+
return 0;
 
 err_free_media:
@@ -2815,6 +2858,9 @@ static void tda1997x_remove(struct i2c_client *client)
struct tda1997x_state *state = to_state(sd);
struct tda1997x_platform_data *pdata = &state->pdata;
 
+   v4l2_debugfs_if_free(state->infoframes);
+   debugfs_remove_recursive(state->debugfs_dir);
+
if (pdata->audout_format) {
mutex_destroy(&state->audio_lock);
}
-- 
2.43.0



[RFC PATCH 5/7] media: i2c: adv7842: export InfoFrames to debugfs

2024-08-21 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/media/i2c/adv7842.c | 120 ++--
 1 file changed, 88 insertions(+), 32 deletions(-)

diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 014fc913225c..e445699da85b 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -114,6 +114,9 @@ struct adv7842_state {
bool restart_stdi_once;
bool hdmi_port_a;
 
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* i2c clients */
struct i2c_client *i2c_sdp_io;
struct i2c_client *i2c_sdp;
@@ -2565,58 +2568,65 @@ struct adv7842_cfg_read_infoframe {
u8 payload_addr;
 };
 
-static void log_infoframe(struct v4l2_subdev *sd, const struct 
adv7842_cfg_read_infoframe *cri)
+static const struct adv7842_cfg_read_infoframe adv7842_cri[] = {
+   { "AVI", 0x01, 0xe0, 0x00 },
+   { "Audio", 0x02, 0xe3, 0x1c },
+   { "SDP", 0x04, 0xe6, 0x2a },
+   { "Vendor", 0x10, 0xec, 0x54 }
+};
+
+static int adv7842_read_infoframe_buf(struct v4l2_subdev *sd, int index,
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN])
 {
-   int i;
-   u8 buffer[32];
-   union hdmi_infoframe frame;
-   u8 len;
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
-   struct device *dev = &client->dev;
+   const struct adv7842_cfg_read_infoframe *cri = &adv7842_cri[index];
+   int len, i;
 
if (!(io_read(sd, 0x60) & cri->present_mask)) {
-   v4l2_info(sd, "%s infoframe not received\n", cri->desc);
-   return;
+   v4l2_dbg(1, debug, sd,
+"%s infoframe not received\n", cri->desc);
+   return -ENOENT;
}
 
for (i = 0; i < 3; i++)
-   buffer[i] = infoframe_read(sd, cri->head_addr + i);
+   buf[i] = infoframe_read(sd, cri->head_addr + i);
 
-   len = buffer[2] + 1;
+   len = buf[2] + 1;
 
-   if (len + 3 > sizeof(buffer)) {
-   v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, 
cri->desc, len);
-   return;
+   if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) {
+   v4l2_err(sd, "%s: invalid %s infoframe length %d\n",
+__func__, cri->desc, len);
+   return -ENOENT;
}
 
for (i = 0; i < len; i++)
-   buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i);
-
-   if (hdmi_infoframe_unpack(&frame, buffer, len + 3) < 0) {
-   v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, 
cri->desc);
-   return;
-   }
-
-   hdmi_infoframe_log(KERN_INFO, dev, &frame);
+   buf[i + 3] = infoframe_read(sd, cri->payload_addr + i);
+   return len + 3;
 }
 
 static void adv7842_log_infoframes(struct v4l2_subdev *sd)
 {
-   int i;
-   static const struct adv7842_cfg_read_infoframe cri[] = {
-   { "AVI", 0x01, 0xe0, 0x00 },
-   { "Audio", 0x02, 0xe3, 0x1c },
-   { "SDP", 0x04, 0xe6, 0x2a },
-   { "Vendor", 0x10, 0xec, 0x54 }
-   };
+   struct i2c_client *client = v4l2_get_subdevdata(sd);
+   struct device *dev = &client->dev;
+   union hdmi_infoframe frame;
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   int len, i;
 
if (!(hdmi_read(sd, 0x05) & 0x80)) {
v4l2_info(sd, "receive DVI-D signal, no infoframes\n");
return;
}
 
-   for (i = 0; i < ARRAY_SIZE(cri); i++)
-   log_infoframe(sd, &cri[i]);
+   for (i = 0; i < ARRAY_SIZE(adv7842_cri); i++) {
+   len = adv7842_read_infoframe_buf(sd, i, buffer);
+   if (len < 0)
+   continue;
+
+   if (hdmi_infoframe_unpack(&frame, buffer, len) < 0)
+   v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+__func__, adv7842_cri[i].desc);
+   else
+   hdmi_infoframe_log(KERN_INFO, dev, &frame);
+   }
 }
 
 #if 0
@@ -3263,6 +3273,41 @@ static int adv7842_subscribe_event(struct v4l2_subdev 
*sd,
}
 }
 
+static ssize_t
+adv7842_debugfs_if_read(u32 type, void *priv, struct file *filp,
+   char __user *ubuf, size_t count, loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int index;
+   int len;
+
+   if (!is_hdmi(sd))
+   return 0;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   index = 0;
+   break;
+   case V4L2

[RFC PATCH 1/7] media: v4l2-core: add v4l2_debugfs_root()

2024-08-21 Thread Hans Verkuil
This new function returns the dentry of the top-level debugfs "v4l2"
directory. If it does not exist yet, then it is created first.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-dev.c | 14 ++
 include/media/v4l2-dev.h   | 15 +++
 2 files changed, 29 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index be2ba7ca5de2..4bbf279a0c8b 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -93,6 +93,8 @@ static struct attribute *video_device_attrs[] = {
 };
 ATTRIBUTE_GROUPS(video_device);
 
+static struct dentry *v4l2_debugfs_root_dir;
+
 /*
  * Active devices
  */
@@ -1104,6 +1106,16 @@ void video_unregister_device(struct video_device *vdev)
 }
 EXPORT_SYMBOL(video_unregister_device);
 
+#ifdef CONFIG_DEBUG_FS
+struct dentry *v4l2_debugfs_root(void)
+{
+   if (!v4l2_debugfs_root_dir)
+   v4l2_debugfs_root_dir = debugfs_create_dir("v4l2", NULL);
+   return v4l2_debugfs_root_dir;
+}
+EXPORT_SYMBOL_GPL(v4l2_debugfs_root);
+#endif
+
 #if defined(CONFIG_MEDIA_CONTROLLER)
 
 __must_check int video_device_pipeline_start(struct video_device *vdev,
@@ -1208,6 +1220,8 @@ static void __exit videodev_exit(void)
 
class_unregister(&video_class);
unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
+   debugfs_remove_recursive(v4l2_debugfs_root_dir);
+   v4l2_debugfs_root_dir = NULL;
 }
 
 subsys_initcall(videodev_init);
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index d82dfdbf6e58..1b6222fab24e 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -62,6 +62,7 @@ struct v4l2_ioctl_callbacks;
 struct video_device;
 struct v4l2_device;
 struct v4l2_ctrl_handler;
+struct dentry;
 
 /**
  * enum v4l2_video_device_flags - Flags used by &struct video_device
@@ -539,6 +540,20 @@ static inline int video_is_registered(struct video_device 
*vdev)
return test_bit(V4L2_FL_REGISTERED, &vdev->flags);
 }
 
+/**
+ * v4l2_debugfs_root - returns the dentry of the top-level "v4l2" debugfs dir
+ *
+ * If this directory does not yet exist, then it will be created.
+ */
+#ifdef CONFIG_DEBUG_FS
+struct dentry *v4l2_debugfs_root(void);
+#else
+static inline struct dentry *v4l2_debugfs_root(void)
+{
+   return NULL;
+}
+#endif
+
 #if defined(CONFIG_MEDIA_CONTROLLER)
 
 /**
-- 
2.43.0



[RFC PATCH 3/7] media: i2c: adv7511-v4l2: export InfoFrames to debugfs

2024-08-21 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
Tested-by: Hans Verkuil 
---
 drivers/media/i2c/adv7511-v4l2.c | 91 ++--
 1 file changed, 74 insertions(+), 17 deletions(-)

diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
index e9406d552699..4036972af3a6 100644
--- a/drivers/media/i2c/adv7511-v4l2.c
+++ b/drivers/media/i2c/adv7511-v4l2.c
@@ -116,6 +116,9 @@ struct adv7511_state {
unsigned edid_detect_counter;
struct workqueue_struct *work_queue;
struct delayed_work edid_handler; /* work entry */
+
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
 };
 
 static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd);
@@ -483,27 +486,25 @@ static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
return 256 - csum;
 }
 
-static void log_infoframe(struct v4l2_subdev *sd, const struct 
adv7511_cfg_read_infoframe *cri)
+static int read_infoframe(struct v4l2_subdev *sd,
+ const struct adv7511_cfg_read_infoframe *cri,
+ u8 *buffer)
 {
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
-   struct device *dev = &client->dev;
-   union hdmi_infoframe frame;
-   u8 buffer[32];
u8 len;
int i;
 
if (!(adv7511_rd(sd, cri->present_reg) & cri->present_mask)) {
v4l2_info(sd, "%s infoframe not transmitted\n", cri->desc);
-   return;
+   return 0;
}
 
memcpy(buffer, cri->header, sizeof(cri->header));
 
len = buffer[2];
 
-   if (len + 4 > sizeof(buffer)) {
+   if (len + 4 > V4L2_DEBUGFS_IF_MAX_LEN) {
v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, 
cri->desc, len);
-   return;
+   return 0;
}
 
if (cri->payload_addr >= 0x100) {
@@ -516,21 +517,38 @@ static void log_infoframe(struct v4l2_subdev *sd, const 
struct adv7511_cfg_read_
buffer[3] = 0;
buffer[3] = hdmi_infoframe_checksum(buffer, len + 4);
 
-   if (hdmi_infoframe_unpack(&frame, buffer, len + 4) < 0) {
-   v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, 
cri->desc);
+   return len + 4;
+}
+
+static void log_infoframe(struct v4l2_subdev *sd,
+ const struct adv7511_cfg_read_infoframe *cri)
+{
+   union hdmi_infoframe frame;
+   struct i2c_client *client = v4l2_get_subdevdata(sd);
+   struct device *dev = &client->dev;
+   u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   int len = read_infoframe(sd, cri, buffer);
+
+   if (len <= 0)
+   return;
+
+   if (hdmi_infoframe_unpack(&frame, buffer, len) < 0) {
+   v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+__func__, cri->desc);
return;
}
 
hdmi_infoframe_log(KERN_INFO, dev, &frame);
 }
 
+static const struct adv7511_cfg_read_infoframe cri[] = {
+   { "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
+   { "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
+   { "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
+};
+
 static void adv7511_log_infoframes(struct v4l2_subdev *sd)
 {
-   static const struct adv7511_cfg_read_infoframe cri[] = {
-   { "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
-   { "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
-   { "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
-   };
int i;
 
for (i = 0; i < ARRAY_SIZE(cri); i++)
@@ -1693,6 +1711,34 @@ static bool adv7511_check_edid_status(struct v4l2_subdev 
*sd)
return false;
 }
 
+static ssize_t
+adv7511_debugfs_if_read(u32 type, void *priv,
+   struct file *filp, char __user *ubuf, size_t count, 
loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int index;
+   int len;
+
+   switch (type) {
+   case V4L2_DEBUGFS_IF_AVI:
+   index = 0;
+   break;
+   case V4L2_DEBUGFS_IF_AUDIO:
+   index = 1;
+   break;
+   case V4L2_DEBUGFS_IF_SPD:
+   index = 2;
+   break;
+   default:
+   return 0;
+   }
+   len = read_infoframe(sd, &cri[index], buf);
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+   return len < 0 ? 0 : len;
+}
+
 static int adv7511_registered(struct v4l2_subdev *sd)
 {
struct adv7511_state *state = get_adv7511_state(sd);
@@ -1700,9 +1746,16 @@ static int adv7511_registered(struct v4l2_subdev *sd)
int err;
 
err = cec_register_adapter(state->cec_adap, &client->dev);
-  

[RFC PATCH 7/7] media: i2c: tc358743: export InfoFrames to debugfs

2024-08-21 Thread Hans Verkuil
Export InfoFrames to debugfs.

Signed-off-by: Hans Verkuil 
---
 drivers/media/i2c/tc358743.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 65d58ddf0287..c7652c0dbaeb 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -87,6 +87,10 @@ struct tc358743_state {
struct timer_list timer;
struct work_struct work_i2c_poll;
 
+   /* debugfs */
+   struct dentry *debugfs_dir;
+   struct v4l2_debugfs_if *infoframes;
+
/* edid  */
u8 edid_blocks_written;
 
@@ -430,12 +434,35 @@ static void tc358743_erase_bksv(struct v4l2_subdev *sd)
 
 /* --- AVI infoframe --- */
 
+static ssize_t
+tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
+char __user *ubuf, size_t count, loff_t *ppos)
+{
+   u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+   struct v4l2_subdev *sd = priv;
+   int len;
+
+   if (!is_hdmi(sd))
+   return 0;
+
+   if (type != V4L2_DEBUGFS_IF_AVI)
+   return 0;
+
+   i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_16BYTE - PK_AVI_0HEAD + 1);
+   len = buf[2] + 3;
+   if (len > V4L2_DEBUGFS_IF_MAX_LEN)
+   len = -ENOENT;
+   if (len > 0)
+   len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+   return len < 0 ? 0 : len;
+}
+
 static void print_avi_infoframe(struct v4l2_subdev *sd)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct device *dev = &client->dev;
union hdmi_infoframe frame;
-   u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
+   u8 buffer[HDMI_INFOFRAME_SIZE(AVI)] = {};
 
if (!is_hdmi(sd)) {
v4l2_info(sd, "DVI-D signal - AVI infoframe not supported\n");
@@ -2161,6 +2188,11 @@ static int tc358743_probe(struct i2c_client *client)
if (err < 0)
goto err_work_queues;
 
+   state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+   state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+ V4L2_DEBUGFS_IF_AVI, sd,
+ tc358743_debugfs_if_read);
+
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
  client->addr << 1, client->adapter->name);
 
@@ -2188,6 +2220,8 @@ static void tc358743_remove(struct i2c_client *client)
flush_work(&state->work_i2c_poll);
}
cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+   v4l2_debugfs_if_free(state->infoframes);
+   debugfs_remove_recursive(state->debugfs_dir);
cec_unregister_adapter(state->cec_adap);
v4l2_async_unregister_subdev(sd);
v4l2_device_unregister_subdev(sd);
-- 
2.43.0



[RFC PATCH 0/7] media: export InfoFrames to debugfs

2024-08-21 Thread Hans Verkuil
Maxime added support for exporting InfoFrames to debugfs for drm,
and this series does the same for the media subsystem.

I used the same names for the InfoFrames as the drm implementation
does, and the format is the same as well. And edid-decode can be
used to parse the InfoFrames and do conformity checking.

The first two patches add helpers for this to the core framework,
and the next 5 patches add support for this to the HDMI drivers.

I tested the three adv drivers, and I hope to test the tc358743
driver at some point in the not too distant future :-)

I don't have a tda1997x available for testing, so I might decide
to just drop this.

It's RFC for now, but I think it is quite straightforward.

This is very useful for debugging received InfoFrames.

Regards,

Hans

Hans Verkuil (7):
  media: v4l2-core: add v4l2_debugfs_root()
  media: v4l2-core: add v4l2_debugfs_if_alloc/free()
  media: i2c: adv7511-v4l2: export InfoFrames to debugfs
  media: i2c: adv7604: export InfoFrames to debugfs
  media: i2c: adv7842: export InfoFrames to debugfs
  media: i2c: tda1997x: export InfoFrames to debugfs
  media: i2c: tc358743: export InfoFrames to debugfs

 drivers/media/i2c/adv7511-v4l2.c  |  91 +---
 drivers/media/i2c/adv7604.c   |  90 
 drivers/media/i2c/adv7842.c   | 120 --
 drivers/media/i2c/tc358743.c  |  36 ++-
 drivers/media/i2c/tda1997x.c  |  50 -
 drivers/media/v4l2-core/v4l2-dev.c|  14 +++
 drivers/media/v4l2-core/v4l2-dv-timings.c |  63 
 include/media/v4l2-dev.h  |  15 +++
 include/media/v4l2-dv-timings.h   |  48 +
 9 files changed, 455 insertions(+), 72 deletions(-)

-- 
2.43.0



[RFC PATCH 2/7] media: v4l2-core: add v4l2_debugfs_if_alloc/free()

2024-08-21 Thread Hans Verkuil
Add new helpers to export received or transmitted HDMI InfoFrames to
debugfs.

This complements similar code in drm where the transmitted HDMI infoframes
are exported to debugfs.

The same names have been used as in drm, so this is consistent.

The exported infoframes can be parsed with the edid-decode utility.

Signed-off-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-dv-timings.c | 63 +++
 include/media/v4l2-dv-timings.h   | 48 +
 2 files changed, 111 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c 
b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 942d0005c55e..86a8627f4bcc 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -1154,3 +1154,66 @@ int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, 
u16 *port)
return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_phys_addr_validate);
+
+#ifdef CONFIG_DEBUG_FS
+
+#define DEBUGFS_FOPS(type, flag)   \
+static ssize_t \
+infoframe_read_##type(struct file *filp,   \
+ char __user *ubuf, size_t count, loff_t *ppos)\
+{  \
+   struct v4l2_debugfs_if *infoframes = filp->private_data;\
+   \
+   return infoframes->if_read((flag), infoframes->priv, filp,  \
+  ubuf, count, ppos);  \
+}  \
+   \
+static const struct file_operations infoframe_##type##_fops = {
\
+   .owner   = THIS_MODULE, \
+   .open= simple_open, \
+   .read= infoframe_read_##type,   \
+}
+
+DEBUGFS_FOPS(avi, V4L2_DEBUGFS_IF_AVI);
+DEBUGFS_FOPS(audio, V4L2_DEBUGFS_IF_AUDIO);
+DEBUGFS_FOPS(spd, V4L2_DEBUGFS_IF_SPD);
+DEBUGFS_FOPS(hdmi, V4L2_DEBUGFS_IF_HDMI);
+
+struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 
if_types,
+ void *priv,
+ v4l2_debugfs_if_read_t if_read)
+{
+   struct v4l2_debugfs_if *infoframes;
+
+   if (IS_ERR_OR_NULL(root) || !if_types || !if_read)
+   return NULL;
+
+   infoframes = kzalloc(sizeof(*infoframes), GFP_KERNEL);
+   if (!infoframes)
+   return NULL;
+
+   infoframes->if_dir = debugfs_create_dir("infoframes", root);
+   infoframes->priv = priv;
+   infoframes->if_read = if_read;
+   if (if_types & V4L2_DEBUGFS_IF_AVI)
+   debugfs_create_file("avi", 0400, infoframes->if_dir, 
infoframes, &infoframe_avi_fops);
+   if (if_types & V4L2_DEBUGFS_IF_AUDIO)
+   debugfs_create_file("audio", 0400, infoframes->if_dir, 
infoframes, &infoframe_audio_fops);
+   if (if_types & V4L2_DEBUGFS_IF_SPD)
+   debugfs_create_file("spd", 0400, infoframes->if_dir, 
infoframes, &infoframe_spd_fops);
+   if (if_types & V4L2_DEBUGFS_IF_HDMI)
+   debugfs_create_file("hdmi", 0400, infoframes->if_dir, 
infoframes, &infoframe_hdmi_fops);
+   return infoframes;
+}
+EXPORT_SYMBOL_GPL(v4l2_debugfs_if_alloc);
+
+void v4l2_debugfs_if_free(struct v4l2_debugfs_if *infoframes)
+{
+   if (infoframes) {
+   debugfs_remove_recursive(infoframes->if_dir);
+   kfree(infoframes);
+   }
+}
+EXPORT_SYMBOL_GPL(v4l2_debugfs_if_free);
+
+#endif
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 8fa963326bf6..13830411bd6c 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -8,6 +8,7 @@
 #ifndef __V4L2_DV_TIMINGS_H
 #define __V4L2_DV_TIMINGS_H
 
+#include 
 #include 
 
 /**
@@ -251,4 +252,51 @@ void v4l2_set_edid_phys_addr(u8 *edid, unsigned int size, 
u16 phys_addr);
 u16 v4l2_phys_addr_for_input(u16 phys_addr, u8 input);
 int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
 
+/* Add support for exporting InfoFrames to debugfs */
+
+/*
+ * HDMI InfoFrames start with a 3 byte header, then a checksum,
+ * followed by the actual IF payload.
+ *
+ * The payload length is limited to 30 bytes according to the HDMI spec,
+ * but since the length is encoded in 5 bits, it can be 31 bytes theoretically.
+ * So set the max length as 31 + 3 (header) + 1 (checksum) = 35.
+ */
+#define V4L2_DEBUGFS_IF_MAX_LEN (35)
+
+#define V4L2_DEBUGFS_IF_AVIBIT(0)
+#define V4L2_DEBUGFS_IF_AUDIO  BIT(1)
+#define V4L2_DEBUGFS_IF_SPD

Re: [PATCH v15 00/29] drm/connector: Create HDMI Connector infrastructure

2024-07-31 Thread Hans Verkuil
Hi Maxime,

On 27/05/2024 15:57, Maxime Ripard wrote:


> Hans Verkuil also expressed interest in implementing a mechanism in v4l2
> to retrieve infoframes from HDMI receiver and implementing a tool to
> decode (and eventually check) infoframes. His current work on
> edid-decode to enable that based on that series can be found here:
> https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil

Since this patch series is now merged in mainline I also pushed support
for parsing InfoFrames to the edid-decode git repo.

I believe the parsing part of the InfoFrames is complete, but the conformity
checks for the AVI and HDMI InfoFrames are still work-in-progress. But it
should be easier to develop this now that is merged.

The git repo for edid-decode is here: https://git.linuxtv.org/edid-decode.git/

I added test files to the test/if directory, and if you run:

edid-decode -I audio.test -I avi.test -I vendor.test -I spd.test edid.test -c

you'll get the output below.

Regards,

Hans

edid-decode (hex):

00 ff ff ff ff ff ff 00 4c 2d 01 0c 01 06 00 01
2a 18 01 03 80 69 3b 78 0a 23 ad a4 54 4d 99 26
0f 47 4a bd ef 80 71 4f 81 c0 81 00 81 80 95 00
a9 c0 b3 00 01 01 08 e8 00 30 f2 70 5a 80 b0 58
8a 00 50 1d 74 00 00 1e 02 3a 80 18 71 38 2d 40
58 2c 45 00 50 1d 74 00 00 1e 00 00 00 fd 00 18
4b 0f 87 3c 00 0a 20 20 20 20 20 20 00 00 00 fc
00 53 41 4d 53 55 4e 47 0a 20 20 20 20 20 01 56

02 03 58 f1 57 61 10 1f 04 13 05 14 20 21 22 5d
5e 5f 60 65 66 62 63 64 07 16 03 12 29 09 07 07
15 07 50 3d 04 c0 83 01 00 00 e2 00 0f e3 05 c0
00 76 03 0c 00 30 00 b8 3c 21 d0 88 01 02 03 04
01 40 3f ff 50 60 80 90 67 d8 5d c4 01 78 80 03
e3 06 05 01 e3 0f 01 e0 01 1d 80 d0 72 1c 16 20
10 2c 25 80 50 1d 74 00 00 9e 66 21 56 aa 51 00
1e 30 46 8f 33 00 50 1d 74 00 00 1e 00 00 00 86



Block 0, Base EDID:
  EDID Structure Version & Revision: 1.3
  Vendor & Product Identification:
Manufacturer: SAM
Model: 3073
Serial Number: 16778753 (0x01000601)
Made in: week 42 of 2014
  Basic Display Parameters & Features:
Digital display
Maximum image size: 105 cm x 59 cm
Gamma: 2.20
RGB color display
First detailed timing is the preferred timing
  Color Characteristics:
Red  : 0.6406, 0.3300
Green: 0.3007, 0.6005
Blue : 0.1503, 0.0605
White: 0.2802, 0.2900
  Established Timings I & II:
IBM :   720x40070.081663 Hz   9:5 31.467 kHz 28.32 MHz
DMT 0x04:   640x48059.940476 Hz   4:3 31.469 kHz 25.175000 MHz
Apple   :   640x48066.67 Hz   4:3 35.000 kHz 30.24 MHz
DMT 0x05:   640x48072.808802 Hz   4:3 37.861 kHz 31.50 MHz
DMT 0x06:   640x48075.00 Hz   4:3 37.500 kHz 31.50 MHz
DMT 0x09:   800x60060.316541 Hz   4:3 37.879 kHz 40.00 MHz
DMT 0x0a:   800x60072.187572 Hz   4:3 48.077 kHz 50.00 MHz
DMT 0x0b:   800x60075.00 Hz   4:3 46.875 kHz 49.50 MHz
Apple   :   832x62474.551266 Hz   4:3 49.726 kHz 57.284000 MHz
DMT 0x10:  1024x76860.003840 Hz   4:3 48.363 kHz 65.00 MHz
DMT 0x11:  1024x76870.069359 Hz   4:3 56.476 kHz 75.00 MHz
DMT 0x12:  1024x76875.028582 Hz   4:3 60.023 kHz 78.75 MHz
DMT 0x24:  1280x1024   75.024675 Hz   5:4 79.976 kHz135.00 MHz
Apple   :  1152x87075.061550 Hz 192:145   68.681 kHz100.00 MHz
  Standard Timings:
DMT 0x15:  1152x86475.00 Hz   4:3 67.500 kHz108.00 MHz
DMT 0x55:  1280x72060.00 Hz  16:9 45.000 kHz 74.25 MHz
DMT 0x1c:  1280x80059.810326 Hz  16:1049.702 kHz 83.50 MHz
DMT 0x23:  1280x1024   60.019740 Hz   5:4 63.981 kHz108.00 MHz
DMT 0x2f:  1440x90059.887445 Hz  16:1055.935 kHz106.50 MHz
DMT 0x53:  1600x90060.00 Hz  16:9 60.000 kHz108.00 MHz 
(RB)
DMT 0x3a:  1680x1050   59.954250 Hz  16:1065.290 kHz146.25 MHz
  Detailed Timing Descriptors:
DTD 1:  3840x2160   60.00 Hz  16:9135.000 kHz594.00 MHz 
(1872 mm x 1053 mm)
 Hfront  176 Hsync  88 Hback  296 Hpol P
 Vfront8 Vsync  10 Vback   72 Vpol P
DTD 2:  1920x1080   60.00 Hz  16:9 67.500 kHz148.50 MHz 
(1872 mm x 1053 mm)
 Hfront   88 Hsync  44 Hback  148 Hpol P
 Vfront4 Vsync   5 Vback   36 Vpol P
Display Range Limits:
  Monitor ranges (GTF): 24-75 Hz V, 15-135 kHz H, max dotclock 600 MHz
Display Product Name: 'SAMSUNG'
  Extension blocks: 1
Checksum: 0x56



Block 1, CTA-861 Extension Block:
  Revision: 3
  Underscans IT Video Formats by default
  Basic audio support
  Supports YCbCr 4:4:4
  Supports YCbCr 4:2:2
  Native detailed modes: 1
  Video Data Block:
VIC  97:  3840x2160   60.00 Hz  16:

Re: [PATCH v7 02/28] v4l2: handle restricted memory flags in queue setup

2024-07-20 Thread Hans Verkuil
On 20/07/2024 09:15, Yunfei Dong wrote:
> From: Jeffrey Kardatzke 
> 
> Validates the restricted memory flags when setting up a queue and
> ensures the queue has the proper capability.
> 
> Signed-off-by: Jeffrey Kardatzke 
> Signed-off-by: Yunfei Dong 
> [Yunfei: Change reviewer's comments]
> ---
>  .../media/common/videobuf2/videobuf2-core.c   | 29 +++
>  .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++-
>  2 files changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
> b/drivers/media/common/videobuf2/videobuf2-core.c
> index 0217392fcc0d..44080121f37e 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -830,6 +830,23 @@ static bool verify_coherency_flags(struct vb2_queue *q, 
> bool non_coherent_mem)
>   return true;
>  }
>  
> +static bool verify_restricted_mem_flags(struct vb2_queue *q, bool 
> restricted_mem)
> +{
> + if (restricted_mem != q->restricted_mem) {
> + dprintk(q, 1, "restricted memory model mismatch\n");
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static inline int restricted_mem_mismatch(bool restricted_mem, struct 
> vb2_queue *q,
> +   enum vb2_memory memory)
> +{
> + return restricted_mem && (!q->allow_restricted_mem || memory != 
> VB2_MEMORY_DMABUF) ?
> +-1 : 0;
> +}
> +
>  static int vb2_core_allocated_buffers_storage(struct vb2_queue *q)
>  {
>   if (!q->bufs)
> @@ -863,6 +880,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   unsigned int q_num_bufs = vb2_get_num_buffers(q);
>   unsigned plane_sizes[VB2_MAX_PLANES] = { };
>   bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
> + bool restricted_mem = flags & V4L2_MEMORY_FLAG_RESTRICTED;
>   unsigned int i, first_index;
>   int ret = 0;
>  
> @@ -906,6 +924,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   return 0;
>   }
>  
> + if (restricted_mem_mismatch(restricted_mem, q, memory))
> + return -EINVAL;
> +
>   /*
>* Make sure the requested values and current defaults are sane.
>*/
> @@ -923,6 +944,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   if (ret)
>   return ret;
>   set_queue_coherency(q, non_coherent_mem);
> + q->restricted_mem = restricted_mem;
>  
>   /*
>* Ask the driver how many buffers and planes per buffer it requires.
> @@ -1031,6 +1053,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   unsigned plane_sizes[VB2_MAX_PLANES] = { };
>   bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
>   unsigned int q_num_bufs = vb2_get_num_buffers(q);
> + bool restricted_mem = flags & V4L2_MEMORY_FLAG_RESTRICTED;
>   bool no_previous_buffers = !q_num_bufs;
>   int ret = 0;
>  
> @@ -1039,6 +1062,9 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   return -ENOBUFS;
>   }
>  
> + if (restricted_mem_mismatch(restricted_mem, q, memory))
> + return -EINVAL;
> +
>   if (no_previous_buffers) {
>   if (q->waiting_in_dqbuf && *count) {
>   dprintk(q, 1, "another dup()ped fd is waiting for a 
> buffer\n");
> @@ -1057,6 +1083,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   return ret;
>   q->waiting_for_buffers = !q->is_output;
>   set_queue_coherency(q, non_coherent_mem);
> + q->restricted_mem = restricted_mem;
>   } else {
>   if (q->memory != memory) {
>   dprintk(q, 1, "memory model mismatch\n");
> @@ -1064,6 +1091,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   }
>   if (!verify_coherency_flags(q, non_coherent_mem))
>   return -EINVAL;
> + if (!verify_restricted_mem_flags(q, restricted_mem))
> + return -EINVAL;
>   }
>  
>   num_buffers = min(*count, q->max_num_buffers - q_num_bufs);
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
> b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 293f3d5f1c4e..9ee24e537e0c 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -682,7 +682,7 @@ static void vb2_set_flags_and_caps(struct vb2_queue *q, 
> u32 memory,
>   *flags = 0;

Hmm, unless I am mistaken, this clears all flags. So if memory is DMABUF, then
the V4L2_MEMORY_FLAG_RESTRICTED is just overwritten with 0. And that's what will
be passed to vb2_core_reqbufs.

So how can this work? I'm not sure how you can have tested this.

In any case, this function should change and do 

Re: [PATCH v7 03/28] media: videobuf2: calculate restricted memory size

2024-07-20 Thread Hans Verkuil
On 20/07/2024 09:15, Yunfei Dong wrote:
> Getting the physical address with sg_dma_address for restricted memory,
> only return the first physical address size since sg may not be physical
> continuous, then leading to the dmabuf size is small than buf size. Need
> to bypass continuous checking for restricted memory.
> 
> Signed-off-by: Yunfei Dong 
> ---
>  .../common/videobuf2/videobuf2-dma-contig.c   | 34 +++
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c 
> b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> index 3d4fd4ef5310..f0e4652b615f 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> @@ -66,6 +66,22 @@ static unsigned long vb2_dc_get_contiguous_size(struct 
> sg_table *sgt)
>   return size;
>  }
>  
> +/**/
> +/*   restricted mem scatterlist table functions   */
> +/**/
> +
> +static unsigned long vb2_dc_get_res_mem_contiguous_size(struct sg_table *sgt)
> +{
> + struct scatterlist *s;
> + unsigned int i;
> + unsigned long size = 0;
> +
> + for_each_sgtable_dma_sg(sgt, s, i)
> + size += sg_dma_len(s);
> +
> + return size;
> +}

I think it is better to add a 'bool restricted' argument to 
vb2_dc_get_contiguous_size.
If true, then skip the 'expected' check there.

> +
>  /*/
>  /* callbacks for all buffers */
>  /*/
> @@ -648,10 +664,13 @@ static void *vb2_dc_get_userptr(struct vb2_buffer *vb, 
> struct device *dev,
>   goto fail_sgt_init;
>   }
>  
> - contig_size = vb2_dc_get_contiguous_size(sgt);
> + if (buf->vb->vb2_queue->restricted_mem)

I think it is better to do the same as with buf->non_coherent_mem,
so add a 'bool restricted_mem' to struct vb2_dc_buf and set it in
vb2_dc_alloc(). It makes this code easier to read.

> + contig_size = vb2_dc_get_res_mem_contiguous_size(sgt);
> + else
> + contig_size = vb2_dc_get_contiguous_size(sgt);
>   if (contig_size < size) {
> - pr_err("contiguous mapping is too small %lu/%lu\n",
> - contig_size, size);
> + pr_err("contiguous mapping is too small %lu/%lu/%u\n",
> +contig_size, size, buf->vb->vb2_queue->restricted_mem);

Rather than add a "/%u", which is not easy to understand, perhaps do this:

pr_err("%scontiguous mapping is too small %lu/%lu\n",
   buf->vb->vb2_queue->restricted_mem ? "restricted " : "",
   contig_size, size);

>   ret = -EFAULT;
>   goto fail_map_sg;
>   }
> @@ -711,10 +730,13 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
>   }
>  
>   /* checking if dmabuf is big enough to store contiguous chunk */
> - contig_size = vb2_dc_get_contiguous_size(sgt);
> + if (buf->vb->vb2_queue->restricted_mem)
> + contig_size = vb2_dc_get_res_mem_contiguous_size(sgt);
> + else
> + contig_size = vb2_dc_get_contiguous_size(sgt);
>   if (contig_size < buf->size) {
> - pr_err("contiguous chunk is too small %lu/%lu\n",
> -contig_size, buf->size);
> + pr_err("contiguous chunk is too small %lu/%lu/%u\n",
> +contig_size, buf->size, 
> buf->vb->vb2_queue->restricted_mem);

Ditto.

>   dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt,
> buf->dma_dir);
>   return -EFAULT;

Regards,

Hans


Re: [PATCH v7 02/28] v4l2: handle restricted memory flags in queue setup

2024-07-20 Thread Hans Verkuil
On 20/07/2024 09:15, Yunfei Dong wrote:
> From: Jeffrey Kardatzke 
> 
> Validates the restricted memory flags when setting up a queue and
> ensures the queue has the proper capability.
> 
> Signed-off-by: Jeffrey Kardatzke 
> Signed-off-by: Yunfei Dong 
> [Yunfei: Change reviewer's comments]
> ---
>  .../media/common/videobuf2/videobuf2-core.c   | 29 +++
>  .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++-
>  2 files changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
> b/drivers/media/common/videobuf2/videobuf2-core.c
> index 0217392fcc0d..44080121f37e 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -830,6 +830,23 @@ static bool verify_coherency_flags(struct vb2_queue *q, 
> bool non_coherent_mem)
>   return true;
>  }
>  
> +static bool verify_restricted_mem_flags(struct vb2_queue *q, bool 
> restricted_mem)
> +{
> + if (restricted_mem != q->restricted_mem) {
> + dprintk(q, 1, "restricted memory model mismatch\n");
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static inline int restricted_mem_mismatch(bool restricted_mem, struct 
> vb2_queue *q,
> +   enum vb2_memory memory)
> +{
> + return restricted_mem && (!q->allow_restricted_mem || memory != 
> VB2_MEMORY_DMABUF) ?
> +-1 : 0;

Returning -1 is odd, just return a bool here.

> +}
> +
>  static int vb2_core_allocated_buffers_storage(struct vb2_queue *q)
>  {
>   if (!q->bufs)
> @@ -863,6 +880,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   unsigned int q_num_bufs = vb2_get_num_buffers(q);
>   unsigned plane_sizes[VB2_MAX_PLANES] = { };
>   bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
> + bool restricted_mem = flags & V4L2_MEMORY_FLAG_RESTRICTED;
>   unsigned int i, first_index;
>   int ret = 0;
>  
> @@ -906,6 +924,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   return 0;
>   }
>  
> + if (restricted_mem_mismatch(restricted_mem, q, memory))
> + return -EINVAL;
> +
>   /*
>* Make sure the requested values and current defaults are sane.
>*/
> @@ -923,6 +944,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   if (ret)
>   return ret;
>   set_queue_coherency(q, non_coherent_mem);
> + q->restricted_mem = restricted_mem;
>  
>   /*
>* Ask the driver how many buffers and planes per buffer it requires.
> @@ -1031,6 +1053,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   unsigned plane_sizes[VB2_MAX_PLANES] = { };
>   bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
>   unsigned int q_num_bufs = vb2_get_num_buffers(q);
> + bool restricted_mem = flags & V4L2_MEMORY_FLAG_RESTRICTED;
>   bool no_previous_buffers = !q_num_bufs;
>   int ret = 0;
>  
> @@ -1039,6 +1062,9 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   return -ENOBUFS;
>   }
>  
> + if (restricted_mem_mismatch(restricted_mem, q, memory))
> + return -EINVAL;
> +
>   if (no_previous_buffers) {
>   if (q->waiting_in_dqbuf && *count) {
>   dprintk(q, 1, "another dup()ped fd is waiting for a 
> buffer\n");
> @@ -1057,6 +1083,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   return ret;
>   q->waiting_for_buffers = !q->is_output;
>   set_queue_coherency(q, non_coherent_mem);
> + q->restricted_mem = restricted_mem;
>   } else {
>   if (q->memory != memory) {
>   dprintk(q, 1, "memory model mismatch\n");
> @@ -1064,6 +1091,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   }
>   if (!verify_coherency_flags(q, non_coherent_mem))
>   return -EINVAL;
> + if (!verify_restricted_mem_flags(q, restricted_mem))
> + return -EINVAL;
>   }
>  
>   num_buffers = min(*count, q->max_num_buffers - q_num_bufs);
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
> b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 293f3d5f1c4e..9ee24e537e0c 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -682,7 +682,7 @@ static void vb2_set_flags_and_caps(struct vb2_queue *q, 
> u32 memory,
>   *flags = 0;
>   } else {
>   /* Clear all unknown flags. */
> - *flags &= V4L2_MEMORY_FLAG_NON_COHERENT;
> + *flags &= V4L2_MEMORY_FLAG_NON_COHERENT | 
> V4L2_MEMORY_FLAG_RESTRICTED;
>   }
>  
>   *caps |= V4L2_BUF_CAP_SUPP

Re: [PATCH v7 01/28] v4l2: add restricted memory flags

2024-07-20 Thread Hans Verkuil
Hi Yunfei,

First a high-level comment:

Adding a new V4L2 uAPI also requires patches to v4l-utils, specifically v4l2-ctl
and v4l2-compliance (i.e. new tests are needed for this flag). This will also 
help
you test the driver.

Some more comments below:

On 20/07/2024 09:15, Yunfei Dong wrote:
> From: Jeffrey Kardatzke 
> 
> Adds a V4L2 flag which indicates that a queue is using restricted
> dmabufs and the corresponding capability flag.
> 
> Signed-off-by: Jeffrey Kardatzke 
> Signed-off-by: Yunfei Dong 
> [Yunfei: Change reviewer's comments]
> ---
>  Documentation/userspace-api/media/v4l/buffer.rst   | 10 +-
>  .../userspace-api/media/v4l/vidioc-reqbufs.rst |  6 ++
>  include/media/videobuf2-core.h |  8 +++-
>  include/uapi/linux/videodev2.h |  2 ++
>  4 files changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
> b/Documentation/userspace-api/media/v4l/buffer.rst
> index 52bbee81c080..901eb007aae8 100644
> --- a/Documentation/userspace-api/media/v4l/buffer.rst
> +++ b/Documentation/userspace-api/media/v4l/buffer.rst
> @@ -696,7 +696,7 @@ enum v4l2_memory
>  
>  .. _memory-flags:
>  
> -Memory Consistency Flags
> +Memory Flags
>  
>  
>  .. raw:: latex
> @@ -728,6 +728,14 @@ Memory Consistency Flags
>   only if the buffer is used for :ref:`memory mapping ` I/O and the
>   queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
>   ` capability.
> +* .. _`V4L2-MEMORY-FLAG-RESTRICTED`:
> +
> +  - ``V4L2_MEMORY_FLAG_RESTRICTED``
> +  - 0x0002
> +  - The queued buffers are expected to be in restricted memory. If not, 
> an
> + error will be returned. This flag can only be used with 
> ``V4L2_MEMORY_DMABUF``.
> + Typically restricted buffers are allocated using a restricted dma-heap. 
> This flag
> + can only be specified if the 
> :ref:`V4L2_BUF_CAP_SUPPORTS_RESTRICTED_MEM` is set.
>  
>  .. raw:: latex
>  
> diff --git a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst 
> b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst
> index bbc22dd76032..8a264ae08db1 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst
> @@ -122,6 +122,7 @@ aborting or finishing any DMA in progress, an implicit
>  .. _V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS:
>  .. _V4L2-BUF-CAP-SUPPORTS-MAX-NUM-BUFFERS:
>  .. _V4L2-BUF-CAP-SUPPORTS-REMOVE-BUFS:
> +.. _V4L2-BUF-CAP-SUPPORTS-RESTRICTED_MEM:
>  
>  .. raw:: latex
>  
> @@ -166,6 +167,11 @@ aborting or finishing any DMA in progress, an implicit
>  :ref:`V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 
> `,
>  :ref:`V4L2_BUF_FLAG_NO_CACHE_CLEAN ` 
> and
>  :ref:`V4L2_MEMORY_FLAG_NON_COHERENT `.
> +* - ``V4L2_BUF_CAP_SUPPORTS_RESTRICTED_MEM``
> +  - 0x0100
> +  - This capability is set by the driver to indicate the queue supports
> +restricted memory. See
> +:ref:`V4L2_MEMORY_FLAG_RESTRICTED `.
>  
>  .. raw:: latex
>  

What is missing in this documentation is what error to expect if you queue a 
buffer
from non-restricted memory to a driver configured for restricted memory. You 
probably
want a specific error code for that (EACCES? EPERM?).

Regards,

Hans

> diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
> index 955237ac503d..afd497e93a37 100644
> --- a/include/media/videobuf2-core.h
> +++ b/include/media/videobuf2-core.h
> @@ -517,6 +517,9 @@ struct vb2_buf_ops {
>   *   ->finish().
>   * @non_coherent_mem: when set queue will attempt to allocate buffers using
>   *   non-coherent memory.
> + * @allow_restricted_mem: when set user-space can pass the 
> %V4L2_MEMORY_FLAG_RESTRICTED
> + *   flag to indicate the dma bufs are restricted.
> + * @restricted_mem: when set queue will verify that the dma bufs are 
> restricted.
>   * @lock:pointer to a mutex that protects the &struct vb2_queue. The
>   *   driver can set this to a mutex to let the v4l2 core serialize
>   *   the queuing ioctls. If the driver wants to handle locking
> @@ -621,6 +624,8 @@ struct vb2_queue {
>   unsigned intuses_requests:1;
>   unsigned intallow_cache_hints:1;
>   unsigned intnon_coherent_mem:1;
> + unsigned intallow_restricted_mem:1;
> + unsigned intrestricted_mem:1;
>  
>   struct mutex*lock;
>   void*owner;
> @@ -792,7 +797,8 @@ void vb2_core_querybuf(struct vb2_queue *q, struct 
> vb2_buffer *vb, void *pb);
>   * @q:   pointer to &struct vb2_queue with videobuf2 queue.
>   * @memory:  memory type, as defined by &enum vb2_memory.
>   * @flags:   auxiliary queue/buffer management flags. Currently, the only

Re: [PATCH] media: videobuf2: sync caches for dmabuf memory

2024-06-19 Thread Hans Verkuil
On 19/06/2024 06:19, Tomasz Figa wrote:
> On Wed, Jun 19, 2024 at 1:24 AM Nicolas Dufresne  wrote:
>>
>> Le mardi 18 juin 2024 à 16:47 +0900, Tomasz Figa a écrit :
>>> Hi TaoJiang,
>>>
>>> On Tue, Jun 18, 2024 at 4:30 PM TaoJiang  wrote:

 From: Ming Qian 

 When the memory type is VB2_MEMORY_DMABUF, the v4l2 device can't know
 whether the dma buffer is coherent or synchronized.

 The videobuf2-core will skip cache syncs as it think the DMA exporter
 should take care of cache syncs

 But in fact it's likely that the client doesn't
 synchronize the dma buf before qbuf() or after dqbuf(). and it's
 difficult to find this type of error directly.

 I think it's helpful that videobuf2-core can call
 dma_buf_end_cpu_access() and dma_buf_begin_cpu_access() to handle the
 cache syncs.

 Signed-off-by: Ming Qian 
 Signed-off-by: TaoJiang 
 ---
  .../media/common/videobuf2/videobuf2-core.c   | 22 +++
  1 file changed, 22 insertions(+)

>>>
>>> Sorry, that patch is incorrect. I believe you're misunderstanding the
>>> way DMA-buf buffers should be managed in the userspace. It's the
>>> userspace responsibility to call the DMA_BUF_IOCTL_SYNC ioctl [1] to
>>> signal start and end of CPU access to the kernel and imply necessary
>>> cache synchronization.
>>>
>>> [1] https://docs.kernel.org/driver-api/dma-buf.html#dma-buffer-ioctls
>>>
>>> So, really sorry, but it's a NAK.
>>
>>
>>
>> This patch *could* make sense if it was inside UVC Driver as an example, as 
>> this
>> driver can import dmabuf, to CPU memcpy, and does omits the required sync 
>> calls
>> (unless that got added recently, I can easily have missed it).
> 
> Yeah, currently V4L2 drivers don't call the in-kernel
> dma_buf_{begin,end}_cpu_access() when they need to access the buffers
> from the CPU, while my quick grep [1] reveals that we have 68 files
> retrieving plane vaddr by calling vb2_plane_vaddr() (not necessarily a
> 100% guarantee of CPU access being done, but rather likely so).
> 
> I also repeated the same thing with VB2_DMABUF [2] and tried to
> attribute both lists to specific drivers (by retaining the path until
> the first - or _ [3]; which seemed to be relatively accurate), leading
> to the following drivers that claim support for DMABUF while also
> retrieving plane vaddr (without proper synchronization - no drivers
> currently call any begin/end CPU access):
> 
>  i2c/video
>  pci/bt8xx/bttv
>  pci/cobalt/cobalt
>  pci/cx18/cx18
>  pci/tw5864/tw5864
>  pci/tw686x/tw686x
>  platform/allegro
>  platform/amphion/vpu
>  platform/chips
>  platform/intel/pxa
>  platform/marvell/mcam
>  platform/mediatek/jpeg/mtk
>  platform/mediatek/vcodec/decoder/mtk
>  platform/mediatek/vcodec/encoder/mtk
>  platform/nuvoton/npcm
>  platform/nvidia/tegra
>  platform/nxp/imx
>  platform/renesas/rcar
>  platform/renesas/vsp1/vsp1
>  platform/rockchip/rkisp1/rkisp1
>  platform/samsung/exynos4
>  platform/samsung/s5p
>  platform/st/sti/delta/delta
>  platform/st/sti/hva/hva
>  platform/verisilicon/hantro
>  usb/au0828/au0828
>  usb/cx231xx/cx231xx
>  usb/dvb
>  usb/em28xx/em28xx
>  usb/gspca/gspca.c
>  usb/hackrf/hackrf.c
>  usb/stk1160/stk1160
>  usb/uvc/uvc
> 
> which means we potentially have ~30 drivers which likely don't handle
> imported DMABUFs correctly (there is still a chance that DMABUF is
> advertised for one queue, while vaddr is used for another).
> 
> I think we have two options:
> 1) add vb2_{begin/end}_cpu_access() helpers, carefully audit each
> driver and add calls to those

I actually started on that 9 (!) years ago:

https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=vb2-cpu-access

If memory serves, the main problem was that there were some drivers where
it wasn't clear what should be done. In the end I never continued this
work since nobody complained about it.

This patch series adds vb2_plane_begin/end_cpu_access() functions,
replaces all calls to vb2_plane_vaddr() in drivers to the new functions,
and at the end removes vb2_plane_vaddr() altogether.

> 2) take a heavy gun approach and just call vb2_begin_cpu_access()
> whenever vb2_plane_vaddr() is called and then vb2_end_cpu_access()
> whenever vb2_buffer_done() is called (if begin was called before).
> 
> The latter has the disadvantage of drivers not having control over the
> timing of the cache sync, so could end up with less than optimal
> performance. Also there could be some more complex cases, where the
> driver needs to mix DMA and CPU accesses to the buffer, so the fixed
> sequence just wouldn't work for them. (But then they just wouldn't
> work today either.)
> 
> Hans, Marek, do you have any thoughts? (I'd personally just go with 2
> and if any driver in the future needs something else, they could call
> begin/end CPU access manually.)

I prefer 1. If nothing else, that makes it easy to identify drivers
that do such things.

But perhaps a mix is possible: if a VB2 flag

Re: [PATCH v3 07/10] media: intel: Add Displayport RX IP driver

2024-06-07 Thread Hans Verkuil
On 04/06/2024 14:32, Paweł Anikiel wrote:
> On Mon, Jun 3, 2024 at 10:37 AM Hans Verkuil  wrote:
>>
>> On 07/05/2024 17:54, Paweł Anikiel wrote:
>>> Add v4l2 subdev driver for the Intel Displayport receiver FPGA IP.
>>> It is a part of the DisplayPort Intel FPGA IP Core, and supports
>>> DisplayPort 1.4, HBR3 video capture and Multi-Stream Transport.
>>>
>>> Signed-off-by: Paweł Anikiel 
>>> ---
>>>  drivers/media/platform/intel/Kconfig  |   12 +
>>>  drivers/media/platform/intel/Makefile |1 +
>>>  drivers/media/platform/intel/intel-dprx.c | 2283 +
>>>  3 files changed, 2296 insertions(+)
>>>  create mode 100644 drivers/media/platform/intel/intel-dprx.c
>>>



>>> +static int dprx_probe(struct platform_device *pdev)
>>> +{
>>> + struct dprx *dprx;
>>> + int irq;
>>> + int res;
>>> + int i;
>>> +
>>> + dprx = devm_kzalloc(&pdev->dev, sizeof(*dprx), GFP_KERNEL);
>>> + if (!dprx)
>>> + return -ENOMEM;
>>> + dprx->dev = &pdev->dev;
>>> + platform_set_drvdata(pdev, dprx);
>>> +
>>> + dprx->iobase = devm_platform_ioremap_resource(pdev, 0);
>>> + if (IS_ERR(dprx->iobase))
>>> + return PTR_ERR(dprx->iobase);
>>> +
>>> + irq = platform_get_irq(pdev, 0);
>>> + if (irq < 0)
>>> + return irq;
>>> +
>>> + res = devm_request_irq(dprx->dev, irq, dprx_isr, 0, "intel-dprx", 
>>> dprx);
>>> + if (res)
>>> + return res;
>>> +
>>> + res = dprx_parse_fwnode(dprx);
>>> + if (res)
>>> + return res;
>>> +
>>> + dprx_init_caps(dprx);
>>> +
>>> + dprx->subdev.owner = THIS_MODULE;
>>> + dprx->subdev.dev = &pdev->dev;
>>> + v4l2_subdev_init(&dprx->subdev, &dprx_subdev_ops);
>>> + v4l2_set_subdevdata(&dprx->subdev, &pdev->dev);
>>> + snprintf(dprx->subdev.name, sizeof(dprx->subdev.name), "%s %s",
>>> +  KBUILD_MODNAME, dev_name(&pdev->dev));
>>> + dprx->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
>>> +
>>> + dprx->subdev.entity.function = MEDIA_ENT_F_DV_DECODER;
>>> + dprx->subdev.entity.ops = &dprx_entity_ops;
>>> +
>>> + v4l2_ctrl_handler_init(&dprx->ctrl_handler, 1);
>>> + v4l2_ctrl_new_std(&dprx->ctrl_handler, NULL,
>>> +   V4L2_CID_DV_RX_POWER_PRESENT, 0, 1, 0, 0);
>>
>> You are creating this control, but it is never set to 1 when the driver 
>> detects
>> that a source is connected. I am wondering if POWER_PRESENT makes sense for a
>> DisplayPort connector. Is there a clean way for a sink driver to detect if a
>> source is connected? For HDMI it detects the 5V pin, but it is not clear if
>> there is an equivalent to that in the DP spec.
> 
> The DP spec says the source can be detected using the AUX lines:
> 
> "The Downstream devices must very weakly pull up AUX+ line and very
> weakly pull down AUX- line with 1MΩ (+/-5%) resistors between the
> Downstream device Connector and the AC-coupling capacitors. When AUX+
> line DC voltage is L level, it means a DisplayPort Upstream device is
> connected. When AUX- line DC voltage is H level, it means that a
> powered DisplayPort Upstream device is connected."
> 
> This exact IP has two input signals: rx_cable_detect, and
> rx_pwr_detect, which are meant to be connected to the AUX+/AUX- lines
> via 10k resistors (or rather that's what the reference design does).
> They're exposed to software via status registers, but there's no way
> to get interrupts from them, so it wouldn't be possible to set the
> control exactly when a source gets plugged in.
> 
>>
>> If there is no good way to detect if a source is connected, then it might be
>> better to drop POWER_PRESENT support.
>>
>> This control is supposed to signal that a source is connected as early as 
>> possible,
>> ideally before link training etc. starts.
>>
>> It helps the software detect that there is a source, and report an error if 
>> a source
>> is detected, but you never get a stable signal (e.g. link training fails).
> 
> This poses another problem, because the chameleon board doesn't have
> this detection circuitry, and instead sets the rx_cable_detect and
> rx_pwr_detect signals to always logical high. That would make the
> control read "always plugged in", which IIUC is not desired.

OK, so it is best to drop support for this control.

I recommend adding a comment in the source code explaining why it is not 
supported.
And in the cover letter you can mention this as well as an explanation of why
there is a v4l2-compliance warning.

Regards,

Hans


Re: [PATCH v3 01/10] media: Add Chameleon v3 video interface driver

2024-06-04 Thread Hans Verkuil
On 04/06/2024 14:03, Paweł Anikiel wrote:
> On Mon, Jun 3, 2024 at 4:56 PM Hans Verkuil  wrote:
>>
>> On 03/06/2024 16:32, Paweł Anikiel wrote:
>>> On Mon, Jun 3, 2024 at 9:57 AM Hans Verkuil  
>>> wrote:
>>>>
>>>> On 07/05/2024 17:54, Paweł Anikiel wrote:
>>>>> Add v4l2 driver for the video interface present on the Google
>>>>> Chameleon v3. The Chameleon v3 uses the video interface to capture
>>>>> a single video source from a given HDMI or DP connector and write
>>>>> the resulting frames to memory.
>>>>>
>>>>> Signed-off-by: Paweł Anikiel 
>>>>> ---
>>>>>  drivers/media/platform/Kconfig |   1 +
>>>>>  drivers/media/platform/Makefile|   1 +
>>>>>  drivers/media/platform/google/Kconfig  |  13 +
>>>>>  drivers/media/platform/google/Makefile |   3 +
>>>>>  drivers/media/platform/google/chv3-video.c | 891 +
>>>>>  5 files changed, 909 insertions(+)
>>>>>  create mode 100644 drivers/media/platform/google/Kconfig
>>>>>  create mode 100644 drivers/media/platform/google/Makefile
>>>>>  create mode 100644 drivers/media/platform/google/chv3-video.c
>>>>>
>>>>> diff --git a/drivers/media/platform/Kconfig 
>>>>> b/drivers/media/platform/Kconfig
>>>>> index 91e54215de3a..b82f7b142b85 100644
>>>>> --- a/drivers/media/platform/Kconfig
>>>>> +++ b/drivers/media/platform/Kconfig
>>>>> @@ -69,6 +69,7 @@ source "drivers/media/platform/aspeed/Kconfig"
>>>>>  source "drivers/media/platform/atmel/Kconfig"
>>>>>  source "drivers/media/platform/cadence/Kconfig"
>>>>>  source "drivers/media/platform/chips-media/Kconfig"
>>>>> +source "drivers/media/platform/google/Kconfig"
>>>>>  source "drivers/media/platform/intel/Kconfig"
>>>>>  source "drivers/media/platform/marvell/Kconfig"
>>>>>  source "drivers/media/platform/mediatek/Kconfig"
>>>>> diff --git a/drivers/media/platform/Makefile 
>>>>> b/drivers/media/platform/Makefile
>>>>> index 3296ec1ebe16..f7067eb05f76 100644
>>>>> --- a/drivers/media/platform/Makefile
>>>>> +++ b/drivers/media/platform/Makefile
>>>>> @@ -12,6 +12,7 @@ obj-y += aspeed/
>>>>>  obj-y += atmel/
>>>>>  obj-y += cadence/
>>>>>  obj-y += chips-media/
>>>>> +obj-y += google/
>>>>>  obj-y += intel/
>>>>>  obj-y += marvell/
>>>>>  obj-y += mediatek/
>>>>> diff --git a/drivers/media/platform/google/Kconfig 
>>>>> b/drivers/media/platform/google/Kconfig
>>>>> new file mode 100644
>>>>> index ..9674a4c12e2d
>>>>> --- /dev/null
>>>>> +++ b/drivers/media/platform/google/Kconfig
>>>>> @@ -0,0 +1,13 @@
>>>>> +# SPDX-License-Identifier: GPL-2.0-only
>>>>> +
>>>>> +config VIDEO_CHAMELEONV3
>>>>> + tristate "Google Chameleon v3 video driver"
>>>>> + depends on V4L_PLATFORM_DRIVERS
>>>>> + depends on VIDEO_DEV
>>>>> + select VIDEOBUF2_DMA_CONTIG
>>>>> + select V4L2_FWNODE
>>>>> + help
>>>>> +   v4l2 driver for the video interface present on the Google
>>>>> +   Chameleon v3. The Chameleon v3 uses the video interface to
>>>>> +   capture a single video source from a given HDMI or DP connector
>>>>> +   and write the resulting frames to memory.
>>>>> diff --git a/drivers/media/platform/google/Makefile 
>>>>> b/drivers/media/platform/google/Makefile
>>>>> new file mode 100644
>>>>> index ..cff06486244c
>>>>> --- /dev/null
>>>>> +++ b/drivers/media/platform/google/Makefile
>>>>> @@ -0,0 +1,3 @@
>>>>> +# SPDX-License-Identifier: GPL-2.0-only
>>>>> +
>>>>> +obj-$(CONFIG_VIDEO_CHAMELEONV3) += chv3-video.o
>>>>> diff --git a/drivers/media/platform/google/chv3-video.c 
>>>>> b/drivers/media/platform/google/chv3-video.c
>>>>> new file mode 100644
>>>>> index ..6e782484abaf
>>>>> --- /dev/null
>>>

Re: [PATCH v3 01/10] media: Add Chameleon v3 video interface driver

2024-06-03 Thread Hans Verkuil
On 03/06/2024 16:32, Paweł Anikiel wrote:
> On Mon, Jun 3, 2024 at 9:57 AM Hans Verkuil  wrote:
>>
>> On 07/05/2024 17:54, Paweł Anikiel wrote:
>>> Add v4l2 driver for the video interface present on the Google
>>> Chameleon v3. The Chameleon v3 uses the video interface to capture
>>> a single video source from a given HDMI or DP connector and write
>>> the resulting frames to memory.
>>>
>>> Signed-off-by: Paweł Anikiel 
>>> ---
>>>  drivers/media/platform/Kconfig |   1 +
>>>  drivers/media/platform/Makefile|   1 +
>>>  drivers/media/platform/google/Kconfig  |  13 +
>>>  drivers/media/platform/google/Makefile |   3 +
>>>  drivers/media/platform/google/chv3-video.c | 891 +
>>>  5 files changed, 909 insertions(+)
>>>  create mode 100644 drivers/media/platform/google/Kconfig
>>>  create mode 100644 drivers/media/platform/google/Makefile
>>>  create mode 100644 drivers/media/platform/google/chv3-video.c
>>>
>>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
>>> index 91e54215de3a..b82f7b142b85 100644
>>> --- a/drivers/media/platform/Kconfig
>>> +++ b/drivers/media/platform/Kconfig
>>> @@ -69,6 +69,7 @@ source "drivers/media/platform/aspeed/Kconfig"
>>>  source "drivers/media/platform/atmel/Kconfig"
>>>  source "drivers/media/platform/cadence/Kconfig"
>>>  source "drivers/media/platform/chips-media/Kconfig"
>>> +source "drivers/media/platform/google/Kconfig"
>>>  source "drivers/media/platform/intel/Kconfig"
>>>  source "drivers/media/platform/marvell/Kconfig"
>>>  source "drivers/media/platform/mediatek/Kconfig"
>>> diff --git a/drivers/media/platform/Makefile 
>>> b/drivers/media/platform/Makefile
>>> index 3296ec1ebe16..f7067eb05f76 100644
>>> --- a/drivers/media/platform/Makefile
>>> +++ b/drivers/media/platform/Makefile
>>> @@ -12,6 +12,7 @@ obj-y += aspeed/
>>>  obj-y += atmel/
>>>  obj-y += cadence/
>>>  obj-y += chips-media/
>>> +obj-y += google/
>>>  obj-y += intel/
>>>  obj-y += marvell/
>>>  obj-y += mediatek/
>>> diff --git a/drivers/media/platform/google/Kconfig 
>>> b/drivers/media/platform/google/Kconfig
>>> new file mode 100644
>>> index ..9674a4c12e2d
>>> --- /dev/null
>>> +++ b/drivers/media/platform/google/Kconfig
>>> @@ -0,0 +1,13 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +
>>> +config VIDEO_CHAMELEONV3
>>> + tristate "Google Chameleon v3 video driver"
>>> + depends on V4L_PLATFORM_DRIVERS
>>> + depends on VIDEO_DEV
>>> + select VIDEOBUF2_DMA_CONTIG
>>> + select V4L2_FWNODE
>>> + help
>>> +   v4l2 driver for the video interface present on the Google
>>> +   Chameleon v3. The Chameleon v3 uses the video interface to
>>> +   capture a single video source from a given HDMI or DP connector
>>> +   and write the resulting frames to memory.
>>> diff --git a/drivers/media/platform/google/Makefile 
>>> b/drivers/media/platform/google/Makefile
>>> new file mode 100644
>>> index ..cff06486244c
>>> --- /dev/null
>>> +++ b/drivers/media/platform/google/Makefile
>>> @@ -0,0 +1,3 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +
>>> +obj-$(CONFIG_VIDEO_CHAMELEONV3) += chv3-video.o
>>> diff --git a/drivers/media/platform/google/chv3-video.c 
>>> b/drivers/media/platform/google/chv3-video.c
>>> new file mode 100644
>>> index ..6e782484abaf
>>> --- /dev/null
>>> +++ b/drivers/media/platform/google/chv3-video.c
>>> @@ -0,0 +1,891 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright 2023-2024 Google LLC.
>>> + * Author: Paweł Anikiel 
>>> + */
>>> +
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +
>>> +#define DEVICE_NAME  "chv3-video"
>>> +
>>> +#define VIDEO_EN

Re: [PATCH v3 00/10] Add Chameleon v3 video support

2024-06-03 Thread Hans Verkuil
Hi Paweł,

On 07/05/2024 17:54, Paweł Anikiel wrote:
> Google Chameleon v3 is a testing device capable of emulating multiple
> DisplayPort monitors, used for testing purposes.  It is based on an Arria
> 10 SoCFPGA.  This patchset adds V4L2 drivers for two IP blocks used in the
> device's FPGA: the Chameleon v3 video interface, and the Intel DisplayPort
> RX IP.  The former is a video capture device that takes video signal and
> writes frames into memory, which can be later processed by userspace.
> The latter is a DisplayPort receiver IP from Intel, its datasheet can
> be found at:
> https://www.intel.com/programmable/technical-pdfs/683273.pdf
> 
> The video interface driver is a regular v4l2 capture device driver, while
> the DP RX driver is a v4l2 subdevice driver. In order to avoid code
> duplication, some parts of the DisplayPort code from the DRM subsystem
> were put into headers usable by the DP RX driver.
> 
> This patchset depends on changes merged into the linux-media tree at:
> git://linuxtv.org/hverkuil/media_tree.git tags/br-v6.10d
> 
> Here is the output of `v4l2-compliance -s` run on a Chameleon v3 for
> /dev/video0 (no attached subdevice):

This v3 series looks pretty good to me, so from a V4L2 perspective I believe
a v4 should be OK.

But I need Acked-by for the drm and bindings patches before I can
merge a v4.

Regards,

Hans

> 
> ```
> v4l2-compliance 1.27.0-5204, 32 bits, 32-bit time_t
> v4l2-compliance SHA: dd049328e528 2024-04-29 13:40:09
> 
> Compliance test for chv3-video device /dev/video0:
> 
> Driver Info:
>   Driver name  : chv3-video
>   Card type: Chameleon v3 video
>   Bus info : platform:c0060500.video
>   Driver version   : 6.9.0
>   Capabilities : 0x8421
>   Video Capture
>   Streaming
>   Extended Pix Format
>   Device Capabilities
>   Device Caps  : 0x0421
>   Video Capture
>   Streaming
>   Extended Pix Format
> 
> Required ioctls:
>   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
>   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
>   test VIDIOC_DV_TIMINGS_CAP: OK
>   test VIDIOC_G/S_EDID: OK (Not Supported)
> 
> Control ioctls (Input 0):
>   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: 2 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)
> 
> 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_REMOVE_BUFS: OK
>   test VIDIOC_EXPBUF: OK
>   test Requests: OK (Not Supported)
>   test TIME32/64: OK
> 
> Test input 0:
> 
> Streaming ioctls:
>   test read/write: OK (Not Supported)
>   test blocking wait: OK
>   test MMAP (no poll): OK
>   test MMAP (select): OK
>   test MMAP (epoll): OK
>   test USERPTR (no poll): OK (Not Supported)
>   test USERPTR (select): OK (Not Supported)
>   test DMABUF: Cannot test, specify --expbuf-d

Re: [PATCH v3 07/10] media: intel: Add Displayport RX IP driver

2024-06-03 Thread Hans Verkuil
On 07/05/2024 17:54, Paweł Anikiel wrote:
> Add v4l2 subdev driver for the Intel Displayport receiver FPGA IP.
> It is a part of the DisplayPort Intel FPGA IP Core, and supports
> DisplayPort 1.4, HBR3 video capture and Multi-Stream Transport.
> 
> Signed-off-by: Paweł Anikiel 
> ---
>  drivers/media/platform/intel/Kconfig  |   12 +
>  drivers/media/platform/intel/Makefile |1 +
>  drivers/media/platform/intel/intel-dprx.c | 2283 +
>  3 files changed, 2296 insertions(+)
>  create mode 100644 drivers/media/platform/intel/intel-dprx.c
> 
> diff --git a/drivers/media/platform/intel/Kconfig 
> b/drivers/media/platform/intel/Kconfig
> index 724e80a9086d..eafcd47cce68 100644
> --- a/drivers/media/platform/intel/Kconfig
> +++ b/drivers/media/platform/intel/Kconfig
> @@ -12,3 +12,15 @@ config VIDEO_PXA27x
>   select V4L2_FWNODE
>   help
> This is a v4l2 driver for the PXA27x Quick Capture Interface
> +
> +config VIDEO_INTEL_DPRX
> + tristate "Intel DisplayPort RX IP driver"
> + depends on V4L_PLATFORM_DRIVERS
> + depends on VIDEO_DEV
> + select V4L2_FWNODE
> + select CRC_DP
> + help
> +   v4l2 subdev driver for Intel Displayport receiver FPGA IP.
> +   It is a part of the DisplayPort Intel FPGA IP Core.
> +   It implements a DisplayPort 1.4 receiver capable of HBR3
> +   video capture and Multi-Stream Transport.
> diff --git a/drivers/media/platform/intel/Makefile 
> b/drivers/media/platform/intel/Makefile
> index 7e8889cbd2df..f571399f5aa8 100644
> --- a/drivers/media/platform/intel/Makefile
> +++ b/drivers/media/platform/intel/Makefile
> @@ -1,2 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
> +obj-$(CONFIG_VIDEO_INTEL_DPRX) += intel-dprx.o
> diff --git a/drivers/media/platform/intel/intel-dprx.c 
> b/drivers/media/platform/intel/intel-dprx.c
> new file mode 100644
> index ..734f6c2395bc
> --- /dev/null
> +++ b/drivers/media/platform/intel/intel-dprx.c
> @@ -0,0 +1,2283 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2023-2024 Google LLC.
> + * Author: Paweł Anikiel 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DPRX_MAX_EDID_BLOCKS 4
> +
> +/* DPRX registers */
> +
> +#define DPRX_RX_CONTROL  0x000
> +#define DPRX_RX_CONTROL_LINK_RATE_SHIFT  16
> +#define DPRX_RX_CONTROL_LINK_RATE_MASK   0xff
> +#define DPRX_RX_CONTROL_RECONFIG_LINKRATE13
> +#define DPRX_RX_CONTROL_TP_SHIFT 8
> +#define DPRX_RX_CONTROL_TP_MASK  0x7
> +#define DPRX_RX_CONTROL_SCRAMBLER_DISABLE7
> +#define DPRX_RX_CONTROL_CHANNEL_CODING_SHIFT 5
> +#define DPRX_RX_CONTROL_CHANNEL_CODING_8B10B 0x1
> +#define DPRX_RX_CONTROL_LANE_COUNT_SHIFT 0
> +#define DPRX_RX_CONTROL_LANE_COUNT_MASK  0x1f
> +
> +#define DPRX_RX_STATUS   0x001
> +#define DPRX_RX_STATUS_INTERLANE_ALIGN   8
> +#define DPRX_RX_STATUS_SYM_LOCK_SHIFT4
> +#define DPRX_RX_STATUS_SYM_LOCK(i)   (4 + i)
> +#define DPRX_RX_STATUS_CR_LOCK_SHIFT 0
> +#define DPRX_RX_STATUS_CR_LOCK(i)(0 + i)
> +
> +#define DPRX_MSA_HTOTAL(i)   (0x022 + 0x20 * (i))
> +#define DPRX_MSA_VTOTAL(i)   (0x023 + 0x20 * (i))
> +#define DPRX_MSA_HSP(i)  (0x024 + 0x20 * (i))
> +#define DPRX_MSA_HSW(i)  (0x025 + 0x20 * (i))
> +#define DPRX_MSA_HSTART(i)   (0x026 + 0x20 * (i))
> +#define DPRX_MSA_VSTART(i)   (0x027 + 0x20 * (i))
> +#define DPRX_MSA_VSP(i)  (0x028 + 0x20 * (i))
> +#define DPRX_MSA_VSW(i)  (0x029 + 0x20 * (i))
> +#define DPRX_MSA_HWIDTH(i)   (0x02a + 0x20 * (i))
> +#define DPRX_MSA_VHEIGHT(i)  (0x02b + 0x20 * (i))
> +#define DPRX_VBID(i) (0x02f + 0x20 * (i))
> +#define DPRX_VBID_MSA_LOCK   7
> +
> +#define DPRX_MST_CONTROL10x0a0
> +#define DPRX_MST_CONTROL1_VCPTAB_UPD_FORCE   31
> +#define DPRX_MST_CONTROL1_VCPTAB_UPD_REQ 30
> +#define DPRX_MST_CONTROL1_VCP_ID_SHIFT(i)(4 + 4 * (i))
> +#define DPRX_MST_CONTROL1_VCP_IDS_SHIFT  4
> +#define DPRX_MST_CONTROL1_VCP_IDS_MASK   0x
> +#define DPRX_MST_CONTROL1_MST_EN 0
> +
> +#define DPRX_MST_STATUS1 0x0a1
> +#define DPRX_MST_STATUS1_VCPTAB_ACT_ACK  30
> +
> +#define DPRX_MST_VCPTAB(i)   (0x0a2 + i)
> +
> +#define DPRX_AUX_CONTROL 0x100
> +#define DPRX_AUX_CONTROL_IRQ_EN  8
> +#define DPRX_AUX_CONTROL_TX_STROBE   7
> +#define DPRX_AUX_CONTROL_LENGTH_SHIFT 

Re: [PATCH v3 01/10] media: Add Chameleon v3 video interface driver

2024-06-03 Thread Hans Verkuil
On 07/05/2024 17:54, Paweł Anikiel wrote:
> Add v4l2 driver for the video interface present on the Google
> Chameleon v3. The Chameleon v3 uses the video interface to capture
> a single video source from a given HDMI or DP connector and write
> the resulting frames to memory.
> 
> Signed-off-by: Paweł Anikiel 
> ---
>  drivers/media/platform/Kconfig |   1 +
>  drivers/media/platform/Makefile|   1 +
>  drivers/media/platform/google/Kconfig  |  13 +
>  drivers/media/platform/google/Makefile |   3 +
>  drivers/media/platform/google/chv3-video.c | 891 +
>  5 files changed, 909 insertions(+)
>  create mode 100644 drivers/media/platform/google/Kconfig
>  create mode 100644 drivers/media/platform/google/Makefile
>  create mode 100644 drivers/media/platform/google/chv3-video.c
> 
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index 91e54215de3a..b82f7b142b85 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -69,6 +69,7 @@ source "drivers/media/platform/aspeed/Kconfig"
>  source "drivers/media/platform/atmel/Kconfig"
>  source "drivers/media/platform/cadence/Kconfig"
>  source "drivers/media/platform/chips-media/Kconfig"
> +source "drivers/media/platform/google/Kconfig"
>  source "drivers/media/platform/intel/Kconfig"
>  source "drivers/media/platform/marvell/Kconfig"
>  source "drivers/media/platform/mediatek/Kconfig"
> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
> index 3296ec1ebe16..f7067eb05f76 100644
> --- a/drivers/media/platform/Makefile
> +++ b/drivers/media/platform/Makefile
> @@ -12,6 +12,7 @@ obj-y += aspeed/
>  obj-y += atmel/
>  obj-y += cadence/
>  obj-y += chips-media/
> +obj-y += google/
>  obj-y += intel/
>  obj-y += marvell/
>  obj-y += mediatek/
> diff --git a/drivers/media/platform/google/Kconfig 
> b/drivers/media/platform/google/Kconfig
> new file mode 100644
> index ..9674a4c12e2d
> --- /dev/null
> +++ b/drivers/media/platform/google/Kconfig
> @@ -0,0 +1,13 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config VIDEO_CHAMELEONV3
> + tristate "Google Chameleon v3 video driver"
> + depends on V4L_PLATFORM_DRIVERS
> + depends on VIDEO_DEV
> + select VIDEOBUF2_DMA_CONTIG
> + select V4L2_FWNODE
> + help
> +   v4l2 driver for the video interface present on the Google
> +   Chameleon v3. The Chameleon v3 uses the video interface to
> +   capture a single video source from a given HDMI or DP connector
> +   and write the resulting frames to memory.
> diff --git a/drivers/media/platform/google/Makefile 
> b/drivers/media/platform/google/Makefile
> new file mode 100644
> index ..cff06486244c
> --- /dev/null
> +++ b/drivers/media/platform/google/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +obj-$(CONFIG_VIDEO_CHAMELEONV3) += chv3-video.o
> diff --git a/drivers/media/platform/google/chv3-video.c 
> b/drivers/media/platform/google/chv3-video.c
> new file mode 100644
> index ..6e782484abaf
> --- /dev/null
> +++ b/drivers/media/platform/google/chv3-video.c
> @@ -0,0 +1,891 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2023-2024 Google LLC.
> + * Author: Paweł Anikiel 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DEVICE_NAME  "chv3-video"
> +
> +#define VIDEO_EN 0x00
> +#define VIDEO_EN_BIT BIT(0)
> +#define VIDEO_HEIGHT 0x04
> +#define VIDEO_WIDTH  0x08
> +#define VIDEO_BUFFERA0x0c
> +#define VIDEO_BUFFERB0x10
> +#define VIDEO_BUFFERSIZE 0x14
> +#define VIDEO_RESET  0x18
> +#define VIDEO_RESET_BIT  BIT(0)
> +#define VIDEO_ERRORSTATUS0x1c
> +#define VIDEO_IOCOLOR0x20
> +#define VIDEO_DATARATE   0x24
> +#define VIDEO_DATARATE_SINGLE0x0
> +#define VIDEO_DATARATE_DOUBLE0x1
> +#define VIDEO_PIXELMODE  0x28
> +#define VIDEO_PIXELMODE_SINGLE   0x0
> +#define VIDEO_PIXELMODE_DOUBLE   0x1
> +#define VIDEO_SYNCPOLARITY   0x2c
> +#define VIDEO_DMAFORMAT  0x30
> +#define VIDEO_DMAFORMAT_8BPC 0x0
> +#define VIDEO_DMAFORMAT_10BPC_UPPER  0x1
> +#define VIDEO_DMAFORMAT_10BPC_LOWER  0x2
> +#define VIDEO_DMAFORMAT_12BPC_UPPER  0x3
> +#define VIDEO_DMAFORMAT_12BPC_LOWER  0x4
> +#define VIDEO_DMAFORMAT_16BPC0x5
> +#define VIDEO_DMAFORMAT_RAW  0x6
> +#define VIDEO_DMAFORMAT_8BPC_PAD 0x7
> +#define VIDEO_VERSION0x34
> +#define VIDEO_VERSION_CURRENT0xc0fb0001
> +
> +

Re: [PATCH v0 00/14] Make I2C terminology more inclusive for I2C Algobit and consumers

2024-04-08 Thread Hans Verkuil
On 05/04/2024 12:18, Wolfram Sang wrote:
> Hello Easwar,
> 
> On Fri, Mar 29, 2024 at 05:00:24PM +, Easwar Hariharan wrote:
>> I2C v7, SMBus 3.2, and I3C specifications have replaced "master/slave"
>> with more appropriate terms. Inspired by and following on to Wolfram's
>> series to fix drivers/i2c/[1], fix the terminology for users of the
>> I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists
>> in the specification.
> 
> I really appreciate that you want to assist in this task to improve the
> I2C core. I do. I am afraid, however, that you took the second step
> before the first one, though. As I mentioned in my original cover
> letter, this is not only about renaming but also improving the I2C API
> (splitting up header files...). So, drivers are not a priority right
> now. They can be better fixed once the core is ready.
> 
> It is true that I changed quite some controller drivers within the i2c
> realm. I did this to gain experience. As you also noticed quite some
> questions came up. We need to agree on answers first. And once we are
> happy with the answers we found, then IMO we can go outside of the i2c
> realm and send patches to other subsystems referencing agreed
> precedence. I intentionally did not go outside i2c yet. Since your
> patches are already there, you probably want to foster them until they
> are ready for inclusion. Yet, regarding further patches, my suggestion
> is to wait until the core is ready. That might take a while, though.
> However, there is enough to discuss until the core is ready. So, your
> collaboration there is highly appreciated!
> 
>> The last patch updating the .master_xfer method to .xfer depends on
>> patch 1 of Wolfram's series below, but the series is otherwise
>> independent. It may make sense for the last patch to go in with
> 
> Please drop the last patch from this series. It will nicely remove the
> dependency. Also, like above, I first want to gain experience with i2c
> before going to other subsystems. That was intended.

OK, based on this I'll mark the media patches in this series as 'Deferred'
in our patchwork.

Regards,

Hans

> 
> All the best and happy hacking,
> 
>Wolfram
> 



Re: [PATCH v7 21/36] drm/connector: hdmi: Add Broadcast RGB property

2024-03-01 Thread Hans Verkuil
On 29/02/2024 20:47, Sebastian Wick wrote:
> On Thu, Feb 22, 2024 at 07:14:07PM +0100, Maxime Ripard wrote:
>> The i915 driver has a property to force the RGB range of an HDMI output.
>> The vc4 driver then implemented the same property with the same
>> semantics. KWin has support for it, and a PR for mutter is also there to
>> support it.
>>
>> Both drivers implementing the same property with the same semantics,
>> plus the userspace having support for it, is proof enough that it's
>> pretty much a de-facto standard now and we can provide helpers for it.
>>
>> Let's plumb it into the newly created HDMI connector.
>>
>> Reviewed-by: Dave Stevenson 
>> Signed-off-by: Maxime Ripard 
>> ---
>>  Documentation/gpu/kms-properties.csv  |  1 -
>>  drivers/gpu/drm/drm_atomic.c  |  2 +
>>  drivers/gpu/drm/drm_atomic_state_helper.c |  4 +-
>>  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++
>>  drivers/gpu/drm/drm_connector.c   | 89 
>> +++
>>  include/drm/drm_connector.h   | 36 +
>>  6 files changed, 134 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/gpu/kms-properties.csv 
>> b/Documentation/gpu/kms-properties.csv
>> index 0f9590834829..caef14c532d4 100644
>> --- a/Documentation/gpu/kms-properties.csv
>> +++ b/Documentation/gpu/kms-properties.csv
>> @@ -17,7 +17,6 @@ Owner Module/Drivers,Group,Property Name,Type,Property 
>> Values,Object attached,De
>>  ,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0x",Connector,property 
>> to suggest an X offset for a connector
>>  ,,“suggested Y”,RANGE,"Min=0, Max=0x",Connector,property to suggest 
>> an Y offset for a connector
>>  ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" 
>> }",Connector,TDB
>> -i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 
>> 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM 
>> is set, the hardware will be programmed with the result of the 
>> multiplication of CTM by the limited range matrix to ensure the pixels 
>> normally in the range 0..1.0 are remapped to the range 16/255..235/255."
>>  ,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
>>  ,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } 
>> etc.",Connector,TBD
>>  ,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> index 26f9e525c0a0..3e57d98d8418 100644
>> --- a/drivers/gpu/drm/drm_atomic.c
>> +++ b/drivers/gpu/drm/drm_atomic.c
>> @@ -1145,6 +1145,8 @@ static void drm_atomic_connector_print_state(struct 
>> drm_printer *p,
>>  
>>  if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
>>  connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
>> +drm_printf(p, "\tbroadcast_rgb=%s\n",
>> +   
>> drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
>>  drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
>>  drm_printf(p, "\toutput_format=%s\n",
>> 
>> drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
>> b/drivers/gpu/drm/drm_atomic_state_helper.c
>> index 9f517599f117..0e8fb653965a 100644
>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>> @@ -589,6 +589,7 @@ void __drm_atomic_helper_connector_hdmi_reset(struct 
>> drm_connector *connector,
>>  
>>  new_state->max_bpc = max_bpc;
>>  new_state->max_requested_bpc = max_bpc;
>> +new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
>>  }
>>  EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
>>  
>> @@ -913,7 +914,8 @@ int drm_atomic_helper_connector_hdmi_check(struct 
>> drm_connector *connector,
>>  if (ret)
>>  return ret;
>>  
>> -if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
>> +if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb ||
>> +old_state->hdmi.output_bpc != new_state->hdmi.output_bpc ||
>>  old_state->hdmi.output_format != new_state->hdmi.output_format) {
>>  struct drm_crtc *crtc = new_state->crtc;
>>  struct drm_crtc_state *crtc_state;
>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
>> b/drivers/gpu/drm/drm_atomic_uapi.c
>> index 29d4940188d4..2b415b4ed506 100644
>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>> @@ -776,6 +776,8 @@ static int drm_atomic_connector_set_property(struct 
>> drm_connector *connector,
>>  state->max_requested_bpc = val;
>>  } else if (property == connector->privacy_screen_sw_state_property) {
>>  state->privacy_screen_sw_state = val;
>> +} else if (property == connector->broadcast_rgb_property) {
>> +state->hdmi.broadcast_

Re: [PATCH v2 1/9] media: v4l2-subdev: Add a pad variant of .query_dv_timings()

2024-02-29 Thread Hans Verkuil
On 2/29/24 12:33, Paweł Anikiel wrote:
> On Thu, Feb 29, 2024 at 9:02 AM Hans Verkuil  wrote:
>>
>> On 28/02/2024 16:34, Paweł Anikiel wrote:
>>> On Wed, Feb 28, 2024 at 12:25 PM Hans Verkuil  
>>> wrote:
>>>>
>>>> Hi Paweł,
>>>>
>>>> On 21/02/2024 17:02, Paweł Anikiel wrote:
>>>>> Currently, .query_dv_timings() is defined as a video callback without
>>>>> a pad argument. This is a problem if the subdevice can have different
>>>>> dv timings for each pad (e.g. a DisplayPort receiver with multiple
>>>>> virtual channels).
>>>>>
>>>>> To solve this, add a pad variant of this callback which includes
>>>>> the pad number as an argument.
>>>>
>>>> So now we have two query_dv_timings ops: one for video ops, and one
>>>> for pad ops. That's not very maintainable. I would suggest switching
>>>> all current users of the video op over to the pad op.
>>>
>>> I agree it would be better if there was only one. However, I have some 
>>> concerns:
>>> 1. Isn't there a problem with backwards compatibility? For example, an
>>> out-of-tree driver is likely to use this callback, which would break.
>>> I'm asking because I'm not familiar with how such API changes are
>>> handled.
>>
>> It's out of tree, so they will just have to adapt. That's how life is if
>> you are not part of the mainline kernel.
>>
>>> 2. If I do switch all current users to the pad op, I can't test those
>>> changes. Isn't that a problem?
>>
>> I can test one or two drivers, but in general I don't expect this to be
>> a problem.
>>
>>> 3. Would I need to get ACK from all the driver maintainers?
>>
>> CC the patches to the maintainers. Generally you will get back Acks from
>> some but not all maintainers, but that's OK. For changes affecting multiple
>> drivers you never reach 100% on that. I can review the remainder. The DV
>> Timings API is my expert area, so that shouldn't be a problem.
>>
>> A quick grep gives me these subdev drivers that implement it:
>>
>> adv748x, adv7604, adv7842, tc358743, tda1997x, tvp7002, gs1662.
>>
>> And these bridge drivers that call the subdevs:
>>
>> cobalt, rcar-vin, vpif_capture.
>>
>> The bridge drivers can use the following pad when calling query_dv_timings:
>>
>> cobalt: ADV76XX_PAD_HDMI_PORT_A
>> rcar_vin: vin->parallel.sink_pad
>> vpif_capture: 0
>>
>> The converted subdev drivers should check if the pad is an input pad.
>> Ideally it should check if the pad is equal to the current input pad
>> since most devices can only query the timings for the currently selected
>> input pad. But some older drivers predate the pad concept and they
>> ignore the pad value.
> 
> Thank you for the helpful info. I will switch all these drivers to the
> pad op, then. Would you like me to prepare a separate patchset, or
> should I include the changes in this one?

I think I prefer a separate patchset for this.

Regards,

Hans


Re: [PATCH v2 1/9] media: v4l2-subdev: Add a pad variant of .query_dv_timings()

2024-02-29 Thread Hans Verkuil
On 28/02/2024 16:34, Paweł Anikiel wrote:
> On Wed, Feb 28, 2024 at 12:25 PM Hans Verkuil  
> wrote:
>>
>> Hi Paweł,
>>
>> On 21/02/2024 17:02, Paweł Anikiel wrote:
>>> Currently, .query_dv_timings() is defined as a video callback without
>>> a pad argument. This is a problem if the subdevice can have different
>>> dv timings for each pad (e.g. a DisplayPort receiver with multiple
>>> virtual channels).
>>>
>>> To solve this, add a pad variant of this callback which includes
>>> the pad number as an argument.
>>
>> So now we have two query_dv_timings ops: one for video ops, and one
>> for pad ops. That's not very maintainable. I would suggest switching
>> all current users of the video op over to the pad op.
> 
> I agree it would be better if there was only one. However, I have some 
> concerns:
> 1. Isn't there a problem with backwards compatibility? For example, an
> out-of-tree driver is likely to use this callback, which would break.
> I'm asking because I'm not familiar with how such API changes are
> handled.

It's out of tree, so they will just have to adapt. That's how life is if
you are not part of the mainline kernel.

> 2. If I do switch all current users to the pad op, I can't test those
> changes. Isn't that a problem?

I can test one or two drivers, but in general I don't expect this to be
a problem.

> 3. Would I need to get ACK from all the driver maintainers?

CC the patches to the maintainers. Generally you will get back Acks from
some but not all maintainers, but that's OK. For changes affecting multiple
drivers you never reach 100% on that. I can review the remainder. The DV
Timings API is my expert area, so that shouldn't be a problem.

A quick grep gives me these subdev drivers that implement it:

adv748x, adv7604, adv7842, tc358743, tda1997x, tvp7002, gs1662.

And these bridge drivers that call the subdevs:

cobalt, rcar-vin, vpif_capture.

The bridge drivers can use the following pad when calling query_dv_timings:

cobalt: ADV76XX_PAD_HDMI_PORT_A
rcar_vin: vin->parallel.sink_pad
vpif_capture: 0

The converted subdev drivers should check if the pad is an input pad.
Ideally it should check if the pad is equal to the current input pad
since most devices can only query the timings for the currently selected
input pad. But some older drivers predate the pad concept and they
ignore the pad value.

Regards,

Hans


Re: [PATCH v2 2/9] media: Add Chameleon v3 framebuffer driver

2024-02-28 Thread Hans Verkuil
On 28/02/2024 16:08, Paweł Anikiel wrote:
> Hi Hans, thanks for the review!
> 
> On Wed, Feb 28, 2024 at 12:24 PM Hans Verkuil  
> wrote:
>>
>> Hi Paweł,
>>
>> On 21/02/2024 17:02, Paweł Anikiel wrote:
>>> Add v4l2 driver for the Google Chameleon v3 framebuffer device.
>>
>> This is just a video capture device, right? A framebuffer device is something
>> that lives in drivers/video/fbdev.
> 
> Yes, it is just a capture device.
> 
>>
>> It is *very* confusing to see the term 'framebuffer' used in a video
>> capture context.
> 
> I agree the name is confusing. I think it started out as something
> else and unfortunately stuck around. I think it's possible to change
> it, though.

That would be very helpful.

> 
>>
>> This commit log should also give a better description of the hardware.
>> Just a single one-liner is a bit on the short side :-)
> 
> Would it be fine to just put the Kconfig help text there?

Yes.

> 
>>
>>>
>>> Signed-off-by: Paweł Anikiel 
>>> ---
>>>  drivers/media/platform/Kconfig|   1 +
>>>  drivers/media/platform/Makefile   |   1 +
>>>  drivers/media/platform/google/Kconfig |   3 +
>>>  drivers/media/platform/google/Makefile|   2 +
>>>  .../media/platform/google/chameleonv3/Kconfig |  13 +
>>>  .../platform/google/chameleonv3/Makefile  |   3 +
>>>  .../platform/google/chameleonv3/chv3-fb.c | 895 ++
>>
>> chv3-video.c would be a much better name for chv3-fb.c.
>>
>> That's a commonly used filename for video capture drivers.
> 
> I'm guessing all the instances of fb or framebuffer in the driver
> itself should be changed as well in that case?

Yes, please. I wouldn't normally ask for such major renaming, but
in this case that name is really confusing.

> 
>>
>>>  7 files changed, 918 insertions(+)
>>>  create mode 100644 drivers/media/platform/google/Kconfig
>>>  create mode 100644 drivers/media/platform/google/Makefile
>>>  create mode 100644 drivers/media/platform/google/chameleonv3/Kconfig
>>>  create mode 100644 drivers/media/platform/google/chameleonv3/Makefile
>>>  create mode 100644 drivers/media/platform/google/chameleonv3/chv3-fb.c
>>>
>>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
>>> index 91e54215de3a..b82f7b142b85 100644
>>> --- a/drivers/media/platform/Kconfig
>>> +++ b/drivers/media/platform/Kconfig
>>> @@ -69,6 +69,7 @@ source "drivers/media/platform/aspeed/Kconfig"
>>>  source "drivers/media/platform/atmel/Kconfig"
>>>  source "drivers/media/platform/cadence/Kconfig"
>>>  source "drivers/media/platform/chips-media/Kconfig"
>>> +source "drivers/media/platform/google/Kconfig"
>>>  source "drivers/media/platform/intel/Kconfig"
>>>  source "drivers/media/platform/marvell/Kconfig"
>>>  source "drivers/media/platform/mediatek/Kconfig"
>>> diff --git a/drivers/media/platform/Makefile 
>>> b/drivers/media/platform/Makefile
>>> index 3296ec1ebe16..f7067eb05f76 100644
>>> --- a/drivers/media/platform/Makefile
>>> +++ b/drivers/media/platform/Makefile
>>> @@ -12,6 +12,7 @@ obj-y += aspeed/
>>>  obj-y += atmel/
>>>  obj-y += cadence/
>>>  obj-y += chips-media/
>>> +obj-y += google/
>>>  obj-y += intel/
>>>  obj-y += marvell/
>>>  obj-y += mediatek/
>>> diff --git a/drivers/media/platform/google/Kconfig 
>>> b/drivers/media/platform/google/Kconfig
>>> new file mode 100644
>>> index ..2a5f01034c11
>>> --- /dev/null
>>> +++ b/drivers/media/platform/google/Kconfig
>>> @@ -0,0 +1,3 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +
>>> +source "drivers/media/platform/google/chameleonv3/Kconfig"
>>> diff --git a/drivers/media/platform/google/Makefile 
>>> b/drivers/media/platform/google/Makefile
>>> new file mode 100644
>>> index ..c971a09faeb4
>>> --- /dev/null
>>> +++ b/drivers/media/platform/google/Makefile
>>> @@ -0,0 +1,2 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +obj-y += chameleonv3/
>>> diff --git a/drivers/media/platform/google/chameleonv3/Kconfig 
>>> b/drivers/media/platform/google/chameleonv3/Kconfig
>>> new file mode 100644
>>> index ..76d0383a8589
>&g

Re: [PATCH v2 6/9] media: intel: Add Displayport RX IP driver

2024-02-28 Thread Hans Verkuil
On 21/02/2024 17:02, Paweł Anikiel wrote:
> Add driver for the Intel DisplayPort RX FPGA IP
> 
> Signed-off-by: Paweł Anikiel 
> ---
>  drivers/media/platform/intel/Kconfig  |   12 +
>  drivers/media/platform/intel/Makefile |1 +
>  drivers/media/platform/intel/intel-dprx.c | 2176 +
>  3 files changed, 2189 insertions(+)
>  create mode 100644 drivers/media/platform/intel/intel-dprx.c
> 
> diff --git a/drivers/media/platform/intel/Kconfig 
> b/drivers/media/platform/intel/Kconfig
> index 724e80a9086d..eafcd47cce68 100644
> --- a/drivers/media/platform/intel/Kconfig
> +++ b/drivers/media/platform/intel/Kconfig
> @@ -12,3 +12,15 @@ config VIDEO_PXA27x
>   select V4L2_FWNODE
>   help
> This is a v4l2 driver for the PXA27x Quick Capture Interface
> +
> +config VIDEO_INTEL_DPRX
> + tristate "Intel DisplayPort RX IP driver"
> + depends on V4L_PLATFORM_DRIVERS
> + depends on VIDEO_DEV
> + select V4L2_FWNODE
> + select CRC_DP
> + help
> +   v4l2 subdev driver for Intel Displayport receiver FPGA IP.
> +   It is a part of the DisplayPort Intel FPGA IP Core.
> +   It implements a DisplayPort 1.4 receiver capable of HBR3
> +   video capture and Multi-Stream Transport.
> diff --git a/drivers/media/platform/intel/Makefile 
> b/drivers/media/platform/intel/Makefile
> index 7e8889cbd2df..f571399f5aa8 100644
> --- a/drivers/media/platform/intel/Makefile
> +++ b/drivers/media/platform/intel/Makefile
> @@ -1,2 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
> +obj-$(CONFIG_VIDEO_INTEL_DPRX) += intel-dprx.o
> diff --git a/drivers/media/platform/intel/intel-dprx.c 
> b/drivers/media/platform/intel/intel-dprx.c
> new file mode 100644
> index ..d0c60e29e51d
> --- /dev/null
> +++ b/drivers/media/platform/intel/intel-dprx.c
> @@ -0,0 +1,2176 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2023-2024 Google LLC.
> + * Author: Paweł Anikiel 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DPRX_MAX_EDID_BLOCKS 4
> +
> +/* DPRX registers */
> +
> +#define DPRX_RX_CONTROL  0x000
> +#define DPRX_RX_CONTROL_LINK_RATE_SHIFT  16
> +#define DPRX_RX_CONTROL_LINK_RATE_MASK   0xff
> +#define DPRX_RX_CONTROL_RECONFIG_LINKRATE13
> +#define DPRX_RX_CONTROL_TP_SHIFT 8
> +#define DPRX_RX_CONTROL_TP_MASK  0x7
> +#define DPRX_RX_CONTROL_SCRAMBLER_DISABLE7
> +#define DPRX_RX_CONTROL_CHANNEL_CODING_SHIFT 5
> +#define DPRX_RX_CONTROL_CHANNEL_CODING_8B10B 0x1
> +#define DPRX_RX_CONTROL_LANE_COUNT_SHIFT 0
> +#define DPRX_RX_CONTROL_LANE_COUNT_MASK  0x1f
> +
> +#define DPRX_RX_STATUS   0x001
> +#define DPRX_RX_STATUS_INTERLANE_ALIGN   8
> +#define DPRX_RX_STATUS_SYM_LOCK_SHIFT4
> +#define DPRX_RX_STATUS_SYM_LOCK(i)   (4 + i)
> +#define DPRX_RX_STATUS_CR_LOCK_SHIFT 0
> +#define DPRX_RX_STATUS_CR_LOCK(i)(0 + i)
> +
> +#define DPRX_MSA_HTOTAL(i)   (0x022 + 0x20 * (i))
> +#define DPRX_MSA_VTOTAL(i)   (0x023 + 0x20 * (i))
> +#define DPRX_MSA_HSP(i)  (0x024 + 0x20 * (i))
> +#define DPRX_MSA_HSW(i)  (0x025 + 0x20 * (i))
> +#define DPRX_MSA_HSTART(i)   (0x026 + 0x20 * (i))
> +#define DPRX_MSA_VSTART(i)   (0x027 + 0x20 * (i))
> +#define DPRX_MSA_VSP(i)  (0x028 + 0x20 * (i))
> +#define DPRX_MSA_VSW(i)  (0x029 + 0x20 * (i))
> +#define DPRX_MSA_HWIDTH(i)   (0x02a + 0x20 * (i))
> +#define DPRX_MSA_VHEIGHT(i)  (0x02b + 0x20 * (i))
> +#define DPRX_VBID(i) (0x02f + 0x20 * (i))
> +#define DPRX_VBID_MSA_LOCK   7
> +
> +#define DPRX_MST_CONTROL10x0a0
> +#define DPRX_MST_CONTROL1_VCPTAB_UPD_FORCE   31
> +#define DPRX_MST_CONTROL1_VCPTAB_UPD_REQ 30
> +#define DPRX_MST_CONTROL1_VCP_ID_SHIFT(i)(4 + 4 * (i))
> +#define DPRX_MST_CONTROL1_VCP_IDS_SHIFT  4
> +#define DPRX_MST_CONTROL1_VCP_IDS_MASK   0x
> +#define DPRX_MST_CONTROL1_MST_EN 0
> +
> +#define DPRX_MST_STATUS1 0x0a1
> +#define DPRX_MST_STATUS1_VCPTAB_ACT_ACK  30
> +
> +#define DPRX_MST_VCPTAB(i)   (0x0a2 + i)
> +
> +#define DPRX_AUX_CONTROL 0x100
> +#define DPRX_AUX_CONTROL_IRQ_EN  8
> +#define DPRX_AUX_CONTROL_TX_STROBE   7
> +#define DPRX_AUX_CONTROL_LENGTH_SHIFT0
> +#define DPRX_AUX_CONTROL_LENGTH_MASK 0x1f
> +
> +#define DPRX_AUX_STATUS  0x101
> +#define DPRX_AUX_STATUS_MSG_READY31
> +

Re: [PATCH v2 1/9] media: v4l2-subdev: Add a pad variant of .query_dv_timings()

2024-02-28 Thread Hans Verkuil
Hi Paweł,

On 21/02/2024 17:02, Paweł Anikiel wrote:
> Currently, .query_dv_timings() is defined as a video callback without
> a pad argument. This is a problem if the subdevice can have different
> dv timings for each pad (e.g. a DisplayPort receiver with multiple
> virtual channels).
> 
> To solve this, add a pad variant of this callback which includes
> the pad number as an argument.

So now we have two query_dv_timings ops: one for video ops, and one
for pad ops. That's not very maintainable. I would suggest switching
all current users of the video op over to the pad op.

Regards,

Hans

> 
> Signed-off-by: Paweł Anikiel 
> ---
>  drivers/media/v4l2-core/v4l2-subdev.c | 11 +++
>  include/media/v4l2-subdev.h   |  5 +
>  2 files changed, 16 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c 
> b/drivers/media/v4l2-core/v4l2-subdev.c
> index 4c6198c48dd6..11f865dd19b4 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -389,6 +389,16 @@ static int call_enum_dv_timings(struct v4l2_subdev *sd,
>  sd->ops->pad->enum_dv_timings(sd, dvt);
>  }
>  
> +static int call_query_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
> +  struct v4l2_dv_timings *timings)
> +{
> + if (!timings)
> + return -EINVAL;
> +
> + return check_pad(sd, pad) ? :
> +sd->ops->pad->query_dv_timings(sd, pad, timings);
> +}
> +
>  static int call_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
>   struct v4l2_mbus_config *config)
>  {
> @@ -489,6 +499,7 @@ static const struct v4l2_subdev_pad_ops 
> v4l2_subdev_call_pad_wrappers = {
>   .set_edid   = call_set_edid,
>   .dv_timings_cap = call_dv_timings_cap,
>   .enum_dv_timings= call_enum_dv_timings,
> + .query_dv_timings   = call_query_dv_timings,
>   .get_frame_desc = call_get_frame_desc,
>   .get_mbus_config= call_get_mbus_config,
>  };
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index a9e6b8146279..dc8963fa5a06 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -797,6 +797,9 @@ struct v4l2_subdev_state {
>   * @enum_dv_timings: callback for VIDIOC_SUBDEV_ENUM_DV_TIMINGS() ioctl 
> handler
>   *code.
>   *
> + * @query_dv_timings: same as query_dv_timings() from v4l2_subdev_video_ops,
> + * but with additional pad argument.
> + *
>   * @link_validate: used by the media controller code to check if the links
>   *  that belongs to a pipeline can be used for stream.
>   *
> @@ -868,6 +871,8 @@ struct v4l2_subdev_pad_ops {
> struct v4l2_dv_timings_cap *cap);
>   int (*enum_dv_timings)(struct v4l2_subdev *sd,
>  struct v4l2_enum_dv_timings *timings);
> + int (*query_dv_timings)(struct v4l2_subdev *sd, unsigned int pad,
> + struct v4l2_dv_timings *timings);
>  #ifdef CONFIG_MEDIA_CONTROLLER
>   int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,
>struct v4l2_subdev_format *source_fmt,



Re: [PATCH v2 2/9] media: Add Chameleon v3 framebuffer driver

2024-02-28 Thread Hans Verkuil
Hi Paweł,

On 21/02/2024 17:02, Paweł Anikiel wrote:
> Add v4l2 driver for the Google Chameleon v3 framebuffer device.

This is just a video capture device, right? A framebuffer device is something
that lives in drivers/video/fbdev.

It is *very* confusing to see the term 'framebuffer' used in a video
capture context.

This commit log should also give a better description of the hardware.
Just a single one-liner is a bit on the short side :-)

> 
> Signed-off-by: Paweł Anikiel 
> ---
>  drivers/media/platform/Kconfig|   1 +
>  drivers/media/platform/Makefile   |   1 +
>  drivers/media/platform/google/Kconfig |   3 +
>  drivers/media/platform/google/Makefile|   2 +
>  .../media/platform/google/chameleonv3/Kconfig |  13 +
>  .../platform/google/chameleonv3/Makefile  |   3 +
>  .../platform/google/chameleonv3/chv3-fb.c | 895 ++

chv3-video.c would be a much better name for chv3-fb.c.

That's a commonly used filename for video capture drivers.

>  7 files changed, 918 insertions(+)
>  create mode 100644 drivers/media/platform/google/Kconfig
>  create mode 100644 drivers/media/platform/google/Makefile
>  create mode 100644 drivers/media/platform/google/chameleonv3/Kconfig
>  create mode 100644 drivers/media/platform/google/chameleonv3/Makefile
>  create mode 100644 drivers/media/platform/google/chameleonv3/chv3-fb.c
> 
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index 91e54215de3a..b82f7b142b85 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -69,6 +69,7 @@ source "drivers/media/platform/aspeed/Kconfig"
>  source "drivers/media/platform/atmel/Kconfig"
>  source "drivers/media/platform/cadence/Kconfig"
>  source "drivers/media/platform/chips-media/Kconfig"
> +source "drivers/media/platform/google/Kconfig"
>  source "drivers/media/platform/intel/Kconfig"
>  source "drivers/media/platform/marvell/Kconfig"
>  source "drivers/media/platform/mediatek/Kconfig"
> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
> index 3296ec1ebe16..f7067eb05f76 100644
> --- a/drivers/media/platform/Makefile
> +++ b/drivers/media/platform/Makefile
> @@ -12,6 +12,7 @@ obj-y += aspeed/
>  obj-y += atmel/
>  obj-y += cadence/
>  obj-y += chips-media/
> +obj-y += google/
>  obj-y += intel/
>  obj-y += marvell/
>  obj-y += mediatek/
> diff --git a/drivers/media/platform/google/Kconfig 
> b/drivers/media/platform/google/Kconfig
> new file mode 100644
> index ..2a5f01034c11
> --- /dev/null
> +++ b/drivers/media/platform/google/Kconfig
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +source "drivers/media/platform/google/chameleonv3/Kconfig"
> diff --git a/drivers/media/platform/google/Makefile 
> b/drivers/media/platform/google/Makefile
> new file mode 100644
> index ..c971a09faeb4
> --- /dev/null
> +++ b/drivers/media/platform/google/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-y += chameleonv3/
> diff --git a/drivers/media/platform/google/chameleonv3/Kconfig 
> b/drivers/media/platform/google/chameleonv3/Kconfig
> new file mode 100644
> index ..76d0383a8589
> --- /dev/null
> +++ b/drivers/media/platform/google/chameleonv3/Kconfig
> @@ -0,0 +1,13 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config VIDEO_CHV3_FB
> + tristate "Google Chameleon v3 framebuffer video driver"
> + depends on V4L_PLATFORM_DRIVERS
> + depends on VIDEO_DEV
> + select VIDEOBUF2_DMA_CONTIG
> + select V4L2_FWNODE
> + help
> +   v4l2 driver for the video interface present on the Google
> +   Chameleon v3. The Chameleon v3 uses the framebuffer IP core
> +   to take the video signal from different sources and directly
> +   write frames into memory.

So it is composing different video streams into buffers? Or does it
capture from a single source at a time? The text is rather ambiguous.

> diff --git a/drivers/media/platform/google/chameleonv3/Makefile 
> b/drivers/media/platform/google/chameleonv3/Makefile
> new file mode 100644
> index ..d63727148688
> --- /dev/null
> +++ b/drivers/media/platform/google/chameleonv3/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +obj-$(CONFIG_VIDEO_CHV3_FB) += chv3-fb.o
> diff --git a/drivers/media/platform/google/chameleonv3/chv3-fb.c 
> b/drivers/media/platform/google/chameleonv3/chv3-fb.c
> new file mode 100644
> index ..35a44365eba0
> --- /dev/null
> +++ b/drivers/media/platform/google/chameleonv3/chv3-fb.c
> @@ -0,0 +1,895 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2023-2024 Google LLC.
> + * Author: Paweł Anikiel 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DEVICE_NAME  "chv3-fb"
> +

Re: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property

2024-02-12 Thread Hans Verkuil
On 12/02/2024 16:49, Ville Syrjälä wrote:
> On Mon, Feb 12, 2024 at 11:01:07AM +0100, Maxime Ripard wrote:
>> On Fri, Feb 09, 2024 at 09:34:35PM +0100, Sebastian Wick wrote:
>>> On Mon, Feb 05, 2024 at 10:39:38AM +0100, Maxime Ripard wrote:
 On Fri, Feb 02, 2024 at 06:37:52PM +0200, Ville Syrjälä wrote:
> On Fri, Feb 02, 2024 at 04:59:30PM +0100, Maxime Ripard wrote:
>> On Fri, Feb 02, 2024 at 05:40:47PM +0200, Ville Syrjälä wrote:
>>> On Fri, Feb 02, 2024 at 02:01:39PM +0100, Maxime Ripard wrote:
 Hi,

 On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote:
>>>  /**
>>>   * DOC: HDMI connector properties
>>>   *
>>> + * Broadcast RGB
>>> + *  Indicates the RGB Quantization Range (Full vs Limited) 
>>> used.
>>> + *  Infoframes will be generated according to that value.
>>> + *
>>> + *  The value of this property can be one of the following:
>>> + *
>>> + *  Automatic:
>>> + *  RGB Range is selected automatically based on the 
>>> mode
>>> + *  according to the HDMI specifications.
>>> + *
>>> + *  Full:
>>> + *  Full RGB Range is forced.
>>> + *
>>> + *  Limited 16:235:
>>> + *  Limited RGB Range is forced. Unlike the name 
>>> suggests,
>>> + *  this works for any number of bits-per-component.
>>> + *
>>> + *  Drivers can set up this property by calling
>>> + *  drm_connector_attach_broadcast_rgb_property().
>>> + *
>>
>> This is a good time to document this in more detail. There might be 
>> two
>> different things being affected:
>>
>> 1. The signalling (InfoFrame/SDP/...)
>> 2. The color pipeline processing
>>
>> All values of Broadcast RGB always affect the color pipeline 
>> processing
>> such that a full-range input to the CRTC is converted to either 
>> full- or
>> limited-range, depending on what the monitor is supposed to accept.
>>
>> When automatic is selected, does that mean that there is no 
>> signalling,
>> or that the signalling matches what the monitor is supposed to accept
>> according to the spec? Also, is this really HDMI specific?
>>
>> When full or limited is selected and the monitor doesn't support the
>> signalling, what happens?
>
> Forgot to mention: user-space still has no control over RGB vs YCbCr 
> on
> the cable, so is this only affecting RGB? If not, how does it affect
> YCbCr?

 So I dug a bit into both the i915 and vc4 drivers, and it looks like if
 we're using a YCbCr format, i915 will always use a limited range while
 vc4 will follow the value of the property.
>>>
>>> The property is literally called "Broadcast *RGB*".
>>> That should explain why it's only affecting RGB.
>>
>> Right. And the limited range option is called "Limited 16:235" despite
>> being usable on bpc > 8 bits. Naming errors occurs, and history happens
>> to make names inconsistent too, that's fine and not an argument in
>> itself.
>>
>>> Full range YCbCr is a much rarer beast so we've never bothered
>>> to enable it.
>>
>> vc4 supports it.
>
> Someone implemented it incorrectly then.

 Incorrectly according to what documentation / specification? I'm sorry,
 but I find it super ironic that i915 gets to do its own thing, not
 document any of it, and when people try to clean things up they get told
 that we got it all wrong.
>>>
>>> FWIW, this was an i915 property and if another driver uses the same
>>> property name it must have the same behavior. Yes, it isn't standardized
>>> and yes, it's not documented (hence this effort here) but it's still on
>>> vc4 to make the property compatible.
>>
>> How is it not compatible? It's a superset of what i915 provides, but
>> it's strictly compatible with it.
> 
> No it is not. Eg. what happens if you set the thing to full range for
> RGB (which you must on many broken monitors), and then the kernel
> automagically switches to YCbCr (for whatever reason) but the monitor
> doesn't support full range YCbCr? Answer: you get crap output.

The Broadcast RGB setting is really specific to RGB output. That's where
you need it, since due to messed up standards in the past it is common to
have to override this.

For YCbCr it is not needed since it is always limited range in practice.
If there is ever a need to support full range YCbCr, then a new "Broadcast 
YCbCr"
setting should be created.

The only place were you see full range YCbCr being used is in combination with
JPEG codecs, since JPEG uses full range YCbCr. 

Re: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()

2024-02-07 Thread Hans Verkuil
On 07/02/2024 14:51, Laurent Pinchart wrote:
> On Wed, Feb 07, 2024 at 02:14:33PM +0100, Krzysztof Hałasa wrote:
>> Hans,
>>
>> Hans Verkuil  writes:
>>
>>> Ideally someone would have to actually test this, perhaps with one of those
>>> Renesas boards. While I do have one, it got bricked after I attempted a
>>> u-boot update :-(
>>
>> May be reversible, though.
> 
> Maybe Morimoto-san could help ? :-) What board did you use Hans ?
> 

I have a Koelsch. I tried to update uboot at one time, but bricked it and was
unable to get a different uboot installed.

It would be nice if it can be revived.

Regards,

Hans


Re: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()

2024-02-06 Thread Hans Verkuil
On 2/6/24 14:41, Laurent Pinchart wrote:
> Hi Morimoto-san,
> 
> (Adding Krzysztof Hałasa)
> 
> Thank you for the patch.
> 
> On Tue, Feb 06, 2024 at 02:55:27AM +, Kuninori Morimoto wrote:
>> From DT point of view, in general, drivers should be asking for a
>> specific port number because their function is fixed in the binding.
>>
>> of_graph_get_next_endpoint() doesn't match to this concept.
>>
>> Simply replace
>>
>>  - of_graph_get_next_endpoint(xxx, NULL);
>>  + of_graph_get_endpoint_by_regs(xxx, 0, -1);
>>
>> Link: https://lore.kernel.org/r/20240202174941.ga310089-r...@kernel.org
>> Signed-off-by: Kuninori Morimoto 
>> ---
>>  drivers/media/i2c/adv7343.c  | 2 +-
>>  drivers/media/i2c/adv7604.c  | 2 +-
>>  drivers/media/i2c/mt9p031.c  | 2 +-
>>  drivers/media/i2c/mt9v032.c  | 2 +-
>>  drivers/media/i2c/ov2659.c   | 2 +-
>>  drivers/media/i2c/ov5645.c   | 2 +-
>>  drivers/media/i2c/ov5647.c   | 2 +-
>>  drivers/media/i2c/s5c73m3/s5c73m3-core.c | 2 +-
>>  drivers/media/i2c/s5k5baf.c  | 2 +-
>>  drivers/media/i2c/tc358743.c | 2 +-
>>  drivers/media/i2c/tda1997x.c | 2 +-
>>  drivers/media/i2c/tvp514x.c  | 2 +-
>>  drivers/media/i2c/tvp7002.c  | 2 +-
>>  13 files changed, 13 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
>> index ff21cd4744d3..4fbe4e18570e 100644
>> --- a/drivers/media/i2c/adv7343.c
>> +++ b/drivers/media/i2c/adv7343.c
>> @@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
>>  if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  return client->dev.platform_data;
>>  
>> -np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  if (!np)
>>  return NULL;
>>  
>> diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
>> index b202a85fbeaa..dcfdbb975473 100644
>> --- a/drivers/media/i2c/adv7604.c
>> +++ b/drivers/media/i2c/adv7604.c
>> @@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state 
>> *state)
>>  np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
>>  
>>  /* Parse the endpoint. */
>> -endpoint = of_graph_get_next_endpoint(np, NULL);
>> +endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
> 
> I think this should be port 1 for the adv7611 and port2 for the adv7612.
> The adv7610 may need to use port 1 too, but the bindings likely need to
> be updated.
> 
> Hans, Krzysztof, any opinion ?

It looks like it. But I suspect the code never worked. The endpoint parsing
is only needed if a specific mbus type is used (i.e., not 'UNKNOWN'), and
I don't think that is used in the device trees in the kernel. So everything
silently falls back to UNKNOWN and some default bus config that 'just works' 
(tm).

I'm pretty sure this code is wrong, but nobody ever noticed. Changing it
to the new code just makes it bug-compatible :-)

Ideally someone would have to actually test this, perhaps with one of those
Renesas boards. While I do have one, it got bricked after I attempted a
u-boot update :-(

Regards,

Hans

> 
>>  if (!endpoint)
>>  return -EINVAL;
>>  
>> diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
>> index 348f1e1098fb..c57a0d436421 100644
>> --- a/drivers/media/i2c/mt9p031.c
>> +++ b/drivers/media/i2c/mt9p031.c
>> @@ -1080,7 +1080,7 @@ mt9p031_get_pdata(struct i2c_client *client)
>>  if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  return client->dev.platform_data;
>>  
>> -np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  if (!np)
>>  return NULL;
>>  
>> diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
>> index 1c6f6cea1204..14d277680fa2 100644
>> --- a/drivers/media/i2c/mt9v032.c
>> +++ b/drivers/media/i2c/mt9v032.c
>> @@ -1008,7 +1008,7 @@ mt9v032_get_pdata(struct i2c_client *client)
>>  if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  return client->dev.platform_data;
>>  
>> -np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>  if (!np)
>>  return NULL;
>>  
>> diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
>> index 2c3dbe164eb6..edea62a02320 100644
>> --- a/drivers/media/i2c/ov2659.c
>> +++ b/drivers/media/i2c/ov2659.c
>> @@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
>>  if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
>>  return client->dev.platform_data;
>>  
>> -endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
>> +endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
>>

Re: [PATCH v5 08/44] drm/connector: hdmi: Add Broadcast RGB property

2024-02-02 Thread Hans Verkuil
On 02/02/2024 12:04, Jani Nikula wrote:
> On Mon, 15 Jan 2024, Sebastian Wick  wrote:
>> On Thu, Dec 07, 2023 at 04:49:31PM +0100, Maxime Ripard wrote:
>>> The i915 driver has a property to force the RGB range of an HDMI output.
>>> The vc4 driver then implemented the same property with the same
>>> semantics. KWin has support for it, and a PR for mutter is also there to
>>> support it.
>>>
>>> Both drivers implementing the same property with the same semantics,
>>> plus the userspace having support for it, is proof enough that it's
>>> pretty much a de-facto standard now and we can provide helpers for it.
>>>
>>> Let's plumb it into the newly created HDMI connector.
>>>
>>> Signed-off-by: Maxime Ripard 
> 
> [snip]
> 
>>> @@ -1655,6 +1678,26 @@ 
>>> EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
>>>  /**
>>>   * DOC: HDMI connector properties
>>>   *
>>> + * Broadcast RGB
>>> + *  Indicates the RGB Quantization Range (Full vs Limited) used.
>>> + *  Infoframes will be generated according to that value.
>>> + *
>>> + *  The value of this property can be one of the following:
>>> + *
>>> + *  Automatic:
>>> + *  RGB Range is selected automatically based on the mode
>>> + *  according to the HDMI specifications.
>>> + *
>>> + *  Full:
>>> + *  Full RGB Range is forced.
>>> + *
>>> + *  Limited 16:235:
>>> + *  Limited RGB Range is forced. Unlike the name suggests,
>>> + *  this works for any number of bits-per-component.
>>> + *
>>> + *  Drivers can set up this property by calling
>>> + *  drm_connector_attach_broadcast_rgb_property().
>>> + *
>>
>> This is a good time to document this in more detail. There might be two
>> different things being affected:
>>
>> 1. The signalling (InfoFrame/SDP/...)
>> 2. The color pipeline processing
>>
>> All values of Broadcast RGB always affect the color pipeline processing
>> such that a full-range input to the CRTC is converted to either full- or
>> limited-range, depending on what the monitor is supposed to accept.
>>
>> When automatic is selected, does that mean that there is no signalling,
>> or that the signalling matches what the monitor is supposed to accept
>> according to the spec? Also, is this really HDMI specific?
> 
> Automatic is based on the mode as described in the specs
> below. Basically certain modes are expected to be broadcast range, and
> others full range.
> 
> I don't remember why we don't use the full range if the display
> indicates it supports selectable quantization range in Video
> Capabilities Data Block. It's quite possible there are displays that
> declare support but don't. Cc: Ville.

I have not seen such displays. Enabling RGB Selectable Quantization Range
is something that a vendor has to do explicitly, so it is reasonable to
expect that it works, otherwise there would be no point to that flag!

Transmitting full range if possible gives a better picture quality and
so is recommended.

> 
> - HDMI 1.4b section 6.6 Video Quantization Ranges
> 
> - HDMI 2.1 section 7.3 Video Quantization Ranges
> 
> - DP 2.1 (and earlier) section 5.1.1.1 Video Colorimetry
> 
> - CTA-861-H (and earlier) section 5.1 Default Encoding Parameters and
>   section 6.4.3 Quantization Range

Note that CTA-861-H deprecated the use of Default Range in the AVI
InfoFrame, instead the source should always signal limited or full range
in the Q field.

Regards,

Hans

> 
>> When full or limited is selected and the monitor doesn't support the
>> signalling, what happens?
> 
> 1) Limited selected, display expects full, colors seem washed out.
> 
> 2) Full selected, display expects limited, black screen possible.
> 
> We receive the occasional bug report for 1, because there are displays
> that incorrectly expect full when spec says it should be limited. We
> reject the bug reports, because erring the other way can lead to black
> screens.
> 
> 
> BR,
> Jani.
> 
> 
> 



Re: [PATCH v3,04/21] v4l: add documentation for secure memory flag

2024-01-08 Thread Hans Verkuil
On 04/01/2024 21:05, Jeffrey Kardatzke wrote:
> On Mon, Dec 11, 2023 at 3:05 AM Hans Verkuil  wrote:
>>
>> On 06/12/2023 09:15, Yunfei Dong wrote:
>>> From: Jeffrey Kardatzke 
>>>
>>> Adds documentation for V4L2_MEMORY_FLAG_SECURE.
>>>
>>> Signed-off-by: Jeffrey Kardatzke 
>>> Signed-off-by: Yunfei Dong 
>>> ---
>>>  Documentation/userspace-api/media/v4l/buffer.rst | 8 +++-
>>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
>>> b/Documentation/userspace-api/media/v4l/buffer.rst
>>> index 52bbee81c080..a5a7d1c72d53 100644
>>> --- a/Documentation/userspace-api/media/v4l/buffer.rst
>>> +++ b/Documentation/userspace-api/media/v4l/buffer.rst
>>> @@ -696,7 +696,7 @@ enum v4l2_memory
>>>
>>>  .. _memory-flags:
>>>
>>> -Memory Consistency Flags
>>> +Memory Flags
>>>  
>>>
>>>  .. raw:: latex
>>> @@ -728,6 +728,12 @@ Memory Consistency Flags
>>>   only if the buffer is used for :ref:`memory mapping ` I/O and 
>>> the
>>>   queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
>>>   ` capability.
>>> +* .. _`V4L2-MEMORY-FLAG-SECURE`:
>>> +
>>> +  - ``V4L2_MEMORY_FLAG_SECURE``
>>> +  - 0x0002
>>> +  - DMA bufs passed into the queue will be validated to ensure they 
>>> were
>>> + allocated from a secure dma-heap.
>>
>> Hmm, that needs a bit more work. How about:
>>
>> - The queued buffers are expected to be in secure memory. If not, an error 
>> will be
>>   returned. This flag can only be used with ``V4L2_MEMORY_DMABUF``. Typically
>>   secure buffers are allocated using a secure dma-heap. This flag can only be
>>   specified if the ``V4L2_BUF_CAP_SUPPORTS_SECURE_MEM`` is set.
>>
> 
> Thanks Hans. Yunfei, can you integrate this change into the patch please?
> 
>> In addition, the title of this table is currently "Memory Consistency 
>> Flags": that
>> should be renamed to "Memory Flags".
> 
> Hans, the patch is already renaming the table as you suggested. :)
> (unless there's some other spot I'm missing)

Sorry for the noise, I missed that change.

Regards,

Hans

>>
>> Regards,
>>
>> Hans
>>
>>>
>>>  .. raw:: latex
>>>
>>



Re: [PATCH v3,04/21] v4l: add documentation for secure memory flag

2023-12-11 Thread Hans Verkuil
On 06/12/2023 09:15, Yunfei Dong wrote:
> From: Jeffrey Kardatzke 
> 
> Adds documentation for V4L2_MEMORY_FLAG_SECURE.
> 
> Signed-off-by: Jeffrey Kardatzke 
> Signed-off-by: Yunfei Dong 
> ---
>  Documentation/userspace-api/media/v4l/buffer.rst | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
> b/Documentation/userspace-api/media/v4l/buffer.rst
> index 52bbee81c080..a5a7d1c72d53 100644
> --- a/Documentation/userspace-api/media/v4l/buffer.rst
> +++ b/Documentation/userspace-api/media/v4l/buffer.rst
> @@ -696,7 +696,7 @@ enum v4l2_memory
>  
>  .. _memory-flags:
>  
> -Memory Consistency Flags
> +Memory Flags
>  
>  
>  .. raw:: latex
> @@ -728,6 +728,12 @@ Memory Consistency Flags
>   only if the buffer is used for :ref:`memory mapping ` I/O and the
>   queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS
>   ` capability.
> +* .. _`V4L2-MEMORY-FLAG-SECURE`:
> +
> +  - ``V4L2_MEMORY_FLAG_SECURE``
> +  - 0x0002
> +  - DMA bufs passed into the queue will be validated to ensure they were
> + allocated from a secure dma-heap.

Hmm, that needs a bit more work. How about:

- The queued buffers are expected to be in secure memory. If not, an error will 
be
  returned. This flag can only be used with ``V4L2_MEMORY_DMABUF``. Typically
  secure buffers are allocated using a secure dma-heap. This flag can only be
  specified if the ``V4L2_BUF_CAP_SUPPORTS_SECURE_MEM`` is set.

In addition, the title of this table is currently "Memory Consistency Flags": 
that
should be renamed to "Memory Flags".

Regards,

Hans

>  
>  .. raw:: latex
>  



Re: [PATCH v3,03/21] v4l2: verify secure dmabufs are used in secure queue

2023-12-11 Thread Hans Verkuil
On 06/12/2023 09:15, Yunfei Dong wrote:
> From: Jeffrey Kardatzke 
> 
> Verfies in the dmabuf implementations that if the secure memory flag is

Verfies -> Verifies

> set for a queue that the dmabuf submitted to the queue is unmappable.
> 
> Signed-off-by: Jeffrey Kardatzke 
> Signed-off-by: Yunfei Dong 
> ---
>  drivers/media/common/videobuf2/videobuf2-dma-contig.c | 6 ++
>  drivers/media/common/videobuf2/videobuf2-dma-sg.c | 6 ++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c 
> b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> index 3d4fd4ef5310..ad58ef8dc231 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> @@ -710,6 +710,12 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
>   return -EINVAL;
>   }
>  
> + /* verify the dmabuf is secure if we are in secure mode */
> + if (buf->vb->vb2_queue->secure_mem && sg_page(sgt->sgl)) {

This needs a bit more explanation. I guess that for secure memory
sg_page returns NULL?

> + pr_err("secure queue requires secure dma_buf");
> + return -EINVAL;
> + }
> +
>   /* checking if dmabuf is big enough to store contiguous chunk */
>   contig_size = vb2_dc_get_contiguous_size(sgt);
>   if (contig_size < buf->size) {
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c 
> b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> index 28f3fdfe23a2..55428c73c380 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> @@ -564,6 +564,12 @@ static int vb2_dma_sg_map_dmabuf(void *mem_priv)
>   return -EINVAL;
>   }
>  
> + /* verify the dmabuf is secure if we are in secure mode */
> + if (buf->vb->vb2_queue->secure_mem && !sg_dma_secure(sgt->sgl)) {

I can't find the sg_dma_secure function. I suspect this patch series
depends on another series?

> + pr_err("secure queue requires secure dma_buf");
> + return -EINVAL;
> + }
> +
>   buf->dma_sgt = sgt;
>   buf->vaddr = NULL;
>  

Regards,

Hans


Re: [PATCH v3,02/21] v4l2: handle secure memory flags in queue setup

2023-12-11 Thread Hans Verkuil
Hi Yunfei, Jeffrey,

Some comments below:

On 06/12/2023 09:15, Yunfei Dong wrote:
> From: Jeffrey Kardatzke 
> 
> Validates the secure memory flags when setting up a queue and ensures
> the queue has the proper capability.
> 
> Signed-off-by: Jeffrey Kardatzke 
> Signed-off-by: Yunfei Dong 
> ---
>  .../media/common/videobuf2/videobuf2-core.c   | 23 +
>  .../media/common/videobuf2/videobuf2-v4l2.c   | 34 +--
>  2 files changed, 46 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
> b/drivers/media/common/videobuf2/videobuf2-core.c
> index 8c1df829745b..09dc030484be 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -813,6 +813,15 @@ static bool verify_coherency_flags(struct vb2_queue *q, 
> bool non_coherent_mem)
>   return true;
>  }
>  
> +static bool verify_secure_mem_flags(struct vb2_queue *q, bool secure_mem)
> +{
> + if (secure_mem != q->secure_mem) {
> + dprintk(q, 1, "secure memory model mismatch\n");
> + return false;
> + }
> + return true;
> +}
> +
>  int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
>unsigned int flags, unsigned int *count)
>  {
> @@ -820,6 +829,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   unsigned int q_num_bufs = vb2_get_num_buffers(q);
>   unsigned plane_sizes[VB2_MAX_PLANES] = { };
>   bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
> + bool secure_mem = flags & V4L2_MEMORY_FLAG_SECURE;
>   unsigned int i;
>   int ret = 0;
>  
> @@ -836,6 +846,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   if (*count == 0 || q_num_bufs != 0 ||
>   (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory) ||
>   !verify_coherency_flags(q, non_coherent_mem)) {
> + bool no_previous_buffers = !q->num_buffers;
> +
>   /*
>* We already have buffers allocated, so first check if they
>* are not in use and can be freed.
> @@ -854,6 +866,12 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   __vb2_queue_free(q, q_num_bufs);
>   mutex_unlock(&q->mmap_lock);
>  
> + /*
> +  * Do not allow switching secure buffer mode.
> +  */
> + if (!no_previous_buffers && !verify_secure_mem_flags(q, 
> secure_mem))
> + return -EINVAL;
> +

Why is this needed? Here VIDIOC_REQBUFS is called either to just delete
all existing buffers (count == 0), or to delete all existing buffers and
allocate new buffers (count > 0).

Since in both cases all existing buffers are deleted, you are free to choose
whatever new secure mode you want.

>   /*
>* In case of REQBUFS(0) return immediately without calling
>* driver's queue_setup() callback and allocating resources.
> @@ -882,6 +900,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   if (ret)
>   return ret;
>   set_queue_coherency(q, non_coherent_mem);
> + q->secure_mem = secure_mem;
>  
>   /*
>* Ask the driver how many buffers and planes per buffer it requires.
> @@ -986,6 +1005,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   unsigned plane_sizes[VB2_MAX_PLANES] = { };
>   bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
>   unsigned int q_num_bufs = vb2_get_num_buffers(q);
> + bool secure_mem = flags & V4L2_MEMORY_FLAG_SECURE;
>   bool no_previous_buffers = !q_num_bufs;
>   int ret = 0;
>  
> @@ -1015,6 +1035,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   return ret;
>   q->waiting_for_buffers = !q->is_output;
>   set_queue_coherency(q, non_coherent_mem);
> + q->secure_mem = secure_mem;
>   } else {
>   if (q->memory != memory) {
>   dprintk(q, 1, "memory model mismatch\n");
> @@ -1022,6 +1043,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   }
>   if (!verify_coherency_flags(q, non_coherent_mem))
>   return -EINVAL;
> + if (!verify_secure_mem_flags(q, secure_mem))
> + return -EINVAL;
>   }
>  
>   num_buffers = min(*count, q->max_num_buffers - q_num_bufs);
> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c 
> b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> index 54d572c3b515..0a530830276c 100644
> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> @@ -686,22 +686,30 @@ static void fill_buf_caps(struct vb2_queue *q, u32 
> *caps)
>   *caps |= V4L2_BUF_CAP_SUPPORTS_MMA

Re: [PATCH v3,16/21] media: medkatek: vcodec: support one plane capture buffer

2023-12-06 Thread Hans Verkuil
On 06/12/2023 09:15, Yunfei Dong wrote:
> The capture buffer has two planes for format MM21, but user space only
> allocate secure memory for plane[0], and the size is Y data + uv data.
> The driver need to support one plane decoder for svp mode.

For a future v4: note the typo in the Subject line: medkatek -> mediatek.
It's present in patches 16-20.

Regards,

Hans

> 
> Signed-off-by: Yunfei Dong 
> ---
>  .../mediatek/vcodec/decoder/mtk_vcodec_dec.c  |  7 -
>  .../vcodec/decoder/mtk_vcodec_dec_stateless.c | 26 ++-
>  .../decoder/vdec/vdec_h264_req_common.c   | 11 +++-
>  .../mediatek/vcodec/decoder/vdec_drv_if.c |  4 +--
>  4 files changed, 26 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c 
> b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
> index 604fdc8ee3ce..ab922e8d2d37 100644
> --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
> +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
> @@ -653,7 +653,12 @@ static int vidioc_vdec_g_fmt(struct file *file, void 
> *priv,
>* So we just return picinfo yet, and update picinfo in
>* stop_streaming hook function
>*/
> - q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
> +
> + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
> + q_data->sizeimage[0] = ctx->picinfo.fb_sz[0] + 
> ctx->picinfo.fb_sz[1];
> + else
> + q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
> +
>   q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
>   q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w;
>   q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w;
> diff --git 
> a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c 
> b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
> index cc42c942eb8a..707ed57a412e 100644
> --- 
> a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
> +++ 
> b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
> @@ -285,14 +285,14 @@ static struct vdec_fb *vdec_get_cap_buffer(struct 
> mtk_vcodec_dec_ctx *ctx)
>   framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
>  
>   pfb = &framebuf->frame_buffer;
> - pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
> + if (!ctx->is_secure_playback)
> + pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
>   pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
>   pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
>  
> - if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
> + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2 && 
> !ctx->is_secure_playback) {
>   pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
> - pfb->base_c.dma_addr =
> - vb2_dma_contig_plane_dma_addr(dst_buf, 1);
> + pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 
> 1);
>   pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
>   }
>   mtk_v4l2_vdec_dbg(1, ctx,
> @@ -339,16 +339,18 @@ static void mtk_vdec_worker(struct work_struct *work)
>   mtk_v4l2_vdec_dbg(3, ctx, "[%d] (%d) id=%d, vb=%p", ctx->id,
> vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
>  
> - bs_src->va = vb2_plane_vaddr(vb2_src, 0);
> - bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
> - bs_src->size = (size_t)vb2_src->planes[0].bytesused;
> - if (!bs_src->va) {
> - v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
> - mtk_v4l2_vdec_err(ctx, "[%d] id=%d source buffer is NULL", 
> ctx->id,
> -   vb2_src->index);
> - return;
> + if (!ctx->is_secure_playback) {
> + bs_src->va = vb2_plane_vaddr(vb2_src, 0);
> + if (!bs_src->va) {
> + v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
> + mtk_v4l2_vdec_err(ctx, "[%d] id=%d source buffer is 
> NULL", ctx->id,
> +   vb2_src->index);
> + return;
> + }
>   }
>  
> + bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
> + bs_src->size = (size_t)vb2_src->planes[0].bytesused;
>   mtk_v4l2_vdec_dbg(3, ctx, "[%d] Bitstream VA=%p DMA=%pad Size=%zx 
> vb=%p",
> ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, 
> vb2_src);
>   /* Apply request controls. */
> diff --git 
> a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c 
> b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_common.c
> index 5ca20d75dc8e..2a57e689ec07 100644
> --- 
> a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h

Re: [PATCH v4 00/45] drm/connector: Create HDMI Connector infrastructure

2023-11-28 Thread Hans Verkuil
On 28/11/2023 11:24, Maxime Ripard wrote:
> Hi,
> 
> Here's a series that creates some extra infrastructure specifically
> targeted at HDMI controllers.
> 
> The idea behind this series came from a recent discussion on IRC during
> which we discussed infoframes generation of i915 vs everything else.
> 
> Infoframes generation code still requires some decent boilerplate, with
> each driver doing some variation of it.
> 
> In parallel, while working on vc4, we ended up converting a lot of i915
> logic (mostly around format / bpc selection, and scrambler setup) to
> apply on top of a driver that relies only on helpers.
> 
> While currently sitting in the vc4 driver, none of that logic actually
> relies on any driver or hardware-specific behaviour.
> 
> The only missing piece to make it shareable are a bunch of extra
> variables stored in a state (current bpc, format, RGB range selection,
> etc.).
> 
> The initial implementation was relying on some generic subclass of
> drm_connector to address HDMI connectors, with a bunch of helpers that
> will take care of all the "HDMI Spec" related code. Scrambler setup is
> missing at the moment but can easily be plugged in.
> 
> The feedback was that creating a connector subclass like was done for
> writeback would prevent the adoption of those helpers since it couldn't
> be used in all situations (like when the connector driver can implement
> multiple output) and required more churn to cast between the
> drm_connector and its subclass. The decision was thus to provide a set
> of helper and to store the required variables in drm_connector and
> drm_connector_state. This what has been implemented now.
> 
> Hans Verkuil also expressed interest in implementing a mechanism in v4l2
> to retrieve infoframes from HDMI receiver and implementing an
> infoframe-decode tool.

For those who are interested in the InfoFrame parser:

https://git.linuxtv.org/hverkuil/edid-decode.git/log/?h=hverkuil

This is work-in-progress, and will definitely be rebased at times.

It is integrated into edid-decode since I want to be able to check the
InfoFrames against the EDID capabilities. If no EDID is given, then
those checks are skipped.

You can parse the InfoFrames with -I . All known InfoFrames
are parsed, and I am working on adding the checks against the EDID whenever
time permits.

It's quite handy already as a parser, but it is really the checks against the
EDID that will make this really useful.

A related note: exposing InfoFrames is equally useful for the media subsystem
for video receivers (and the odd V4L2 video transmitter driver). I did look
at whether any of this drm code could be generalized, but it is too different
and frankly not worth the effort.

Also, when receiving InfoFrames you don't want to use the hdmi.h functions,
you want to dump the raw unprocessed InfoFrame.

I did a proof-of-concept for the adv7511-v4l2 tx and adv7604 rx drivers here:

https://git.linuxtv.org/hverkuil/media_tree.git/commit/?h=infoframe&id=19c80e21b30e2cafc0669cfae093a0b7a17c6b55

I am using debugfs here as well, but I am not actually certain whether that's
the best approach, esp. for receivers where access to InfoFrames can be very
useful for userspace. Options are e.g. 
/sys/class/video4linux//infoframes
or perhaps using V4L2 controls. TBD.

Regards,

Hans

> 
> This series thus leverages the infoframe generation code to expose it
> through debugfs.
> 
> I also used the occasion to unit-test everything but the infoframe
> generation, which can come later once I get a proper understanding of
> what the infoframe are supposed to look like. This required to add some
> extra kunit helpers and infrastructure to have multiple EDIDs and allow
> each test to run with a particular set of capabilities.
> 
> This entire series has been tested on a Pi4, passes all its unittests
> (125 new tests), and has only been build-tested for sunxi and rockchip.
> 
> Let me know what you think,
> Maxime
> 
> Signed-off-by: Maxime Ripard 
> ---
> Changes in v4:
> - Create unit tests for everything but infoframes
> - Fix a number of bugs identified by the unit tests
> - Rename DRM (Dynamic Range and Mastering) infoframe file to HDR_DRM
> - Drop RFC status
> - Link to v3: 
> https://lore.kernel.org/r/20231031-kms-hdmi-connector-state-v3-0-328b0fae4...@kernel.org
> 
> Changes in v3:
> - Made sure the series work on the RaspberryPi4
> - Handle YUV420 in the char clock rate computation
> - Use the maximum bpc value the connector allows at reset
> - Expose the RGB Limited vs Full Range value in the connector state
>   instead of through a helper
> - Fix Broadcast RGB documentation
> - Add more debug logging
> - Small fixes here and there
> - Link to v2: 
> ht

Re: [PATCH 20/32] media/ivtvfb: Initialize fb_ops to fbdev I/O-memory helpers

2023-11-20 Thread Hans Verkuil
Hi Thomas,

On 15/11/2023 11:19, Thomas Zimmermann wrote:
> Initialize the instance of struct fb_ops with fbdev initializer
> macros for framebuffers in I/O address space. This explictily sets
> the read/write, draw and mmap callbacks to the correct default
> implementation.
> 
> Fbdev drivers sometimes rely on the callbacks being NULL for a
> default implementation to be invoked; hence requireing the I/O
> helpers to be built in any case. Setting all callbacks in all
> drivers explicitly will allow to make the I/O helpers optional.
> This benefits systems that do not use these functions.
> 
> Set the callbacks via macros. No functional changes.

Makes sense, shall I pick up this patch?

If you prefer to take it, then you can add:

Reviewed-by: Hans Verkuil 

Regards,

Hans

> 
> Signed-off-by: Thomas Zimmermann 
> Cc: Andy Walls 
> Cc: Mauro Carvalho Chehab 
> Cc: linux-me...@vger.kernel.org
> ---
>  drivers/media/pci/ivtv/Kconfig  | 4 +---
>  drivers/media/pci/ivtv/ivtvfb.c | 6 +++---
>  2 files changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/pci/ivtv/Kconfig b/drivers/media/pci/ivtv/Kconfig
> index 9be52101bc4f2..2498f9079b756 100644
> --- a/drivers/media/pci/ivtv/Kconfig
> +++ b/drivers/media/pci/ivtv/Kconfig
> @@ -48,9 +48,7 @@ config VIDEO_IVTV_ALSA
>  config VIDEO_FB_IVTV
>   tristate "Conexant cx23415 framebuffer support"
>   depends on VIDEO_IVTV && FB
> - select FB_CFB_FILLRECT
> - select FB_CFB_COPYAREA
> - select FB_CFB_IMAGEBLIT
> + select FB_IOMEM_HELPERS
>   help
> This is a framebuffer driver for the Conexant cx23415 MPEG
> encoder/decoder.
> diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
> index 23c8c094e791b..410477e3e6216 100644
> --- a/drivers/media/pci/ivtv/ivtvfb.c
> +++ b/drivers/media/pci/ivtv/ivtvfb.c
> @@ -927,17 +927,17 @@ static int ivtvfb_blank(int blank_mode, struct fb_info 
> *info)
>  
>  static const struct fb_ops ivtvfb_ops = {
>   .owner = THIS_MODULE,
> + .fb_read= fb_io_read,
>   .fb_write   = ivtvfb_write,
>   .fb_check_var   = ivtvfb_check_var,
>   .fb_set_par = ivtvfb_set_par,
>   .fb_setcolreg   = ivtvfb_setcolreg,
> - .fb_fillrect= cfb_fillrect,
> - .fb_copyarea= cfb_copyarea,
> - .fb_imageblit   = cfb_imageblit,
> + __FB_DEFAULT_IOMEM_OPS_DRAW,
>   .fb_cursor  = NULL,
>   .fb_ioctl   = ivtvfb_ioctl,
>   .fb_pan_display = ivtvfb_pan_display,
>   .fb_blank   = ivtvfb_blank,
> + __FB_DEFAULT_IOMEM_OPS_MMAP,
>  };
>  
>  /* Restore hardware after firmware restart */



Re: [PATCH RFC v3 12/37] drm/connector: hdmi: Create Infoframe DebugFS entries

2023-11-06 Thread Hans Verkuil
On 06/11/2023 15:44, Maxime Ripard wrote:
> Hi Hans,
> 
> On Fri, Nov 03, 2023 at 10:05:18AM +0100, Hans Verkuil wrote:
>> Hi Maxime,
>>
>> Thank you for posting v3, this time it runs fine on my RPi 4, thank you for
>> fixing that.
>>
>> I'll start working on a conformity checker for this.
> 
> Awesome :)

And anyone who is interested can find the work-in-progress for that here:

git://linuxtv.org/hverkuil/edid-decode.git

Use the -I option to point to the file containing the infoframe to parse
it. Later it will also check the conformity of the infoframe against the
display's EDID. That's why this is part of edid-decode since you need an
EDID parser to verify if the InfoFrames are also conform the standards.

> 
>>> +static int create_hdmi_infoframe_files(struct drm_connector *connector,
>>> +  struct dentry *parent)
>>> +{
>>> +   int ret;
>>> +
>>> +   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, audio);
>>> +   if (ret)
>>> +   return ret;
>>> +
>>> +   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, avi);
>>> +   if (ret)
>>> +   return ret;
>>> +
>>> +   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, drm);
>>
>> Hmm, I had to look into the code to figure out that 'drm' stands for
>> Dynamic Range and Mastering InfoFrame. While entirely correct, it is
>> also very confusing in the context of the 'drm' subsystem.
>>
>> I am not quite certain what the best approach is here.
>>
>> Internally in the drm code it is talking about 'hdr' or 'hdr metadata',
>> but that's a bit confusing as well since there is also an HDR Dynamic
>> Metadata Extended InfoFrame defined in CTA-861, even though support for
>> that is not (yet) implemented in drm.
>>
>> At minimum there should be a comment in the code explaining what drm
>> stands for in this context.
>>
>> One option to consider is renaming this file to hdr_drm, thus indicating
>> that this is HDR related.
> 
> I ended up doing both, thanks for the suggestion
> 
>>> +   if (ret)
>>> +   return ret;
>>> +
>>> +   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, spd);
>>> +   if (ret)
>>> +   return ret;
>>> +
>>> +   ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, vendor);
>>
>> There may be multiple vendor specific InfoFrames in the future, so how
>> would that be handled? Perhaps add a comment here that currently only one
>> vendor specific InfoFrame is supported, but suggest how to handle multiple
>> VSIFs in the future.
>>
>> What would actually be nice (although probably not that easy to fix) is if
>> the name of the file would be "vendor-XX' where 'XX' is the IEEE OUI
>> number.
> 
> I guess it's not entirely clear to me what that would look like. In
> order for the framework to create the debugfs files, we would need some
> enumeration mechanism (probably through a callback?), and then the
> driver would generate the entire content of that file.
> 
> Which makes me question whether the framework should be initialised at
> all? Maybe the simpler would be to just have drivers maintain their own
> debugfs files and storing the content in their own, private, structure.

It's a good question. And I also would like to use this for HDMI receivers
(so using it in the media subsystem).

Let me try and find some time this week or next week to dig into this a bit
more and see if I can implement it on the media side as well. See what would
be the best approach here.

It would not surprise me if the debugfs part should move to video/hdmi.c
since that's already used by both drm and media.

Regards,

Hans

> 
> Maxime



Re: [PATCH RFC v3 12/37] drm/connector: hdmi: Create Infoframe DebugFS entries

2023-11-03 Thread Hans Verkuil
Hi Maxime,

Thank you for posting v3, this time it runs fine on my RPi 4, thank you for
fixing that.

I'll start working on a conformity checker for this.

I have a few remarks:

On 31/10/2023 17:48, Maxime Ripard wrote:
> There has been some discussions recently about the infoframes sent by
> drivers and if they were properly generated.
> 
> In parallel, there's been some interest in creating an infoframe-decode
> tool similar to edid-decode.
> 
> Both would be much easier if we were to expose the infoframes programmed
> in the hardware. It won't be perfect since we have no guarantee that
> it's actually what goes through the wire, but it's the best we can do.
> 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/drm_debugfs.c | 110 
> ++
>  1 file changed, 110 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
> index 2de43ff3ce0a..3c65b1d3f926 100644
> --- a/drivers/gpu/drm/drm_debugfs.c
> +++ b/drivers/gpu/drm/drm_debugfs.c
> @@ -538,6 +538,114 @@ static const struct file_operations drm_connector_fops 
> = {
>   .write = connector_write
>  };
>  
> +struct debugfs_wrapper {
> + struct drm_connector *connector;
> + struct drm_connector_hdmi_infoframe *frame;
> +};
> +
> +#define HDMI_MAX_INFOFRAME_SIZE  29
> +
> +static ssize_t
> +infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t 
> *ppos)
> +{
> + const struct debugfs_wrapper *wrapper = filp->private_data;
> + struct drm_connector *connector = wrapper->connector;
> + struct drm_connector_hdmi_infoframe *infoframe = wrapper->frame;
> + union hdmi_infoframe *frame = &infoframe->data;
> + u8 buf[HDMI_MAX_INFOFRAME_SIZE];
> + ssize_t len = 0;
> +
> + mutex_lock(&connector->hdmi.infoframes.lock);
> +
> + if (!infoframe->set)
> + goto out;
> +
> + len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
> + if (len < 0)
> + goto out;
> +
> + len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
> +
> +out:
> + mutex_unlock(&connector->hdmi.infoframes.lock);
> + return len;
> +}
> +
> +static const struct file_operations infoframe_fops = {
> + .owner   = THIS_MODULE,
> + .open= simple_open,
> + .read= infoframe_read,
> +};
> +
> +static int create_hdmi_infoframe_file(struct drm_connector *connector,
> +   struct dentry *parent,
> +   const char *filename,
> +   struct drm_connector_hdmi_infoframe 
> *frame)
> +{
> + struct drm_device *dev = connector->dev;
> + struct debugfs_wrapper *wrapper;
> + struct dentry *file;
> +
> + wrapper = drmm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
> + if (!wrapper)
> + return -ENOMEM;
> +
> + wrapper->connector = connector;
> + wrapper->frame = frame;
> +
> + file = debugfs_create_file(filename, 0400, parent, wrapper, 
> &infoframe_fops);
> + if (IS_ERR(file))
> + return PTR_ERR(file);
> +
> + return 0;
> +}
> +
> +#define CREATE_HDMI_INFOFRAME_FILE(c, p, i)  \
> + create_hdmi_infoframe_file(c, p, #i, &(c)->hdmi.infoframes.i)
> +
> +static int create_hdmi_infoframe_files(struct drm_connector *connector,
> +struct dentry *parent)
> +{
> + int ret;
> +
> + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, audio);
> + if (ret)
> + return ret;
> +
> + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, avi);
> + if (ret)
> + return ret;
> +
> + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, drm);

Hmm, I had to look into the code to figure out that 'drm' stands for
Dynamic Range and Mastering InfoFrame. While entirely correct, it is
also very confusing in the context of the 'drm' subsystem.

I am not quite certain what the best approach is here.

Internally in the drm code it is talking about 'hdr' or 'hdr metadata',
but that's a bit confusing as well since there is also an HDR Dynamic
Metadata Extended InfoFrame defined in CTA-861, even though support for
that is not (yet) implemented in drm.

At minimum there should be a comment in the code explaining what drm
stands for in this context.

One option to consider is renaming this file to hdr_drm, thus indicating
that this is HDR related.

> + if (ret)
> + return ret;
> +
> + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, spd);
> + if (ret)
> + return ret;
> +
> + ret = CREATE_HDMI_INFOFRAME_FILE(connector, parent, vendor);

There may be multiple vendor specific InfoFrames in the future, so how
would that be handled? Perhaps add a comment here that currently only one
vendor specific InfoFrame is supported, but suggest how to handle multiple
VSIFs in the future.

What would actually be nice (although probably not that easy to fix) is if
the name of

Re: [PATCH v3 3/9] drm/vc4: hdmi: Add Broadcast RGB property to allow override of RGB range

2023-10-19 Thread Hans Verkuil
Hi Maxime,

On 19/10/2023 10:02, Maxime Ripard wrote:
> Hi,
> 
> On Wed, Oct 11, 2023 at 03:23:18PM +0200, Daniel Vetter wrote:
>> On Mon, 6 Mar 2023 at 11:49, Maxime Ripard  wrote:
>>>
>>> From: Dave Stevenson 
>>>
>>> Copy Intel's "Broadcast RGB" property semantics to add manual override
>>> of the HDMI pixel range for monitors that don't abide by the content
>>> of the AVI Infoframe.
>>>
>>> Signed-off-by: Dave Stevenson 
>>> Signed-off-by: Maxime Ripard 
>>
>> Stumbled over this grepping around, but would have been nice to lift
>> this into drm code and document the property. It's one of the legacy
>> ones from the table of horrors after all ...
>>
>> Shouldn't be an uapi problem because it's copypasted to much, just not great.
> 
> We already discussed it on IRC, but just for the record I have a current
> series that should address exactly that:
> 
> https://lore.kernel.org/dri-devel/20230920-kms-hdmi-connector-state-v2-3-17932dadd...@kernel.org/
> 
> Maxime

I've pasted a snippet from that patch below for a quick review:

>  /**
>   * DOC: HDMI connector properties
>   *
> + * Broadcast RGB (HDMI Specific):

Full vs Limited is actually not HDMI specific, DisplayPort can signal this as
well for whatever it is worth.

> + *  Indicates the RGB Range (Full vs Limited) used.

RGB Range -> RGB Quantization Range

> + *
> + *  The value of this property can be one of the following:
> + *
> + *  Automatic:
> + *  RGB Range is selected automatically based on the mode
> + *  according to the HDMI specifications.
> + *
> + *  Full:
> + *  Full RGB Range is forced.
> + *
> + *  Limited 16:235:

It is very unfortunate that this is called "Limited 16:235" instead of just 
"Limited"
since for color component bit depths > 8 these values are different.

I have no idea if it is possible to add an alias "Limited" that you can use 
instead.
In any case, this should document that it works just as well for higher bit 
depths,
but with different limits.

Regards,

Hans

> + *  Limited RGB Range is forced.
> + *
> + *  Drivers can set up this property by calling
> + *  drm_connector_attach_broadcast_rgb_property().
> + *
>   * content type (HDMI specific):
>   *   Indicates content type setting to be used in HDMI infoframes to indicate
>   *   content type for the external device, so that it adjusts its display



Re: [PATCH RFC v2 00/37] drm/connector: Create HDMI Connector infrastructure

2023-09-21 Thread Hans Verkuil
On 20/09/2023 16:35, Maxime Ripard wrote:
> Hi,
> 
> Here's a series that creates a subclass of drm_connector specifically
> targeted at HDMI controllers.
> 
> The idea behind this series came from a recent discussion on IRC during
> which we discussed infoframes generation of i915 vs everything else. 
> 
> Infoframes generation code still requires some decent boilerplate, with
> each driver doing some variation of it.
> 
> In parallel, while working on vc4, we ended up converting a lot of i915
> logic (mostly around format / bpc selection, and scrambler setup) to
> apply on top of a driver that relies only on helpers.
> 
> While currently sitting in the vc4 driver, none of that logic actually
> relies on any driver or hardware-specific behaviour.
> 
> The only missing piece to make it shareable are a bunch of extra
> variables stored in a state (current bpc, format, RGB range selection,
> etc.).
> 
> The initial implementation was relying on some generic subclass of
> drm_connector to address HDMI connectors, with a bunch of helpers that
> will take care of all the "HDMI Spec" related code. Scrambler setup is
> missing at the moment but can easily be plugged in.
> 
> The feedback was that creating a connector subclass like was done for
> writeback would prevent the adoption of those helpers since it couldn't
> be used in all situations (like when the connector driver can implement
> multiple output) and required more churn to cast between the
> drm_connector and its subclass. The decision was thus to provide a set
> of helper and to store the required variables in drm_connector and
> drm_connector_state. This what has been implemented now.
> 
> Hans Verkuil also expressed interest in implementing a mechanism in v4l2
> to retrieve infoframes from HDMI receiver and implementing an
> infoframe-decode tool.

I'd love to get started on that, but...

> 
> This series thus leverages the infoframe generation code to expose it
> through debugfs.
> 
> This entire series is only build-tested at the moment. Let me know what
> you think,

...trying this series on my RPi4 gives me this during boot:

[2.361239] vc4-drm gpu: bound fe40.hvs (ops 0x800080cac6f8)
[2.367834] Unable to handle kernel NULL pointer dereference at virtual 
address 0090
[2.376748] Mem abort info:
[2.379570]   ESR = 0x9644
[2.383367]   EC = 0x25: DABT (current EL), IL = 32 bits
[2.388748]   SET = 0, FnV = 0
[2.391835]   EA = 0, S1PTW = 0
[2.395011]   FSC = 0x04: level 0 translation fault
[2.399951] Data abort info:
[2.402864]   ISV = 0, ISS = 0x0044, ISS2 = 0x
[2.408420]   CM = 0, WnR = 1, TnD = 0, TagAccess = 0
[2.413536]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[2.418916] [0090] user address but active_mm is swapper
[2.425353] Internal error: Oops: 9644 [#1] PREEMPT SMP
[2.431700] Modules linked in:
[2.434791] CPU: 2 PID: 55 Comm: kworker/u8:3 Not tainted 6.6.0-rc1-hdmi-dbg 
#245
[2.442372] Hardware name: Raspberry Pi 4 Model B Rev 1.4 (DT)
[2.448278] Workqueue: events_unbound deferred_probe_work_func
[2.454193] pstate: 8005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[2.461245] pc : drm_connector_attach_max_bpc_property+0x48/0x90
[2.467332] lr : drm_connector_attach_max_bpc_property+0x3c/0x90
[2.473415] sp : 800081d038b0
[2.476766] x29: 800081d038b0 x28:  x27: 0001041968c0
[2.483999] x26:  x25: 00010339d558 x24: 000103399000
[2.491231] x23: 800080caa3e8 x22: 800080e96a20 x21: 000c
[2.498463] x20: 000c x19: 00010339d558 x18: 
[2.505694] x17: 0001008e7650 x16: 800080d55500 x15: 
[2.512926] x14: 000105dda209 x13: 0006 x12: 0001
[2.520158] x11: 0101010101010101 x10: 00027effe219 x9 : 0001
[2.527389] x8 : 000105db8ad4 x7 : c0c0c0c0 x6 : c0c0c0c0
[2.534620] x5 :  x4 : 00010339d728 x3 : 00010339d728
[2.541852] x2 : 000c x1 :  x0 : 
[2.549083] Call trace:
[2.551554]  drm_connector_attach_max_bpc_property+0x48/0x90
[2.557285]  drmm_connector_hdmi_init+0x114/0x14c
[2.562048]  vc4_hdmi_bind+0x320/0xa40
[2.565842]  component_bind_all+0x114/0x23c
[2.570077]  vc4_drm_bind+0x148/0x2c0
[2.573784]  try_to_bring_up_aggregate_device+0x168/0x1d4
[2.579253]  __component_add+0xa4/0x16c
[2.583136]  component_add+0x14/0x20
[2.586754]  vc4_hdmi_dev_probe+0x1c/0x28
[2.590815]  platform_probe+0x68/0xc4
[2.594522]  really_probe+0x148/0x2b0
[2.598228]  __driver_probe_device+0x78/0x12c
[2.602638]  driver_pr

Re: [PATCH v5 00/14] add support MDP3 on MT8195 platform

2023-09-15 Thread Hans Verkuil
Hi Moudy,

On 12/09/2023 09:57, Moudy Ho wrote:
> Changes since v4:
> - Rebase on v6.6-rc1
> - Remove any unnecessary DTS settings.
> - Adjust the usage of MOD and clock in blending components.
> 
> Changes since v3:
> - Depend on :
>   [1] https://patchwork.kernel.org/project/linux-media/list/?series=719841
> - Suggested by Krzysztof, integrating all newly added bindings for
>   the mt8195 MDP3 into the file "mediatek,mt8195-mdp3.yaml".
> - Revise MDP3 nodes with generic names.
> 
> Changes since v2:
> - Depend on :
>   [1] MMSYS/MUTEX: 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=711592
>   [2] MDP3: 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=711618
> - Suggested by Rob to revise MDP3 bindings to pass dtbs check
> - Add parallel paths feature.
> - Add blended components settings.
> 
> Changes since v1:
> - Depend on :
>   [1] MDP3 : 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=698872
>   [2] MMSYS/MUTEX: 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=684959
> - Fix compilation failure due to use of undeclared identifier in file 
> "mtk-mdp3-cmdq.c"
> 
> Hello,
> 
> This patch is used to add support for MDP3 on the MT8195 platform that
> contains more picture quality components, and can arrange more pipelines
> through two sets of MMSYS and MUTEX respectively.

I ran this series through our build system and I got the following compile 
warning:

drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c: In function 
'mdp_path_config.isra':
drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c:449:51: warning: 'ctx' may 
be used uninitialized [-Wmaybe-uninitialized]
  449 | out = CFG_COMP(MT8195, ctx->param, outputs[0]);
  |~~~^~~
drivers/media/platform/mediatek/mdp3/mtk-img-ipi.h:137:25: note: in definition 
of macro 'CFG_COMP'
  137 | (IS_ERR_OR_NULL(comp) ? 0 : _CFG_COMP(plat, comp, mem))
  | ^~~~
drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c:402:30: note: 'ctx' was 
declared here
  402 | struct mdp_comp_ctx *ctx;
  |  ^~~

And also a few smatch warnings/errors:

drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c:871 wait_wrot_event() 
warn: variable dereferenced before check 'mdp_cfg' (see line 864)
drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c:1024 reset_luma_hist() 
warn: variable dereferenced before check 'mdp_cfg' (see line 1015)
drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c:447 mdp_path_config() 
error: potentially dereferencing uninitialized 'ctx'.
drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c:449 mdp_path_config() 
error: potentially dereferencing uninitialized 'ctx'.

You can run the same tests yourself, see this announcement:

https://lore.kernel.org/linux-media/18989016-6392-a77b-6cf7-1223c9161...@xs4all.nl/

Regards,

Hans

> 
> Moudy Ho (14):
>   arm64: dts: mediatek: mt8183: correct MDP3 DMA-related nodes
>   arm64: dts: mediatek: mt8195: add MDP3 nodes
>   media: platform: mtk-mdp3: add support second sets of MMSYS
>   media: platform: mtk-mdp3: add support second sets of MUTEX
>   media: platform: mtk-mdp3: introduce more pipelines from MT8195
>   media: platform: mtk-mdp3: introduce more MDP3 components
>   media: platform: mtk-mdp3: add checks for dummy components
>   media: platform: mtk-mdp3: avoid multiple driver registrations
>   media: platform: mtk-mdp3: extend GCE event waiting in RDMA and WROT
>   media: platform: mtk-mdp3: add support for blending multiple
> components
>   media: platform: mtk-mdp3: add mt8195 platform configuration
>   media: platform: mtk-mdp3: add mt8195 shared memory configurations
>   media: platform: mtk-mdp3: add mt8195 MDP3 component settings
>   media: platform: mtk-mdp3: add support for parallel pipe to improve
> FPS
> 
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi  |   6 +-
>  arch/arm64/boot/dts/mediatek/mt8195.dtsi  | 378 
>  .../platform/mediatek/mdp3/mdp_cfg_data.c | 729 ++-
>  .../platform/mediatek/mdp3/mdp_reg_aal.h  |  25 +
>  .../platform/mediatek/mdp3/mdp_reg_color.h|  31 +
>  .../media/platform/mediatek/mdp3/mdp_reg_fg.h |  23 +
>  .../platform/mediatek/mdp3/mdp_reg_hdr.h  |  31 +
>  .../platform/mediatek/mdp3/mdp_reg_merge.h|  25 +
>  .../platform/mediatek/mdp3/mdp_reg_ovl.h  |  25 +
>  .../platform/mediatek/mdp3/mdp_reg_pad.h  |  21 +
>  .../platform/mediatek/mdp3/mdp_reg_rdma.h |  24 +
>  .../platform/mediatek/mdp3/mdp_reg_rsz.h  |   2 +
>  .../platform/mediatek/mdp3/mdp_reg_tdshp.h|  34 +
>  .../platform/mediatek/mdp3/mdp_reg_wrot.h |   8 +
>  .../platform/mediatek/mdp3/mdp_sm_mt8195.h| 283 ++
>  .../platform/mediatek/mdp3/mtk-img-ipi.h  |   4 +
>  .../platform/mediatek/mdp3/mtk-mdp3-cfg.h |   2 +
>  .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c| 447 +++--
>  .../

Re: [PATCH v5 00/14] add support MDP3 on MT8195 platform

2023-09-15 Thread Hans Verkuil
On 12/09/2023 12:28, Chen-Yu Tsai wrote:
> On Tue, Sep 12, 2023 at 5:43 PM AngeloGioacchino Del Regno
>  wrote:
>>
>> Il 12/09/23 11:37, Chen-Yu Tsai ha scritto:
>>> On Tue, Sep 12, 2023 at 5:00 PM AngeloGioacchino Del Regno
>>>  wrote:

 Il 12/09/23 09:57, Moudy Ho ha scritto:
> Changes since v4:
> - Rebase on v6.6-rc1
> - Remove any unnecessary DTS settings.
> - Adjust the usage of MOD and clock in blending components.
>
> Changes since v3:
> - Depend on :
> [1] 
> https://patchwork.kernel.org/project/linux-media/list/?series=719841
> - Suggested by Krzysztof, integrating all newly added bindings for
> the mt8195 MDP3 into the file "mediatek,mt8195-mdp3.yaml".
> - Revise MDP3 nodes with generic names.
>
> Changes since v2:
> - Depend on :
> [1] MMSYS/MUTEX: 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=711592
> [2] MDP3: 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=711618
> - Suggested by Rob to revise MDP3 bindings to pass dtbs check
> - Add parallel paths feature.
> - Add blended components settings.
>
> Changes since v1:
> - Depend on :
> [1] MDP3 : 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=698872
> [2] MMSYS/MUTEX: 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=684959
> - Fix compilation failure due to use of undeclared identifier in file 
> "mtk-mdp3-cmdq.c"
>
> Hello,
>
> This patch is used to add support for MDP3 on the MT8195 platform that
> contains more picture quality components, and can arrange more pipelines
> through two sets of MMSYS and MUTEX respectively.
>
> Moudy Ho (14):
> arm64: dts: mediatek: mt8183: correct MDP3 DMA-related nodes
> arm64: dts: mediatek: mt8195: add MDP3 nodes

 Please send the DTS patches separately, those go through a different 
 maintainer.
>>>
>>> I thought most people prefer the _full_ view in a patchset?
>>>
>>
>> Yeah but those going through a different maintainer makes it more 
>> straightforward
>> to pick; besides, essentially, you can also get a full view with dt-bindings
>> patches instead of devicetrees, as the latter are "constructed from" bindings
>> anyway.
> 
> Sure, but testing, especially by people not in the recipients or CC list,
> is a bit painful when the full set of patches isn't bundled together.
> Having them bundled together shows what the submitter tested and makes
> it easier for others to reproduce.
> 
> AFAIK other ARM platforms have been sending patches all grouped together.
> It's MediaTek that has been different, as they normally have (for Chromebooks)
> a system integration engineer handling the device tree stuff, while component
> driver owners just handle the drivers, and by extension, the DT bindings.
> 
>> Moreover, it would be definitely nice to add a link to the devicetree series
>> in the cover letter of this series, so that people *do* get a full overview
>> by checking both series :-)
> 
> Most maintainers seem to know what to do: apply the subset destined for
> their tree. At least the subsystems that frequently deal with DT-based
> platforms anyway.

As maintainer I know that I need to skip dts patches, but there is a risk that
I forget to drop them. So my preference is also to have them as a separate
patch series, but it's a preference only. If you *do* send it as a separate 
series,
then also include the linux-media mailinglist in the CC, that way I do have
the full overview if I need it.

Regards,

Hans

> 
> 
> ChenYu
> 
>> Cheers!
>>
 P.S.: The dt-bindings patch can be sent inside of this series, please do 
 that.

 Thanks!
 Angelo


>>



Re: [PATCH 0/6] drm, cec and edid updates

2023-08-31 Thread Hans Verkuil
On 31/08/2023 20:51, Jani Nikula wrote:
> On Thu, 24 Aug 2023, Jani Nikula  wrote:
>> Avoid accessing the raw edid directly. Pre-parse the source physical
>> address during normal EDID parsing and use that for CEC.
>>
>> Jani Nikula (6):
>>   drm/edid: add drm_edid_is_digital()
>>   drm/i915/display: use drm_edid_is_digital()
>>   drm/edid: parse source physical address
>>   drm/cec: add drm_dp_cec_attach() as the non-edid version of set edid
>>   drm/i915/cec: switch to setting physical address directly
> 
> Maarten, Maxime, Thomas, ack for merging patches 1, 3 and 4 via via
> drm-intel?
> 
>>   media: cec: core: add note about *_from_edid() function usage in drm
> 
> Hans, while there's no build dependency here, I think it would make
> sense to merge this together with patches 3 and 4. Ack for merging via
> drm-intel?

That's fine, it makes sense to do that.

If you need it, for this series:

Acked-by: Hans Verkuil 

Regards,

Hans

> 
> Thanks,
> Jani.
> 
> 
>>
>>  drivers/gpu/drm/display/drm_dp_cec.c  | 22 +++---
>>  drivers/gpu/drm/drm_edid.c| 22 --
>>  drivers/gpu/drm/i915/display/intel_crt.c  | 11 ---
>>  drivers/gpu/drm/i915/display/intel_dp.c   |  7 ++-
>>  drivers/gpu/drm/i915/display/intel_hdmi.c |  8 +++-
>>  drivers/gpu/drm/i915/display/intel_sdvo.c |  7 ++-
>>  drivers/media/cec/core/cec-adap.c |  4 
>>  drivers/media/cec/core/cec-notifier.c |  4 
>>  include/drm/display/drm_dp_helper.h   |  6 ++
>>  include/drm/drm_connector.h   |  8 
>>  include/drm/drm_edid.h|  1 +
>>  11 files changed, 73 insertions(+), 27 deletions(-)
> 



Re: [PATCH v2] media: cec: core: add note about *_from_edid() function usage in drm

2023-08-31 Thread Hans Verkuil
On 31/08/2023 12:51, Jani Nikula wrote:
> In the drm subsystem, the source physical address is, in most cases,
> available without having to parse the EDID again. Add notes about
> preferring to use the pre-parsed address instead.
> 
> Cc: Hans Verkuil 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Jani Nikula 

Reviewed-by: Hans Verkuil 

Thanks!

Hans

> 
> ---
> 
> v2: rephrase comments, in particular indicate cec_s_phys_addr() should
> be false (Hans)
> ---
>  drivers/media/cec/core/cec-adap.c | 5 +
>  drivers/media/cec/core/cec-notifier.c | 5 +
>  2 files changed, 10 insertions(+)
> 
> diff --git a/drivers/media/cec/core/cec-adap.c 
> b/drivers/media/cec/core/cec-adap.c
> index 241b1621b197..1109af525c35 100644
> --- a/drivers/media/cec/core/cec-adap.c
> +++ b/drivers/media/cec/core/cec-adap.c
> @@ -1688,6 +1688,11 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 
> phys_addr, bool block)
>  }
>  EXPORT_SYMBOL_GPL(cec_s_phys_addr);
>  
> +/*
> + * Note: In the drm subsystem, prefer calling (if possible):
> + *
> + * cec_s_phys_addr(adap, connector->display_info.source_physical_address, 
> false);
> + */
>  void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
>  const struct edid *edid)
>  {
> diff --git a/drivers/media/cec/core/cec-notifier.c 
> b/drivers/media/cec/core/cec-notifier.c
> index 389dc664b211..d600be0f7b67 100644
> --- a/drivers/media/cec/core/cec-notifier.c
> +++ b/drivers/media/cec/core/cec-notifier.c
> @@ -195,6 +195,11 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, 
> u16 pa)
>  }
>  EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
>  
> +/*
> + * Note: In the drm subsystem, prefer calling (if possible):
> + *
> + * cec_notifier_set_phys_addr(n, 
> connector->display_info.source_physical_address);
> + */
>  void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
> const struct edid *edid)
>  {



Re: [PATCH v2] drm/cec: add drm_dp_cec_attach() as the non-edid version of set edid

2023-08-30 Thread Hans Verkuil
Hi Jani,

Sorry, I missed the v2.

On 25/08/2023 15:01, Jani Nikula wrote:
> Connectors have source physical address available in display
> info. There's no need to parse the EDID again for this. Add
> drm_dp_cec_attach() to do this.
> 
> Seems like the set_edid/unset_edid naming is a bit specific now that
> there's no need to pass the EDID at all, so aim for attach/detach going
> forward.
> 
> v2: Fix the embarrashing build failures
> 
> Cc: Hans Verkuil 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Jani Nikula 

Reviewed-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/gpu/drm/display/drm_dp_cec.c | 23 ---
>  include/drm/display/drm_dp_helper.h  |  6 ++
>  2 files changed, 26 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_cec.c 
> b/drivers/gpu/drm/display/drm_dp_cec.c
> index ae39dc794190..007ceb281d00 100644
> --- a/drivers/gpu/drm/display/drm_dp_cec.c
> +++ b/drivers/gpu/drm/display/drm_dp_cec.c
> @@ -14,6 +14,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  /*
>   * Unfortunately it turns out that we have a chicken-and-egg situation
> @@ -297,7 +298,7 @@ static void drm_dp_cec_unregister_work(struct work_struct 
> *work)
>   * were unchanged and just update the CEC physical address. Otherwise
>   * unregister the old CEC adapter and create a new one.
>   */
> -void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
> +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address)
>  {
>   struct drm_connector *connector = aux->cec.connector;
>   u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
> @@ -339,7 +340,7 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
> struct edid *edid)
>   if (aux->cec.adap->capabilities == cec_caps &&
>   aux->cec.adap->available_log_addrs == num_las) {
>   /* Unchanged, so just set the phys addr */
> - cec_s_phys_addr_from_edid(aux->cec.adap, edid);
> + cec_s_phys_addr(aux->cec.adap, source_physical_address, 
> false);
>   goto unlock;
>   }
>   /*
> @@ -370,11 +371,27 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
> struct edid *edid)
>* from drm_dp_cec_register_connector() edid == NULL, so in
>* that case the phys addr is just invalidated.
>*/
> - cec_s_phys_addr_from_edid(aux->cec.adap, edid);
> + cec_s_phys_addr(aux->cec.adap, source_physical_address, false);
>   }
>  unlock:
>   mutex_unlock(&aux->cec.lock);
>  }
> +EXPORT_SYMBOL(drm_dp_cec_attach);
> +
> +/*
> + * Note: Prefer calling drm_dp_cec_attach() with
> + * connector->display_info.source_physical_address if possible.
> + */
> +void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
> +{
> + u16 pa = CEC_PHYS_ADDR_INVALID;
> +
> + if (edid && edid->extensions)
> + pa = cec_get_edid_phys_addr((const u8 *)edid,
> + EDID_LENGTH * (edid->extensions + 
> 1), NULL);
> +
> + drm_dp_cec_attach(aux, pa);
> +}
>  EXPORT_SYMBOL(drm_dp_cec_set_edid);
>  
>  /*
> diff --git a/include/drm/display/drm_dp_helper.h 
> b/include/drm/display/drm_dp_helper.h
> index 86f24a759268..3369104e2d25 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -699,6 +699,7 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux);
>  void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
>  struct drm_connector *connector);
>  void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux);
> +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address);
>  void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid);
>  void drm_dp_cec_unset_edid(struct drm_dp_aux *aux);
>  #else
> @@ -716,6 +717,11 @@ static inline void 
> drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)
>  {
>  }
>  
> +static inline void drm_dp_cec_attach(struct drm_dp_aux *aux,
> +  u16 source_physical_address)
> +{
> +}
> +
>  static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,
>  const struct edid *edid)
>  {



Re: [PATCH 6/6] media: cec: core: add note about *_from_edid() function usage in drm

2023-08-30 Thread Hans Verkuil
On 24/08/2023 15:46, Jani Nikula wrote:
> In the drm subsystem, the source physical address is, in most cases,
> available without having to parse the EDID again. Add notes about
> preferring to use the pre-parsed address instead.
> 
> Cc: Hans Verkuil 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Jani Nikula 
> ---
>  drivers/media/cec/core/cec-adap.c | 4 
>  drivers/media/cec/core/cec-notifier.c | 4 
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/media/cec/core/cec-adap.c 
> b/drivers/media/cec/core/cec-adap.c
> index 241b1621b197..2c627ed611ed 100644
> --- a/drivers/media/cec/core/cec-adap.c
> +++ b/drivers/media/cec/core/cec-adap.c
> @@ -1688,6 +1688,10 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 
> phys_addr, bool block)
>  }
>  EXPORT_SYMBOL_GPL(cec_s_phys_addr);
>  
> +/*
> + * Note: In the drm subsystem, prefer calling cec_s_phys_addr() with
> + * connector->display_info.source_physical_address if possible.
> + */

I would rephrase this:

/*
 * Note: in the drm subsystem, prefer calling (if possible):
 *
 * cec_s_phys_addr(adap, connector->display_info.source_physical_address, 
false);
 */

I think it is important to indicate that the last argument should be 'false'.

>  void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
>  const struct edid *edid)
>  {
> diff --git a/drivers/media/cec/core/cec-notifier.c 
> b/drivers/media/cec/core/cec-notifier.c
> index 389dc664b211..13f043b3025b 100644
> --- a/drivers/media/cec/core/cec-notifier.c
> +++ b/drivers/media/cec/core/cec-notifier.c
> @@ -195,6 +195,10 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, 
> u16 pa)
>  }
>  EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
>  
> +/*
> + * Note: In the drm subsystem, prefer calling cec_notifier_set_phys_addr() 
> with
> + * connector->display_info.source_physical_address if possible.
> + */

This comment is fine, there is no similar last argument here. But perhaps
it is good to use a similar format as above. Up to you.

>  void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
> const struct edid *edid)
>  {

Regards,

Hans


Re: [PATCH 5/6] drm/i915/cec: switch to setting physical address directly

2023-08-30 Thread Hans Verkuil
On 24/08/2023 15:46, Jani Nikula wrote:
> Avoid parsing the EDID again for source physical address. Also gets rids
> of a few remaining raw EDID usages.
> 
> Cc: Hans Verkuil 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Jani Nikula 

Reviewed-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c   | 7 ++-
>  drivers/gpu/drm/i915/display/intel_hdmi.c | 5 ++---
>  2 files changed, 4 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 7067ee3a4bd3..c4b8e0e74c15 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5198,7 +5198,6 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
>   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>   struct intel_connector *connector = intel_dp->attached_connector;
>   const struct drm_edid *drm_edid;
> - const struct edid *edid;
>   bool vrr_capable;
>  
>   intel_dp_unset_edid(intel_dp);
> @@ -5216,10 +5215,8 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
>   intel_dp_update_dfp(intel_dp, drm_edid);
>   intel_dp_update_420(intel_dp);
>  
> - /* FIXME: Get rid of drm_edid_raw() */
> - edid = drm_edid_raw(drm_edid);
> -
> - drm_dp_cec_set_edid(&intel_dp->aux, edid);
> + drm_dp_cec_attach(&intel_dp->aux,
> +   connector->base.display_info.source_physical_address);
>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c 
> b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index aa9915098dda..5d6255ee8b54 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -2482,9 +2482,8 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>  
>   intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
>  
> - /* FIXME: Get rid of drm_edid_raw() */
> - cec_notifier_set_phys_addr_from_edid(intel_hdmi->cec_notifier,
> -  drm_edid_raw(drm_edid));
> + cec_notifier_set_phys_addr(intel_hdmi->cec_notifier,
> +
> connector->display_info.source_physical_address);
>  
>   return connected;
>  }



Re: [PATCH 4/6] drm/cec: add drm_dp_cec_attach() as the non-edid version of set edid

2023-08-30 Thread Hans Verkuil
On 24/08/2023 15:46, Jani Nikula wrote:
> Connectors have source physical address available in display
> info. There's no need to parse the EDID again for this. Add
> drm_dp_cec_attach() to do this.
> 
> Seems like the set_edid/unset_edid naming is a bit specific now that
> there's no need to pass the EDID at all, so aim for attach/detach going
> forward.
> 
> Cc: Hans Verkuil 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/display/drm_dp_cec.c | 22 +++---
>  include/drm/display/drm_dp_helper.h  |  6 ++
>  2 files changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_cec.c 
> b/drivers/gpu/drm/display/drm_dp_cec.c
> index ae39dc794190..da7a7d357446 100644
> --- a/drivers/gpu/drm/display/drm_dp_cec.c
> +++ b/drivers/gpu/drm/display/drm_dp_cec.c
> @@ -297,7 +297,7 @@ static void drm_dp_cec_unregister_work(struct work_struct 
> *work)
>   * were unchanged and just update the CEC physical address. Otherwise
>   * unregister the old CEC adapter and create a new one.
>   */
> -void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
> +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address)
>  {
>   struct drm_connector *connector = aux->cec.connector;
>   u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
> @@ -339,7 +339,7 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
> struct edid *edid)
>   if (aux->cec.adap->capabilities == cec_caps &&
>   aux->cec.adap->available_log_addrs == num_las) {
>   /* Unchanged, so just set the phys addr */
> - cec_s_phys_addr_from_edid(aux->cec.adap, edid);
> + cec_s_phys_addr(adap, source_physical_address, false);

As the kernel test robot indicated, this does not compile, this should
be aux->cec.adap.

>   goto unlock;
>   }
>   /*
> @@ -370,11 +370,27 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const 
> struct edid *edid)
>* from drm_dp_cec_register_connector() edid == NULL, so in
>* that case the phys addr is just invalidated.
>*/
> - cec_s_phys_addr_from_edid(aux->cec.adap, edid);
> + cec_s_phys_addr(adap, source_physical_address, false);
>   }
>  unlock:
>   mutex_unlock(&aux->cec.lock);
>  }
> +EXPORT_SYMBOL(drm_dp_cec_attach);
> +
> +/*
> + * Note: Prefer calling drm_dp_cec_attach() with
> + * connector->display_info.source_physical_address if possible.
> + */
> +void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
> +{
> + u16 source_physical_address = CEC_PHYS_ADDR_INVALID;
> +
> + if (edid && edid->extensions)

And this source needs to include , also as found by
the kernel test robot.

Regards,

Hans

> + pa = cec_get_edid_phys_addr((const u8 *)edid,
> + EDID_LENGTH * (edid->extensions + 
> 1), NULL);
> +
> + drm_dp_cec_attach(aux, source_physical_address);
> +}
>  EXPORT_SYMBOL(drm_dp_cec_set_edid);
>  
>  /*
> diff --git a/include/drm/display/drm_dp_helper.h 
> b/include/drm/display/drm_dp_helper.h
> index 86f24a759268..3369104e2d25 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -699,6 +699,7 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux);
>  void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
>  struct drm_connector *connector);
>  void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux);
> +void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address);
>  void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid);
>  void drm_dp_cec_unset_edid(struct drm_dp_aux *aux);
>  #else
> @@ -716,6 +717,11 @@ static inline void 
> drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)
>  {
>  }
>  
> +static inline void drm_dp_cec_attach(struct drm_dp_aux *aux,
> +  u16 source_physical_address)
> +{
> +}
> +
>  static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,
>  const struct edid *edid)
>  {



Re: [PATCH 3/6] drm/edid: parse source physical address

2023-08-30 Thread Hans Verkuil
On 24/08/2023 15:46, Jani Nikula wrote:
> CEC needs the source physical address. Parsing it is trivial with the
> existing EDID CEA DB infrastructure.
> 
> Default to CEC_PHYS_ADDR_INVALID (0x) instead of 0 to cater for
> easier CEC usage.
> 
> Cc: Hans Verkuil 
> Cc: linux-me...@vger.kernel.org
> Signed-off-by: Jani Nikula 

Reviewed-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/gpu/drm/drm_edid.c  | 5 +
>  include/drm/drm_connector.h | 8 
>  2 files changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 1dbb15439468..39dd3f694544 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -29,6 +29,7 @@
>   */
>  
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -6192,6 +6193,8 @@ drm_parse_hdmi_vsdb_video(struct drm_connector 
> *connector, const u8 *db)
>  
>   info->is_hdmi = true;
>  
> + info->source_physical_address = (db[4] << 8) | db[5];
> +
>   if (len >= 6)
>   info->dvi_dual = db[6] & 1;
>   if (len >= 7)
> @@ -6470,6 +6473,8 @@ static void drm_reset_display_info(struct drm_connector 
> *connector)
>   info->vics_len = 0;
>  
>   info->quirks = 0;
> +
> + info->source_physical_address = CEC_PHYS_ADDR_INVALID;
>  }
>  
>  static void update_displayid_info(struct drm_connector *connector,
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index d300fde6c1a4..40a5e7acf2fa 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -816,6 +816,14 @@ struct drm_display_info {
>* @quirks: EDID based quirks. Internal to EDID parsing.
>*/
>   u32 quirks;
> +
> + /**
> +  * @source_physical_address: Source Physical Address from HDMI
> +  * Vendor-Specific Data Block, for CEC usage.
> +  *
> +  * Defaults to CEC_PHYS_ADDR_INVALID (0x).
> +  */
> + u16 source_physical_address;
>  };
>  
>  int drm_display_info_set_bus_formats(struct drm_display_info *info,



Re: [PATCH RFC 00/13] drm/connector: Create HDMI Connector infrastructure

2023-08-16 Thread Hans Verkuil
On 14/08/2023 15:56, Maxime Ripard wrote:
> Hi,
> 
> Here's a series that creates a subclass of drm_connector specifically
> targeted at HDMI controllers.
> 
> The idea behind this series came from a recent discussion on IRC during
> which we discussed infoframes generation of i915 vs everything else. 
> 
> Infoframes generation code still requires some decent boilerplate, with
> each driver doing some variation of it.
> 
> In parallel, while working on vc4, we ended up converting a lot of i915
> logic (mostly around format / bpc selection, and scrambler setup) to
> apply on top of a driver that relies only on helpers.
> 
> While currently sitting in the vc4 driver, none of that logic actually
> relies on any driver or hardware-specific behaviour.
> 
> The only missing piec to make it shareable are a bunch of extra
> variables stored in a state (current bpc, format, RGB range selection,
> etc.).
> 
> Thus, I decided to create some generic subclass of drm_connector to
> address HDMI connectors, with a bunch of helpers that will take care of
> all the "HDMI Spec" related code. Scrambler setup is missing at the
> moment but can easily be plugged in.
> 
> Last week, Hans Verkuil also expressed interest in retrieving the
> infoframes generated from userspace to create an infoframe-decode tool.
> This series thus leverages the infoframe generation code to expose it
> through debugfs.

Some background here: I maintain the edid-decode utility to parse and verify
EDIDs, and an infoframe-decode counterpart would be very nice. I can add
support for exposing infoframes to debugfs in HDMI receivers as well, and
that will help parse and verify received infoframes for correctness.

I added the linux-media mailinglist as well, since this will be of interest
for that subsystem as well.

Regards,

Hans

> 
> This entire series is only build-tested at the moment. Let me know what
> you think,
> Maxime
> 
> Signed-off-by: Maxime Ripard 
> ---
> Maxime Ripard (13):
>   drm/connector: Introduce an HDMI connector
>   drm/connector: hdmi: Create a custom state
>   drm/connector: hdmi: Add Broadcast RGB property
>   drm/connector: hdmi: Add helper to get the RGB range
>   drm/connector: hdmi: Add output BPC to the connector state
>   drm/connector: hdmi: Add support for output format
>   drm/connector: hdmi: Calculate TMDS character rate
>   drm/connector: hdmi: Add custom hook to filter TMDS character rate
>   drm/connector: hdmi: Compute bpc and format automatically
>   drm/connector: hdmi: Add Infoframes generation
>   drm/connector: hdmi: Create Infoframe DebugFS entries
>   drm/vc4: hdmi: Create destroy state implementation
>   drm/vc4: hdmi: Switch to HDMI connector
> 
>  drivers/gpu/drm/Makefile |1 +
>  drivers/gpu/drm/drm_hdmi_connector.c | 1112 
> ++
>  drivers/gpu/drm/vc4/vc4_hdmi.c   |  720 --
>  drivers/gpu/drm/vc4/vc4_hdmi.h   |   37 +-
>  drivers/gpu/drm/vc4/vc4_hdmi_phy.c   |4 +-
>  include/drm/drm_connector.h  |  256 
>  6 files changed, 1508 insertions(+), 622 deletions(-)
> ---
> base-commit: 5d0c230f1de8c7515b6567d9afba1f196fb4e2f4
> change-id: 20230814-kms-hdmi-connector-state-616787e67927
> 
> Best regards,



Re: [v3] media: mediatek: vcodec: fix AV1 decoding on MT8188

2023-08-07 Thread Hans Verkuil
FYI: the v2 patch has already been merged, so I dropped this v3.

On 03/08/2023 13:10, Xiaoyong Lu wrote:
> Fix AV1 decoding failure when the iova is 36bit.
> 
> Before this fix, the decoder was accessing incorrect addresses with 36bit
> iova tile buffer, leading to iommu faults.
> 
> Fixes: 2f5d0aef37c6 ("media: mediatek: vcodec: support stateless AV1 decoder")
> Signed-off-by: Xiaoyong Lu
> ---
> Changes from v2:
> 
> - refine commit subject and message

It's only subject/commit message changes, the actual code is the same.

Regards,

Hans

> 
> Changes from v1:
> 
> - prefer '|' rather than '+'
> - prefer '&' rather than shift operation
> - add comments for address operations
> 
> v1:
> - VDEC HW can access tile buffer and decode normally.
> - Test ok by mt8195 32bit and mt8188 36bit iova.
> 
> ---
>  .../mediatek/vcodec/vdec/vdec_av1_req_lat_if.c   | 12 
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git 
> a/drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c 
> b/drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c
> index 404a1a23fd402..e9f2393f6a883 100644
> --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c
> +++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c
> @@ -1658,9 +1658,9 @@ static void vdec_av1_slice_setup_tile_buffer(struct 
> vdec_av1_slice_instance *ins
>   u32 allow_update_cdf = 0;
>   u32 sb_boundary_x_m1 = 0, sb_boundary_y_m1 = 0;
>   int tile_info_base;
> - u32 tile_buf_pa;
> + u64 tile_buf_pa;
>   u32 *tile_info_buf = instance->tile.va;
> - u32 pa = (u32)bs->dma_addr;
> + u64 pa = (u64)bs->dma_addr;
>  
>   if (uh->disable_cdf_update == 0)
>   allow_update_cdf = 1;
> @@ -1673,8 +1673,12 @@ static void vdec_av1_slice_setup_tile_buffer(struct 
> vdec_av1_slice_instance *ins
>   tile_info_buf[tile_info_base + 0] = 
> (tile_group->tile_size[tile_num] << 3);
>   tile_buf_pa = pa + tile_group->tile_start_offset[tile_num];
>  
> - tile_info_buf[tile_info_base + 1] = (tile_buf_pa >> 4) << 4;
> - tile_info_buf[tile_info_base + 2] = (tile_buf_pa % 16) << 3;
> + /* save av1 tile high 4bits(bit 32-35) address in lower 4 bits 
> position
> +  * and clear original for hw requirement.
> +  */
> + tile_info_buf[tile_info_base + 1] = (tile_buf_pa & 
> 0xFFF0ull) |
> + ((tile_buf_pa & 0xFull) >> 32);
> + tile_info_buf[tile_info_base + 2] = (tile_buf_pa & 0xFull) << 3;
>  
>   sb_boundary_x_m1 =
>   (tile->mi_col_starts[tile_col + 1] - 
> tile->mi_col_starts[tile_col] - 1) &



Re: [PATCH v2 01/47] media/vivid: Use fbdev I/O helpers

2023-08-02 Thread Hans Verkuil
On 01/08/2023 18:54, Thomas Zimmermann wrote:
> Hi
> 
> Am 01.08.23 um 13:22 schrieb Hans Verkuil:
>> On 01/08/2023 12:13, Thomas Zimmermann wrote:
>>> Set struct fb_ops and with FB_DEFAULT_IO_OPS, fbdev's initializer
>>> for I/O memory. Sets the callbacks to the cfb_ and fb_io_ functions.
>>> Select the correct modules with Kconfig's FB_IO_HELPERS token.
>>>
>>> The macro and token set the currently selected values, so there is
>>> no functional change.
>>>
>>> v2:
>>> * updated to use _IOMEM_ tokens
>>>
>>> Signed-off-by: Thomas Zimmermann 
>>> Reviewed-by: Sam Ravnborg 
>>> Acked-by: Helge Deller 
>>> Cc: Hans Verkuil 
>>> Cc: Mauro Carvalho Chehab 
>>> ---
>>>   drivers/media/test-drivers/vivid/Kconfig | 4 +---
>>>   drivers/media/test-drivers/vivid/vivid-osd.c | 4 +---
>>>   2 files changed, 2 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/media/test-drivers/vivid/Kconfig 
>>> b/drivers/media/test-drivers/vivid/Kconfig
>>> index 318799d317ba..5b08a5ad291e 100644
>>> --- a/drivers/media/test-drivers/vivid/Kconfig
>>> +++ b/drivers/media/test-drivers/vivid/Kconfig
>>> @@ -3,11 +3,9 @@ config VIDEO_VIVID
>>>   tristate "Virtual Video Test Driver"
>>>   depends on VIDEO_DEV && !SPARC32 && !SPARC64 && FB
>>>   depends on HAS_DMA
>>> +    select FB_IOMEM_HELPERS
>>>   select FONT_SUPPORT
>>>   select FONT_8x16
>>> -    select FB_CFB_FILLRECT
>>> -    select FB_CFB_COPYAREA
>>> -    select FB_CFB_IMAGEBLIT
>>>   select VIDEOBUF2_VMALLOC
>>>   select VIDEOBUF2_DMA_CONTIG
>>>   select VIDEO_V4L2_TPG
>>> diff --git a/drivers/media/test-drivers/vivid/vivid-osd.c 
>>> b/drivers/media/test-drivers/vivid/vivid-osd.c
>>> index 051f1805a16d..5c931b94a7b5 100644
>>> --- a/drivers/media/test-drivers/vivid/vivid-osd.c
>>> +++ b/drivers/media/test-drivers/vivid/vivid-osd.c
>>> @@ -246,12 +246,10 @@ static int vivid_fb_blank(int blank_mode, struct 
>>> fb_info *info)
>>>     static const struct fb_ops vivid_fb_ops = {
>>>   .owner = THIS_MODULE,
>>> +    FB_DEFAULT_IOMEM_OPS,
>>
>> This macro also sets fb_read and fb_write ops here, in addition to the
>> cfb_* ops, based on this patch:
>>
>> https://lore.kernel.org/all/20230729193157.15446-2-tzimmerm...@suse.de/#Z2e.:20230729193157.15446-2-tzimmermann::40suse.de:1include:linux:fb.h
>>
>> But those two ops were never set in this driver before.
>>
>> It's been ages since I last worked with this, so I can't tell whether that's
>> good or bad, all I know is that it makes what appears to be a functional 
>> change.
>>
>> Can you explain a bit more? Am I missing something?
> 
> That change is intentional and welcome. If no fb_read/fb_write pointers are 
> given fbdev uses them as their default. See
> 
> 
> https://elixir.bootlin.com/linux/v6.5-rc1/source/drivers/video/fbdev/core/fbmem.c#L773
> 
> and below. Once all drivers set these pointers explicitly, we can drop the 
> default and make the helpers optional and modular. For the drivers in this 
> patchset there's no functional change.

Ah, that explains it!

I wonder if it wouldn't be a good idea to include that information in the 
commit log.

In any case, for this patch:

Reviewed-by: Hans Verkuil 

Regards,

Hans

> 
> Best regards
> Thomas
> 
>>
>> Regards,
>>
>> Hans
>>
>>>   .fb_check_var   = vivid_fb_check_var,
>>>   .fb_set_par = vivid_fb_set_par,
>>>   .fb_setcolreg   = vivid_fb_setcolreg,
>>> -    .fb_fillrect    = cfb_fillrect,
>>> -    .fb_copyarea    = cfb_copyarea,
>>> -    .fb_imageblit   = cfb_imageblit,
>>>   .fb_cursor  = NULL,
>>>   .fb_ioctl   = vivid_fb_ioctl,
>>>   .fb_pan_display = vivid_fb_pan_display,
>>
> 



Re: [PATCH v2 01/47] media/vivid: Use fbdev I/O helpers

2023-08-01 Thread Hans Verkuil
On 01/08/2023 12:13, Thomas Zimmermann wrote:
> Set struct fb_ops and with FB_DEFAULT_IO_OPS, fbdev's initializer
> for I/O memory. Sets the callbacks to the cfb_ and fb_io_ functions.
> Select the correct modules with Kconfig's FB_IO_HELPERS token.
> 
> The macro and token set the currently selected values, so there is
> no functional change.
> 
> v2:
>   * updated to use _IOMEM_ tokens
> 
> Signed-off-by: Thomas Zimmermann 
> Reviewed-by: Sam Ravnborg 
> Acked-by: Helge Deller 
> Cc: Hans Verkuil 
> Cc: Mauro Carvalho Chehab 
> ---
>  drivers/media/test-drivers/vivid/Kconfig | 4 +---
>  drivers/media/test-drivers/vivid/vivid-osd.c | 4 +---
>  2 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/test-drivers/vivid/Kconfig 
> b/drivers/media/test-drivers/vivid/Kconfig
> index 318799d317ba..5b08a5ad291e 100644
> --- a/drivers/media/test-drivers/vivid/Kconfig
> +++ b/drivers/media/test-drivers/vivid/Kconfig
> @@ -3,11 +3,9 @@ config VIDEO_VIVID
>   tristate "Virtual Video Test Driver"
>   depends on VIDEO_DEV && !SPARC32 && !SPARC64 && FB
>   depends on HAS_DMA
> + select FB_IOMEM_HELPERS
>   select FONT_SUPPORT
>   select FONT_8x16
> - select FB_CFB_FILLRECT
> - select FB_CFB_COPYAREA
> - select FB_CFB_IMAGEBLIT
>   select VIDEOBUF2_VMALLOC
>   select VIDEOBUF2_DMA_CONTIG
>   select VIDEO_V4L2_TPG
> diff --git a/drivers/media/test-drivers/vivid/vivid-osd.c 
> b/drivers/media/test-drivers/vivid/vivid-osd.c
> index 051f1805a16d..5c931b94a7b5 100644
> --- a/drivers/media/test-drivers/vivid/vivid-osd.c
> +++ b/drivers/media/test-drivers/vivid/vivid-osd.c
> @@ -246,12 +246,10 @@ static int vivid_fb_blank(int blank_mode, struct 
> fb_info *info)
>  
>  static const struct fb_ops vivid_fb_ops = {
>   .owner = THIS_MODULE,
> + FB_DEFAULT_IOMEM_OPS,

This macro also sets fb_read and fb_write ops here, in addition to the
cfb_* ops, based on this patch:

https://lore.kernel.org/all/20230729193157.15446-2-tzimmerm...@suse.de/#Z2e.:20230729193157.15446-2-tzimmermann::40suse.de:1include:linux:fb.h

But those two ops were never set in this driver before.

It's been ages since I last worked with this, so I can't tell whether that's
good or bad, all I know is that it makes what appears to be a functional change.

Can you explain a bit more? Am I missing something?

Regards,

Hans

>   .fb_check_var   = vivid_fb_check_var,
>   .fb_set_par = vivid_fb_set_par,
>   .fb_setcolreg   = vivid_fb_setcolreg,
> - .fb_fillrect= cfb_fillrect,
> - .fb_copyarea= cfb_copyarea,
> - .fb_imageblit   = cfb_imageblit,
>   .fb_cursor  = NULL,
>   .fb_ioctl   = vivid_fb_ioctl,
>   .fb_pan_display = vivid_fb_pan_display,



Re: [PATCH v4 11/18] media: Remove flag FBINFO_FLAG_DEFAULT from fbdev drivers

2023-07-18 Thread Hans Verkuil
Hi Thomas,

On 15/07/2023 20:51, Thomas Zimmermann wrote:
> The flag FBINFO_FLAG_DEFAULT is 0 and has no effect, as struct
> fbinfo.flags has been allocated to zero by kzalloc(). So do not
> set it.
> 
> Flags should signal differences from the default values. After cleaning
> up all occurrences of FBINFO_DEFAULT, the token will be removed.
> 
> v2:
>   * fix commit message (Miguel)
> 
> Signed-off-by: Thomas Zimmermann 
> Acked-by: Sam Ravnborg 
> Cc: Andy Walls 
> Cc: Mauro Carvalho Chehab 
> Cc: Hans Verkuil 
> ---
>  drivers/media/pci/ivtv/ivtvfb.c  | 1 -
>  drivers/media/test-drivers/vivid/vivid-osd.c | 1 -
>  2 files changed, 2 deletions(-)

I can take this patches for 6.6, unless you prefer to have this whole series
merged in one go?

In that case you can use my:

Reviewed-by: Hans Verkuil 

Regards,

Hans

> 
> diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
> index 0aeb9daaee4c..23c8c094e791 100644
> --- a/drivers/media/pci/ivtv/ivtvfb.c
> +++ b/drivers/media/pci/ivtv/ivtvfb.c
> @@ -1048,7 +1048,6 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
>   /* Generate valid fb_info */
>  
>   oi->ivtvfb_info.node = -1;
> - oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
>   oi->ivtvfb_info.par = itv;
>   oi->ivtvfb_info.var = oi->ivtvfb_defined;
>   oi->ivtvfb_info.fix = oi->ivtvfb_fix;
> diff --git a/drivers/media/test-drivers/vivid/vivid-osd.c 
> b/drivers/media/test-drivers/vivid/vivid-osd.c
> index ec25edc679b3..051f1805a16d 100644
> --- a/drivers/media/test-drivers/vivid/vivid-osd.c
> +++ b/drivers/media/test-drivers/vivid/vivid-osd.c
> @@ -310,7 +310,6 @@ static int vivid_fb_init_vidmode(struct vivid_dev *dev)
>   /* Generate valid fb_info */
>  
>   dev->fb_info.node = -1;
> - dev->fb_info.flags = FBINFO_FLAG_DEFAULT;
>   dev->fb_info.par = dev;
>   dev->fb_info.var = dev->fb_defined;
>   dev->fb_info.fix = dev->fb_fix;



Re: [v10] media: mediatek: vcodec: support stateless AV1 decoder

2023-05-26 Thread Hans Verkuil
On 14/04/2023 10:30, Xiaoyong Lu wrote:
> Add mediatek av1 decoder linux driver which use the stateless API in
> MT8195.
> 
> Signed-off-by: Xiaoyong Lu
> Tested-by: Nicolas Dufresne 
> Reviewed-by: Nicolas Dufresne 
> Tested-by: AngeloGioacchino Del Regno 
> 
> Reviewed-by: AngeloGioacchino Del Regno 
> 

After rebasing on top of our media staging tree I get these compile errors:

  CC [M]  drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.o
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c: In function 
‘vdec_av1_slice_lat_decode’:
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:2075:46: 
error: ‘struct mtk_vcodec_dev’ has no member named ‘msg_queue_core_ctx’
 2075 | vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, 
lat_buf);
  |  ^~
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:2114:46: 
error: ‘struct mtk_vcodec_dev’ has no member named ‘msg_queue_core_ctx’
 2114 | vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, 
lat_buf);
  |  ^~

That's due to the patch "media: mediatek: vcodec: move core context from device
to each instance" that has now been merged and that drops that queue.

Can you rebase v10? This is now the only remaining blocked for the av1 series
to be merged.

Regards,

Hans


Re: [PATCH 2/4] drm/msm: add hdmi cec support

2023-05-26 Thread Hans Verkuil
Hi Arnaud,

My apologies for the long delay in replying, it's been very, very busy lately.
I hope I'll be able to be more responsive going forward.

On 21/04/2023 18:58, Arnaud Vrac wrote:
> Le ven. 21 avr. 2023 à 15:27, Hans Verkuil  a écrit 
> :
>>
>> Hi Arnaud,
>>
>> Some review comments below...
> 
> Hi Hans,
> 
> For context, I first based my work on the fbdev driver from Qualcomm a
> few years ago, on our own CEC framework which does not implement any
> CEC protocol logic (as android does). At the time I verified that the
> messages were matching the electrical and protocol spec, using manual
> tests and a QD882EA analyzer. I also passed HDMI and CEC certs.
> 
> I simply ported this work more recently to a newer kernel and the
> media-cec framework, also checking the port that Qualcomm did later
> on.
> 
>> On 4/18/23 20:10, Arnaud Vrac wrote:
>>> Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996
>>> and MSM8998. The hardware block can handle a single CEC logical address
>>> and broadcast messages.
>>>
>>> Port the CEC driver from downstream msm-4.4 kernel. It has been tested
>>> on MSM8998 and passes the cec-compliance tool tests.
>>
>> Just to verify: did you run the cec-compliance --test-adapter test? That's
>> the important one to verify your own driver.
> 
> Yes, and I also ran the cec-compliance -r 0 with a pulse8 emulating a
> tv on the bus. Here's the result of cec-compliance --test-adapter:
> 
> Find remote devices:
> Polling: OK
> 
> CEC API:
> CEC_ADAP_G_CAPS: OK
> Invalid ioctls: OK
> CEC_DQEVENT: OK
> CEC_ADAP_G/S_PHYS_ADDR: OK
> CEC_ADAP_G/S_LOG_ADDRS: OK
> CEC_TRANSMIT: OK
> CEC_RECEIVE: OK
> CEC_TRANSMIT/RECEIVE (non-blocking): OK (Presumed)
> CEC_G/S_MODE: OK
> warn: cec-test-adapter.cpp(1189): Too many transmits (3)
> without receives
> SFTs for repeating messages (>= 7): 7: 38, 8: 2
> SFTs for newly transmitted messages (>= 5): 6: 2, 7: 17
> SFTs for newly transmitted remote messages (>= 5): 6: 20
> CEC_EVENT_LOST_MSGS: OK
> 
> Network topology:
> [...]
> 
> Total for hdmi_msm device /dev/cec0: 11, Succeeded: 11, Failed: 0, Warnings: 1
> 
>>
>>>
>>> Signed-off-by: Arnaud Vrac 
>>> ---
>>>  drivers/gpu/drm/msm/Kconfig |   8 ++
>>>  drivers/gpu/drm/msm/Makefile|   1 +
>>>  drivers/gpu/drm/msm/hdmi/hdmi.c |  15 ++
>>>  drivers/gpu/drm/msm/hdmi/hdmi.h |  18 +++
>>>  drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 
>>> 
>>>  5 files changed, 322 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
>>> index 85f5ab1d552c4..2a02c74207935 100644
>>> --- a/drivers/gpu/drm/msm/Kconfig
>>> +++ b/drivers/gpu/drm/msm/Kconfig
>>> @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP
>>>   default y
>>>   help
>>> Choose this option to enable HDCP state machine
>>> +
>>> +config DRM_MSM_HDMI_CEC
>>> + bool "Enable HDMI CEC support in MSM DRM driver"
>>> + depends on DRM_MSM && DRM_MSM_HDMI
>>> + select CEC_CORE
>>> + default y
>>> + help
>>> +   Choose this option to enable CEC support
>>> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
>>> index 7274c41228ed9..0237a2f219ac2 100644
>>> --- a/drivers/gpu/drm/msm/Makefile
>>> +++ b/drivers/gpu/drm/msm/Makefile
>>> @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
>>>
>>>  msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
>>>
>>> +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o
>>>  msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
>>>
>>>  msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \
>>> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c 
>>> b/drivers/gpu/drm/msm/hdmi/hdmi.c
>>> index 3132105a2a433..1dde3890e25c0 100644
>>> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c
>>> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
>>> @@ -11,6 +11,8 @@
>>>  #include 
>>>  #include 
>>>
>>> +#include 
>>> +
>>>  #include 
>>>  #include "hdmi.h"
>>>
>>> @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id)
>>>   if (hdmi->hdcp_ctrl)
>>&g

Re: [PATCH v5 01/11] i2c: Enhance i2c_new_ancillary_device API

2023-05-23 Thread Hans Verkuil
On 22/05/2023 12:18, Biju Das wrote:
> Renesas PMIC RAA215300 exposes two separate i2c devices, one for the main
> device and another for rtc device.
> 
> Enhance i2c_new_ancillary_device() to instantiate a real device.
> (eg: Instantiate rtc device from PMIC driver)
> 
> Added helper function __i2c_new_dummy_device to share the code
> between i2c_new_dummy_device and i2c_new_ancillary_device().
> 
> Also added helper function __i2c_new_client_device() to pass parent dev
> parameter, so that the ancillary device can assign its parent during
> creation.
> 
> Suggested-by: Geert Uytterhoeven 
> Signed-off-by: Biju Das 
> ---
> v4->v5:
>  * Replaced parameter dev->parent in __i2c_new_client_device() and
>__i2c_new_dummy_device().
>  * Improved error message in __i2c_new_dummy_device() by printing device name.
>  * Updated comment for ancillary's device parent
>  * Dropped aux_device_name check in i2c_new_ancillary_device().
> v3->v4:
>  * Dropped Rb tag from Geert as there are new changes.
>  * Introduced __i2c_new_dummy_device() to share the code between
>i2c_new_dummy_device and i2c_new_ancillary_device().
>  * Introduced __i2c_new_client_device() to pass parent dev
>parameter, so that the ancillary device can assign its parent during
>creation.
> v3:
>  * New patch
> 
> Ref:
>  
> https://patchwork.kernel.org/project/linux-renesas-soc/patch/20230505172530.357455-5-biju.das...@bp.renesas.com/
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c |  6 +-
>  drivers/i2c/i2c-core-base.c  | 92 +---
>  drivers/media/i2c/adv748x/adv748x-core.c |  2 +-
>  drivers/media/i2c/adv7604.c  |  3 +-
>  include/linux/i2c.h      |  3 +-
>  5 files changed, 69 insertions(+), 37 deletions(-)

For the media and adv7511 bits:

Reviewed-by: Hans Verkuil 

Regards,

Hans

> 
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index ddceafa7b637..86306b010a0a 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -1072,7 +1072,7 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
>   int ret;
>  
>   adv->i2c_cec = i2c_new_ancillary_device(adv->i2c_main, "cec",
> - ADV7511_CEC_I2C_ADDR_DEFAULT);
> + ADV7511_CEC_I2C_ADDR_DEFAULT, NULL);
>   if (IS_ERR(adv->i2c_cec))
>   return PTR_ERR(adv->i2c_cec);
>  
> @@ -1261,7 +1261,7 @@ static int adv7511_probe(struct i2c_client *i2c)
>   adv7511_packet_disable(adv7511, 0x);
>  
>   adv7511->i2c_edid = i2c_new_ancillary_device(i2c, "edid",
> - ADV7511_EDID_I2C_ADDR_DEFAULT);
> + ADV7511_EDID_I2C_ADDR_DEFAULT, NULL);
>   if (IS_ERR(adv7511->i2c_edid)) {
>   ret = PTR_ERR(adv7511->i2c_edid);
>   goto uninit_regulators;
> @@ -1271,7 +1271,7 @@ static int adv7511_probe(struct i2c_client *i2c)
>adv7511->i2c_edid->addr << 1);
>  
>   adv7511->i2c_packet = i2c_new_ancillary_device(i2c, "packet",
> - ADV7511_PACKET_I2C_ADDR_DEFAULT);
> + ADV7511_PACKET_I2C_ADDR_DEFAULT, NULL);
>   if (IS_ERR(adv7511->i2c_packet)) {
>   ret = PTR_ERR(adv7511->i2c_packet);
>   goto err_i2c_unregister_edid;
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index ae3af738b03f..3442aa80290f 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -893,24 +893,10 @@ int i2c_dev_irq_from_resources(const struct resource 
> *resources,
>   return 0;
>  }
>  
> -/**
> - * i2c_new_client_device - instantiate an i2c device
> - * @adap: the adapter managing the device
> - * @info: describes one I2C device; bus_num is ignored
> - * Context: can sleep
> - *
> - * Create an i2c device. Binding is handled through driver model
> - * probe()/remove() methods.  A driver may be bound to this device when we
> - * return from this function, or any later moment (e.g. maybe hotplugging 
> will
> - * load the driver module).  This call is not appropriate for use by 
> mainboard
> - * initialization logic, which usually runs during an arch_initcall() long
> - * before any i2c_adapter could exist.
> - *
> - * This returns the new i2c client, which may be saved for later use with
> - * i2c_unregister_device(); or an ERR_PTR to describe the error.
>

Re: [PATCH 2/4] drm/msm: add hdmi cec support

2023-04-21 Thread Hans Verkuil
Hi Arnaud,

Some review comments below...

On 4/18/23 20:10, Arnaud Vrac wrote:
> Some Qualcomm SoCs that support HDMI also support CEC, including MSM8996
> and MSM8998. The hardware block can handle a single CEC logical address
> and broadcast messages.
> 
> Port the CEC driver from downstream msm-4.4 kernel. It has been tested
> on MSM8998 and passes the cec-compliance tool tests.

Just to verify: did you run the cec-compliance --test-adapter test? That's
the important one to verify your own driver.

> 
> Signed-off-by: Arnaud Vrac 
> ---
>  drivers/gpu/drm/msm/Kconfig |   8 ++
>  drivers/gpu/drm/msm/Makefile|   1 +
>  drivers/gpu/drm/msm/hdmi/hdmi.c |  15 ++
>  drivers/gpu/drm/msm/hdmi/hdmi.h |  18 +++
>  drivers/gpu/drm/msm/hdmi/hdmi_cec.c | 280 
> 
>  5 files changed, 322 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
> index 85f5ab1d552c4..2a02c74207935 100644
> --- a/drivers/gpu/drm/msm/Kconfig
> +++ b/drivers/gpu/drm/msm/Kconfig
> @@ -165,3 +165,11 @@ config DRM_MSM_HDMI_HDCP
>   default y
>   help
> Choose this option to enable HDCP state machine
> +
> +config DRM_MSM_HDMI_CEC
> + bool "Enable HDMI CEC support in MSM DRM driver"
> + depends on DRM_MSM && DRM_MSM_HDMI
> + select CEC_CORE
> + default y
> + help
> +   Choose this option to enable CEC support
> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> index 7274c41228ed9..0237a2f219ac2 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -131,6 +131,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
>  
>  msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
>  
> +msm-$(CONFIG_DRM_MSM_HDMI_CEC) += hdmi/hdmi_cec.o
>  msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
>  
>  msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
> index 3132105a2a433..1dde3890e25c0 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
> @@ -11,6 +11,8 @@
>  #include 
>  #include 
>  
> +#include 
> +
>  #include 
>  #include "hdmi.h"
>  
> @@ -53,6 +55,9 @@ static irqreturn_t msm_hdmi_irq(int irq, void *dev_id)
>   if (hdmi->hdcp_ctrl)
>   msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl);
>  
> + /* Process CEC: */
> + msm_hdmi_cec_irq(hdmi);
> +
>   /* TODO audio.. */
>  
>   return IRQ_HANDLED;
> @@ -66,6 +71,8 @@ static void msm_hdmi_destroy(struct hdmi *hdmi)
>*/
>   if (hdmi->workq)
>   destroy_workqueue(hdmi->workq);
> +
> + msm_hdmi_cec_exit(hdmi);
>   msm_hdmi_hdcp_destroy(hdmi);
>  
>   if (hdmi->i2c)
> @@ -139,6 +146,8 @@ static int msm_hdmi_init(struct hdmi *hdmi)
>   hdmi->hdcp_ctrl = NULL;
>   }
>  
> + msm_hdmi_cec_init(hdmi);
> +
>   return 0;
>  
>  fail:
> @@ -198,6 +207,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
>  
>   drm_connector_attach_encoder(hdmi->connector, hdmi->encoder);
>  
> + if (hdmi->cec_adap) {
> + struct cec_connector_info conn_info;
> + cec_fill_conn_info_from_drm(&conn_info, hdmi->connector);
> + cec_s_conn_info(hdmi->cec_adap, &conn_info);
> + }
> +
>   ret = devm_request_irq(dev->dev, hdmi->irq,
>   msm_hdmi_irq, IRQF_TRIGGER_HIGH,
>   "hdmi_isr", hdmi);
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
> index e8dbee50637fa..c639bd87f4b8f 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.h
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
> @@ -29,6 +29,7 @@ struct hdmi_audio {
>  };
>  
>  struct hdmi_hdcp_ctrl;
> +struct cec_adapter;
>  
>  struct hdmi {
>   struct drm_device *dev;
> @@ -73,6 +74,7 @@ struct hdmi {
>   struct workqueue_struct *workq;
>  
>   struct hdmi_hdcp_ctrl *hdcp_ctrl;
> + struct cec_adapter *cec_adap;
>  
>   /*
>   * spinlock to protect registers shared by different execution
> @@ -261,4 +263,20 @@ static inline void msm_hdmi_hdcp_off(struct 
> hdmi_hdcp_ctrl *hdcp_ctrl) {}
>  static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
>  #endif
>  
> +/*
> + * cec
> + */
> +#ifdef CONFIG_DRM_MSM_HDMI_CEC
> +int msm_hdmi_cec_init(struct hdmi *hdmi);
> +void msm_hdmi_cec_exit(struct hdmi *hdmi);
> +void msm_hdmi_cec_irq(struct hdmi *hdmi);
> +#else
> +static inline int msm_hdmi_cec_init(struct hdmi *hdmi)
> +{
> + return -ENXIO;
> +}
> +static inline void msm_hdmi_cec_exit(struct hdmi *hdmi) {}
> +static inline void msm_hdmi_cec_irq(struct hdmi *hdmi) {}
> +#endif
> +
>  #endif /* __HDMI_CONNECTOR_H__ */
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_cec.c 
> b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c
> new file mode 100644
> index 0..51326e493e5da
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_cec.c
> @@ -0,0 +1,280 @@
> +#include 
> +#include 
> +
> +#include "hd

Re: [PATCH 1/3] dt-bindings: display: synopsys, dw-hdmi: Add property for disabling CEC

2023-04-21 Thread Hans Verkuil
On 18/04/2023 23:41, Rob Herring wrote:
> On Sat, Apr 15, 2023 at 12:46:11PM +0200, Jernej Skrabec wrote:
>> Even though some DW-HDMI controllers have perfectly usable HDMI-CEC
>> implementation, some boards might prefer not to use it or even use
>> software implementation instead.
>>
>> Add property for disabling CEC so driver doesn't expose unused CEC
>> interface, if CEC pin isn't connected anywhere.
> 
> Isn't this all true for any bridge supporting CEC? Make this common.

I agree with that, there was a similar case in the past:

https://lore.kernel.org/linux-media/20180323125915.13986-1-hverk...@xs4all.nl/

I never followed up to that, but I believe this is generic for any HDMI 
transmitter
or receiver with built-in CEC support where the CEC line is not actually hooked
up to the HDMI pin.

There is no way for the CEC driver to detect that, so this has to be 
communicated
in the device tree.

For standalone CEC devices you can just disable them in the device tree, of 
course,
but if it is incorporated into the HDMI device itself, then it needs to be told.

Regards,

Hans

> 
>>
>> Signed-off-by: Jernej Skrabec 
>> ---
>>  .../devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml | 5 +
>>  1 file changed, 5 insertions(+)
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml 
>> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml
>> index 4b7e54a8f037..624d32c024f6 100644
>> --- a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml
>> +++ b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml
>> @@ -48,6 +48,11 @@ properties:
>>interrupts:
>>  maxItems: 1
>>  
>> +  snps,disable-cec:
>> +$ref: /schemas/types.yaml#/definitions/flag
>> +description:
>> +  Disable HDMI-CEC.
>> +
>>  additionalProperties: true
>>  
>>  ...
>> -- 
>> 2.40.0
>>



Re: [PATCH v5 14/20] staging: media: tegra-video: move MIPI calibration calls from VI to CSI

2023-04-18 Thread Hans Verkuil
On 18/04/2023 10:07, Luca Ceresoli wrote:
> Hi Hans,
> 
> On Fri, 14 Apr 2023 17:51:34 +0200
> Hans Verkuil  wrote:
> 
>> Hi Luca,
>>
>> I just encountered an error in this patch, so I have rejected the PR I made.
>>
>> See below for the details:
>>
>> On 07/04/2023 15:38, Luca Ceresoli wrote:
>>> The CSI module does not handle all the MIPI lane calibration procedure,
>>> leaving a small part of it to the VI module. In doing this,
>>> tegra_channel_enable_stream() (vi.c) manipulates the private data of the
>>> upstream subdev casting it to struct 'tegra_csi_channel', which will be
>>> wrong after introducing a VIP (parallel video input) channel.
>>>
>>> This prevents adding support for the VIP module.  It also breaks the
>>> logical isolation between modules.
>>>
>>> Since the lane calibration requirement does not exist in the parallel input
>>> module, moving the calibration function to a per-module op is not
>>> optimal. Instead move the calibration procedure in the CSI module, together
>>> with the rest of the calibration procedures. After this change,
>>> tegra_channel_enable_stream() just calls v4l2_subdev_call() to ask for a
>>> stream start/stop to the CSI module, which in turn knows all the
>>> CSI-specific details to implement it.
>>>
>>> Signed-off-by: Luca Ceresoli 
>>> Reviewed-by: Dmitry Osipenko 
>>>
>>> ---
>>>
>>> No changes in v5
>>>
>>> Changed in v4:
>>>  - Added review tags
>>>
>>> No changes in v3
>>> No changes in v2
>>> ---
>>>  drivers/staging/media/tegra-video/csi.c | 44 
>>>  drivers/staging/media/tegra-video/vi.c  | 54 ++---
>>>  2 files changed, 48 insertions(+), 50 deletions(-)
>>>
>>> diff --git a/drivers/staging/media/tegra-video/csi.c 
>>> b/drivers/staging/media/tegra-video/csi.c
>>> index 9a03d5ccdf3c..b93fc879ef3a 100644
>>> --- a/drivers/staging/media/tegra-video/csi.c
>>> +++ b/drivers/staging/media/tegra-video/csi.c
>>> @@ -328,12 +328,42 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
>>> *subdev)
>>> }
>>>  
>>> csi_chan->pg_mode = chan->pg_mode;
>>> +
>>> +   /*
>>> +* Tegra CSI receiver can detect the first LP to HS transition.
>>> +* So, start the CSI stream-on prior to sensor stream-on and
>>> +* vice-versa for stream-off.
>>> +*/
>>> ret = csi->ops->csi_start_streaming(csi_chan);
>>> if (ret < 0)
>>> goto finish_calibration;
>>>  
>>> +   if (csi_chan->mipi) {
>>> +   struct v4l2_subdev *src_subdev;
>>> +   /*
>>> +* TRM has incorrectly documented to wait for done status from
>>> +* calibration logic after CSI interface power on.
>>> +* As per the design, calibration results are latched and 
>>> applied
>>> +* to the pads only when the link is in LP11 state which will 
>>> happen
>>> +* during the sensor stream-on.
>>> +* CSI subdev stream-on triggers start of MIPI pads calibration.
>>> +* Wait for calibration to finish here after sensor subdev 
>>> stream-on.
>>> +*/
>>> +   src_subdev = tegra_channel_get_remote_source_subdev(chan);
>>> +   ret = v4l2_subdev_call(src_subdev, video, s_stream, true);
>>> +   err = tegra_mipi_finish_calibration(csi_chan->mipi);
>>> +
>>> +   if (ret < 0 && ret != -ENOIOCTLCMD)
>>> +   goto disable_csi_stream;  
>>
>> If there was an error from s_stream, then tegra_mipi_finish_calibration is 
>> called
>> and it goes to disable_csi_stream...
>>
>>> +
>>> +   if (err < 0)
>>> +   dev_warn(csi->dev, "MIPI calibration failed: %d\n", 
>>> err);
>>> +   }
>>> +
>>> return 0;
>>>  
>>> +disable_csi_stream:
>>> +   csi->ops->csi_stop_streaming(csi_chan);
>>>  finish_calibration:
>>> if (csi_chan->mipi)
>>> tegra_mipi_finish_calibration(csi_chan->mipi);  
>>
>> ...but here tegra_mipi_finish_calibration() is called again, leading to an 
>> unlock
>> imbalance.
> 
> Many thanks for your testing! Unfortunately I have no Tegra210 hardware
> so this never happened here, but with your report the problem got
> obvious and, luckily, the fix appeared to be just a oneliner.
> 
> v6 just sent! I'm wondering whether there is still hope to get this
> 6.4...

Sorry, it's too late for 6.4 now. Only fixes can go in for 6.4.

Regards,

Hans

> 
> Best regards,
> Luca
> 



Re: [PATCH v5 14/20] staging: media: tegra-video: move MIPI calibration calls from VI to CSI

2023-04-14 Thread Hans Verkuil
Hi Luca,

I just encountered an error in this patch, so I have rejected the PR I made.

See below for the details:

On 07/04/2023 15:38, Luca Ceresoli wrote:
> The CSI module does not handle all the MIPI lane calibration procedure,
> leaving a small part of it to the VI module. In doing this,
> tegra_channel_enable_stream() (vi.c) manipulates the private data of the
> upstream subdev casting it to struct 'tegra_csi_channel', which will be
> wrong after introducing a VIP (parallel video input) channel.
> 
> This prevents adding support for the VIP module.  It also breaks the
> logical isolation between modules.
> 
> Since the lane calibration requirement does not exist in the parallel input
> module, moving the calibration function to a per-module op is not
> optimal. Instead move the calibration procedure in the CSI module, together
> with the rest of the calibration procedures. After this change,
> tegra_channel_enable_stream() just calls v4l2_subdev_call() to ask for a
> stream start/stop to the CSI module, which in turn knows all the
> CSI-specific details to implement it.
> 
> Signed-off-by: Luca Ceresoli 
> Reviewed-by: Dmitry Osipenko 
> 
> ---
> 
> No changes in v5
> 
> Changed in v4:
>  - Added review tags
> 
> No changes in v3
> No changes in v2
> ---
>  drivers/staging/media/tegra-video/csi.c | 44 
>  drivers/staging/media/tegra-video/vi.c  | 54 ++---
>  2 files changed, 48 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/staging/media/tegra-video/csi.c 
> b/drivers/staging/media/tegra-video/csi.c
> index 9a03d5ccdf3c..b93fc879ef3a 100644
> --- a/drivers/staging/media/tegra-video/csi.c
> +++ b/drivers/staging/media/tegra-video/csi.c
> @@ -328,12 +328,42 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
> *subdev)
>   }
>  
>   csi_chan->pg_mode = chan->pg_mode;
> +
> + /*
> +  * Tegra CSI receiver can detect the first LP to HS transition.
> +  * So, start the CSI stream-on prior to sensor stream-on and
> +  * vice-versa for stream-off.
> +  */
>   ret = csi->ops->csi_start_streaming(csi_chan);
>   if (ret < 0)
>   goto finish_calibration;
>  
> + if (csi_chan->mipi) {
> + struct v4l2_subdev *src_subdev;
> + /*
> +  * TRM has incorrectly documented to wait for done status from
> +  * calibration logic after CSI interface power on.
> +  * As per the design, calibration results are latched and 
> applied
> +  * to the pads only when the link is in LP11 state which will 
> happen
> +  * during the sensor stream-on.
> +  * CSI subdev stream-on triggers start of MIPI pads calibration.
> +  * Wait for calibration to finish here after sensor subdev 
> stream-on.
> +  */
> + src_subdev = tegra_channel_get_remote_source_subdev(chan);
> + ret = v4l2_subdev_call(src_subdev, video, s_stream, true);
> + err = tegra_mipi_finish_calibration(csi_chan->mipi);
> +
> + if (ret < 0 && ret != -ENOIOCTLCMD)
> + goto disable_csi_stream;

If there was an error from s_stream, then tegra_mipi_finish_calibration is 
called
and it goes to disable_csi_stream...

> +
> + if (err < 0)
> + dev_warn(csi->dev, "MIPI calibration failed: %d\n", 
> err);
> + }
> +
>   return 0;
>  
> +disable_csi_stream:
> + csi->ops->csi_stop_streaming(csi_chan);
>  finish_calibration:
>   if (csi_chan->mipi)
>   tegra_mipi_finish_calibration(csi_chan->mipi);

...but here tegra_mipi_finish_calibration() is called again, leading to an 
unlock
imbalance.

This is the callstack:

[  109.894502] IMX274 5-001a: s_stream failed

[  109.900203] =
[  109.904898] WARNING: bad unlock balance detected!
[  109.909594] 6.3.0-rc2-tegra #16 Not tainted
[  109.913774] -
[  109.918470] v4l2-ctl/2000 is trying to release lock (&mipi->lock) at:
[  109.924911] [] tegra_mipi_finish_calibration+0x84/0xb0
[  109.931621] but there are no more locks to release!
[  109.936489]
   other info that might help us debug this:
[  109.943004] 1 lock held by v4l2-ctl/2000:
[  109.947009]  #0: 83bcf6a8 (&chan->video_lock){}-{3:3}, at: 
__video_do_ioctl+0xdc/0x3c8
[  109.955987]
   stack backtrace:
[  109.960336] CPU: 2 PID: 2000 Comm: v4l2-ctl Not tainted 6.3.0-rc2-tegra #16
[  109.967290] Hardware name: NVIDIA Jetson TX1 Developer Kit (DT)
[  109.973200] Call trace:
[  109.975642]  dump_backtrace+0xa0/0xfc
[  109.979308]  show_stack+0x18/0x24
[  109.982622]  dump_stack_lvl+0x48/0x60
[  109.986285]  dump_stack+0x18/0x24
[  109.989598]  print_unlock_imbalance_bug+0x130/0x148
[  109.994472]  lock_release+0x1bc/0x248
[  109.998131]  __mutex_unlock_slowpath+0x48/0x2cc
[  110.002657]  mutex_unlock+0x20/0x2c
[  110.006141]  tegra_mipi

Re: [PATCH v2 1/7] media: videobuf2: Don't assert held reservation lock for dma-buf mmapping

2023-04-12 Thread Hans Verkuil
On 06/04/2023 18:06, Dmitry Osipenko wrote:
> Don't assert held dma-buf reservation lock on memory mapping of exported
> buffer.
> 
> We're going to change dma-buf mmap() locking policy such that exporters
> will have to handle the lock. The previous locking policy caused deadlock
> problem for DRM drivers in a case of self-imported dma-bufs once these
> drivers are moved to use reservation lock universally. The problem is
> solved by moving the lock down to exporters. This patch prepares videobuf2
> for the locking policy update.
> 
> Reviewed-by: Emil Velikov 
> Signed-off-by: Dmitry Osipenko 

Reviewed-by: Hans Verkuil 

Regards,

Hans

> ---
>  drivers/media/common/videobuf2/videobuf2-dma-contig.c | 3 ---
>  drivers/media/common/videobuf2/videobuf2-dma-sg.c | 3 ---
>  drivers/media/common/videobuf2/videobuf2-vmalloc.c| 3 ---
>  3 files changed, 9 deletions(-)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c 
> b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> index 205d3cac425c..2fa455d4a048 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> @@ -11,7 +11,6 @@
>   */
>  
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -456,8 +455,6 @@ static int vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf, 
> struct iosys_map *map)
>  static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf,
>   struct vm_area_struct *vma)
>  {
> - dma_resv_assert_held(dbuf->resv);
> -
>   return vb2_dc_mmap(dbuf->priv, vma);
>  }
>  
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c 
> b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> index 183037fb1273..28f3fdfe23a2 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> @@ -10,7 +10,6 @@
>   * the Free Software Foundation.
>   */
>  
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -498,8 +497,6 @@ static int vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf 
> *dbuf,
>  static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf,
>   struct vm_area_struct *vma)
>  {
> - dma_resv_assert_held(dbuf->resv);
> -
>   return vb2_dma_sg_mmap(dbuf->priv, vma);
>  }
>  
> diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c 
> b/drivers/media/common/videobuf2/videobuf2-vmalloc.c
> index a6c6d2fcaaa4..7c635e292106 100644
> --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c
> +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c
> @@ -10,7 +10,6 @@
>   * the Free Software Foundation.
>   */
>  
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -319,8 +318,6 @@ static int vb2_vmalloc_dmabuf_ops_vmap(struct dma_buf 
> *dbuf,
>  static int vb2_vmalloc_dmabuf_ops_mmap(struct dma_buf *dbuf,
>   struct vm_area_struct *vma)
>  {
> - dma_resv_assert_held(dbuf->resv);
> -
>   return vb2_vmalloc_mmap(dbuf->priv, vma);
>  }
>  



Re: [v9] media: mediatek: vcodec: support stateless AV1 decoder

2023-04-12 Thread Hans Verkuil
On 12/04/2023 14:22, Hans Verkuil wrote:
> On 12/04/2023 05:30, Xiaoyong Lu wrote:
>> Add mediatek av1 decoder linux driver which use the stateless API in
>> MT8195.
>>
>> Signed-off-by: Xiaoyong Lu
>> Tested-by: Nicolas Dufresne 
>> Reviewed-by: Nicolas Dufresne 
>> Tested-by: AngeloGioacchino Del Regno 
>> 
>> Reviewed-by: AngeloGioacchino Del Regno 
>> 
> 
> Hmm, I get this compile error:
> 
> drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c: In 
> function ‘vdec_av1_slice_setup_uh’:
> drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:48:58: 
> error: ‘V4L2_AV1_FRAME_FLAG_UNIFORM_TILE_SPACING’ undeclared (first use in 
> this function); did you mean
> ‘V4L2_AV1_TILE_INFO_FLAG_UNIFORM_TILE_SPACING’?
>48 | #define FH_FLAG(x, name)(!!((x)->flags & 
> V4L2_AV1_FRAME_FLAG_##name))
>   |  
> ^~~~
> drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:1322:41: 
> note: in expansion of macro ‘FH_FLAG’
>  1322 | uh->uniform_tile_spacing_flag = FH_FLAG(ctrl_fh, 
> UNIFORM_TILE_SPACING);
>   | ^~~
> drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:48:58: 
> note: each undeclared identifier is reported only once for each function it 
> appears in
>48 | #define FH_FLAG(x, name)(!!((x)->flags & 
> V4L2_AV1_FRAME_FLAG_##name))
>   |  
> ^~~~
> drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:1322:41: 
> note: in expansion of macro ‘FH_FLAG’
>  1322 | uh->uniform_tile_spacing_flag = FH_FLAG(ctrl_fh, 
> UNIFORM_TILE_SPACING);
>   | ^~~
> 
> This flag was renamed from V4L2_AV1_FRAME_FLAG_UNIFORM_TILE_SPACING to
> V4L2_AV1_TILE_INFO_FLAG_UNIFORM_TILE_SPACING in v5 of the AV1 uAPI.
> 
> So this suggests to me that you are testing with an old version of the AV1
> uAPI. The correct one is v7:
> 
> https://patchwork.linuxtv.org/project/linux-media/patch/20230306161850.492072-1-daniel.alme...@collabora.com/
> 
> You have to compile and test with that v7 patch since that's the version we
> want to merge.

smatch also gave this error:

vdec_av1_req_lat_if.c:2121 vdec_av1_slice_lat_decode() error: we previously 
assumed 'pfc' could be null (see line 2056)

Regards,

Hans


Re: [v9] media: mediatek: vcodec: support stateless AV1 decoder

2023-04-12 Thread Hans Verkuil
On 12/04/2023 05:30, Xiaoyong Lu wrote:
> Add mediatek av1 decoder linux driver which use the stateless API in
> MT8195.
> 
> Signed-off-by: Xiaoyong Lu
> Tested-by: Nicolas Dufresne 
> Reviewed-by: Nicolas Dufresne 
> Tested-by: AngeloGioacchino Del Regno 
> 
> Reviewed-by: AngeloGioacchino Del Regno 
> 

Hmm, I get this compile error:

drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c: In function 
‘vdec_av1_slice_setup_uh’:
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:48:58: error: 
‘V4L2_AV1_FRAME_FLAG_UNIFORM_TILE_SPACING’ undeclared (first use in this 
function); did you mean
‘V4L2_AV1_TILE_INFO_FLAG_UNIFORM_TILE_SPACING’?
   48 | #define FH_FLAG(x, name)(!!((x)->flags & 
V4L2_AV1_FRAME_FLAG_##name))
  |  
^~~~
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:1322:41: 
note: in expansion of macro ‘FH_FLAG’
 1322 | uh->uniform_tile_spacing_flag = FH_FLAG(ctrl_fh, 
UNIFORM_TILE_SPACING);
  | ^~~
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:48:58: note: 
each undeclared identifier is reported only once for each function it appears in
   48 | #define FH_FLAG(x, name)(!!((x)->flags & 
V4L2_AV1_FRAME_FLAG_##name))
  |  
^~~~
drivers/media/platform/mediatek/vcodec/vdec/vdec_av1_req_lat_if.c:1322:41: 
note: in expansion of macro ‘FH_FLAG’
 1322 | uh->uniform_tile_spacing_flag = FH_FLAG(ctrl_fh, 
UNIFORM_TILE_SPACING);
  | ^~~

This flag was renamed from V4L2_AV1_FRAME_FLAG_UNIFORM_TILE_SPACING to
V4L2_AV1_TILE_INFO_FLAG_UNIFORM_TILE_SPACING in v5 of the AV1 uAPI.

So this suggests to me that you are testing with an old version of the AV1
uAPI. The correct one is v7:

https://patchwork.linuxtv.org/project/linux-media/patch/20230306161850.492072-1-daniel.alme...@collabora.com/

You have to compile and test with that v7 patch since that's the version we
want to merge.

Regards,

Hans


Re: [PATCH v5 00/20] Add Tegra20 parallel video input capture

2023-04-12 Thread Hans Verkuil
On 12/04/2023 11:16, Luca Ceresoli wrote:
> Hello Hans,
> 
> On Fri,  7 Apr 2023 15:38:32 +0200
> Luca Ceresoli  wrote:
> 
>> New in v5: dropped the patch that was removing lots of the logic behind
>> enum_format, after discussion with Hans. The rest is unmodified except for
>> rebasing and fixing a couple typos in comments.
>>
>> Full details follow.
>>
>> Tegra20 and other Tegra SoCs have a video input (VI) peripheral that can
>> receive from either MIPI CSI-2 or parallel video (called respectively "CSI"
>> and "VIP" in the documentation). The kernel currently has a staging driver
>> for Tegra210 CSI capture. This patch set adds support for Tegra20 VIP
>> capture.
>>
>> Unfortunately I had no real documentation available to base this work on.
>> I only had a working downstream 3.1 kernel, so I started with the driver
>> found there and heavily reworked it to fit into the mainline tegra-video
>> driver structure. The existing code appears written with the intent of
>> being modular and allow adding new input mechanisms and new SoCs while
>> keeping a unique VI core module. However its modularity and extensibility
>> was not enough to add Tegra20 VIP support, so I added some hooks to turn
>> hard-coded behaviour into per-SoC or per-bus customizable code. There are
>> also a fix, some generic cleanups and DT bindings.
>>
>> Quick tour of the patches:
>>
>>  * Device tree bindings
>>
>>01. dt-bindings: display: tegra: add Tegra20 VIP
>>02. dt-bindings: display: tegra: vi: add 'vip' property and example
>>
>>  * Minor improvements to logging, comments, cleanups
>>
>>03. staging: media: tegra-video: improve documentation of 
>> tegra_video_format fields
>>04. staging: media: tegra-video: document 
>> tegra_channel_get_remote_source_subdev
>>05. staging: media: tegra-video: fix typos in comment
>>06. staging: media: tegra-video: improve error messages
>>07. staging: media: tegra-video: slightly simplify cleanup on errors
>>08. staging: media: tegra-video: move private struct declaration to C file
>>09. staging: media: tegra-video: move tegra210_csi_soc to C file
>>10. staging: media: tegra-video: remove unneeded include
>>
>>  * Preparation to make the VI module generic enough to host Tegra20 and VIP
>>
>>11. staging: media: tegra-video: Kconfig: allow TPG only on Tegra210
>>12. staging: media: tegra-video: move tegra_channel_fmt_align to a 
>> per-soc op
>>13. staging: media: tegra-video: move default format to soc-specific data
>>14. staging: media: tegra-video: move MIPI calibration calls from VI to 
>> CSI
>>15. staging: media: tegra-video: add a per-soc enable/disable op
>>16. staging: media: tegra-video: move syncpt init/free to a per-soc op
>>17. staging: media: tegra-video: add syncpts for Tegra20 to struct 
>> tegra_vi
>>18. staging: media: tegra-video: add hooks for planar YUV and H/V flip
>>19. staging: media: tegra-video: add H/V flip controls
>>
>>  * Implementation of VIP and Tegra20
>>
>>20. staging: media: tegra-video: add support for Tegra20 parallel input
>>
>> Enjoy!
>>
>> Changed in v5:
>> - removed patch 3 as requested by Hans Verkuil; now the driver is kept
>>   video-node-centric and the enum_format logic is unchanged
>> - rebased on top of that
>> - trivial fixes (typos)
> 
> According to your review of v4, removing patch 3 was the only change
> required, and I didn't do anything else, and there have been no big
> changes since v1 anyway, so I was wondering whether this series has any
> hope to make it for 6.4...

It's borderline. I first need to test it again, and I can do that Friday
at the earliest (if I find the time). I'll try, but no promises...

Regards,

Hans


Re: [RESEND PATCH v4 03/21] staging: media: tegra-video: fix .vidioc_enum_fmt_vid_cap to return all formats

2023-04-05 Thread Hans Verkuil
On 05/04/2023 10:31, Luca Ceresoli wrote:
> Hi Laurent,
> 
> On Wed, 5 Apr 2023 05:30:48 +0300
> Laurent Pinchart  wrote:
> 
>> Hi Luca,
>>
>> On Tue, Apr 04, 2023 at 04:12:51PM +0200, Luca Ceresoli wrote:
>>> On Wed, 29 Mar 2023 13:16:22 +0200 Hans Verkuil wrote:
>>>   
>>>> Hi Luca,
>>>>
>>>> I finally found the time to test this series. It looks OK, except for this 
>>>> patch.  
>>>
>>> Thank you very much for taking the time!
>>>   
>>>> The list of supported formats really has to be the intersection of what 
>>>> the tegra
>>>> supports and what the sensor supports.
>>>>
>>>> Otherwise you would advertise pixelformats that cannot be used, and the 
>>>> application
>>>> would have no way of knowing that.  
>>>
>>> As far as I understand, I think we should rather make this driver fully
>>> behave as an MC-centric device. It is already using MC quite
>>> successfully after all.
>>>
>>> Do you think this is correct?  
>>
>> Given the use cases for this driver, I agree.

I disagree.

This driver doesn't use the media controller for anything at the moment. The
/dev/mediaX device just shows the internal topology (i.e. connected sensors),
but otherwise it does nothing.

While it would be great if we could unlock the ISP on the Tegra, the reality
is that it is entirely closed source and can't be used in a linux driver, and
that's not going to change, sadly.

That leaves us with just a basic CSI capture driver. Rather than trying to
change this driver to a full MC device with no benefits, just drop this change
and get your code in.

Note that this driver will stay in staging since it still fails when I try to
capture from two sensors at the same time: syncpoint errors start appearing
in that case. I think there are locking issues. I think I have someone to take
a look at that, but first I want your series to get merged.

In the very unlikely event that the ISP can be implemented in a linux driver,
it will probably become a new driver.

Regards,

Hans

> 
> Ok, thanks for the feedback. I will send a v5 with this change.
> 
> Best regards,
> Luca
> 



Re: [RESEND PATCH v4 03/21] staging: media: tegra-video: fix .vidioc_enum_fmt_vid_cap to return all formats

2023-03-29 Thread Hans Verkuil
Hi Luca,

On 29/03/2023 13:16, Hans Verkuil wrote:
> Hi Luca,
> 
> I finally found the time to test this series. It looks OK, except for this 
> patch.
> The list of supported formats really has to be the intersection of what the 
> tegra
> supports and what the sensor supports.
> 
> Otherwise you would advertise pixelformats that cannot be used, and the 
> application
> would have no way of knowing that.
> 
> This patch needs to be dropped.
> 
> I'll run this series through my other checks, and I will let you know today if
> anything else needs to be changed.

All other checks passed, so this is the only issue blocking this series from 
being
merged.

Regards,

Hans

> 
> Regards,
> 
>   Hans
> 
> On 09/03/2023 15:43, Luca Ceresoli wrote:
>> The .vidioc_enum_fmt_vid_cap (called tegra_channel_enum_format() here)
>> should return all the supported formats. Instead the current implementation
>> computes the intersection between the formats it supports and those
>> supported by the first subdev in the stream (typically the image sensor).
>>
>> Remove all the unnecessary logic that supports such algorithm. In order to
>> do this, also change the Tegra210 CSI TPG formats from the current
>> open-coded implementation in vi_tpg_fmts_bitmap_init() to a const array in
>> tegra210.c, just like the one that describes the regular formats.
>>
>> Fixes: 3d8a97eabef0 ("media: tegra-video: Add Tegra210 Video input driver")
>> Signed-off-by: Luca Ceresoli 
>> Reviewed-by: Dmitry Osipenko 
>>
>> ---
>>
>> Changed in v4:
>>  - Added review tags
>>
>> No changes in v3
>> No changes in v2
>> ---
>>  drivers/staging/media/tegra-video/tegra210.c |   7 +-
>>  drivers/staging/media/tegra-video/vi.c   | 103 +--
>>  drivers/staging/media/tegra-video/vi.h   |   4 -
>>  3 files changed, 9 insertions(+), 105 deletions(-)
>>
>> diff --git a/drivers/staging/media/tegra-video/tegra210.c 
>> b/drivers/staging/media/tegra-video/tegra210.c
>> index d58370a84737..eb19dd5107ce 100644
>> --- a/drivers/staging/media/tegra-video/tegra210.c
>> +++ b/drivers/staging/media/tegra-video/tegra210.c
>> @@ -683,8 +683,12 @@ enum tegra210_image_format {
>>  V4L2_PIX_FMT_##FOURCC,  \
>>  }
>>  
>> -/* Tegra210 supported video formats */
>>  static const struct tegra_video_format tegra210_video_formats[] = {
>> +#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
>> +/* VI only support 2 formats in TPG mode */
>> +TEGRA210_VIDEO_FMT(RAW10,  10, SRGGB10_1X10,  2, T_R16_I,
>> SRGGB10),
>> +TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8, 
>> RGBX32),
>> +#else
>>  /* RAW 8 */
>>  TEGRA210_VIDEO_FMT(RAW8, 8, SRGGB8_1X8, 1, T_L8, SRGGB8),
>>  TEGRA210_VIDEO_FMT(RAW8, 8, SGRBG8_1X8, 1, T_L8, SGRBG8),
>> @@ -714,6 +718,7 @@ static const struct tegra_video_format 
>> tegra210_video_formats[] = {
>>  TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_2X8, 2, T_V8_Y8__U8_Y8, YUYV),
>>  TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_2X8, 2, T_Y8_U8__Y8_V8, VYUY),
>>  TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_2X8, 2, T_Y8_V8__Y8_U8, UYVY),
>> +#endif
>>  };
>>  
>>  /* Tegra210 VI operations */
>> diff --git a/drivers/staging/media/tegra-video/vi.c 
>> b/drivers/staging/media/tegra-video/vi.c
>> index 11dd142c98c5..9dba6e97ebdd 100644
>> --- a/drivers/staging/media/tegra-video/vi.c
>> +++ b/drivers/staging/media/tegra-video/vi.c
>> @@ -3,7 +3,6 @@
>>   * Copyright (C) 2020 NVIDIA CORPORATION.  All rights reserved.
>>   */
>>  
>> -#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -73,15 +72,6 @@ static int tegra_get_format_idx_by_code(struct tegra_vi 
>> *vi,
>>  return -1;
>>  }
>>  
>> -static u32 tegra_get_format_fourcc_by_idx(struct tegra_vi *vi,
>> -  unsigned int index)
>> -{
>> -if (index >= vi->soc->nformats)
>> -return -EINVAL;
>> -
>> -return vi->soc->video_formats[index].fourcc;
>> -}
>> -
>>  static const struct tegra_video_format *
>>  tegra_get_format_by_fourcc(struct tegra_vi *vi, u32 fourcc)
>>  {
>> @@ -430,19 +420,12 @@ static int tegra_channel_enum_format(struct file 
>> *file, void *fh,
>>   struct v4l2_fmtdesc *f)
>>  {
>>  struct tegra_vi_channel *chan = video_drvdata(file);
>> -unsigned in

Re: [RESEND PATCH v4 03/21] staging: media: tegra-video: fix .vidioc_enum_fmt_vid_cap to return all formats

2023-03-29 Thread Hans Verkuil
Hi Luca,

I finally found the time to test this series. It looks OK, except for this 
patch.
The list of supported formats really has to be the intersection of what the 
tegra
supports and what the sensor supports.

Otherwise you would advertise pixelformats that cannot be used, and the 
application
would have no way of knowing that.

This patch needs to be dropped.

I'll run this series through my other checks, and I will let you know today if
anything else needs to be changed.

Regards,

Hans

On 09/03/2023 15:43, Luca Ceresoli wrote:
> The .vidioc_enum_fmt_vid_cap (called tegra_channel_enum_format() here)
> should return all the supported formats. Instead the current implementation
> computes the intersection between the formats it supports and those
> supported by the first subdev in the stream (typically the image sensor).
> 
> Remove all the unnecessary logic that supports such algorithm. In order to
> do this, also change the Tegra210 CSI TPG formats from the current
> open-coded implementation in vi_tpg_fmts_bitmap_init() to a const array in
> tegra210.c, just like the one that describes the regular formats.
> 
> Fixes: 3d8a97eabef0 ("media: tegra-video: Add Tegra210 Video input driver")
> Signed-off-by: Luca Ceresoli 
> Reviewed-by: Dmitry Osipenko 
> 
> ---
> 
> Changed in v4:
>  - Added review tags
> 
> No changes in v3
> No changes in v2
> ---
>  drivers/staging/media/tegra-video/tegra210.c |   7 +-
>  drivers/staging/media/tegra-video/vi.c   | 103 +--
>  drivers/staging/media/tegra-video/vi.h   |   4 -
>  3 files changed, 9 insertions(+), 105 deletions(-)
> 
> diff --git a/drivers/staging/media/tegra-video/tegra210.c 
> b/drivers/staging/media/tegra-video/tegra210.c
> index d58370a84737..eb19dd5107ce 100644
> --- a/drivers/staging/media/tegra-video/tegra210.c
> +++ b/drivers/staging/media/tegra-video/tegra210.c
> @@ -683,8 +683,12 @@ enum tegra210_image_format {
>   V4L2_PIX_FMT_##FOURCC,  \
>  }
>  
> -/* Tegra210 supported video formats */
>  static const struct tegra_video_format tegra210_video_formats[] = {
> +#if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
> + /* VI only support 2 formats in TPG mode */
> + TEGRA210_VIDEO_FMT(RAW10,  10, SRGGB10_1X10,  2, T_R16_I,
> SRGGB10),
> + TEGRA210_VIDEO_FMT(RGB888, 24, RGB888_1X32_PADHI, 4, T_A8B8G8R8, 
> RGBX32),
> +#else
>   /* RAW 8 */
>   TEGRA210_VIDEO_FMT(RAW8, 8, SRGGB8_1X8, 1, T_L8, SRGGB8),
>   TEGRA210_VIDEO_FMT(RAW8, 8, SGRBG8_1X8, 1, T_L8, SGRBG8),
> @@ -714,6 +718,7 @@ static const struct tegra_video_format 
> tegra210_video_formats[] = {
>   TEGRA210_VIDEO_FMT(YUV422_8, 16, VYUY8_2X8, 2, T_V8_Y8__U8_Y8, YUYV),
>   TEGRA210_VIDEO_FMT(YUV422_8, 16, YUYV8_2X8, 2, T_Y8_U8__Y8_V8, VYUY),
>   TEGRA210_VIDEO_FMT(YUV422_8, 16, YVYU8_2X8, 2, T_Y8_V8__Y8_U8, UYVY),
> +#endif
>  };
>  
>  /* Tegra210 VI operations */
> diff --git a/drivers/staging/media/tegra-video/vi.c 
> b/drivers/staging/media/tegra-video/vi.c
> index 11dd142c98c5..9dba6e97ebdd 100644
> --- a/drivers/staging/media/tegra-video/vi.c
> +++ b/drivers/staging/media/tegra-video/vi.c
> @@ -3,7 +3,6 @@
>   * Copyright (C) 2020 NVIDIA CORPORATION.  All rights reserved.
>   */
>  
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -73,15 +72,6 @@ static int tegra_get_format_idx_by_code(struct tegra_vi 
> *vi,
>   return -1;
>  }
>  
> -static u32 tegra_get_format_fourcc_by_idx(struct tegra_vi *vi,
> -   unsigned int index)
> -{
> - if (index >= vi->soc->nformats)
> - return -EINVAL;
> -
> - return vi->soc->video_formats[index].fourcc;
> -}
> -
>  static const struct tegra_video_format *
>  tegra_get_format_by_fourcc(struct tegra_vi *vi, u32 fourcc)
>  {
> @@ -430,19 +420,12 @@ static int tegra_channel_enum_format(struct file *file, 
> void *fh,
>struct v4l2_fmtdesc *f)
>  {
>   struct tegra_vi_channel *chan = video_drvdata(file);
> - unsigned int index = 0, i;
> - unsigned long *fmts_bitmap = chan->tpg_fmts_bitmap;
> -
> - if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG))
> - fmts_bitmap = chan->fmts_bitmap;
> + const struct tegra_vi_soc *soc = chan->vi->soc;
>  
> - if (f->index >= bitmap_weight(fmts_bitmap, MAX_FORMAT_NUM))
> + if (f->index >= soc->nformats)
>   return -EINVAL;
>  
> - for (i = 0; i < f->index + 1; i++, index++)
> - index = find_next_bit(fmts_bitmap, MAX_FORMAT_NUM, index);
> -
> - f->pixelformat = tegra_get_format_fourcc_by_idx(chan->vi, index - 1);
> + f->pixelformat = soc->video_formats[f->index].fourcc;
>  
>   return 0;
>  }
> @@ -1059,78 +1042,6 @@ static int tegra_channel_setup_ctrl_handler(struct 
> tegra_vi_channel *chan)
>   return 0;
>  }
>  
> -/* VI only support 2 formats in TPG mode */
> -static void vi_tpg_fmts_bitmap_init(struct tegra_vi_channel *chan)
> -{
> - in

Re: [PATCH 01/12] gpu: host1x: Make host1x_client_unregister() return void

2023-03-27 Thread Hans Verkuil
On 22/03/2023 18:02, Uwe Kleine-König wrote:
> This function returned zero unconditionally. Make it return no value and
> simplify all callers accordingly.
> 
> Signed-off-by: Uwe Kleine-König 
> ---
>  drivers/gpu/drm/tegra/dc.c  | 7 +--
>  drivers/gpu/drm/tegra/dsi.c | 8 +---
>  drivers/gpu/drm/tegra/gr2d.c| 8 +---
>  drivers/gpu/drm/tegra/gr3d.c| 8 +---
>  drivers/gpu/drm/tegra/hdmi.c| 8 +---
>  drivers/gpu/drm/tegra/hub.c | 9 ++---
>  drivers/gpu/drm/tegra/nvdec.c   | 8 +---
>  drivers/gpu/drm/tegra/sor.c | 8 +---
>  drivers/gpu/drm/tegra/vic.c | 8 +---
>  drivers/gpu/host1x/bus.c| 6 ++
>  drivers/staging/media/tegra-video/csi.c | 8 +---
>  drivers/staging/media/tegra-video/vi.c  | 8 +---
>  include/linux/host1x.h  | 2 +-
>  13 files changed, 15 insertions(+), 81 deletions(-)

Acked-by: Hans Verkuil 

Regards,

Hans

> 
> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> index a67453cee883..bd108159fc2c 100644
> --- a/drivers/gpu/drm/tegra/dc.c
> +++ b/drivers/gpu/drm/tegra/dc.c
> @@ -3268,12 +3268,7 @@ static int tegra_dc_remove(struct platform_device 
> *pdev)
>   struct tegra_dc *dc = platform_get_drvdata(pdev);
>   int err;
>  
> - err = host1x_client_unregister(&dc->client);
> - if (err < 0) {
> - dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
> - err);
> - return err;
> - }
> + host1x_client_unregister(&dc->client);
>  
>   err = tegra_dc_rgb_remove(dc);
>   if (err < 0) {
> diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
> index de1333dc0d86..c8a02a1024bc 100644
> --- a/drivers/gpu/drm/tegra/dsi.c
> +++ b/drivers/gpu/drm/tegra/dsi.c
> @@ -1662,16 +1662,10 @@ static int tegra_dsi_probe(struct platform_device 
> *pdev)
>  static int tegra_dsi_remove(struct platform_device *pdev)
>  {
>   struct tegra_dsi *dsi = platform_get_drvdata(pdev);
> - int err;
>  
>   pm_runtime_disable(&pdev->dev);
>  
> - err = host1x_client_unregister(&dsi->client);
> - if (err < 0) {
> - dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
> - err);
> - return err;
> - }
> + host1x_client_unregister(&dsi->client);
>  
>   tegra_output_remove(&dsi->output);
>  
> diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
> index e3bb4c99ed39..49b8d4953e7f 100644
> --- a/drivers/gpu/drm/tegra/gr2d.c
> +++ b/drivers/gpu/drm/tegra/gr2d.c
> @@ -298,14 +298,8 @@ static int gr2d_probe(struct platform_device *pdev)
>  static int gr2d_remove(struct platform_device *pdev)
>  {
>   struct gr2d *gr2d = platform_get_drvdata(pdev);
> - int err;
>  
> - err = host1x_client_unregister(&gr2d->client.base);
> - if (err < 0) {
> - dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
> - err);
> - return err;
> - }
> + host1x_client_unregister(&gr2d->client.base);
>  
>   return 0;
>  }
> diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
> index a1fd3113ea96..cd3679d8eef9 100644
> --- a/drivers/gpu/drm/tegra/gr3d.c
> +++ b/drivers/gpu/drm/tegra/gr3d.c
> @@ -553,14 +553,8 @@ static int gr3d_probe(struct platform_device *pdev)
>  static int gr3d_remove(struct platform_device *pdev)
>  {
>   struct gr3d *gr3d = platform_get_drvdata(pdev);
> - int err;
>  
> - err = host1x_client_unregister(&gr3d->client.base);
> - if (err < 0) {
> - dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
> - err);
> - return err;
> - }
> + host1x_client_unregister(&gr3d->client.base);
>  
>   return 0;
>  }
> diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
> index 40ec3e6cf204..6798eea317df 100644
> --- a/drivers/gpu/drm/tegra/hdmi.c
> +++ b/drivers/gpu/drm/tegra/hdmi.c
> @@ -1877,14 +1877,8 @@ static int tegra_hdmi_probe(struct platform_device 
> *pdev)
>  static int tegra_hdmi_remove(struct platform_device *pdev)
>  {
>   struct tegra_hdmi *hdmi = platform_get_drvdata(pdev);
> - int err;
>  
> - err = host1x_client_unregister(&hdmi->client);
> - if (err < 0) {
> - dev_err(&pdev->

Re: [RESEND PATCH v4 00/21] Add Tegra20 parallel video input capture

2023-03-22 Thread Hans Verkuil
On 22/03/2023 10:14, Luca Ceresoli wrote:
> Hello,
> 
> On Thu,  9 Mar 2023 15:42:59 +0100
> Luca Ceresoli  wrote:
> 
>> TL;DR: Resending this series with Rob's review tag added. Now all DT
>> patches have at least a reviewed-by tag from Rob or Krzysztof, all the
>> driver patches have one from Dmitry.
> 
> This is a gentle ping about this series. All patches have a
> reviewed-by, there are no major changes since v2, and it's touching a
> staging driver anyway.
> 
> I don't think there is more I can do at the moment besides pinging, but
> should there be anything, I'd be glad to know! :-)

I actually started on this last week, but now I am abroad again with no
hardware access.

I hope I can resume work on it next week, because after that I am again
abroad for 10 days or so.

It's currently very high on my todo list, so I really hope I will be able
to make progress on it next week.

Regards,

Hans


Re: [PATCH v2 1/9] drm/vc4: Switch to container_of_const

2023-02-21 Thread Hans Verkuil
On 2/21/23 12:38, Maxime Ripard wrote:
> Hi Hans,
> 
> On Sat, Feb 18, 2023 at 11:45:04AM +0100, Hans Verkuil wrote:
>>> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
>>> index 86d629e45307..d0a00ed42cb0 100644
>>> --- a/drivers/gpu/drm/vc4/vc4_bo.c
>>> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
>>> @@ -609,7 +609,7 @@ static void vc4_free_object(struct drm_gem_object 
>>> *gem_bo)
>>>  static void vc4_bo_cache_time_work(struct work_struct *work)
>>>  {
>>> struct vc4_dev *vc4 =
>>> -   container_of(work, struct vc4_dev, bo_cache.time_work);
>>> +   container_of_const(work, struct vc4_dev, bo_cache.time_work);
>>
>> ...I think this is misleading. It's definitely not const, so switching to
>> container_of_const suggests that there is some 'constness' involved, which
>> isn't the case. I'd leave this just as 'container_of'. This also reduces the
>> size of the patch, since this is done in quite a few places.
> 
> The name threw me off too, but it's supposed to keep the argument
> pointer constness, not always take and return a const pointer. I still
> believe that it's beneficial since, if the work pointer was ever to
> change constness, we would have that additional check.

If both inner (work) and outer (vc4) pointers are non-const, then there is no 
sense
in switching to container_of_const. I don't see it used like that elsewhere
in the kernel.

It only makes sense to use it if the inner pointer might be const.

If the work pointer (in this example) would ever become const, then the
regular container_of macro would report a warning, that's something that
was added in commit 7376e561fd2e. So preemptively switching to 
container_of_const
appears unnecessary to me.

Regards,

Hans


Re: [PATCH v2 3/9] drm/vc4: hdmi: Add Broadcast RGB property to allow override of RGB range

2023-02-21 Thread Hans Verkuil
On 2/20/23 16:23, Dave Stevenson wrote:
> Hi Hans
> 
> On Sat, 18 Feb 2023 at 11:33, Hans Verkuil  wrote:
>>
>> Hi Maxime, Dave,
>>
>> On 26/01/2023 14:46, Maxime Ripard wrote:
>>> From: Dave Stevenson 
>>>
>>> Copy Intel's "Broadcast RGB" property semantics to add manual override
>>> of the HDMI pixel range for monitors that don't abide by the content
>>> of the AVI Infoframe.
>>
>> Do we have to copy that property as-is?
> 
> Firstly I'll agree with your later comment that having this control
> allows testing of a range of output modes, and working around HDMI
> sinks that have dodgy implementations.
> (In our vendor kernel we now also have a property to override the
> kernel chosen output format to enable testing of YCbCr4:4:4 and 4:2:2
> output).
> 
> The DRM subsystem has the requirement for an open-source userspace
> project to be using any new property before it will be merged [1].
> This property already exists for i915 and gma-500, therefore avoids
> that requirement.
> 
> There are objections to the UAPI for Broadcast RGB [2], but if it's
> good enough for the existing implementations then there can be no
> objection to it being implemented in the same way for other drivers.
> Otherwise it is a missing feature of the DRM API, and the linked
> discussion is realistically at least a year away from being resolved.
> Why bury our heads in the sand for that period?
> 
> [1] 
> https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements
> [2] https://lists.freedesktop.org/archives/dri-devel/2023-February/391061.html
> 
>> First of all, I think this should really be a drm-level property, rather than
>> a driver property: RGB Quantization Range mismatches are the bane of my life,
>> and I think a way to override this would help everyone.
> 
> Linked to above, if it were the preferred method for controlling this
> then I would expect it to become a drm-level property.
> 
>> Secondly, I hate the name they came up with: 'Broadcast RGB' is pretty 
>> meaningless.
>> Can't we stick to something closer to what the CTA-861/HDMI specs use, which 
>> is
>> 'RGB Quantization Range'? So either use that, or just 'RGB Range'.
>>
>> In addition, 'Limited 16:235' should just be 'Limited' since the actual range
>> depends on the bits-per-color-component.
> 
> It's documented UAPI with those names[3], therefore any change would
> be a change to user-space's expectation and a regression. At least by
> sticking with the same names then any user space implementation that
> exists for i915 or gma-500 will also work in the same way on vc4.
> 
> [3] 
> https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#existing-kms-properties

Thank you for linking to these threads. It's a terrible name, but it is still
better to have this property than to not have it :-)

> 
>>>
>>> Signed-off-by: Dave Stevenson 
>>> Signed-off-by: Maxime Ripard 
>>> ---
>>>  drivers/gpu/drm/vc4/vc4_hdmi.c | 97 
>>> --
>>>  drivers/gpu/drm/vc4/vc4_hdmi.h |  9 
>>>  2 files changed, 102 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
>>> index 4b3bf77bb5cd..78749c6fa837 100644
>>> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
>>> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
>>> @@ -150,10 +150,16 @@ static bool vc4_hdmi_mode_needs_scrambling(const 
>>> struct drm_display_mode *mode,
>>>  }
>>>
>>>  static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
>>> -const struct drm_display_mode *mode)
>>> +struct vc4_hdmi_connector_state 
>>> *vc4_state)
>>>  {
>>> + const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
>>>   struct drm_display_info *display = &vc4_hdmi->connector.display_info;
>>>
>>> + if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED)
>>> + return false;
>>> + else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL)
>>> + return true;
>>> +
>>>   return !display->is_hdmi ||
>>>   drm_default_rgb_quant_range(mode) == 
>>> HDMI_QUANTIZATION_RANGE_FULL;
>>>  }
>>> @@ -524,8 +530,12 @@ static int vc4_hdmi_connector_atomic_check(struct 
&

Re: [PATCH v2 3/9] drm/vc4: hdmi: Add Broadcast RGB property to allow override of RGB range

2023-02-18 Thread Hans Verkuil
Hi Maxime, Dave,

On 26/01/2023 14:46, Maxime Ripard wrote:
> From: Dave Stevenson 
> 
> Copy Intel's "Broadcast RGB" property semantics to add manual override
> of the HDMI pixel range for monitors that don't abide by the content
> of the AVI Infoframe.

Do we have to copy that property as-is?

First of all, I think this should really be a drm-level property, rather than
a driver property: RGB Quantization Range mismatches are the bane of my life,
and I think a way to override this would help everyone.

Secondly, I hate the name they came up with: 'Broadcast RGB' is pretty 
meaningless.
Can't we stick to something closer to what the CTA-861/HDMI specs use, which is
'RGB Quantization Range'? So either use that, or just 'RGB Range'.

In addition, 'Limited 16:235' should just be 'Limited' since the actual range
depends on the bits-per-color-component.

> 
> Signed-off-by: Dave Stevenson 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/vc4_hdmi.c | 97 
> --
>  drivers/gpu/drm/vc4/vc4_hdmi.h |  9 
>  2 files changed, 102 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 4b3bf77bb5cd..78749c6fa837 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -150,10 +150,16 @@ static bool vc4_hdmi_mode_needs_scrambling(const struct 
> drm_display_mode *mode,
>  }
>  
>  static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
> -const struct drm_display_mode *mode)
> +struct vc4_hdmi_connector_state 
> *vc4_state)
>  {
> + const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
>   struct drm_display_info *display = &vc4_hdmi->connector.display_info;
>  
> + if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED)
> + return false;
> + else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL)
> + return true;
> +
>   return !display->is_hdmi ||
>   drm_default_rgb_quant_range(mode) == 
> HDMI_QUANTIZATION_RANGE_FULL;
>  }
> @@ -524,8 +530,12 @@ static int vc4_hdmi_connector_atomic_check(struct 
> drm_connector *connector,
>  {
>   struct drm_connector_state *old_state =
>   drm_atomic_get_old_connector_state(state, connector);
> + struct vc4_hdmi_connector_state *old_vc4_state =
> + conn_state_to_vc4_hdmi_conn_state(old_state);
>   struct drm_connector_state *new_state =
>   drm_atomic_get_new_connector_state(state, connector);
> + struct vc4_hdmi_connector_state *new_vc4_state =
> + conn_state_to_vc4_hdmi_conn_state(new_state);
>   struct drm_crtc *crtc = new_state->crtc;
>  
>   if (!crtc)
> @@ -558,6 +568,7 @@ static int vc4_hdmi_connector_atomic_check(struct 
> drm_connector *connector,
>   }
>  
>   if (old_state->colorspace != new_state->colorspace ||
> + old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||

The problem with this is that this will cause a mode change, even though all
that is necessary is to update the csc matrix and AVI InfoFrame.

I used this code (added just before the 'return 0;' at the end of this 
function):

if (old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb) {
const struct drm_display_mode *mode = 
&vc4_hdmi->saved_adjusted_mode;

old_vc4_state->broadcast_rgb = new_vc4_state->broadcast_rgb;
vc4_hdmi_set_avi_infoframe(encoder);
if (vc4_hdmi->variant->csc_setup)
vc4_hdmi->variant->csc_setup(vc4_hdmi, old_state, mode);
}

I'm certain this is in the wrong place, but I'm not familiar enough with the 
drm API
to determine where this should go.

This approach probably applies to the hdr_metadata metadata as well, that too
doesn't need a mode change.

I see that the i915 driver has a 'fastset' mechanism for changes like this, but
it is not clear to me how that interacts with the drm API.

I've been playing around with this vc4 driver and it is proving to be very 
useful
for debugging all sorts of quantization range bugs in other equipment.

Regards,

Hans

>   !drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
>   struct drm_crtc_state *crtc_state;
>  
> @@ -571,6 +582,49 @@ static int vc4_hdmi_connector_atomic_check(struct 
> drm_connector *connector,
>   return 0;
>  }
>  
> +static int vc4_hdmi_connector_get_property(struct drm_connector *connector,
> +const struct drm_connector_state 
> *state,
> +struct drm_property *property,
> +uint64_t *val)
> +{
> + struct drm_device *drm = connector->dev;
> + struct vc4_hdmi *vc4_hdmi =
> + connector_to_vc4_hdmi(connector);
> + con

Re: [PATCH v2 1/9] drm/vc4: Switch to container_of_const

2023-02-18 Thread Hans Verkuil
Hi Maxime,

On 26/01/2023 14:46, Maxime Ripard wrote:
> container_of_const() allows to preserve the pointer constness and is
> thus more flexible than inline functions.
> 
> Let's switch all our instances of container_of() to
> container_of_const().
> 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/tests/vc4_mock.h|  3 ++
>  drivers/gpu/drm/vc4/tests/vc4_mock_output.c |  4 +-
>  drivers/gpu/drm/vc4/vc4_bo.c|  2 +-
>  drivers/gpu/drm/vc4/vc4_crtc.c  |  4 +-
>  drivers/gpu/drm/vc4/vc4_dpi.c   |  7 +---
>  drivers/gpu/drm/vc4/vc4_drv.h   | 65 
> +
>  drivers/gpu/drm/vc4/vc4_dsi.c   | 19 -
>  drivers/gpu/drm/vc4/vc4_gem.c   |  7 ++--
>  drivers/gpu/drm/vc4/vc4_hdmi.c  |  7 ++--
>  drivers/gpu/drm/vc4/vc4_hdmi.h  | 16 +++
>  drivers/gpu/drm/vc4/vc4_irq.c   |  2 +-
>  drivers/gpu/drm/vc4/vc4_kms.c   | 16 +++
>  drivers/gpu/drm/vc4/vc4_plane.c |  2 +-
>  drivers/gpu/drm/vc4/vc4_txp.c   | 12 ++
>  drivers/gpu/drm/vc4/vc4_v3d.c   |  2 +-
>  drivers/gpu/drm/vc4/vc4_vec.c   | 14 ++-
>  16 files changed, 65 insertions(+), 117 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h 
> b/drivers/gpu/drm/vc4/tests/vc4_mock.h
> index db8e9a141ef8..2d0b339bd9f3 100644
> --- a/drivers/gpu/drm/vc4/tests/vc4_mock.h
> +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h
> @@ -43,6 +43,9 @@ struct vc4_dummy_output {
>   struct drm_connector connector;
>  };
>  
> +#define encoder_to_vc4_dummy_output(_enc)\
> + container_of_const(_enc, struct vc4_dummy_output, encoder.base)

I think it is OKish to do this in a define like this, but...

> +
>  struct vc4_dummy_output *vc4_dummy_output(struct kunit *test,
> struct drm_device *drm,
> struct drm_crtc *crtc,
> diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c 
> b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
> index 8d33be828d9a..6e11fcc9ef45 100644
> --- a/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
> +++ b/drivers/gpu/drm/vc4/tests/vc4_mock_output.c
> @@ -80,7 +80,7 @@ int vc4_mock_atomic_add_output(struct kunit *test,
>   crtc = vc4_find_crtc_for_encoder(test, drm, encoder);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
>  
> - output = container_of(encoder, struct vc4_dummy_output, encoder.base);
> + output = encoder_to_vc4_dummy_output(encoder);
>   conn = &output->connector;
>   conn_state = drm_atomic_get_connector_state(state, conn);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
> @@ -126,7 +126,7 @@ int vc4_mock_atomic_del_output(struct kunit *test,
>   ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
>   KUNIT_ASSERT_EQ(test, ret, 0);
>  
> - output = container_of(encoder, struct vc4_dummy_output, encoder.base);
> + output = encoder_to_vc4_dummy_output(encoder);
>   conn = &output->connector;
>   conn_state = drm_atomic_get_connector_state(state, conn);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
> index 86d629e45307..d0a00ed42cb0 100644
> --- a/drivers/gpu/drm/vc4/vc4_bo.c
> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
> @@ -609,7 +609,7 @@ static void vc4_free_object(struct drm_gem_object *gem_bo)
>  static void vc4_bo_cache_time_work(struct work_struct *work)
>  {
>   struct vc4_dev *vc4 =
> - container_of(work, struct vc4_dev, bo_cache.time_work);
> + container_of_const(work, struct vc4_dev, bo_cache.time_work);

...I think this is misleading. It's definitely not const, so switching to
container_of_const suggests that there is some 'constness' involved, which
isn't the case. I'd leave this just as 'container_of'. This also reduces the
size of the patch, since this is done in quite a few places.

Regards,

Hans

>   struct drm_device *dev = &vc4->base;
>  
>   mutex_lock(&vc4->bo_lock);
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index cdc0559221f0..4425dc15308d 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -869,7 +869,7 @@ vc4_async_page_flip_complete(struct vc4_async_flip_state 
> *flip_state)
>  static void vc4_async_page_flip_seqno_complete(struct vc4_seqno_cb *cb)
>  {
>   struct vc4_async_flip_state *flip_state =
> - container_of(cb, struct vc4_async_flip_state, cb.seqno);
> + container_of_const(cb, struct vc4_async_flip_state, cb.seqno);
>   struct vc4_bo *bo = NULL;
>  
>   if (flip_state->old_fb) {
> @@ -897,7 +897,7 @@ static void vc4_async_page_flip_fence_complete(struct 
> dma_fence *fence,
>  struct dma_fence_cb *cb)
>  {
>   struct vc4_async_flip_state

Re: [PATCH v2 00/21] Enable Colorspace connector property in amdgpu

2023-02-18 Thread Hans Verkuil
On 07/02/2023 13:47, Pekka Paalanen wrote:
> On Fri, 13 Jan 2023 11:24:07 -0500
> Harry Wentland  wrote:
> 
>> This patchset enables the DP and HDMI infoframe properties
>> in amdgpu.
>>
>> The first two patches are not completely related to the rest. The
>> first patch allows for HDR_OUTPUT_METADATA with EOTFs that are
>> unknown in the kernel.
>>
>> The second one prints a connector's max_bpc as part of the atomic
>> state debugfs print.
>>
>> The following patches rework the connector colorspace code to
>> 1) allow for easy printing of the colorspace in the drm_atomic
>>state debugfs, and
>> 2) allow drivers to specify the supported colorspaces on a
>>connector.
>>
>> The rest of the patches deal with the Colorspace enablement
>> in amdgpu.
>>
>> Why do drivers need to specify supported colorspaces? The amdgpu
>> driver needs support for RGB-to-YCbCr conversion when we drive
>> the display in YCbCr. This is currently not implemented for all
>> colorspaces.
>>
>> Since the Colorspace property didn't have an IGT test I added
>> one to kms_hdr. The relevant patchset can be found on the IGT
>> mailing list or on
>> https://gitlab.freedesktop.org/hwentland/igt-gpu-tools/-/tree/hdr-colorimetry
>>
>> We tested v1 of the patchset and confirmed that the infoframes
>> are as expected for both DP and HDMI when running the IGT
>> colorimetry tests.
>>
>> Open Items
>> --
>>
>> A couple comments from Pekka about colorspace documentation are
>> left unaddressed. I hope they won't block merging this set but
>> should still be addressed separately.
>>
>> Pekka's questions really got me thinking of how this colorspace
>> property should be used and working with it more closely with
>> Joshua who is enabling HDR in gamescope made me wonder even more.
>>
>> Uma, is there a (canonical, upstream) userspace that uses this
>> property that I can look at to understand more?
>>
>> One of the key challenges that is currently not addressed is that
>> userspace is expected to pick a colorspace format straight from the
>> list of definitions out of the DP or HDMI spec. But the kernel
>> driver are the ones deciding on the output encoding (RGB, YCBCR444,
>> YCBCR420, etc.). So there is no way for userspace to decide correctly
>> between, for example, BT2020_RGB, BT2020_CYCC, BT2020_YCC.
>>
>> So we end up in a scenario where gamescope sets BT2020_RGB but we
>> output YCBCR444 so have to correct the colorspace value to
>> BT2020_YCC. This in turn breaks the colorspace IGT tests I
>> wrote. I don't think "fixing" the IGT tests to accept this is
>> the right thing to do.
>>
>> The way it stands this patchset allows us to specify the output
>> colorspace on amdgpu and we try to do the right thing, but I don't
>> thing the way the colorspace property is defined is right. We're trying
>> to expose things to userspace that should be under driver control. A
>> much better approach would be to give userspace options for colorspace
>> that are not tied to DP or HDMI specs, i.e., sRGB, BT709, BT2020, etc.,
>> and have the driver do the right thing to fill the infoframe, e.g., by
>> picking BT2020_YCC if the requested colorspace is BT2020 and the
>> is YCBCR444.
> 
> Hi Harry,
> 
> well explained.
> 
> Indeed, if you want to keep the driver in control of the encoding on
> the monitor cable, then your suggestion seems correct (ignoring the
> question whether it breaks something existing).
> 
> I do recall something about letting userspace control the encoding on
> the cable though, particularly when it affects performance or quality.
> E.g. 4:2:0 sub-sampling might be wanted in some cases and unwanted in
> others. It's a bit similar to bpc. The trade-off may be frame rate or
> resolution. It might better to know that the hardware cannot do what
> you ask, than to silently degrade. E.g. if you use sub-pixel rendering,
> you really do not want 4:2:0.
> 
> That's compatible with your suggestion on changing the Colorspace
> property, I think it would complement it. Cable encoding parameters
> could be other properties, which might also be on "auto".
> 
> If Colorspace property cannot be changed, then options I haven't seen
> discussed yet are have it force the cable encoding parameters, or
> another new property replacing it.
> 
>> If no upstream userspace currently makes use of this property I
>> can make that change, i.e., no longer tie the colorspace property
>> directly to the infoframe and reduce the options to sRGB, BT709,
>> BT601, and BT2020 (and possibly opRGB).
>>
>> v2:
>> - Tested with DP and HDMI analyzers
>> - Confirmed driver will fallback to lower bpc when needed
>> - Dropped hunk to set HDMI AVI infoframe as it was a no-op
>> - Fixed BT.2020 YCbCr colorimetry (JoshuaAshton)
>> - Simplify initialization of supported colorspaces (Jani)
>> - Fix kerneldoc (kernel test robot)
> 
> I recall saying this before, but in the series there are occurrences
> where sRGB is spelled as "RGB". I find that very confusing that "RGB"
>

Re: [PATCH] drm/vc4: hdmi: make CEC adapter name unique

2023-01-23 Thread Hans Verkuil
On 20/01/2023 20:13, Maxime Ripard wrote:
> Hi Hans,
> 
> On Thu, Jan 19, 2023 at 10:02:19AM +0100, Hans Verkuil wrote:
>> The bcm2711 has two HDMI outputs, each with their own CEC adapter.
>> The CEC adapter name has to be unique, but it is currently
>> hardcoded to "vc4" for both outputs. Change this to use the card_name
>> from the variant information in order to make the adapter name unique.
>>
>> Signed-off-by: Hans Verkuil 
> 
> The patch looks good but should we Cc stable and add a Fixes tag here?

Good idea:

Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support")

Regards,

Hans


Re: [PATCH v3 0/7] media/drm: renesas: Add new pixel formats

2023-01-20 Thread Hans Verkuil
On 21/12/2022 10:24, Tomi Valkeinen wrote:
> From: Tomi Valkeinen 
> 
> Hi,
> 
> These add new pixel formats for Renesas V3U and V4H SoCs.
> 
> As the display pipeline is split between DRM and V4L2 components, this
> series touches both subsystems. I'm sending all these together to
> simplify review. If needed, I can later split this to V4L2 and DRM
> parts, of which the V4L2 part needs to be merged first.
> 
> Changes in v3:
> - Addressed all the review comments
> - Added Y212
> - Updated the kernel docs for the new formats
> - Changed the RGB format names to match the DRM's format names
> - Updated RPF register field macros according to the comments

For this series:

Acked-by: Hans Verkuil 

Thanks,

Hans

> 
>  Tomi
> 
> Tomi Valkeinen (7):
>   media: Add 2-10-10-10 RGB formats
>   media: Add Y210, Y212 and Y216 formats
>   media: renesas: vsp1: Change V3U to be gen4
>   media: renesas: vsp1: Add V4H SoC version
>   media: renesas: vsp1: Add new formats (2-10-10-10 ARGB, Y210, Y212)
>   drm: rcar-du: Bump V3U to gen 4
>   drm: rcar-du: Add new formats (2-10-10-10 ARGB, Y210)
> 
>  .../media/v4l/pixfmt-packed-yuv.rst   |  49 -
>  .../userspace-api/media/v4l/pixfmt-rgb.rst| 194 ++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c |   2 +-
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c |  30 +++
>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c |  50 -
>  .../media/platform/renesas/vsp1/vsp1_drv.c|   4 +-
>  .../media/platform/renesas/vsp1/vsp1_hgo.c|   4 +-
>  .../media/platform/renesas/vsp1/vsp1_lif.c|   1 +
>  .../media/platform/renesas/vsp1/vsp1_pipe.c   |  18 ++
>  .../media/platform/renesas/vsp1/vsp1_regs.h   |  26 ++-
>  .../media/platform/renesas/vsp1/vsp1_rpf.c|  64 +-
>  .../media/platform/renesas/vsp1/vsp1_video.c  |   4 +-
>  .../media/platform/renesas/vsp1/vsp1_wpf.c|   4 +-
>  drivers/media/v4l2-core/v4l2-ioctl.c  |   6 +
>  include/uapi/linux/videodev2.h|  11 +
>  15 files changed, 447 insertions(+), 20 deletions(-)
> 



[PATCH] drm/vc4: hdmi: make CEC adapter name unique

2023-01-19 Thread Hans Verkuil
The bcm2711 has two HDMI outputs, each with their own CEC adapter.
The CEC adapter name has to be unique, but it is currently
hardcoded to "vc4" for both outputs. Change this to use the card_name
from the variant information in order to make the adapter name unique.

Signed-off-by: Hans Verkuil 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index b39a1ba2c29b..d4c112c03f58 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -3018,7 +3018,8 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
}

vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
- vc4_hdmi, "vc4",
+ vc4_hdmi,
+ vc4_hdmi->variant->card_name,
  CEC_CAP_DEFAULTS |
  CEC_CAP_CONNECTOR_INFO, 1);
ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
-- 
2.39.0



Re: [PATCH 20/22] media: remove sh_vou

2023-01-13 Thread Hans Verkuil
On 13/01/2023 09:01, Laurent Pinchart wrote:
> Hi Christoph,
> 
> Thank you for the patch.
> 
> On Fri, Jan 13, 2023 at 07:23:37AM +0100, Christoph Hellwig wrote:
>> Now that arch/sh is removed this driver is dead code.
>>
>> Signed-off-by: Christoph Hellwig 
>> ---
>>  drivers/media/platform/renesas/Kconfig  |9 -
>>  drivers/media/platform/renesas/Makefile |1 -
>>  drivers/media/platform/renesas/sh_vou.c | 1375 ---
> 
> You can also emove include/media/drv-intf/sh_vou.sh. With that, and the
> corresponding MAINTAINERS entry dropped,
> 
> Reviewed-by: Laurent Pinchart 

And with that you can also add my Ack:

Acked-by: Hans Verkuil 

Regards,

Hans

> 
>>  3 files changed, 1385 deletions(-)
>>  delete mode 100644 drivers/media/platform/renesas/sh_vou.c
> 



Re: [PATCH v2 7/7] drm: rcar-du: Add new formats (2-10-10-10 ARGB, Y210)

2022-12-20 Thread Hans Verkuil
On 20/12/2022 10:18, Laurent Pinchart wrote:
> Hello,
> 
> On Tue, Dec 20, 2022 at 10:01:04AM +0100, Hans Verkuil wrote:
>> On 19/12/2022 22:47, Laurent Pinchart wrote:
>>> Hi Tomi,
>>>
>>> (CC'ing Sakari and Hans)
>>>
>>> Thank you for the patch.
>>>
>>> On Mon, Dec 19, 2022 at 04:01:39PM +0200, Tomi Valkeinen wrote:
>>>> Add new pixel formats: RGBX1010102, RGBA1010102, ARGB2101010 and Y210.
>>>>
>>>> Signed-off-by: Tomi Valkeinen 
>>>> ---
>>>>  drivers/gpu/drm/rcar-du/rcar_du_kms.c | 24 +
>>>>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 49 +--
>>>>  2 files changed, 71 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
>>>> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>>>> index 8c2719efda2a..8ccabf5a30c4 100644
>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>>>> @@ -259,6 +259,24 @@ static const struct rcar_du_format_info 
>>>> rcar_du_format_infos[] = {
>>>>.bpp = 32,
>>>>.planes = 1,
>>>>.hsub = 1,
>>>> +  }, {
>>>> +  .fourcc = DRM_FORMAT_RGBX1010102,
>>>
>>> Ah, here the format makes sense.
>>>
>>>> +  .v4l2 = V4L2_PIX_FMT_XBGR2101010,
>>>
>>> But this is horrible :-( Could we use the same names as DRM for new
>>> formats, when there is no conflict with existing V4L2 formats ?
>>>
>>> Sakari, Hans, what do you think ? Please see patch 1/7 in the series for
>>> the format definitions.
>>
>> V4L2 describes pixel formats based on how they appear in memory from the
>> lowest to highest memory address.
>>
>> If I am not mistaken, DRM uses the CPU order. So that explains the difference
>> in naming. I don't think we should hide that difference. And V4L2 has been
>> quite consistent in following memory ordering in the naming (except possibly
>> for some of the really old pixelformats).
> 
> We depart from that rule with at least the following RGB formats:
> 
> V4L2_PIX_FMT_XBGR32
> V4L2_PIX_FMT_BGRX32
> V4L2_PIX_FMT_ABGR32
> V4L2_PIX_FMT_BGRA32
> 
> While the following formats follow the rule:
> 
> V4L2_PIX_FMT_RGB24
> V4L2_PIX_FMT_BGR24
> V4L2_PIX_FMT_XRGB32
> V4L2_PIX_FMT_RGBX32
> V4L2_PIX_FMT_RGBA32
> V4L2_PIX_FMT_ARGB32
> 
> For 16-bit RGB formats, we name them based on the order in a 16-bit word
> which is then stored in memory in little endian (except for the formats
> explicitly defined as big-endian):
> 
> #define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R', '4', '4', '4') /* 16   
>  */
> #define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_RGBA444 v4l2_fourcc('R', 'A', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_RGBX444 v4l2_fourcc('R', 'X', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_ABGR444 v4l2_fourcc('A', 'B', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_XBGR444 v4l2_fourcc('X', 'B', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_BGRA444 v4l2_fourcc('G', 'A', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_BGRX444 v4l2_fourcc('B', 'X', '1', '2') /* 16   
>  */
> #define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R', 'G', 'B', 'O') /* 16  RGB-5-5-5 
> */
> #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') /* 16  
> ARGB-1-5-5-5  */
> #define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5') /* 16  
> XRGB-1-5-5-5  */
> #define V4L2_PIX_FMT_RGBA555 v4l2_fourcc('R', 'A', '1', '5') /* 16  
> RGBA-5-5-5-1  */
> #define V4L2_PIX_FMT_RGBX555 v4l2_fourcc('R', 'X', '1', '5') /* 16  
> RGBX-5-5-5-1  */
> #define V4L2_PIX_FMT_ABGR555 v4l2_fourcc('A', 'B', '1', '5&

Re: [PATCH v2 7/7] drm: rcar-du: Add new formats (2-10-10-10 ARGB, Y210)

2022-12-20 Thread Hans Verkuil
On 20/12/2022 10:09, Geert Uytterhoeven wrote:
> Hi Hans,
> 
> On Tue, Dec 20, 2022 at 10:01 AM Hans Verkuil  
> wrote:
>> On 19/12/2022 22:47, Laurent Pinchart wrote:
>>> (CC'ing Sakari and Hans)
>>>
>>> Thank you for the patch.
>>>
>>> On Mon, Dec 19, 2022 at 04:01:39PM +0200, Tomi Valkeinen wrote:
>>>> Add new pixel formats: RGBX1010102, RGBA1010102, ARGB2101010 and Y210.
>>>>
>>>> Signed-off-by: Tomi Valkeinen 
>>>> ---
>>>>  drivers/gpu/drm/rcar-du/rcar_du_kms.c | 24 +
>>>>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 49 +--
>>>>  2 files changed, 71 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
>>>> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>>>> index 8c2719efda2a..8ccabf5a30c4 100644
>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>>>> @@ -259,6 +259,24 @@ static const struct rcar_du_format_info 
>>>> rcar_du_format_infos[] = {
>>>>  .bpp = 32,
>>>>  .planes = 1,
>>>>  .hsub = 1,
>>>> +}, {
>>>> +.fourcc = DRM_FORMAT_RGBX1010102,
>>>
>>> Ah, here the format makes sense.
>>>
>>>> +.v4l2 = V4L2_PIX_FMT_XBGR2101010,
>>>
>>> But this is horrible :-( Could we use the same names as DRM for new
>>> formats, when there is no conflict with existing V4L2 formats ?
>>>
>>> Sakari, Hans, what do you think ? Please see patch 1/7 in the series for
>>> the format definitions.
>>
>> V4L2 describes pixel formats based on how they appear in memory from the
>> lowest to highest memory address.
> 
> So that means big endian?

Yes.

> 
>> If I am not mistaken, DRM uses the CPU order. So that explains the difference
>> in naming. I don't think we should hide that difference. And V4L2 has been
>> quite consistent in following memory ordering in the naming (except possibly
>> for some of the really old pixelformats).
> 
> DRM uses little endian.

So not CPU order, but always little endian order? I.e., on a big endian system
a given DRM_FORMAT_ would have the same memory layout as on a little endian
system?

Regards,

Hans

> 
>> Departing from that would be more of a hindrance than a help, IMHO.
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- 
> ge...@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like 
> that.
> -- Linus Torvalds



Re: [PATCH v2 7/7] drm: rcar-du: Add new formats (2-10-10-10 ARGB, Y210)

2022-12-20 Thread Hans Verkuil
On 19/12/2022 22:47, Laurent Pinchart wrote:
> Hi Tomi,
> 
> (CC'ing Sakari and Hans)
> 
> Thank you for the patch.
> 
> On Mon, Dec 19, 2022 at 04:01:39PM +0200, Tomi Valkeinen wrote:
>> Add new pixel formats: RGBX1010102, RGBA1010102, ARGB2101010 and Y210.
>>
>> Signed-off-by: Tomi Valkeinen 
>> ---
>>  drivers/gpu/drm/rcar-du/rcar_du_kms.c | 24 +
>>  drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 49 +--
>>  2 files changed, 71 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
>> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>> index 8c2719efda2a..8ccabf5a30c4 100644
>> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
>> @@ -259,6 +259,24 @@ static const struct rcar_du_format_info 
>> rcar_du_format_infos[] = {
>>  .bpp = 32,
>>  .planes = 1,
>>  .hsub = 1,
>> +}, {
>> +.fourcc = DRM_FORMAT_RGBX1010102,
> 
> Ah, here the format makes sense.
> 
>> +.v4l2 = V4L2_PIX_FMT_XBGR2101010,
> 
> But this is horrible :-( Could we use the same names as DRM for new
> formats, when there is no conflict with existing V4L2 formats ?
> 
> Sakari, Hans, what do you think ? Please see patch 1/7 in the series for
> the format definitions.

V4L2 describes pixel formats based on how they appear in memory from the
lowest to highest memory address.

If I am not mistaken, DRM uses the CPU order. So that explains the difference
in naming. I don't think we should hide that difference. And V4L2 has been
quite consistent in following memory ordering in the naming (except possibly
for some of the really old pixelformats).

Departing from that would be more of a hindrance than a help, IMHO.

Regards,

Hans

> 
>> +.bpp = 32,
>> +.planes = 1,
>> +.hsub = 1,
>> +}, {
>> +.fourcc = DRM_FORMAT_RGBA1010102,
>> +.v4l2 = V4L2_PIX_FMT_ABGR2101010,
>> +.bpp = 32,
>> +.planes = 1,
>> +.hsub = 1,
>> +}, {
>> +.fourcc = DRM_FORMAT_ARGB2101010,
>> +.v4l2 = V4L2_PIX_FMT_BGRA1010102,
>> +.bpp = 32,
>> +.planes = 1,
>> +.hsub = 1,
>>  }, {
>>  .fourcc = DRM_FORMAT_YVYU,
>>  .v4l2 = V4L2_PIX_FMT_YVYU,
>> @@ -307,6 +325,12 @@ static const struct rcar_du_format_info 
>> rcar_du_format_infos[] = {
>>  .bpp = 24,
>>  .planes = 3,
>>  .hsub = 1,
>> +}, {
>> +.fourcc = DRM_FORMAT_Y210,
>> +.v4l2 = V4L2_PIX_FMT_Y210,
>> +.bpp = 32,
>> +.planes = 1,
>> +.hsub = 2,
>>  },
> 
> Any reason why you'd not adding Y212 support already ?
> 
>>  };
>>  
>> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c 
>> b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>> index e465aef41585..6f3e109a4f80 100644
>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>> @@ -139,6 +139,42 @@ static const u32 rcar_du_vsp_formats[] = {
>>  DRM_FORMAT_YVU444,
>>  };
>>  
>> +/*
>> + * Gen4 supports the same formats as above, and additionally 2-10-10-10 RGB
>> + * formats and Y210 format.
>> + */
>> +static const u32 rcar_du_vsp_formats_gen4[] = {
>> +DRM_FORMAT_RGB332,
>> +DRM_FORMAT_ARGB,
>> +DRM_FORMAT_XRGB,
>> +DRM_FORMAT_ARGB1555,
>> +DRM_FORMAT_XRGB1555,
>> +DRM_FORMAT_RGB565,
>> +DRM_FORMAT_BGR888,
>> +DRM_FORMAT_RGB888,
>> +DRM_FORMAT_BGRA,
>> +DRM_FORMAT_BGRX,
>> +DRM_FORMAT_ARGB,
>> +DRM_FORMAT_XRGB,
>> +DRM_FORMAT_RGBX1010102,
>> +DRM_FORMAT_RGBA1010102,
>> +DRM_FORMAT_ARGB2101010,
>> +DRM_FORMAT_UYVY,
>> +DRM_FORMAT_YUYV,
>> +DRM_FORMAT_YVYU,
>> +DRM_FORMAT_NV12,
>> +DRM_FORMAT_NV21,
>> +DRM_FORMAT_NV16,
>> +DRM_FORMAT_NV61,
>> +DRM_FORMAT_YUV420,
>> +DRM_FORMAT_YVU420,
>> +DRM_FORMAT_YUV422,
>> +DRM_FORMAT_YVU422,
>> +DRM_FORMAT_YUV444,
>> +DRM_FORMAT_YVU444,
>> +DRM_FORMAT_Y210,
>> +};
>> +
>>  static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
>>  {
>>  struct rcar_du_vsp_plane_state *state =
>> @@ -436,14 +472,23 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct 
>> device_node *np,
>>   ? DRM_PLANE_TYPE_PRIMARY
>>   : DRM_PLANE_TYPE_OVERLAY;
>>  struct rcar_du_vsp_plane *plane = &vsp->planes[i];
>> +unsigned int num_formats;
>> +const u32 *formats;
>> +
>> +if (rcdu->info->gen < 4) {
>> +num_formats = ARRAY_SIZE(rcar_du_vsp_formats);
>> +formats = rcar_du_vsp_formats;
>> +} else {
>> +num_formats = ARRAY_SIZE(rcar_du_vsp_formats_gen4);
>> +formats = rcar_du_vsp_formats_gen4;
>> +}
>>  
>> 

Re: [PATCH mm-unstable v1 16/20] mm/frame-vector: remove FOLL_FORCE usage

2022-11-29 Thread Hans Verkuil
On 29/11/2022 09:48, David Hildenbrand wrote:
> On 28.11.22 23:59, Andrew Morton wrote:
>> On Mon, 28 Nov 2022 09:18:47 +0100 David Hildenbrand  
>> wrote:
>>
 Less chances of things going wrong that way.

 Just mention in the v2 cover letter that the first patch was added to
 make it easy to backport that fix without being hampered by merge
 conflicts if it was added after your frame_vector.c patch.
>>>
>>> Yes, that's the way I would naturally do, it, however, Andrew prefers
>>> delta updates for minor changes.
>>>
>>> @Andrew, whatever you prefer!
>>
>> I'm inclined to let things sit as they are.  Cross-tree conflicts
>> happen, and Linus handles them.  I'll flag this (very simple) conflict
>> in the pull request, if MM merges second.  If v4l merges second then
>> hopefully they will do the same.  But this one is so simple that Linus
>> hardly needs our help.

It's not about cross-tree conflicts, it's about the fact that my patch is
a fix that needs to be backported to older kernels. It should apply cleanly
to those older kernels if my patch goes in first, but if it is the other way
around I would have to make a new patch for the stable kernels.

Also, the updated changelog in David's patch that sits on top of mine
makes a lot more sense.

If you really don't want to take my patch as part of this, then let me know
and I'll take it through the media subsystem and hope for the best :-)

Regards,

Hans

>>
>> But Linus won't be editing changelogs so that the changelog makes more
>> sense after both trees are joined.  I'm inclined to let the changelog
>> sit as it is as well.
> 
> Works for me. Thanks Andrew!
> 



Re: [PATCH mm-unstable v1 16/20] mm/frame-vector: remove FOLL_FORCE usage

2022-11-28 Thread Hans Verkuil
On 28/11/2022 09:18, David Hildenbrand wrote:
> On 28.11.22 09:17, Hans Verkuil wrote:
>> Hi David,
>>
>> On 27/11/2022 11:35, David Hildenbrand wrote:
>>> On 16.11.22 11:26, David Hildenbrand wrote:
>>>> FOLL_FORCE is really only for ptrace access. According to commit
>>>> 707947247e95 ("media: videobuf2-vmalloc: get_userptr: buffers are always
>>>> writable"), get_vaddr_frames() currently pins all pages writable as a
>>>> workaround for issues with read-only buffers.
>>>>
>>>> FOLL_FORCE, however, seems to be a legacy leftover as it predates
>>>> commit 707947247e95 ("media: videobuf2-vmalloc: get_userptr: buffers are
>>>> always writable"). Let's just remove it.
>>>>
>>>> Once the read-only buffer issue has been resolved, FOLL_WRITE could
>>>> again be set depending on the DMA direction.
>>>>
>>>> Cc: Hans Verkuil 
>>>> Cc: Marek Szyprowski 
>>>> Cc: Tomasz Figa 
>>>> Cc: Marek Szyprowski 
>>>> Cc: Mauro Carvalho Chehab 
>>>> Signed-off-by: David Hildenbrand 
>>>> ---
>>>>    drivers/media/common/videobuf2/frame_vector.c | 2 +-
>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/media/common/videobuf2/frame_vector.c 
>>>> b/drivers/media/common/videobuf2/frame_vector.c
>>>> index 542dde9d2609..062e98148c53 100644
>>>> --- a/drivers/media/common/videobuf2/frame_vector.c
>>>> +++ b/drivers/media/common/videobuf2/frame_vector.c
>>>> @@ -50,7 +50,7 @@ int get_vaddr_frames(unsigned long start, unsigned int 
>>>> nr_frames,
>>>>    start = untagged_addr(start);
>>>>      ret = pin_user_pages_fast(start, nr_frames,
>>>> -  FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM,
>>>> +  FOLL_WRITE | FOLL_LONGTERM,
>>>>  (struct page **)(vec->ptrs));
>>>>    if (ret > 0) {
>>>>    vec->got_ref = true;
>>>
>>>
>>> Hi Andrew,
>>>
>>> see the discussion at [1] regarding a conflict and how to proceed with
>>> upstreaming. The conflict would be easy to resolve, however, also
>>> the patch description doesn't make sense anymore with [1].
>>
>> Might it be easier and less confusing if you post a v2 of this series
>> with my patch first? That way it is clear that 1) my patch has to come
>> first, and 2) that it is part of a single series and should be merged
>> by the mm subsystem.
>>
>> Less chances of things going wrong that way.
>>
>> Just mention in the v2 cover letter that the first patch was added to
>> make it easy to backport that fix without being hampered by merge
>> conflicts if it was added after your frame_vector.c patch.
> 
> Yes, that's the way I would naturally do, it, however, Andrew prefers delta 
> updates for minor changes.
> 
> @Andrew, whatever you prefer!

Andrew, I've resent my patch, this time with you CCed as well.

Regards,

Hans

> 
> Thanks!
> 



  1   2   3   4   5   6   7   8   9   10   >