* [PATCH] thermal: mediatek: add suspend/resume callback
From: michael.kao @ 2019-07-02 9:16 UTC (permalink / raw)
To: Zhang Rui, Eduardo Valentin, Daniel Lezcano, Rob Herring,
Mark Rutland, Matthias Brugger, hsinyi
Cc: linux-pm, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis Yu, Michael Kao
From: Louis Yu <louis.yu@mediatek.com>
Add suspend/resume callback to disable/enable Mediatek thermal sensor
respectively. Since thermal power domain is off in suspend, thermal driver
needs re-initialization during resume.
Signed-off-by: Louis Yu <louis.yu@mediatek.com>
Signed-off-by: Michael Kao <michael.kao@mediatek.com>
---
This patch series base on these patches [1][2][3].
[1]thermal: mediatek: mt8183: fix bank number settings (https://patchwork.kernel.org/patch/10938817/)
[2]thermal: mediatek: add another get_temp ops for thermal sensors (https://patchwork.kernel.org/patch/10938829/)
[3]thermal: mediatek: use spinlock to protect PTPCORESEL (https://patchwork.kernel.org/patch/10938841/)
drivers/thermal/mtk_thermal.c | 134 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 125 insertions(+), 9 deletions(-)
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 3d01153..61d4114 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -30,6 +30,7 @@
#include <linux/thermal.h>
#include <linux/reset.h>
#include <linux/types.h>
+#include <linux/iopoll.h>
/* AUXADC Registers */
#define AUXADC_CON1_SET_V 0x008
@@ -39,6 +40,8 @@
#define APMIXED_SYS_TS_CON1 0x604
+#define APMIXED_SYS_TS_CON1_BUFFER_OFF 0x30
+
/* Thermal Controller Registers */
#define TEMP_MONCTL0 0x000
#define TEMP_MONCTL1 0x004
@@ -46,6 +49,7 @@
#define TEMP_MONIDET0 0x014
#define TEMP_MONIDET1 0x018
#define TEMP_MSRCTL0 0x038
+#define TEMP_MSRCTL1 0x03c
#define TEMP_AHBPOLL 0x040
#define TEMP_AHBTO 0x044
#define TEMP_ADCPNP0 0x048
@@ -95,6 +99,9 @@
#define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5)
#define TEMP_ADCVALIDMASK_VALID_POS(bit) (bit)
+#define TEMP_MSRCTL1_BUS_STA (BIT(0) | BIT(7))
+#define TEMP_MSRCTL1_SENSING_POINTS_PAUSE 0x10E
+
/* MT8173 thermal sensors */
#define MT8173_TS1 0
#define MT8173_TS2 1
@@ -266,6 +273,10 @@ struct mtk_thermal_data {
struct mtk_thermal {
struct device *dev;
void __iomem *thermal_base;
+ void __iomem *apmixed_base;
+ void __iomem *auxadc_base;
+ u64 apmixed_phys_base;
+ u64 auxadc_phys_base;
struct clk *clk_peri_therm;
struct clk *clk_auxadc;
@@ -795,6 +806,42 @@ static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
mtk_thermal_put_bank(bank);
}
+static int mtk_thermal_disable_sensing(struct mtk_thermal *mt, int num)
+{
+ struct mtk_thermal_bank *bank = &mt->banks[num];
+ u32 val;
+ unsigned long timeout;
+ void __iomem *addr;
+ int ret = 0;
+
+ bank->id = num;
+ bank->mt = mt;
+
+ mtk_thermal_get_bank(bank);
+
+ val = readl(mt->thermal_base + TEMP_MSRCTL1);
+ /* pause periodic temperature measurement for sensing points */
+ writel(val | TEMP_MSRCTL1_SENSING_POINTS_PAUSE,
+ mt->thermal_base + TEMP_MSRCTL1);
+
+ /* wait until temperature measurement bus idle */
+ timeout = jiffies + HZ;
+ addr = mt->thermal_base + TEMP_MSRCTL1;
+
+ ret = readl_poll_timeout(addr, val, (val & TEMP_MSRCTL1_BUS_STA) == 0x0,
+ 0, timeout);
+ if (ret < 0)
+ goto out;
+
+ /* disable periodic temperature meausrement on sensing points */
+ writel(0x0, mt->thermal_base + TEMP_MONCTL0);
+
+out:
+ mtk_thermal_put_bank(bank);
+
+ return ret;
+}
+
static u64 of_get_phys_base(struct device_node *np)
{
u64 size64;
@@ -917,7 +964,6 @@ static int mtk_thermal_probe(struct platform_device *pdev)
struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
struct mtk_thermal *mt;
struct resource *res;
- u64 auxadc_phys_base, apmixed_phys_base;
struct thermal_zone_device *tzdev;
struct mtk_thermal_zone *tz;
@@ -954,11 +1000,11 @@ static int mtk_thermal_probe(struct platform_device *pdev)
return -ENODEV;
}
- auxadc_phys_base = of_get_phys_base(auxadc);
+ mt->auxadc_phys_base = of_get_phys_base(auxadc);
of_node_put(auxadc);
- if (auxadc_phys_base == OF_BAD_ADDR) {
+ if (mt->auxadc_phys_base == OF_BAD_ADDR) {
dev_err(&pdev->dev, "Can't get auxadc phys address\n");
return -EINVAL;
}
@@ -969,11 +1015,12 @@ static int mtk_thermal_probe(struct platform_device *pdev)
return -ENODEV;
}
- apmixed_phys_base = of_get_phys_base(apmixedsys);
+ mt->apmixed_phys_base = of_get_phys_base(apmixedsys);
+ mt->apmixed_base = of_iomap(apmixedsys, 0);
of_node_put(apmixedsys);
- if (apmixed_phys_base == OF_BAD_ADDR) {
+ if (mt->apmixed_phys_base == OF_BAD_ADDR) {
dev_err(&pdev->dev, "Can't get auxadc phys address\n");
return -EINVAL;
}
@@ -985,19 +1032,19 @@ static int mtk_thermal_probe(struct platform_device *pdev)
ret = clk_prepare_enable(mt->clk_auxadc);
if (ret) {
dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
- return ret;
+ goto err_disable_clk_auxadc;
}
ret = clk_prepare_enable(mt->clk_peri_therm);
if (ret) {
dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
- goto err_disable_clk_auxadc;
+ goto err_disable_clk_peri_therm;
}
for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
for (i = 0; i < mt->conf->num_banks; i++)
- mtk_thermal_init_bank(mt, i, apmixed_phys_base,
- auxadc_phys_base, ctrl_id);
+ mtk_thermal_init_bank(mt, i, mt->apmixed_phys_base,
+ mt->auxadc_phys_base, ctrl_id);
platform_set_drvdata(pdev, mt);
@@ -1041,11 +1088,80 @@ static int mtk_thermal_remove(struct platform_device *pdev)
return 0;
}
+static int __maybe_unused mtk_thermal_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mtk_thermal *mt = platform_get_drvdata(pdev);
+ int i, ret;
+
+ for (i = 0; i < mt->conf->num_banks; i++) {
+ ret = mtk_thermal_disable_sensing(mt, i);
+ if (ret)
+ goto out;
+ }
+
+ /* disable buffer */
+ writel(readl(mt->apmixed_base + APMIXED_SYS_TS_CON1) |
+ APMIXED_SYS_TS_CON1_BUFFER_OFF,
+ mt->apmixed_base + APMIXED_SYS_TS_CON1);
+
+ clk_disable_unprepare(mt->clk_peri_therm);
+ clk_disable_unprepare(mt->clk_auxadc);
+
+ return 0;
+
+out:
+ dev_err(&pdev->dev, "Failed to wait until bus idle\n");
+
+ return ret;
+}
+
+static int __maybe_unused mtk_thermal_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mtk_thermal *mt = platform_get_drvdata(pdev);
+ int i, ret, ctrl_id;
+
+ ret = device_reset(&pdev->dev);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(mt->clk_auxadc);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
+ goto err_disable_clk_auxadc;
+ }
+
+ ret = clk_prepare_enable(mt->clk_peri_therm);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
+ goto err_disable_clk_peri_therm;
+ }
+
+ for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
+ for (i = 0; i < mt->conf->num_banks; i++)
+ mtk_thermal_init_bank(mt, i, mt->apmixed_phys_base,
+ mt->auxadc_phys_base, ctrl_id);
+
+ return 0;
+
+err_disable_clk_peri_therm:
+ clk_disable_unprepare(mt->clk_peri_therm);
+err_disable_clk_auxadc:
+ clk_disable_unprepare(mt->clk_auxadc);
+
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(mtk_thermal_pm_ops,
+ mtk_thermal_suspend, mtk_thermal_resume);
+
static struct platform_driver mtk_thermal_driver = {
.probe = mtk_thermal_probe,
.remove = mtk_thermal_remove,
.driver = {
.name = "mtk-thermal",
+ .pm = &mtk_thermal_pm_ops,
.of_match_table = mtk_thermal_of_match,
},
};
--
1.9.1
^ permalink raw reply related
* Re: [RFCv2 2/8] clk: imx8m-composite: Switch to determine_rate
From: Abel Vesa @ 2019-07-02 7:13 UTC (permalink / raw)
To: Leonard Crestez
Cc: Alexandre Bailon, Georgi Djakov, Stephen Boyd, Michael Turquette,
Viresh Kumar, MyungJoo Ham, Kyungmin Park, Shawn Guo,
Aisheng Dong, Fabio Estevam, Rafael J. Wysocki, Jacky Bai,
Anson Huang, Krzysztof Kozlowski, Ulf Hansson, Saravana Kannan,
kernel@pengutronix.de, dl-linux-imx, linux-pm@vger.kernel.org,
linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <VI1PR04MB50552AC6EAB0C145D638E618EEFC0@VI1PR04MB5055.eurprd04.prod.outlook.com>
On 19-06-28 08:56:35, Leonard Crestez wrote:
> On 28.06.2019 11:45, Abel Vesa wrote:
> > On 19-06-28 10:39:50, Leonard Crestez wrote:
>
> >> This allows consumers to use min_rate max_rate.
> >>
> >> @@ -45,10 +45,12 @@ static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw,
> >> divider->flags, PCG_DIV_WIDTH);
> >> }
> >>
> >> static int imx8m_clk_composite_compute_dividers(unsigned long rate,
> >> unsigned long parent_rate,
> >> + unsigned long min_rate,
> >> + unsigned long max_rate,
> >
> > You should pass on the req instead of min_rate and max_rate here.
>
> Then I'd have to switch imx8m_clk_composite_divider_set_rate to allocate
> a dummy struct clk_rate_request on the stack. It's clearer if I just
> pass the minimum parameters required.
>
That is correct. Nevermind my earlier comment then.
> --
> Regards,
> Leonard
>
^ permalink raw reply
* [PATCH 2/2] opp: Manage empty OPP tables with clk handle
From: Rajendra Nayak @ 2019-07-02 4:36 UTC (permalink / raw)
To: vireshk, sboyd; +Cc: linux-pm, linux-kernel, linux-arm-msm, Rajendra Nayak
In-Reply-To: <20190702043643.1746-1-rnayak@codeaurora.org>
With OPP core now supporting DVFS for IO devices, we have instances of
IO devices (same IP block) with require an OPP on some platforms/SoCs
while just needing to scale the clock on some others.
In order to avoid conditional code in every driver, (to check for
availability of OPPs and then deciding to do either dev_pm_opp_set_rate()
or clk_set_rate()) add support to manage empty OPP tables with a clk handle.
This makes dev_pm_opp_set_rate() equivalent of a clk_set_rate() for devices
with just a clk and no OPPs specified.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
drivers/opp/core.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index ae033bb1e5b7..fa7d4d6d37b3 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -801,6 +801,11 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
goto put_opp_table;
}
+ if (!_get_opp_count(opp_table)) {
+ ret = _generic_set_opp_clk_only(dev, clk, freq);
+ goto put_opp_table;
+ }
+
temp_freq = old_freq;
old_opp = _find_freq_ceil(opp_table, &temp_freq);
if (IS_ERR(old_opp)) {
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* [PATCH 1/2] opp: Export dev_pm_opp_set_genpd_virt_dev()
From: Rajendra Nayak @ 2019-07-02 4:36 UTC (permalink / raw)
To: vireshk, sboyd; +Cc: linux-pm, linux-kernel, linux-arm-msm, Rajendra Nayak
Export dev_pm_opp_set_genpd_virt_dev() so loadable modules can use it.
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
---
drivers/opp/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 8fbdbedc009c..ae033bb1e5b7 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1797,6 +1797,7 @@ struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev,
return opp_table;
}
+EXPORT_SYMBOL_GPL(dev_pm_opp_set_genpd_virt_dev);
/**
* dev_pm_opp_put_genpd_virt_dev() - Releases resources blocked for genpd device.
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
^ permalink raw reply related
* Re: [PATCH v2 1/5] PM: ACPI/PCI: Resume all devices during hibernation
From: Robert R. Howell @ 2019-07-02 4:24 UTC (permalink / raw)
To: Rafael J. Wysocki, Linux PM
Cc: Linux PCI, Linux ACPI, LKML, Bjorn Helgaas, Andy Shevchenko,
Mika Westerberg, Hans De Goede
In-Reply-To: <6191578.xJk2HsE5MX@kreacher>
On 7/1/19 4:44 AM, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Both the PCI bus type and the ACPI PM domain avoid resuming
> runtime-suspended devices with DPM_FLAG_SMART_SUSPEND set during
> hibernation (before creating the snapshot image of system memory),
> but that turns out to be a mistake. It leads to functional issues
> and adds complexity that's hard to justify.
>
> For this reason, resume all runtime-suspended PCI devices and all
> devices in the ACPI PM domains before creating a snapshot image of
> system memory during hibernation.
>
> Fixes: 05087360fd7a (ACPI / PM: Take SMART_SUSPEND driver flag into account)
> Fixes: c4b65157aeef (PCI / PM: Take SMART_SUSPEND driver flag into account)
> Link: https://lore.kernel.org/linux-acpi/917d4399-2e22-67b1-9d54-808561f9083f@uwyo.edu/T/#maf065fe6e4974f2a9d79f332ab99dfaba635f64c
> Reported-by: Robert R. Howell <RHowell@uwyo.edu>
> Tested-by: Robert R. Howell <RHowell@uwyo.edu>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>
> -> v2: No changes.
I've tested your v2 patch set on my ASUS T100TA, applying just those 5 patches to the
5.2-rc7 kernel, and they do fix the hibernation problem. The i2c_designware
timeout errors are now gone and sound does now work after resume from both
suspend and hibernate.
As before I still see the "i2c_designware 80860F41:00: Transfer while suspended" error
on the first resume from either suspend or hibernate, but also as before that
particular error doesn't seem to cause a persistent problem and the system works
normally after the resume.
Bob Howell
^ permalink raw reply
* [PATCH] PM / Domains: Use seq_puts() in genpd_summary_one()
From: Markus Elfring @ 2019-07-01 19:50 UTC (permalink / raw)
To: linux-pm, Greg Kroah-Hartman, Kevin Hilman, Len Brown,
Pavel Machek, Rafael J. Wysocki, Ulf Hansson
Cc: LKML, kernel-janitors
From: Markus Elfring <elfring@users.sourceforge.net>
Date: Mon, 1 Jul 2019 21:42:31 +0200
A string which did not contain a data format specification should be put
into a sequence. Thus use the corresponding function “seq_puts”.
This issue was detected by using the Coccinelle software.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
drivers/base/power/domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 33c30c1e6a30..7dd433fab7ec 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2796,7 +2796,7 @@ static int genpd_summary_one(struct seq_file *s,
* Also genpd->name is immutable.
*/
list_for_each_entry(link, &genpd->master_links, master_node) {
- seq_printf(s, "%s", link->slave->name);
+ seq_puts(s, link->slave->name);
if (!list_is_last(&link->master_node, &genpd->master_links))
seq_puts(s, ", ");
}
--
2.22.0
^ permalink raw reply related
* Re: [PATCH 4/5] drm/msm/dsi: get the clocks into OFF state at init
From: Rob Clark @ 2019-07-01 19:34 UTC (permalink / raw)
To: Jeffrey Hugo
Cc: dri-devel, linux-arm-msm, freedreno, aarch64-laptops, linux-clk,
Linux PM, Rob Clark, Sean Paul, David Airlie, Daniel Vetter,
Jordan Crouse, Abhinav Kumar, Sibi Sankar, Mamta Shukla,
Chandan Uddaraju, Archit Taneja, Rajesh Yadav,
Linux Kernel Mailing List
In-Reply-To: <9fbf9226-578a-90aa-693d-9ea4fcda8281@codeaurora.org>
On Mon, Jul 1, 2019 at 12:07 PM Jeffrey Hugo <jhugo@codeaurora.org> wrote:
>
> On 7/1/2019 12:58 PM, Rob Clark wrote:
> > On Mon, Jul 1, 2019 at 11:37 AM Jeffrey Hugo <jhugo@codeaurora.org> wrote:
> >>
> >> On 6/30/2019 9:01 AM, Rob Clark wrote:
> >>> From: Rob Clark <robdclark@chromium.org>
> >>>
> >>> Do an extra enable/disable cycle at init, to get the clks into disabled
> >>> state in case bootloader left them enabled.
> >>>
> >>> In case they were already enabled, the clk_prepare_enable() has no real
> >>> effect, other than getting the enable_count/prepare_count into the right
> >>> state so that we can disable clocks in the correct order. This way we
> >>> avoid having stuck clocks when we later want to do a modeset and set the
> >>> clock rates.
> >>>
> >>> Signed-off-by: Rob Clark <robdclark@chromium.org>
> >>> ---
> >>> drivers/gpu/drm/msm/dsi/dsi_host.c | 18 +++++++++++++++---
> >>> drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 1 +
> >>> 2 files changed, 16 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> >>> index aabab6311043..d0172d8db882 100644
> >>> --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> >>> +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> >>> @@ -354,6 +354,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
> >>> if (rc)
> >>> pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
> >>> pll->id, status);
> >>> +rc = 0; // HACK, this will fail if PLL already running..
> >>
> >> Umm, why? Is this intentional?
> >>
> >
> > I need to sort out a proper solution for this.. but PLL lock will fail
> > if the clk is already running (which, in that case, is fine since it
> > is already running and locked), which will cause the clk_enable to
> > fail..
> >
> > I guess there is some way that I can check that clk is already running
> > and skip this check..
>
>
> I'm sorry, but this makes no sense to me. What clock are we talking
> about here?
>
> If the pll is locked, the the lock check should just drop through. If
> the pll cannot lock, you have an issue. I'm confused as to how any of
> the downstream clocks can actually be running if the pll isn't locked.
>
> I feel like we are not yet on the same page about what situation you
> seem to be in. Can you describe in exacting detail?
yeah, I'd expect the lock bit to still be set (since the display is
obviously running at that point).. but I didn't really debug it yet,
I just hacked that in so the clk_enable didn't fail, so that we could
get correct enable/prepare_counts in order to do the
clk_disable_unprepare()..
BR,
-R
^ permalink raw reply
* Re: [PATCH 4/5] drm/msm/dsi: get the clocks into OFF state at init
From: Jeffrey Hugo @ 2019-07-01 19:07 UTC (permalink / raw)
To: Rob Clark
Cc: dri-devel, linux-arm-msm, freedreno, aarch64-laptops, linux-clk,
Linux PM, Rob Clark, Sean Paul, David Airlie, Daniel Vetter,
Jordan Crouse, Abhinav Kumar, Sibi Sankar, Mamta Shukla,
Chandan Uddaraju, Archit Taneja, Rajesh Yadav,
Linux Kernel Mailing List
In-Reply-To: <CAF6AEGufiSU_sFZFdLH=KT5iCQGwccszURqAQCHd=dhuZafvZg@mail.gmail.com>
On 7/1/2019 12:58 PM, Rob Clark wrote:
> On Mon, Jul 1, 2019 at 11:37 AM Jeffrey Hugo <jhugo@codeaurora.org> wrote:
>>
>> On 6/30/2019 9:01 AM, Rob Clark wrote:
>>> From: Rob Clark <robdclark@chromium.org>
>>>
>>> Do an extra enable/disable cycle at init, to get the clks into disabled
>>> state in case bootloader left them enabled.
>>>
>>> In case they were already enabled, the clk_prepare_enable() has no real
>>> effect, other than getting the enable_count/prepare_count into the right
>>> state so that we can disable clocks in the correct order. This way we
>>> avoid having stuck clocks when we later want to do a modeset and set the
>>> clock rates.
>>>
>>> Signed-off-by: Rob Clark <robdclark@chromium.org>
>>> ---
>>> drivers/gpu/drm/msm/dsi/dsi_host.c | 18 +++++++++++++++---
>>> drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 1 +
>>> 2 files changed, 16 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
>>> index aabab6311043..d0172d8db882 100644
>>> --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
>>> +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
>>> @@ -354,6 +354,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
>>> if (rc)
>>> pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
>>> pll->id, status);
>>> +rc = 0; // HACK, this will fail if PLL already running..
>>
>> Umm, why? Is this intentional?
>>
>
> I need to sort out a proper solution for this.. but PLL lock will fail
> if the clk is already running (which, in that case, is fine since it
> is already running and locked), which will cause the clk_enable to
> fail..
>
> I guess there is some way that I can check that clk is already running
> and skip this check..
I'm sorry, but this makes no sense to me. What clock are we talking
about here?
If the pll is locked, the the lock check should just drop through. If
the pll cannot lock, you have an issue. I'm confused as to how any of
the downstream clocks can actually be running if the pll isn't locked.
I feel like we are not yet on the same page about what situation you
seem to be in. Can you describe in exacting detail?
^ permalink raw reply
* Re: [PATCH 1/5] clk: inherit clocks enabled by bootloader
From: Rob Clark @ 2019-07-01 19:05 UTC (permalink / raw)
To: Eric Anholt
Cc: dri-devel, linux-arm-msm, Rob Clark, aarch64-laptops, Linux PM,
Stephen Boyd, Michael Turquette, Linux Kernel Mailing List,
Andy Gross, freedreno, linux-clk
In-Reply-To: <8736jpzk67.fsf@anholt.net>
On Mon, Jul 1, 2019 at 11:25 AM Eric Anholt <eric@anholt.net> wrote:
>
> Rob Clark <robdclark@gmail.com> writes:
>
> > From: Rob Clark <robdclark@chromium.org>
> >
> > The goal here is to support inheriting a display setup by bootloader,
> > although there may also be some non-display related use-cases.
> >
> > Rough idea is to add a flag for clks and power domains that might
> > already be enabled when kernel starts, and which should not be
> > disabled at late_initcall if the kernel thinks they are "unused".
> >
> > If bootloader is enabling display, and kernel is using efifb before
> > real display driver is loaded (potentially from kernel module after
> > userspace starts, in a typical distro kernel), we don't want to kill
> > the clocks and power domains that are used by the display before
> > userspace starts.
> >
> > Signed-off-by: Rob Clark <robdclark@chromium.org>
>
> Raspberry Pi is carrying downstream hacks to do similar stuff, and it
> would be great to see CCF finally support this.
yeah, both this and the multiple-possible-panel thing are a big source
of downstream hacks on basically every android device too.. :-/
it certainly would be nice to have upstream solutions for these
problems to give downstream hacks a reason not to exist
BR,
-R
^ permalink raw reply
* Re: [PATCH 4/5] drm/msm/dsi: get the clocks into OFF state at init
From: Rob Clark @ 2019-07-01 18:58 UTC (permalink / raw)
To: Jeffrey Hugo
Cc: dri-devel, linux-arm-msm, freedreno, aarch64-laptops, linux-clk,
Linux PM, Rob Clark, Sean Paul, David Airlie, Daniel Vetter,
Jordan Crouse, Abhinav Kumar, Sibi Sankar, Mamta Shukla,
Chandan Uddaraju, Archit Taneja, Rajesh Yadav,
Linux Kernel Mailing List
In-Reply-To: <75a2921d-bf1a-c4c1-6d9a-122474eface4@codeaurora.org>
On Mon, Jul 1, 2019 at 11:37 AM Jeffrey Hugo <jhugo@codeaurora.org> wrote:
>
> On 6/30/2019 9:01 AM, Rob Clark wrote:
> > From: Rob Clark <robdclark@chromium.org>
> >
> > Do an extra enable/disable cycle at init, to get the clks into disabled
> > state in case bootloader left them enabled.
> >
> > In case they were already enabled, the clk_prepare_enable() has no real
> > effect, other than getting the enable_count/prepare_count into the right
> > state so that we can disable clocks in the correct order. This way we
> > avoid having stuck clocks when we later want to do a modeset and set the
> > clock rates.
> >
> > Signed-off-by: Rob Clark <robdclark@chromium.org>
> > ---
> > drivers/gpu/drm/msm/dsi/dsi_host.c | 18 +++++++++++++++---
> > drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 1 +
> > 2 files changed, 16 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> > index aabab6311043..d0172d8db882 100644
> > --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> > +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> > @@ -354,6 +354,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
> > if (rc)
> > pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
> > pll->id, status);
> > +rc = 0; // HACK, this will fail if PLL already running..
>
> Umm, why? Is this intentional?
>
I need to sort out a proper solution for this.. but PLL lock will fail
if the clk is already running (which, in that case, is fine since it
is already running and locked), which will cause the clk_enable to
fail..
I guess there is some way that I can check that clk is already running
and skip this check..
BR,
-R
^ permalink raw reply
* [patch 2/5] cpuidle: add get_poll_time callback
From: Marcelo Tosatti @ 2019-07-01 18:53 UTC (permalink / raw)
To: kvm, linux-pm
Cc: Paolo Bonzini, Radim Krcmar, Andrea Arcangeli, Rafael J. Wysocki,
Peter Zijlstra, Wanpeng Li, Konrad Rzeszutek Wilk,
Raslan KarimAllah, Boris Ostrovsky, Ankur Arora,
Christian Borntraeger, Marcelo Tosatti
In-Reply-To: <20190701185310.540706841@asus.localdomain>
Add a "get_poll_time" callback to the cpuidle_governor structure,
and change poll state to poll for that amount of time.
Provide a default method for it, while allowing individual governors
to override it.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
drivers/cpuidle/cpuidle.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/cpuidle/poll_state.c | 11 ++---------
include/linux/cpuidle.h | 8 ++++++++
3 files changed, 50 insertions(+), 9 deletions(-)
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle.c
===================================================================
--- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/cpuidle.c
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle.c
@@ -362,6 +362,46 @@ void cpuidle_reflect(struct cpuidle_devi
}
/**
+ * cpuidle_default_poll_time - default routine used to return poll time
+ * governors can override it if necessary
+ *
+ * @drv: the cpuidle driver tied with the cpu
+ * @dev: the cpuidle device
+ *
+ */
+static u64 cpuidle_default_poll_time(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+{
+ int i;
+
+ for (i = 1; i < drv->state_count; i++) {
+ if (drv->states[i].disabled || dev->states_usage[i].disable)
+ continue;
+
+ return (u64)drv->states[i].target_residency * NSEC_PER_USEC;
+ }
+
+ return TICK_NSEC;
+}
+
+/**
+ * cpuidle_get_poll_time - tell the polling driver how much time to poll,
+ * in nanoseconds.
+ *
+ * @drv: the cpuidle driver tied with the cpu
+ * @dev: the cpuidle device
+ *
+ */
+u64 cpuidle_get_poll_time(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+{
+ if (cpuidle_curr_governor->get_poll_time)
+ return cpuidle_curr_governor->get_poll_time(drv, dev);
+
+ return cpuidle_default_poll_time(drv, dev);
+}
+
+/**
* cpuidle_install_idle_handler - installs the cpuidle idle loop handler
*/
void cpuidle_install_idle_handler(void)
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/poll_state.c
===================================================================
--- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/poll_state.c
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/poll_state.c
@@ -20,16 +20,9 @@ static int __cpuidle poll_idle(struct cp
local_irq_enable();
if (!current_set_polling_and_test()) {
unsigned int loop_count = 0;
- u64 limit = TICK_NSEC;
- int i;
+ u64 limit;
- for (i = 1; i < drv->state_count; i++) {
- if (drv->states[i].disabled || dev->states_usage[i].disable)
- continue;
-
- limit = (u64)drv->states[i].target_residency * NSEC_PER_USEC;
- break;
- }
+ limit = cpuidle_get_poll_time(drv, dev);
while (!need_resched()) {
cpu_relax();
Index: linux-2.6-newcpuidle.git/include/linux/cpuidle.h
===================================================================
--- linux-2.6-newcpuidle.git.orig/include/linux/cpuidle.h
+++ linux-2.6-newcpuidle.git/include/linux/cpuidle.h
@@ -132,6 +132,8 @@ extern int cpuidle_select(struct cpuidle
extern int cpuidle_enter(struct cpuidle_driver *drv,
struct cpuidle_device *dev, int index);
extern void cpuidle_reflect(struct cpuidle_device *dev, int index);
+extern u64 cpuidle_get_poll_time(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev);
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
extern struct cpuidle_driver *cpuidle_get_driver(void);
@@ -166,6 +168,9 @@ static inline int cpuidle_enter(struct c
struct cpuidle_device *dev, int index)
{return -ENODEV; }
static inline void cpuidle_reflect(struct cpuidle_device *dev, int index) { }
+extern u64 cpuidle_get_poll_time(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+{return 0; }
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
{return -ENODEV; }
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
@@ -246,6 +251,9 @@ struct cpuidle_governor {
struct cpuidle_device *dev,
bool *stop_tick);
void (*reflect) (struct cpuidle_device *dev, int index);
+
+ u64 (*get_poll_time) (struct cpuidle_driver *drv,
+ struct cpuidle_device *dev);
};
#ifdef CONFIG_CPU_IDLE
^ permalink raw reply
* [patch 3/5] cpuidle: add haltpoll governor
From: Marcelo Tosatti @ 2019-07-01 18:53 UTC (permalink / raw)
To: kvm, linux-pm
Cc: Paolo Bonzini, Radim Krcmar, Andrea Arcangeli, Rafael J. Wysocki,
Peter Zijlstra, Wanpeng Li, Konrad Rzeszutek Wilk,
Raslan KarimAllah, Boris Ostrovsky, Ankur Arora,
Christian Borntraeger, Marcelo Tosatti
In-Reply-To: <20190701185310.540706841@asus.localdomain>
The cpuidle_haltpoll governor, in conjunction with the haltpoll cpuidle
driver, allows guest vcpus to poll for a specified amount of time before
halting.
This provides the following benefits to host side polling:
1) The POLL flag is set while polling is performed, which allows
a remote vCPU to avoid sending an IPI (and the associated
cost of handling the IPI) when performing a wakeup.
2) The VM-exit cost can be avoided.
The downside of guest side polling is that polling is performed
even with other runnable tasks in the host.
Results comparing halt_poll_ns and server/client application
where a small packet is ping-ponged:
host --> 31.33
halt_poll_ns=300000 / no guest busy spin --> 33.40 (93.8%)
halt_poll_ns=0 / guest_halt_poll_ns=300000 --> 32.73 (95.7%)
For the SAP HANA benchmarks (where idle_spin is a parameter
of the previous version of the patch, results should be the
same):
hpns == halt_poll_ns
idle_spin=0/ idle_spin=800/ idle_spin=0/
hpns=200000 hpns=0 hpns=800000
DeleteC06T03 (100 thread) 1.76 1.71 (-3%) 1.78 (+1%)
InsertC16T02 (100 thread) 2.14 2.07 (-3%) 2.18 (+1.8%)
DeleteC00T01 (1 thread) 1.34 1.28 (-4.5%) 1.29 (-3.7%)
UpdateC00T03 (1 thread) 4.72 4.18 (-12%) 4.53 (-5%)
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
Documentation/virtual/guest-halt-polling.txt | 79 ++++++++++++
drivers/cpuidle/Kconfig | 11 +
drivers/cpuidle/governors/Makefile | 1
drivers/cpuidle/governors/haltpoll.c | 175 +++++++++++++++++++++++++++
4 files changed, 266 insertions(+)
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/Kconfig
===================================================================
--- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/Kconfig
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/Kconfig
@@ -33,6 +33,17 @@ config CPU_IDLE_GOV_TEO
Some workloads benefit from using it and it generally should be safe
to use. Say Y here if you are not happy with the alternatives.
+config CPU_IDLE_GOV_HALTPOLL
+ bool "Haltpoll governor (for virtualized systems)"
+ depends on KVM_GUEST
+ help
+ This governor implements haltpoll idle state selection, to be
+ used in conjunction with the haltpoll cpuidle driver, allowing
+ for polling for a certain amount of time before entering idle
+ state.
+
+ Some virtualized workloads benefit from using it.
+
config DT_IDLE_STATES
bool
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/governors/Makefile
===================================================================
--- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/governors/Makefile
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/governors/Makefile
@@ -6,3 +6,4 @@
obj-$(CONFIG_CPU_IDLE_GOV_LADDER) += ladder.o
obj-$(CONFIG_CPU_IDLE_GOV_MENU) += menu.o
obj-$(CONFIG_CPU_IDLE_GOV_TEO) += teo.o
+obj-$(CONFIG_CPU_IDLE_GOV_HALTPOLL) += haltpoll.o
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/governors/haltpoll.c
===================================================================
--- /dev/null
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/governors/haltpoll.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * haltpoll.c - haltpoll idle governor
+ *
+ * Copyright 2019 Red Hat, Inc. and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Authors: Marcelo Tosatti <mtosatti@redhat.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kvm_para.h>
+
+static unsigned int guest_halt_poll_us __read_mostly = 200;
+module_param(guest_halt_poll_us, uint, 0644);
+
+/* division factor to shrink halt_poll_us */
+static unsigned int guest_halt_poll_shrink __read_mostly = 2;
+module_param(guest_halt_poll_shrink, uint, 0644);
+
+/* multiplication factor to grow per-cpu halt_poll_us */
+static unsigned int guest_halt_poll_grow __read_mostly = 2;
+module_param(guest_halt_poll_grow, uint, 0644);
+
+/* value in us to start growing per-cpu halt_poll_us */
+static unsigned int guest_halt_poll_grow_start __read_mostly = 50;
+module_param(guest_halt_poll_grow_start, uint, 0644);
+
+/* allow shrinking guest halt poll */
+static bool guest_halt_poll_allow_shrink __read_mostly = true;
+module_param(guest_halt_poll_allow_shrink, bool, 0644);
+
+struct haltpoll_device {
+ int last_state_idx;
+ unsigned int halt_poll_us;
+};
+
+static DEFINE_PER_CPU_ALIGNED(struct haltpoll_device, hpoll_devices);
+
+/**
+ * haltpoll_select - selects the next idle state to enter
+ * @drv: cpuidle driver containing state data
+ * @dev: the CPU
+ * @stop_tick: indication on whether or not to stop the tick
+ */
+static int haltpoll_select(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev,
+ bool *stop_tick)
+{
+ struct haltpoll_device *hdev = this_cpu_ptr(&hpoll_devices);
+ int latency_req = cpuidle_governor_latency_req(dev->cpu);
+
+ if (!drv->state_count || latency_req == 0) {
+ *stop_tick = false;
+ return 0;
+ }
+
+ if (hdev->halt_poll_us == 0)
+ return 1;
+
+ /* Last state was poll? */
+ if (hdev->last_state_idx == 0) {
+ /* Halt if no event occurred on poll window */
+ if (dev->poll_time_limit == true)
+ return 1;
+
+ *stop_tick = false;
+ /* Otherwise, poll again */
+ return 0;
+ }
+
+ *stop_tick = false;
+ /* Last state was halt: poll */
+ return 0;
+}
+
+static void adjust_haltpoll_us(unsigned int block_us,
+ struct haltpoll_device *dev)
+{
+ unsigned int val;
+
+ /* Grow cpu_halt_poll_us if
+ * cpu_halt_poll_us < block_ns < guest_halt_poll_us
+ */
+ if (block_us > dev->halt_poll_us && block_us <= guest_halt_poll_us) {
+ val = dev->halt_poll_us * guest_halt_poll_grow;
+
+ if (val < guest_halt_poll_grow_start)
+ val = guest_halt_poll_grow_start;
+ if (val > guest_halt_poll_us)
+ val = guest_halt_poll_us;
+
+ dev->halt_poll_us = val;
+ } else if (block_us > guest_halt_poll_us &&
+ guest_halt_poll_allow_shrink) {
+ unsigned int shrink = guest_halt_poll_shrink;
+
+ val = dev->halt_poll_us;
+ if (shrink == 0)
+ val = 0;
+ else
+ val /= shrink;
+ dev->halt_poll_us = val;
+ }
+}
+
+/**
+ * haltpoll_reflect - update variables and update poll time
+ * @dev: the CPU
+ * @index: the index of actual entered state
+ */
+static void haltpoll_reflect(struct cpuidle_device *dev, int index)
+{
+ struct haltpoll_device *hdev = this_cpu_ptr(&hpoll_devices);
+
+ hdev->last_state_idx = index;
+
+ if (index != 0)
+ adjust_haltpoll_us(dev->last_residency, hdev);
+}
+
+/**
+ * haltpoll_enable_device - scans a CPU's states and does setup
+ * @drv: cpuidle driver
+ * @dev: the CPU
+ */
+static int haltpoll_enable_device(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+{
+ struct haltpoll_device *hdev = &per_cpu(hpoll_devices, dev->cpu);
+
+ memset(hdev, 0, sizeof(struct haltpoll_device));
+
+ return 0;
+}
+
+/**
+ * haltpoll_get_poll_time - return amount of poll time
+ * @drv: cpuidle driver
+ * @dev: the CPU
+ */
+static u64 haltpoll_get_poll_time(struct cpuidle_driver *drv,
+ struct cpuidle_device *dev)
+{
+ struct haltpoll_device *hdev = &per_cpu(hpoll_devices, dev->cpu);
+
+ return hdev->halt_poll_us * NSEC_PER_USEC;
+}
+
+static struct cpuidle_governor haltpoll_governor = {
+ .name = "haltpoll",
+ .rating = 21,
+ .enable = haltpoll_enable_device,
+ .select = haltpoll_select,
+ .reflect = haltpoll_reflect,
+ .get_poll_time = haltpoll_get_poll_time,
+};
+
+static int __init init_haltpoll(void)
+{
+ if (kvm_para_available())
+ return cpuidle_register_governor(&haltpoll_governor);
+
+ return 0;
+}
+
+postcore_initcall(init_haltpoll);
Index: linux-2.6-newcpuidle.git/Documentation/virtual/guest-halt-polling.txt
===================================================================
--- /dev/null
+++ linux-2.6-newcpuidle.git/Documentation/virtual/guest-halt-polling.txt
@@ -0,0 +1,79 @@
+Guest halt polling
+==================
+
+The cpuidle_haltpoll driver, with the haltpoll governor, allows
+the guest vcpus to poll for a specified amount of time before
+halting.
+This provides the following benefits to host side polling:
+
+ 1) The POLL flag is set while polling is performed, which allows
+ a remote vCPU to avoid sending an IPI (and the associated
+ cost of handling the IPI) when performing a wakeup.
+
+ 2) The VM-exit cost can be avoided.
+
+The downside of guest side polling is that polling is performed
+even with other runnable tasks in the host.
+
+The basic logic as follows: A global value, guest_halt_poll_us,
+is configured by the user, indicating the maximum amount of
+time polling is allowed. This value is fixed.
+
+Each vcpu has an adjustable guest_halt_poll_us
+("per-cpu guest_halt_poll_us"), which is adjusted by the algorithm
+in response to events (explained below).
+
+Module Parameters
+=================
+
+The haltpoll governor has 5 tunable module parameters:
+
+1) guest_halt_poll_us:
+Maximum amount of time, in microseconds, that polling is
+performed before halting.
+
+Default: 200
+
+2) guest_halt_poll_shrink:
+Division factor used to shrink per-cpu guest_halt_poll_us when
+wakeup event occurs after the global guest_halt_poll_us.
+
+Default: 2
+
+3) guest_halt_poll_grow:
+Multiplication factor used to grow per-cpu guest_halt_poll_us
+when event occurs after per-cpu guest_halt_poll_us
+but before global guest_halt_poll_us.
+
+Default: 2
+
+4) guest_halt_poll_grow_start:
+The per-cpu guest_halt_poll_us eventually reaches zero
+in case of an idle system. This value sets the initial
+per-cpu guest_halt_poll_us when growing. This can
+be increased from 10, to avoid misses during the initial
+growth stage:
+
+10, 20, 40, ... (example assumes guest_halt_poll_grow=2).
+
+Default: 50
+
+5) guest_halt_poll_allow_shrink:
+
+Bool parameter which allows shrinking. Set to N
+to avoid it (per-cpu guest_halt_poll_us will remain
+high once achieves global guest_halt_poll_us value).
+
+Default: Y
+
+The module parameters can be set from the debugfs files in:
+
+ /sys/module/haltpoll/parameters/
+
+Further Notes
+=============
+
+- Care should be taken when setting the guest_halt_poll_us parameter as a
+large value has the potential to drive the cpu usage to 100% on a machine which
+would be almost entirely idle otherwise.
+
^ permalink raw reply
* [patch 1/5] add cpuidle-haltpoll driver
From: Marcelo Tosatti @ 2019-07-01 18:53 UTC (permalink / raw)
To: kvm, linux-pm
Cc: Paolo Bonzini, Radim Krcmar, Andrea Arcangeli, Rafael J. Wysocki,
Peter Zijlstra, Wanpeng Li, Konrad Rzeszutek Wilk,
Raslan KarimAllah, Boris Ostrovsky, Ankur Arora,
Christian Borntraeger, Marcelo Tosatti
In-Reply-To: <20190701185310.540706841@asus.localdomain>
Add a cpuidle driver that calls the architecture default_idle routine.
To be used in conjunction with the haltpoll governor.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
arch/x86/kernel/process.c | 2 -
drivers/cpuidle/Kconfig | 9 +++++
drivers/cpuidle/Makefile | 1
drivers/cpuidle/cpuidle-haltpoll.c | 65 +++++++++++++++++++++++++++++++++++++
4 files changed, 76 insertions(+), 1 deletion(-)
Index: linux-2.6-newcpuidle.git/arch/x86/kernel/process.c
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/kernel/process.c
+++ linux-2.6-newcpuidle.git/arch/x86/kernel/process.c
@@ -580,7 +580,7 @@ void __cpuidle default_idle(void)
safe_halt();
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
}
-#ifdef CONFIG_APM_MODULE
+#if defined(CONFIG_APM_MODULE) || defined(CONFIG_HALTPOLL_CPUIDLE_MODULE)
EXPORT_SYMBOL(default_idle);
#endif
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/Kconfig
===================================================================
--- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/Kconfig
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/Kconfig
@@ -51,6 +51,15 @@ depends on PPC
source "drivers/cpuidle/Kconfig.powerpc"
endmenu
+config HALTPOLL_CPUIDLE
+ tristate "Halt poll cpuidle driver"
+ depends on X86 && KVM_GUEST
+ default y
+ help
+ This option enables halt poll cpuidle driver, which allows to poll
+ before halting in the guest (more efficient than polling in the
+ host via halt_poll_ns for some scenarios).
+
endif
config ARCH_NEEDS_CPU_IDLE_COUPLED
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/Makefile
===================================================================
--- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/Makefile
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/Makefile
@@ -7,6 +7,7 @@ obj-y += cpuidle.o driver.o governor.o s
obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
obj-$(CONFIG_DT_IDLE_STATES) += dt_idle_states.o
obj-$(CONFIG_ARCH_HAS_CPU_RELAX) += poll_state.o
+obj-$(CONFIG_HALTPOLL_CPUIDLE) += cpuidle-haltpoll.o
##################################################################################
# ARM SoC drivers
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c
===================================================================
--- /dev/null
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * cpuidle driver for haltpoll governor.
+ *
+ * Copyright 2019 Red Hat, Inc. and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Authors: Marcelo Tosatti <mtosatti@redhat.com>
+ */
+
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <linux/sched/idle.h>
+#include <linux/kvm_para.h>
+
+static int default_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ if (current_clr_polling_and_test()) {
+ local_irq_enable();
+ return index;
+ }
+ default_idle();
+ return index;
+}
+
+static struct cpuidle_driver haltpoll_driver = {
+ .name = "haltpoll",
+ .owner = THIS_MODULE,
+ .states = {
+ { /* entry 0 is for polling */ },
+ {
+ .enter = default_enter_idle,
+ .exit_latency = 1,
+ .target_residency = 1,
+ .power_usage = -1,
+ .name = "haltpoll idle",
+ .desc = "default architecture idle",
+ },
+ },
+ .safe_state_index = 0,
+ .state_count = 2,
+};
+
+static int __init haltpoll_init(void)
+{
+ struct cpuidle_driver *drv = &haltpoll_driver;
+
+ cpuidle_poll_state_init(drv);
+
+ if (!kvm_para_available())
+ return 0;
+
+ return cpuidle_register(&haltpoll_driver, NULL);
+}
+
+static void __exit haltpoll_exit(void)
+{
+ cpuidle_unregister(&haltpoll_driver);
+}
+
+module_init(haltpoll_init);
+module_exit(haltpoll_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marcelo Tosatti <mtosatti@redhat.com>");
+
^ permalink raw reply
* [patch 4/5] kvm: x86: add host poll control msrs
From: Marcelo Tosatti @ 2019-07-01 18:53 UTC (permalink / raw)
To: kvm, linux-pm
Cc: Paolo Bonzini, Radim Krcmar, Andrea Arcangeli, Rafael J. Wysocki,
Peter Zijlstra, Wanpeng Li, Konrad Rzeszutek Wilk,
Raslan KarimAllah, Boris Ostrovsky, Ankur Arora,
Christian Borntraeger, Marcelo Tosatti
In-Reply-To: <20190701185310.540706841@asus.localdomain>
Add an MSRs which allows the guest to disable
host polling (specifically the cpuidle-haltpoll,
when performing polling in the guest, disables
host side polling).
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
Documentation/virtual/kvm/msr.txt | 9 +++++++++
arch/x86/include/asm/kvm_host.h | 2 ++
arch/x86/include/uapi/asm/kvm_para.h | 2 ++
arch/x86/kvm/Kconfig | 1 +
arch/x86/kvm/cpuid.c | 3 ++-
arch/x86/kvm/x86.c | 23 +++++++++++++++++++++++
6 files changed, 39 insertions(+), 1 deletion(-)
Index: linux-2.6-newcpuidle.git/Documentation/virtual/kvm/msr.txt
===================================================================
--- linux-2.6-newcpuidle.git.orig/Documentation/virtual/kvm/msr.txt
+++ linux-2.6-newcpuidle.git/Documentation/virtual/kvm/msr.txt
@@ -273,3 +273,12 @@ MSR_KVM_EOI_EN: 0x4b564d04
guest must both read the least significant bit in the memory area and
clear it using a single CPU instruction, such as test and clear, or
compare and exchange.
+
+MSR_KVM_POLL_CONTROL: 0x4b564d05
+ Control host side polling.
+
+ data: Bit 0 enables (1) or disables (0) host halt poll
+ logic.
+ KVM guests can disable host halt polling when performing
+ polling themselves.
+
Index: linux-2.6-newcpuidle.git/arch/x86/include/asm/kvm_host.h
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/include/asm/kvm_host.h
+++ linux-2.6-newcpuidle.git/arch/x86/include/asm/kvm_host.h
@@ -752,6 +752,8 @@ struct kvm_vcpu_arch {
struct gfn_to_hva_cache data;
} pv_eoi;
+ u64 msr_kvm_poll_control;
+
/*
* Indicate whether the access faults on its page table in guest
* which is set when fix page fault and used to detect unhandeable
Index: linux-2.6-newcpuidle.git/arch/x86/include/uapi/asm/kvm_para.h
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/include/uapi/asm/kvm_para.h
+++ linux-2.6-newcpuidle.git/arch/x86/include/uapi/asm/kvm_para.h
@@ -29,6 +29,7 @@
#define KVM_FEATURE_PV_TLB_FLUSH 9
#define KVM_FEATURE_ASYNC_PF_VMEXIT 10
#define KVM_FEATURE_PV_SEND_IPI 11
+#define KVM_FEATURE_POLL_CONTROL 12
#define KVM_HINTS_REALTIME 0
@@ -47,6 +48,7 @@
#define MSR_KVM_ASYNC_PF_EN 0x4b564d02
#define MSR_KVM_STEAL_TIME 0x4b564d03
#define MSR_KVM_PV_EOI_EN 0x4b564d04
+#define MSR_KVM_POLL_CONTROL 0x4b564d05
struct kvm_steal_time {
__u64 steal;
Index: linux-2.6-newcpuidle.git/arch/x86/kvm/Kconfig
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/kvm/Kconfig
+++ linux-2.6-newcpuidle.git/arch/x86/kvm/Kconfig
@@ -41,6 +41,7 @@ config KVM
select PERF_EVENTS
select HAVE_KVM_MSI
select HAVE_KVM_CPU_RELAX_INTERCEPT
+ select HAVE_KVM_NO_POLL
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
select KVM_VFIO
select SRCU
Index: linux-2.6-newcpuidle.git/arch/x86/kvm/cpuid.c
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/kvm/cpuid.c
+++ linux-2.6-newcpuidle.git/arch/x86/kvm/cpuid.c
@@ -640,7 +640,8 @@ static inline int __do_cpuid_ent(struct
(1 << KVM_FEATURE_PV_UNHALT) |
(1 << KVM_FEATURE_PV_TLB_FLUSH) |
(1 << KVM_FEATURE_ASYNC_PF_VMEXIT) |
- (1 << KVM_FEATURE_PV_SEND_IPI);
+ (1 << KVM_FEATURE_PV_SEND_IPI) |
+ (1 << KVM_FEATURE_POLL_CONTROL);
if (sched_info_on())
entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
Index: linux-2.6-newcpuidle.git/arch/x86/kvm/x86.c
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/kvm/x86.c
+++ linux-2.6-newcpuidle.git/arch/x86/kvm/x86.c
@@ -1174,6 +1174,7 @@ static u32 emulated_msrs[] = {
MSR_IA32_POWER_CTL,
MSR_K7_HWCR,
+ MSR_KVM_POLL_CONTROL,
};
static unsigned num_emulated_msrs;
@@ -2625,6 +2626,14 @@ int kvm_set_msr_common(struct kvm_vcpu *
return 1;
break;
+ case MSR_KVM_POLL_CONTROL:
+ /* only enable bit supported */
+ if (data & (-1ULL << 1))
+ return 1;
+
+ vcpu->arch.msr_kvm_poll_control = data;
+ break;
+
case MSR_IA32_MCG_CTL:
case MSR_IA32_MCG_STATUS:
case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1:
@@ -2874,6 +2883,9 @@ int kvm_get_msr_common(struct kvm_vcpu *
case MSR_KVM_PV_EOI_EN:
msr_info->data = vcpu->arch.pv_eoi.msr_val;
break;
+ case MSR_KVM_POLL_CONTROL:
+ msr_info->data = vcpu->arch.msr_kvm_poll_control;
+ break;
case MSR_IA32_P5_MC_ADDR:
case MSR_IA32_P5_MC_TYPE:
case MSR_IA32_MCG_CAP:
@@ -8874,6 +8886,10 @@ void kvm_arch_vcpu_postcreate(struct kvm
msr.host_initiated = true;
kvm_write_tsc(vcpu, &msr);
vcpu_put(vcpu);
+
+ /* poll control enabled by default */
+ vcpu->arch.msr_kvm_poll_control = 1;
+
mutex_unlock(&vcpu->mutex);
if (!kvmclock_periodic_sync)
@@ -9948,6 +9964,13 @@ bool kvm_vector_hashing_enabled(void)
}
EXPORT_SYMBOL_GPL(kvm_vector_hashing_enabled);
+bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
+{
+ return (vcpu->arch.msr_kvm_poll_control & 1) == 0;
+}
+EXPORT_SYMBOL_GPL(kvm_arch_no_poll);
+
+
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_fast_mmio);
EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
^ permalink raw reply
* [patch 5/5] cpuidle-haltpoll: disable host side polling when kvm virtualized
From: Marcelo Tosatti @ 2019-07-01 18:53 UTC (permalink / raw)
To: kvm, linux-pm
Cc: Paolo Bonzini, Radim Krcmar, Andrea Arcangeli, Rafael J. Wysocki,
Peter Zijlstra, Wanpeng Li, Konrad Rzeszutek Wilk,
Raslan KarimAllah, Boris Ostrovsky, Ankur Arora,
Christian Borntraeger, Marcelo Tosatti
In-Reply-To: <20190701185310.540706841@asus.localdomain>
When performing guest side polling, it is not necessary to
also perform host side polling.
So disable host side polling, via the new MSR interface,
when loading cpuidle-haltpoll driver.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
arch/x86/Kconfig | 7 +++++
arch/x86/include/asm/cpuidle_haltpoll.h | 8 ++++++
arch/x86/kernel/kvm.c | 42 ++++++++++++++++++++++++++++++++
drivers/cpuidle/cpuidle-haltpoll.c | 10 ++++++-
include/linux/cpuidle_haltpoll.h | 16 ++++++++++++
5 files changed, 82 insertions(+), 1 deletion(-)
Index: linux-2.6-newcpuidle.git/arch/x86/include/asm/cpuidle_haltpoll.h
===================================================================
--- /dev/null
+++ linux-2.6-newcpuidle.git/arch/x86/include/asm/cpuidle_haltpoll.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ARCH_HALTPOLL_H
+#define _ARCH_HALTPOLL_H
+
+void arch_haltpoll_enable(void);
+void arch_haltpoll_disable(void);
+
+#endif
Index: linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c
===================================================================
--- linux-2.6-newcpuidle.git.orig/drivers/cpuidle/cpuidle-haltpoll.c
+++ linux-2.6-newcpuidle.git/drivers/cpuidle/cpuidle-haltpoll.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/sched/idle.h>
#include <linux/kvm_para.h>
+#include <linux/cpuidle_haltpoll.h>
static int default_enter_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
@@ -47,6 +48,7 @@ static struct cpuidle_driver haltpoll_dr
static int __init haltpoll_init(void)
{
+ int ret;
struct cpuidle_driver *drv = &haltpoll_driver;
cpuidle_poll_state_init(drv);
@@ -54,11 +56,16 @@ static int __init haltpoll_init(void)
if (!kvm_para_available())
return 0;
- return cpuidle_register(&haltpoll_driver, NULL);
+ ret = cpuidle_register(&haltpoll_driver, NULL);
+ if (ret == 0)
+ arch_haltpoll_enable();
+
+ return ret;
}
static void __exit haltpoll_exit(void)
{
+ arch_haltpoll_disable();
cpuidle_unregister(&haltpoll_driver);
}
Index: linux-2.6-newcpuidle.git/include/linux/cpuidle_haltpoll.h
===================================================================
--- /dev/null
+++ linux-2.6-newcpuidle.git/include/linux/cpuidle_haltpoll.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _CPUIDLE_HALTPOLL_H
+#define _CPUIDLE_HALTPOLL_H
+
+#ifdef CONFIG_ARCH_CPUIDLE_HALTPOLL
+#include <asm/cpuidle_haltpoll.h>
+#else
+static inline void arch_haltpoll_enable(void)
+{
+}
+
+static inline void arch_haltpoll_disable(void)
+{
+}
+#endif
+#endif
Index: linux-2.6-newcpuidle.git/arch/x86/Kconfig
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/Kconfig
+++ linux-2.6-newcpuidle.git/arch/x86/Kconfig
@@ -787,6 +787,7 @@ config KVM_GUEST
bool "KVM Guest support (including kvmclock)"
depends on PARAVIRT
select PARAVIRT_CLOCK
+ select ARCH_CPUIDLE_HALTPOLL
default y
---help---
This option enables various optimizations for running under the KVM
@@ -795,6 +796,12 @@ config KVM_GUEST
underlying device model, the host provides the guest with
timing infrastructure such as time of day, and system time
+config ARCH_CPUIDLE_HALTPOLL
+ def_bool n
+ prompt "Disable host haltpoll when loading haltpoll driver"
+ help
+ If virtualized under KVM, disable host haltpoll.
+
config PVH
bool "Support for running PVH guests"
---help---
Index: linux-2.6-newcpuidle.git/arch/x86/kernel/kvm.c
===================================================================
--- linux-2.6-newcpuidle.git.orig/arch/x86/kernel/kvm.c
+++ linux-2.6-newcpuidle.git/arch/x86/kernel/kvm.c
@@ -853,3 +853,45 @@ void __init kvm_spinlock_init(void)
}
#endif /* CONFIG_PARAVIRT_SPINLOCKS */
+
+#ifdef CONFIG_ARCH_CPUIDLE_HALTPOLL
+
+static void kvm_disable_host_haltpoll(void *i)
+{
+ wrmsrl(MSR_KVM_POLL_CONTROL, 0);
+}
+
+static void kvm_enable_host_haltpoll(void *i)
+{
+ wrmsrl(MSR_KVM_POLL_CONTROL, 1);
+}
+
+void arch_haltpoll_enable(void)
+{
+ if (!kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL)) {
+ printk(KERN_ERR "kvm: host does not support poll control\n");
+ printk(KERN_ERR "kvm: host upgrade recommended\n");
+ return;
+ }
+
+ preempt_disable();
+ /* Enable guest halt poll disables host halt poll */
+ kvm_disable_host_haltpoll(NULL);
+ smp_call_function(kvm_disable_host_haltpoll, NULL, 1);
+ preempt_enable();
+}
+EXPORT_SYMBOL_GPL(arch_haltpoll_enable);
+
+void arch_haltpoll_disable(void)
+{
+ if (!kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL))
+ return;
+
+ preempt_disable();
+ /* Enable guest halt poll disables host halt poll */
+ kvm_enable_host_haltpoll(NULL);
+ smp_call_function(kvm_enable_host_haltpoll, NULL, 1);
+ preempt_enable();
+}
+EXPORT_SYMBOL_GPL(arch_haltpoll_disable);
+#endif
^ permalink raw reply
* [patch 0/5] cpuidle haltpoll driver and governor (v5)
From: Marcelo Tosatti @ 2019-07-01 18:53 UTC (permalink / raw)
To: kvm, linux-pm
Cc: Paolo Bonzini, Radim Krcmar, Andrea Arcangeli, Rafael J. Wysocki,
Peter Zijlstra, Wanpeng Li, Konrad Rzeszutek Wilk,
Raslan KarimAllah, Boris Ostrovsky, Ankur Arora,
Christian Borntraeger
The cpuidle-haltpoll driver with haltpoll governor allows the guest
vcpus to poll for a specified amount of time before halting.
This provides the following benefits to host side polling:
1) The POLL flag is set while polling is performed, which allows
a remote vCPU to avoid sending an IPI (and the associated
cost of handling the IPI) when performing a wakeup.
2) The VM-exit cost can be avoided.
The downside of guest side polling is that polling is performed
even with other runnable tasks in the host.
Results comparing halt_poll_ns and server/client application
where a small packet is ping-ponged:
host --> 31.33
halt_poll_ns=300000 / no guest busy spin --> 33.40 (93.8%)
halt_poll_ns=0 / guest_halt_poll_ns=300000 --> 32.73 (95.7%)
For the SAP HANA benchmarks (where idle_spin is a parameter
of the previous version of the patch, results should be the
same):
hpns == halt_poll_ns
idle_spin=0/ idle_spin=800/ idle_spin=0/
hpns=200000 hpns=0 hpns=800000
DeleteC06T03 (100 thread) 1.76 1.71 (-3%) 1.78 (+1%)
InsertC16T02 (100 thread) 2.14 2.07 (-3%) 2.18 (+1.8%)
DeleteC00T01 (1 thread) 1.34 1.28 (-4.5%) 1.29 (-3.7%)
UpdateC00T03 (1 thread) 4.72 4.18 (-12%) 4.53 (-5%)
V2:
- Move from x86 to generic code (Paolo/Christian)
- Add auto-tuning logic (Paolo)
- Add MSR to disable host side polling (Paolo)
V3:
- Do not be specific about HLT VM-exit in the documentation (Ankur Arora)
- Mark tuning parameters static and __read_mostly (Andrea Arcangeli)
- Add WARN_ON if host does not support poll control (Joao Martins)
- Use sched_clock and cleanup haltpoll_enter_idle (Peter Zijlstra)
- Mark certain functions in kvm.c as static (kernel test robot)
- Remove tracepoints as they use RCU from extended quiescent state (kernel
test robot)
V4:
- Use a haltpoll governor, use poll_state.c poll code (Rafael J. Wysocki)
V5:
- Take latency requirement into consideration (Rafael J. Wysocki)
- Set target_residency/exit_latency to 1 (Rafael J. Wysocki)
- Do not load cpuidle driver if not virtualized (Rafael J. Wysocki)
^ permalink raw reply
* Re: [PATCH 5/5] drm/bridge: ti-sn65dsi86: support booloader enabled display
From: Jeffrey Hugo @ 2019-07-01 18:39 UTC (permalink / raw)
To: Rob Clark, dri-devel, linux-arm-msm
Cc: freedreno, aarch64-laptops, linux-clk, linux-pm, Rob Clark,
Andrzej Hajda, Laurent Pinchart, David Airlie, Daniel Vetter,
linux-kernel
In-Reply-To: <20190630150230.7878-6-robdclark@gmail.com>
On 6/30/2019 9:01 AM, Rob Clark wrote:
> From: Rob Clark <robdclark@chromium.org>
>
> Request the enable gpio ASIS to avoid disabling bridge during probe, if
> already enabled. And if already enabled, defer enabling runpm until
> attach to avoid cutting off the power to the bridge.
>
> Once we get to attach, we know panel and drm driver are probed
> successfully, so at this point it i s safe to enable runpm and reset the
is?
> bridge. If we do it earlier, we kill efifb (in the case that panel or
> drm driver do not probe successfully, giving the user no way to see what
> is going on.
Where should the missing ")" be?
^ permalink raw reply
* Re: [PATCH 4/5] drm/msm/dsi: get the clocks into OFF state at init
From: Jeffrey Hugo @ 2019-07-01 18:37 UTC (permalink / raw)
To: Rob Clark, dri-devel, linux-arm-msm
Cc: freedreno, aarch64-laptops, linux-clk, linux-pm, Rob Clark,
Sean Paul, David Airlie, Daniel Vetter, Jordan Crouse,
Abhinav Kumar, Sibi Sankar, Mamta Shukla, Chandan Uddaraju,
Archit Taneja, Rajesh Yadav, linux-kernel
In-Reply-To: <20190630150230.7878-5-robdclark@gmail.com>
On 6/30/2019 9:01 AM, Rob Clark wrote:
> From: Rob Clark <robdclark@chromium.org>
>
> Do an extra enable/disable cycle at init, to get the clks into disabled
> state in case bootloader left them enabled.
>
> In case they were already enabled, the clk_prepare_enable() has no real
> effect, other than getting the enable_count/prepare_count into the right
> state so that we can disable clocks in the correct order. This way we
> avoid having stuck clocks when we later want to do a modeset and set the
> clock rates.
>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
> drivers/gpu/drm/msm/dsi/dsi_host.c | 18 +++++++++++++++---
> drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 1 +
> 2 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> index aabab6311043..d0172d8db882 100644
> --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
> @@ -354,6 +354,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
> if (rc)
> pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
> pll->id, status);
> +rc = 0; // HACK, this will fail if PLL already running..
Umm, why? Is this intentional?
--
Jeffrey Hugo
Qualcomm Datacenter Technologies as an affiliate of Qualcomm
Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* Re: [Freedreno] [PATCH 3/5] drm/msm/dsi: split clk rate setting and enable
From: Jeffrey Hugo @ 2019-07-01 18:32 UTC (permalink / raw)
To: Rob Clark
Cc: open list:DRM PANEL DRIVERS, MSM, Rob Clark, aarch64-laptops,
Archit Taneja, Laurent Pinchart, linux-pm, David Airlie,
Sean Paul, Allison Randal, Jordan Crouse, Abhinav Kumar, lkml,
Sibi Sankar, Daniel Vetter, Greg Kroah-Hartman, Thomas Gleixner,
freedreno, linux-clk, Chandan Uddaraju
In-Reply-To: <20190630150230.7878-4-robdclark@gmail.com>
On Sun, Jun 30, 2019 at 9:03 AM Rob Clark <robdclark@gmail.com> wrote:
>
> From: Rob Clark <robdclark@chromium.org>
>
> Prep work for the following patch.
>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
^ permalink raw reply
* Re: [PATCH 1/5] clk: inherit clocks enabled by bootloader
From: Eric Anholt @ 2019-07-01 18:25 UTC (permalink / raw)
To: Rob Clark, dri-devel, linux-arm-msm
Cc: Rob Clark, aarch64-laptops, linux-pm, Stephen Boyd,
Michael Turquette, linux-kernel, Andy Gross, freedreno, linux-clk
In-Reply-To: <20190630150230.7878-2-robdclark@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 899 bytes --]
Rob Clark <robdclark@gmail.com> writes:
> From: Rob Clark <robdclark@chromium.org>
>
> The goal here is to support inheriting a display setup by bootloader,
> although there may also be some non-display related use-cases.
>
> Rough idea is to add a flag for clks and power domains that might
> already be enabled when kernel starts, and which should not be
> disabled at late_initcall if the kernel thinks they are "unused".
>
> If bootloader is enabling display, and kernel is using efifb before
> real display driver is loaded (potentially from kernel module after
> userspace starts, in a typical distro kernel), we don't want to kill
> the clocks and power domains that are used by the display before
> userspace starts.
>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
Raspberry Pi is carrying downstream hacks to do similar stuff, and it
would be great to see CCF finally support this.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply
* Re: [Freedreno] [PATCH 2/5] genpd/gdsc: inherit display powerdomain from bootloader
From: Jeffrey Hugo @ 2019-07-01 18:08 UTC (permalink / raw)
To: Rob Clark
Cc: open list:DRM PANEL DRIVERS, MSM, Rob Clark, aarch64-laptops,
Ulf Hansson, Len Brown, linux-pm, Stephen Boyd,
Greg Kroah-Hartman, Michael Turquette, Kevin Hilman,
Rafael J. Wysocki, lkml, Andy Gross, Pavel Machek, freedreno,
linux-clk
In-Reply-To: <20190630150230.7878-3-robdclark@gmail.com>
On Sun, Jun 30, 2019 at 9:02 AM Rob Clark <robdclark@gmail.com> wrote:
>
> From: Rob Clark <robdclark@chromium.org>
>
> Mark power domains that may be enabled by bootloader, and which should
> not be disabled until a driver takes them over.
>
> This keeps efifb alive until the real driver can be probed. In a distro
> kernel, the driver will most likely built as a module, and not probed
> until we get to userspace (after late_initcall)
>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
^ permalink raw reply
* Re: [Freedreno] [PATCH 1/5] clk: inherit clocks enabled by bootloader
From: Jeffrey Hugo @ 2019-07-01 18:02 UTC (permalink / raw)
To: Rob Clark
Cc: open list:DRM PANEL DRIVERS, MSM, Rob Clark, aarch64-laptops,
linux-pm, Stephen Boyd, Michael Turquette, lkml, Andy Gross,
freedreno, linux-clk
In-Reply-To: <20190630150230.7878-2-robdclark@gmail.com>
On Sun, Jun 30, 2019 at 9:02 AM Rob Clark <robdclark@gmail.com> wrote:
>
> From: Rob Clark <robdclark@chromium.org>
>
> The goal here is to support inheriting a display setup by bootloader,
> although there may also be some non-display related use-cases.
>
> Rough idea is to add a flag for clks and power domains that might
> already be enabled when kernel starts, and which should not be
> disabled at late_initcall if the kernel thinks they are "unused".
>
> If bootloader is enabling display, and kernel is using efifb before
> real display driver is loaded (potentially from kernel module after
> userspace starts, in a typical distro kernel), we don't want to kill
> the clocks and power domains that are used by the display before
> userspace starts.
>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
Seems sane to me. I'm curious what Stephen Boyd thinks.
I'll try to give it a spin on one of the 835 laptops.
Reviewed-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
^ permalink raw reply
* Re: [PATCH v2 0/5] PM: PCI/ACPI: Hibernation handling fixes
From: Mika Westerberg @ 2019-07-01 16:20 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, Linux PCI, Linux ACPI, LKML, Bjorn Helgaas,
Andy Shevchenko, Hans De Goede, Robert R. Howell
In-Reply-To: <4976412.ihyb9sT5jY@kreacher>
On Mon, Jul 01, 2019 at 12:42:14PM +0200, Rafael J. Wysocki wrote:
> Hi All,
>
> This series of patches addresses a few issues related to the handling of
> hibernation in the PCI bus type and the ACPI PM domain and ACPI LPSS driver.
>
> The v2 addresses Hans' concerns regarding the LPSS changes.
>
> First of all, all of the runtime-suspended PCI devices and devices in the ACPI PM and LPSS
> PM domains will be resumed during hibernation (first patch). This appears to be the
> only way to avoid weird corner cases and the benefit from avoiding to resume those
> devices during hibernation is questionable.
>
> That change allows the the hibernation callbacks in all of the involved subsystems to be
> simplified (patches 2 and 3).
>
> Moreover, reusing bus-level suspend callbacks for the "poweroff" transition during
> hibernation (which is the case for the ACPI PM domain and LPSS) is incorrect, so patch 4
> fixes that.
>
> Finally, there are some leftover items in linux/acpi.h that can be dropped (patch 5).
For the whole series,
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
^ permalink raw reply
* Re: [PATCH v2 1/5] PM: ACPI/PCI: Resume all devices during hibernation
From: Mika Westerberg @ 2019-07-01 16:15 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux PM, Linux PCI, Linux ACPI, LKML, Bjorn Helgaas,
Andy Shevchenko, Hans De Goede, Robert R. Howell
In-Reply-To: <6191578.xJk2HsE5MX@kreacher>
On Mon, Jul 01, 2019 at 12:44:25PM +0200, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Both the PCI bus type and the ACPI PM domain avoid resuming
> runtime-suspended devices with DPM_FLAG_SMART_SUSPEND set during
> hibernation (before creating the snapshot image of system memory),
> but that turns out to be a mistake. It leads to functional issues
> and adds complexity that's hard to justify.
>
> For this reason, resume all runtime-suspended PCI devices and all
> devices in the ACPI PM domains before creating a snapshot image of
> system memory during hibernation.
>
> Fixes: 05087360fd7a (ACPI / PM: Take SMART_SUSPEND driver flag into account)
> Fixes: c4b65157aeef (PCI / PM: Take SMART_SUSPEND driver flag into account)
> Link: https://lore.kernel.org/linux-acpi/917d4399-2e22-67b1-9d54-808561f9083f@uwyo.edu/T/#maf065fe6e4974f2a9d79f332ab99dfaba635f64c
> Reported-by: Robert R. Howell <RHowell@uwyo.edu>
> Tested-by: Robert R. Howell <RHowell@uwyo.edu>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>
> -> v2: No changes.
>
> ---
> drivers/acpi/device_pm.c | 13 +++++++------
> drivers/pci/pci-driver.c | 16 ++++++++--------
> 2 files changed, 15 insertions(+), 14 deletions(-)
>
> Index: linux-pm/drivers/acpi/device_pm.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/device_pm.c
> +++ linux-pm/drivers/acpi/device_pm.c
> @@ -1155,13 +1155,14 @@ EXPORT_SYMBOL_GPL(acpi_subsys_resume_ear
> int acpi_subsys_freeze(struct device *dev)
> {
> /*
> - * This used to be done in acpi_subsys_prepare() for all devices and
> - * some drivers may depend on it, so do it here. Ideally, however,
> - * runtime-suspended devices should not be touched during freeze/thaw
> - * transitions.
> + * Resume all runtime-suspended devices before creating a snapshot
> + * image of system memory, because the restore kernel generally cannot
> + * be expected to always handle them consistently and they need to be
> + * put into the runtime-active metastate during system resume anyway,
> + * so it is better to ensure that the state saved in the image will be
> + * alwyas consistent with that.
alwyas -> always
> */
> - if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND))
> - pm_runtime_resume(dev);
> + pm_runtime_resume(dev);
>
> return pm_generic_freeze(dev);
> }
> Index: linux-pm/drivers/pci/pci-driver.c
> ===================================================================
> --- linux-pm.orig/drivers/pci/pci-driver.c
> +++ linux-pm/drivers/pci/pci-driver.c
> @@ -1012,15 +1012,15 @@ static int pci_pm_freeze(struct device *
> }
>
> /*
> - * This used to be done in pci_pm_prepare() for all devices and some
> - * drivers may depend on it, so do it here. Ideally, runtime-suspended
> - * devices should not be touched during freeze/thaw transitions,
> - * however.
> + * Resume all runtime-suspended devices before creating a snapshot
> + * image of system memory, because the restore kernel generally cannot
> + * be expected to always handle them consistently and they need to be
> + * put into the runtime-active metastate during system resume anyway,
> + * so it is better to ensure that the state saved in the image will be
> + * alwyas consistent with that.
ditto
> */
> - if (!dev_pm_smart_suspend_and_suspended(dev)) {
> - pm_runtime_resume(dev);
> - pci_dev->state_saved = false;
> - }
> + pm_runtime_resume(dev);
> + pci_dev->state_saved = false;
>
> if (pm->freeze) {
> int error;
>
>
>
^ permalink raw reply
* Re: [PATCH 2/2] drivers: qcom: rpmh-rsc: fix read back of trigger register
From: Lina Iyer @ 2019-07-01 15:53 UTC (permalink / raw)
To: agross, bjorn.andersson
Cc: linux-arm-msm, linux-soc, rnayak, linux-kernel, linux-pm, swboyd,
dianders, mkshah
In-Reply-To: <20190701152907.16407-2-ilina@codeaurora.org>
Switching Andy's email address.
On Mon, Jul 01 2019 at 09:32 -0600, Lina Iyer wrote:
>When triggering a TCS to send its contents, reading back the trigger
>value may return an incorrect value. That is because, writing the
>trigger may raise an interrupt which could be handled immediately and
>the trigger value could be reset in the interrupt handler. By doing a
>read back we may end up spinning waiting for the value we wrote.
>
>Fixes: 658628 ("drivers: qcom: rpmh-rsc: add RPMH controller for QCOM
>SoCs")
>Signed-off-by: Lina Iyer <ilina@codeaurora.org>
>---
> drivers/soc/qcom/rpmh-rsc.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
>index 92461311aef3..2fc2fa879480 100644
>--- a/drivers/soc/qcom/rpmh-rsc.c
>+++ b/drivers/soc/qcom/rpmh-rsc.c
>@@ -300,7 +300,7 @@ static void __tcs_trigger(struct rsc_drv *drv, int tcs_id)
> enable = TCS_AMC_MODE_ENABLE;
> write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
> enable |= TCS_AMC_MODE_TRIGGER;
>- write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
>+ write_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, enable);
> }
>
> static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
>--
>The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>a Linux Foundation Collaborative Project
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox