diff mbox series

[RFC,v3,16/18] gpu: host1x: mipi: Split tegra_mipi_calibrate and tegra_mipi_wait

Message ID 1594786855-26506-17-git-send-email-skomatineni@nvidia.com (mailing list archive)
State New, archived
Headers show
Series Support for Tegra video capture from external sensor | expand

Commit Message

Sowjanya Komatineni July 15, 2020, 4:20 a.m. UTC
SW can trigger MIPI pads calibration any time after power on
but calibration results will be latched and applied to the pads
by MIPI CAL unit only when the link is in LP-11 state and then
status register will be updated.

For CSI, trigger of pads calibration happen during CSI stream
enable where CSI receiver is kept ready prior to sensor or CSI
transmitter stream start.

So, pads may not be in LP-11 at this time and waiting for the
calibration to be done immediate after calibration start will
result in timeout.

This patch splits tegra_mipi_calibrate() and tegra_mipi_wait()
so triggering for calibration and waiting for it to complete can
happen at different stages.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/gpu/drm/tegra/dsi.c |  7 ++++++-
 drivers/gpu/host1x/mipi.c   | 17 +++++++++++++----
 include/linux/host1x.h      |  1 +
 3 files changed, 20 insertions(+), 5 deletions(-)

Comments

Dmitry Osipenko July 16, 2020, 8:38 p.m. UTC | #1
15.07.2020 07:20, Sowjanya Komatineni пишет:
> SW can trigger MIPI pads calibration any time after power on
> but calibration results will be latched and applied to the pads
> by MIPI CAL unit only when the link is in LP-11 state and then
> status register will be updated.
> 
> For CSI, trigger of pads calibration happen during CSI stream
> enable where CSI receiver is kept ready prior to sensor or CSI
> transmitter stream start.
> 
> So, pads may not be in LP-11 at this time and waiting for the
> calibration to be done immediate after calibration start will
> result in timeout.
> 
> This patch splits tegra_mipi_calibrate() and tegra_mipi_wait()
> so triggering for calibration and waiting for it to complete can
> happen at different stages.
> 
> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
> ---
...
>  int tegra_mipi_calibrate(struct tegra_mipi_device *device)
>  {
> @@ -370,12 +381,10 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device)
>  	value |= MIPI_CAL_CTRL_START;
>  	tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
>  
> -	err = tegra_mipi_wait(device->mipi);

Doesn't MIPI clock need to be enabled during of the calibration process?

>  	mutex_unlock(&device->mipi->lock);
>  	clk_disable(device->mipi->clk);
>  
> -	return err;
> +	return 0;
>  }
>  EXPORT_SYMBOL(tegra_mipi_calibrate);
Sowjanya Komatineni July 16, 2020, 9:09 p.m. UTC | #2
On 7/16/20 1:38 PM, Dmitry Osipenko wrote:
> 15.07.2020 07:20, Sowjanya Komatineni пишет:
>> SW can trigger MIPI pads calibration any time after power on
>> but calibration results will be latched and applied to the pads
>> by MIPI CAL unit only when the link is in LP-11 state and then
>> status register will be updated.
>>
>> For CSI, trigger of pads calibration happen during CSI stream
>> enable where CSI receiver is kept ready prior to sensor or CSI
>> transmitter stream start.
>>
>> So, pads may not be in LP-11 at this time and waiting for the
>> calibration to be done immediate after calibration start will
>> result in timeout.
>>
>> This patch splits tegra_mipi_calibrate() and tegra_mipi_wait()
>> so triggering for calibration and waiting for it to complete can
>> happen at different stages.
>>
>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>> ---
> ...
>>   int tegra_mipi_calibrate(struct tegra_mipi_device *device)
>>   {
>> @@ -370,12 +381,10 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device)
>>   	value |= MIPI_CAL_CTRL_START;
>>   	tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
>>   
>> -	err = tegra_mipi_wait(device->mipi);
> Doesn't MIPI clock need to be enabled during of the calibration process?
MIPI clock is already enabled in tegra_mipi_calibrate
>
>>   	mutex_unlock(&device->mipi->lock);
>>   	clk_disable(device->mipi->clk);
>>   
>> -	return err;
>> +	return 0;
>>   }
>>   EXPORT_SYMBOL(tegra_mipi_calibrate);
Dmitry Osipenko July 16, 2020, 9:18 p.m. UTC | #3
17.07.2020 00:09, Sowjanya Komatineni пишет:
> 
> On 7/16/20 1:38 PM, Dmitry Osipenko wrote:
>> 15.07.2020 07:20, Sowjanya Komatineni пишет:
>>> SW can trigger MIPI pads calibration any time after power on
>>> but calibration results will be latched and applied to the pads
>>> by MIPI CAL unit only when the link is in LP-11 state and then
>>> status register will be updated.
>>>
>>> For CSI, trigger of pads calibration happen during CSI stream
>>> enable where CSI receiver is kept ready prior to sensor or CSI
>>> transmitter stream start.
>>>
>>> So, pads may not be in LP-11 at this time and waiting for the
>>> calibration to be done immediate after calibration start will
>>> result in timeout.
>>>
>>> This patch splits tegra_mipi_calibrate() and tegra_mipi_wait()
>>> so triggering for calibration and waiting for it to complete can
>>> happen at different stages.
>>>
>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>> ---
>> ...
>>>   int tegra_mipi_calibrate(struct tegra_mipi_device *device)
>>>   {
>>> @@ -370,12 +381,10 @@ int tegra_mipi_calibrate(struct
>>> tegra_mipi_device *device)
>>>       value |= MIPI_CAL_CTRL_START;
>>>       tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
>>>   -    err = tegra_mipi_wait(device->mipi);
>> Doesn't MIPI clock need to be enabled during of the calibration process?
> MIPI clock is already enabled in tegra_mipi_calibrate
>>
>>>       mutex_unlock(&device->mipi->lock);
>>>       clk_disable(device->mipi->clk);

What keeps MIPI clock enabled after completion of the
tegra_mipi_calibrate() invocation?

>>>   -    return err;
>>> +    return 0;
>>>   }
>>>   EXPORT_SYMBOL(tegra_mipi_calibrate);
Sowjanya Komatineni July 16, 2020, 10:49 p.m. UTC | #4
On 7/16/20 2:18 PM, Dmitry Osipenko wrote:
> 17.07.2020 00:09, Sowjanya Komatineni пишет:
>> On 7/16/20 1:38 PM, Dmitry Osipenko wrote:
>>> 15.07.2020 07:20, Sowjanya Komatineni пишет:
>>>> SW can trigger MIPI pads calibration any time after power on
>>>> but calibration results will be latched and applied to the pads
>>>> by MIPI CAL unit only when the link is in LP-11 state and then
>>>> status register will be updated.
>>>>
>>>> For CSI, trigger of pads calibration happen during CSI stream
>>>> enable where CSI receiver is kept ready prior to sensor or CSI
>>>> transmitter stream start.
>>>>
>>>> So, pads may not be in LP-11 at this time and waiting for the
>>>> calibration to be done immediate after calibration start will
>>>> result in timeout.
>>>>
>>>> This patch splits tegra_mipi_calibrate() and tegra_mipi_wait()
>>>> so triggering for calibration and waiting for it to complete can
>>>> happen at different stages.
>>>>
>>>> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
>>>> ---
>>> ...
>>>>    int tegra_mipi_calibrate(struct tegra_mipi_device *device)
>>>>    {
>>>> @@ -370,12 +381,10 @@ int tegra_mipi_calibrate(struct
>>>> tegra_mipi_device *device)
>>>>        value |= MIPI_CAL_CTRL_START;
>>>>        tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
>>>>    -    err = tegra_mipi_wait(device->mipi);
>>> Doesn't MIPI clock need to be enabled during of the calibration process?
>> MIPI clock is already enabled in tegra_mipi_calibrate
>>>>        mutex_unlock(&device->mipi->lock);
>>>>        clk_disable(device->mipi->clk);
> What keeps MIPI clock enabled after completion of the
> tegra_mipi_calibrate() invocation?

MIPI clock is disabled at end of tegra_mipi_calibrate and is re-enabled 
during tegra_mipi_wait.

I think I should fix this to keep the clock enabled till calibration 
results are latched.

All consumers of tegra_mipi_calibrate() will call tegra_mipi_wait().

So will remove clk_disable mipi clk at end of tegra_mipi_calibrate() and 
clk_enable mipi_clk at beginning of tegra_mipi_wait()

>
>>>>    -    return err;
>>>> +    return 0;
>>>>    }
>>>>    EXPORT_SYMBOL(tegra_mipi_calibrate);
Dmitry Osipenko July 16, 2020, 11:01 p.m. UTC | #5
17.07.2020 01:49, Sowjanya Komatineni пишет:
>> What keeps MIPI clock enabled after completion of the
>> tegra_mipi_calibrate() invocation?
> 
> MIPI clock is disabled at end of tegra_mipi_calibrate and is re-enabled
> during tegra_mipi_wait.
> 
> I think I should fix this to keep the clock enabled till calibration
> results are latched.
> 
> All consumers of tegra_mipi_calibrate() will call tegra_mipi_wait().
> 
> So will remove clk_disable mipi clk at end of tegra_mipi_calibrate() and
> clk_enable mipi_clk at beginning of tegra_mipi_wait()

