mbox series

[v2,0/9] media: ov2740: reset GPIO, clk and 180 MHz link-frequency support

Message ID 20231126141517.7534-1-hdegoede@redhat.com
Headers show
Series media: ov2740: reset GPIO, clk and 180 MHz link-frequency support | expand

Message

Hans de Goede Nov. 26, 2023, 2:15 p.m. UTC
Hi All,

Here is v2 of my ov2740 patch series. The big change in v2 is adding
a bunch of new patches (patch 3 - 9) to add support for 180 MHz
link-frequency.

These new patches allow the mainline ov2740 driver to be used on
various Lenovo ThinkPad models using the IPU6 + ov2740 for their
camera. This series has been tested on a Lenovo ThinkPad X1 yoga gen 8
with both:

1. The out of tree IPU6 driver with Intel's proprietary userspace stack
2. The pending mainline IPU6 CSI2 receiver patches using raw bayer capture
   in combination with the WIP libcamera SoftISP code

Besides the new patches there is a small change in patch 2/9
to stay within the 80 chars limit.

Regards,

Hans


Hans de Goede (9):
  media: ov2740: Add support for reset GPIO
  media: ov2740: Add support for external clock
  media: ov2740: Move fwnode_graph_get_next_endpoint() call up
  media: ov2740: Improve ov2740_check_hwcfg() error reporting
  media: ov2740: Fix hts value
  media: ov2740: Check hwcfg after allocating the ov2740 struct
  media: ov2740: Add support for 180 MHz link frequency
  media: ov2740: Add a sleep after resetting the sensor
  media: ipu-bridge: Change ov2740 link-frequency to 180 MHz

 drivers/media/i2c/ov2740.c           | 375 +++++++++++++++++++++++----
 drivers/media/pci/intel/ipu-bridge.c |   2 +-
 2 files changed, 326 insertions(+), 51 deletions(-)

Comments

Bingbu Cao Nov. 27, 2023, 4:15 a.m. UTC | #1
Hans,

On 11/26/23 10:15 PM, Hans de Goede wrote:
> Split the resetting of the sensor out of the link_freq_config reg_list
> and add a delay after this.
> 
> This hopefully fixes the stream sometimes not starting, this was
> taken from the ov2740 sensor driver in the out of tree IPU6 driver:

Thanks for your patch.

I don't know the details for ov2740 here, we met some similar issues
with another OminiVision camera sensor, it is somehow related to the
OTP read. Unfortunately, we didn't find the root-cause.

Maybe you can remove the OTP read to check, I think the OTP is useless
if I don't forget anything.

Hao, do you have any details for this issue?

> 
> https://github.com/intel/ipu6-drivers/
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/media/i2c/ov2740.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
> index 8f5c33f68d42..a49c065c6cf4 100644
> --- a/drivers/media/i2c/ov2740.c
> +++ b/drivers/media/i2c/ov2740.c
> @@ -128,7 +128,6 @@ struct ov2740_mode {
>  };
>  
>  static const struct ov2740_reg mipi_data_rate_720mbps[] = {
> -	{0x0103, 0x01},
>  	{0x0302, 0x4b},
>  	{0x030d, 0x4b},
>  	{0x030e, 0x02},
> @@ -137,7 +136,6 @@ static const struct ov2740_reg mipi_data_rate_720mbps[] = {
>  };
>  
>  static const struct ov2740_reg mipi_data_rate_360mbps[] = {
> -	{0x0103, 0x01},
>  	{0x0302, 0x4b},
>  	{0x0303, 0x01},
>  	{0x030d, 0x4b},
> @@ -935,6 +933,15 @@ static int ov2740_start_streaming(struct ov2740 *ov2740)
>  	if (ov2740->nvm)
>  		ov2740_load_otp_data(ov2740->nvm);
>  
> +	/* Reset the sensor */
> +	ret = ov2740_write_reg(ov2740, 0x0103, 1, 0x01);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to reset\n");
> +		return ret;
> +	}
> +
> +	usleep_range(10000, 15000);
> +
>  	link_freq_index = ov2740->cur_mode->link_freq_index;
>  	reg_list = &link_freq_configs[link_freq_index].reg_list;
>  	ret = ov2740_write_reg_list(ov2740, reg_list);
>
Hao Yao Nov. 27, 2023, 6:39 a.m. UTC | #2
Hi Bingbu, Hans,

On 2023/11/27 12:15, Bingbu Cao wrote:
> 
> Hans,
> 
> On 11/26/23 10:15 PM, Hans de Goede wrote:
>> Split the resetting of the sensor out of the link_freq_config reg_list
>> and add a delay after this.
>>
>> This hopefully fixes the stream sometimes not starting, this was
>> taken from the ov2740 sensor driver in the out of tree IPU6 driver:
> 
> Thanks for your patch.
> 
> I don't know the details for ov2740 here, we met some similar issues
> with another OminiVision camera sensor, it is somehow related to the
> OTP read. Unfortunately, we didn't find the root-cause.
> 
> Maybe you can remove the OTP read to check, I think the OTP is useless
> if I don't forget anything.
> 
> Hao, do you have any details for this issue?
> 

Are we talking about this Github issue?
https://github.com/intel/ipu6-drivers/issues/187

I remembered that I added sleep after the power on/off. As for software 
resetting, I encountered similar issue when I worked on HM2170 sensor. 
It hangs if we transfer I2C messages immediately after software reset. 
Even OV2740 document didn't say anything about delay after software 
reset, I think it's worth a try.

I didn't use the OTP feature so I didn't look into it on OV2740.


Best Regards,
Hao Yao

>>
>> https://github.com/intel/ipu6-drivers/
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>   drivers/media/i2c/ov2740.c | 11 +++++++++--
>>   1 file changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
>> index 8f5c33f68d42..a49c065c6cf4 100644
>> --- a/drivers/media/i2c/ov2740.c
>> +++ b/drivers/media/i2c/ov2740.c
>> @@ -128,7 +128,6 @@ struct ov2740_mode {
>>   };
>>   
>>   static const struct ov2740_reg mipi_data_rate_720mbps[] = {
>> -	{0x0103, 0x01},
>>   	{0x0302, 0x4b},
>>   	{0x030d, 0x4b},
>>   	{0x030e, 0x02},
>> @@ -137,7 +136,6 @@ static const struct ov2740_reg mipi_data_rate_720mbps[] = {
>>   };
>>   
>>   static const struct ov2740_reg mipi_data_rate_360mbps[] = {
>> -	{0x0103, 0x01},
>>   	{0x0302, 0x4b},
>>   	{0x0303, 0x01},
>>   	{0x030d, 0x4b},
>> @@ -935,6 +933,15 @@ static int ov2740_start_streaming(struct ov2740 *ov2740)
>>   	if (ov2740->nvm)
>>   		ov2740_load_otp_data(ov2740->nvm);
>>   
>> +	/* Reset the sensor */
>> +	ret = ov2740_write_reg(ov2740, 0x0103, 1, 0x01);
>> +	if (ret) {
>> +		dev_err(&client->dev, "failed to reset\n");
>> +		return ret;
>> +	}
>> +
>> +	usleep_range(10000, 15000);
>> +
>>   	link_freq_index = ov2740->cur_mode->link_freq_index;
>>   	reg_list = &link_freq_configs[link_freq_index].reg_list;
>>   	ret = ov2740_write_reg_list(ov2740, reg_list);
>>
>
Sakari Ailus Nov. 27, 2023, 11:55 a.m. UTC | #3
Hi Hans,

On Sun, Nov 26, 2023 at 03:15:11PM +0100, Hans de Goede wrote:
> If the bridge has not yet setup the fwnode-graph then
> the fwnode_property_read_u32("clock-frequency") call will fail.
> 
> Move the fwnode_graph_get_next_endpoint() call to above reading
> the clock-frequency.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/media/i2c/ov2740.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
> index 0396e40419ca..832f24721dca 100644
> --- a/drivers/media/i2c/ov2740.c
> +++ b/drivers/media/i2c/ov2740.c
> @@ -926,6 +926,14 @@ static int ov2740_check_hwcfg(struct device *dev)
>  	int ret;
>  	unsigned int i, j;
>  
> +	/*
> +	 * Sometimes the fwnode graph is initialized by the bridge driver,
> +	 * wait for this.
> +	 */
> +	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> +	if (!ep)
> +		return -EPROBE_DEFER;
> +

You'll need

	fwnode_handle_put(ep);

in error cases below, too.

>  	ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
>  	if (ret)
>  		return ret;
> @@ -935,10 +943,6 @@ static int ov2740_check_hwcfg(struct device *dev)
>  				     "external clock %d is not supported\n",
>  				     mclk);
>  
> -	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
> -	if (!ep)
> -		return -EPROBE_DEFER;
> -
>  	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
>  	fwnode_handle_put(ep);
>  	if (ret)