From: Kieran Bingham <kieran.bingham@ideasonboard.com>
To: Jacopo Mondi <jacopo@jmondi.org>
Cc: Jacopo Mondi <jacopo+renesas@jmondi.org>,
sakari.ailus@linux.intel.com, laurent.pinchart@ideasonboard.com,
niklas.soderlund+renesas@ragnatech.se,
linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
dave.stevenson@raspberrypi.org
Subject: Re: [RFC 2/5] media: adv748x: Post-pone IO10 write to power up
Date: Wed, 10 Jun 2020 10:50:15 +0100 [thread overview]
Message-ID: <0d37be83-eda5-8946-6dd0-c48e731245e1@ideasonboard.com> (raw)
In-Reply-To: <20190415070026.3yq5tbufajptkijf@uno.localdomain>
Hi Jacopo,
Sorry for dragging up an old thread...
On 15/04/2019 08:00, Jacopo Mondi wrote:
> Hi Kieran,
>
> On Fri, Apr 12, 2019 at 04:57:45PM +0100, Kieran Bingham wrote:
>> Hi Jacopo,
>>
>> On 12/04/2019 15:45, Jacopo Mondi wrote:
>>> Hi Kieran,
>>>
>>> On Fri, Apr 12, 2019 at 03:15:46PM +0100, Kieran Bingham wrote:
>>>> Hi Jacopo,
>>>>
>>>> On 16/03/2019 15:47, Jacopo Mondi wrote:
>>>>> Post-pone the write of the ADV748X_IO_10 register that controls the active
>>>>> routing between the CP and AFE cores to the 4-lanes CSI-2 TXA at TX
>>>>> power-up time.
>>>>
>>>> "by caching its configuration in the driver state."
>>>>
>>>>>
>>>>> While at there, use the 'csi4_in_sel' name, which matches the register
>>>>
>>>> 'While at it, use the...'
>>>>
>>>> Except I'm not sure csi4_in_sel is the right name for the cached values
>>>> as below...
>>>>
>>>>
>>>>> field description in the manual, in place of 'io_10' which is the full
>>>>> register name.
>>>>>
>>>>
>>>> This has a fixes tag, but doesn't state what the actual problem is?
>>>>
>>>
>>> As reported in the cover letter, please see:
>>> "[PATCH] media: adv748x: Don't disable CSI-2 on link_setup"
>>
>> Ah I see, I had missed that.
>>
>> The patch itself should still describe the problem if it's fixing
>> something. The cover letter will not be available in the git-log.
>>
>
> You're right, I'll expand the commit message.
>
>> Ok, so this patch supersedes "[PATCH] media: adv748x: Don't disable
>> CSI-2 on link_setup" ?
>>
>
> Yes
>
>>>> Can I assume that the problem is that the configuration here is being
>>>> written to the hardware before it is powered up or such?
>>>>
>>>> Or perhaps reading through the patch again, is it that the call to
>>>> link_setup can affect running streams?
>>>
>>> The issue I was trying to solve, even with the first patch is that
>>> going through a link disable (eg. at media graph reset time) wrote to
>>> the csi4_in_sel register a 0 value, when both TXA and TXB routing
>>> where disabled and this causes issues on some HDMI transmiters, for
>>> reason Ian and Hans tried to expand but about which I'm not yet sure
>>> about.
>>
>> Ok, I found that patch and read their comments. So disabling the CSI2
>> might trigger a hot-plug event to the transmitter which makes them think
>> they have been (physically) disconnected in some way, or triggers them
>> to re-read the EDID which will fail. But we don't really know what the
>> fault is yet.
>>
>
> Correct. Please note that I've seen this happening with one HDMI
> transmitter (a chromecast device), while if HDMI source is a laptop
> everything's fine...
>
>>
>>> The idea here is to cache the routing settings at link_setup time
>>> (upon activation or deactivation of a link) and apply them to hardware
>>> at tx power up time, which happens at s_stream(1).
>>>
>>> In this way, if streaming is started, we know at least one link is
>>> enabled and we can write to csi4_in_sel.
>>
>> Overall this seems reasonable, only making a change to io10 when either
>> of the stream states are changed.
>>
>
> Thanks, I'll re-send (maybe even out of this series if it gets stale).
> Could I have your tag on the next iteration?
I found this patch on a branch while rebasing old patches to latest.
It still applies, and seems to make sense - and it looks like I agreed
with you back when you posted it.
It seems it only needed me to say:
"Yes,
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
"
To unblock this particular patch (separate from the rest of the series
it currently resides in.
So there you have it ;-)
With the only action remaining being to try to briefly describe the
problem it fixes in the commit message.
Thanks,
--
Kieran
>
> Thanks
> j
>
>>
>>>>> Fixes: 9423ca350df7 ("media: adv748x: Implement TX link_setup callback")
>>>>> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
>>>>> ---
>>>>> drivers/media/i2c/adv748x/adv748x-core.c | 53 ++++++++++++++----------
>>>>> drivers/media/i2c/adv748x/adv748x.h | 2 +
>>>>> 2 files changed, 33 insertions(+), 22 deletions(-)
>>>>>
>>>>> diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
>>>>> index 0e5a75eb6d75..02135741b1a6 100644
>>>>> --- a/drivers/media/i2c/adv748x/adv748x-core.c
>>>>> +++ b/drivers/media/i2c/adv748x/adv748x-core.c
>>>>> @@ -305,23 +305,35 @@ static int adv748x_power_down_tx(struct adv748x_csi2 *tx)
>>>>>
>>>>> int adv748x_tx_power(struct adv748x_csi2 *tx, bool on)
>>>>> {
>>>>> - int val;
>>>>> + u8 io10_mask = ADV748X_IO_10_CSI1_EN | ADV748X_IO_10_CSI4_EN |
>>>>> + ADV748X_IO_10_CSI4_IN_SEL_AFE;
>>>>> + struct adv748x_state *state = tx->state;
>>>>> + int ret;
>>>>>
>>>>> if (!is_tx_enabled(tx))
>>>>> return 0;
>>>>>
>>>>> - val = tx_read(tx, ADV748X_CSI_FS_AS_LS);
>>>>> - if (val < 0)
>>>>> - return val;
>>>>> + ret = tx_read(tx, ADV748X_CSI_FS_AS_LS);
>>>>> + if (ret < 0)
>>>>> + return ret;
>>>>>
>>>>> /*
>>>>> * This test against BIT(6) is not documented by the datasheet, but was
>>>>> * specified in the downstream driver.
>>>>> * Track with a WARN_ONCE to determine if it is ever set by HW.
>>>>> */
>>>>> - WARN_ONCE((on && val & ADV748X_CSI_FS_AS_LS_UNKNOWN),
>>>>> + WARN_ONCE((on && ret & ADV748X_CSI_FS_AS_LS_UNKNOWN),
>>>>> "Enabling with unknown bit set");
>>>>>
>>>>> + /* Configure TXA routing. */
>>>>
>>>> Should TXA routing be configured even on TXB power up? This function
>>>> handles both TX code paths. (Edit: possibly yes)
>>>>
>>>
>>> The comment is wrong, thanks for noticing.
>>>
>>>> Can the logic that determines state->csi4_in_sel value simply be moved
>>>> here (or to an independent adv748x_configure_routing() function)?
>>>>
>>>
>>> It has to be changed at link_setup time in rensponse to a media link
>>> activation or deactivation.
>>>
>>>> I think this patch means that changes to routing will now only take
>>>> effect when starting or stopping a stream, is that right? (If so - could
>>>> that go into the commit message please?)
>>>>
>>>
>>> Well...
>>>
>>> Post-pone the write of the ADV748X_IO_10 register that controls the active
>>> routing between the CP and AFE cores to the 4-lanes CSI-2 TXA at TX
>>> power-up time.
>>>
>>> Doesn't it say that? Or what confused you is that s_stream->s_power(1)
>>> and I should mention streaming instead of power up?
>>
>> I think of "Power up" meaning at device probe time (or possibly some
>> runtime-pm event time). But yes, I think the distinction that it now
>> happens at stream_on/stream_off is important.
>>
>>
>>
>>>
>>>>
>>>>
>>>>
>>>>> + if (on) {
>>>>> + ret = io_clrset(state, ADV748X_IO_10, io10_mask,
>>>>> + state->csi4_in_sel);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> + }
>>>>> +
>>>>> +
>>>>> return on ? adv748x_power_up_tx(tx) : adv748x_power_down_tx(tx);
>>>>> }
>>>>>
>>>>> @@ -337,10 +349,7 @@ static int adv748x_link_setup(struct media_entity *entity,
>>>>> struct adv748x_state *state = v4l2_get_subdevdata(sd);
>>>>> struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
>>>>> bool enable = flags & MEDIA_LNK_FL_ENABLED;
>>>>> - u8 io10_mask = ADV748X_IO_10_CSI1_EN |
>>>>> - ADV748X_IO_10_CSI4_EN |
>>>>> - ADV748X_IO_10_CSI4_IN_SEL_AFE;
>>>>> - u8 io10 = 0;
>>>>> + u8 csi4_in_sel = 0;
>>>>>
>>>>> /* Refuse to enable multiple links to the same TX at the same time. */
>>>>> if (enable && tx->src)
>>>>> @@ -359,17 +368,19 @@ static int adv748x_link_setup(struct media_entity *entity,
>>>>>
>>>>> if (state->afe.tx) {
>>>>> /* AFE Requires TXA enabled, even when output to TXB */
>>>>> - io10 |= ADV748X_IO_10_CSI4_EN;
>>>>> + csi4_in_sel |= ADV748X_IO_10_CSI4_EN;
>>>>> if (is_txa(tx))
>>>>> - io10 |= ADV748X_IO_10_CSI4_IN_SEL_AFE;
>>>>> + csi4_in_sel |= ADV748X_IO_10_CSI4_IN_SEL_AFE;
>>>>
>>>> Hrm ... this is the one part that I think can't be determined without
>>>> caching some sort of value to state the routing.
>>>>
>>>
>>> Yes
>>
>> But the actual hardware shouldn't be updated if the stream is running
>> right? (I wonder if the media-controller would prevent that anyway).
>>
>>
>>
>>>
>>>>> else
>>>>> - io10 |= ADV748X_IO_10_CSI1_EN;
>>>>> + csi4_in_sel |= ADV748X_IO_10_CSI1_EN;
>>>>> }
>>>>>
>>>>> if (state->hdmi.tx)
>>>>> - io10 |= ADV748X_IO_10_CSI4_EN;
>>>>> + csi4_in_sel |= ADV748X_IO_10_CSI4_EN;
>>>>>
>>>>> - return io_clrset(state, ADV748X_IO_10, io10_mask, io10);
>>>>> + state->csi4_in_sel = csi4_in_sel;
>>>>> +
>>>>> + return 0;
>>>>> }
>>>>>
>>>>> static const struct media_entity_operations adv748x_tx_media_ops = {
>>>>> @@ -485,7 +496,6 @@ static int adv748x_sw_reset(struct adv748x_state *state)
>>>>> static int adv748x_reset(struct adv748x_state *state)
>>>>> {
>>>>> int ret;
>>>>> - u8 regval = 0;
>>>>>
>>>>> ret = adv748x_sw_reset(state);
>>>>> if (ret < 0)
>>>>> @@ -504,6 +514,12 @@ static int adv748x_reset(struct adv748x_state *state)
>>>>> if (ret)
>>>>> return ret;
>>>>>
>>>>
>>>> Should adv748x_reset() reset the state->csi4_in_sel cached value to 0
>>>> before setting it?
>>>
>>> I should better check when reset happens, and if it happens only when
>>> links have been disabled or not.
>>> If links are disabled, the variable gets zeroed by the link_setup
>>> callback. If reset happens with links active, we should not zero it
>>> otherwise we lose the configuration
>>
>>
>> Ah yes, I missed that the local variable is initialised to zero, and
>> this state variable is set to the result at the end of the call...
>>
>> It does mean that the function ordering will be important here.
>>
>> It becomes irrelevant if these conditionals move to the same point
>> anyway though.
>>
>>
>>
>>>
>>>>
>>>>
>>>>> + /* Conditionally enable TXa and TXb. */
>>>>> + if (is_tx_enabled(&state->txa))
>>>>> + state->csi4_in_sel |= ADV748X_IO_10_CSI4_EN;
>>>>> + if (is_tx_enabled(&state->txb))
>>>>> + state->csi4_in_sel |= ADV748X_IO_10_CSI1_EN;
>>>>
>>>> This makes it looks like the naming "csi4_in_sel" is less appropriate,
>>>> as it covers both CSI4 and CSI1...
>>>>
>>>
>>> Blame the hw designers :)
>>
>> Always. ... of course they keep blaming us back :D
>>
>>>
>>>> Also, this is confusing two terms, between the 'enable' and the 'select'
>>>>
>>>> The _EN bits looks like they control the activation of the CSI
>>>> transmitter, where as the 'select' bits control the routing.
>>>>
>>>
>>> You are righ. csi4_in_sel should only control the 3 bits used for
>>> routing, while enabling and disabling of the TXes is controlled by
>>> other bits of the io_10 register.
>>> I'll look into changing the name back
>>>
>>>> As the is_tx_enabled($TX) state is constant, perhaps that bit could be
>>>> inferred later when the register is written, and doesn't need to be
>>>> cached here?
>>>
>>> I'll consider that, thanks
>>
>> I think it's only the routing choice that needs to be stored in the
>> state. That would minimise being stored 'globally', and the values could
>> be determined at the time of programming the register.
>>
>>>
>>> Thanks
>>> j
>>>
>>>>
>>>>
>>>>> +
>>>>> /* Reset TXA and TXB */
>>>>> adv748x_tx_power(&state->txa, 1);
>>>>> adv748x_tx_power(&state->txa, 0);
>>>>> @@ -513,13 +529,6 @@ static int adv748x_reset(struct adv748x_state *state)
>>>>> /* Disable chip powerdown & Enable HDMI Rx block */
>>>>> io_write(state, ADV748X_IO_PD, ADV748X_IO_PD_RX_EN);
>>>>>
>>>>> - /* Conditionally enable TXa and TXb. */
>>>>> - if (is_tx_enabled(&state->txa))
>>>>> - regval |= ADV748X_IO_10_CSI4_EN;
>>>>> - if (is_tx_enabled(&state->txb))
>>>>> - regval |= ADV748X_IO_10_CSI1_EN;
>>>>> - io_write(state, ADV748X_IO_10, regval);
>>>>> -
>>>>> /* Use vid_std and v_freq as freerun resolution for CP */
>>>>> cp_clrset(state, ADV748X_CP_CLMP_POS, ADV748X_CP_CLMP_POS_DIS_AUTO,
>>>>> ADV748X_CP_CLMP_POS_DIS_AUTO);
>>>>> diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
>>>>> index 4a5a6445604f..27c116d09284 100644
>>>>> --- a/drivers/media/i2c/adv748x/adv748x.h
>>>>> +++ b/drivers/media/i2c/adv748x/adv748x.h
>>>>> @@ -196,6 +196,8 @@ struct adv748x_state {
>>>>> struct adv748x_afe afe;
>>>>> struct adv748x_csi2 txa;
>>>>> struct adv748x_csi2 txb;
>>>>> +
>>>>> + unsigned int csi4_in_sel;
>>>>> };
>>>>>
>>>>> #define adv748x_hdmi_to_state(h) container_of(h, struct adv748x_state, hdmi)
>>>>> --
>>>>> 2.21.0
>>>>>
>>
>> --
>> Regards
>> --
>> Kieran
--
Regards
--
Kieran
next prev parent reply other threads:[~2020-06-10 9:50 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-16 15:47 [RFC 0/5] media: Implement negotiation of CSI-2 data lanes Jacopo Mondi
2019-03-16 15:47 ` [RFC 1/5] v4l: subdev: Add MIPI CSI-2 PHY to frame desc Jacopo Mondi
2019-03-16 16:20 ` Sergei Shtylyov
2019-03-18 8:23 ` Jacopo Mondi
2019-03-16 17:51 ` Sakari Ailus
2019-03-18 8:31 ` Jacopo Mondi
2019-03-18 15:29 ` Dave Stevenson
2019-03-20 16:45 ` Jacopo Mondi
2019-04-04 8:49 ` Sakari Ailus
2019-04-04 16:36 ` Dave Stevenson
2019-04-10 16:51 ` Jacopo Mondi
2019-03-16 15:47 ` [RFC 2/5] media: adv748x: Post-pone IO10 write to power up Jacopo Mondi
2019-04-12 14:15 ` Kieran Bingham
2019-04-12 14:45 ` Jacopo Mondi
2019-04-12 15:57 ` Kieran Bingham
2019-04-15 7:00 ` Jacopo Mondi
2020-06-10 9:50 ` Kieran Bingham [this message]
2019-03-16 15:47 ` [RFC 3/5] media: adv748x: Make lanes number depend on routing Jacopo Mondi
2019-04-12 14:45 ` Kieran Bingham
2019-03-16 15:48 ` [RFC 4/5] media: adv748x: Report D-PHY configuration Jacopo Mondi
2019-03-16 15:48 ` [RFC 5/5] media: rcar-csi2: Configure CSI-2 with frame desc Jacopo Mondi
2019-03-20 19:50 ` Niklas Söderlund
2019-03-21 0:51 ` Jacopo Mondi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0d37be83-eda5-8946-6dd0-c48e731245e1@ideasonboard.com \
--to=kieran.bingham@ideasonboard.com \
--cc=dave.stevenson@raspberrypi.org \
--cc=jacopo+renesas@jmondi.org \
--cc=jacopo@jmondi.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=niklas.soderlund+renesas@ragnatech.se \
--cc=sakari.ailus@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).