diff mbox series

[v5,3/5] drm/msm/dp: set stream_pixel rate directly

Message ID 20220217055529.499829-4-dmitry.baryshkov@linaro.org (mailing list archive)
State Not Applicable
Headers show
Series drm/msm: rework clock handling | expand

Commit Message

Dmitry Baryshkov Feb. 17, 2022, 5:55 a.m. UTC
The only clock for which we set the rate is the "stream_pixel". Rather
than storing the rate and then setting it by looping over all the
clocks, set the clock rate directly.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/dp/dp_clk_util.c | 33 ----------------------------
 drivers/gpu/drm/msm/dp/dp_clk_util.h |  9 --------
 drivers/gpu/drm/msm/dp/dp_ctrl.c     |  2 +-
 drivers/gpu/drm/msm/dp/dp_parser.c   |  7 ------
 drivers/gpu/drm/msm/dp/dp_power.c    | 10 ---------
 5 files changed, 1 insertion(+), 60 deletions(-)

Comments

Stephen Boyd March 3, 2022, 10:32 p.m. UTC | #1
Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
> The only clock for which we set the rate is the "stream_pixel". Rather
> than storing the rate and then setting it by looping over all the
> clocks, set the clock rate directly.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
[...]
> diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> index 07f6bf7e1acb..8e6361dedd77 100644
> --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
> +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> @@ -1315,7 +1315,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
>         DRM_DEBUG_DP("setting rate=%lu on clk=%s\n", rate, name);
>
>         if (num)
> -               cfg->rate = rate;
> +               clk_set_rate(cfg->clk, rate);

This looks bad. From what I can tell we set the rate of the pixel clk
after enabling the phy and configuring it. See the order of operations
in dp_ctrl_enable_mainlink_clocks() and note how dp_power_clk_enable()
is the one that eventually sets a rate through dp_power_clk_set_rate()

        dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
                                        ctrl->link->link_params.rate * 1000);

        phy_configure(phy, &dp_io->phy_opts);
        phy_power_on(phy);

        ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);	

and I vaguely recall that the DP phy needs to be configured for some
frequency so that the pixel clk can use it when determining the rate to
set.

>         else
>                 DRM_ERROR("%s clock doesn't exit to set rate %lu\n",
>                                 name, rate);
Dmitry Baryshkov March 4, 2022, 4:23 a.m. UTC | #2
On Fri, 4 Mar 2022 at 01:32, Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
> > The only clock for which we set the rate is the "stream_pixel". Rather
> > than storing the rate and then setting it by looping over all the
> > clocks, set the clock rate directly.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> [...]
> > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > index 07f6bf7e1acb..8e6361dedd77 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > @@ -1315,7 +1315,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
> >         DRM_DEBUG_DP("setting rate=%lu on clk=%s\n", rate, name);
> >
> >         if (num)
> > -               cfg->rate = rate;
> > +               clk_set_rate(cfg->clk, rate);
>
> This looks bad. From what I can tell we set the rate of the pixel clk
> after enabling the phy and configuring it. See the order of operations
> in dp_ctrl_enable_mainlink_clocks() and note how dp_power_clk_enable()
> is the one that eventually sets a rate through dp_power_clk_set_rate()
>
>         dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
>                                         ctrl->link->link_params.rate * 1000);
>
>         phy_configure(phy, &dp_io->phy_opts);
>         phy_power_on(phy);
>
>         ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);

This code has been changed in the previous patch.

Let's get back a bit.
Currently dp_ctrl_set_clock_rate() doesn't change the clock rate. It
just stores the rate in the config so that later the sequence of
dp_power_clk_enable() -> dp_power_clk_set_rate() ->
[dp_power_clk_set_link_rate() -> dev_pm_opp_set_rate() or
msm_dss_clk_set_rate() -> clk_set_rate()] will use that.

There are only two users of dp_ctrl_set_clock_rate():
- dp_ctrl_enable_mainlink_clocks(), which you have quoted above.
  This case is handled in the patch 1 from this series. It makes