Isn't it possible to perform the calibration after enabling CSI and
before of starting the sensor streaming?
Sowjanya Komatineni July 16, 2020, 11:06 p.m. UTC | #6
On 7/16/20 4:01 PM, Dmitry Osipenko wrote:
> 17.07.2020 01:49, Sowjanya Komatineni пишет:
>>> What keeps MIPI clock enabled after completion of the
>>> tegra_mipi_calibrate() invocation?
>> MIPI clock is disabled at end of tegra_mipi_calibrate and is re-enabled
>> during tegra_mipi_wait.
>>
>> I think I should fix this to keep the clock enabled till calibration
>> results are latched.
>>
>> All consumers of tegra_mipi_calibrate() will call tegra_mipi_wait().
>>
>> So will remove clk_disable mipi clk at end of tegra_mipi_calibrate() and
>> clk_enable mipi_clk at beginning of tegra_mipi_wait()
> Isn't it possible to perform the calibration after enabling CSI and
> before of starting the sensor streaming?
Currently this is what I am doing. Triggering calibration start during 
CSI receiver being ready and then sensor streaming will happen where 
internal MIPI CAL detects for LP -> HS transition and applies results to 
pads. So checking for calibration results after sensor stream is enabled
Sowjanya Komatineni July 16, 2020, 11:09 p.m. UTC | #7
On 7/16/20 4:06 PM, Sowjanya Komatineni wrote:
>
> On 7/16/20 4:01 PM, Dmitry Osipenko wrote:
>> 17.07.2020 01:49, Sowjanya Komatineni пишет:
>>>> What keeps MIPI clock enabled after completion of the
>>>> tegra_mipi_calibrate() invocation?
>>> MIPI clock is disabled at end of tegra_mipi_calibrate and is re-enabled
>>> during tegra_mipi_wait.
>>>
>>> I think I should fix this to keep the clock enabled till calibration
>>> results are latched.
>>>
>>> All consumers of tegra_mipi_calibrate() will call tegra_mipi_wait().
>>>
>>> So will remove clk_disable mipi clk at end of tegra_mipi_calibrate() 
>>> and
>>> clk_enable mipi_clk at beginning of tegra_mipi_wait()
>> Isn't it possible to perform the calibration after enabling CSI and
>> before of starting the sensor streaming?
> Currently this is what I am doing. Triggering calibration start during 
> CSI receiver being ready and then sensor streaming will happen where 
> internal MIPI CAL detects for LP -> HS transition and applies results 
> to pads. So checking for calibration results after sensor stream is 
> enabled

1. Calling tegra_mipi_calibrate() during CSI streaming where CSI pads 
are enabled and receiver is kept ready

2. Start Sensor stream

3. Calling tegra_mipi_wait() to check for MIPI Cal status.

