This patch set adds support for runtime power management for hdmi and mixer devices. Its also adds support for hdmiphy power control.
It has been tested for hot plugin-plugout and dpms scenarios.
Based on exynos-drm-next branch of http://git.kernel.org/?p=linux/kernel/git/daeinki/drm-exynos.git
Rahul Sharma (3): drm/exynos: added runtime pm support for hdmi drm/exynos: add runtime pm support for mixer drm/exynos: add support for hdmiphy power control for exynos5
drivers/gpu/drm/exynos/exynos_hdmi.c | 81 +++++++++++++++++++++++++++++--- drivers/gpu/drm/exynos/exynos_mixer.c | 65 +++++++++++++++++++++++--- drivers/gpu/drm/exynos/regs-hdmi.h | 5 ++ 3 files changed, 136 insertions(+), 15 deletions(-)
This patch adds runtime power management support for exynos drm hdmi driver.
Signed-off-by: Rahul Sharma rahul.sharma@samsung.com Signed-off-by: Shirish S s.shirish@samsung.com --- drivers/gpu/drm/exynos/exynos_hdmi.c | 60 +++++++++++++++++++++++++++++---- 1 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 59839cc..a85fc58 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2064,8 +2064,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
mutex_unlock(&hdata->hdmi_mutex);
- pm_runtime_get_sync(hdata->dev); - regulator_bulk_enable(res->regul_count, res->regul_bulk); clk_enable(res->hdmiphy); clk_enable(res->hdmi); @@ -2094,8 +2092,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata) clk_disable(res->hdmiphy); regulator_bulk_disable(res->regul_count, res->regul_bulk);
- pm_runtime_put_sync(hdata->dev); - mutex_lock(&hdata->hdmi_mutex);
hdata->powered = false; @@ -2108,16 +2104,18 @@ static void hdmi_dpms(void *ctx, int mode) { struct hdmi_context *hdata = ctx;
- DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + DRM_DEBUG_KMS("[%d] %s mode %d\n", __LINE__, __func__, mode);
switch (mode) { case DRM_MODE_DPMS_ON: - hdmi_poweron(hdata); + if (pm_runtime_suspended(hdata->dev)) + pm_runtime_get_sync(hdata->dev); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - hdmi_poweroff(hdata); + if (!pm_runtime_suspended(hdata->dev)) + pm_runtime_put_sync(hdata->dev); break; default: DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); @@ -2540,6 +2538,8 @@ static int hdmi_suspend(struct device *dev) struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); struct hdmi_context *hdata = ctx->ctx;
+ DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + disable_irq(hdata->internal_irq); disable_irq(hdata->external_irq);
@@ -2547,6 +2547,11 @@ static int hdmi_suspend(struct device *dev) if (ctx->drm_dev) drm_helper_hpd_irq_event(ctx->drm_dev);
+ if (pm_runtime_suspended(dev)) { + DRM_DEBUG_KMS("%s : Already suspended\n", __func__); + return 0; + } + hdmi_poweroff(hdata);
return 0; @@ -2557,13 +2562,52 @@ static int hdmi_resume(struct device *dev) struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); struct hdmi_context *hdata = ctx->ctx;
+ DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + hdata->hpd = gpio_get_value(hdata->hpd_gpio); + enable_irq(hdata->external_irq); enable_irq(hdata->internal_irq); + + if (!pm_runtime_suspended(dev)) { + DRM_DEBUG_KMS("%s : Already resumed\n", __func__); + return 0; + } + + hdmi_poweron(hdata); + + return 0; +} +#endif + +#ifdef CONFIG_PM_RUNTIME +static int hdmi_runtime_suspend(struct device *dev) +{ + struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); + struct hdmi_context *hdata = ctx->ctx; + DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + hdmi_poweroff(hdata); + + return 0; +} + +static int hdmi_runtime_resume(struct device *dev) +{ + struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); + struct hdmi_context *hdata = ctx->ctx; + DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + hdmi_poweron(hdata); + return 0; } #endif
-static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume); +static const struct dev_pm_ops hdmi_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(hdmi_suspend, hdmi_resume) + SET_RUNTIME_PM_OPS(hdmi_runtime_suspend, hdmi_runtime_resume, NULL) +};
struct platform_driver hdmi_driver = { .probe = hdmi_probe,
This patch adds support for runtime power management for drm mixer driver.
Signed-off-by: Rahul Sharma rahul.sharma@samsung.com Signed-off-by: Shirish S s.shirish@samsung.com --- drivers/gpu/drm/exynos/exynos_mixer.c | 65 +++++++++++++++++++++++++++++---- 1 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 0d3ed28..b15b770 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -679,8 +679,6 @@ static void mixer_poweron(struct mixer_context *ctx) ctx->powered = true; mutex_unlock(&ctx->mixer_mutex);
- pm_runtime_get_sync(ctx->dev); - clk_enable(res->mixer); if (ctx->vp_enabled) { clk_enable(res->vp); @@ -710,8 +708,6 @@ static void mixer_poweroff(struct mixer_context *ctx) clk_disable(res->sclk_mixer); }
- pm_runtime_put_sync(ctx->dev); - mutex_lock(&ctx->mixer_mutex); ctx->powered = false;
@@ -754,12 +750,14 @@ static void mixer_dpms(void *ctx, int mode)
switch (mode) { case DRM_MODE_DPMS_ON: - mixer_poweron(mixer_ctx); + if (pm_runtime_suspended(mixer_ctx->dev)) + pm_runtime_get_sync(mixer_ctx->dev); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - mixer_poweroff(mixer_ctx); + if (!pm_runtime_suspended(mixer_ctx->dev)) + pm_runtime_put_sync(mixer_ctx->dev); break; default: DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); @@ -1193,13 +1191,66 @@ static int mixer_suspend(struct device *dev) struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev); struct mixer_context *ctx = drm_hdmi_ctx->ctx;
+ DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + if (pm_runtime_suspended(dev)) { + DRM_DEBUG_KMS("%s : Already suspended\n", __func__); + return 0; + } + mixer_poweroff(ctx);
return 0; } + +static int mixer_resume(struct device *dev) +{ + struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev); + struct mixer_context *ctx = drm_hdmi_ctx->ctx; + + DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + if (!pm_runtime_suspended(dev)) { + DRM_DEBUG_KMS("%s : Already resumed\n", __func__); + return 0; + } + + mixer_poweron(ctx); + + return 0; +} #endif
-static SIMPLE_DEV_PM_OPS(mixer_pm_ops, mixer_suspend, NULL); +#ifdef CONFIG_PM_RUNTIME +static int mixer_runtime_suspend(struct device *dev) +{ + struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev); + struct mixer_context *ctx = drm_hdmi_ctx->ctx; + + DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + mixer_poweroff(ctx); + + return 0; +} + +static int mixer_runtime_resume(struct device *dev) +{ + struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev); + struct mixer_context *ctx = drm_hdmi_ctx->ctx; + + DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + mixer_poweron(ctx); + + return 0; +} +#endif + +static const struct dev_pm_ops mixer_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend, mixer_resume) + SET_RUNTIME_PM_OPS(mixer_runtime_suspend, mixer_runtime_resume, NULL) +};
struct platform_driver mixer_driver = { .driver = {
This patch adds support for controlling power of hdmi phy for exynos5 soc. A special bit is provided in exynos5 for directly switching of PHY while in exynos4, phy power needs to be controlled through i2c settings. I2C configuration may affect the suspend to resume and wake-up time requirements hence not added.
Signed-off-by: Rahul Sharma rahul.sharma@samsung.com --- drivers/gpu/drm/exynos/exynos_hdmi.c | 21 +++++++++++++++++++++ drivers/gpu/drm/exynos/regs-hdmi.h | 5 +++++ 2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index a85fc58..74e38a5 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1877,6 +1877,24 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata) mdelay(10); }
+static void hdmiphy_poweron(struct hdmi_context *hdata) +{ + DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + if (hdata->type == HDMI_TYPE14) + hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, + HDMI_PHY_POWER_OFF_EN); +} + +static void hdmiphy_poweroff(struct hdmi_context *hdata) +{ + DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); + + if (hdata->type == HDMI_TYPE14) + hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, + HDMI_PHY_POWER_OFF_EN); +} + static void hdmiphy_conf_apply(struct hdmi_context *hdata) { const u8 *hdmiphy_data; @@ -2068,6 +2086,8 @@ static void hdmi_poweron(struct hdmi_context *hdata) clk_enable(res->hdmiphy); clk_enable(res->hdmi); clk_enable(res->sclk_hdmi); + + hdmiphy_poweron(hdata); }
static void hdmi_poweroff(struct hdmi_context *hdata) @@ -2086,6 +2106,7 @@ static void hdmi_poweroff(struct hdmi_context *hdata) * its reset state seems to meet the condition. */ hdmiphy_conf_reset(hdata); + hdmiphy_poweroff(hdata);
clk_disable(res->sclk_hdmi); clk_disable(res->hdmi); diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h index 9cc7c5e..59ff7fa 100644 --- a/drivers/gpu/drm/exynos/regs-hdmi.h +++ b/drivers/gpu/drm/exynos/regs-hdmi.h @@ -176,6 +176,11 @@ #define HDMI_PHY_CMU HDMI_CTRL_BASE(0x007C) #define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0080)
+/* PHY Control bit definition */ + +/* HDMI_PHY_CON_0 */ +#define HDMI_PHY_POWER_OFF_EN (1 << 0) + /* Video related registers */ #define HDMI_YMAX HDMI_CORE_BASE(0x0060) #define HDMI_YMIN HDMI_CORE_BASE(0x0064)
Hi All,
Kindly review the following patch set for Runtime PM Changes for Mixer and Hdmi.
regards, Rahul Sharma
On Wed, Nov 28, 2012 at 11:30 AM, Rahul Sharma rahul.sharma@samsung.com wrote:
This patch set adds support for runtime power management for hdmi and mixer devices. Its also adds support for hdmiphy power control.
It has been tested for hot plugin-plugout and dpms scenarios.
Based on exynos-drm-next branch of http://git.kernel.org/?p=linux/kernel/git/daeinki/drm-exynos.git
Rahul Sharma (3): drm/exynos: added runtime pm support for hdmi drm/exynos: add runtime pm support for mixer drm/exynos: add support for hdmiphy power control for exynos5
drivers/gpu/drm/exynos/exynos_hdmi.c | 81 +++++++++++++++++++++++++++++--- drivers/gpu/drm/exynos/exynos_mixer.c | 65 +++++++++++++++++++++++--- drivers/gpu/drm/exynos/regs-hdmi.h | 5 ++ 3 files changed, 136 insertions(+), 15 deletions(-)
dri-devel@lists.freedesktop.org