diff mbox series

[v7,10/24] drm/rockchip: dw_hdmi: Add support for hclk

Message ID 20220225075150.2729401-11-s.hauer@pengutronix.de (mailing list archive)
State New, archived
Headers show
Series drm/rockchip: RK356x VOP2 support | expand

Commit Message

Sascha Hauer Feb. 25, 2022, 7:51 a.m. UTC
The rk3568 HDMI has an additional clock that needs to be enabled for the
HDMI controller to work. The purpose of that clock is not clear. It is
named "hclk" in the downstream driver, so use the same name.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---

Notes:
    Changes since v5:
    - Use devm_clk_get_optional rather than devm_clk_get

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Dmitry Osipenko Feb. 25, 2022, 10:26 a.m. UTC | #1
25.02.2022 10:51, Sascha Hauer пишет:
> The rk3568 HDMI has an additional clock that needs to be enabled for the
> HDMI controller to work. The purpose of that clock is not clear. It is
> named "hclk" in the downstream driver, so use the same name.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> 
> Notes:
>     Changes since v5:
>     - Use devm_clk_get_optional rather than devm_clk_get
> 
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index fe4f9556239ac..c6c00e8779ab5 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>  	const struct rockchip_hdmi_chip_data *chip_data;
>  	struct clk *ref_clk;
>  	struct clk *grf_clk;
> +	struct clk *hclk_clk;
>  	struct dw_hdmi *hdmi;
>  	struct regulator *avdd_0v9;
>  	struct regulator *avdd_1v8;
> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>  		return PTR_ERR(hdmi->grf_clk);
>  	}
>  
> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {

Have you tried to investigate the hclk? I'm still thinking that's not
only HDMI that needs this clock and then the hardware description
doesn't look correct.
Sascha Hauer Feb. 25, 2022, 10:49 a.m. UTC | #2
On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> 25.02.2022 10:51, Sascha Hauer пишет:
> > The rk3568 HDMI has an additional clock that needs to be enabled for the
> > HDMI controller to work. The purpose of that clock is not clear. It is
> > named "hclk" in the downstream driver, so use the same name.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > 
> > Notes:
> >     Changes since v5:
> >     - Use devm_clk_get_optional rather than devm_clk_get
> > 
> >  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > index fe4f9556239ac..c6c00e8779ab5 100644
> > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> >  	const struct rockchip_hdmi_chip_data *chip_data;
> >  	struct clk *ref_clk;
> >  	struct clk *grf_clk;
> > +	struct clk *hclk_clk;
> >  	struct dw_hdmi *hdmi;
> >  	struct regulator *avdd_0v9;
> >  	struct regulator *avdd_1v8;
> > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
> >  		return PTR_ERR(hdmi->grf_clk);
> >  	}
> >  
> > +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> > +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> 
> Have you tried to investigate the hclk? I'm still thinking that's not
> only HDMI that needs this clock and then the hardware description
> doesn't look correct.

I am still not sure what you mean. Yes, it's not only the HDMI that
needs this clock. The VOP2 needs it as well and the driver handles that.

Sascha
Dmitry Osipenko Feb. 25, 2022, 11:10 a.m. UTC | #3
25.02.2022 13:49, Sascha Hauer пишет:
> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>> 25.02.2022 10:51, Sascha Hauer пишет:
>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>> named "hclk" in the downstream driver, so use the same name.
>>>
>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>> ---
>>>
>>> Notes:
>>>     Changes since v5:
>>>     - Use devm_clk_get_optional rather than devm_clk_get
>>>
>>>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>  1 file changed, 16 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>  	const struct rockchip_hdmi_chip_data *chip_data;
>>>  	struct clk *ref_clk;
>>>  	struct clk *grf_clk;
>>> +	struct clk *hclk_clk;
>>>  	struct dw_hdmi *hdmi;
>>>  	struct regulator *avdd_0v9;
>>>  	struct regulator *avdd_1v8;
>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>  		return PTR_ERR(hdmi->grf_clk);
>>>  	}
>>>  
>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>
>> Have you tried to investigate the hclk? I'm still thinking that's not
>> only HDMI that needs this clock and then the hardware description
>> doesn't look correct.
> 
> I am still not sure what you mean. Yes, it's not only the HDMI that
> needs this clock. The VOP2 needs it as well and the driver handles that.

I'm curious whether DSI/DP also need that clock to be enabled. If they
do, then you aren't modeling h/w properly AFAICS.
Sascha Hauer Feb. 25, 2022, 11:37 a.m. UTC | #4
On Fri, Feb 25, 2022 at 02:10:55PM +0300, Dmitry Osipenko wrote:
> 25.02.2022 13:49, Sascha Hauer пишет:
> > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> >> 25.02.2022 10:51, Sascha Hauer пишет:
> >>> The rk3568 HDMI has an additional clock that needs to be enabled for the
> >>> HDMI controller to work. The purpose of that clock is not clear. It is
> >>> named "hclk" in the downstream driver, so use the same name.
> >>>
> >>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> >>> ---
> >>>
> >>> Notes:
> >>>     Changes since v5:
> >>>     - Use devm_clk_get_optional rather than devm_clk_get
> >>>
> >>>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
> >>>  1 file changed, 16 insertions(+)
> >>>
> >>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>> index fe4f9556239ac..c6c00e8779ab5 100644
> >>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> >>>  	const struct rockchip_hdmi_chip_data *chip_data;
> >>>  	struct clk *ref_clk;
> >>>  	struct clk *grf_clk;
> >>> +	struct clk *hclk_clk;
> >>>  	struct dw_hdmi *hdmi;
> >>>  	struct regulator *avdd_0v9;
> >>>  	struct regulator *avdd_1v8;
> >>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
> >>>  		return PTR_ERR(hdmi->grf_clk);
> >>>  	}
> >>>  
> >>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> >>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> >>
> >> Have you tried to investigate the hclk? I'm still thinking that's not
> >> only HDMI that needs this clock and then the hardware description
> >> doesn't look correct.
> > 
> > I am still not sure what you mean. Yes, it's not only the HDMI that
> > needs this clock. The VOP2 needs it as well and the driver handles that.
> 
> I'm curious whether DSI/DP also need that clock to be enabled. If they
> do, then you aren't modeling h/w properly AFAICS.

Indeed I can confirm that DSI and DP need that clock enabled for
register access as well. Do you think these devices should be under an
additional bus layer in the device tree which drives the clock? Or
should HCLK_VOP be enabled as part of the RK3568_PD_VO power domain?

Sascha
Robin Murphy Feb. 25, 2022, 12:41 p.m. UTC | #5
On 2022-02-25 11:10, Dmitry Osipenko wrote:
> 25.02.2022 13:49, Sascha Hauer пишет:
>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>> named "hclk" in the downstream driver, so use the same name.
>>>>
>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>> ---
>>>>
>>>> Notes:
>>>>      Changes since v5:
>>>>      - Use devm_clk_get_optional rather than devm_clk_get
>>>>
>>>>   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>   1 file changed, 16 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>   	const struct rockchip_hdmi_chip_data *chip_data;
>>>>   	struct clk *ref_clk;
>>>>   	struct clk *grf_clk;
>>>> +	struct clk *hclk_clk;
>>>>   	struct dw_hdmi *hdmi;
>>>>   	struct regulator *avdd_0v9;
>>>>   	struct regulator *avdd_1v8;
>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>   		return PTR_ERR(hdmi->grf_clk);
>>>>   	}
>>>>   
>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>
>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>> only HDMI that needs this clock and then the hardware description
>>> doesn't look correct.
>>
>> I am still not sure what you mean. Yes, it's not only the HDMI that
>> needs this clock. The VOP2 needs it as well and the driver handles that.
> 
> I'm curious whether DSI/DP also need that clock to be enabled. If they
> do, then you aren't modeling h/w properly AFAICS.

Assuming nobody at Rockchip decided to make things needlessly 
inconsistent with previous SoCs, HCLK_VOP should be the clock for the 
VOP's AHB slave interface. Usually, if that affected anything other than 
accessing VOP registers, indeed it would smell of something being wrong 
in the clock tree, but in this case I'd also be suspicious of whether it 
might have ended up clocking related GRF registers as well (either 
directly, or indirectly via some gate that the clock driver hasn't 
modelled yet).

If the symptom of not claiming HCLK_VOP is hanging on some register 
access in the HDMI driver while the VOP is idle, then it should be 
relatively straightforward to narrow down with some logging, and see if 
it looks like this is really just another "grf" clock. If not, then 
we're back to suspecting something more insidiously wrong elsewhere.

