[PATCH 5/6] drm: rcar-du: Fix setting a reserved bit in DPLLCR

Tomi Valkeinen tomi.valkeinen+renesas at ideasonboard.com
Thu Jan 19 10:24:48 UTC 2023


On 19/01/2023 11:40, Laurent Pinchart wrote:
> Hi Tomi,
> 
> On Thu, Jan 19, 2023 at 11:17:58AM +0200, Tomi Valkeinen wrote:
>> On 18/01/2023 23:38, Laurent Pinchart wrote:
>>> On Tue, Jan 17, 2023 at 03:51:53PM +0200, Tomi Valkeinen wrote:
>>>> On H3 ES1 two bits in DPLLCR are used to select the DU input dot clock
>>>
>>> s/ES1/ES1.x/
>>>
>>> Same below.
>>
>> Ok. But I do wonder, is there a difference? What's the case when ES1
>> could be mistaken to mean something else?
> 
> It's just for consistency I suppose. No big deal.
> 
>>>> source. These are bits 20 and 21 for DU2, and bits 22 and 23 for DU1. On
>>>> non-ES1, only the higher bits are used (bits 21 and 23), and the lower
>>>> bits are reserved and should be set to 0 (or not set at all).
>>>
>>> How do you not set a bit ? :-)
>>
>> By leaving it to the value the register already has. But as we don't
>> read the register as a base value here, I guess that comment is a bit
>> misleading.
>>
>>>> The current code always sets the lower bits, even on non-ES1.
>>>
>>> I think that's harmless, and not worth making the driver more complex,
>>> but I'll stop fighting.
>>>
>>>> For both DU1 and DU2, on all SoC versions, when writing zeroes to those
>>>> bits the input clock is DCLKIN, and thus there's no difference between
>>>> ES1 and non-ES1.
>>>>
>>>> For DU1, writing 0b10 to the bits (or only writing the higher bit)
>>>> results in using PLL0 as the input clock, so in this case there's also
>>>> no difference between ES1 and non-ES1.
>>>>
>>>> However, for DU2, writing 0b10 to the bits results in using PLL0 as the
>>>> input clock on ES1, whereas on non-ES1 it results in using PLL1. On ES1
>>>> you need to write 0b11 to select PLL1.
>>>>
>>>> The current code always writes 0b11 to PLCS0 field to select PLL1 on all
>>>> SoC versions, which works but causes an illegal (in the sense of not
>>>> allowed by the documentation) write to a reserved bit field.
>>>>
>>>> To remove the illegal bit write on PLSC0 we need to handle the input dot
>>>> clock selection differently for ES1 and non-ES1.
>>>>
>>>> Add a new quirk, RCAR_DU_QUIRK_H3_ES1_PLL, for this, and a new
>>>> rcar_du_device_info entry for the ES1 SoC. Using these, we can always
>>>
>>> The new entry was added in the previous patch already.
>>
>> Indeed.
>>
>>>> set the bit 21 on PLSC0 when choosing the PLL as the source clock, and
>>>> additionally set the bit 20 when on ES1.
>>>>
>>>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas at ideasonboard.com>
>>>> ---
>>>>    drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 12 ++++++++++--
>>>>    drivers/gpu/drm/rcar-du/rcar_du_drv.c  |  3 ++-
>>>>    drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  1 +
>>>>    drivers/gpu/drm/rcar-du/rcar_du_regs.h |  3 ++-
>>>>    4 files changed, 15 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>> index f2d3266509cc..8d660a6141bf 100644
>>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
>>>> @@ -245,12 +245,20 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
>>>>    		       | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
>>>>    		       | DPLLCR_STBY;
>>>>    
>>>> -		if (rcrtc->index == 1)
>>>> +		if (rcrtc->index == 1) {
>>>>    			dpllcr |= DPLLCR_PLCS1
>>>>    			       |  DPLLCR_INCS_DOTCLKIN1;
>>>> -		else
>>>> +		} else {
>>>>    			dpllcr |= DPLLCR_PLCS0
>>>>    			       |  DPLLCR_INCS_DOTCLKIN0;
>>>> +			/*
>>>> +			 * On H3 ES1.x, in addition to setting bit 21 (PLCS0),
>>>> +			 * also bit 20 has to be set to select PLL1 as the
>>>> +			 * clock source.
>>>
>>> I'd add "On ES2 and newer, PLL1 is selected unconditionally.".
>>
>> It's not selected unconditionally, we need to set bit 21. And possibly
>> we need to set bit 20 to 0, although it's not documented what bit 20
>> would do when set to 1.
> 
> We currently set bit 20 to 1 and it works, so I concluded that bit 20 is

Ah, right, we do set it to 1.

> ignored. That's what I meant by PLL1 being selected automatically,
> between PLL0 and PLL1. We still need to select PLL instead of DCLKIN
> with bit 21.
> 
>> And is that "ES2.x"? =)
> 
> Good point :-)
> 
>> How about:
>>
>>    * On ES2.x and newer, PLL1 is selected by setting bit
>>    * 21 (PLCS0) to 1 and keeping the (reserved) bit 20 as
>>    * 0. On H3 ES1.x, in addition to setting bit 21, also
>>    * bit 20 has to be set to select PLL1 as the clock source.
> 
> What I'd like to capture in the comment is that the clock topology is
> 
>          bit 20
>            |     bit 21
>            v       |
>           |\       v
> PLL0 --> |0|     |\
> PLL1 --> |1| --> |1| -->
>           |/  /-> |0|
>               |   |/
> DCLKIN ------/
> 
> on H3 ES1.x, while on newer revisions, bit 20 is ignored and the first
> mux is hardcoded to PLL1.

Isn't that the stuff that's supposed to be found by reading the manual? 
I could, of course, copy the above picture, and draw a similar one for 
ES2+, but that feels like just useless copying of the manual...

Doesn't the above comment already describe why we set the bits as we do? 
I could change the comment to talk about muxes, if you think that's a 
better approach. But, if I recall right, the manuals don't talk about 
muxes, just "set this to X to use PLL1", so my comment above approaches 
from that direction.

Maybe something in this direction, then:

On ES2.x we have a single mux controlled via bit 21, which selects 
between DCLKIN source (bit 21 = 0) and a PLL source (bit 21 = 1), where 
the PLL is always PLL1. On ES1.x we have an additional mux, controlled 
via bit 20, for choosing between PLL0 (bit 20 = 0) and PLL1 (bit 20 = 
1). We always want to use PLL1, so on ES1.x, in addition to setting bit 
21, we need to set the bit 20.

  Tomi



More information about the dri-devel mailing list