dp_ctrl_enable_mainlink_clocks() call dev_pm_opp_set_rate() directly
without storing (!) the rate in the config, calling
phy_configure()/phy_power_on() and then setting the opp via the
sequence of calls specified above

- dp_ctrl_enable_stream_clocks(), which calls dp_power_clk_enable()
immediately afterwards. This call would set the stream_pixel rate
while enabling stream clocks. As far as I can see, the stream_pixel is
the only stream clock. So this patch sets the clock rate without
storing in the interim configuration data.

Could you please clarify, what exactly looks bad to you?

> and I vaguely recall that the DP phy needs to be configured for some
> frequency so that the pixel clk can use it when determining the rate to
> set.
>
> >         else
> >                 DRM_ERROR("%s clock doesn't exit to set rate %lu\n",
> >                                 name, rate);
Stephen Boyd March 4, 2022, 4:31 a.m. UTC | #3
Quoting Dmitry Baryshkov (2022-03-03 20:23:06)
> On Fri, 4 Mar 2022 at 01:32, Stephen Boyd <swboyd@chromium.org> wrote:
> >
> > Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
> > > The only clock for which we set the rate is the "stream_pixel". Rather
> > > than storing the rate and then setting it by looping over all the
> > > clocks, set the clock rate directly.
> > >
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > [...]
> > > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > index 07f6bf7e1acb..8e6361dedd77 100644
> > > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > @@ -1315,7 +1315,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
> > >         DRM_DEBUG_DP("setting rate=%lu on clk=%s\n", rate, name);
> > >
> > >         if (num)
> > > -               cfg->rate = rate;
> > > +               clk_set_rate(cfg->clk, rate);
> >
> > This looks bad. From what I can tell we set the rate of the pixel clk
> > after enabling the phy and configuring it. See the order of operations
> > in dp_ctrl_enable_mainlink_clocks() and note how dp_power_clk_enable()
> > is the one that eventually sets a rate through dp_power_clk_set_rate()
> >
> >         dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
> >                                         ctrl->link->link_params.rate * 1000);
> >
> >         phy_configure(phy, &dp_io->phy_opts);
> >         phy_power_on(phy);
> >
> >         ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);
>
> This code has been changed in the previous patch.
>
> Let's get back a bit.
> Currently dp_ctrl_set_clock_rate() doesn't change the clock rate. It
> just stores the rate in the config so that later the sequence of
> dp_power_clk_enable() -> dp_power_clk_set_rate() ->
> [dp_power_clk_set_link_rate() -> dev_pm_opp_set_rate() or
> msm_dss_clk_set_rate() -> clk_set_rate()] will use that.
>
> There are only two users of dp_ctrl_set_clock_rate():
> - dp_ctrl_enable_mainlink_clocks(), which you have quoted above.
>   This case is handled in the patch 1 from this series. It makes

Patch 1 form this series says DP is unaffected. Huh?

> dp_ctrl_enable_mainlink_clocks() call dev_pm_opp_set_rate() directly
> without storing (!) the rate in the config, calling
> phy_configure()/phy_power_on() and then setting the opp via the
> sequence of calls specified above
>
> - dp_ctrl_enable_stream_clocks(), which calls dp_power_clk_enable()
> immediately afterwards. This call would set the stream_pixel rate
> while enabling stream clocks. As far as I can see, the stream_pixel is
> the only stream clock. So this patch sets the clock rate without
> storing in the interim configuration data.
>
> Could you please clarify, what exactly looks bad to you?
>

I'm concerned about the order of operations changing between the
phy being powered on and the pixel clk frequency being set. From what I
recall the pixel clk rate operations depend on the phy frequency being
set (which is done through phy_configure?) so if we call clk_set_rate()
on the pixel clk before the phy is set then the clk frequency will be
calculated badly and probably be incorrect.
Dmitry Baryshkov March 4, 2022, 7:58 a.m. UTC | #4
On Fri, 4 Mar 2022 at 07:31, Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Dmitry Baryshkov (2022-03-03 20:23:06)
> > On Fri, 4 Mar 2022 at 01:32, Stephen Boyd <swboyd@chromium.org> wrote:
> > >
> > > Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
> > > > The only clock for which we set the rate is the "stream_pixel". Rather
> > > > than storing the rate and then setting it by looping over all the
> > > > clocks, set the clock rate directly.
> > > >
> > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > [...]
> > > > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > > index 07f6bf7e1acb..8e6361dedd77 100644
> > > > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > > @@ -1315,7 +1315,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
> > > >         DRM_DEBUG_DP("setting rate=%lu on clk=%s\n", rate, name);
> > > >
> > > >         if (num)
> > > > -               cfg->rate = rate;
> > > > +               clk_set_rate(cfg->clk, rate);
> > >
> > > This looks bad. From what I can tell we set the rate of the pixel clk
> > > after enabling the phy and configuring it. See the order of operations
> > > in dp_ctrl_enable_mainlink_clocks() and note how dp_power_clk_enable()
> > > is the one that eventually sets a rate through dp_power_clk_set_rate()
> > >
> > >         dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
> > >                                         ctrl->link->link_params.rate * 1000);
> > >
> > >         phy_configure(phy, &dp_io->phy_opts);
> > >         phy_power_on(phy);
> > >
> > >         ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);
> >
> > This code has been changed in the previous patch.
> >
> > Let's get back a bit.
> > Currently dp_ctrl_set_clock_rate() doesn't change the clock rate. It
> > just stores the rate in the config so that later the sequence of
> > dp_power_clk_enable() -> dp_power_clk_set_rate() ->
> > [dp_power_clk_set_link_rate() -> dev_pm_opp_set_rate() or
> > msm_dss_clk_set_rate() -> clk_set_rate()] will use that.
> >
> > There are only two users of dp_ctrl_set_clock_rate():
> > - dp_ctrl_enable_mainlink_clocks(), which you have quoted above.
> >   This case is handled in the patch 1 from this series. It makes
>
> Patch 1 form this series says DP is unaffected. Huh?
>
> > dp_ctrl_enable_mainlink_clocks() call dev_pm_opp_set_rate() directly
> > without storing (!) the rate in the config, calling
> > phy_configure()/phy_power_on() and then setting the opp via the
> > sequence of calls specified above

Note, this handles the "ctrl_link" clock.

> >
> > - dp_ctrl_enable_stream_clocks(), which calls dp_power_clk_enable()
> > immediately afterwards. This call would set the stream_pixel rate
> > while enabling stream clocks. As far as I can see, the stream_pixel is
> > the only stream clock. So this patch sets the clock rate without
> > storing in the interim configuration data.
> >
> > Could you please clarify, what exactly looks bad to you?
> >

Note, this handles the "stream_pixel" clock.

>
> I'm concerned about the order of operations changing between the
> phy being powered on and the pixel clk frequency being set. From what I
> recall the pixel clk rate operations depend on the phy frequency being
> set (which is done through phy_configure?) so if we call clk_set_rate()
> on the pixel clk before the phy is set then the clk frequency will be
> calculated badly and probably be incorrect.

But the order of operations is mostly unchanged. The only major change
is that the opp point is now set before calling the
phy_configure()/phy_power_on()

For the pixel clock the driver has:
static int dp_ctrl_enable_stream_clocks(struct dp_ctrl_private *ctrl)
{
        int ret = 0;

        dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel",
                                        ctrl->dp_ctrl.pixel_rate * 1000);

        ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true);
[skipped the error handling]
}

dp_power_clk_enable() doesn't have any special handlers for the the
DP_STREAM_PM,
so this code would be equivalent to the following pseudo code (given
that there is only one stream clock):

unsigned int rate = ctrl->dp_ctrl.pixel_rate * 1000;

/* dp_ctrl_set_clock_rate() */
cfg = find_clock_cfg("stream_pixel");
cfg->rate = rate;

/* dp_power_clk_enable() */
clk = find_clock("stream_pixel")
clk_set_rate(clk, cfg->rate);
clk_prepare_enable(clk);

The proposed patch does exactly this.

Please correct me if I'm wrong.
Stephen Boyd March 8, 2022, 8:46 p.m. UTC | #5
Quoting Dmitry Baryshkov (2022-03-03 23:58:58)
> On Fri, 4 Mar 2022 at 07:31, Stephen Boyd <swboyd@chromium.org> wrote:
> >
> > Quoting Dmitry Baryshkov (2022-03-03 20:23:06)
> > > On Fri, 4 Mar 2022 at 01:32, Stephen Boyd <swboyd@chromium.org> wrote:
> > > >
> > > > Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
> > > > > The only clock for which we set the rate is the "stream_pixel". Rather
> > > > > than storing the rate and then setting it by looping over all the
> > > > > clocks, set the clock rate directly.
> > > > >
> > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > > [...]
> > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > > > index 07f6bf7e1acb..8e6361dedd77 100644
> > > > > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > > > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
> > > > > @@ -1315,7 +1315,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
> > > > >         DRM_DEBUG_DP("setting rate=%lu on clk=%s\n", rate, name);
> > > > >
> > > > >         if (num)
> > > > > -               cfg->rate = rate;
> > > > > +               clk_set_rate(cfg->clk, rate);
> > > >
> > > > This looks bad. From what I can tell we set the rate of the pixel clk
> > > > after enabling the phy and configuring it. See the order of operations
> > > > in dp_ctrl_enable_mainlink_clocks() and note how dp_power_clk_enable()
> > > > is the one that eventually sets a rate through dp_power_clk_set_rate()
> > > >
> > > >         dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
> > > >                                         ctrl->link->link_params.rate * 1000);
> > > >
> > > >         phy_configure(phy, &dp_io->phy_opts);
> > > >         phy_power_on(phy);
> > > >
> > > >         ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);
> > >
> > > This code has been changed in the previous patch.
> > >
> > > Let's get back a bit.
> > > Currently dp_ctrl_set_clock_rate() doesn't change the clock rate. It
> > > just stores the rate in the config so that later the sequence of
> > > dp_power_clk_enable() -> dp_power_clk_set_rate() ->
> > > [dp_power_clk_set_link_rate() -> dev_pm_opp_set_rate() or
> > > msm_dss_clk_set_rate() -> clk_set_rate()] will use that.
> > >
> > > There are only two users of dp_ctrl_set_clock_rate():
> > > - dp_ctrl_enable_mainlink_clocks(), which you have quoted above.
> > >   This case is handled in the patch 1 from this series. It makes
> >
> > Patch 1 form this series says DP is unaffected. Huh?
> >
> > > dp_ctrl_enable_mainlink_clocks() call dev_pm_opp_set_rate() directly
> > > without storing (!) the rate in the config, calling
> > > phy_configure()/phy_power_on() and then setting the opp via the
> > > sequence of calls specified above
>
> Note, this handles the "ctrl_link" clock.
>
> > >
> > > - dp_ctrl_enable_stream_clocks(), which calls dp_power_clk_enable()
> > > immediately afterwards. This call would set the stream_pixel rate
> > > while enabling stream clocks. As far as I can see, the stream_pixel is
> > > the only stream clock. So this patch sets the clock rate without
> > > storing in the interim configuration data.
> > >
> > > Could you please clarify, what exactly looks bad to you?
> > >
>
> Note, this handles the "stream_pixel" clock.
>
> >
> > I'm concerned about the order of operations changing between the
> > phy being powered on and the pixel clk frequency being set. From what I
> > recall the pixel clk rate operations depend on the phy frequency being
> > set (which is done through phy_configure?) so if we call clk_set_rate()
> > on the pixel clk before the phy is set then the clk frequency will be
> > calculated badly and probably be incorrect.
>
> But the order of operations is mostly unchanged. The only major change
> is that the opp point is now set before calling the
> phy_configure()/phy_power_on()

Yes that's my concern. The qmp phy driver has a couple clk_set_rate()
calls in the .configure_dp_phy callback. That is called from
phy_power_on() (see qcom_qmp_phy_power_on() and qcom_qmp_phy_dp_ops).
Looking at qcom_qmp_v3_phy_configure_dp_phy() it does

        clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
        clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);

and I believe the child of dp_pixel_hw is find_clock("stream_pixel").
Looks like that is DISP_CC_MDSS_DP_PIXEL_CLK which is
disp_cc_mdss_dp_pixel_clk_src for the rate settable part. That has
clk_dp_ops which is clk_rcg2_dp_set_rate() for the set rate part. That
wants the parent clk frequency to be something non-zero to use in
rational_best_approximation(). If the clk_set_rate("stream_pixel") call
is made before phy_power_on() then the parent_rate in
clk_rcg2_dp_set_rate() won't be valid and the pixel clk frequency will
be wrong.

>
> For the pixel clock the driver has:
> static int dp_ctrl_enable_stream_clocks(struct dp_ctrl_private *ctrl)
> {
>         int ret = 0;
>
>         dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel",
>                                         ctrl->dp_ctrl.pixel_rate * 1000);
>
>         ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true);
> [skipped the error handling]
> }
>
> dp_power_clk_enable() doesn't have any special handlers for the the
> DP_STREAM_PM,
> so this code would be equivalent to the following pseudo code (given
> that there is only one stream clock):
>
> unsigned int rate = ctrl->dp_ctrl.pixel_rate * 1000;
>
> /* dp_ctrl_set_clock_rate() */
> cfg = find_clock_cfg("stream_pixel");
> cfg->rate = rate;
>
> /* dp_power_clk_enable() */
> clk = find_clock("stream_pixel")
> clk_set_rate(clk, cfg->rate);
> clk_prepare_enable(clk);
>
> The proposed patch does exactly this.
>
> Please correct me if I'm wrong.
>
Dmitry Baryshkov April 19, 2022, 4:34 p.m. UTC | #6
On 08/03/2022 23:46, Stephen Boyd wrote:
> Quoting Dmitry Baryshkov (2022-03-03 23:58:58)
>> On Fri, 4 Mar 2022 at 07:31, Stephen Boyd <swboyd@chromium.org> wrote:
>>>
>>> Quoting Dmitry Baryshkov (2022-03-03 20:23:06)
>>>> On Fri, 4 Mar 2022 at 01:32, Stephen Boyd <swboyd@chromium.org> wrote:
>>>>>
>>>>> Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
>>>>>> The only clock for which we set the rate is the "stream_pixel". Rather
>>>>>> than storing the rate and then setting it by looping over all the
>>>>>> clocks, set the clock rate directly.
>>>>>>
>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> [...]
>>>>>> diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
>>>>>> index 07f6bf7e1acb..8e6361dedd77 100644
>>>>>> --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
>>>>>> +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
>>>>>> @@ -1315,7 +1315,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
>>>>>>          DRM_DEBUG_DP("setting rate=%lu on clk=%s\n", rate, name);
>>>>>>
>>>>>>          if (num)
>>>>>> -               cfg->rate = rate;
>>>>>> +               clk_set_rate(cfg->clk, rate);
>>>>>
>>>>> This looks bad. From what I can tell we set the rate of the pixel clk
>>>>> after enabling the phy and configuring it. See the order of operations
>>>>> in dp_ctrl_enable_mainlink_clocks() and note how dp_power_clk_enable()
>>>>> is the one that eventually sets a rate through dp_power_clk_set_rate()
>>>>>
>>>>>          dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link",
>>>>>                                          ctrl->link->link_params.rate * 1000);
>>>>>
>>>>>          phy_configure(phy, &dp_io->phy_opts);
>>>>>          phy_power_on(phy);
>>>>>
>>>>>          ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);
>>>>
>>>> This code has been changed in the previous patch.
>>>>
>>>> Let's get back a bit.
>>>> Currently dp_ctrl_set_clock_rate() doesn't change the clock rate. It
>>>> just stores the rate in the config so that later the sequence of
>>>> dp_power_clk_enable() -> dp_power_clk_set_rate() ->
>>>> [dp_power_clk_set_link_rate() -> dev_pm_opp_set_rate() or
>>>> msm_dss_clk_set_rate() -> clk_set_rate()] will use that.
>>>>
>>>> There are only two users of dp_ctrl_set_clock_rate():
>>>> - dp_ctrl_enable_mainlink_clocks(), which you have quoted above.
>>>>    This case is handled in the patch 1 from this series. It makes
>>>
>>> Patch 1 form this series says DP is unaffected. Huh?
>>>
>>>> dp_ctrl_enable_mainlink_clocks() call dev_pm_opp_set_rate() directly
>>>> without storing (!) the rate in the config, calling
>>>> phy_configure()/phy_power_on() and then setting the opp via the
>>>> sequence of calls specified above
>>
>> Note, this handles the "ctrl_link" clock.
>>
>>>>
>>>> - dp_ctrl_enable_stream_clocks(), which calls dp_power_clk_enable()
>>>> immediately afterwards. This call would set the stream_pixel rate
>>>> while enabling stream clocks. As far as I can see, the stream_pixel is
>>>> the only stream clock. So this patch sets the clock rate without
>>>> storing in the interim configuration data.
>>>>
>>>> Could you please clarify, what exactly looks bad to you?
>>>>
>>
>> Note, this handles the "stream_pixel" clock.
>>
>>>
>>> I'm concerned about the order of operations changing between the
>>> phy being powered on and the pixel clk frequency being set. From what I
>>> recall the pixel clk rate operations depend on the phy frequency being
>>> set (which is done through phy_configure?) so if we call clk_set_rate()
>>> on the pixel clk before the phy is set then the clk frequency will be
>>> calculated badly and probably be incorrect.
>>
>> But the order of operations is mostly unchanged. The only major change
>> is that the opp point is now set before calling the
>> phy_configure()/phy_power_on()
> 
> Yes that's my concern. The qmp phy driver has a couple clk_set_rate()
> calls in the .configure_dp_phy callback. That is called from
> phy_power_on() (see qcom_qmp_phy_power_on() and qcom_qmp_phy_dp_ops).
> Looking at qcom_qmp_v3_phy_configure_dp_phy() it does
> 
>          clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
>          clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
> 
> and I believe the child of dp_pixel_hw is find_clock("stream_pixel").
> Looks like that is DISP_CC_MDSS_DP_PIXEL_CLK which is
> disp_cc_mdss_dp_pixel_clk_src for the rate settable part. That has
> clk_dp_ops which is clk_rcg2_dp_set_rate() for the set rate part. That
> wants the parent clk frequency to be something non-zero to use in
> rational_best_approximation(). If the clk_set_rate("stream_pixel") call
> is made before phy_power_on() then the parent_rate in
> clk_rcg2_dp_set_rate() won't be valid and the pixel clk frequency will
> be wrong.


Please excuse me, I didn't have time for this patchset up to now.

I double checked the previous patch (drm/msm/dp: "inline" 
dp_ctrl_set_clock_rate("ctrl_link")). Note, that the OPP is set _after_ 
the PHY is powered on and configured.

Does that cover your concerns?
Stephen Boyd April 28, 2022, 9:49 p.m. UTC | #7
Quoting Dmitry Baryshkov (2022-04-19 09:34:18)
> On 08/03/2022 23:46, Stephen Boyd wrote:
> >
> > Yes that's my concern. The qmp phy driver has a couple clk_set_rate()
> > calls in the .configure_dp_phy callback. That is called from
> > phy_power_on() (see qcom_qmp_phy_power_on() and qcom_qmp_phy_dp_ops).
> > Looking at qcom_qmp_v3_phy_configure_dp_phy() it does
> >
> >          clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
> >          clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
> >
> > and I believe the child of dp_pixel_hw is find_clock("stream_pixel").
> > Looks like that is DISP_CC_MDSS_DP_PIXEL_CLK which is
> > disp_cc_mdss_dp_pixel_clk_src for the rate settable part. That has
> > clk_dp_ops which is clk_rcg2_dp_set_rate() for the set rate part. That
> > wants the parent clk frequency to be something non-zero to use in
> > rational_best_approximation(). If the clk_set_rate("stream_pixel") call
> > is made before phy_power_on() then the parent_rate in
> > clk_rcg2_dp_set_rate() won't be valid and the pixel clk frequency will
> > be wrong.
>
>
> Please excuse me, I didn't have time for this patchset up to now.

No worries. I lost this in my inbox!