So as mipi cal clk need to be kept enabled till 3rd step, we can enable 
clock during tegra_mipi_calibrate() and leave it enabled and disable it 
in tegra_mipi_wait after status check.
Dmitry Osipenko July 16, 2020, 11:47 p.m. UTC | #8
17.07.2020 02:09, Sowjanya Komatineni пишет:
> 
> On 7/16/20 4:06 PM, Sowjanya Komatineni wrote:
>>
>> On 7/16/20 4:01 PM, Dmitry Osipenko wrote:
>>> 17.07.2020 01:49, Sowjanya Komatineni пишет:
>>>>> What keeps MIPI clock enabled after completion of the
>>>>> tegra_mipi_calibrate() invocation?
>>>> MIPI clock is disabled at end of tegra_mipi_calibrate and is re-enabled
>>>> during tegra_mipi_wait.
>>>>
>>>> I think I should fix this to keep the clock enabled till calibration
>>>> results are latched.
>>>>
>>>> All consumers of tegra_mipi_calibrate() will call tegra_mipi_wait().
>>>>
>>>> So will remove clk_disable mipi clk at end of tegra_mipi_calibrate()
>>>> and
>>>> clk_enable mipi_clk at beginning of tegra_mipi_wait()
>>> Isn't it possible to perform the calibration after enabling CSI and
>>> before of starting the sensor streaming?
>> Currently this is what I am doing. Triggering calibration start during
>> CSI receiver being ready and then sensor streaming will happen where
>> internal MIPI CAL detects for LP -> HS transition and applies results
>> to pads. So checking for calibration results after sensor stream is
>> enabled
> 
> 1. Calling tegra_mipi_calibrate() during CSI streaming where CSI pads
> are enabled and receiver is kept ready
> 
> 2. Start Sensor stream
> 
> 3. Calling tegra_mipi_wait() to check for MIPI Cal status.
> 
> So as mipi cal clk need to be kept enabled till 3rd step, we can enable
> clock during tegra_mipi_calibrate() and leave it enabled and disable it
> in tegra_mipi_wait after status check.

From TRM:

The following sequence is recommended for capturing a single frame:

1. Set up CSI registers for use case such as number of lanes, virtual
channel, etc.
2. Initialize and power up CSI interface
3. Wait for initialization time or done signal from calibration logic
4. Power up camera through the I2C interface
5. All CSI data and clock lanes are in stop state, LP11
6. Initiate frame capture through the I2C
7. Frame done, CSI goes back to stop state, LP11

Hence, is it really necessary to perform the manual calibration?
Sowjanya Komatineni July 17, 2020, 12:16 a.m. UTC | #9
On 7/16/20 4:47 PM, Dmitry Osipenko wrote:
> 17.07.2020 02:09, Sowjanya Komatineni пишет:
>> On 7/16/20 4:06 PM, Sowjanya Komatineni wrote:
>>> On 7/16/20 4:01 PM, Dmitry Osipenko wrote:
>>>> 17.07.2020 01:49, Sowjanya Komatineni пишет:
>>>>>> What keeps MIPI clock enabled after completion of the
>>>>>> tegra_mipi_calibrate() invocation?
>>>>> MIPI clock is disabled at end of tegra_mipi_calibrate and is re-enabled
>>>>> during tegra_mipi_wait.
>>>>>
>>>>> I think I should fix this to keep the clock enabled till calibration
>>>>> results are latched.
>>>>>
>>>>> All consumers of tegra_mipi_calibrate() will call tegra_mipi_wait().
>>>>>
>>>>> So will remove clk_disable mipi clk at end of tegra_mipi_calibrate()
>>>>> and
>>>>> clk_enable mipi_clk at beginning of tegra_mipi_wait()
>>>> Isn't it possible to perform the calibration after enabling CSI and
>>>> before of starting the sensor streaming?
>>> Currently this is what I am doing. Triggering calibration start during
>>> CSI receiver being ready and then sensor streaming will happen where
>>> internal MIPI CAL detects for LP -> HS transition and applies results
>>> to pads. So checking for calibration results after sensor stream is
>>> enabled
>> 1. Calling tegra_mipi_calibrate() during CSI streaming where CSI pads
>> are enabled and receiver is kept ready
>>
>> 2. Start Sensor stream
>>
>> 3. Calling tegra_mipi_wait() to check for MIPI Cal status.
>>
>> So as mipi cal clk need to be kept enabled till 3rd step, we can enable
>> clock during tegra_mipi_calibrate() and leave it enabled and disable it
>> in tegra_mipi_wait after status check.
>  From TRM:
>
> The following sequence is recommended for capturing a single frame:
>
> 1. Set up CSI registers for use case such as number of lanes, virtual
> channel, etc.
> 2. Initialize and power up CSI interface
> 3. Wait for initialization time or done signal from calibration logic
> 4. Power up camera through the I2C interface
> 5. All CSI data and clock lanes are in stop state, LP11
> 6. Initiate frame capture through the I2C
> 7. Frame done, CSI goes back to stop state, LP11
>
> Hence, is it really necessary to perform the manual calibration?

done signal from calibration logic will happen only when it sees LP to 
HS transition as thats when calibration results are applied to pads and 
then done signal is set.

Also MIPI Pads calibration need to be done on every power off/on. So 
need to do calibration and trigger it along with CSI receiver 
programming to keep it ready and then need to check/wait for status only 
after sensor stream happens as thats where LP->HS transition happen.
Sowjanya Komatineni July 17, 2020, 4:46 a.m. UTC | #10
On 7/16/20 5:16 PM, Sowjanya Komatineni wrote:
>
> On 7/16/20 4:47 PM, Dmitry Osipenko wrote:
>> 17.07.2020 02:09, Sowjanya Komatineni пишет:
>>> On 7/16/20 4:06 PM, Sowjanya Komatineni wrote:
>>>> On 7/16/20 4:01 PM, Dmitry Osipenko wrote:
>>>>> 17.07.2020 01:49, Sowjanya Komatineni пишет:
>>>>>>> What keeps MIPI clock enabled after completion of the
>>>>>>> tegra_mipi_calibrate() invocation?
>>>>>> MIPI clock is disabled at end of tegra_mipi_calibrate and is 
>>>>>> re-enabled
>>>>>> during tegra_mipi_wait.
>>>>>>
>>>>>> I think I should fix this to keep the clock enabled till calibration
>>>>>> results are latched.
>>>>>>
>>>>>> All consumers of tegra_mipi_calibrate() will call tegra_mipi_wait().
>>>>>>
>>>>>> So will remove clk_disable mipi clk at end of tegra_mipi_calibrate()
>>>>>> and
>>>>>> clk_enable mipi_clk at beginning of tegra_mipi_wait()
>>>>> Isn't it possible to perform the calibration after enabling CSI and
>>>>> before of starting the sensor streaming?
>>>> Currently this is what I am doing. Triggering calibration start during
>>>> CSI receiver being ready and then sensor streaming will happen where
>>>> internal MIPI CAL detects for LP -> HS transition and applies results
>>>> to pads. So checking for calibration results after sensor stream is
>>>> enabled
>>> 1. Calling tegra_mipi_calibrate() during CSI streaming where CSI pads
>>> are enabled and receiver is kept ready
>>>
>>> 2. Start Sensor stream
>>>
>>> 3. Calling tegra_mipi_wait() to check for MIPI Cal status.
>>>
>>> So as mipi cal clk need to be kept enabled till 3rd step, we can enable
>>> clock during tegra_mipi_calibrate() and leave it enabled and disable it
>>> in tegra_mipi_wait after status check.
>>  From TRM:
>>
>> The following sequence is recommended for capturing a single frame:
>>
>> 1. Set up CSI registers for use case such as number of lanes, virtual
>> channel, etc.
>> 2. Initialize and power up CSI interface
>> 3. Wait for initialization time or done signal from calibration logic
>> 4. Power up camera through the I2C interface
>> 5. All CSI data and clock lanes are in stop state, LP11
>> 6. Initiate frame capture through the I2C
>> 7. Frame done, CSI goes back to stop state, LP11
>>
>> Hence, is it really necessary to perform the manual calibration?
>
> done signal from calibration logic will happen only when it sees LP to 
> HS transition as thats when calibration results are applied to pads 
> and then done signal is set.
>
> Also MIPI Pads calibration need to be done on every power off/on. So 
> need to do calibration and trigger it along with CSI receiver 
> programming to keep it ready and then need to check/wait for status 
> only after sensor stream happens as thats where LP->HS transition happen.
>
Looks like sequence posted in TRM need to be updated clearly for proper 
MIPI CAL start and wait.

Correct steps should be like below

1. Set up CSI registers for use case such as number of lanes, virtual  
channel, etc.
2. Initialize and power up CSI CIL interface
3. Program MIPI CAL bias pads, cal configs, cal control registers and 
enable calibration start
4. Power up camera through the I2C interface and start sensor streaming 
through the I2C

Note: All sensors might not leave pads in LP-11 state as sensor may be 
power down when not in use.

So start streaming prior to checking for calibration done status as 
LP-11 -> HS transition happens during sensor stream and calibration 
logic can apply results to pads and update done status,

5. Wait for done signal from calibration logic

6. perform frame capture thru VI
7. Frame done, CSI goes back to stop state, LP11

Will work internally to correct sequence in TRM ...


In mipi driver will update as below to have mipi clk enabled till 
calibration status check is done.

Always tegra_mipi_wait() followes tegra_mipi_calibrate() in both DSI and 
CSI. So below sequence should work good.

tegra_mipi_calibrate()

- clk_enable mipi cal
- program mipi cal registers (bias pads cfgs, mipi cal ctrl and trigger 
calibration start)

tegra_mipi_wait()
- read mipi cal status and wait for active and done bits
- clk_disable mipi cal

Thanks

Sowjanya
Dmitry Osipenko July 17, 2020, 3:01 p.m. UTC | #11
17.07.2020 07:46, Sowjanya Komatineni пишет:
...
> Looks like sequence posted in TRM need to be updated clearly for proper
> MIPI CAL start and wait.
> 
> Correct steps should be like below
> 
> 1. Set up CSI registers for use case such as number of lanes, virtual 
> channel, etc.
> 2. Initialize and power up CSI CIL interface
> 3. Program MIPI CAL bias pads, cal configs, cal control registers and
> enable calibration start
> 4. Power up camera through the I2C interface and start sensor streaming
> through the I2C
> 
> Note: All sensors might not leave pads in LP-11 state as sensor may be
> power down when not in use.
> 
> So start streaming prior to checking for calibration done status as
> LP-11 -> HS transition happens during sensor stream and calibration
> logic can apply results to pads and update done status,
> 
> 5. Wait for done signal from calibration logic
> 
> 6. perform frame capture thru VI
> 7. Frame done, CSI goes back to stop state, LP11
> 
> Will work internally to correct sequence in TRM ...

Will be nice to have an updated TRM, thank you!

Also, what about the auto-calibration? Isn't it needed to be enabled for
CSI?

> In mipi driver will update as below to have mipi clk enabled till
> calibration status check is done.
> 
> Always tegra_mipi_wait() followes tegra_mipi_calibrate() in both DSI and
> CSI. So below sequence should work good.
> 
> tegra_mipi_calibrate()
> 
> - clk_enable mipi cal
> - program mipi cal registers (bias pads cfgs, mipi cal ctrl and trigger
> calibration start)
> 
> tegra_mipi_wait()
> - read mipi cal status and wait for active and done bits
> - clk_disable mipi cal


Maybe then it should be better to rename the functions like this:

tegra_mipi_calibrate() -> tegra_mipi_start_calibration()
tegra_mipi_wait()      -> tegra_mipi_finish_calibration().

and there also should be tegra_mipi_cancel_calibration().


Example:

	tegra_mipi_start_calibration();

	ret = v4l2_subdev_call(subdev, video, s_stream, on);
	if (ret < 0) {
		tegra_mipi_cancel_calibration();
		goto err;
	}

	tegra_mipi_finish_calibration();
Sowjanya Komatineni July 17, 2020, 3:41 p.m. UTC | #12
On 7/17/20 8:01 AM, Dmitry Osipenko wrote:
> 17.07.2020 07:46, Sowjanya Komatineni пишет:
> ...
>> Looks like sequence posted in TRM need to be updated clearly for proper
>> MIPI CAL start and wait.
>>
>> Correct steps should be like below
>>
>> 1. Set up CSI registers for use case such as number of lanes, virtual
>> channel, etc.
>> 2. Initialize and power up CSI CIL interface
>> 3. Program MIPI CAL bias pads, cal configs, cal control registers and
>> enable calibration start
>> 4. Power up camera through the I2C interface and start sensor streaming
>> through the I2C
>>
>> Note: All sensors might not leave pads in LP-11 state as sensor may be
>> power down when not in use.
>>
>> So start streaming prior to checking for calibration done status as
>> LP-11 -> HS transition happens during sensor stream and calibration
>> logic can apply results to pads and update done status,
>>
>> 5. Wait for done signal from calibration logic
>>
>> 6. perform frame capture thru VI
>> 7. Frame done, CSI goes back to stop state, LP11
>>
>> Will work internally to correct sequence in TRM ...
> Will be nice to have an updated TRM, thank you!
>
> Also, what about the auto-calibration? Isn't it needed to be enabled for
> CSI?
STARTCAL does one time calibration and with AUTOCAL calibration will be 
triggered periodically.

For pads PULLUP/PULLDN/TERM impedance calibration, we only need one-time 
calibration on pads power up.

We always use one time pads calibration for CSI.