Robin.
Sascha Hauer Feb. 25, 2022, 1:11 p.m. UTC | #6
On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
> On 2022-02-25 11:10, Dmitry Osipenko wrote:
> > 25.02.2022 13:49, Sascha Hauer пишет:
> > > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> > > > 25.02.2022 10:51, Sascha Hauer пишет:
> > > > > The rk3568 HDMI has an additional clock that needs to be enabled for the
> > > > > HDMI controller to work. The purpose of that clock is not clear. It is
> > > > > named "hclk" in the downstream driver, so use the same name.
> > > > > 
> > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > > ---
> > > > > 
> > > > > Notes:
> > > > >      Changes since v5:
> > > > >      - Use devm_clk_get_optional rather than devm_clk_get
> > > > > 
> > > > >   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
> > > > >   1 file changed, 16 insertions(+)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > index fe4f9556239ac..c6c00e8779ab5 100644
> > > > > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> > > > >   	const struct rockchip_hdmi_chip_data *chip_data;
> > > > >   	struct clk *ref_clk;
> > > > >   	struct clk *grf_clk;
> > > > > +	struct clk *hclk_clk;
> > > > >   	struct dw_hdmi *hdmi;
> > > > >   	struct regulator *avdd_0v9;
> > > > >   	struct regulator *avdd_1v8;
> > > > > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
> > > > >   		return PTR_ERR(hdmi->grf_clk);
> > > > >   	}
> > > > > +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> > > > > +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> > > > 
> > > > Have you tried to investigate the hclk? I'm still thinking that's not
> > > > only HDMI that needs this clock and then the hardware description
> > > > doesn't look correct.
> > > 
> > > I am still not sure what you mean. Yes, it's not only the HDMI that
> > > needs this clock. The VOP2 needs it as well and the driver handles that.
> > 
> > I'm curious whether DSI/DP also need that clock to be enabled. If they
> > do, then you aren't modeling h/w properly AFAICS.
> 
> Assuming nobody at Rockchip decided to make things needlessly inconsistent
> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
> interface. Usually, if that affected anything other than accessing VOP
> registers, indeed it would smell of something being wrong in the clock tree,
> but in this case I'd also be suspicious of whether it might have ended up
> clocking related GRF registers as well (either directly, or indirectly via
> some gate that the clock driver hasn't modelled yet).

Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
hanging when HCLK_VOP is disabled by disabling that clock via sysfs
using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
of that units can't be accessed. However, when I disable HCLK_VOP by
directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
accessing VOP registers hangs, the other units stay functional.
So it seems it must be the parent clock which must be enabled. The
parent clock is hclk_vo. This clock should be handled as part of the
RK3568_PD_VO power domain:

	power-domain@RK3568_PD_VO {
                reg = <RK3568_PD_VO>;
                clocks = <&cru HCLK_VO>,
                         <&cru PCLK_VO>,
                         <&cru ACLK_VOP_PRE>;
                 pm_qos = <&qos_hdcp>,
                          <&qos_vop_m0>,
                          <&qos_vop_m1>;
                 #power-domain-cells = <0>;
        };

The HDMI controller is part of that domain, so I think this should work,
but it doesn't. That's where I am now, I'll have a closer look.

Sascha
Robin Murphy Feb. 25, 2022, 1:33 p.m. UTC | #7
On 2022-02-25 13:11, Sascha Hauer wrote:
> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
>>> 25.02.2022 13:49, Sascha Hauer пишет:
>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>>>> named "hclk" in the downstream driver, so use the same name.
>>>>>>
>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>>>> ---
>>>>>>
>>>>>> Notes:
>>>>>>       Changes since v5:
>>>>>>       - Use devm_clk_get_optional rather than devm_clk_get
>>>>>>
>>>>>>    drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>>>    1 file changed, 16 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>>>    	const struct rockchip_hdmi_chip_data *chip_data;
>>>>>>    	struct clk *ref_clk;
>>>>>>    	struct clk *grf_clk;
>>>>>> +	struct clk *hclk_clk;
>>>>>>    	struct dw_hdmi *hdmi;
>>>>>>    	struct regulator *avdd_0v9;
>>>>>>    	struct regulator *avdd_1v8;
>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>>>    		return PTR_ERR(hdmi->grf_clk);
>>>>>>    	}
>>>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>>>
>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>>>> only HDMI that needs this clock and then the hardware description
>>>>> doesn't look correct.
>>>>
>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
>>>
>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
>>> do, then you aren't modeling h/w properly AFAICS.
>>
>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
>> interface. Usually, if that affected anything other than accessing VOP
>> registers, indeed it would smell of something being wrong in the clock tree,
>> but in this case I'd also be suspicious of whether it might have ended up
>> clocking related GRF registers as well (either directly, or indirectly via
>> some gate that the clock driver hasn't modelled yet).
> 
> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
> of that units can't be accessed. However, when I disable HCLK_VOP by
> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
> accessing VOP registers hangs, the other units stay functional.
> So it seems it must be the parent clock which must be enabled. The
> parent clock is hclk_vo. This clock should be handled as part of the
> RK3568_PD_VO power domain:
> 
> 	power-domain@RK3568_PD_VO {
>                  reg = <RK3568_PD_VO>;
>                  clocks = <&cru HCLK_VO>,
>                           <&cru PCLK_VO>,
>                           <&cru ACLK_VOP_PRE>;
>                   pm_qos = <&qos_hdcp>,
>                            <&qos_vop_m0>,
>                            <&qos_vop_m1>;
>                   #power-domain-cells = <0>;
>          };
> 
> The HDMI controller is part of that domain, so I think this should work,
> but it doesn't. That's where I am now, I'll have a closer look.

Ah, interesting. Looking at the clock driver, I'd also be suspicious 
whether pclk_vo is somehow messed up such that we're currently relying 
on hclk_vo to keep the common grandparent enabled. Seems like the DSI 
and eDP (and HDCP if anyone ever used it) registers would be similarly 
affected if so, and sure enough they both have a similarly suspect extra 
"hclk" in the downstream DT too.

Robin.
Sascha Hauer Feb. 28, 2022, 2:19 p.m. UTC | #8
On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
> > On 2022-02-25 11:10, Dmitry Osipenko wrote:
> > > 25.02.2022 13:49, Sascha Hauer пишет:
> > > > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> > > > > 25.02.2022 10:51, Sascha Hauer пишет:
> > > > > > The rk3568 HDMI has an additional clock that needs to be enabled for the
> > > > > > HDMI controller to work. The purpose of that clock is not clear. It is
> > > > > > named "hclk" in the downstream driver, so use the same name.
> > > > > > 
> > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > > > ---
> > > > > > 
> > > > > > Notes:
> > > > > >      Changes since v5:
> > > > > >      - Use devm_clk_get_optional rather than devm_clk_get
> > > > > > 
> > > > > >   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
> > > > > >   1 file changed, 16 insertions(+)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > index fe4f9556239ac..c6c00e8779ab5 100644
> > > > > > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> > > > > >   	const struct rockchip_hdmi_chip_data *chip_data;
> > > > > >   	struct clk *ref_clk;
> > > > > >   	struct clk *grf_clk;
> > > > > > +	struct clk *hclk_clk;
> > > > > >   	struct dw_hdmi *hdmi;
> > > > > >   	struct regulator *avdd_0v9;
> > > > > >   	struct regulator *avdd_1v8;
> > > > > > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
> > > > > >   		return PTR_ERR(hdmi->grf_clk);
> > > > > >   	}
> > > > > > +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> > > > > > +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> > > > > 
> > > > > Have you tried to investigate the hclk? I'm still thinking that's not
> > > > > only HDMI that needs this clock and then the hardware description
> > > > > doesn't look correct.
> > > > 
> > > > I am still not sure what you mean. Yes, it's not only the HDMI that
> > > > needs this clock. The VOP2 needs it as well and the driver handles that.
> > > 
> > > I'm curious whether DSI/DP also need that clock to be enabled. If they
> > > do, then you aren't modeling h/w properly AFAICS.
> > 
> > Assuming nobody at Rockchip decided to make things needlessly inconsistent
> > with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
> > interface. Usually, if that affected anything other than accessing VOP
> > registers, indeed it would smell of something being wrong in the clock tree,
> > but in this case I'd also be suspicious of whether it might have ended up
> > clocking related GRF registers as well (either directly, or indirectly via
> > some gate that the clock driver hasn't modelled yet).
> 
> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
> of that units can't be accessed. However, when I disable HCLK_VOP by
> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
> accessing VOP registers hangs, the other units stay functional.
> So it seems it must be the parent clock which must be enabled. The
> parent clock is hclk_vo. This clock should be handled as part of the
> RK3568_PD_VO power domain:
> 
> 	power-domain@RK3568_PD_VO {
>                 reg = <RK3568_PD_VO>;
>                 clocks = <&cru HCLK_VO>,
>                          <&cru PCLK_VO>,
>                          <&cru ACLK_VOP_PRE>;
>                  pm_qos = <&qos_hdcp>,
>                           <&qos_vop_m0>,
>                           <&qos_vop_m1>;
>                  #power-domain-cells = <0>;
>         };

Forget this. The clocks in this node are only enabled during enabling or
disabling the power domain, they are disabled again immediately afterwards.

OK, I need HCLK_VO to access the HDMI registers. I verified that by
disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
HDMI registers become inaccessible then. This means I'll replace
HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?

Sascha
Dmitry Osipenko Feb. 28, 2022, 10:56 p.m. UTC | #9
On 2/28/22 17:19, Sascha Hauer wrote:
> On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
>> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
>>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
>>>> 25.02.2022 13:49, Sascha Hauer пишет:
>>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>>>>> named "hclk" in the downstream driver, so use the same name.
>>>>>>>
>>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>>>>> ---
>>>>>>>
>>>>>>> Notes:
>>>>>>>      Changes since v5:
>>>>>>>      - Use devm_clk_get_optional rather than devm_clk_get
>>>>>>>
>>>>>>>   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>>>>   1 file changed, 16 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>>>>   	const struct rockchip_hdmi_chip_data *chip_data;
>>>>>>>   	struct clk *ref_clk;
>>>>>>>   	struct clk *grf_clk;
>>>>>>> +	struct clk *hclk_clk;
>>>>>>>   	struct dw_hdmi *hdmi;
>>>>>>>   	struct regulator *avdd_0v9;
>>>>>>>   	struct regulator *avdd_1v8;
>>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>>>>   		return PTR_ERR(hdmi->grf_clk);
>>>>>>>   	}
>>>>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>>>>
>>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>>>>> only HDMI that needs this clock and then the hardware description
>>>>>> doesn't look correct.
>>>>>
>>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
>>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
>>>>
>>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
>>>> do, then you aren't modeling h/w properly AFAICS.
>>>
>>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
>>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
>>> interface. Usually, if that affected anything other than accessing VOP
>>> registers, indeed it would smell of something being wrong in the clock tree,
>>> but in this case I'd also be suspicious of whether it might have ended up
>>> clocking related GRF registers as well (either directly, or indirectly via
>>> some gate that the clock driver hasn't modelled yet).
>>
>> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
>> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
>> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
>> of that units can't be accessed. However, when I disable HCLK_VOP by
>> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
>> accessing VOP registers hangs, the other units stay functional.
>> So it seems it must be the parent clock which must be enabled. The
>> parent clock is hclk_vo. This clock should be handled as part of the
>> RK3568_PD_VO power domain:
>>
>> 	power-domain@RK3568_PD_VO {
>>                 reg = <RK3568_PD_VO>;
>>                 clocks = <&cru HCLK_VO>,
>>                          <&cru PCLK_VO>,
>>                          <&cru ACLK_VOP_PRE>;
>>                  pm_qos = <&qos_hdcp>,
>>                           <&qos_vop_m0>,
>>                           <&qos_vop_m1>;
>>                  #power-domain-cells = <0>;
>>         };
> 
> Forget this. The clocks in this node are only enabled during enabling or
> disabling the power domain, they are disabled again immediately afterwards.
> 
> OK, I need HCLK_VO to access the HDMI registers. I verified that by
> disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
> HDMI registers become inaccessible then. This means I'll replace
> HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?

The RK3568_PD_VO already has HCLK_VO and the domain should be
auto-enabled before HDMI registers are accessed, hence you should do the
opposite and remove the HCLK_VO/P clock from the HDMI DT, not add it. If
the HCLK_VO clock isn't enabled by the domain driver, then you need to
check why. Or am I missing something?

What about DSI and DP? Don't they depend on RK3568_PD_VO as well?
Sascha Hauer March 1, 2022, 8:37 a.m. UTC | #10
On Tue, Mar 01, 2022 at 01:56:59AM +0300, Dmitry Osipenko wrote:
> On 2/28/22 17:19, Sascha Hauer wrote:
> > On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
> >> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
> >>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
> >>>> 25.02.2022 13:49, Sascha Hauer пишет:
> >>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> >>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
> >>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
> >>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
> >>>>>>> named "hclk" in the downstream driver, so use the same name.
> >>>>>>>
> >>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> >>>>>>> ---
> >>>>>>>
> >>>>>>> Notes:
> >>>>>>>      Changes since v5:
> >>>>>>>      - Use devm_clk_get_optional rather than devm_clk_get
> >>>>>>>
> >>>>>>>   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
> >>>>>>>   1 file changed, 16 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
> >>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> >>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> >>>>>>>   	const struct rockchip_hdmi_chip_data *chip_data;
> >>>>>>>   	struct clk *ref_clk;
> >>>>>>>   	struct clk *grf_clk;
> >>>>>>> +	struct clk *hclk_clk;
> >>>>>>>   	struct dw_hdmi *hdmi;
> >>>>>>>   	struct regulator *avdd_0v9;
> >>>>>>>   	struct regulator *avdd_1v8;
> >>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
> >>>>>>>   		return PTR_ERR(hdmi->grf_clk);
> >>>>>>>   	}
> >>>>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> >>>>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> >>>>>>
> >>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
> >>>>>> only HDMI that needs this clock and then the hardware description
> >>>>>> doesn't look correct.
> >>>>>
> >>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
> >>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
> >>>>
> >>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
> >>>> do, then you aren't modeling h/w properly AFAICS.
> >>>
> >>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
> >>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
> >>> interface. Usually, if that affected anything other than accessing VOP
> >>> registers, indeed it would smell of something being wrong in the clock tree,
> >>> but in this case I'd also be suspicious of whether it might have ended up
> >>> clocking related GRF registers as well (either directly, or indirectly via
> >>> some gate that the clock driver hasn't modelled yet).
> >>
> >> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
> >> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
> >> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
> >> of that units can't be accessed. However, when I disable HCLK_VOP by
> >> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
> >> accessing VOP registers hangs, the other units stay functional.
> >> So it seems it must be the parent clock which must be enabled. The
> >> parent clock is hclk_vo. This clock should be handled as part of the
> >> RK3568_PD_VO power domain:
> >>
> >> 	power-domain@RK3568_PD_VO {
> >>                 reg = <RK3568_PD_VO>;
> >>                 clocks = <&cru HCLK_VO>,
> >>                          <&cru PCLK_VO>,
> >>                          <&cru ACLK_VOP_PRE>;
> >>                  pm_qos = <&qos_hdcp>,
> >>                           <&qos_vop_m0>,
> >>                           <&qos_vop_m1>;
> >>                  #power-domain-cells = <0>;
> >>         };
> > 
> > Forget this. The clocks in this node are only enabled during enabling or
> > disabling the power domain, they are disabled again immediately afterwards.
> > 
> > OK, I need HCLK_VO to access the HDMI registers. I verified that by
> > disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
> > HDMI registers become inaccessible then. This means I'll replace
> > HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
> 
> The RK3568_PD_VO already has HCLK_VO and the domain should be
> auto-enabled before HDMI registers are accessed,

As said, the clocks given in the power domain are only enabled during
the process of enabling/disabling the power domain and are disabled
again directly afterwards:

> 	if (rockchip_pmu_domain_is_on(pd) != power_on) {

They are enabled here:

> 		ret = clk_bulk_enable(pd->num_clks, pd->clks);
> 		if (ret < 0) {
> 			dev_err(pmu->dev, "failed to enable clocks\n");
> 			mutex_unlock(&pmu->mutex);
> 			return ret;
> 		}
> 
> 		if (!power_on) {
> 			rockchip_pmu_save_qos(pd);
> 
> 			/* if powering down, idle request to NIU first */
> 			rockchip_pmu_set_idle_request(pd, true);
> 		}
>

Then the power domain is switched:

> 		rockchip_do_pmu_set_power_domain(pd, power_on);
> 
> 		if (power_on) {
> 			/* if powering up, leave idle mode */
> 			rockchip_pmu_set_idle_request(pd, false);
> 
> 			rockchip_pmu_restore_qos(pd);
> 		}
> 

And here the clocks are disabled again:

> 		clk_bulk_disable(pd->num_clks, pd->clks);
> 	}

> hence you should do the
> opposite and remove the HCLK_VO/P clock from the HDMI DT, not add it. If
> the HCLK_VO clock isn't enabled by the domain driver, then you need to
> check why. Or am I missing something?

What the power domain driver additionally does is: It does a of_clk_get()
on all the clocks found in the node of a power domains consumer. It then
does a pm_clk_add_clk() on the clocks and sets the GENPD_FLAG_PM_CLK
flag. This has the effect that all clocks of a device in a power domain
are enabled as long as the power domain itself is enabled. This means
when I just add HCLK_VO to the DSI node, then the power domain driver
will enable it, even when the clock is not touched in the DSI driver at
all. To me this looks really fishy because I think a device itself
should have control over its clocks. I don't know how many devices
really depend on the power domain driver controlling their clocks, but
everyone of them will stop working when the power domain driver is not
compiled in.

> 
> What about DSI and DP? Don't they depend on RK3568_PD_VO as well?

Yes, they depend on that power domain as well.

Sascha
Dmitry Osipenko March 1, 2022, 1:22 p.m. UTC | #11
On 3/1/22 11:37, Sascha Hauer wrote:
> On Tue, Mar 01, 2022 at 01:56:59AM +0300, Dmitry Osipenko wrote:
>> On 2/28/22 17:19, Sascha Hauer wrote:
>>> On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
>>>> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
>>>>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
>>>>>> 25.02.2022 13:49, Sascha Hauer пишет:
>>>>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>>>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>>>>>>> named "hclk" in the downstream driver, so use the same name.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>> Notes:
>>>>>>>>>      Changes since v5:
>>>>>>>>>      - Use devm_clk_get_optional rather than devm_clk_get
>>>>>>>>>
>>>>>>>>>   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>>>>>>   1 file changed, 16 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>>>>>>   	const struct rockchip_hdmi_chip_data *chip_data;
>>>>>>>>>   	struct clk *ref_clk;
>>>>>>>>>   	struct clk *grf_clk;
>>>>>>>>> +	struct clk *hclk_clk;
>>>>>>>>>   	struct dw_hdmi *hdmi;
>>>>>>>>>   	struct regulator *avdd_0v9;
>>>>>>>>>   	struct regulator *avdd_1v8;
>>>>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>>>>>>   		return PTR_ERR(hdmi->grf_clk);
>>>>>>>>>   	}
>>>>>>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>>>>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>>>>>>
>>>>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>>>>>>> only HDMI that needs this clock and then the hardware description
>>>>>>>> doesn't look correct.
>>>>>>>
>>>>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
>>>>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
>>>>>>
>>>>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
>>>>>> do, then you aren't modeling h/w properly AFAICS.
>>>>>
>>>>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
>>>>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
>>>>> interface. Usually, if that affected anything other than accessing VOP
>>>>> registers, indeed it would smell of something being wrong in the clock tree,
>>>>> but in this case I'd also be suspicious of whether it might have ended up
>>>>> clocking related GRF registers as well (either directly, or indirectly via
>>>>> some gate that the clock driver hasn't modelled yet).
>>>>
>>>> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
>>>> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
>>>> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
>>>> of that units can't be accessed. However, when I disable HCLK_VOP by
>>>> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
>>>> accessing VOP registers hangs, the other units stay functional.
>>>> So it seems it must be the parent clock which must be enabled. The
>>>> parent clock is hclk_vo. This clock should be handled as part of the
>>>> RK3568_PD_VO power domain:
>>>>
>>>> 	power-domain@RK3568_PD_VO {
>>>>                 reg = <RK3568_PD_VO>;
>>>>                 clocks = <&cru HCLK_VO>,
>>>>                          <&cru PCLK_VO>,
>>>>                          <&cru ACLK_VOP_PRE>;
>>>>                  pm_qos = <&qos_hdcp>,
>>>>                           <&qos_vop_m0>,
>>>>                           <&qos_vop_m1>;
>>>>                  #power-domain-cells = <0>;
>>>>         };
>>>
>>> Forget this. The clocks in this node are only enabled during enabling or
>>> disabling the power domain, they are disabled again immediately afterwards.
>>>
>>> OK, I need HCLK_VO to access the HDMI registers. I verified that by
>>> disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
>>> HDMI registers become inaccessible then. This means I'll replace
>>> HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
>>
>> The RK3568_PD_VO already has HCLK_VO and the domain should be
>> auto-enabled before HDMI registers are accessed,
> 
> As said, the clocks given in the power domain are only enabled during
> the process of enabling/disabling the power domain and are disabled
> again directly afterwards:
> 
>> 	if (rockchip_pmu_domain_is_on(pd) != power_on) {
> 
> They are enabled here:
> 
>> 		ret = clk_bulk_enable(pd->num_clks, pd->clks);
>> 		if (ret < 0) {
>> 			dev_err(pmu->dev, "failed to enable clocks\n");
>> 			mutex_unlock(&pmu->mutex);
>> 			return ret;
>> 		}
>>
>> 		if (!power_on) {
>> 			rockchip_pmu_save_qos(pd);
>>
>> 			/* if powering down, idle request to NIU first */
>> 			rockchip_pmu_set_idle_request(pd, true);
>> 		}
>>
> 
> Then the power domain is switched:
> 
>> 		rockchip_do_pmu_set_power_domain(pd, power_on);
>>
>> 		if (power_on) {
>> 			/* if powering up, leave idle mode */
>> 			rockchip_pmu_set_idle_request(pd, false);
>>
>> 			rockchip_pmu_restore_qos(pd);
>> 		}
>>
> 
> And here the clocks are disabled again:
> 
>> 		clk_bulk_disable(pd->num_clks, pd->clks);
>> 	}
> 
>> hence you should do the
>> opposite and remove the HCLK_VO/P clock from the HDMI DT, not add it. If
>> the HCLK_VO clock isn't enabled by the domain driver, then you need to
>> check why. Or am I missing something?
> 
> What the power domain driver additionally does is: It does a of_clk_get()
> on all the clocks found in the node of a power domains consumer. It then
> does a pm_clk_add_clk() on the clocks and sets the GENPD_FLAG_PM_CLK
> flag. This has the effect that all clocks of a device in a power domain
> are enabled as long as the power domain itself is enabled. This means
> when I just add HCLK_VO to the DSI node, then the power domain driver
> will enable it, even when the clock is not touched in the DSI driver at
> all. To me this looks really fishy because I think a device itself
> should have control over its clocks. I don't know how many devices
> really depend on the power domain driver controlling their clocks, but
> everyone of them will stop working when the power domain driver is not
> compiled in.

This is a correct behaviour of the GENPD driver. Thank you for the
clarification, I completely forgot that clocks should be kept disabled
by GENPD after power-on.

Now I see why you want to add HCLK_VO to the HDMI node, it's good to me
to add the HCLK_VO to the HDMI node. You may copy this clarification to
the commit message of the HDMI DT patch in v8.

I think it's okay that PD driver uses pm_clk_add_clk(). Shouldn't be a
problem to change that later on if some specific driver will want to
have an explicit control over clocks.

But yes, CONFIG_ROCKCHIP_PM_DOMAINS must be enabled (auto-selected?). Is
ARCH_ROCKCHIP available on ARM64 at all?

>> What about DSI and DP? Don't they depend on RK3568_PD_VO as well?
> 
> Yes, they depend on that power domain as well.

So DSI/DP bindings will require a similar HCLK_VO change. You're not
using DP/DSI in this patchset, hence should be okay to postpone the
DSI/DP changes if you don't want to touch them for now.

Seems nothing holds back you now from making the v8.
Robin Murphy March 1, 2022, 1:39 p.m. UTC | #12
On 2022-02-28 14:19, Sascha Hauer wrote:
> On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
>> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
>>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
>>>> 25.02.2022 13:49, Sascha Hauer пишет:
>>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>>>>> named "hclk" in the downstream driver, so use the same name.
>>>>>>>
>>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>>>>> ---
>>>>>>>
>>>>>>> Notes:
>>>>>>>       Changes since v5:
>>>>>>>       - Use devm_clk_get_optional rather than devm_clk_get
>>>>>>>
>>>>>>>    drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>>>>    1 file changed, 16 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>>>>    	const struct rockchip_hdmi_chip_data *chip_data;
>>>>>>>    	struct clk *ref_clk;
>>>>>>>    	struct clk *grf_clk;
>>>>>>> +	struct clk *hclk_clk;
>>>>>>>    	struct dw_hdmi *hdmi;
>>>>>>>    	struct regulator *avdd_0v9;
>>>>>>>    	struct regulator *avdd_1v8;
>>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>>>>    		return PTR_ERR(hdmi->grf_clk);
>>>>>>>    	}
>>>>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>>>>
>>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>>>>> only HDMI that needs this clock and then the hardware description
>>>>>> doesn't look correct.
>>>>>
>>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
>>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
>>>>
>>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
>>>> do, then you aren't modeling h/w properly AFAICS.
>>>
>>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
>>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
>>> interface. Usually, if that affected anything other than accessing VOP
>>> registers, indeed it would smell of something being wrong in the clock tree,
>>> but in this case I'd also be suspicious of whether it might have ended up
>>> clocking related GRF registers as well (either directly, or indirectly via
>>> some gate that the clock driver hasn't modelled yet).
>>
>> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
>> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
>> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
>> of that units can't be accessed. However, when I disable HCLK_VOP by
>> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
>> accessing VOP registers hangs, the other units stay functional.
>> So it seems it must be the parent clock which must be enabled. The
>> parent clock is hclk_vo. This clock should be handled as part of the
>> RK3568_PD_VO power domain:
>>
>> 	power-domain@RK3568_PD_VO {
>>                  reg = <RK3568_PD_VO>;
>>                  clocks = <&cru HCLK_VO>,
>>                           <&cru PCLK_VO>,
>>                           <&cru ACLK_VOP_PRE>;
>>                   pm_qos = <&qos_hdcp>,
>>                            <&qos_vop_m0>,
>>                            <&qos_vop_m1>;
>>                   #power-domain-cells = <0>;
>>          };
> 
> Forget this. The clocks in this node are only enabled during enabling or
> disabling the power domain, they are disabled again immediately afterwards.
> 
> OK, I need HCLK_VO to access the HDMI registers. I verified that by
> disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
> HDMI registers become inaccessible then. This means I'll replace
> HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?

Well, it's still a mystery hack overall, and in some ways it seems even 
more suspect to be claiming a whole branch of the clock tree rather than 
a leaf gate with a specific purpose. I'm really starting to think that 
the underlying issue here is a bug in the clock driver, or a hardware 
mishap that should logically be worked around by the clock driver, 
rather than individual the consumers.

Does it work if you hack the clock driver to think that PCLK_VO is a 
child of HCLK_VO? Even if that's not technically true, it would seem to 
effectively match the observed behaviour (i.e. all 3 things whose 
register access apparently *should* be enabled by a gate off PCLK_VO, 
seem to also require HCLK_VO).

Thanks,
Robin.
Sascha Hauer March 2, 2022, 11:25 a.m. UTC | #13
On Tue, Mar 01, 2022 at 01:39:31PM +0000, Robin Murphy wrote:
> On 2022-02-28 14:19, Sascha Hauer wrote:
> > On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
> > > On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
> > > > On 2022-02-25 11:10, Dmitry Osipenko wrote:
> > > > > 25.02.2022 13:49, Sascha Hauer пишет:
> > > > > > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> > > > > > > 25.02.2022 10:51, Sascha Hauer пишет:
> > > > > > > > The rk3568 HDMI has an additional clock that needs to be enabled for the
> > > > > > > > HDMI controller to work. The purpose of that clock is not clear. It is
> > > > > > > > named "hclk" in the downstream driver, so use the same name.
> > > > > > > > 
> > > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > > > > > ---
> > > > > > > > 
> > > > > > > > Notes:
> > > > > > > >       Changes since v5:
> > > > > > > >       - Use devm_clk_get_optional rather than devm_clk_get
> > > > > > > > 
> > > > > > > >    drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
> > > > > > > >    1 file changed, 16 insertions(+)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > index fe4f9556239ac..c6c00e8779ab5 100644
> > > > > > > > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> > > > > > > >    	const struct rockchip_hdmi_chip_data *chip_data;
> > > > > > > >    	struct clk *ref_clk;
> > > > > > > >    	struct clk *grf_clk;
> > > > > > > > +	struct clk *hclk_clk;
> > > > > > > >    	struct dw_hdmi *hdmi;
> > > > > > > >    	struct regulator *avdd_0v9;
> > > > > > > >    	struct regulator *avdd_1v8;
> > > > > > > > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
> > > > > > > >    		return PTR_ERR(hdmi->grf_clk);
> > > > > > > >    	}
> > > > > > > > +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> > > > > > > > +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> > > > > > > 
> > > > > > > Have you tried to investigate the hclk? I'm still thinking that's not
> > > > > > > only HDMI that needs this clock and then the hardware description
> > > > > > > doesn't look correct.
> > > > > > 
> > > > > > I am still not sure what you mean. Yes, it's not only the HDMI that
> > > > > > needs this clock. The VOP2 needs it as well and the driver handles that.
> > > > > 
> > > > > I'm curious whether DSI/DP also need that clock to be enabled. If they
> > > > > do, then you aren't modeling h/w properly AFAICS.
> > > > 
> > > > Assuming nobody at Rockchip decided to make things needlessly inconsistent
> > > > with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
> > > > interface. Usually, if that affected anything other than accessing VOP
> > > > registers, indeed it would smell of something being wrong in the clock tree,
> > > > but in this case I'd also be suspicious of whether it might have ended up
> > > > clocking related GRF registers as well (either directly, or indirectly via
> > > > some gate that the clock driver hasn't modelled yet).
> > > 
> > > Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
> > > hanging when HCLK_VOP is disabled by disabling that clock via sysfs
> > > using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
> > > of that units can't be accessed. However, when I disable HCLK_VOP by
> > > directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
> > > accessing VOP registers hangs, the other units stay functional.
> > > So it seems it must be the parent clock which must be enabled. The
> > > parent clock is hclk_vo. This clock should be handled as part of the
> > > RK3568_PD_VO power domain:
> > > 
> > > 	power-domain@RK3568_PD_VO {
> > >                  reg = <RK3568_PD_VO>;
> > >                  clocks = <&cru HCLK_VO>,
> > >                           <&cru PCLK_VO>,
> > >                           <&cru ACLK_VOP_PRE>;
> > >                   pm_qos = <&qos_hdcp>,
> > >                            <&qos_vop_m0>,
> > >                            <&qos_vop_m1>;
> > >                   #power-domain-cells = <0>;
> > >          };
> > 
> > Forget this. The clocks in this node are only enabled during enabling or
> > disabling the power domain, they are disabled again immediately afterwards.
> > 
> > OK, I need HCLK_VO to access the HDMI registers. I verified that by
> > disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
> > HDMI registers become inaccessible then. This means I'll replace
> > HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
> 
> Well, it's still a mystery hack overall, and in some ways it seems even more
> suspect to be claiming a whole branch of the clock tree rather than a leaf
> gate with a specific purpose. I'm really starting to think that the
> underlying issue here is a bug in the clock driver, or a hardware mishap
> that should logically be worked around by the clock driver, rather than
> individual the consumers.
> 
> Does it work if you hack the clock driver to think that PCLK_VO is a child
> of HCLK_VO? Even if that's not technically true, it would seem to
> effectively match the observed behaviour (i.e. all 3 things whose register
> access apparently *should* be enabled by a gate off PCLK_VO, seem to also
> require HCLK_VO).

Yes, that works as expected. I am not sure though if we really want to
go that path. The pclk rates will become completely bogus with this and
should we have to play with the rates in the future we might regret this
step.

Sascha
Sascha Hauer March 4, 2022, 2:22 p.m. UTC | #14
On Wed, Mar 02, 2022 at 12:25:28PM +0100, Sascha Hauer wrote:
> On Tue, Mar 01, 2022 at 01:39:31PM +0000, Robin Murphy wrote:
> > On 2022-02-28 14:19, Sascha Hauer wrote:
> > > On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
> > > > On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
> > > > > On 2022-02-25 11:10, Dmitry Osipenko wrote:
> > > > > > 25.02.2022 13:49, Sascha Hauer пишет:
> > > > > > > On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
> > > > > > > > 25.02.2022 10:51, Sascha Hauer пишет:
> > > > > > > > > The rk3568 HDMI has an additional clock that needs to be enabled for the
> > > > > > > > > HDMI controller to work. The purpose of that clock is not clear. It is
> > > > > > > > > named "hclk" in the downstream driver, so use the same name.
> > > > > > > > > 
> > > > > > > > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > > > > > > > ---
> > > > > > > > > 
> > > > > > > > > Notes:
> > > > > > > > >       Changes since v5:
> > > > > > > > >       - Use devm_clk_get_optional rather than devm_clk_get
> > > > > > > > > 
> > > > > > > > >    drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
> > > > > > > > >    1 file changed, 16 insertions(+)
> > > > > > > > > 
> > > > > > > > > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > > index fe4f9556239ac..c6c00e8779ab5 100644
> > > > > > > > > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > > > > > > > > @@ -76,6 +76,7 @@ struct rockchip_hdmi {
> > > > > > > > >    	const struct rockchip_hdmi_chip_data *chip_data;
> > > > > > > > >    	struct clk *ref_clk;
> > > > > > > > >    	struct clk *grf_clk;
> > > > > > > > > +	struct clk *hclk_clk;
> > > > > > > > >    	struct dw_hdmi *hdmi;
> > > > > > > > >    	struct regulator *avdd_0v9;
> > > > > > > > >    	struct regulator *avdd_1v8;
> > > > > > > > > @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
> > > > > > > > >    		return PTR_ERR(hdmi->grf_clk);
> > > > > > > > >    	}
> > > > > > > > > +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
> > > > > > > > > +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
> > > > > > > > 
> > > > > > > > Have you tried to investigate the hclk? I'm still thinking that's not
> > > > > > > > only HDMI that needs this clock and then the hardware description
> > > > > > > > doesn't look correct.
> > > > > > > 
> > > > > > > I am still not sure what you mean. Yes, it's not only the HDMI that
> > > > > > > needs this clock. The VOP2 needs it as well and the driver handles that.
> > > > > > 
> > > > > > I'm curious whether DSI/DP also need that clock to be enabled. If they
> > > > > > do, then you aren't modeling h/w properly AFAICS.
> > > > > 
> > > > > Assuming nobody at Rockchip decided to make things needlessly inconsistent
> > > > > with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
> > > > > interface. Usually, if that affected anything other than accessing VOP
> > > > > registers, indeed it would smell of something being wrong in the clock tree,
> > > > > but in this case I'd also be suspicious of whether it might have ended up
> > > > > clocking related GRF registers as well (either directly, or indirectly via
> > > > > some gate that the clock driver hasn't modelled yet).
> > > > 
> > > > Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
> > > > hanging when HCLK_VOP is disabled by disabling that clock via sysfs
> > > > using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
> > > > of that units can't be accessed. However, when I disable HCLK_VOP by
> > > > directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
> > > > accessing VOP registers hangs, the other units stay functional.
> > > > So it seems it must be the parent clock which must be enabled. The
> > > > parent clock is hclk_vo. This clock should be handled as part of the
> > > > RK3568_PD_VO power domain:
> > > > 
> > > > 	power-domain@RK3568_PD_VO {
> > > >                  reg = <RK3568_PD_VO>;
> > > >                  clocks = <&cru HCLK_VO>,
> > > >                           <&cru PCLK_VO>,
> > > >                           <&cru ACLK_VOP_PRE>;
> > > >                   pm_qos = <&qos_hdcp>,
> > > >                            <&qos_vop_m0>,
> > > >                            <&qos_vop_m1>;
> > > >                   #power-domain-cells = <0>;
> > > >          };
> > > 
> > > Forget this. The clocks in this node are only enabled during enabling or
> > > disabling the power domain, they are disabled again immediately afterwards.
> > > 
> > > OK, I need HCLK_VO to access the HDMI registers. I verified that by
> > > disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
> > > HDMI registers become inaccessible then. This means I'll replace
> > > HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
> > 
> > Well, it's still a mystery hack overall, and in some ways it seems even more
> > suspect to be claiming a whole branch of the clock tree rather than a leaf
> > gate with a specific purpose. I'm really starting to think that the
> > underlying issue here is a bug in the clock driver, or a hardware mishap
> > that should logically be worked around by the clock driver, rather than
> > individual the consumers.
> > 
> > Does it work if you hack the clock driver to think that PCLK_VO is a child
> > of HCLK_VO? Even if that's not technically true, it would seem to
> > effectively match the observed behaviour (i.e. all 3 things whose register
> > access apparently *should* be enabled by a gate off PCLK_VO, seem to also
> > require HCLK_VO).
> 
> Yes, that works as expected. I am not sure though if we really want to
> go that path. The pclk rates will become completely bogus with this and
> should we have to play with the rates in the future we might regret this
> step.

How do we proceed here? I can include a patch which makes PCLK_VO a
child of HCLK_VO if that's what we agree upon.

Sascha
Dmitry Osipenko March 4, 2022, 11:55 p.m. UTC | #15
On 3/4/22 17:22, Sascha Hauer wrote:
> On Wed, Mar 02, 2022 at 12:25:28PM +0100, Sascha Hauer wrote:
>> On Tue, Mar 01, 2022 at 01:39:31PM +0000, Robin Murphy wrote:
>>> On 2022-02-28 14:19, Sascha Hauer wrote:
>>>> On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
>>>>> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
>>>>>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
>>>>>>> 25.02.2022 13:49, Sascha Hauer пишет:
>>>>>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>>>>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>>>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>>>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>>>>>>>> named "hclk" in the downstream driver, so use the same name.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>>>>>>>> ---
>>>>>>>>>>
>>>>>>>>>> Notes:
>>>>>>>>>>       Changes since v5:
>>>>>>>>>>       - Use devm_clk_get_optional rather than devm_clk_get
>>>>>>>>>>
>>>>>>>>>>    drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>>>>>>>    1 file changed, 16 insertions(+)
>>>>>>>>>>
>>>>>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>>>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>>>>>>>    	const struct rockchip_hdmi_chip_data *chip_data;
>>>>>>>>>>    	struct clk *ref_clk;
>>>>>>>>>>    	struct clk *grf_clk;
>>>>>>>>>> +	struct clk *hclk_clk;
>>>>>>>>>>    	struct dw_hdmi *hdmi;
>>>>>>>>>>    	struct regulator *avdd_0v9;
>>>>>>>>>>    	struct regulator *avdd_1v8;
>>>>>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>>>>>>>    		return PTR_ERR(hdmi->grf_clk);
>>>>>>>>>>    	}
>>>>>>>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>>>>>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>>>>>>>
>>>>>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>>>>>>>> only HDMI that needs this clock and then the hardware description
>>>>>>>>> doesn't look correct.
>>>>>>>>
>>>>>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
>>>>>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
>>>>>>>
>>>>>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
>>>>>>> do, then you aren't modeling h/w properly AFAICS.
>>>>>>
>>>>>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
>>>>>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
>>>>>> interface. Usually, if that affected anything other than accessing VOP
>>>>>> registers, indeed it would smell of something being wrong in the clock tree,
>>>>>> but in this case I'd also be suspicious of whether it might have ended up
>>>>>> clocking related GRF registers as well (either directly, or indirectly via
>>>>>> some gate that the clock driver hasn't modelled yet).
>>>>>
>>>>> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
>>>>> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
>>>>> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
>>>>> of that units can't be accessed. However, when I disable HCLK_VOP by
>>>>> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
>>>>> accessing VOP registers hangs, the other units stay functional.
>>>>> So it seems it must be the parent clock which must be enabled. The
>>>>> parent clock is hclk_vo. This clock should be handled as part of the
>>>>> RK3568_PD_VO power domain:
>>>>>
>>>>> 	power-domain@RK3568_PD_VO {
>>>>>                  reg = <RK3568_PD_VO>;
>>>>>                  clocks = <&cru HCLK_VO>,
>>>>>                           <&cru PCLK_VO>,
>>>>>                           <&cru ACLK_VOP_PRE>;
>>>>>                   pm_qos = <&qos_hdcp>,
>>>>>                            <&qos_vop_m0>,
>>>>>                            <&qos_vop_m1>;
>>>>>                   #power-domain-cells = <0>;
>>>>>          };
>>>>
>>>> Forget this. The clocks in this node are only enabled during enabling or
>>>> disabling the power domain, they are disabled again immediately afterwards.
>>>>
>>>> OK, I need HCLK_VO to access the HDMI registers. I verified that by
>>>> disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
>>>> HDMI registers become inaccessible then. This means I'll replace
>>>> HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
>>>
>>> Well, it's still a mystery hack overall, and in some ways it seems even more
>>> suspect to be claiming a whole branch of the clock tree rather than a leaf
>>> gate with a specific purpose. I'm really starting to think that the
>>> underlying issue here is a bug in the clock driver, or a hardware mishap
>>> that should logically be worked around by the clock driver, rather than
>>> individual the consumers.
>>>
>>> Does it work if you hack the clock driver to think that PCLK_VO is a child
>>> of HCLK_VO? Even if that's not technically true, it would seem to
>>> effectively match the observed behaviour (i.e. all 3 things whose register
>>> access apparently *should* be enabled by a gate off PCLK_VO, seem to also
>>> require HCLK_VO).
>>
>> Yes, that works as expected. I am not sure though if we really want to
>> go that path. The pclk rates will become completely bogus with this and
>> should we have to play with the rates in the future we might regret this
>> step.
> 
> How do we proceed here? I can include a patch which makes PCLK_VO a
> child of HCLK_VO if that's what we agree upon.

Couldn't Andy clarify the actual clock tree structure of the h/w for us?

This will be the best option because datasheet doesn't give the clear
answer, or at least I couldn't find it. Technically, PCLK indeed should
be a child of the HCLK in general, so Robin could be right.
Andy Yan March 8, 2022, 3:31 a.m. UTC | #16
Hi :

On 3/5/22 07:55, Dmitry Osipenko wrote:
> On 3/4/22 17:22, Sascha Hauer wrote:
>> On Wed, Mar 02, 2022 at 12:25:28PM +0100, Sascha Hauer wrote:
>>> On Tue, Mar 01, 2022 at 01:39:31PM +0000, Robin Murphy wrote:
>>>> On 2022-02-28 14:19, Sascha Hauer wrote:
>>>>> On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
>>>>>> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
>>>>>>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
>>>>>>>> 25.02.2022 13:49, Sascha Hauer пишет:
>>>>>>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>>>>>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>>>>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>>>>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>>>>>>>>> named "hclk" in the downstream driver, so use the same name.
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>>>>>>>>> ---
>>>>>>>>>>>
>>>>>>>>>>> Notes:
>>>>>>>>>>>        Changes since v5:
>>>>>>>>>>>        - Use devm_clk_get_optional rather than devm_clk_get
>>>>>>>>>>>
>>>>>>>>>>>     drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>>>>>>>>     1 file changed, 16 insertions(+)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>>>>>>>>     	const struct rockchip_hdmi_chip_data *chip_data;
>>>>>>>>>>>     	struct clk *ref_clk;
>>>>>>>>>>>     	struct clk *grf_clk;
>>>>>>>>>>> +	struct clk *hclk_clk;
>>>>>>>>>>>     	struct dw_hdmi *hdmi;
>>>>>>>>>>>     	struct regulator *avdd_0v9;
>>>>>>>>>>>     	struct regulator *avdd_1v8;
>>>>>>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>>>>>>>>     		return PTR_ERR(hdmi->grf_clk);
>>>>>>>>>>>     	}
>>>>>>>>>>> +	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>>>>>>>>> +	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>>>>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>>>>>>>>> only HDMI that needs this clock and then the hardware description
>>>>>>>>>> doesn't look correct.
>>>>>>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
>>>>>>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
>>>>>>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
>>>>>>>> do, then you aren't modeling h/w properly AFAICS.
>>>>>>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
>>>>>>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
>>>>>>> interface. Usually, if that affected anything other than accessing VOP
>>>>>>> registers, indeed it would smell of something being wrong in the clock tree,
>>>>>>> but in this case I'd also be suspicious of whether it might have ended up
>>>>>>> clocking related GRF registers as well (either directly, or indirectly via
>>>>>>> some gate that the clock driver hasn't modelled yet).
>>>>>> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
>>>>>> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
>>>>>> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
>>>>>> of that units can't be accessed. However, when I disable HCLK_VOP by
>>>>>> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
>>>>>> accessing VOP registers hangs, the other units stay functional.
>>>>>> So it seems it must be the parent clock which must be enabled. The
>>>>>> parent clock is hclk_vo. This clock should be handled as part of the
>>>>>> RK3568_PD_VO power domain:
>>>>>>
>>>>>> 	power-domain@RK3568_PD_VO {
>>>>>>                   reg = <RK3568_PD_VO>;
>>>>>>                   clocks = <&cru HCLK_VO>,
>>>>>>                            <&cru PCLK_VO>,
>>>>>>                            <&cru ACLK_VOP_PRE>;
>>>>>>                    pm_qos = <&qos_hdcp>,
>>>>>>                             <&qos_vop_m0>,
>>>>>>                             <&qos_vop_m1>;
>>>>>>                    #power-domain-cells = <0>;
>>>>>>           };
>>>>> Forget this. The clocks in this node are only enabled during enabling or
>>>>> disabling the power domain, they are disabled again immediately afterwards.
>>>>>
>>>>> OK, I need HCLK_VO to access the HDMI registers. I verified that by
>>>>> disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
>>>>> HDMI registers become inaccessible then. This means I'll replace
>>>>> HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
>>>> Well, it's still a mystery hack overall, and in some ways it seems even more
>>>> suspect to be claiming a whole branch of the clock tree rather than a leaf
>>>> gate with a specific purpose. I'm really starting to think that the
>>>> underlying issue here is a bug in the clock driver, or a hardware mishap
>>>> that should logically be worked around by the clock driver, rather than
>>>> individual the consumers.
>>>>
>>>> Does it work if you hack the clock driver to think that PCLK_VO is a child
>>>> of HCLK_VO? Even if that's not technically true, it would seem to
>>>> effectively match the observed behaviour (i.e. all 3 things whose register
>>>> access apparently *should* be enabled by a gate off PCLK_VO, seem to also
>>>> require HCLK_VO).
>>> Yes, that works as expected. I am not sure though if we really want to
>>> go that path. The pclk rates will become completely bogus with this and
>>> should we have to play with the rates in the future we might regret this
>>> step.
>> How do we proceed here? I can include a patch which makes PCLK_VO a
>> child of HCLK_VO if that's what we agree upon.
> Couldn't Andy clarify the actual clock tree structure of the h/w for us?
>
> This will be the best option because datasheet doesn't give the clear
> answer, or at least I couldn't find it. Technically, PCLK indeed should
> be a child of the HCLK in general, so Robin could be right.


Add our clk expert Elaine, she will share some information about the 
actual clock structure.


> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
Elaine Zhang March 9, 2022, 1:41 a.m. UTC | #17
hi,all:

Let me explain the clock dependency:
From the clock tree, pclk_vo0 and hclk_vo0 are completely independent clocks with different parent clocks and different clock frequencies。



But the niu path is :
pclk_vo is dependent on hclk_vo, and the pclk_vo niu goes through  hclk_vo niu.

The clock tree and NIU bus paths are designed independently
So there are three solutions to this problem:
1. DTS adds a reference to Hclk while referencing Pclk.
2, The dependent clock is always on, such as HCLK_VO0, but this is not friendly for the system power.
3. Create a non-clock-tree reference. Clk-link, for example, we have an implementation in our internal branch, but Upstream is not sure how to push it.





张晴
瑞芯微电子股份有限公司
Rockchip Electronics Co.,Ltd
地址:福建省福州市铜盘路软件大道89号软件园A区21号楼
Add:No.21 Building, A District, No.89 Software Boulevard Fuzhou, Fujian 350003, P.R.China
Tel:+86-0591-83991906-8601
邮编:350003
E-mail:elaine.zhang@rock-chips.com
****************************************************************************
保密提示:本邮件及其附件含有机密信息,仅发送给本邮件所指特定收件人。若非该特定收件人,请勿复制、使用或披露本邮件的任何内容。若误收本邮件,请从系统中永久性删除本邮件及所有附件,并以回复邮件或其他方式即刻告知发件人。福州瑞芯微电子有限公司拥有本邮件信息的著作权及解释权,禁止任何未经授权许可的侵权行为。
IMPORTANT NOTICE: This email is from Fuzhou Rockchip Electronics Co., Ltd .The contents of this email and any attachments may contain information that is privileged, confidential and/or exempt from disclosure under applicable law and relevant NDA. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information is STRICTLY PROHIBITED. Please immediately contact the sender as soon as possible and destroy the material in its entirety in any format. Thank you.
****************************************************************************
 
From: Andy Yan
Date: 2022-03-08 11:31
To: Dmitry Osipenko; Sascha Hauer; Robin Murphy; elaine.zhang
CC: devicetree; Benjamin Gaignard; kernel; Sandy Huang; dri-devel; linux-rockchip; Michael Riesch; Peter Geis; Dmitry Osipenko; linux-arm-kernel; Kever Yang; algea.cao; huangtao
Subject: Re: [PATCH v7 10/24] drm/rockchip: dw_hdmi: Add support for hclk
Hi :
 
On 3/5/22 07:55, Dmitry Osipenko wrote:
> On 3/4/22 17:22, Sascha Hauer wrote:
>> On Wed, Mar 02, 2022 at 12:25:28PM +0100, Sascha Hauer wrote:
>>> On Tue, Mar 01, 2022 at 01:39:31PM +0000, Robin Murphy wrote:
>>>> On 2022-02-28 14:19, Sascha Hauer wrote:
>>>>> On Fri, Feb 25, 2022 at 02:11:54PM +0100, Sascha Hauer wrote:
>>>>>> On Fri, Feb 25, 2022 at 12:41:23PM +0000, Robin Murphy wrote:
>>>>>>> On 2022-02-25 11:10, Dmitry Osipenko wrote:
>>>>>>>> 25.02.2022 13:49, Sascha Hauer пишет:
>>>>>>>>> On Fri, Feb 25, 2022 at 01:26:14PM +0300, Dmitry Osipenko wrote:
>>>>>>>>>> 25.02.2022 10:51, Sascha Hauer пишет:
>>>>>>>>>>> The rk3568 HDMI has an additional clock that needs to be enabled for the
>>>>>>>>>>> HDMI controller to work. The purpose of that clock is not clear. It is
>>>>>>>>>>> named "hclk" in the downstream driver, so use the same name.
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
>>>>>>>>>>> ---
>>>>>>>>>>>
>>>>>>>>>>> Notes:
>>>>>>>>>>>        Changes since v5:
>>>>>>>>>>>        - Use devm_clk_get_optional rather than devm_clk_get
>>>>>>>>>>>
>>>>>>>>>>>     drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++++++++++++++++
>>>>>>>>>>>     1 file changed, 16 insertions(+)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>>> index fe4f9556239ac..c6c00e8779ab5 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
>>>>>>>>>>> @@ -76,6 +76,7 @@ struct rockchip_hdmi {
>>>>>>>>>>>     const struct rockchip_hdmi_chip_data *chip_data;
>>>>>>>>>>>     struct clk *ref_clk;
>>>>>>>>>>>     struct clk *grf_clk;
>>>>>>>>>>> + struct clk *hclk_clk;
>>>>>>>>>>>     struct dw_hdmi *hdmi;
>>>>>>>>>>>     struct regulator *avdd_0v9;
>>>>>>>>>>>     struct regulator *avdd_1v8;
>>>>>>>>>>> @@ -229,6 +230,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
>>>>>>>>>>>     return PTR_ERR(hdmi->grf_clk);
>>>>>>>>>>>     }
>>>>>>>>>>> + hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
>>>>>>>>>>> + if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
>>>>>>>>>> Have you tried to investigate the hclk? I'm still thinking that's not
>>>>>>>>>> only HDMI that needs this clock and then the hardware description
>>>>>>>>>> doesn't look correct.
>>>>>>>>> I am still not sure what you mean. Yes, it's not only the HDMI that
>>>>>>>>> needs this clock. The VOP2 needs it as well and the driver handles that.
>>>>>>>> I'm curious whether DSI/DP also need that clock to be enabled. If they
>>>>>>>> do, then you aren't modeling h/w properly AFAICS.
>>>>>>> Assuming nobody at Rockchip decided to make things needlessly inconsistent
>>>>>>> with previous SoCs, HCLK_VOP should be the clock for the VOP's AHB slave
>>>>>>> interface. Usually, if that affected anything other than accessing VOP
>>>>>>> registers, indeed it would smell of something being wrong in the clock tree,
>>>>>>> but in this case I'd also be suspicious of whether it might have ended up
>>>>>>> clocking related GRF registers as well (either directly, or indirectly via
>>>>>>> some gate that the clock driver hasn't modelled yet).
>>>>>> Ok, I am beginning to understand. I verified that hdmi, mipi and dp are
>>>>>> hanging when HCLK_VOP is disabled by disabling that clock via sysfs
>>>>>> using CLOCK_ALLOW_WRITE_DEBUGFS. When it's disabled then the registers
>>>>>> of that units can't be accessed. However, when I disable HCLK_VOP by
>>>>>> directly writing to the gate bit RK3568_CLKGATE_CON(20) then only
>>>>>> accessing VOP registers hangs, the other units stay functional.
>>>>>> So it seems it must be the parent clock which must be enabled. The
>>>>>> parent clock is hclk_vo. This clock should be handled as part of the
>>>>>> RK3568_PD_VO power domain:
>>>>>>
>>>>>> power-domain@RK3568_PD_VO {
>>>>>>                   reg = <RK3568_PD_VO>;
>>>>>>                   clocks = <&cru HCLK_VO>,
>>>>>>                            <&cru PCLK_VO>,
>>>>>>                            <&cru ACLK_VOP_PRE>;
>>>>>>                    pm_qos = <&qos_hdcp>,
>>>>>>                             <&qos_vop_m0>,
>>>>>>                             <&qos_vop_m1>;
>>>>>>                    #power-domain-cells = <0>;
>>>>>>           };
>>>>> Forget this. The clocks in this node are only enabled during enabling or
>>>>> disabling the power domain, they are disabled again immediately afterwards.
>>>>>
>>>>> OK, I need HCLK_VO to access the HDMI registers. I verified that by
>>>>> disabling HCLK_VO at register level (CRU_GATE_CON(20) BIT(1)). The
>>>>> HDMI registers become inaccessible then. This means I'll replace
>>>>> HCLK_VOP in the HDMI node with HCLK_VO. Does this sound sane?
>>>> Well, it's still a mystery hack overall, and in some ways it seems even more
>>>> suspect to be claiming a whole branch of the clock tree rather than a leaf
>>>> gate with a specific purpose. I'm really starting to think that the
>>>> underlying issue here is a bug in the clock driver, or a hardware mishap
>>>> that should logically be worked around by the clock driver, rather than
>>>> individual the consumers.
>>>>
>>>> Does it work if you hack the clock driver to think that PCLK_VO is a child
>>>> of HCLK_VO? Even if that's not technically true, it would seem to
>>>> effectively match the observed behaviour (i.e. all 3 things whose register
>>>> access apparently *should* be enabled by a gate off PCLK_VO, seem to also
>>>> require HCLK_VO).
>>> Yes, that works as expected. I am not sure though if we really want to
>>> go that path. The pclk rates will become completely bogus with this and
>>> should we have to play with the rates in the future we might regret this
>>> step.
>> How do we proceed here? I can include a patch which makes PCLK_VO a
>> child of HCLK_VO if that's what we agree upon.
> Couldn't Andy clarify the actual clock tree structure of the h/w for us?
>
> This will be the best option because datasheet doesn't give the clear
> answer, or at least I couldn't find it. Technically, PCLK indeed should
> be a child of the HCLK in general, so Robin could be right.
 
 
Add our clk expert Elaine, she will share some information about the 
actual clock structure.
 
 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
Sascha Hauer March 9, 2022, 8:18 a.m. UTC | #18
Hi Elaine,

On Wed, Mar 09, 2022 at 09:41:39AM +0800, zhangqing@rock-chips.com wrote:
>    hi,all:
>    Let me explain the clock dependency:
>    From the clock tree, pclk_vo0 and hclk_vo0 are completely independent
>    clocks with different parent clocks and different clock frequencies。
>    But the niu path is :
>    pclk_vo is dependent on hclk_vo, and the pclk_vo niu goes through  hclk_vo
>    niu.

Thanks, this is the information we are looking for. What is "NIU" btw?
I think this is even documented in the Reference Manual. With the right
pointer I just found:

> A part of niu clocks have a dependence on another niu clock in order to
> sharing the internal bus. When these clocks are in use, another niu
> clock must be opened, and cannot be gated.  These clocks and the special
> clock on which they are relied are as following:
>
> Clocks which have dependency     The clock which can not be gated
> -----------------------------------------------------------------
> ...
> pclk_vo_niu, hclk_vo_s_niu       hclk_vo_niu
> ...



>    The clock tree and NIU bus paths are designed independently
>    So there are three solutions to this problem:
>    1. DTS adds a reference to Hclk while referencing Pclk.
>    2, The dependent clock is always on, such as HCLK_VO0, but this is not
>    friendly for the system power.
>    3. Create a non-clock-tree reference. Clk-link, for example, we have an
>    implementation in our internal branch, but Upstream is not sure how to
>    push it.

I thought about something similar. That would help us here and on i.MX
we have a similar situation: We have one bit that switches multiple
clocks. That as well cannot be designed properly in the clock framework
currently, but could be modelled with a concept of linked clocks.

Doing this sounds like quite a bit of work and discussion though, I
don't really like having this as a dependency to mainline the VOP2
driver. I vote for 1. in that case, we could still ignore the hclk in
dts later when we have linked clocks.

Sascha
Elaine Zhang March 9, 2022, 8:37 a.m. UTC | #19
hi,


在 2022/3/9 下午4:18, Sascha Hauer 写道:
> Hi Elaine,
>
> On Wed, Mar 09, 2022 at 09:41:39AM +0800, zhangqing@rock-chips.com wrote:
>>     hi,all:
>>     Let me explain the clock dependency:
>>     From the clock tree, pclk_vo0 and hclk_vo0 are completely independent
>>     clocks with different parent clocks and different clock frequencies。
>>     But the niu path is :
>>     pclk_vo is dependent on hclk_vo, and the pclk_vo niu goes through  hclk_vo
>>     niu.
> Thanks, this is the information we are looking for. What is "NIU" btw?
> I think this is even documented in the Reference Manual. With the right
> pointer I just found:

The NIU (native interface unit)

You can see 2.8.6(NIU Clock gating reliance) in TRM.

>
>> A part of niu clocks have a dependence on another niu clock in order to
>> sharing the internal bus. When these clocks are in use, another niu
>> clock must be opened, and cannot be gated.  These clocks and the special
>> clock on which they are relied are as following:
>>
>> Clocks which have dependency     The clock which can not be gated
>> -----------------------------------------------------------------
>> ...
>> pclk_vo_niu, hclk_vo_s_niu       hclk_vo_niu
>> ...

Yeah, the dependency is this.

It may be not very detailed, I don't have permission to publish detailed 
NIU designs.

>
>
>>     The clock tree and NIU bus paths are designed independently
>>     So there are three solutions to this problem:
>>     1. DTS adds a reference to Hclk while referencing Pclk.
>>     2, The dependent clock is always on, such as HCLK_VO0, but this is not
>>     friendly for the system power.
>>     3. Create a non-clock-tree reference. Clk-link, for example, we have an
>>     implementation in our internal branch, but Upstream is not sure how to
>>     push it.
> I thought about something similar. That would help us here and on i.MX
> we have a similar situation: We have one bit that switches multiple
> clocks. That as well cannot be designed properly in the clock framework
> currently, but could be modelled with a concept of linked clocks.
>
> Doing this sounds like quite a bit of work and discussion though, I
> don't really like having this as a dependency to mainline the VOP2
> driver. I vote for 1. in that case, we could still ignore the hclk in
> dts later when we have linked clocks.
>
> Sascha
>
Robin Murphy March 9, 2022, 12:06 p.m. UTC | #20
On 2022-03-09 08:37, elaine.zhang wrote:
> hi,
> 
> 
> 在 2022/3/9 下午4:18, Sascha Hauer 写道:
>> Hi Elaine,
>>
>> On Wed, Mar 09, 2022 at 09:41:39AM +0800, zhangqing@rock-chips.com wrote:
>>>     hi,all:
>>>     Let me explain the clock dependency:
>>>     From the clock tree, pclk_vo0 and hclk_vo0 are completely 
>>> independent
>>>     clocks with different parent clocks and different clock 
>>> frequencies。
>>>     But the niu path is :
>>>     pclk_vo is dependent on hclk_vo, and the pclk_vo niu goes 
>>> through  hclk_vo
>>>     niu.
>> Thanks, this is the information we are looking for. What is "NIU" btw?
>> I think this is even documented in the Reference Manual. With the right
>> pointer I just found:
> 
> The NIU (native interface unit)
> 
> You can see 2.8.6(NIU Clock gating reliance) in TRM.
> 
>>
>>> A part of niu clocks have a dependence on another niu clock in order to
>>> sharing the internal bus. When these clocks are in use, another niu
>>> clock must be opened, and cannot be gated.  These clocks and the special
>>> clock on which they are relied are as following:
>>>
>>> Clocks which have dependency     The clock which can not be gated
>>> -----------------------------------------------------------------
>>> ...
>>> pclk_vo_niu, hclk_vo_s_niu       hclk_vo_niu
>>> ...
> 
> Yeah, the dependency is this.
> 
> It may be not very detailed, I don't have permission to publish detailed 
> NIU designs.
> 
>>
>>
>>>     The clock tree and NIU bus paths are designed independently
>>>     So there are three solutions to this problem:
>>>     1. DTS adds a reference to Hclk while referencing Pclk.
>>>     2, The dependent clock is always on, such as HCLK_VO0, but this 
>>> is not
>>>     friendly for the system power.
>>>     3. Create a non-clock-tree reference. Clk-link, for example, we 
>>> have an
>>>     implementation in our internal branch, but Upstream is not sure 
>>> how to
>>>     push it.
>> I thought about something similar. That would help us here and on i.MX
>> we have a similar situation: We have one bit that switches multiple
>> clocks. That as well cannot be designed properly in the clock framework
>> currently, but could be modelled with a concept of linked clocks.
>>
>> Doing this sounds like quite a bit of work and discussion though, I
>> don't really like having this as a dependency to mainline the VOP2
>> driver. I vote for 1. in that case, we could still ignore the hclk in
>> dts later when we have linked clocks.

OK so just to clarify, the issue is not just that the upstream clock 
driver doesn't currently model the NIU clocks, but that even if it did, 
it would still need to implement some new multi-parent clock type to 
manage the internal dependency? That's fair enough - I do think that 
improving the clock driver would be the best long-term goal, but for the 
scope of this series, having an interim workaround does seem more 
reasonable now that we understand *why* we need it.

Thanks,
Robin.
diff mbox series

Patch

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index fe4f9556239ac..c6c00e8779ab5 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -76,6 +76,7 @@  struct rockchip_hdmi {
 	const struct rockchip_hdmi_chip_data *chip_data;
 	struct clk *ref_clk;
 	struct clk *grf_clk;
+	struct clk *hclk_clk;
 	struct dw_hdmi *hdmi;
 	struct regulator *avdd_0v9;
 	struct regulator *avdd_1v8;
@@ -229,6 +230,14 @@  static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 		return PTR_ERR(hdmi->grf_clk);
 	}
 
+	hdmi->hclk_clk = devm_clk_get_optional(hdmi->dev, "hclk");
+	if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
+		return -EPROBE_DEFER;
+	} else if (IS_ERR(hdmi->hclk_clk)) {
+		DRM_DEV_ERROR(hdmi->dev, "failed to get hclk_clk clock\n");
+		return PTR_ERR(hdmi->hclk_clk);
+	}
+
 	hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9");
 	if (IS_ERR(hdmi->avdd_0v9))
 		return PTR_ERR(hdmi->avdd_0v9);
@@ -596,6 +605,13 @@  static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 		goto err_clk;
 	}
 
+	ret = clk_prepare_enable(hdmi->hclk_clk);
+	if (ret) {
+		DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI hclk clock: %d\n",
+			      ret);
+		goto err_clk;
+	}
+
 	if (hdmi->chip_data == &rk3568_chip_data) {
 		regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
 			     HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK |