This is just a resend of v3:
https://lore.kernel.org/lkml/[email protected]/
Just added Ulf's R-b tag to the 2nd patch. No other changes.
Abel Vesa (1):
PM: domains: Add the domain HW-managed mode to the summary
Jagadeesh Kona (3):
clk: qcom: gdsc: Add set and get hwmode callbacks to switch GDSC mode
clk: qcom: Use HW_CTRL_TRIGGER flag to switch video GDSC to HW mode
venus: pm_helpers: Use dev_pm_genpd_set_hwmode to switch GDSC mode
Ulf Hansson (1):
PM: domains: Allow devices attached to genpd to be managed by HW
drivers/base/power/domain.c | 84 ++++++++++++++++++-
drivers/clk/qcom/gdsc.c | 32 +++++++
drivers/clk/qcom/gdsc.h | 1 +
drivers/clk/qcom/videocc-sc7180.c | 2 +-
drivers/clk/qcom/videocc-sc7280.c | 2 +-
drivers/clk/qcom/videocc-sdm845.c | 4 +-
drivers/clk/qcom/videocc-sm8250.c | 4 +-
drivers/clk/qcom/videocc-sm8550.c | 4 +-
drivers/media/platform/qcom/venus/core.c | 4 +
drivers/media/platform/qcom/venus/core.h | 1 +
.../media/platform/qcom/venus/pm_helpers.c | 47 +++++------
include/linux/pm_domain.h | 17 ++++
12 files changed, 165 insertions(+), 37 deletions(-)
--
2.34.1
On 23-09-23 14:49:45, Abel Vesa wrote:
> This is just a resend of v3:
> https://lore.kernel.org/lkml/[email protected]/
>
> Just added Ulf's R-b tag to the 2nd patch. No other changes.
>
Urgh, for some reason, only cover letter was sent. Please see full
patchset here:
https://lore.kernel.org/all/[email protected]/
> Abel Vesa (1):
> PM: domains: Add the domain HW-managed mode to the summary
>
> Jagadeesh Kona (3):
> clk: qcom: gdsc: Add set and get hwmode callbacks to switch GDSC mode
> clk: qcom: Use HW_CTRL_TRIGGER flag to switch video GDSC to HW mode
> venus: pm_helpers: Use dev_pm_genpd_set_hwmode to switch GDSC mode
>
> Ulf Hansson (1):
> PM: domains: Allow devices attached to genpd to be managed by HW
>
> drivers/base/power/domain.c | 84 ++++++++++++++++++-
> drivers/clk/qcom/gdsc.c | 32 +++++++
> drivers/clk/qcom/gdsc.h | 1 +
> drivers/clk/qcom/videocc-sc7180.c | 2 +-
> drivers/clk/qcom/videocc-sc7280.c | 2 +-
> drivers/clk/qcom/videocc-sdm845.c | 4 +-
> drivers/clk/qcom/videocc-sm8250.c | 4 +-
> drivers/clk/qcom/videocc-sm8550.c | 4 +-
> drivers/media/platform/qcom/venus/core.c | 4 +
> drivers/media/platform/qcom/venus/core.h | 1 +
> .../media/platform/qcom/venus/pm_helpers.c | 47 +++++------
> include/linux/pm_domain.h | 17 ++++
> 12 files changed, 165 insertions(+), 37 deletions(-)
>
> --
> 2.34.1
>
From: Jagadeesh Kona <[email protected]>
The current HW_CTRL flag switches the video GDSC to HW control mode as
part of GDSC enable itself, instead of that use HW_CTRL_TRIGGER flag to
give consumer drivers more control and switch the GDSC mode as and when
required.
HW_CTRL_TRIGGER flag allows consumer drivers to switch the video GDSC to
HW/SW control modes at runtime using dev_pm_genpd_set_hwmode API.
Signed-off-by: Jagadeesh Kona <[email protected]>
Signed-off-by: Abel Vesa <[email protected]>
---
drivers/clk/qcom/videocc-sc7180.c | 2 +-
drivers/clk/qcom/videocc-sc7280.c | 2 +-
drivers/clk/qcom/videocc-sdm845.c | 4 ++--
drivers/clk/qcom/videocc-sm8250.c | 4 ++--
drivers/clk/qcom/videocc-sm8550.c | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/qcom/videocc-sc7180.c b/drivers/clk/qcom/videocc-sc7180.c
index 5b9b54f616b8..51439f7ba70c 100644
--- a/drivers/clk/qcom/videocc-sc7180.c
+++ b/drivers/clk/qcom/videocc-sc7180.c
@@ -166,7 +166,7 @@ static struct gdsc vcodec0_gdsc = {
.pd = {
.name = "vcodec0_gdsc",
},
- .flags = HW_CTRL,
+ .flags = HW_CTRL_TRIGGER,
.pwrsts = PWRSTS_OFF_ON,
};
diff --git a/drivers/clk/qcom/videocc-sc7280.c b/drivers/clk/qcom/videocc-sc7280.c
index 615695d82319..3d07b1e95986 100644
--- a/drivers/clk/qcom/videocc-sc7280.c
+++ b/drivers/clk/qcom/videocc-sc7280.c
@@ -236,7 +236,7 @@ static struct gdsc mvs0_gdsc = {
.name = "mvs0_gdsc",
},
.pwrsts = PWRSTS_OFF_ON,
- .flags = HW_CTRL | RETAIN_FF_ENABLE,
+ .flags = HW_CTRL_TRIGGER | RETAIN_FF_ENABLE,
};
static struct gdsc mvsc_gdsc = {
diff --git a/drivers/clk/qcom/videocc-sdm845.c b/drivers/clk/qcom/videocc-sdm845.c
index c77a4dd5d39c..dad011c48973 100644
--- a/drivers/clk/qcom/videocc-sdm845.c
+++ b/drivers/clk/qcom/videocc-sdm845.c
@@ -260,7 +260,7 @@ static struct gdsc vcodec0_gdsc = {
},
.cxcs = (unsigned int []){ 0x890, 0x930 },
.cxc_count = 2,
- .flags = HW_CTRL | POLL_CFG_GDSCR,
+ .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR,
.pwrsts = PWRSTS_OFF_ON,
};
@@ -271,7 +271,7 @@ static struct gdsc vcodec1_gdsc = {
},
.cxcs = (unsigned int []){ 0x8d0, 0x950 },
.cxc_count = 2,
- .flags = HW_CTRL | POLL_CFG_GDSCR,
+ .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR,
.pwrsts = PWRSTS_OFF_ON,
};
diff --git a/drivers/clk/qcom/videocc-sm8250.c b/drivers/clk/qcom/videocc-sm8250.c
index ad46c4014a40..c1b73d852f1c 100644
--- a/drivers/clk/qcom/videocc-sm8250.c
+++ b/drivers/clk/qcom/videocc-sm8250.c
@@ -293,7 +293,7 @@ static struct gdsc mvs0_gdsc = {
.pd = {
.name = "mvs0_gdsc",
},
- .flags = HW_CTRL,
+ .flags = HW_CTRL_TRIGGER,
.pwrsts = PWRSTS_OFF_ON,
};
@@ -302,7 +302,7 @@ static struct gdsc mvs1_gdsc = {
.pd = {
.name = "mvs1_gdsc",
},
- .flags = HW_CTRL,
+ .flags = HW_CTRL_TRIGGER,
.pwrsts = PWRSTS_OFF_ON,
};
diff --git a/drivers/clk/qcom/videocc-sm8550.c b/drivers/clk/qcom/videocc-sm8550.c
index 3bb136ec31b1..504b2ef264eb 100644
--- a/drivers/clk/qcom/videocc-sm8550.c
+++ b/drivers/clk/qcom/videocc-sm8550.c
@@ -324,7 +324,7 @@ static struct gdsc video_cc_mvs0_gdsc = {
},
.pwrsts = PWRSTS_OFF_ON,
.parent = &video_cc_mvs0c_gdsc.pd,
- .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL,
+ .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER,
};
static struct gdsc video_cc_mvs1c_gdsc = {
@@ -349,7 +349,7 @@ static struct gdsc video_cc_mvs1_gdsc = {
},
.pwrsts = PWRSTS_OFF_ON,
.parent = &video_cc_mvs1c_gdsc.pd,
- .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL,
+ .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER,
};
static struct clk_regmap *video_cc_sm8550_clocks[] = {
--
2.34.1
From: Jagadeesh Kona <[email protected]>
Add support for set and get hwmode callbacks to switch the GDSC between
SW and HW modes. Currently, the GDSC is moved to HW control mode
using HW_CTRL flag and if this flag is present, GDSC is moved to HW
mode as part of GDSC enable itself. The intention is to keep the
HW_CTRL flag functionality as is, since many older chipsets still use
this flag.
Introduce a new HW_CTRL_TRIGGER flag to switch the GDSC back and forth
between HW/SW modes dynamically at runtime. If HW_CTRL_TRIGGER flag is
present, register set_hwmode_dev callback to switch the GDSC mode which
can be invoked from consumer drivers using dev_pm_genpd_set_hwmode
function. Unlike HW_CTRL flag, HW_CTRL_TRIGGER won't move the GDSC to HW
control mode as part of GDSC enable itself, GDSC will be moved to HW
control mode only when consumer driver explicity calls
dev_pm_genpd_set_hwmode to switch to HW mode. Also add the
dev_pm_genpd_get_hwmode to allow the consumers to read the actual
HW/SW mode from hardware.
Signed-off-by: Jagadeesh Kona <[email protected]>
Signed-off-by: Abel Vesa <[email protected]>
---
drivers/clk/qcom/gdsc.c | 32 ++++++++++++++++++++++++++++++++
drivers/clk/qcom/gdsc.h | 1 +
2 files changed, 33 insertions(+)
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 5358e28122ab..c763524cd5da 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -363,6 +363,34 @@ static int gdsc_disable(struct generic_pm_domain *domain)
return 0;
}
+static int gdsc_set_hwmode(struct generic_pm_domain *domain, struct device *dev, bool mode)
+{
+ struct gdsc *sc = domain_to_gdsc(domain);
+
+ if (sc->rsupply && !regulator_is_enabled(sc->rsupply)) {
+ pr_err("Cannot set mode while parent is disabled\n");
+ return -EIO;
+ }
+
+ return gdsc_hwctrl(sc, mode);
+}
+
+static bool gdsc_get_hwmode(struct generic_pm_domain *domain, struct device *dev)
+{
+ struct gdsc *sc = domain_to_gdsc(domain);
+ u32 val;
+ int ret;
+
+ ret = regmap_read(sc->regmap, sc->gdscr, &val);
+ if (ret)
+ return ret;
+
+ if (val & HW_CONTROL_MASK)
+ return true;
+
+ return false;
+}
+
static int gdsc_init(struct gdsc *sc)
{
u32 mask, val;
@@ -451,6 +479,10 @@ static int gdsc_init(struct gdsc *sc)
sc->pd.power_off = gdsc_disable;
if (!sc->pd.power_on)
sc->pd.power_on = gdsc_enable;
+ if (sc->flags & HW_CTRL_TRIGGER) {
+ sc->pd.set_hwmode_dev = gdsc_set_hwmode;
+ sc->pd.get_hwmode_dev = gdsc_get_hwmode;
+ }
ret = pm_genpd_init(&sc->pd, NULL, !on);
if (ret)
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 803512688336..1e2779b823d1 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -67,6 +67,7 @@ struct gdsc {
#define ALWAYS_ON BIT(6)
#define RETAIN_FF_ENABLE BIT(7)
#define NO_RET_PERIPH BIT(8)
+#define HW_CTRL_TRIGGER BIT(9)
struct reset_controller_dev *rcdev;
unsigned int *resets;
unsigned int reset_count;
--
2.34.1
Now that genpd supports dynamically switching the control for an
attached device between hardware- and software-mode, let's add this
information to the genpd summary in debugfs.
Suggested-by: Taniya Das <[email protected]>
Signed-off-by: Abel Vesa <[email protected]>
Reviewed-by: Ulf Hansson <[email protected]>
---
drivers/base/power/domain.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index dfb4f1de540d..93350e67b0e8 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -3171,6 +3171,15 @@ static void rtpm_status_str(struct seq_file *s, struct device *dev)
seq_printf(s, "%-25s ", p);
}
+static void mode_status_str(struct seq_file *s, struct device *dev)
+{
+ struct generic_pm_domain_data *gpd_data;
+
+ gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
+
+ seq_printf(s, "%20s", gpd_data->hw_mode ? "HW" : "SW");
+}
+
static void perf_status_str(struct seq_file *s, struct device *dev)
{
struct generic_pm_domain_data *gpd_data;
@@ -3229,6 +3238,7 @@ static int genpd_summary_one(struct seq_file *s,
seq_printf(s, "\n %-50s ", kobj_path);
rtpm_status_str(s, pm_data->dev);
perf_status_str(s, pm_data->dev);
+ mode_status_str(s, pm_data->dev);
kfree(kobj_path);
}
@@ -3245,8 +3255,9 @@ static int summary_show(struct seq_file *s, void *data)
int ret = 0;
seq_puts(s, "domain status children performance\n");
- seq_puts(s, " /device runtime status\n");
- seq_puts(s, "----------------------------------------------------------------------------------------------\n");
+ seq_puts(s, " /device runtime status managed by\n");
+ seq_puts(s, "------------------------------------------------------------------------------------------------------------\n");
+
ret = mutex_lock_interruptible(&gpd_list_lock);
if (ret)
--
2.34.1