>
> I double checked the previous patch (drm/msm/dp: "inline"
> dp_ctrl_set_clock_rate("ctrl_link")). Note, that the OPP is set _after_
> the PHY is powered on and configured.
>

Ok. If the clk_set_rate("stream_pixel") call is made after the
phy_power_on() then it should be equivalent.
Dmitry Baryshkov April 28, 2022, 9:51 p.m. UTC | #8
On Fri, 29 Apr 2022 at 00:49, Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Dmitry Baryshkov (2022-04-19 09:34:18)
> > On 08/03/2022 23:46, Stephen Boyd wrote:
> > >
> > > Yes that's my concern. The qmp phy driver has a couple clk_set_rate()
> > > calls in the .configure_dp_phy callback. That is called from
> > > phy_power_on() (see qcom_qmp_phy_power_on() and qcom_qmp_phy_dp_ops).
> > > Looking at qcom_qmp_v3_phy_configure_dp_phy() it does
> > >
> > >          clk_set_rate(dp_clks->dp_link_hw.clk, dp_opts->link_rate * 100000);
> > >          clk_set_rate(dp_clks->dp_pixel_hw.clk, pixel_freq);
> > >
> > > and I believe the child of dp_pixel_hw is find_clock("stream_pixel").
> > > Looks like that is DISP_CC_MDSS_DP_PIXEL_CLK which is
> > > disp_cc_mdss_dp_pixel_clk_src for the rate settable part. That has
> > > clk_dp_ops which is clk_rcg2_dp_set_rate() for the set rate part. That
> > > wants the parent clk frequency to be something non-zero to use in
> > > rational_best_approximation(). If the clk_set_rate("stream_pixel") call
> > > is made before phy_power_on() then the parent_rate in
> > > clk_rcg2_dp_set_rate() won't be valid and the pixel clk frequency will
> > > be wrong.
> >
> >
> > Please excuse me, I didn't have time for this patchset up to now.
>
> No worries. I lost this in my inbox!
>
> >
> > I double checked the previous patch (drm/msm/dp: "inline"
> > dp_ctrl_set_clock_rate("ctrl_link")). Note, that the OPP is set _after_
> > the PHY is powered on and configured.
> >
>
> Ok. If the clk_set_rate("stream_pixel") call is made after the
> phy_power_on() then it should be equivalent.

R-B?
Stephen Boyd April 29, 2022, 1:20 a.m. UTC | #9
Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
> The only clock for which we set the rate is the "stream_pixel". Rather
> than storing the rate and then setting it by looping over all the
> clocks, set the clock rate directly.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---

Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Dmitry Baryshkov April 29, 2022, 9:44 a.m. UTC | #10
On Fri, 29 Apr 2022 at 04:20, Stephen Boyd <swboyd@chromium.org> wrote:
>
> Quoting Dmitry Baryshkov (2022-02-16 21:55:27)
> > The only clock for which we set the rate is the "stream_pixel". Rather
> > than storing the rate and then setting it by looping over all the
> > clocks, set the clock rate directly.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>

Thanks! I think this series can be queued for 5.20 then (probably not
worth rushing it into 5.19)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/msm/dp/dp_clk_util.c b/drivers/gpu/drm/msm/dp/dp_clk_util.c
index 44a4fc59ff31..85abed31c68b 100644
--- a/drivers/gpu/drm/msm/dp/dp_clk_util.c
+++ b/drivers/gpu/drm/msm/dp/dp_clk_util.c
@@ -51,39 +51,6 @@  int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk)
 	return rc;
 }
 
-int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk)
-{
-	int i, rc = 0;
-
-	for (i = 0; i < num_clk; i++) {
-		if (clk_arry[i].clk) {
-			if (clk_arry[i].type != DSS_CLK_AHB) {
-				DEV_DBG("%pS->%s: '%s' rate %ld\n",
-					__builtin_return_address(0), __func__,
-					clk_arry[i].clk_name,
-					clk_arry[i].rate);
-				rc = clk_set_rate(clk_arry[i].clk,
-					clk_arry[i].rate);
-				if (rc) {
-					DEV_ERR("%pS->%s: %s failed. rc=%d\n",
-						__builtin_return_address(0),
-						__func__,
-						clk_arry[i].clk_name, rc);
-					break;
-				}
-			}
-		} else {
-			DEV_ERR("%pS->%s: '%s' is not available\n",
-				__builtin_return_address(0), __func__,
-				clk_arry[i].clk_name);
-			rc = -EPERM;
-			break;
-		}
-	}
-
-	return rc;
-}
-
 int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
 {
 	int i, rc = 0;
diff --git a/drivers/gpu/drm/msm/dp/dp_clk_util.h b/drivers/gpu/drm/msm/dp/dp_clk_util.h
index 067bf87f3d97..c3d59b5017a9 100644
--- a/drivers/gpu/drm/msm/dp/dp_clk_util.h
+++ b/drivers/gpu/drm/msm/dp/dp_clk_util.h
@@ -13,17 +13,9 @@ 
 #define DEV_WARN(fmt, args...)  pr_warn(fmt, ##args)
 #define DEV_ERR(fmt, args...)   pr_err(fmt, ##args)
 
-enum dss_clk_type {
-	DSS_CLK_AHB, /* no set rate. rate controlled through rpm */
-	DSS_CLK_PCLK,
-};
-
 struct dss_clk {
 	struct clk *clk; /* clk handle */
 	char clk_name[32];
-	enum dss_clk_type type;
-	unsigned long rate;
-	unsigned long max_rate;
 };
 
 struct dss_module_power {
@@ -33,6 +25,5 @@  struct dss_module_power {
 
 int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk);
 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
-int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
 int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
 #endif /* __DP_CLK_UTIL_H__ */
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 07f6bf7e1acb..8e6361dedd77 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1315,7 +1315,7 @@  static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
 	DRM_DEBUG_DP("setting rate=%lu on clk=%s\n", rate, name);
 
 	if (num)
-		cfg->rate = rate;
+		clk_set_rate(cfg->clk, rate);
 	else
 		DRM_ERROR("%s clock doesn't exit to set rate %lu\n",
 				name, rate);
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index a7acc23f742b..4f2d80bc0671 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -237,14 +237,12 @@  static int dp_parser_clock(struct dp_parser *parser)
 			struct dss_clk *clk =
 				&core_power->clk_config[core_clk_index];
 			strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
-			clk->type = DSS_CLK_AHB;
 			core_clk_index++;
 		} else if (dp_parser_check_prefix("stream", clk_name) &&
 				stream_clk_index < stream_clk_count) {
 			struct dss_clk *clk =
 				&stream_power->clk_config[stream_clk_index];
 			strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
-			clk->type = DSS_CLK_PCLK;
 			stream_clk_index++;
 		} else if (dp_parser_check_prefix("ctrl", clk_name) &&
 			   ctrl_clk_index < ctrl_clk_count) {
@@ -252,11 +250,6 @@  static int dp_parser_clock(struct dp_parser *parser)
 				&ctrl_power->clk_config[ctrl_clk_index];
 			strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
 			ctrl_clk_index++;
-			if (dp_parser_check_prefix("ctrl_link", clk_name) ||
-			    dp_parser_check_prefix("stream_pixel", clk_name))
-				clk->type = DSS_CLK_PCLK;
-			else
-				clk->type = DSS_CLK_AHB;
 		}
 	}
 
diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c
index 893a57dd97d9..6920d787e7aa 100644
--- a/drivers/gpu/drm/msm/dp/dp_power.c
+++ b/drivers/gpu/drm/msm/dp/dp_power.c
@@ -156,16 +156,6 @@  static int dp_power_clk_set_rate(struct dp_power_private *power,
 	int rc = 0;
 	struct dss_module_power *mp = &power->parser->mp[module];
 
-	if (module != DP_CTRL_PM) {
-		if (enable) {
-			rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
-			if (rc) {
-				DRM_ERROR("failed to set clks rate\n");
-				return rc;
-			}
-		}
-	}
-
 	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
 	if (rc) {
 		DRM_ERROR("failed to %d clks, err: %d\n", enable, rc);