>
>> In mipi driver will update as below to have mipi clk enabled till
>> calibration status check is done.
>>
>> Always tegra_mipi_wait() followes tegra_mipi_calibrate() in both DSI and
>> CSI. So below sequence should work good.
>>
>> tegra_mipi_calibrate()
>>
>> - clk_enable mipi cal
>> - program mipi cal registers (bias pads cfgs, mipi cal ctrl and trigger
>> calibration start)
>>
>> tegra_mipi_wait()
>> - read mipi cal status and wait for active and done bits
>> - clk_disable mipi cal
>
> Maybe then it should be better to rename the functions like this:
>
> tegra_mipi_calibrate() -> tegra_mipi_start_calibration()
> tegra_mipi_wait()      -> tegra_mipi_finish_calibration().
>
> and there also should be tegra_mipi_cancel_calibration().
>
>
> Example:
>
> 	tegra_mipi_start_calibration();
>
> 	ret = v4l2_subdev_call(subdev, video, s_stream, on);
> 	if (ret < 0) {
> 		tegra_mipi_cancel_calibration();
> 		goto err;
> 	}
>
> 	tegra_mipi_finish_calibration();
>
>
Dmitry Osipenko July 17, 2020, 8:14 p.m. UTC | #13
17.07.2020 18:41, Sowjanya Komatineni пишет:
...
>> Also, what about the auto-calibration? Isn't it needed to be enabled for
>> CSI?
> STARTCAL does one time calibration and with AUTOCAL calibration will be
> triggered periodically.
> 
> For pads PULLUP/PULLDN/TERM impedance calibration, we only need one-time
> calibration on pads power up.
> 
> We always use one time pads calibration for CSI.

Alright, thank you for the clarification!
diff mbox series

Patch

diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 3c09e29..1a76f1f 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -670,6 +670,7 @@  static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
 static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
 {
 	u32 value;
+	int ret;
 
 	/*
 	 * XXX Is this still needed? The module reset is deasserted right
@@ -693,7 +694,11 @@  static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
 		DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
 	tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);
 
-	return tegra_mipi_calibrate(dsi->mipi);
+	ret = tegra_mipi_calibrate(dsi->mipi);
+	if (ret < 0)
+		return ret;
+
+	return tegra_mipi_wait(dsi->mipi);
 }
 
 static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,
diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c
index 259e70c..e606464 100644
--- a/drivers/gpu/host1x/mipi.c
+++ b/drivers/gpu/host1x/mipi.c
@@ -293,18 +293,29 @@  int tegra_mipi_disable(struct tegra_mipi_device *dev)
 }
 EXPORT_SYMBOL(tegra_mipi_disable);
 
-static int tegra_mipi_wait(struct tegra_mipi *mipi)
+int tegra_mipi_wait(struct tegra_mipi_device *device)
 {
+	struct tegra_mipi *mipi = device->mipi;
 	void __iomem *status_reg = mipi->regs + (MIPI_CAL_STATUS << 2);
 	u32 value;
 	int err;
 
+	err = clk_enable(device->mipi->clk);
+	if (err < 0)
+		return err;
+
+	mutex_lock(&device->mipi->lock);
+
 	err = readl_relaxed_poll_timeout(status_reg, value,
 					 !(value & MIPI_CAL_STATUS_ACTIVE) &&
 					 (value & MIPI_CAL_STATUS_DONE), 50,
 					 250000);
+	mutex_unlock(&device->mipi->lock);
+	clk_disable(device->mipi->clk);
+
 	return err;
 }
+EXPORT_SYMBOL(tegra_mipi_wait);
 
 int tegra_mipi_calibrate(struct tegra_mipi_device *device)
 {
@@ -370,12 +381,10 @@  int tegra_mipi_calibrate(struct tegra_mipi_device *device)
 	value |= MIPI_CAL_CTRL_START;
 	tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL);
 
-	err = tegra_mipi_wait(device->mipi);
-
 	mutex_unlock(&device->mipi->lock);
 	clk_disable(device->mipi->clk);
 
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL(tegra_mipi_calibrate);
 
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index 9e67841..20c885d 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -334,5 +334,6 @@  void tegra_mipi_free(struct tegra_mipi_device *device);
 int tegra_mipi_enable(struct tegra_mipi_device *device);
 int tegra_mipi_disable(struct tegra_mipi_device *device);
 int tegra_mipi_calibrate(struct tegra_mipi_device *device);
+int tegra_mipi_wait(struct tegra_mipi_device *device);
 
 #endif