Message ID | 20220217055529.499829-4-dmitry.baryshkov@linaro.org |
---|---|
State | Accepted |
Commit | 26345e0117234c89e9d581c63aa25f10e6b50517 |
Headers | show |
Series | drm/msm: rework clock handling | expand |
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);
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);
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.
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.
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. >
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?
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.
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?
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>
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 --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);
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(-)