Re: [PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
Looping back on this, after digging a bit deeper... On Fri, Feb 14, 2020 at 9:38 AM Nick Fan (范哲維) wrote: > [snip] > > > Another thing that I'm not implementing is the dance that Mediatek > > > does in their kbase driver when changing the clock (described in > > > patch > > > 2/7): > > > "" > > > The binding we use with out-of-tree Mali drivers includes more > > > clocks, this is used for devfreq: the out-of-tree driver switches > > > clk_mux to clk_sub_parent (26Mhz), adjusts clk_main_parent, then > > > switches clk_mux back to clk_main_parent: > > > (see > > > https://chromium.googlesource.com/chromiumos/third_party/kernel/+/ch > > > romeos-4.19/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_run > > > time_pm.c#423) > > > clocks = > > > <&topckgen CLK_TOP_MFGPLL_CK>, > > > <&topckgen CLK_TOP_MUX_MFG>, > > > <&clk26m>, > > > <&mfgcfg CLK_MFG_BG3D>; > > > clock-names = > > > "clk_main_parent", > > > "clk_mux", > > > "clk_sub_parent", > > > "subsys_mfg_cg"; > > > "" > > > Is there a clean/simple way to implement this in the clock > > > framework/device tree? Or should we implement something in the > > > panfrost driver? > > > > Putting parent clocks into 'clocks' for a device is a pretty common > > abuse. The 'assigned-clocks' binding is what's used for parent clock > > setup. Not sure that's going to help here though. Is this dance > > because the parent clock frequency can't be changed cleanly? > > Nick/Weiyi, any idea why we do that dance in the first place? (maybe the PLL > clock is unstable while it's being changed?) > > Clock source may become unstable during clock frequency changes, so it is > always safer to switch to a more reliable clock source. > Otherwise, it may cause some problem in some corner case. > I would suggest to keep it. The Mediatek CPUfreq driver actually does a very similar dance: https://github.com/torvalds/linux/blob/master/drivers/cpufreq/mediatek-cpufreq.c#L249 What they have in the device tree is the main clock, and the "intermediate" clock that is required during switching: clocks = <&mcucfg CLK_MCU_MP0_SEL>, <&topckgen CLK_TOP_ARMPLL_DIV_PLL1>; clock-names = "cpu", "intermediate"; The topology looks like this: clk26m 15 1512600 0 0 5 armpll_ll 110 141700 0 0 5 mcu_mp0_sel000 141700 0 0 5 And device tree provides mcu_mp0_sel as "cpu", and the armpll_div_pll1 as "intermediate". The driver looks up armpll_ll by calling get_parent, then: - set_parent(mcu_mp0_sel, armpll_div_pll1) - set_rate(armpll_ll, new_rate) - set_parent(mcu_mp0_sel, armpll_ll) On MT8183's GPU, the topology is a little bit more complicated (but I think there should be a way to merge mfg_bg3d an mfg_sel in the clock core) clk26m 15 1512600 0 0 5 mfgpll110 41817 0 0 5 mfgpll_ck 220 41817 0 0 5 mfg_sel 330 41817 0 0 5 mfg_bg3d 110 41817 0 0 5 We're going to need a special panfrost devfreq driver for mt8183 anyway (to handle the 2 regulators), so it would be easy to take a similar approach: - Add "intermediate" clock in the device tree (clk26m) - Find mfg_sel/mfgpll_ck using 1/2 clk_get_parent calls. - Switch mfg_sel to clk26m, set mfgpll_ck rate, switch mfg_sel back to mfgpll_ck. (BTW, I tried to look, and couldn't find examples or reparenting during clock changes in drivers/clk, are there existing drivers doing similar things? Or this would be new?). ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
RE: [PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
On Thu, Feb 13, 2020 at 3:57 PM Nicolas Boichat wrote: > > > [snip] > > > But then there's a slight problem: panfrost_devfreq uses a bunch of > > > clk_get_rate calls, and the clock PLLs (at least on MTK platform) are > > > never fully precise, so we get back 29955 for 300 Mhz and > > > 79878 for 800 Mhz. That means that the kernel is unable to keep > > > devfreq stats as neither of these values are in the table: > > > [ 4802.470952] devfreq devfreq1: Couldn't update frequency transition > > > information. > > > The kbase driver fixes this by remembering the last set frequency, and > > > reporting that to devfreq. Should we do that as well or is there a > > > better fix? This one is my bad, I was missing this patch in my forklift to 4.19: 22bd4df9dadf46f drm/panfrost: devfreq: Round frequencies to OPPs (should really try to boot that board on linux-next, but that's for another time) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
On Wed, Feb 12, 2020 at 2:19 PM Nicolas Boichat wrote: > > +Viresh Kumar +Stephen Boyd for clock advice. You missed adding us in the cc list of the email, fixed that now :) ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
+Weiyi Lu +Nick Fan @MTK who may have more ideas. On Thu, Feb 13, 2020 at 2:14 AM Rob Herring wrote: > > On Wed, Feb 12, 2020 at 2:49 AM Nicolas Boichat wrote: > > > > +Viresh Kumar +Stephen Boyd for clock advice. > > > > On Fri, Feb 7, 2020 at 1:27 PM Nicolas Boichat > > wrote: > > > > > > The Bifrost GPU on MT8183 uses 2 regulators (core and SRAM) for > > > devfreq, and provides OPP table with 2 sets of voltages. > > > > > > TODO: This is incomplete as we'll need add support for setting > > > a pair of voltages as well. > > > > So all we need for this to work (at least apparently, that is, I can > > change frequency) is this: > > https://lore.kernel.org/patchwork/patch/1192945/ > > (ah well, Viresh just replied, so, probably not, I'll check that out > > and use the correct API) > > > > But then there's a slight problem: panfrost_devfreq uses a bunch of > > clk_get_rate calls, and the clock PLLs (at least on MTK platform) are > > never fully precise, so we get back 29955 for 300 Mhz and > > 79878 for 800 Mhz. That means that the kernel is unable to keep > > devfreq stats as neither of these values are in the table: > > [ 4802.470952] devfreq devfreq1: Couldn't update frequency transition > > information. > > The kbase driver fixes this by remembering the last set frequency, and > > reporting that to devfreq. Should we do that as well or is there a > > better fix? > > > > Another thing that I'm not implementing is the dance that Mediatek > > does in their kbase driver when changing the clock (described in patch > > 2/7): > > "" > > The binding we use with out-of-tree Mali drivers includes more > > clocks, this is used for devfreq: the out-of-tree driver switches > > clk_mux to clk_sub_parent (26Mhz), adjusts clk_main_parent, then > > switches clk_mux back to clk_main_parent: > > (see > > https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-4.19/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_runtime_pm.c#423) > > clocks = > > <&topckgen CLK_TOP_MFGPLL_CK>, > > <&topckgen CLK_TOP_MUX_MFG>, > > <&clk26m>, > > <&mfgcfg CLK_MFG_BG3D>; > > clock-names = > > "clk_main_parent", > > "clk_mux", > > "clk_sub_parent", > > "subsys_mfg_cg"; > > "" > > Is there a clean/simple way to implement this in the clock > > framework/device tree? Or should we implement something in the > > panfrost driver? > > Putting parent clocks into 'clocks' for a device is a pretty common > abuse. The 'assigned-clocks' binding is what's used for parent clock > setup. Not sure that's going to help here though. Is this dance > because the parent clock frequency can't be changed cleanly? Nick/Weiyi, any idea why we do that dance in the first place? (maybe the PLL clock is unstable while it's being changed?) If we really need it, can we move that logic to the clock core? > If up to > me, I'd put that dance in the clock driver. The GPU shouldn't have to > care. > > Rob ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
On Wed, Feb 12, 2020 at 2:49 AM Nicolas Boichat wrote: > > +Viresh Kumar +Stephen Boyd for clock advice. > > On Fri, Feb 7, 2020 at 1:27 PM Nicolas Boichat wrote: > > > > The Bifrost GPU on MT8183 uses 2 regulators (core and SRAM) for > > devfreq, and provides OPP table with 2 sets of voltages. > > > > TODO: This is incomplete as we'll need add support for setting > > a pair of voltages as well. > > So all we need for this to work (at least apparently, that is, I can > change frequency) is this: > https://lore.kernel.org/patchwork/patch/1192945/ > (ah well, Viresh just replied, so, probably not, I'll check that out > and use the correct API) > > But then there's a slight problem: panfrost_devfreq uses a bunch of > clk_get_rate calls, and the clock PLLs (at least on MTK platform) are > never fully precise, so we get back 29955 for 300 Mhz and > 79878 for 800 Mhz. That means that the kernel is unable to keep > devfreq stats as neither of these values are in the table: > [ 4802.470952] devfreq devfreq1: Couldn't update frequency transition > information. > The kbase driver fixes this by remembering the last set frequency, and > reporting that to devfreq. Should we do that as well or is there a > better fix? > > Another thing that I'm not implementing is the dance that Mediatek > does in their kbase driver when changing the clock (described in patch > 2/7): > "" > The binding we use with out-of-tree Mali drivers includes more > clocks, this is used for devfreq: the out-of-tree driver switches > clk_mux to clk_sub_parent (26Mhz), adjusts clk_main_parent, then > switches clk_mux back to clk_main_parent: > (see > https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-4.19/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_runtime_pm.c#423) > clocks = > <&topckgen CLK_TOP_MFGPLL_CK>, > <&topckgen CLK_TOP_MUX_MFG>, > <&clk26m>, > <&mfgcfg CLK_MFG_BG3D>; > clock-names = > "clk_main_parent", > "clk_mux", > "clk_sub_parent", > "subsys_mfg_cg"; > "" > Is there a clean/simple way to implement this in the clock > framework/device tree? Or should we implement something in the > panfrost driver? Putting parent clocks into 'clocks' for a device is a pretty common abuse. The 'assigned-clocks' binding is what's used for parent clock setup. Not sure that's going to help here though. Is this dance because the parent clock frequency can't be changed cleanly? If up to me, I'd put that dance in the clock driver. The GPU shouldn't have to care. Rob ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
+Viresh Kumar +Stephen Boyd for clock advice. On Fri, Feb 7, 2020 at 1:27 PM Nicolas Boichat wrote: > > The Bifrost GPU on MT8183 uses 2 regulators (core and SRAM) for > devfreq, and provides OPP table with 2 sets of voltages. > > TODO: This is incomplete as we'll need add support for setting > a pair of voltages as well. So all we need for this to work (at least apparently, that is, I can change frequency) is this: https://lore.kernel.org/patchwork/patch/1192945/ (ah well, Viresh just replied, so, probably not, I'll check that out and use the correct API) But then there's a slight problem: panfrost_devfreq uses a bunch of clk_get_rate calls, and the clock PLLs (at least on MTK platform) are never fully precise, so we get back 29955 for 300 Mhz and 79878 for 800 Mhz. That means that the kernel is unable to keep devfreq stats as neither of these values are in the table: [ 4802.470952] devfreq devfreq1: Couldn't update frequency transition information. The kbase driver fixes this by remembering the last set frequency, and reporting that to devfreq. Should we do that as well or is there a better fix? Another thing that I'm not implementing is the dance that Mediatek does in their kbase driver when changing the clock (described in patch 2/7): "" The binding we use with out-of-tree Mali drivers includes more clocks, this is used for devfreq: the out-of-tree driver switches clk_mux to clk_sub_parent (26Mhz), adjusts clk_main_parent, then switches clk_mux back to clk_main_parent: (see https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-4.19/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_runtime_pm.c#423) clocks = <&topckgen CLK_TOP_MFGPLL_CK>, <&topckgen CLK_TOP_MUX_MFG>, <&clk26m>, <&mfgcfg CLK_MFG_BG3D>; clock-names = "clk_main_parent", "clk_mux", "clk_sub_parent", "subsys_mfg_cg"; "" Is there a clean/simple way to implement this in the clock framework/device tree? Or should we implement something in the panfrost driver? Thanks! > > Signed-off-by: Nicolas Boichat > > --- > drivers/gpu/drm/panfrost/panfrost_devfreq.c | 17 + > drivers/gpu/drm/panfrost/panfrost_device.h | 1 + > 2 files changed, 18 insertions(+) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c > index 413987038fbfccb..9c0987a3d71c597 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c > @@ -79,6 +79,21 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) > struct devfreq *devfreq; > struct thermal_cooling_device *cooling; > > + /* If we have 2 regulator, we need an OPP table with 2 voltages. */ > + if (pfdev->comp->num_supplies > 1) { > + pfdev->devfreq.dev_opp_table = > + dev_pm_opp_set_regulators(dev, > + pfdev->comp->supply_names, > + pfdev->comp->num_supplies); > + if (IS_ERR(pfdev->devfreq.dev_opp_table)) { > + ret = PTR_ERR(pfdev->devfreq.dev_opp_table); > + pfdev->devfreq.dev_opp_table = NULL; > + dev_err(dev, > + "Failed to init devfreq opp table: %d\n", > ret); > + return ret; > + } > + } > + > ret = dev_pm_opp_of_add_table(dev); > if (ret == -ENODEV) /* Optional, continue without devfreq */ > return 0; > @@ -119,6 +134,8 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev) > if (pfdev->devfreq.cooling) > devfreq_cooling_unregister(pfdev->devfreq.cooling); > dev_pm_opp_of_remove_table(&pfdev->pdev->dev); > + if (pfdev->devfreq.dev_opp_table) > + dev_pm_opp_put_regulators(pfdev->devfreq.dev_opp_table); > } > > void panfrost_devfreq_resume(struct panfrost_device *pfdev) > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h > b/drivers/gpu/drm/panfrost/panfrost_device.h > index c30c719a805940a..5009a8b7c853ea1 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.h > +++ b/drivers/gpu/drm/panfrost/panfrost_device.h > @@ -110,6 +110,7 @@ struct panfrost_device { > struct { > struct devfreq *devfreq; > struct thermal_cooling_device *cooling; > + struct opp_table *dev_opp_table; > ktime_t busy_time; > ktime_t idle_time; > ktime_t time_last_update; > -- > 2.25.0.341.g760bfbb309-goog > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 7/7] RFC: drm/panfrost: devfreq: Add support for 2 regulators
The Bifrost GPU on MT8183 uses 2 regulators (core and SRAM) for devfreq, and provides OPP table with 2 sets of voltages. TODO: This is incomplete as we'll need add support for setting a pair of voltages as well. Signed-off-by: Nicolas Boichat --- drivers/gpu/drm/panfrost/panfrost_devfreq.c | 17 + drivers/gpu/drm/panfrost/panfrost_device.h | 1 + 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c index 413987038fbfccb..9c0987a3d71c597 100644 --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c @@ -79,6 +79,21 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) struct devfreq *devfreq; struct thermal_cooling_device *cooling; + /* If we have 2 regulator, we need an OPP table with 2 voltages. */ + if (pfdev->comp->num_supplies > 1) { + pfdev->devfreq.dev_opp_table = + dev_pm_opp_set_regulators(dev, + pfdev->comp->supply_names, + pfdev->comp->num_supplies); + if (IS_ERR(pfdev->devfreq.dev_opp_table)) { + ret = PTR_ERR(pfdev->devfreq.dev_opp_table); + pfdev->devfreq.dev_opp_table = NULL; + dev_err(dev, + "Failed to init devfreq opp table: %d\n", ret); + return ret; + } + } + ret = dev_pm_opp_of_add_table(dev); if (ret == -ENODEV) /* Optional, continue without devfreq */ return 0; @@ -119,6 +134,8 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev) if (pfdev->devfreq.cooling) devfreq_cooling_unregister(pfdev->devfreq.cooling); dev_pm_opp_of_remove_table(&pfdev->pdev->dev); + if (pfdev->devfreq.dev_opp_table) + dev_pm_opp_put_regulators(pfdev->devfreq.dev_opp_table); } void panfrost_devfreq_resume(struct panfrost_device *pfdev) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index c30c719a805940a..5009a8b7c853ea1 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -110,6 +110,7 @@ struct panfrost_device { struct { struct devfreq *devfreq; struct thermal_cooling_device *cooling; + struct opp_table *dev_opp_table; ktime_t busy_time; ktime_t idle_time; ktime_t time_last_update; -- 2.25.0.341.g760bfbb309-goog ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel