* [PATCH v2 01/21] drm/i915: use drm_i915_private everywhere in the power domain api
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-06 19:00 ` Jesse Barnes
2014-03-04 17:22 ` [PATCH v2 02/21] drm/i915: fold in __intel_power_well_get/put functions Imre Deak
` (19 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
The power domains framework is internal to the i915 driver, so pass
drm_i915_private instead of drm_device to its functions.
Also remove a dangling intel_set_power_well() declaration.
No functional change.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_dma.c | 14 ++++----
drivers/gpu/drm/i915/i915_drv.c | 4 +--
drivers/gpu/drm/i915/i915_drv.h | 4 +--
drivers/gpu/drm/i915/intel_display.c | 27 +++++++--------
drivers/gpu/drm/i915/intel_drv.h | 17 +++++-----
drivers/gpu/drm/i915/intel_pm.c | 65 ++++++++++++++----------------------
6 files changed, 58 insertions(+), 73 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 7688abc..8177c17 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1325,7 +1325,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto cleanup_gem_stolen;
- intel_power_domains_init_hw(dev);
+ intel_power_domains_init_hw(dev_priv);
/* Important: The output setup functions called by modeset_init need
* working irqs for e.g. gmbus and dp aux transfers. */
@@ -1343,7 +1343,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
/* FIXME: do pre/post-mode set stuff in core KMS code */
dev->vblank_disable_allowed = true;
if (INTEL_INFO(dev)->num_pipes == 0) {
- intel_display_power_put(dev, POWER_DOMAIN_VGA);
+ intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
return 0;
}
@@ -1381,7 +1381,7 @@ cleanup_gem:
WARN_ON(dev_priv->mm.aliasing_ppgtt);
drm_mm_takedown(&dev_priv->gtt.base.mm);
cleanup_power:
- intel_display_power_put(dev, POWER_DOMAIN_VGA);
+ intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
drm_irq_uninstall(dev);
cleanup_gem_stolen:
i915_gem_cleanup_stolen(dev);
@@ -1702,7 +1702,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_gem_unload;
}
- intel_power_domains_init(dev);
+ intel_power_domains_init(dev_priv);
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = i915_load_modeset_init(dev);
@@ -1731,7 +1731,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
return 0;
out_power_well:
- intel_power_domains_remove(dev);
+ intel_power_domains_remove(dev_priv);
drm_vblank_cleanup(dev);
out_gem_unload:
if (dev_priv->mm.inactive_shrinker.scan_objects)
@@ -1781,8 +1781,8 @@ int i915_driver_unload(struct drm_device *dev)
/* The i915.ko module is still not prepared to be loaded when
* the power well is not enabled, so just enable it in case
* we're going to unload/reload. */
- intel_display_set_init_power(dev, true);
- intel_power_domains_remove(dev);
+ intel_display_set_init_power(dev_priv, true);
+ intel_power_domains_remove(dev_priv);
i915_teardown_sysfs(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 08052f3d..ce898af 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -429,7 +429,7 @@ static int i915_drm_freeze(struct drm_device *dev)
/* We do a lot of poking in a lot of registers, make sure they work
* properly. */
hsw_disable_package_c8(dev_priv);
- intel_display_set_init_power(dev, true);
+ intel_display_set_init_power(dev_priv, true);
drm_kms_helper_poll_disable(dev);
@@ -551,7 +551,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
mutex_unlock(&dev->struct_mutex);
}
- intel_power_domains_init_hw(dev);
+ intel_power_domains_init_hw(dev_priv);
i915_restore_state(dev);
intel_opregion_setup(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 05cfcc1..53b0512 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1024,9 +1024,9 @@ struct i915_power_well {
int count;
unsigned long domains;
void *data;
- void (*set)(struct drm_device *dev, struct i915_power_well *power_well,
+ void (*set)(struct drm_i915_private *dev_priv, struct i915_power_well *power_well,
bool enable);
- bool (*is_enabled)(struct drm_device *dev,
+ bool (*is_enabled)(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well);
};
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6f15627..5cc116b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1122,7 +1122,7 @@ void assert_pipe(struct drm_i915_private *dev_priv,
if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
state = true;
- if (!intel_display_power_enabled(dev_priv->dev,
+ if (!intel_display_power_enabled(dev_priv,
POWER_DOMAIN_TRANSCODER(cpu_transcoder))) {
cur_state = false;
} else {
@@ -6858,23 +6858,23 @@ static unsigned long get_pipe_power_domains(struct drm_device *dev,
return mask;
}
-void intel_display_set_init_power(struct drm_device *dev, bool enable)
+void intel_display_set_init_power(struct drm_i915_private *dev_priv,
+ bool enable)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
if (dev_priv->power_domains.init_power_on == enable)
return;
if (enable)
- intel_display_power_get(dev, POWER_DOMAIN_INIT);
+ intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
else
- intel_display_power_put(dev, POWER_DOMAIN_INIT);
+ intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
dev_priv->power_domains.init_power_on = enable;
}
static void modeset_update_power_wells(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
struct intel_crtc *crtc;
@@ -6893,19 +6893,19 @@ static void modeset_update_power_wells(struct drm_device *dev)
crtc->config.pch_pfit.enabled);
for_each_power_domain(domain, pipe_domains[crtc->pipe])
- intel_display_power_get(dev, domain);
+ intel_display_power_get(dev_priv, domain);
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
enum intel_display_power_domain domain;
for_each_power_domain(domain, crtc->enabled_power_domains)
- intel_display_power_put(dev, domain);
+ intel_display_power_put(dev_priv, domain);
crtc->enabled_power_domains = pipe_domains[crtc->pipe];
}
- intel_display_set_init_power(dev, false);
+ intel_display_set_init_power(dev_priv, false);
}
static void haswell_modeset_global_resources(struct drm_device *dev)
@@ -6986,7 +6986,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
pipe_config->cpu_transcoder = TRANSCODER_EDP;
}
- if (!intel_display_power_enabled(dev,
+ if (!intel_display_power_enabled(dev_priv,
POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder)))
return false;
@@ -7014,7 +7014,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
intel_get_pipe_timings(crtc, pipe_config);
pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
- if (intel_display_power_enabled(dev, pfit_domain))
+ if (intel_display_power_enabled(dev_priv, pfit_domain))
ironlake_get_pfit_config(crtc, pipe_config);
if (IS_HASWELL(dev))
@@ -11602,7 +11602,8 @@ intel_display_capture_error_state(struct drm_device *dev)
for_each_pipe(i) {
error->pipe[i].power_domain_on =
- intel_display_power_enabled_sw(dev, POWER_DOMAIN_PIPE(i));
+ intel_display_power_enabled_sw(dev_priv,
+ POWER_DOMAIN_PIPE(i));
if (!error->pipe[i].power_domain_on)
continue;
@@ -11640,7 +11641,7 @@ intel_display_capture_error_state(struct drm_device *dev)
enum transcoder cpu_transcoder = transcoders[i];
error->transcoder[i].power_domain_on =
- intel_display_power_enabled_sw(dev,
+ intel_display_power_enabled_sw(dev_priv,
POWER_DOMAIN_TRANSCODER(cpu_transcoder));
if (!error->transcoder[i].power_domain_on)
continue;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a4ffc02..6042797 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -732,7 +732,7 @@ ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
bool intel_crtc_active(struct drm_crtc *crtc);
void hsw_enable_ips(struct intel_crtc *crtc);
void hsw_disable_ips(struct intel_crtc *crtc);
-void intel_display_set_init_power(struct drm_device *dev, bool enable);
+void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
int valleyview_get_vco(struct drm_i915_private *dev_priv);
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
struct intel_crtc_config *pipe_config);
@@ -871,18 +871,17 @@ bool intel_fbc_enabled(struct drm_device *dev);
void intel_update_fbc(struct drm_device *dev);
void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
void intel_gpu_ips_teardown(void);
-int intel_power_domains_init(struct drm_device *dev);
-void intel_power_domains_remove(struct drm_device *dev);
-bool intel_display_power_enabled(struct drm_device *dev,
+int intel_power_domains_init(struct drm_i915_private *);
+void intel_power_domains_remove(struct drm_i915_private *);
+bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
-bool intel_display_power_enabled_sw(struct drm_device *dev,
+bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
-void intel_display_power_get(struct drm_device *dev,
+void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
-void intel_display_power_put(struct drm_device *dev,
+void intel_display_power_put(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
-void intel_power_domains_init_hw(struct drm_device *dev);
-void intel_set_power_well(struct drm_device *dev, bool enable);
+void intel_power_domains_init_hw(struct drm_i915_private *dev_priv);
void intel_enable_gt_powersave(struct drm_device *dev);
void intel_disable_gt_powersave(struct drm_device *dev);
void ironlake_teardown_rc6(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c8347ae..aa9c2df 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5169,19 +5169,16 @@ void intel_suspend_hw(struct drm_device *dev)
* enable it, so check if it's enabled and also check if we've requested it to
* be enabled.
*/
-static bool hsw_power_well_enabled(struct drm_device *dev,
+static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
return I915_READ(HSW_PWR_WELL_DRIVER) ==
(HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
}
-bool intel_display_power_enabled_sw(struct drm_device *dev,
+bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_power_domains *power_domains;
power_domains = &dev_priv->power_domains;
@@ -5189,10 +5186,9 @@ bool intel_display_power_enabled_sw(struct drm_device *dev,
return power_domains->domain_use_count[domain];
}
-bool intel_display_power_enabled(struct drm_device *dev,
+bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_power_domains *power_domains;
struct i915_power_well *power_well;
bool is_enabled;
@@ -5207,7 +5203,7 @@ bool intel_display_power_enabled(struct drm_device *dev,
if (power_well->always_on)
continue;
- if (!power_well->is_enabled(dev, power_well)) {
+ if (!power_well->is_enabled(dev_priv, power_well)) {
is_enabled = false;
break;
}
@@ -5273,10 +5269,9 @@ static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
-static void hsw_set_power_well(struct drm_device *dev,
+static void hsw_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
bool is_enabled, enable_requested;
uint32_t tmp;
@@ -5310,35 +5305,30 @@ static void hsw_set_power_well(struct drm_device *dev,
}
}
-static void __intel_power_well_get(struct drm_device *dev,
+static void __intel_power_well_get(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
if (!power_well->count++ && power_well->set) {
hsw_disable_package_c8(dev_priv);
- power_well->set(dev, power_well, true);
+ power_well->set(dev_priv, power_well, true);
}
}
-static void __intel_power_well_put(struct drm_device *dev,
+static void __intel_power_well_put(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
WARN_ON(!power_well->count);
if (!--power_well->count && power_well->set &&
i915.disable_power_well) {
- power_well->set(dev, power_well, false);
+ power_well->set(dev_priv, power_well, false);
hsw_enable_package_c8(dev_priv);
}
}
-void intel_display_power_get(struct drm_device *dev,
+void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_power_domains *power_domains;
struct i915_power_well *power_well;
int i;
@@ -5348,17 +5338,16 @@ void intel_display_power_get(struct drm_device *dev,
mutex_lock(&power_domains->lock);
for_each_power_well(i, power_well, BIT(domain), power_domains)
- __intel_power_well_get(dev, power_well);
+ __intel_power_well_get(dev_priv, power_well);
power_domains->domain_use_count[domain]++;
mutex_unlock(&power_domains->lock);
}
-void intel_display_power_put(struct drm_device *dev,
+void intel_display_power_put(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_power_domains *power_domains;
struct i915_power_well *power_well;
int i;
@@ -5371,7 +5360,7 @@ void intel_display_power_put(struct drm_device *dev,
power_domains->domain_use_count[domain]--;
for_each_power_well_rev(i, power_well, BIT(domain), power_domains)
- __intel_power_well_put(dev, power_well);
+ __intel_power_well_put(dev_priv, power_well);
mutex_unlock(&power_domains->lock);
}
@@ -5388,7 +5377,7 @@ void i915_request_power_well(void)
dev_priv = container_of(hsw_pwr, struct drm_i915_private,
power_domains);
- intel_display_power_get(dev_priv->dev, POWER_DOMAIN_AUDIO);
+ intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
}
EXPORT_SYMBOL_GPL(i915_request_power_well);
@@ -5402,7 +5391,7 @@ void i915_release_power_well(void)
dev_priv = container_of(hsw_pwr, struct drm_i915_private,
power_domains);
- intel_display_power_put(dev_priv->dev, POWER_DOMAIN_AUDIO);
+ intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
}
EXPORT_SYMBOL_GPL(i915_release_power_well);
@@ -5447,9 +5436,8 @@ static struct i915_power_well bdw_power_wells[] = {
(power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
})
-int intel_power_domains_init(struct drm_device *dev)
+int intel_power_domains_init(struct drm_i915_private *dev_priv)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_power_domains *power_domains = &dev_priv->power_domains;
mutex_init(&power_domains->lock);
@@ -5458,10 +5446,10 @@ int intel_power_domains_init(struct drm_device *dev)
* The enabling order will be from lower to higher indexed wells,
* the disabling order is reversed.
*/
- if (IS_HASWELL(dev)) {
+ if (IS_HASWELL(dev_priv->dev)) {
set_power_wells(power_domains, hsw_power_wells);
hsw_pwr = power_domains;
- } else if (IS_BROADWELL(dev)) {
+ } else if (IS_BROADWELL(dev_priv->dev)) {
set_power_wells(power_domains, bdw_power_wells);
hsw_pwr = power_domains;
} else {
@@ -5471,14 +5459,13 @@ int intel_power_domains_init(struct drm_device *dev)
return 0;
}
-void intel_power_domains_remove(struct drm_device *dev)
+void intel_power_domains_remove(struct drm_i915_private *dev_priv)
{
hsw_pwr = NULL;
}
-static void intel_power_domains_resume(struct drm_device *dev)
+static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct i915_power_well *power_well;
int i;
@@ -5486,7 +5473,7 @@ static void intel_power_domains_resume(struct drm_device *dev)
mutex_lock(&power_domains->lock);
for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
if (power_well->set)
- power_well->set(dev, power_well, power_well->count > 0);
+ power_well->set(dev_priv, power_well, power_well->count > 0);
}
mutex_unlock(&power_domains->lock);
}
@@ -5497,15 +5484,13 @@ static void intel_power_domains_resume(struct drm_device *dev)
* to be enabled, and it will only be disabled if none of the registers is
* requesting it to be enabled.
*/
-void intel_power_domains_init_hw(struct drm_device *dev)
+void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
/* For now, we need the power well to be always enabled. */
- intel_display_set_init_power(dev, true);
- intel_power_domains_resume(dev);
+ intel_display_set_init_power(dev_priv, true);
+ intel_power_domains_resume(dev_priv);
- if (!(IS_HASWELL(dev) || IS_BROADWELL(dev)))
+ if (!(IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev)))
return;
/* We're taking over the BIOS, so clear any requests made by it since
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 01/21] drm/i915: use drm_i915_private everywhere in the power domain api
2014-03-04 17:22 ` [PATCH v2 01/21] drm/i915: use drm_i915_private everywhere in the power domain api Imre Deak
@ 2014-03-06 19:00 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:00 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:22:50 +0200
Imre Deak <imre.deak@intel.com> wrote:
> The power domains framework is internal to the i915 driver, so pass
> drm_i915_private instead of drm_device to its functions.
>
> Also remove a dangling intel_set_power_well() declaration.
>
> No functional change.
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> ---
> drivers/gpu/drm/i915/i915_dma.c | 14 ++++----
> drivers/gpu/drm/i915/i915_drv.c | 4 +--
> drivers/gpu/drm/i915/i915_drv.h | 4 +--
> drivers/gpu/drm/i915/intel_display.c | 27 +++++++--------
> drivers/gpu/drm/i915/intel_drv.h | 17 +++++-----
> drivers/gpu/drm/i915/intel_pm.c | 65 ++++++++++++++----------------------
> 6 files changed, 58 insertions(+), 73 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 7688abc..8177c17 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -1325,7 +1325,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
> if (ret)
> goto cleanup_gem_stolen;
>
> - intel_power_domains_init_hw(dev);
> + intel_power_domains_init_hw(dev_priv);
>
> /* Important: The output setup functions called by modeset_init need
> * working irqs for e.g. gmbus and dp aux transfers. */
> @@ -1343,7 +1343,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
> /* FIXME: do pre/post-mode set stuff in core KMS code */
> dev->vblank_disable_allowed = true;
> if (INTEL_INFO(dev)->num_pipes == 0) {
> - intel_display_power_put(dev, POWER_DOMAIN_VGA);
> + intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
> return 0;
> }
>
> @@ -1381,7 +1381,7 @@ cleanup_gem:
> WARN_ON(dev_priv->mm.aliasing_ppgtt);
> drm_mm_takedown(&dev_priv->gtt.base.mm);
> cleanup_power:
> - intel_display_power_put(dev, POWER_DOMAIN_VGA);
> + intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);
> drm_irq_uninstall(dev);
> cleanup_gem_stolen:
> i915_gem_cleanup_stolen(dev);
> @@ -1702,7 +1702,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
> goto out_gem_unload;
> }
>
> - intel_power_domains_init(dev);
> + intel_power_domains_init(dev_priv);
>
> if (drm_core_check_feature(dev, DRIVER_MODESET)) {
> ret = i915_load_modeset_init(dev);
> @@ -1731,7 +1731,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
> return 0;
>
> out_power_well:
> - intel_power_domains_remove(dev);
> + intel_power_domains_remove(dev_priv);
> drm_vblank_cleanup(dev);
> out_gem_unload:
> if (dev_priv->mm.inactive_shrinker.scan_objects)
> @@ -1781,8 +1781,8 @@ int i915_driver_unload(struct drm_device *dev)
> /* The i915.ko module is still not prepared to be loaded when
> * the power well is not enabled, so just enable it in case
> * we're going to unload/reload. */
> - intel_display_set_init_power(dev, true);
> - intel_power_domains_remove(dev);
> + intel_display_set_init_power(dev_priv, true);
> + intel_power_domains_remove(dev_priv);
>
> i915_teardown_sysfs(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 08052f3d..ce898af 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -429,7 +429,7 @@ static int i915_drm_freeze(struct drm_device *dev)
> /* We do a lot of poking in a lot of registers, make sure they work
> * properly. */
> hsw_disable_package_c8(dev_priv);
> - intel_display_set_init_power(dev, true);
> + intel_display_set_init_power(dev_priv, true);
>
> drm_kms_helper_poll_disable(dev);
>
> @@ -551,7 +551,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
> mutex_unlock(&dev->struct_mutex);
> }
>
> - intel_power_domains_init_hw(dev);
> + intel_power_domains_init_hw(dev_priv);
>
> i915_restore_state(dev);
> intel_opregion_setup(dev);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 05cfcc1..53b0512 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1024,9 +1024,9 @@ struct i915_power_well {
> int count;
> unsigned long domains;
> void *data;
> - void (*set)(struct drm_device *dev, struct i915_power_well *power_well,
> + void (*set)(struct drm_i915_private *dev_priv, struct i915_power_well *power_well,
> bool enable);
> - bool (*is_enabled)(struct drm_device *dev,
> + bool (*is_enabled)(struct drm_i915_private *dev_priv,
> struct i915_power_well *power_well);
> };
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 6f15627..5cc116b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1122,7 +1122,7 @@ void assert_pipe(struct drm_i915_private *dev_priv,
> if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
> state = true;
>
> - if (!intel_display_power_enabled(dev_priv->dev,
> + if (!intel_display_power_enabled(dev_priv,
> POWER_DOMAIN_TRANSCODER(cpu_transcoder))) {
> cur_state = false;
> } else {
> @@ -6858,23 +6858,23 @@ static unsigned long get_pipe_power_domains(struct drm_device *dev,
> return mask;
> }
>
> -void intel_display_set_init_power(struct drm_device *dev, bool enable)
> +void intel_display_set_init_power(struct drm_i915_private *dev_priv,
> + bool enable)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> -
> if (dev_priv->power_domains.init_power_on == enable)
> return;
>
> if (enable)
> - intel_display_power_get(dev, POWER_DOMAIN_INIT);
> + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> else
> - intel_display_power_put(dev, POWER_DOMAIN_INIT);
> + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
>
> dev_priv->power_domains.init_power_on = enable;
> }
>
> static void modeset_update_power_wells(struct drm_device *dev)
> {
> + struct drm_i915_private *dev_priv = dev->dev_private;
> unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
> struct intel_crtc *crtc;
>
> @@ -6893,19 +6893,19 @@ static void modeset_update_power_wells(struct drm_device *dev)
> crtc->config.pch_pfit.enabled);
>
> for_each_power_domain(domain, pipe_domains[crtc->pipe])
> - intel_display_power_get(dev, domain);
> + intel_display_power_get(dev_priv, domain);
> }
>
> list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
> enum intel_display_power_domain domain;
>
> for_each_power_domain(domain, crtc->enabled_power_domains)
> - intel_display_power_put(dev, domain);
> + intel_display_power_put(dev_priv, domain);
>
> crtc->enabled_power_domains = pipe_domains[crtc->pipe];
> }
>
> - intel_display_set_init_power(dev, false);
> + intel_display_set_init_power(dev_priv, false);
> }
>
> static void haswell_modeset_global_resources(struct drm_device *dev)
> @@ -6986,7 +6986,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> pipe_config->cpu_transcoder = TRANSCODER_EDP;
> }
>
> - if (!intel_display_power_enabled(dev,
> + if (!intel_display_power_enabled(dev_priv,
> POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder)))
> return false;
>
> @@ -7014,7 +7014,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> intel_get_pipe_timings(crtc, pipe_config);
>
> pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
> - if (intel_display_power_enabled(dev, pfit_domain))
> + if (intel_display_power_enabled(dev_priv, pfit_domain))
> ironlake_get_pfit_config(crtc, pipe_config);
>
> if (IS_HASWELL(dev))
> @@ -11602,7 +11602,8 @@ intel_display_capture_error_state(struct drm_device *dev)
>
> for_each_pipe(i) {
> error->pipe[i].power_domain_on =
> - intel_display_power_enabled_sw(dev, POWER_DOMAIN_PIPE(i));
> + intel_display_power_enabled_sw(dev_priv,
> + POWER_DOMAIN_PIPE(i));
> if (!error->pipe[i].power_domain_on)
> continue;
>
> @@ -11640,7 +11641,7 @@ intel_display_capture_error_state(struct drm_device *dev)
> enum transcoder cpu_transcoder = transcoders[i];
>
> error->transcoder[i].power_domain_on =
> - intel_display_power_enabled_sw(dev,
> + intel_display_power_enabled_sw(dev_priv,
> POWER_DOMAIN_TRANSCODER(cpu_transcoder));
> if (!error->transcoder[i].power_domain_on)
> continue;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index a4ffc02..6042797 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -732,7 +732,7 @@ ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
> bool intel_crtc_active(struct drm_crtc *crtc);
> void hsw_enable_ips(struct intel_crtc *crtc);
> void hsw_disable_ips(struct intel_crtc *crtc);
> -void intel_display_set_init_power(struct drm_device *dev, bool enable);
> +void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
> int valleyview_get_vco(struct drm_i915_private *dev_priv);
> void intel_mode_from_pipe_config(struct drm_display_mode *mode,
> struct intel_crtc_config *pipe_config);
> @@ -871,18 +871,17 @@ bool intel_fbc_enabled(struct drm_device *dev);
> void intel_update_fbc(struct drm_device *dev);
> void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
> void intel_gpu_ips_teardown(void);
> -int intel_power_domains_init(struct drm_device *dev);
> -void intel_power_domains_remove(struct drm_device *dev);
> -bool intel_display_power_enabled(struct drm_device *dev,
> +int intel_power_domains_init(struct drm_i915_private *);
> +void intel_power_domains_remove(struct drm_i915_private *);
> +bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain);
> -bool intel_display_power_enabled_sw(struct drm_device *dev,
> +bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain);
> -void intel_display_power_get(struct drm_device *dev,
> +void intel_display_power_get(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain);
> -void intel_display_power_put(struct drm_device *dev,
> +void intel_display_power_put(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain);
> -void intel_power_domains_init_hw(struct drm_device *dev);
> -void intel_set_power_well(struct drm_device *dev, bool enable);
> +void intel_power_domains_init_hw(struct drm_i915_private *dev_priv);
> void intel_enable_gt_powersave(struct drm_device *dev);
> void intel_disable_gt_powersave(struct drm_device *dev);
> void ironlake_teardown_rc6(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index c8347ae..aa9c2df 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5169,19 +5169,16 @@ void intel_suspend_hw(struct drm_device *dev)
> * enable it, so check if it's enabled and also check if we've requested it to
> * be enabled.
> */
> -static bool hsw_power_well_enabled(struct drm_device *dev,
> +static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
> struct i915_power_well *power_well)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> -
> return I915_READ(HSW_PWR_WELL_DRIVER) ==
> (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
> }
>
> -bool intel_display_power_enabled_sw(struct drm_device *dev,
> +bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct i915_power_domains *power_domains;
>
> power_domains = &dev_priv->power_domains;
> @@ -5189,10 +5186,9 @@ bool intel_display_power_enabled_sw(struct drm_device *dev,
> return power_domains->domain_use_count[domain];
> }
>
> -bool intel_display_power_enabled(struct drm_device *dev,
> +bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct i915_power_domains *power_domains;
> struct i915_power_well *power_well;
> bool is_enabled;
> @@ -5207,7 +5203,7 @@ bool intel_display_power_enabled(struct drm_device *dev,
> if (power_well->always_on)
> continue;
>
> - if (!power_well->is_enabled(dev, power_well)) {
> + if (!power_well->is_enabled(dev_priv, power_well)) {
> is_enabled = false;
> break;
> }
> @@ -5273,10 +5269,9 @@ static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
> spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> }
>
> -static void hsw_set_power_well(struct drm_device *dev,
> +static void hsw_set_power_well(struct drm_i915_private *dev_priv,
> struct i915_power_well *power_well, bool enable)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> bool is_enabled, enable_requested;
> uint32_t tmp;
>
> @@ -5310,35 +5305,30 @@ static void hsw_set_power_well(struct drm_device *dev,
> }
> }
>
> -static void __intel_power_well_get(struct drm_device *dev,
> +static void __intel_power_well_get(struct drm_i915_private *dev_priv,
> struct i915_power_well *power_well)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> -
> if (!power_well->count++ && power_well->set) {
> hsw_disable_package_c8(dev_priv);
> - power_well->set(dev, power_well, true);
> + power_well->set(dev_priv, power_well, true);
> }
> }
>
> -static void __intel_power_well_put(struct drm_device *dev,
> +static void __intel_power_well_put(struct drm_i915_private *dev_priv,
> struct i915_power_well *power_well)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> -
> WARN_ON(!power_well->count);
>
> if (!--power_well->count && power_well->set &&
> i915.disable_power_well) {
> - power_well->set(dev, power_well, false);
> + power_well->set(dev_priv, power_well, false);
> hsw_enable_package_c8(dev_priv);
> }
> }
>
> -void intel_display_power_get(struct drm_device *dev,
> +void intel_display_power_get(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct i915_power_domains *power_domains;
> struct i915_power_well *power_well;
> int i;
> @@ -5348,17 +5338,16 @@ void intel_display_power_get(struct drm_device *dev,
> mutex_lock(&power_domains->lock);
>
> for_each_power_well(i, power_well, BIT(domain), power_domains)
> - __intel_power_well_get(dev, power_well);
> + __intel_power_well_get(dev_priv, power_well);
>
> power_domains->domain_use_count[domain]++;
>
> mutex_unlock(&power_domains->lock);
> }
>
> -void intel_display_power_put(struct drm_device *dev,
> +void intel_display_power_put(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct i915_power_domains *power_domains;
> struct i915_power_well *power_well;
> int i;
> @@ -5371,7 +5360,7 @@ void intel_display_power_put(struct drm_device *dev,
> power_domains->domain_use_count[domain]--;
>
> for_each_power_well_rev(i, power_well, BIT(domain), power_domains)
> - __intel_power_well_put(dev, power_well);
> + __intel_power_well_put(dev_priv, power_well);
>
> mutex_unlock(&power_domains->lock);
> }
> @@ -5388,7 +5377,7 @@ void i915_request_power_well(void)
>
> dev_priv = container_of(hsw_pwr, struct drm_i915_private,
> power_domains);
> - intel_display_power_get(dev_priv->dev, POWER_DOMAIN_AUDIO);
> + intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
> }
> EXPORT_SYMBOL_GPL(i915_request_power_well);
>
> @@ -5402,7 +5391,7 @@ void i915_release_power_well(void)
>
> dev_priv = container_of(hsw_pwr, struct drm_i915_private,
> power_domains);
> - intel_display_power_put(dev_priv->dev, POWER_DOMAIN_AUDIO);
> + intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
> }
> EXPORT_SYMBOL_GPL(i915_release_power_well);
>
> @@ -5447,9 +5436,8 @@ static struct i915_power_well bdw_power_wells[] = {
> (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
> })
>
> -int intel_power_domains_init(struct drm_device *dev)
> +int intel_power_domains_init(struct drm_i915_private *dev_priv)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct i915_power_domains *power_domains = &dev_priv->power_domains;
>
> mutex_init(&power_domains->lock);
> @@ -5458,10 +5446,10 @@ int intel_power_domains_init(struct drm_device *dev)
> * The enabling order will be from lower to higher indexed wells,
> * the disabling order is reversed.
> */
> - if (IS_HASWELL(dev)) {
> + if (IS_HASWELL(dev_priv->dev)) {
> set_power_wells(power_domains, hsw_power_wells);
> hsw_pwr = power_domains;
> - } else if (IS_BROADWELL(dev)) {
> + } else if (IS_BROADWELL(dev_priv->dev)) {
> set_power_wells(power_domains, bdw_power_wells);
> hsw_pwr = power_domains;
> } else {
> @@ -5471,14 +5459,13 @@ int intel_power_domains_init(struct drm_device *dev)
> return 0;
> }
>
> -void intel_power_domains_remove(struct drm_device *dev)
> +void intel_power_domains_remove(struct drm_i915_private *dev_priv)
> {
> hsw_pwr = NULL;
> }
>
> -static void intel_power_domains_resume(struct drm_device *dev)
> +static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct i915_power_domains *power_domains = &dev_priv->power_domains;
> struct i915_power_well *power_well;
> int i;
> @@ -5486,7 +5473,7 @@ static void intel_power_domains_resume(struct drm_device *dev)
> mutex_lock(&power_domains->lock);
> for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
> if (power_well->set)
> - power_well->set(dev, power_well, power_well->count > 0);
> + power_well->set(dev_priv, power_well, power_well->count > 0);
> }
> mutex_unlock(&power_domains->lock);
> }
> @@ -5497,15 +5484,13 @@ static void intel_power_domains_resume(struct drm_device *dev)
> * to be enabled, and it will only be disabled if none of the registers is
> * requesting it to be enabled.
> */
> -void intel_power_domains_init_hw(struct drm_device *dev)
> +void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> -
> /* For now, we need the power well to be always enabled. */
> - intel_display_set_init_power(dev, true);
> - intel_power_domains_resume(dev);
> + intel_display_set_init_power(dev_priv, true);
> + intel_power_domains_resume(dev_priv);
>
> - if (!(IS_HASWELL(dev) || IS_BROADWELL(dev)))
> + if (!(IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev)))
> return;
>
> /* We're taking over the BIOS, so clear any requests made by it since
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 02/21] drm/i915: fold in __intel_power_well_get/put functions
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
2014-03-04 17:22 ` [PATCH v2 01/21] drm/i915: use drm_i915_private everywhere in the power domain api Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-04 17:22 ` [PATCH v2 03/21] drm/i915: move modeset_update_power_wells earlier Imre Deak
` (18 subsequent siblings)
20 siblings, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
These functions are used only by a single call site and are simple
enough to just fold them in.
Note that in later patches the parts folded in here are further
simplified as we'll remove hsw_{disable,enable}_package_c8 and the NULL
check of the power well enable/disable handlers. All this means that at
the end intel_display_power_get/put() becomes more understandable as we
don't need to jump between two functions when reading the code.
No functional change.
v2:
- clarify the rational for the change (Chris)
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_pm.c | 37 +++++++++++++------------------------
1 file changed, 13 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index aa9c2df..db48d55 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5305,27 +5305,6 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
}
}
-static void __intel_power_well_get(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- if (!power_well->count++ && power_well->set) {
- hsw_disable_package_c8(dev_priv);
- power_well->set(dev_priv, power_well, true);
- }
-}
-
-static void __intel_power_well_put(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- WARN_ON(!power_well->count);
-
- if (!--power_well->count && power_well->set &&
- i915.disable_power_well) {
- power_well->set(dev_priv, power_well, false);
- hsw_enable_package_c8(dev_priv);
- }
-}
-
void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
@@ -5338,7 +5317,10 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
mutex_lock(&power_domains->lock);
for_each_power_well(i, power_well, BIT(domain), power_domains)
- __intel_power_well_get(dev_priv, power_well);
+ if (!power_well->count++ && power_well->set) {
+ hsw_disable_package_c8(dev_priv);
+ power_well->set(dev_priv, power_well, true);
+ }
power_domains->domain_use_count[domain]++;
@@ -5359,8 +5341,15 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
WARN_ON(!power_domains->domain_use_count[domain]);
power_domains->domain_use_count[domain]--;
- for_each_power_well_rev(i, power_well, BIT(domain), power_domains)
- __intel_power_well_put(dev_priv, power_well);
+ for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
+ WARN_ON(!power_well->count);
+
+ if (!--power_well->count && power_well->set &&
+ i915.disable_power_well) {
+ power_well->set(dev_priv, power_well, false);
+ hsw_enable_package_c8(dev_priv);
+ }
+ }
mutex_unlock(&power_domains->lock);
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v2 03/21] drm/i915: move modeset_update_power_wells earlier
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
2014-03-04 17:22 ` [PATCH v2 01/21] drm/i915: use drm_i915_private everywhere in the power domain api Imre Deak
2014-03-04 17:22 ` [PATCH v2 02/21] drm/i915: fold in __intel_power_well_get/put functions Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
2014-03-04 17:22 ` [PATCH v2 04/21] drm/i915: move power domain macros to intel_pm.c Imre Deak
` (17 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
These functions will be needed by the valleyview specific power well
update functionality added in an upcoming patch, so move them earlier.
No functional change.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_display.c | 140 +++++++++++++++++------------------
1 file changed, 70 insertions(+), 70 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5cc116b..70b7c42 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3953,6 +3953,76 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
I915_WRITE(BCLRPAT(crtc->pipe), 0);
}
+#define for_each_power_domain(domain, mask) \
+ for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
+ if ((1 << (domain)) & (mask))
+
+static unsigned long get_pipe_power_domains(struct drm_device *dev,
+ enum pipe pipe, bool pfit_enabled)
+{
+ unsigned long mask;
+ enum transcoder transcoder;
+
+ transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
+
+ mask = BIT(POWER_DOMAIN_PIPE(pipe));
+ mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
+ if (pfit_enabled)
+ mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
+
+ return mask;
+}
+
+void intel_display_set_init_power(struct drm_i915_private *dev_priv,
+ bool enable)
+{
+ if (dev_priv->power_domains.init_power_on == enable)
+ return;
+
+ if (enable)
+ intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+ else
+ intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+
+ dev_priv->power_domains.init_power_on = enable;
+}
+
+static void modeset_update_power_wells(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
+ struct intel_crtc *crtc;
+
+ /*
+ * First get all needed power domains, then put all unneeded, to avoid
+ * any unnecessary toggling of the power wells.
+ */
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+ enum intel_display_power_domain domain;
+
+ if (!crtc->base.enabled)
+ continue;
+
+ pipe_domains[crtc->pipe] = get_pipe_power_domains(dev,
+ crtc->pipe,
+ crtc->config.pch_pfit.enabled);
+
+ for_each_power_domain(domain, pipe_domains[crtc->pipe])
+ intel_display_power_get(dev_priv, domain);
+ }
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+ enum intel_display_power_domain domain;
+
+ for_each_power_domain(domain, crtc->enabled_power_domains)
+ intel_display_power_put(dev_priv, domain);
+
+ crtc->enabled_power_domains = pipe_domains[crtc->pipe];
+ }
+
+ intel_display_set_init_power(dev_priv, false);
+}
+
int valleyview_get_vco(struct drm_i915_private *dev_priv)
{
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
@@ -6838,76 +6908,6 @@ static void hsw_package_c8_gpu_busy(struct drm_i915_private *dev_priv)
mutex_unlock(&dev_priv->pc8.lock);
}
-#define for_each_power_domain(domain, mask) \
- for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
- if ((1 << (domain)) & (mask))
-
-static unsigned long get_pipe_power_domains(struct drm_device *dev,
- enum pipe pipe, bool pfit_enabled)
-{
- unsigned long mask;
- enum transcoder transcoder;
-
- transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
-
- mask = BIT(POWER_DOMAIN_PIPE(pipe));
- mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
- if (pfit_enabled)
- mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
-
- return mask;
-}
-
-void intel_display_set_init_power(struct drm_i915_private *dev_priv,
- bool enable)
-{
- if (dev_priv->power_domains.init_power_on == enable)
- return;
-
- if (enable)
- intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
- else
- intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
-
- dev_priv->power_domains.init_power_on = enable;
-}
-
-static void modeset_update_power_wells(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
- struct intel_crtc *crtc;
-
- /*
- * First get all needed power domains, then put all unneeded, to avoid
- * any unnecessary toggling of the power wells.
- */
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
- enum intel_display_power_domain domain;
-
- if (!crtc->base.enabled)
- continue;
-
- pipe_domains[crtc->pipe] = get_pipe_power_domains(dev,
- crtc->pipe,
- crtc->config.pch_pfit.enabled);
-
- for_each_power_domain(domain, pipe_domains[crtc->pipe])
- intel_display_power_get(dev_priv, domain);
- }
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
- enum intel_display_power_domain domain;
-
- for_each_power_domain(domain, crtc->enabled_power_domains)
- intel_display_power_put(dev_priv, domain);
-
- crtc->enabled_power_domains = pipe_domains[crtc->pipe];
- }
-
- intel_display_set_init_power(dev_priv, false);
-}
-
static void haswell_modeset_global_resources(struct drm_device *dev)
{
modeset_update_power_wells(dev);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v3 03/21] drm/i915: move modeset_update_power_wells earlier
2014-03-04 17:22 ` [PATCH v2 03/21] drm/i915: move modeset_update_power_wells earlier Imre Deak
@ 2014-03-05 14:20 ` Imre Deak
0 siblings, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-05 14:20 UTC (permalink / raw)
To: intel-gfx
These functions will be needed by the valleyview specific power well
update functionality added in an upcoming patch, so move them earlier.
No functional change.
v2:
- no change
v3:
- rebase on latest -nightly
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 140 +++++++++++++++++------------------
1 file changed, 70 insertions(+), 70 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a57a35f..6b5df4e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3958,6 +3958,76 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
I915_WRITE(BCLRPAT(crtc->pipe), 0);
}
+#define for_each_power_domain(domain, mask) \
+ for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
+ if ((1 << (domain)) & (mask))
+
+static unsigned long get_pipe_power_domains(struct drm_device *dev,
+ enum pipe pipe, bool pfit_enabled)
+{
+ unsigned long mask;
+ enum transcoder transcoder;
+
+ transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
+
+ mask = BIT(POWER_DOMAIN_PIPE(pipe));
+ mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
+ if (pfit_enabled)
+ mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
+
+ return mask;
+}
+
+void intel_display_set_init_power(struct drm_i915_private *dev_priv,
+ bool enable)
+{
+ if (dev_priv->power_domains.init_power_on == enable)
+ return;
+
+ if (enable)
+ intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+ else
+ intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
+
+ dev_priv->power_domains.init_power_on = enable;
+}
+
+static void modeset_update_crtc_power_domains(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
+ struct intel_crtc *crtc;
+
+ /*
+ * First get all needed power domains, then put all unneeded, to avoid
+ * any unnecessary toggling of the power wells.
+ */
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+ enum intel_display_power_domain domain;
+
+ if (!crtc->base.enabled)
+ continue;
+
+ pipe_domains[crtc->pipe] = get_pipe_power_domains(dev,
+ crtc->pipe,
+ crtc->config.pch_pfit.enabled);
+
+ for_each_power_domain(domain, pipe_domains[crtc->pipe])
+ intel_display_power_get(dev_priv, domain);
+ }
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+ enum intel_display_power_domain domain;
+
+ for_each_power_domain(domain, crtc->enabled_power_domains)
+ intel_display_power_put(dev_priv, domain);
+
+ crtc->enabled_power_domains = pipe_domains[crtc->pipe];
+ }
+
+ intel_display_set_init_power(dev_priv, false);
+}
+
int valleyview_get_vco(struct drm_i915_private *dev_priv)
{
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
@@ -6817,76 +6887,6 @@ done:
mutex_unlock(&dev_priv->pc8.lock);
}
-#define for_each_power_domain(domain, mask) \
- for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
- if ((1 << (domain)) & (mask))
-
-static unsigned long get_pipe_power_domains(struct drm_device *dev,
- enum pipe pipe, bool pfit_enabled)
-{
- unsigned long mask;
- enum transcoder transcoder;
-
- transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
-
- mask = BIT(POWER_DOMAIN_PIPE(pipe));
- mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
- if (pfit_enabled)
- mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
-
- return mask;
-}
-
-void intel_display_set_init_power(struct drm_i915_private *dev_priv,
- bool enable)
-{
- if (dev_priv->power_domains.init_power_on == enable)
- return;
-
- if (enable)
- intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
- else
- intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
-
- dev_priv->power_domains.init_power_on = enable;
-}
-
-static void modeset_update_crtc_power_domains(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
- struct intel_crtc *crtc;
-
- /*
- * First get all needed power domains, then put all unneeded, to avoid
- * any unnecessary toggling of the power wells.
- */
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
- enum intel_display_power_domain domain;
-
- if (!crtc->base.enabled)
- continue;
-
- pipe_domains[crtc->pipe] = get_pipe_power_domains(dev,
- crtc->pipe,
- crtc->config.pch_pfit.enabled);
-
- for_each_power_domain(domain, pipe_domains[crtc->pipe])
- intel_display_power_get(dev_priv, domain);
- }
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
- enum intel_display_power_domain domain;
-
- for_each_power_domain(domain, crtc->enabled_power_domains)
- intel_display_power_put(dev_priv, domain);
-
- crtc->enabled_power_domains = pipe_domains[crtc->pipe];
- }
-
- intel_display_set_init_power(dev_priv, false);
-}
-
static void haswell_modeset_global_resources(struct drm_device *dev)
{
modeset_update_crtc_power_domains(dev);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v2 04/21] drm/i915: move power domain macros to intel_pm.c
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (2 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 03/21] drm/i915: move modeset_update_power_wells earlier Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-06 19:00 ` Jesse Barnes
2014-03-04 17:22 ` [PATCH v2 05/21] drm/i915: add init power domain to always-on power wells Imre Deak
` (16 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
These macros are used only locally, so move them to the .c file.
No functional change.
v2:
- add init power domain to always-on power wells in the following
- separate - patch (Paulo)
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 10 ----------
drivers/gpu/drm/i915/intel_pm.c | 20 ++++++++++++++++++--
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 53b0512..0794bbd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -121,8 +121,6 @@ enum intel_display_power_domain {
POWER_DOMAIN_NUM,
};
-#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
-
#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
@@ -130,14 +128,6 @@ enum intel_display_power_domain {
((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
(tran) + POWER_DOMAIN_TRANSCODER_A)
-#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
- BIT(POWER_DOMAIN_PIPE_A) | \
- BIT(POWER_DOMAIN_TRANSCODER_EDP))
-#define BDW_ALWAYS_ON_POWER_DOMAINS ( \
- BIT(POWER_DOMAIN_PIPE_A) | \
- BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
- BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER))
-
enum hpd_pin {
HPD_NONE = 0,
HPD_PORT_A = HPD_NONE, /* PORT_A is internal */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index db48d55..ebbd0ed 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5384,6 +5384,22 @@ void i915_release_power_well(void)
}
EXPORT_SYMBOL_GPL(i915_release_power_well);
+#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
+
+#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PIPE_A) | \
+ BIT(POWER_DOMAIN_TRANSCODER_EDP))
+#define HSW_DISPLAY_POWER_DOMAINS ( \
+ (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define BDW_ALWAYS_ON_POWER_DOMAINS ( \
+ HSW_ALWAYS_ON_POWER_DOMAINS | \
+ BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER))
+#define BDW_DISPLAY_POWER_DOMAINS ( \
+ (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
+ BIT(POWER_DOMAIN_INIT))
+
static struct i915_power_well i9xx_always_on_power_well[] = {
{
.name = "always-on",
@@ -5400,7 +5416,7 @@ static struct i915_power_well hsw_power_wells[] = {
},
{
.name = "display",
- .domains = POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS,
+ .domains = HSW_DISPLAY_POWER_DOMAINS,
.is_enabled = hsw_power_well_enabled,
.set = hsw_set_power_well,
},
@@ -5414,7 +5430,7 @@ static struct i915_power_well bdw_power_wells[] = {
},
{
.name = "display",
- .domains = POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS,
+ .domains = BDW_DISPLAY_POWER_DOMAINS,
.is_enabled = hsw_power_well_enabled,
.set = hsw_set_power_well,
},
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 04/21] drm/i915: move power domain macros to intel_pm.c
2014-03-04 17:22 ` [PATCH v2 04/21] drm/i915: move power domain macros to intel_pm.c Imre Deak
@ 2014-03-06 19:00 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:00 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:22:53 +0200
Imre Deak <imre.deak@intel.com> wrote:
> These macros are used only locally, so move them to the .c file.
>
> No functional change.
>
> v2:
> - add init power domain to always-on power wells in the following
> - separate - patch (Paulo)
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 10 ----------
> drivers/gpu/drm/i915/intel_pm.c | 20 ++++++++++++++++++--
> 2 files changed, 18 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 53b0512..0794bbd 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -121,8 +121,6 @@ enum intel_display_power_domain {
> POWER_DOMAIN_NUM,
> };
>
> -#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
> -
> #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
> #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
> ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
> @@ -130,14 +128,6 @@ enum intel_display_power_domain {
> ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
> (tran) + POWER_DOMAIN_TRANSCODER_A)
>
> -#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
> - BIT(POWER_DOMAIN_PIPE_A) | \
> - BIT(POWER_DOMAIN_TRANSCODER_EDP))
> -#define BDW_ALWAYS_ON_POWER_DOMAINS ( \
> - BIT(POWER_DOMAIN_PIPE_A) | \
> - BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
> - BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER))
> -
> enum hpd_pin {
> HPD_NONE = 0,
> HPD_PORT_A = HPD_NONE, /* PORT_A is internal */
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index db48d55..ebbd0ed 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5384,6 +5384,22 @@ void i915_release_power_well(void)
> }
> EXPORT_SYMBOL_GPL(i915_release_power_well);
>
> +#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
> +
> +#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
> + BIT(POWER_DOMAIN_PIPE_A) | \
> + BIT(POWER_DOMAIN_TRANSCODER_EDP))
> +#define HSW_DISPLAY_POWER_DOMAINS ( \
> + (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
> + BIT(POWER_DOMAIN_INIT))
> +
> +#define BDW_ALWAYS_ON_POWER_DOMAINS ( \
> + HSW_ALWAYS_ON_POWER_DOMAINS | \
> + BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER))
> +#define BDW_DISPLAY_POWER_DOMAINS ( \
> + (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
> + BIT(POWER_DOMAIN_INIT))
> +
> static struct i915_power_well i9xx_always_on_power_well[] = {
> {
> .name = "always-on",
> @@ -5400,7 +5416,7 @@ static struct i915_power_well hsw_power_wells[] = {
> },
> {
> .name = "display",
> - .domains = POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS,
> + .domains = HSW_DISPLAY_POWER_DOMAINS,
> .is_enabled = hsw_power_well_enabled,
> .set = hsw_set_power_well,
> },
> @@ -5414,7 +5430,7 @@ static struct i915_power_well bdw_power_wells[] = {
> },
> {
> .name = "display",
> - .domains = POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS,
> + .domains = BDW_DISPLAY_POWER_DOMAINS,
> .is_enabled = hsw_power_well_enabled,
> .set = hsw_set_power_well,
> },
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 05/21] drm/i915: add init power domain to always-on power wells
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (3 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 04/21] drm/i915: move power domain macros to intel_pm.c Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-06 19:01 ` Jesse Barnes
2014-03-04 17:22 ` [PATCH v2 06/21] drm/i915: split power well 'set' handler to separate enable/disable/sync_hw Imre Deak
` (15 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
Whenever we request a power domain it has to guarantee that all HW
resources are enabled that are needed to access a HW register associated
with that power domain. In case a register is on an always-on power well
this won't result in turning on a power well, but it may require
enabling some other HW resource. One such resource is the HSW/BDW device
D0 state that is required for all register accesses and thus for all
power wells/power domains.
So far the init power domain (guaranteeing access to all HW registers)
was part of the default i9xx always-on power well, but not the HSW/BDW
always-on power wells. Add the domain to the latter power wells too.
Atm, all the always-on power wells have noop handlers, so this doesn't
change the functionality.
v2:
- clarify semantics of always-on power wells (Paulo)
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ebbd0ed..9a608f1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5388,7 +5388,8 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PIPE_A) | \
- BIT(POWER_DOMAIN_TRANSCODER_EDP))
+ BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
+ BIT(POWER_DOMAIN_INIT))
#define HSW_DISPLAY_POWER_DOMAINS ( \
(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
BIT(POWER_DOMAIN_INIT))
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 05/21] drm/i915: add init power domain to always-on power wells
2014-03-04 17:22 ` [PATCH v2 05/21] drm/i915: add init power domain to always-on power wells Imre Deak
@ 2014-03-06 19:01 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:01 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:22:54 +0200
Imre Deak <imre.deak@intel.com> wrote:
> Whenever we request a power domain it has to guarantee that all HW
> resources are enabled that are needed to access a HW register associated
> with that power domain. In case a register is on an always-on power well
> this won't result in turning on a power well, but it may require
> enabling some other HW resource. One such resource is the HSW/BDW device
> D0 state that is required for all register accesses and thus for all
> power wells/power domains.
>
> So far the init power domain (guaranteeing access to all HW registers)
> was part of the default i9xx always-on power well, but not the HSW/BDW
> always-on power wells. Add the domain to the latter power wells too.
>
> Atm, all the always-on power wells have noop handlers, so this doesn't
> change the functionality.
>
> v2:
> - clarify semantics of always-on power wells (Paulo)
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_pm.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index ebbd0ed..9a608f1 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5388,7 +5388,8 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
>
> #define HSW_ALWAYS_ON_POWER_DOMAINS ( \
> BIT(POWER_DOMAIN_PIPE_A) | \
> - BIT(POWER_DOMAIN_TRANSCODER_EDP))
> + BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
> + BIT(POWER_DOMAIN_INIT))
> #define HSW_DISPLAY_POWER_DOMAINS ( \
> (POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
> BIT(POWER_DOMAIN_INIT))
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 06/21] drm/i915: split power well 'set' handler to separate enable/disable/sync_hw
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (4 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 05/21] drm/i915: add init power domain to always-on power wells Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-06 20:04 ` Daniel Vetter
2014-03-04 17:22 ` [PATCH v2 07/21] drm/i915: add noop power well handlers instead of NULL checking them Imre Deak
` (14 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
Split the 'set' power well handler into an 'enable', 'disable' and
'sync_hw' handler. This maps more conveniently to higher level
operations, for example it allows us to push the hsw package c8 handling
into the corresponding hsw/bdw enable/disable handlers and the hsw BIOS
hand-over setting into the hsw/bdw sync_hw handler.
No functional change.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_drv.h | 35 +++++++++++++++++---
drivers/gpu/drm/i915/intel_pm.c | 73 +++++++++++++++++++++++++++--------------
2 files changed, 80 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0794bbd..2b6d2a2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1006,6 +1006,36 @@ struct intel_ilk_power_mgmt {
struct drm_i915_gem_object *renderctx;
};
+struct drm_i915_private;
+struct i915_power_well;
+
+struct i915_power_well_ops {
+ /*
+ * Synchronize the well's hw state to match the current sw state, for
+ * example enable/disable it based on the current refcount. Called
+ * during driver init and resume time, possibly after first calling
+ * the enable/disable handlers.
+ */
+ void (*sync_hw)(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well);
+ /*
+ * Enable the well and resources that depend on it (for example
+ * interrupts located on the well). Called after the 0->1 refcount
+ * transition.
+ */
+ void (*enable)(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well);
+ /*
+ * Disable the well and resources that depend on it. Called after
+ * the 1->0 refcount transition.
+ */
+ void (*disable)(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well);
+ /* Returns the hw enabled state. */
+ bool (*is_enabled)(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well);
+};
+
/* Power well structure for haswell */
struct i915_power_well {
const char *name;
@@ -1014,10 +1044,7 @@ struct i915_power_well {
int count;
unsigned long domains;
void *data;
- void (*set)(struct drm_i915_private *dev_priv, struct i915_power_well *power_well,
- bool enable);
- bool (*is_enabled)(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well);
+ const struct i915_power_well_ops *ops;
};
struct i915_power_domains {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9a608f1..7866426 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5203,7 +5203,7 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
if (power_well->always_on)
continue;
- if (!power_well->is_enabled(dev_priv, power_well)) {
+ if (!power_well->ops->is_enabled(dev_priv, power_well)) {
is_enabled = false;
break;
}
@@ -5305,6 +5305,33 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
}
}
+static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ hsw_set_power_well(dev_priv, power_well, power_well->count > 0);
+
+ /*
+ * We're taking over the BIOS, so clear any requests made by it since
+ * the driver is in charge now.
+ */
+ if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST)
+ I915_WRITE(HSW_PWR_WELL_BIOS, 0);
+}
+
+static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ hsw_disable_package_c8(dev_priv);
+ hsw_set_power_well(dev_priv, power_well, true);
+}
+
+static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ hsw_set_power_well(dev_priv, power_well, false);
+ hsw_enable_package_c8(dev_priv);
+}
+
void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
@@ -5317,10 +5344,8 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
mutex_lock(&power_domains->lock);
for_each_power_well(i, power_well, BIT(domain), power_domains)
- if (!power_well->count++ && power_well->set) {
- hsw_disable_package_c8(dev_priv);
- power_well->set(dev_priv, power_well, true);
- }
+ if (!power_well->count++ && power_well->ops->enable)
+ power_well->ops->enable(dev_priv, power_well);
power_domains->domain_use_count[domain]++;
@@ -5344,11 +5369,9 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
WARN_ON(!power_well->count);
- if (!--power_well->count && power_well->set &&
- i915.disable_power_well) {
- power_well->set(dev_priv, power_well, false);
- hsw_enable_package_c8(dev_priv);
- }
+ if (!--power_well->count && power_well->ops->disable &&
+ i915.disable_power_well)
+ power_well->ops->disable(dev_priv, power_well);
}
mutex_unlock(&power_domains->lock);
@@ -5401,25 +5424,35 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
(POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
BIT(POWER_DOMAIN_INIT))
+static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { };
+
static struct i915_power_well i9xx_always_on_power_well[] = {
{
.name = "always-on",
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
+ .ops = &i9xx_always_on_power_well_ops,
},
};
+static const struct i915_power_well_ops hsw_power_well_ops = {
+ .sync_hw = hsw_power_well_sync_hw,
+ .enable = hsw_power_well_enable,
+ .disable = hsw_power_well_disable,
+ .is_enabled = hsw_power_well_enabled,
+};
+
static struct i915_power_well hsw_power_wells[] = {
{
.name = "always-on",
.always_on = 1,
.domains = HSW_ALWAYS_ON_POWER_DOMAINS,
+ .ops = &i9xx_always_on_power_well_ops,
},
{
.name = "display",
.domains = HSW_DISPLAY_POWER_DOMAINS,
- .is_enabled = hsw_power_well_enabled,
- .set = hsw_set_power_well,
+ .ops = &hsw_power_well_ops,
},
};
@@ -5428,12 +5461,12 @@ static struct i915_power_well bdw_power_wells[] = {
.name = "always-on",
.always_on = 1,
.domains = BDW_ALWAYS_ON_POWER_DOMAINS,
+ .ops = &i9xx_always_on_power_well_ops,
},
{
.name = "display",
.domains = BDW_DISPLAY_POWER_DOMAINS,
- .is_enabled = hsw_power_well_enabled,
- .set = hsw_set_power_well,
+ .ops = &hsw_power_well_ops,
},
};
@@ -5478,8 +5511,8 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
mutex_lock(&power_domains->lock);
for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
- if (power_well->set)
- power_well->set(dev_priv, power_well, power_well->count > 0);
+ if (power_well->ops->sync_hw)
+ power_well->ops->sync_hw(dev_priv, power_well);
}
mutex_unlock(&power_domains->lock);
}
@@ -5495,14 +5528,6 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
/* For now, we need the power well to be always enabled. */
intel_display_set_init_power(dev_priv, true);
intel_power_domains_resume(dev_priv);
-
- if (!(IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev)))
- return;
-
- /* We're taking over the BIOS, so clear any requests made by it since
- * the driver is in charge now. */
- if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST)
- I915_WRITE(HSW_PWR_WELL_BIOS, 0);
}
/* Disables PC8 so we can use the GMBUS and DP AUX interrupts. */
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 06/21] drm/i915: split power well 'set' handler to separate enable/disable/sync_hw
2014-03-04 17:22 ` [PATCH v2 06/21] drm/i915: split power well 'set' handler to separate enable/disable/sync_hw Imre Deak
@ 2014-03-06 20:04 ` Daniel Vetter
0 siblings, 0 replies; 45+ messages in thread
From: Daniel Vetter @ 2014-03-06 20:04 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, Mar 04, 2014 at 07:22:55PM +0200, Imre Deak wrote:
> Split the 'set' power well handler into an 'enable', 'disable' and
> 'sync_hw' handler. This maps more conveniently to higher level
> operations, for example it allows us to push the hsw package c8 handling
> into the corresponding hsw/bdw enable/disable handlers and the hsw BIOS
> hand-over setting into the hsw/bdw sync_hw handler.
>
> No functional change.
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
checkpatch complained about some whitespace fail in this patch. I've fixed
it up, but please double check this in the future.
-Daniel
> ---
> drivers/gpu/drm/i915/i915_drv.h | 35 +++++++++++++++++---
> drivers/gpu/drm/i915/intel_pm.c | 73 +++++++++++++++++++++++++++--------------
> 2 files changed, 80 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 0794bbd..2b6d2a2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1006,6 +1006,36 @@ struct intel_ilk_power_mgmt {
> struct drm_i915_gem_object *renderctx;
> };
>
> +struct drm_i915_private;
> +struct i915_power_well;
> +
> +struct i915_power_well_ops {
> + /*
> + * Synchronize the well's hw state to match the current sw state, for
> + * example enable/disable it based on the current refcount. Called
> + * during driver init and resume time, possibly after first calling
> + * the enable/disable handlers.
> + */
> + void (*sync_hw)(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well);
> + /*
> + * Enable the well and resources that depend on it (for example
> + * interrupts located on the well). Called after the 0->1 refcount
> + * transition.
> + */
> + void (*enable)(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well);
> + /*
> + * Disable the well and resources that depend on it. Called after
> + * the 1->0 refcount transition.
> + */
> + void (*disable)(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well);
> + /* Returns the hw enabled state. */
> + bool (*is_enabled)(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well);
> +};
> +
> /* Power well structure for haswell */
> struct i915_power_well {
> const char *name;
> @@ -1014,10 +1044,7 @@ struct i915_power_well {
> int count;
> unsigned long domains;
> void *data;
> - void (*set)(struct drm_i915_private *dev_priv, struct i915_power_well *power_well,
> - bool enable);
> - bool (*is_enabled)(struct drm_i915_private *dev_priv,
> - struct i915_power_well *power_well);
> + const struct i915_power_well_ops *ops;
> };
>
> struct i915_power_domains {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 9a608f1..7866426 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5203,7 +5203,7 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
> if (power_well->always_on)
> continue;
>
> - if (!power_well->is_enabled(dev_priv, power_well)) {
> + if (!power_well->ops->is_enabled(dev_priv, power_well)) {
> is_enabled = false;
> break;
> }
> @@ -5305,6 +5305,33 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
> }
> }
>
> +static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + hsw_set_power_well(dev_priv, power_well, power_well->count > 0);
> +
> + /*
> + * We're taking over the BIOS, so clear any requests made by it since
> + * the driver is in charge now.
> + */
> + if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST)
> + I915_WRITE(HSW_PWR_WELL_BIOS, 0);
> +}
> +
> +static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + hsw_disable_package_c8(dev_priv);
> + hsw_set_power_well(dev_priv, power_well, true);
> +}
> +
> +static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + hsw_set_power_well(dev_priv, power_well, false);
> + hsw_enable_package_c8(dev_priv);
> +}
> +
> void intel_display_power_get(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain)
> {
> @@ -5317,10 +5344,8 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
> mutex_lock(&power_domains->lock);
>
> for_each_power_well(i, power_well, BIT(domain), power_domains)
> - if (!power_well->count++ && power_well->set) {
> - hsw_disable_package_c8(dev_priv);
> - power_well->set(dev_priv, power_well, true);
> - }
> + if (!power_well->count++ && power_well->ops->enable)
> + power_well->ops->enable(dev_priv, power_well);
>
> power_domains->domain_use_count[domain]++;
>
> @@ -5344,11 +5369,9 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
> for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
> WARN_ON(!power_well->count);
>
> - if (!--power_well->count && power_well->set &&
> - i915.disable_power_well) {
> - power_well->set(dev_priv, power_well, false);
> - hsw_enable_package_c8(dev_priv);
> - }
> + if (!--power_well->count && power_well->ops->disable &&
> + i915.disable_power_well)
> + power_well->ops->disable(dev_priv, power_well);
> }
>
> mutex_unlock(&power_domains->lock);
> @@ -5401,25 +5424,35 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
> (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
> BIT(POWER_DOMAIN_INIT))
>
> +static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { };
> +
> static struct i915_power_well i9xx_always_on_power_well[] = {
> {
> .name = "always-on",
> .always_on = 1,
> .domains = POWER_DOMAIN_MASK,
> + .ops = &i9xx_always_on_power_well_ops,
> },
> };
>
> +static const struct i915_power_well_ops hsw_power_well_ops = {
> + .sync_hw = hsw_power_well_sync_hw,
> + .enable = hsw_power_well_enable,
> + .disable = hsw_power_well_disable,
> + .is_enabled = hsw_power_well_enabled,
> +};
> +
> static struct i915_power_well hsw_power_wells[] = {
> {
> .name = "always-on",
> .always_on = 1,
> .domains = HSW_ALWAYS_ON_POWER_DOMAINS,
> + .ops = &i9xx_always_on_power_well_ops,
> },
> {
> .name = "display",
> .domains = HSW_DISPLAY_POWER_DOMAINS,
> - .is_enabled = hsw_power_well_enabled,
> - .set = hsw_set_power_well,
> + .ops = &hsw_power_well_ops,
> },
> };
>
> @@ -5428,12 +5461,12 @@ static struct i915_power_well bdw_power_wells[] = {
> .name = "always-on",
> .always_on = 1,
> .domains = BDW_ALWAYS_ON_POWER_DOMAINS,
> + .ops = &i9xx_always_on_power_well_ops,
> },
> {
> .name = "display",
> .domains = BDW_DISPLAY_POWER_DOMAINS,
> - .is_enabled = hsw_power_well_enabled,
> - .set = hsw_set_power_well,
> + .ops = &hsw_power_well_ops,
> },
> };
>
> @@ -5478,8 +5511,8 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
>
> mutex_lock(&power_domains->lock);
> for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
> - if (power_well->set)
> - power_well->set(dev_priv, power_well, power_well->count > 0);
> + if (power_well->ops->sync_hw)
> + power_well->ops->sync_hw(dev_priv, power_well);
> }
> mutex_unlock(&power_domains->lock);
> }
> @@ -5495,14 +5528,6 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
> /* For now, we need the power well to be always enabled. */
> intel_display_set_init_power(dev_priv, true);
> intel_power_domains_resume(dev_priv);
> -
> - if (!(IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev)))
> - return;
> -
> - /* We're taking over the BIOS, so clear any requests made by it since
> - * the driver is in charge now. */
> - if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST)
> - I915_WRITE(HSW_PWR_WELL_BIOS, 0);
> }
>
> /* Disables PC8 so we can use the GMBUS and DP AUX interrupts. */
> --
> 1.8.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 07/21] drm/i915: add noop power well handlers instead of NULL checking them
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (5 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 06/21] drm/i915: split power well 'set' handler to separate enable/disable/sync_hw Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-06 19:02 ` Jesse Barnes
2014-03-04 17:22 ` [PATCH v2 08/21] drm/i915: add port power domains Imre Deak
` (13 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
Reading code free of special cases wins over the small overhead of
calling a noop handler. Suggested by Jesse.
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7866426..a94f5dd 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5332,6 +5332,17 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
hsw_enable_package_c8(dev_priv);
}
+static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+}
+
+static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ return true;
+}
+
void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
@@ -5344,7 +5355,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
mutex_lock(&power_domains->lock);
for_each_power_well(i, power_well, BIT(domain), power_domains)
- if (!power_well->count++ && power_well->ops->enable)
+ if (!power_well->count++)
power_well->ops->enable(dev_priv, power_well);
power_domains->domain_use_count[domain]++;
@@ -5369,8 +5380,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
WARN_ON(!power_well->count);
- if (!--power_well->count && power_well->ops->disable &&
- i915.disable_power_well)
+ if (!--power_well->count && i915.disable_power_well)
power_well->ops->disable(dev_priv, power_well);
}
@@ -5424,7 +5434,12 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
(POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
BIT(POWER_DOMAIN_INIT))
-static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { };
+static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
+ .sync_hw = i9xx_always_on_power_well_noop,
+ .enable = i9xx_always_on_power_well_noop,
+ .disable = i9xx_always_on_power_well_noop,
+ .is_enabled = i9xx_always_on_power_well_enabled,
+};
static struct i915_power_well i9xx_always_on_power_well[] = {
{
@@ -5510,10 +5525,8 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
int i;
mutex_lock(&power_domains->lock);
- for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
- if (power_well->ops->sync_hw)
- power_well->ops->sync_hw(dev_priv, power_well);
- }
+ for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains)
+ power_well->ops->sync_hw(dev_priv, power_well);
mutex_unlock(&power_domains->lock);
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 07/21] drm/i915: add noop power well handlers instead of NULL checking them
2014-03-04 17:22 ` [PATCH v2 07/21] drm/i915: add noop power well handlers instead of NULL checking them Imre Deak
@ 2014-03-06 19:02 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:02 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:22:56 +0200
Imre Deak <imre.deak@intel.com> wrote:
> Reading code free of special cases wins over the small overhead of
> calling a noop handler. Suggested by Jesse.
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_pm.c | 29 +++++++++++++++++++++--------
> 1 file changed, 21 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 7866426..a94f5dd 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5332,6 +5332,17 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
> hsw_enable_package_c8(dev_priv);
> }
>
> +static void i9xx_always_on_power_well_noop(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> +}
> +
> +static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + return true;
> +}
> +
> void intel_display_power_get(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain)
> {
> @@ -5344,7 +5355,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
> mutex_lock(&power_domains->lock);
>
> for_each_power_well(i, power_well, BIT(domain), power_domains)
> - if (!power_well->count++ && power_well->ops->enable)
> + if (!power_well->count++)
> power_well->ops->enable(dev_priv, power_well);
>
> power_domains->domain_use_count[domain]++;
> @@ -5369,8 +5380,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
> for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
> WARN_ON(!power_well->count);
>
> - if (!--power_well->count && power_well->ops->disable &&
> - i915.disable_power_well)
> + if (!--power_well->count && i915.disable_power_well)
> power_well->ops->disable(dev_priv, power_well);
> }
>
> @@ -5424,7 +5434,12 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
> (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
> BIT(POWER_DOMAIN_INIT))
>
> -static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { };
> +static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
> + .sync_hw = i9xx_always_on_power_well_noop,
> + .enable = i9xx_always_on_power_well_noop,
> + .disable = i9xx_always_on_power_well_noop,
> + .is_enabled = i9xx_always_on_power_well_enabled,
> +};
>
> static struct i915_power_well i9xx_always_on_power_well[] = {
> {
> @@ -5510,10 +5525,8 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
> int i;
>
> mutex_lock(&power_domains->lock);
> - for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
> - if (power_well->ops->sync_hw)
> - power_well->ops->sync_hw(dev_priv, power_well);
> - }
> + for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains)
> + power_well->ops->sync_hw(dev_priv, power_well);
> mutex_unlock(&power_domains->lock);
> }
>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 08/21] drm/i915: add port power domains
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (6 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 07/21] drm/i915: add noop power well handlers instead of NULL checking them Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-04 17:22 ` [PATCH v2 09/21] drm/i915: get port power domain in connector detect handlers Imre Deak
` (12 subsequent siblings)
20 siblings, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
Parts that poke port specific HW blocks like the encoder HW state
readout or connector hotplug detect code need a way to check whether
required power domains are on or enable/disable these. For this purpose
add a set of power domains that refer to the port HW blocks. Get the
proper port power domains during modeset.
For now when requesting the power domain for a DDI port get it for a 4
lane configuration. This can be optimized later to request only the 2
lane power domain, when proper support is added on the VLV PHY side for
this. Atm, the PHY setup code assumes a 4 lane config in all cases.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_debugfs.c | 22 ++++++++++++++++
drivers/gpu/drm/i915/i915_drv.h | 11 ++++++++
drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++++++----
drivers/gpu/drm/i915/intel_drv.h | 2 ++
drivers/gpu/drm/i915/intel_pm.c | 9 +++++++
5 files changed, 90 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index d90a707..14c7730 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2030,6 +2030,28 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
return "TRANSCODER_C";
case POWER_DOMAIN_TRANSCODER_EDP:
return "TRANSCODER_EDP";
+ case POWER_DOMAIN_PORT_DDI_A_2_LANES:
+ return "PORT_DDI_A_2_LANES";
+ case POWER_DOMAIN_PORT_DDI_A_4_LANES:
+ return "PORT_DDI_A_4_LANES";
+ case POWER_DOMAIN_PORT_DDI_B_2_LANES:
+ return "PORT_DDI_B_2_LANES";
+ case POWER_DOMAIN_PORT_DDI_B_4_LANES:
+ return "PORT_DDI_B_4_LANES";
+ case POWER_DOMAIN_PORT_DDI_C_2_LANES:
+ return "PORT_DDI_C_2_LANES";
+ case POWER_DOMAIN_PORT_DDI_C_4_LANES:
+ return "PORT_DDI_C_4_LANES";
+ case POWER_DOMAIN_PORT_DDI_D_2_LANES:
+ return "PORT_DDI_D_2_LANES";
+ case POWER_DOMAIN_PORT_DDI_D_4_LANES:
+ return "PORT_DDI_D_4_LANES";
+ case POWER_DOMAIN_PORT_DSI:
+ return "PORT_DSI";
+ case POWER_DOMAIN_PORT_CRT:
+ return "PORT_CRT";
+ case POWER_DOMAIN_PORT_OTHER:
+ return "PORT_OTHER";
case POWER_DOMAIN_VGA:
return "VGA";
case POWER_DOMAIN_AUDIO:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2b6d2a2..58065a2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -114,6 +114,17 @@ enum intel_display_power_domain {
POWER_DOMAIN_TRANSCODER_B,
POWER_DOMAIN_TRANSCODER_C,
POWER_DOMAIN_TRANSCODER_EDP,
+ POWER_DOMAIN_PORT_DDI_A_2_LANES,
+ POWER_DOMAIN_PORT_DDI_A_4_LANES,
+ POWER_DOMAIN_PORT_DDI_B_2_LANES,
+ POWER_DOMAIN_PORT_DDI_B_4_LANES,
+ POWER_DOMAIN_PORT_DDI_C_2_LANES,
+ POWER_DOMAIN_PORT_DDI_C_4_LANES,
+ POWER_DOMAIN_PORT_DDI_D_2_LANES,
+ POWER_DOMAIN_PORT_DDI_D_4_LANES,
+ POWER_DOMAIN_PORT_DSI,
+ POWER_DOMAIN_PORT_CRT,
+ POWER_DOMAIN_PORT_OTHER,
POWER_DOMAIN_VGA,
POWER_DOMAIN_AUDIO,
POWER_DOMAIN_INIT,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 70b7c42..ec51ce8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3957,9 +3957,49 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
if ((1 << (domain)) & (mask))
-static unsigned long get_pipe_power_domains(struct drm_device *dev,
- enum pipe pipe, bool pfit_enabled)
+enum intel_display_power_domain
+intel_display_port_power_domain(struct intel_encoder *intel_encoder)
{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct intel_digital_port *intel_dig_port;
+
+ switch (intel_encoder->type) {
+ case INTEL_OUTPUT_UNKNOWN:
+ /* Only DDI platforms should ever use this output type */
+ WARN_ON_ONCE(!HAS_DDI(dev));
+ case INTEL_OUTPUT_DISPLAYPORT:
+ case INTEL_OUTPUT_HDMI:
+ case INTEL_OUTPUT_EDP:
+ intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+ switch (intel_dig_port->port) {
+ case PORT_A:
+ return POWER_DOMAIN_PORT_DDI_A_4_LANES;
+ case PORT_B:
+ return POWER_DOMAIN_PORT_DDI_B_4_LANES;
+ case PORT_C:
+ return POWER_DOMAIN_PORT_DDI_C_4_LANES;
+ case PORT_D:
+ return POWER_DOMAIN_PORT_DDI_D_4_LANES;
+ default:
+ WARN_ON_ONCE(1);
+ return POWER_DOMAIN_PORT_OTHER;
+ }
+ case INTEL_OUTPUT_ANALOG:
+ return POWER_DOMAIN_PORT_CRT;
+ case INTEL_OUTPUT_DSI:
+ return POWER_DOMAIN_PORT_DSI;
+ default:
+ return POWER_DOMAIN_PORT_OTHER;
+ }
+}
+
+static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct intel_encoder *intel_encoder;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum pipe pipe = intel_crtc->pipe;
+ bool pfit_enabled = intel_crtc->config.pch_pfit.enabled;
unsigned long mask;
enum transcoder transcoder;
@@ -3970,6 +4010,9 @@ static unsigned long get_pipe_power_domains(struct drm_device *dev,
if (pfit_enabled)
mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
+ for_each_encoder_on_crtc(dev, crtc, intel_encoder)
+ mask |= BIT(intel_display_port_power_domain(intel_encoder));
+
return mask;
}
@@ -4003,9 +4046,7 @@ static void modeset_update_power_wells(struct drm_device *dev)
if (!crtc->base.enabled)
continue;
- pipe_domains[crtc->pipe] = get_pipe_power_domains(dev,
- crtc->pipe,
- crtc->config.pch_pfit.enabled);
+ pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
for_each_power_domain(domain, pipe_domains[crtc->pipe])
intel_display_power_get(dev_priv, domain);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6042797..e31eb1e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -733,6 +733,8 @@ bool intel_crtc_active(struct drm_crtc *crtc);
void hsw_enable_ips(struct intel_crtc *crtc);
void hsw_disable_ips(struct intel_crtc *crtc);
void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
+enum intel_display_power_domain
+intel_display_port_power_domain(struct intel_encoder *intel_encoder);
int valleyview_get_vco(struct drm_i915_private *dev_priv);
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
struct intel_crtc_config *pipe_config);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a94f5dd..78e8989 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5422,6 +5422,15 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
BIT(POWER_DOMAIN_PIPE_A) | \
BIT(POWER_DOMAIN_TRANSCODER_EDP) | \
+ BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_CRT) | \
BIT(POWER_DOMAIN_INIT))
#define HSW_DISPLAY_POWER_DOMAINS ( \
(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v2 09/21] drm/i915: get port power domain in connector detect handlers
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (7 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 08/21] drm/i915: add port power domains Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
2014-03-04 17:22 ` [PATCH v2 10/21] drm/i915: check port power domain when reading the encoder hw state Imre Deak
` (11 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
The connector detect and get_mode handlers need to access the port
specific HW blocks to read the EDID etc. Get/put the port power domains
around these handlers.
v2:
- get port power domain for HDMI too (Ville)
- get port power domain for the DP,HDMI audio detect handlers (Jesse)
- Leave the intel_runtime_pm_get/put in the DP detect function in place.
Instead of just removing them, these should be moved to the appropriate
power_well enable/disable handlers. We can do this after Paulo's
'Merge PC8 with runtime PM, v2' patchset.
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_crt.c | 42 +++++++++++++++++++++++++++++++--------
drivers/gpu/drm/i915/intel_dp.c | 25 +++++++++++++++++++++++
drivers/gpu/drm/i915/intel_dsi.c | 13 +++++++++++-
drivers/gpu/drm/i915/intel_hdmi.c | 29 ++++++++++++++++++++++++---
4 files changed, 97 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 9864aa1..2a38429 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -630,7 +630,10 @@ static enum drm_connector_status
intel_crt_detect(struct drm_connector *connector, bool force)
{
struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crt *crt = intel_attached_crt(connector);
+ struct intel_encoder *intel_encoder = &crt->base;
+ enum intel_display_power_domain power_domain;
enum drm_connector_status status;
struct intel_load_detect_pipe tmp;
@@ -638,6 +641,11 @@ intel_crt_detect(struct drm_connector *connector, bool force)
connector->base.id, drm_get_connector_name(connector),
force);
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
+ status = connector_status_connected;
+
if (I915_HAS_HOTPLUG(dev)) {
/* We can not rely on the HPD pin always being correctly wired
* up, for example many KVM do not pass it through, and so
@@ -645,23 +653,27 @@ intel_crt_detect(struct drm_connector *connector, bool force)
*/
if (intel_crt_detect_hotplug(connector)) {
DRM_DEBUG_KMS("CRT detected via hotplug\n");
- return connector_status_connected;
+ goto out;
} else
DRM_DEBUG_KMS("CRT not detected via hotplug\n");
}
if (intel_crt_detect_ddc(connector))
- return connector_status_connected;
+ goto out;
/* Load detection is broken on HPD capable machines. Whoever wants a
* broken monitor (without edid) to work behind a broken kvm (that fails
* to have the right resistors for HP detection) needs to fix this up.
* For now just bail out. */
- if (I915_HAS_HOTPLUG(dev))
- return connector_status_disconnected;
+ if (I915_HAS_HOTPLUG(dev)) {
+ status = connector_status_disconnected;
+ goto out;
+ }
- if (!force)
- return connector->status;
+ if (!force) {
+ status = connector->status;
+ goto out;
+ }
/* for pre-945g platforms use load detect */
if (intel_get_load_detect_pipe(connector, NULL, &tmp)) {
@@ -673,6 +685,9 @@ intel_crt_detect(struct drm_connector *connector, bool force)
} else
status = connector_status_unknown;
+out:
+ intel_display_power_put(dev_priv, power_domain);
+
return status;
}
@@ -686,17 +701,28 @@ static int intel_crt_get_modes(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crt *crt = intel_attached_crt(connector);
+ struct intel_encoder *intel_encoder = &crt->base;
+ enum intel_display_power_domain power_domain;
int ret;
struct i2c_adapter *i2c;
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
ret = intel_crt_ddc_get_modes(connector, i2c);
if (ret || !IS_G4X(dev))
- return ret;
+ goto out;
/* Try to probe digital port for output in DVI-I -> VGA mode. */
i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
- return intel_crt_ddc_get_modes(connector, i2c);
+ ret = intel_crt_ddc_get_modes(connector, i2c);
+
+out:
+ intel_display_power_put(dev_priv, power_domain);
+
+ return ret;
}
static int intel_crt_set_property(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f53c95c..3bc2fbc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3224,10 +3224,14 @@ intel_dp_detect(struct drm_connector *connector, bool force)
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum drm_connector_status status;
+ enum intel_display_power_domain power_domain;
struct edid *edid = NULL;
intel_runtime_pm_get(dev_priv);
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, drm_get_connector_name(connector));
@@ -3258,21 +3262,32 @@ intel_dp_detect(struct drm_connector *connector, bool force)
status = connector_status_connected;
out:
+ intel_display_power_put(dev_priv, power_domain);
+
intel_runtime_pm_put(dev_priv);
+
return status;
}
static int intel_dp_get_modes(struct drm_connector *connector)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum intel_display_power_domain power_domain;
int ret;
/* We should parse the EDID data and find out if it has an audio sink
*/
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
+ intel_display_power_put(dev_priv, power_domain);
if (ret)
return ret;
@@ -3293,15 +3308,25 @@ static bool
intel_dp_detect_audio(struct drm_connector *connector)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *intel_encoder = &intel_dig_port->base;
+ struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum intel_display_power_domain power_domain;
struct edid *edid;
bool has_audio = false;
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
edid = intel_dp_get_edid(connector, &intel_dp->adapter);
if (edid) {
has_audio = drm_detect_monitor_audio(edid);
kfree(edid);
}
+ intel_display_power_put(dev_priv, power_domain);
+
return has_audio;
}
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 3ee1db1..63b95bbd 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -488,8 +488,19 @@ static enum drm_connector_status
intel_dsi_detect(struct drm_connector *connector, bool force)
{
struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
+ struct intel_encoder *intel_encoder = &intel_dsi->base;
+ enum intel_display_power_domain power_domain;
+ enum drm_connector_status connector_status;
+ struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private;
+
DRM_DEBUG_KMS("\n");
- return intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
+ power_domain = intel_display_port_power_domain(intel_encoder);
+
+ intel_display_power_get(dev_priv, power_domain);
+ connector_status = intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
+ intel_display_power_put(dev_priv, power_domain);
+
+ return connector_status;
}
static int intel_dsi_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index aa4641d..d0e2026 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -909,11 +909,15 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct drm_i915_private *dev_priv = dev->dev_private;
struct edid *edid;
+ enum intel_display_power_domain power_domain;
enum drm_connector_status status = connector_status_disconnected;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, drm_get_connector_name(connector));
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
intel_hdmi->has_hdmi_sink = false;
intel_hdmi->has_audio = false;
intel_hdmi->rgb_quant_range_selectable = false;
@@ -941,31 +945,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
intel_encoder->type = INTEL_OUTPUT_HDMI;
}
+ intel_display_power_put(dev_priv, power_domain);
+
return status;
}
static int intel_hdmi_get_modes(struct drm_connector *connector)
{
- struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+ struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ enum intel_display_power_domain power_domain;
+ int ret;
/* We should parse the EDID data and find out if it's an HDMI sink so
* we can send audio to it.
*/
- return intel_ddc_get_modes(connector,
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
+ ret = intel_ddc_get_modes(connector,
intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus));
+
+ intel_display_power_put(dev_priv, power_domain);
+
+ return ret;
}
static bool
intel_hdmi_detect_audio(struct drm_connector *connector)
{
- struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+ struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ enum intel_display_power_domain power_domain;
struct edid *edid;
bool has_audio = false;
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
edid = drm_get_edid(connector,
intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus));
@@ -975,6 +996,8 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
kfree(edid);
}
+ intel_display_power_put(dev_priv, power_domain);
+
return has_audio;
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v3 09/21] drm/i915: get port power domain in connector detect handlers
2014-03-04 17:22 ` [PATCH v2 09/21] drm/i915: get port power domain in connector detect handlers Imre Deak
@ 2014-03-05 14:20 ` Imre Deak
2014-03-06 19:04 ` Jesse Barnes
0 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-05 14:20 UTC (permalink / raw)
To: intel-gfx
The connector detect and get_mode handlers need to access the port
specific HW blocks to read the EDID etc. Get/put the port power domains
around these handlers.
v2:
- get port power domain for HDMI too (Ville)
- get port power domain for the DP,HDMI audio detect handlers (Jesse)
- Leave the intel_runtime_pm_get/put in the DP detect function in place.
Instead of just removing them, these should be moved to the appropriate
power_well enable/disable handlers. We can do this after Paulo's
'Merge PC8 with runtime PM, v2' patchset.
v3:
- rebased on latest -nightly
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_crt.c | 22 ++++++++++++++++++++--
drivers/gpu/drm/i915/intel_dp.c | 25 +++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_dsi.c | 13 ++++++++++++-
drivers/gpu/drm/i915/intel_hdmi.c | 29 ++++++++++++++++++++++++++---
4 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 4c1230c..4a9d097 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -632,6 +632,8 @@ intel_crt_detect(struct drm_connector *connector, bool force)
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crt *crt = intel_attached_crt(connector);
+ struct intel_encoder *intel_encoder = &crt->base;
+ enum intel_display_power_domain power_domain;
enum drm_connector_status status;
struct intel_load_detect_pipe tmp;
@@ -641,6 +643,9 @@ intel_crt_detect(struct drm_connector *connector, bool force)
connector->base.id, drm_get_connector_name(connector),
force);
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
if (I915_HAS_HOTPLUG(dev)) {
/* We can not rely on the HPD pin always being correctly wired
* up, for example many KVM do not pass it through, and so
@@ -684,7 +689,9 @@ intel_crt_detect(struct drm_connector *connector, bool force)
status = connector_status_unknown;
out:
+ intel_display_power_put(dev_priv, power_domain);
intel_runtime_pm_put(dev_priv);
+
return status;
}
@@ -698,17 +705,28 @@ static int intel_crt_get_modes(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crt *crt = intel_attached_crt(connector);
+ struct intel_encoder *intel_encoder = &crt->base;
+ enum intel_display_power_domain power_domain;
int ret;
struct i2c_adapter *i2c;
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
ret = intel_crt_ddc_get_modes(connector, i2c);
if (ret || !IS_G4X(dev))
- return ret;
+ goto out;
/* Try to probe digital port for output in DVI-I -> VGA mode. */
i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
- return intel_crt_ddc_get_modes(connector, i2c);
+ ret = intel_crt_ddc_get_modes(connector, i2c);
+
+out:
+ intel_display_power_put(dev_priv, power_domain);
+
+ return ret;
}
static int intel_crt_set_property(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f53c95c..3bc2fbc 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3224,10 +3224,14 @@ intel_dp_detect(struct drm_connector *connector, bool force)
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum drm_connector_status status;
+ enum intel_display_power_domain power_domain;
struct edid *edid = NULL;
intel_runtime_pm_get(dev_priv);
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, drm_get_connector_name(connector));
@@ -3258,21 +3262,32 @@ intel_dp_detect(struct drm_connector *connector, bool force)
status = connector_status_connected;
out:
+ intel_display_power_put(dev_priv, power_domain);
+
intel_runtime_pm_put(dev_priv);
+
return status;
}
static int intel_dp_get_modes(struct drm_connector *connector)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct intel_connector *intel_connector = to_intel_connector(connector);
struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum intel_display_power_domain power_domain;
int ret;
/* We should parse the EDID data and find out if it has an audio sink
*/
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
+ intel_display_power_put(dev_priv, power_domain);
if (ret)
return ret;
@@ -3293,15 +3308,25 @@ static bool
intel_dp_detect_audio(struct drm_connector *connector)
{
struct intel_dp *intel_dp = intel_attached_dp(connector);
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *intel_encoder = &intel_dig_port->base;
+ struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum intel_display_power_domain power_domain;
struct edid *edid;
bool has_audio = false;
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
edid = intel_dp_get_edid(connector, &intel_dp->adapter);
if (edid) {
has_audio = drm_detect_monitor_audio(edid);
kfree(edid);
}
+ intel_display_power_put(dev_priv, power_domain);
+
return has_audio;
}
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 3ee1db1..63b95bbd 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -488,8 +488,19 @@ static enum drm_connector_status
intel_dsi_detect(struct drm_connector *connector, bool force)
{
struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
+ struct intel_encoder *intel_encoder = &intel_dsi->base;
+ enum intel_display_power_domain power_domain;
+ enum drm_connector_status connector_status;
+ struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private;
+
DRM_DEBUG_KMS("\n");
- return intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
+ power_domain = intel_display_port_power_domain(intel_encoder);
+
+ intel_display_power_get(dev_priv, power_domain);
+ connector_status = intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
+ intel_display_power_put(dev_priv, power_domain);
+
+ return connector_status;
}
static int intel_dsi_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index aa4641d..d0e2026 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -909,11 +909,15 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct drm_i915_private *dev_priv = dev->dev_private;
struct edid *edid;
+ enum intel_display_power_domain power_domain;
enum drm_connector_status status = connector_status_disconnected;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, drm_get_connector_name(connector));
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
intel_hdmi->has_hdmi_sink = false;
intel_hdmi->has_audio = false;
intel_hdmi->rgb_quant_range_selectable = false;
@@ -941,31 +945,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
intel_encoder->type = INTEL_OUTPUT_HDMI;
}
+ intel_display_power_put(dev_priv, power_domain);
+
return status;
}
static int intel_hdmi_get_modes(struct drm_connector *connector)
{
- struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+ struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ enum intel_display_power_domain power_domain;
+ int ret;
/* We should parse the EDID data and find out if it's an HDMI sink so
* we can send audio to it.
*/
- return intel_ddc_get_modes(connector,
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
+ ret = intel_ddc_get_modes(connector,
intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus));
+
+ intel_display_power_put(dev_priv, power_domain);
+
+ return ret;
}
static bool
intel_hdmi_detect_audio(struct drm_connector *connector)
{
- struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+ struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
+ struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ enum intel_display_power_domain power_domain;
struct edid *edid;
bool has_audio = false;
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
edid = drm_get_edid(connector,
intel_gmbus_get_adapter(dev_priv,
intel_hdmi->ddc_bus));
@@ -975,6 +996,8 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
kfree(edid);
}
+ intel_display_power_put(dev_priv, power_domain);
+
return has_audio;
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v3 09/21] drm/i915: get port power domain in connector detect handlers
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
@ 2014-03-06 19:04 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:04 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Wed, 5 Mar 2014 16:20:53 +0200
Imre Deak <imre.deak@intel.com> wrote:
> The connector detect and get_mode handlers need to access the port
> specific HW blocks to read the EDID etc. Get/put the port power domains
> around these handlers.
>
> v2:
> - get port power domain for HDMI too (Ville)
> - get port power domain for the DP,HDMI audio detect handlers (Jesse)
> - Leave the intel_runtime_pm_get/put in the DP detect function in place.
> Instead of just removing them, these should be moved to the appropriate
> power_well enable/disable handlers. We can do this after Paulo's
> 'Merge PC8 with runtime PM, v2' patchset.
> v3:
> - rebased on latest -nightly
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_crt.c | 22 ++++++++++++++++++++--
> drivers/gpu/drm/i915/intel_dp.c | 25 +++++++++++++++++++++++++
> drivers/gpu/drm/i915/intel_dsi.c | 13 ++++++++++++-
> drivers/gpu/drm/i915/intel_hdmi.c | 29 ++++++++++++++++++++++++++---
> 4 files changed, 83 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index 4c1230c..4a9d097 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -632,6 +632,8 @@ intel_crt_detect(struct drm_connector *connector, bool force)
> struct drm_device *dev = connector->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crt *crt = intel_attached_crt(connector);
> + struct intel_encoder *intel_encoder = &crt->base;
> + enum intel_display_power_domain power_domain;
> enum drm_connector_status status;
> struct intel_load_detect_pipe tmp;
>
> @@ -641,6 +643,9 @@ intel_crt_detect(struct drm_connector *connector, bool force)
> connector->base.id, drm_get_connector_name(connector),
> force);
>
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> if (I915_HAS_HOTPLUG(dev)) {
> /* We can not rely on the HPD pin always being correctly wired
> * up, for example many KVM do not pass it through, and so
> @@ -684,7 +689,9 @@ intel_crt_detect(struct drm_connector *connector, bool force)
> status = connector_status_unknown;
>
> out:
> + intel_display_power_put(dev_priv, power_domain);
> intel_runtime_pm_put(dev_priv);
> +
> return status;
> }
>
> @@ -698,17 +705,28 @@ static int intel_crt_get_modes(struct drm_connector *connector)
> {
> struct drm_device *dev = connector->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_crt *crt = intel_attached_crt(connector);
> + struct intel_encoder *intel_encoder = &crt->base;
> + enum intel_display_power_domain power_domain;
> int ret;
> struct i2c_adapter *i2c;
>
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
> ret = intel_crt_ddc_get_modes(connector, i2c);
> if (ret || !IS_G4X(dev))
> - return ret;
> + goto out;
>
> /* Try to probe digital port for output in DVI-I -> VGA mode. */
> i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB);
> - return intel_crt_ddc_get_modes(connector, i2c);
> + ret = intel_crt_ddc_get_modes(connector, i2c);
> +
> +out:
> + intel_display_power_put(dev_priv, power_domain);
> +
> + return ret;
> }
>
> static int intel_crt_set_property(struct drm_connector *connector,
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index f53c95c..3bc2fbc 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3224,10 +3224,14 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> struct drm_device *dev = connector->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> enum drm_connector_status status;
> + enum intel_display_power_domain power_domain;
> struct edid *edid = NULL;
>
> intel_runtime_pm_get(dev_priv);
>
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> connector->base.id, drm_get_connector_name(connector));
>
> @@ -3258,21 +3262,32 @@ intel_dp_detect(struct drm_connector *connector, bool force)
> status = connector_status_connected;
>
> out:
> + intel_display_power_put(dev_priv, power_domain);
> +
> intel_runtime_pm_put(dev_priv);
> +
> return status;
> }
>
> static int intel_dp_get_modes(struct drm_connector *connector)
> {
> struct intel_dp *intel_dp = intel_attached_dp(connector);
> + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> + struct intel_encoder *intel_encoder = &intel_dig_port->base;
> struct intel_connector *intel_connector = to_intel_connector(connector);
> struct drm_device *dev = connector->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + enum intel_display_power_domain power_domain;
> int ret;
>
> /* We should parse the EDID data and find out if it has an audio sink
> */
>
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter);
> + intel_display_power_put(dev_priv, power_domain);
> if (ret)
> return ret;
>
> @@ -3293,15 +3308,25 @@ static bool
> intel_dp_detect_audio(struct drm_connector *connector)
> {
> struct intel_dp *intel_dp = intel_attached_dp(connector);
> + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> + struct intel_encoder *intel_encoder = &intel_dig_port->base;
> + struct drm_device *dev = connector->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + enum intel_display_power_domain power_domain;
> struct edid *edid;
> bool has_audio = false;
>
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> edid = intel_dp_get_edid(connector, &intel_dp->adapter);
> if (edid) {
> has_audio = drm_detect_monitor_audio(edid);
> kfree(edid);
> }
>
> + intel_display_power_put(dev_priv, power_domain);
> +
> return has_audio;
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index 3ee1db1..63b95bbd 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -488,8 +488,19 @@ static enum drm_connector_status
> intel_dsi_detect(struct drm_connector *connector, bool force)
> {
> struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
> + struct intel_encoder *intel_encoder = &intel_dsi->base;
> + enum intel_display_power_domain power_domain;
> + enum drm_connector_status connector_status;
> + struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private;
> +
> DRM_DEBUG_KMS("\n");
> - return intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
> + power_domain = intel_display_port_power_domain(intel_encoder);
> +
> + intel_display_power_get(dev_priv, power_domain);
> + connector_status = intel_dsi->dev.dev_ops->detect(&intel_dsi->dev);
> + intel_display_power_put(dev_priv, power_domain);
> +
> + return connector_status;
> }
>
> static int intel_dsi_get_modes(struct drm_connector *connector)
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index aa4641d..d0e2026 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -909,11 +909,15 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> struct intel_encoder *intel_encoder = &intel_dig_port->base;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct edid *edid;
> + enum intel_display_power_domain power_domain;
> enum drm_connector_status status = connector_status_disconnected;
>
> DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> connector->base.id, drm_get_connector_name(connector));
>
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> intel_hdmi->has_hdmi_sink = false;
> intel_hdmi->has_audio = false;
> intel_hdmi->rgb_quant_range_selectable = false;
> @@ -941,31 +945,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> intel_encoder->type = INTEL_OUTPUT_HDMI;
> }
>
> + intel_display_power_put(dev_priv, power_domain);
> +
> return status;
> }
>
> static int intel_hdmi_get_modes(struct drm_connector *connector)
> {
> - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> + struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
> + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
> struct drm_i915_private *dev_priv = connector->dev->dev_private;
> + enum intel_display_power_domain power_domain;
> + int ret;
>
> /* We should parse the EDID data and find out if it's an HDMI sink so
> * we can send audio to it.
> */
>
> - return intel_ddc_get_modes(connector,
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> + ret = intel_ddc_get_modes(connector,
> intel_gmbus_get_adapter(dev_priv,
> intel_hdmi->ddc_bus));
> +
> + intel_display_power_put(dev_priv, power_domain);
> +
> + return ret;
> }
>
> static bool
> intel_hdmi_detect_audio(struct drm_connector *connector)
> {
> - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> + struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
> + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base);
> struct drm_i915_private *dev_priv = connector->dev->dev_private;
> + enum intel_display_power_domain power_domain;
> struct edid *edid;
> bool has_audio = false;
>
> + power_domain = intel_display_port_power_domain(intel_encoder);
> + intel_display_power_get(dev_priv, power_domain);
> +
> edid = drm_get_edid(connector,
> intel_gmbus_get_adapter(dev_priv,
> intel_hdmi->ddc_bus));
> @@ -975,6 +996,8 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
> kfree(edid);
> }
>
> + intel_display_power_put(dev_priv, power_domain);
> +
> return has_audio;
> }
>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 10/21] drm/i915: check port power domain when reading the encoder hw state
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (8 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 09/21] drm/i915: get port power domain in connector detect handlers Imre Deak
@ 2014-03-04 17:22 ` Imre Deak
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
2014-03-04 17:23 ` [PATCH v2 11/21] drm/i915: check pipe power domain when reading its " Imre Deak
` (10 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:22 UTC (permalink / raw)
To: intel-gfx
Since the encoder is tied to its port, we need to make sure the power
domain for that port is on before reading out the encoder HW state.
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_ddi.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 23 ++++++++++++++++++-----
drivers/gpu/drm/i915/intel_drv.h | 1 +
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 2643d3b..f95bc3a 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1110,7 +1110,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
enum transcoder cpu_transcoder;
uint32_t tmp;
- if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
+ if (!intel_encoder_get_hw_state(intel_encoder, &pipe))
return false;
if (port == PORT_A)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ec51ce8..0975cb4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4519,7 +4519,7 @@ static void intel_connector_check_state(struct intel_connector *connector)
WARN(!encoder->connectors_active,
"encoder->connectors_active not set\n");
- encoder_enabled = encoder->get_hw_state(encoder, &pipe);
+ encoder_enabled = intel_encoder_get_hw_state(encoder, &pipe);
WARN(!encoder_enabled, "encoder not enabled\n");
if (WARN_ON(!encoder->base.crtc))
return;
@@ -4561,7 +4561,7 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
enum pipe pipe = 0;
struct intel_encoder *encoder = connector->encoder;
- return encoder->get_hw_state(encoder, &pipe);
+ return intel_encoder_get_hw_state(encoder, &pipe);
}
static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
@@ -9464,6 +9464,19 @@ check_connector_state(struct drm_device *dev)
}
}
+bool intel_encoder_get_hw_state(struct intel_encoder *intel_encoder,
+ enum pipe *pipe)
+{
+ enum intel_display_power_domain power_domain;
+ struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private;
+
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ if (!intel_display_power_enabled(dev_priv, power_domain))
+ return false;
+
+ return intel_encoder->get_hw_state(intel_encoder, pipe);
+}
+
static void
check_encoder_state(struct drm_device *dev)
{
@@ -9504,7 +9517,7 @@ check_encoder_state(struct drm_device *dev)
"encoder's computed active state doesn't match tracked active state "
"(expected %i, found %i)\n", active, encoder->connectors_active);
- active = encoder->get_hw_state(encoder, &pipe);
+ active = intel_encoder_get_hw_state(encoder, &pipe);
WARN(active != encoder->connectors_active,
"encoder's hw state doesn't match sw tracking "
"(expected %i, found %i)\n",
@@ -9571,7 +9584,7 @@ check_crtc_state(struct drm_device *dev)
enum pipe pipe;
if (encoder->base.crtc != &crtc->base)
continue;
- if (encoder->get_hw_state(encoder, &pipe))
+ if (intel_encoder_get_hw_state(encoder, &pipe))
encoder->get_config(encoder, &pipe_config);
}
@@ -11350,7 +11363,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
base.head) {
pipe = 0;
- if (encoder->get_hw_state(encoder, &pipe)) {
+ if (intel_encoder_get_hw_state(encoder, &pipe)) {
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
encoder->base.crtc = &crtc->base;
encoder->get_config(encoder, &crtc->config);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e31eb1e..afc01a4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -738,6 +738,7 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder);
int valleyview_get_vco(struct drm_i915_private *dev_priv);
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
struct intel_crtc_config *pipe_config);
+bool intel_encoder_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
/* intel_dp.c */
void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v3 10/21] drm/i915: check port power domain when reading the encoder hw state
2014-03-04 17:22 ` [PATCH v2 10/21] drm/i915: check port power domain when reading the encoder hw state Imre Deak
@ 2014-03-05 14:20 ` Imre Deak
2014-03-06 19:06 ` Jesse Barnes
0 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-05 14:20 UTC (permalink / raw)
To: intel-gfx
Since the encoder is tied to its port, we need to make sure the power
domain for that port is on before reading out the encoder HW state.
Note that this also covers also all connector get_hw_state handlers,
since all those just call the corresponding encoder get_hw_state
handler, which checks - after this change - for all power domains
the connector needs.
v2:
- no change
v3:
- push down the power domain checks into the specific encoder
get_hw_state handlers (Daniel)
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_crt.c | 5 +++++
drivers/gpu/drm/i915/intel_ddi.c | 5 +++++
drivers/gpu/drm/i915/intel_dp.c | 9 ++++++++-
drivers/gpu/drm/i915/intel_dsi.c | 5 +++++
drivers/gpu/drm/i915/intel_hdmi.c | 5 +++++
5 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 4a9d097..6ecea69 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -68,8 +68,13 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crt *crt = intel_encoder_to_crt(encoder);
+ enum intel_display_power_domain power_domain;
u32 tmp;
+ power_domain = intel_display_port_power_domain(encoder);
+ if (!intel_display_power_enabled(dev_priv, power_domain))
+ return false;
+
tmp = I915_READ(crt->adpa_reg);
if (!(tmp & ADPA_DAC_ENABLE))
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 2643d3b..e2665e0 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1145,9 +1145,14 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
enum port port = intel_ddi_get_encoder_port(encoder);
+ enum intel_display_power_domain power_domain;
u32 tmp;
int i;
+ power_domain = intel_display_port_power_domain(encoder);
+ if (!intel_display_power_enabled(dev_priv, power_domain))
+ return false;
+
tmp = I915_READ(DDI_BUF_CTL(port));
if (!(tmp & DDI_BUF_CTL_ENABLE))
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3bc2fbc..2c5fae4 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1485,7 +1485,14 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
enum port port = dp_to_dig_port(intel_dp)->port;
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 tmp = I915_READ(intel_dp->output_reg);
+ enum intel_display_power_domain power_domain;
+ u32 tmp;
+
+ power_domain = intel_display_port_power_domain(encoder);
+ if (!intel_display_power_enabled(dev_priv, power_domain))
+ return false;
+
+ tmp = I915_READ(intel_dp->output_reg);
if (!(tmp & DP_PORT_EN))
return false;
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 63b95bbd..cf7322e 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -243,11 +243,16 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
enum pipe *pipe)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ enum intel_display_power_domain power_domain;
u32 port, func;
enum pipe p;
DRM_DEBUG_KMS("\n");
+ power_domain = intel_display_port_power_domain(encoder);
+ if (!intel_display_power_enabled(dev_priv, power_domain))
+ return false;
+
/* XXX: this only works for one DSI output */
for (p = PIPE_A; p <= PIPE_B; p++) {
port = I915_READ(MIPI_PORT_CTRL(p));
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index d0e2026..ceb4797 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -667,8 +667,13 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+ enum intel_display_power_domain power_domain;
u32 tmp;
+ power_domain = intel_display_port_power_domain(encoder);
+ if (!intel_display_power_enabled(dev_priv, power_domain))
+ return false;
+
tmp = I915_READ(intel_hdmi->hdmi_reg);
if (!(tmp & SDVO_ENABLE))
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v3 10/21] drm/i915: check port power domain when reading the encoder hw state
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
@ 2014-03-06 19:06 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:06 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Wed, 5 Mar 2014 16:20:54 +0200
Imre Deak <imre.deak@intel.com> wrote:
> Since the encoder is tied to its port, we need to make sure the power
> domain for that port is on before reading out the encoder HW state.
>
> Note that this also covers also all connector get_hw_state handlers,
> since all those just call the corresponding encoder get_hw_state
> handler, which checks - after this change - for all power domains
> the connector needs.
>
> v2:
> - no change
> v3:
> - push down the power domain checks into the specific encoder
> get_hw_state handlers (Daniel)
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_crt.c | 5 +++++
> drivers/gpu/drm/i915/intel_ddi.c | 5 +++++
> drivers/gpu/drm/i915/intel_dp.c | 9 ++++++++-
> drivers/gpu/drm/i915/intel_dsi.c | 5 +++++
> drivers/gpu/drm/i915/intel_hdmi.c | 5 +++++
> 5 files changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index 4a9d097..6ecea69 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -68,8 +68,13 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
> struct drm_device *dev = encoder->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crt *crt = intel_encoder_to_crt(encoder);
> + enum intel_display_power_domain power_domain;
> u32 tmp;
>
> + power_domain = intel_display_port_power_domain(encoder);
> + if (!intel_display_power_enabled(dev_priv, power_domain))
> + return false;
> +
> tmp = I915_READ(crt->adpa_reg);
>
> if (!(tmp & ADPA_DAC_ENABLE))
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 2643d3b..e2665e0 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1145,9 +1145,14 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
> struct drm_device *dev = encoder->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> enum port port = intel_ddi_get_encoder_port(encoder);
> + enum intel_display_power_domain power_domain;
> u32 tmp;
> int i;
>
> + power_domain = intel_display_port_power_domain(encoder);
> + if (!intel_display_power_enabled(dev_priv, power_domain))
> + return false;
> +
> tmp = I915_READ(DDI_BUF_CTL(port));
>
> if (!(tmp & DDI_BUF_CTL_ENABLE))
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 3bc2fbc..2c5fae4 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1485,7 +1485,14 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
> enum port port = dp_to_dig_port(intel_dp)->port;
> struct drm_device *dev = encoder->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> - u32 tmp = I915_READ(intel_dp->output_reg);
> + enum intel_display_power_domain power_domain;
> + u32 tmp;
> +
> + power_domain = intel_display_port_power_domain(encoder);
> + if (!intel_display_power_enabled(dev_priv, power_domain))
> + return false;
> +
> + tmp = I915_READ(intel_dp->output_reg);
>
> if (!(tmp & DP_PORT_EN))
> return false;
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index 63b95bbd..cf7322e 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -243,11 +243,16 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
> enum pipe *pipe)
> {
> struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> + enum intel_display_power_domain power_domain;
> u32 port, func;
> enum pipe p;
>
> DRM_DEBUG_KMS("\n");
>
> + power_domain = intel_display_port_power_domain(encoder);
> + if (!intel_display_power_enabled(dev_priv, power_domain))
> + return false;
> +
> /* XXX: this only works for one DSI output */
> for (p = PIPE_A; p <= PIPE_B; p++) {
> port = I915_READ(MIPI_PORT_CTRL(p));
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index d0e2026..ceb4797 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -667,8 +667,13 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
> struct drm_device *dev = encoder->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> + enum intel_display_power_domain power_domain;
> u32 tmp;
>
> + power_domain = intel_display_port_power_domain(encoder);
> + if (!intel_display_power_enabled(dev_priv, power_domain))
> + return false;
> +
> tmp = I915_READ(intel_hdmi->hdmi_reg);
>
> if (!(tmp & SDVO_ENABLE))
Given the way the functions work, returning the power domain required
and making things fairly opaque, I'm not sure Daniel's suggestion buys
us anything. So to me the wrapper seemed nicer... but either way works
I guess.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 11/21] drm/i915: check pipe power domain when reading its hw state
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (9 preceding siblings ...)
2014-03-04 17:22 ` [PATCH v2 10/21] drm/i915: check port power domain when reading the encoder hw state Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
2014-03-04 17:23 ` [PATCH v2 12/21] drm/i915: vlv: keep first level vblank IRQs masked Imre Deak
` (9 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
We can read out the pipe HW state only if the required power domain is
on. If not we consider the pipe to be off.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_display.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0975cb4..b296c1a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9535,6 +9535,18 @@ check_encoder_state(struct drm_device *dev)
}
}
+static bool intel_display_get_pipe_config(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config)
+{
+ struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
+ if (!intel_display_power_enabled(dev_priv,
+ POWER_DOMAIN_PIPE(crtc->pipe)))
+ return false;
+
+ return dev_priv->display.get_pipe_config(crtc, pipe_config);
+}
+
static void
check_crtc_state(struct drm_device *dev)
{
@@ -9572,8 +9584,7 @@ check_crtc_state(struct drm_device *dev)
"crtc's computed enabled state doesn't match tracked enabled state "
"(expected %i, found %i)\n", enabled, crtc->base.enabled);
- active = dev_priv->display.get_pipe_config(crtc,
- &pipe_config);
+ active = intel_display_get_pipe_config(crtc, &pipe_config);
/* hw state is inconsistent with the pipe A quirk */
if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
@@ -11328,8 +11339,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
base.head) {
memset(&crtc->config, 0, sizeof(crtc->config));
- crtc->active = dev_priv->display.get_pipe_config(crtc,
- &crtc->config);
+ crtc->active = intel_display_get_pipe_config(crtc,
+ &crtc->config);
crtc->base.enabled = crtc->active;
crtc->primary_enabled = crtc->active;
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v3 11/21] drm/i915: check pipe power domain when reading its hw state
2014-03-04 17:23 ` [PATCH v2 11/21] drm/i915: check pipe power domain when reading its " Imre Deak
@ 2014-03-05 14:20 ` Imre Deak
2014-03-06 19:06 ` Jesse Barnes
0 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-05 14:20 UTC (permalink / raw)
To: intel-gfx
We can read out the pipe HW state only if the required power domain is
on. If not we consider the pipe to be off.
v2:
- no change
v3:
- push down the power domain checks into the specific crtc
get_pipe_config handlers (Daniel)
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 32407ea..cde6d02 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5611,6 +5611,10 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t tmp;
+ if (!intel_display_power_enabled(dev_priv,
+ POWER_DOMAIN_PIPE(crtc->pipe)))
+ return false;
+
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
@@ -6981,6 +6985,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
enum intel_display_power_domain pfit_domain;
uint32_t tmp;
+ if (!intel_display_power_enabled(dev_priv,
+ POWER_DOMAIN_PIPE(crtc->pipe)))
+ return false;
+
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v3 11/21] drm/i915: check pipe power domain when reading its hw state
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
@ 2014-03-06 19:06 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:06 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Wed, 5 Mar 2014 16:20:55 +0200
Imre Deak <imre.deak@intel.com> wrote:
> We can read out the pipe HW state only if the required power domain is
> on. If not we consider the pipe to be off.
>
> v2:
> - no change
> v3:
> - push down the power domain checks into the specific crtc
> get_pipe_config handlers (Daniel)
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 32407ea..cde6d02 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5611,6 +5611,10 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
> struct drm_i915_private *dev_priv = dev->dev_private;
> uint32_t tmp;
>
> + if (!intel_display_power_enabled(dev_priv,
> + POWER_DOMAIN_PIPE(crtc->pipe)))
> + return false;
> +
> pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
> pipe_config->shared_dpll = DPLL_ID_PRIVATE;
>
> @@ -6981,6 +6985,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> enum intel_display_power_domain pfit_domain;
> uint32_t tmp;
>
> + if (!intel_display_power_enabled(dev_priv,
> + POWER_DOMAIN_PIPE(crtc->pipe)))
> + return false;
> +
> pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
> pipe_config->shared_dpll = DPLL_ID_PRIVATE;
>
Same goes here, though I suppose there's more room for additional,
specific domains down at this level...
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 12/21] drm/i915: vlv: keep first level vblank IRQs masked
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (10 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 11/21] drm/i915: check pipe power domain when reading its " Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-06 19:09 ` Jesse Barnes
2014-03-04 17:23 ` [PATCH v2 13/21] drm/i915: sanitize PUNIT register macro definitions Imre Deak
` (8 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
This is a left-over from
commit b7e634cc8dcd320123199a18bae0937b40dc28b8
Author: Imre Deak <imre.deak@intel.com>
Date: Tue Feb 4 21:35:45 2014 +0200
drm/i915: vlv: don't unmask IIR[DISPLAY_PIPE_A/B_VBLANK] interrupt
where we stopped unmasking the vblank IRQs, but left them enabled in the
IER register. Disable them in IER too.
v2:
- remove comment becoming stale after this change (Ville)
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 331f89c..471d8f9 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3026,17 +3026,9 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
enable_mask = I915_DISPLAY_PORT_INTERRUPT;
enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
- I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
- /*
- *Leave vblank interrupts masked initially. enable/disable will
- * toggle them based on usage.
- */
- dev_priv->irq_mask = (~enable_mask) |
- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
+ dev_priv->irq_mask = ~enable_mask;
I915_WRITE(PORT_HOTPLUG_EN, 0);
POSTING_READ(PORT_HOTPLUG_EN);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 12/21] drm/i915: vlv: keep first level vblank IRQs masked
2014-03-04 17:23 ` [PATCH v2 12/21] drm/i915: vlv: keep first level vblank IRQs masked Imre Deak
@ 2014-03-06 19:09 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:09 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:23:01 +0200
Imre Deak <imre.deak@intel.com> wrote:
> This is a left-over from
>
> commit b7e634cc8dcd320123199a18bae0937b40dc28b8
> Author: Imre Deak <imre.deak@intel.com>
> Date: Tue Feb 4 21:35:45 2014 +0200
>
> drm/i915: vlv: don't unmask IIR[DISPLAY_PIPE_A/B_VBLANK] interrupt
>
> where we stopped unmasking the vblank IRQs, but left them enabled in the
> IER register. Disable them in IER too.
>
> v2:
> - remove comment becoming stale after this change (Ville)
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_irq.c | 12 ++----------
> 1 file changed, 2 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 331f89c..471d8f9 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -3026,17 +3026,9 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
>
> enable_mask = I915_DISPLAY_PORT_INTERRUPT;
> enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
> - I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
> - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
> - I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
> + I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
>
> - /*
> - *Leave vblank interrupts masked initially. enable/disable will
> - * toggle them based on usage.
> - */
> - dev_priv->irq_mask = (~enable_mask) |
> - I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
> - I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
> + dev_priv->irq_mask = ~enable_mask;
>
> I915_WRITE(PORT_HOTPLUG_EN, 0);
> POSTING_READ(PORT_HOTPLUG_EN);
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 13/21] drm/i915: sanitize PUNIT register macro definitions
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (11 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 12/21] drm/i915: vlv: keep first level vblank IRQs masked Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-04 17:23 ` [PATCH v2 14/21] drm/i915: factor out reset_vblank_counter Imre Deak
` (7 subsequent siblings)
20 siblings, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
In the upcoming patches we'll need to access the rest of the fields in
the punit power gating register, so prepare for that.
v2:
- add doc reference for the power well subsystem IDs (Jesse)
- remove IDs for non-existant DPIO_RX[23] subsystems (Jesse)
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_reg.h | 28 ++++++++++++++++++++++------
drivers/gpu/drm/i915/intel_uncore.c | 4 +++-
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f564ce..2aa3c3d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -377,14 +377,30 @@
#define DSPFREQSTAT_MASK (0x3 << DSPFREQSTAT_SHIFT)
#define DSPFREQGUAR_SHIFT 14
#define DSPFREQGUAR_MASK (0x3 << DSPFREQGUAR_SHIFT)
+
+/* See the PUNIT HAS v0.8 for the below bits */
+enum punit_power_well {
+ PUNIT_POWER_WELL_RENDER = 0,
+ PUNIT_POWER_WELL_MEDIA = 1,
+ PUNIT_POWER_WELL_DISP2D = 3,
+ PUNIT_POWER_WELL_DPIO_CMN_BC = 5,
+ PUNIT_POWER_WELL_DPIO_TX_B_LANES_01 = 6,
+ PUNIT_POWER_WELL_DPIO_TX_B_LANES_23 = 7,
+ PUNIT_POWER_WELL_DPIO_TX_C_LANES_01 = 8,
+ PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9,
+ PUNIT_POWER_WELL_DPIO_RX0 = 10,
+ PUNIT_POWER_WELL_DPIO_RX1 = 11,
+
+ PUNIT_POWER_WELL_NUM,
+};
+
#define PUNIT_REG_PWRGT_CTRL 0x60
#define PUNIT_REG_PWRGT_STATUS 0x61
-#define PUNIT_CLK_GATE 1
-#define PUNIT_PWR_RESET 2
-#define PUNIT_PWR_GATE 3
-#define RENDER_PWRGT (PUNIT_PWR_GATE << 0)
-#define MEDIA_PWRGT (PUNIT_PWR_GATE << 2)
-#define DISP2D_PWRGT (PUNIT_PWR_GATE << 6)
+#define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2))
+#define PUNIT_PWRGT_PWR_ON(power_well) (0 << ((power_well) * 2))
+#define PUNIT_PWRGT_CLK_GATE(power_well) (1 << ((power_well) * 2))
+#define PUNIT_PWRGT_RESET(power_well) (2 << ((power_well) * 2))
+#define PUNIT_PWRGT_PWR_GATE(power_well) (3 << ((power_well) * 2))
#define PUNIT_REG_GPU_LFM 0xd3
#define PUNIT_REG_GPU_FREQ_REQ 0xd4
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index c628414..4aab7c2 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -354,7 +354,9 @@ void intel_uncore_sanitize(struct drm_device *dev)
mutex_lock(&dev_priv->rps.hw_lock);
reg_val = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS);
- if (reg_val & (RENDER_PWRGT | MEDIA_PWRGT | DISP2D_PWRGT))
+ if (reg_val & (PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_RENDER) |
+ PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_MEDIA) |
+ PUNIT_PWRGT_PWR_GATE(PUNIT_POWER_WELL_DISP2D)))
vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, 0x0);
mutex_unlock(&dev_priv->rps.hw_lock);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v2 14/21] drm/i915: factor out reset_vblank_counter
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (12 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 13/21] drm/i915: sanitize PUNIT register macro definitions Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-06 19:10 ` Jesse Barnes
2014-03-04 17:23 ` [PATCH v2 15/21] drm/i915: switch order of power domain init wrt. irq install Imre Deak
` (6 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
We need to do the same for other platforms in upcoming patches.
v2:
- s/p/pipe (Ville)
- Call the new helper with the vbl_lock already held. The part it
protects is short, so releasing it between pipes only makes proving
correctness more difficult.
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 78e8989..28fae53 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5249,11 +5249,18 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
}
}
+static void reset_vblank_counter(struct drm_device *dev, enum pipe pipe)
+{
+ assert_spin_locked(&dev->vbl_lock);
+
+ dev->vblank[pipe].last = 0;
+}
+
static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
- enum pipe p;
unsigned long irqflags;
+ enum pipe pipe;
/*
* After this, the registers on the pipes that are part of the power
@@ -5263,9 +5270,9 @@ static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
* FIXME: Should we do this in general in drm_vblank_post_modeset?
*/
spin_lock_irqsave(&dev->vbl_lock, irqflags);
- for_each_pipe(p)
- if (p != PIPE_A)
- dev->vblank[p].last = 0;
+ for_each_pipe(pipe)
+ if (pipe != PIPE_A)
+ reset_vblank_counter(dev, pipe);
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 14/21] drm/i915: factor out reset_vblank_counter
2014-03-04 17:23 ` [PATCH v2 14/21] drm/i915: factor out reset_vblank_counter Imre Deak
@ 2014-03-06 19:10 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:10 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:23:03 +0200
Imre Deak <imre.deak@intel.com> wrote:
> We need to do the same for other platforms in upcoming patches.
>
> v2:
> - s/p/pipe (Ville)
> - Call the new helper with the vbl_lock already held. The part it
> protects is short, so releasing it between pipes only makes proving
> correctness more difficult.
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_pm.c | 15 +++++++++++----
> 1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 78e8989..28fae53 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5249,11 +5249,18 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
> }
> }
>
> +static void reset_vblank_counter(struct drm_device *dev, enum pipe pipe)
> +{
> + assert_spin_locked(&dev->vbl_lock);
> +
> + dev->vblank[pipe].last = 0;
> +}
> +
> static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
> {
> struct drm_device *dev = dev_priv->dev;
> - enum pipe p;
> unsigned long irqflags;
> + enum pipe pipe;
>
> /*
> * After this, the registers on the pipes that are part of the power
> @@ -5263,9 +5270,9 @@ static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
> * FIXME: Should we do this in general in drm_vblank_post_modeset?
> */
> spin_lock_irqsave(&dev->vbl_lock, irqflags);
> - for_each_pipe(p)
> - if (p != PIPE_A)
> - dev->vblank[p].last = 0;
> + for_each_pipe(pipe)
> + if (pipe != PIPE_A)
> + reset_vblank_counter(dev, pipe);
> spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> }
>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 15/21] drm/i915: switch order of power domain init wrt. irq install
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (13 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 14/21] drm/i915: factor out reset_vblank_counter Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-04 17:23 ` [PATCH v2 16/21] drm/i915: use power domain api to check vga power state Imre Deak
` (5 subsequent siblings)
20 siblings, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
On VLV at least the display IRQ register access and functionality
depends on its power well to be on, so move the power domain HW init
before we install the IRQs.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_dma.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 8177c17..f8f7a59 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1321,12 +1321,12 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto cleanup_vga_switcheroo;
+ intel_power_domains_init_hw(dev_priv);
+
ret = drm_irq_install(dev);
if (ret)
goto cleanup_gem_stolen;
- intel_power_domains_init_hw(dev_priv);
-
/* Important: The output setup functions called by modeset_init need
* working irqs for e.g. gmbus and dp aux transfers. */
intel_modeset_init(dev);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v2 16/21] drm/i915: use power domain api to check vga power state
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (14 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 15/21] drm/i915: switch order of power domain init wrt. irq install Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-04 17:23 ` [PATCH v2 17/21] drm/i915: sanity check power well sw state against hw state Imre Deak
` (4 subsequent siblings)
20 siblings, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
This way we can reuse the check on other platforms too. Also factor out
a version of the function that doesn't check if the power is on, we'll
need to call this from within the power domain framework.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 20 +++++++++++++-------
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 58065a2..711a061 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2593,6 +2593,7 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
extern void intel_modeset_setup_hw_state(struct drm_device *dev,
bool force_restore);
extern void i915_redisable_vga(struct drm_device *dev);
+extern void i915_redisable_vga_power_on(struct drm_device *dev);
extern bool intel_fbc_enabled(struct drm_device *dev);
extern void intel_disable_fbc(struct drm_device *dev);
extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b296c1a..6fb40cb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11304,10 +11304,20 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
* the crtc fixup. */
}
+void i915_redisable_vga_power_on(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 vga_reg = i915_vgacntrl_reg(dev);
+
+ if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) {
+ DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
+ i915_disable_vga(dev);
+ }
+}
+
void i915_redisable_vga(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 vga_reg = i915_vgacntrl_reg(dev);
/* This function can be called both from intel_modeset_setup_hw_state or
* at a very early point in our resume sequence, where the power well
@@ -11316,14 +11326,10 @@ void i915_redisable_vga(struct drm_device *dev)
* level, just check if the power well is enabled instead of trying to
* follow the "don't touch the power well if we don't need it" policy
* the rest of the driver uses. */
- if ((IS_HASWELL(dev) || IS_BROADWELL(dev)) &&
- (I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE_ENABLED) == 0)
+ if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_VGA))
return;
- if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) {
- DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
- i915_disable_vga(dev);
- }
+ i915_redisable_vga_power_on(dev);
}
static void intel_modeset_readout_hw_state(struct drm_device *dev)
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v2 17/21] drm/i915: sanity check power well sw state against hw state
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (15 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 16/21] drm/i915: use power domain api to check vga power state Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-06 19:11 ` Jesse Barnes
2014-03-04 17:23 ` [PATCH v2 18/21] drm/i915: vlv: factor out valleyview_display_irq_install Imre Deak
` (3 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
Suggested by Daniel.
v2:
- sanitize the state checking condition, the original was rather
confusing (partly due to the unfortunate naming of
i915.disable_power_well) (Ville)
- simpler message+backtrace generation by using WARN instead of WARN_ON
(Ville)
- check if always-on power wells are truly on all the time
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 38 +++++++++++++++++++++++++++++++++++---
1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 28fae53..c034842 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5350,6 +5350,29 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
return true;
}
+static void check_power_well_state(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ bool enabled = power_well->ops->is_enabled(dev_priv, power_well);
+
+ if (power_well->always_on || !i915.disable_power_well) {
+ if (!enabled)
+ goto mismatch;
+
+ return;
+ }
+
+ if (enabled != (power_well->count > 0))
+ goto mismatch;
+
+ return;
+
+mismatch:
+ WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n",
+ power_well->name, power_well->always_on, enabled,
+ power_well->count, i915.disable_power_well);
+}
+
void intel_display_power_get(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain)
{
@@ -5361,9 +5384,14 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
mutex_lock(&power_domains->lock);
- for_each_power_well(i, power_well, BIT(domain), power_domains)
- if (!power_well->count++)
+ for_each_power_well(i, power_well, BIT(domain), power_domains) {
+ if (!power_well->count++) {
+ DRM_DEBUG_KMS("enabling %s\n", power_well->name);
power_well->ops->enable(dev_priv, power_well);
+ }
+
+ check_power_well_state(dev_priv, power_well);
+ }
power_domains->domain_use_count[domain]++;
@@ -5387,8 +5415,12 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
WARN_ON(!power_well->count);
- if (!--power_well->count && i915.disable_power_well)
+ if (!--power_well->count && i915.disable_power_well) {
+ DRM_DEBUG_KMS("disabling %s\n", power_well->name);
power_well->ops->disable(dev_priv, power_well);
+ }
+
+ check_power_well_state(dev_priv, power_well);
}
mutex_unlock(&power_domains->lock);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 17/21] drm/i915: sanity check power well sw state against hw state
2014-03-04 17:23 ` [PATCH v2 17/21] drm/i915: sanity check power well sw state against hw state Imre Deak
@ 2014-03-06 19:11 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:11 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:23:06 +0200
Imre Deak <imre.deak@intel.com> wrote:
> Suggested by Daniel.
>
> v2:
> - sanitize the state checking condition, the original was rather
> confusing (partly due to the unfortunate naming of
> i915.disable_power_well) (Ville)
> - simpler message+backtrace generation by using WARN instead of WARN_ON
> (Ville)
> - check if always-on power wells are truly on all the time
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_pm.c | 38 +++++++++++++++++++++++++++++++++++---
> 1 file changed, 35 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 28fae53..c034842 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5350,6 +5350,29 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
> return true;
> }
>
> +static void check_power_well_state(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + bool enabled = power_well->ops->is_enabled(dev_priv, power_well);
> +
> + if (power_well->always_on || !i915.disable_power_well) {
> + if (!enabled)
> + goto mismatch;
> +
> + return;
> + }
> +
> + if (enabled != (power_well->count > 0))
> + goto mismatch;
> +
> + return;
> +
> +mismatch:
> + WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n",
> + power_well->name, power_well->always_on, enabled,
> + power_well->count, i915.disable_power_well);
> +}
> +
> void intel_display_power_get(struct drm_i915_private *dev_priv,
> enum intel_display_power_domain domain)
> {
> @@ -5361,9 +5384,14 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
>
> mutex_lock(&power_domains->lock);
>
> - for_each_power_well(i, power_well, BIT(domain), power_domains)
> - if (!power_well->count++)
> + for_each_power_well(i, power_well, BIT(domain), power_domains) {
> + if (!power_well->count++) {
> + DRM_DEBUG_KMS("enabling %s\n", power_well->name);
> power_well->ops->enable(dev_priv, power_well);
> + }
> +
> + check_power_well_state(dev_priv, power_well);
> + }
>
> power_domains->domain_use_count[domain]++;
>
> @@ -5387,8 +5415,12 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
> for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
> WARN_ON(!power_well->count);
>
> - if (!--power_well->count && i915.disable_power_well)
> + if (!--power_well->count && i915.disable_power_well) {
> + DRM_DEBUG_KMS("disabling %s\n", power_well->name);
> power_well->ops->disable(dev_priv, power_well);
> + }
> +
> + check_power_well_state(dev_priv, power_well);
> }
>
> mutex_unlock(&power_domains->lock);
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 18/21] drm/i915: vlv: factor out valleyview_display_irq_install
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (16 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 17/21] drm/i915: sanity check power well sw state against hw state Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-06 19:17 ` Jesse Barnes
2014-03-04 17:23 ` [PATCH v2 19/21] drm/i915: move hsw power domain comment to its right place Imre Deak
` (2 subsequent siblings)
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
We'll need to disable/re-enable the display-side IRQs when turning
off/on the VLV display power well. Factor out the helper functions
for this. For now keep the display IRQs enabled by default, so the
functionality doesn't change. This will be changed to enable/disable
the IRQs on-demand when adding support for VLV power wells in an
upcoming patch.
v2:
- take the irq spin lock for the whole enable/disable sequence as
these can be called with interrupts enabled
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_dma.c | 1 +
drivers/gpu/drm/i915/i915_drv.h | 5 ++
drivers/gpu/drm/i915/i915_irq.c | 116 ++++++++++++++++++++++++++++++++++------
3 files changed, 106 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index f8f7a59..dca4dc3 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1668,6 +1668,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_mtrrfree;
}
+ dev_priv->display_irqs_enabled = true;
intel_irq_init(dev);
intel_uncore_sanitize(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 711a061..fea0216 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1455,6 +1455,8 @@ typedef struct drm_i915_private {
/* protects the irq masks */
spinlock_t irq_lock;
+ bool display_irqs_enabled;
+
/* To control wakeup latency, e.g. for irq-driven dp aux transfers. */
struct pm_qos_request pm_qos;
@@ -2053,6 +2055,9 @@ void
i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe,
u32 status_mask);
+void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv);
+void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv);
+
/* i915_gem.c */
int i915_gem_init_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 471d8f9..9d9309c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3016,36 +3016,113 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
return 0;
}
+static void valleyview_display_irqs_install(struct drm_i915_private *dev_priv)
+{
+ u32 pipestat_mask;
+ u32 iir_mask;
+
+ pipestat_mask = PIPESTAT_INT_STATUS_MASK |
+ PIPE_FIFO_UNDERRUN_STATUS;
+
+ I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask);
+ I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask);
+ POSTING_READ(PIPESTAT(PIPE_A));
+
+ pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV |
+ PIPE_CRC_DONE_INTERRUPT_STATUS;
+
+ i915_enable_pipestat(dev_priv, PIPE_A, pipestat_mask |
+ PIPE_GMBUS_INTERRUPT_STATUS);
+ i915_enable_pipestat(dev_priv, PIPE_B, pipestat_mask);
+
+ iir_mask = I915_DISPLAY_PORT_INTERRUPT |
+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
+ dev_priv->irq_mask &= ~iir_mask;
+
+ I915_WRITE(VLV_IIR, iir_mask);
+ I915_WRITE(VLV_IIR, iir_mask);
+ I915_WRITE(VLV_IMR, dev_priv->irq_mask);
+ I915_WRITE(VLV_IER, ~dev_priv->irq_mask);
+ POSTING_READ(VLV_IER);
+}
+
+static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv)
+{
+ u32 pipestat_mask;
+ u32 iir_mask;
+
+ iir_mask = I915_DISPLAY_PORT_INTERRUPT |
+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
+
+ dev_priv->irq_mask |= iir_mask;
+ I915_WRITE(VLV_IER, ~dev_priv->irq_mask);
+ I915_WRITE(VLV_IMR, dev_priv->irq_mask);
+ I915_WRITE(VLV_IIR, iir_mask);
+ I915_WRITE(VLV_IIR, iir_mask);
+ POSTING_READ(VLV_IIR);
+
+ pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV |
+ PIPE_CRC_DONE_INTERRUPT_STATUS;
+
+ i915_disable_pipestat(dev_priv, PIPE_A, pipestat_mask |
+ PIPE_GMBUS_INTERRUPT_STATUS);
+ i915_disable_pipestat(dev_priv, PIPE_B, pipestat_mask);
+
+ pipestat_mask = PIPESTAT_INT_STATUS_MASK |
+ PIPE_FIFO_UNDERRUN_STATUS;
+ I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask);
+ I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask);
+ POSTING_READ(PIPESTAT(PIPE_A));
+}
+
+void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv)
+{
+ assert_spin_locked(&dev_priv->irq_lock);
+
+ if (dev_priv->display_irqs_enabled)
+ return;
+
+ dev_priv->display_irqs_enabled = true;
+
+ if (dev_priv->dev->irq_enabled)
+ valleyview_display_irqs_install(dev_priv);
+}
+
+void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv)
+{
+ assert_spin_locked(&dev_priv->irq_lock);
+
+ if (!dev_priv->display_irqs_enabled)
+ return;
+
+ dev_priv->display_irqs_enabled = false;
+
+ if (dev_priv->dev->irq_enabled)
+ valleyview_display_irqs_uninstall(dev_priv);
+}
+
static int valleyview_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- u32 enable_mask;
- u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV |
- PIPE_CRC_DONE_INTERRUPT_STATUS;
unsigned long irqflags;
- enable_mask = I915_DISPLAY_PORT_INTERRUPT;
- enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
- I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
-
- dev_priv->irq_mask = ~enable_mask;
+ dev_priv->irq_mask = ~0;
I915_WRITE(PORT_HOTPLUG_EN, 0);
POSTING_READ(PORT_HOTPLUG_EN);
I915_WRITE(VLV_IMR, dev_priv->irq_mask);
- I915_WRITE(VLV_IER, enable_mask);
+ I915_WRITE(VLV_IER, ~dev_priv->irq_mask);
I915_WRITE(VLV_IIR, 0xffffffff);
- I915_WRITE(PIPESTAT(0), 0xffff);
- I915_WRITE(PIPESTAT(1), 0xffff);
POSTING_READ(VLV_IER);
/* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy. */
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable);
- i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
- i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable);
+ if (dev_priv->display_irqs_enabled)
+ valleyview_display_irqs_install(dev_priv);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
I915_WRITE(VLV_IIR, 0xffffffff);
@@ -3176,6 +3253,7 @@ static void gen8_irq_uninstall(struct drm_device *dev)
static void valleyview_irq_uninstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ unsigned long irqflags;
int pipe;
if (!dev_priv)
@@ -3189,8 +3267,14 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
I915_WRITE(HWSTAM, 0xffffffff);
I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
- for_each_pipe(pipe)
- I915_WRITE(PIPESTAT(pipe), 0xffff);
+
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ if (dev_priv->display_irqs_enabled)
+ valleyview_display_irqs_uninstall(dev_priv);
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+ dev_priv->irq_mask = 0;
+
I915_WRITE(VLV_IIR, 0xffffffff);
I915_WRITE(VLV_IMR, 0xffffffff);
I915_WRITE(VLV_IER, 0x0);
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 18/21] drm/i915: vlv: factor out valleyview_display_irq_install
2014-03-04 17:23 ` [PATCH v2 18/21] drm/i915: vlv: factor out valleyview_display_irq_install Imre Deak
@ 2014-03-06 19:17 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:17 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:23:07 +0200
Imre Deak <imre.deak@intel.com> wrote:
> +void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv)
> +{
> + assert_spin_locked(&dev_priv->irq_lock);
> +
> + if (dev_priv->display_irqs_enabled)
> + return;
> +
> + dev_priv->display_irqs_enabled = true;
> +
> + if (dev_priv->dev->irq_enabled)
> + valleyview_display_irqs_install(dev_priv);
> +}
This made me do a double take, then I saw you were checking the actual
drm_device irq enabled state rather than checking the new field again...
Looks good.
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 19/21] drm/i915: move hsw power domain comment to its right place
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (17 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 18/21] drm/i915: vlv: factor out valleyview_display_irq_install Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-06 19:17 ` Jesse Barnes
2014-03-04 17:23 ` [PATCH v2 20/21] drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock Imre Deak
2014-03-04 17:23 ` [PATCH v2 21/21] drm/i915: power domains: add vlv power wells Imre Deak
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/intel_pm.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c034842..39acffd 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5213,6 +5213,12 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
return is_enabled;
}
+/*
+ * Starting with Haswell, we have a "Power Down Well" that can be turned off
+ * when not needed anymore. We have 4 registers that can request the power well
+ * to be enabled, and it will only be disabled if none of the registers is
+ * requesting it to be enabled.
+ */
static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
@@ -5578,12 +5584,6 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
mutex_unlock(&power_domains->lock);
}
-/*
- * Starting with Haswell, we have a "Power Down Well" that can be turned off
- * when not needed anymore. We have 4 registers that can request the power well
- * to be enabled, and it will only be disabled if none of the registers is
- * requesting it to be enabled.
- */
void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
{
/* For now, we need the power well to be always enabled. */
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 19/21] drm/i915: move hsw power domain comment to its right place
2014-03-04 17:23 ` [PATCH v2 19/21] drm/i915: move hsw power domain comment to its right place Imre Deak
@ 2014-03-06 19:17 ` Jesse Barnes
0 siblings, 0 replies; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:17 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:23:08 +0200
Imre Deak <imre.deak@intel.com> wrote:
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/intel_pm.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index c034842..39acffd 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5213,6 +5213,12 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
> return is_enabled;
> }
>
> +/*
> + * Starting with Haswell, we have a "Power Down Well" that can be turned off
> + * when not needed anymore. We have 4 registers that can request the power well
> + * to be enabled, and it will only be disabled if none of the registers is
> + * requesting it to be enabled.
> + */
> static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
> {
> struct drm_device *dev = dev_priv->dev;
> @@ -5578,12 +5584,6 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
> mutex_unlock(&power_domains->lock);
> }
>
> -/*
> - * Starting with Haswell, we have a "Power Down Well" that can be turned off
> - * when not needed anymore. We have 4 registers that can request the power well
> - * to be enabled, and it will only be disabled if none of the registers is
> - * requesting it to be enabled.
> - */
> void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
> {
> /* For now, we need the power well to be always enabled. */
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 20/21] drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (18 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 19/21] drm/i915: move hsw power domain comment to its right place Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-06 19:18 ` Jesse Barnes
2014-03-04 17:23 ` [PATCH v2 21/21] drm/i915: power domains: add vlv power wells Imre Deak
20 siblings, 1 reply; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
Needed by the next patch, wanting to set the underrun reporting as part
of a bigger dev_priv->irq_lock'ed sequence.
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_irq.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9d9309c..bc94cfb 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -387,17 +387,14 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
*
* Returns the previous state of underrun reporting.
*/
-bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
- enum pipe pipe, bool enable)
+bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
+ enum pipe pipe, bool enable)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- unsigned long flags;
bool ret;
- spin_lock_irqsave(&dev_priv->irq_lock, flags);
-
ret = !intel_crtc->cpu_fifo_underrun_disabled;
if (enable == ret)
@@ -415,7 +412,20 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
done:
+ return ret;
+}
+
+bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
+ enum pipe pipe, bool enable)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long flags;
+ bool ret;
+
+ spin_lock_irqsave(&dev_priv->irq_lock, flags);
+ ret = intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, enable);
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+
return ret;
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 20/21] drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock
2014-03-04 17:23 ` [PATCH v2 20/21] drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock Imre Deak
@ 2014-03-06 19:18 ` Jesse Barnes
2014-03-06 20:46 ` Daniel Vetter
0 siblings, 1 reply; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 19:18 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:23:09 +0200
Imre Deak <imre.deak@intel.com> wrote:
> Needed by the next patch, wanting to set the underrun reporting as part
> of a bigger dev_priv->irq_lock'ed sequence.
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_irq.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 9d9309c..bc94cfb 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -387,17 +387,14 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
> *
> * Returns the previous state of underrun reporting.
> */
> -bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> - enum pipe pipe, bool enable)
> +bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
> + enum pipe pipe, bool enable)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> - unsigned long flags;
> bool ret;
>
> - spin_lock_irqsave(&dev_priv->irq_lock, flags);
> -
> ret = !intel_crtc->cpu_fifo_underrun_disabled;
>
> if (enable == ret)
> @@ -415,7 +412,20 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
>
> done:
> + return ret;
> +}
> +
> +bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> + enum pipe pipe, bool enable)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + unsigned long flags;
> + bool ret;
> +
> + spin_lock_irqsave(&dev_priv->irq_lock, flags);
> + ret = intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, enable);
> spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
> +
> return ret;
> }
>
Funky how diff left the spin_unlock line alone. :)
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread* Re: [PATCH v2 20/21] drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock
2014-03-06 19:18 ` Jesse Barnes
@ 2014-03-06 20:46 ` Daniel Vetter
0 siblings, 0 replies; 45+ messages in thread
From: Daniel Vetter @ 2014-03-06 20:46 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
On Thu, Mar 06, 2014 at 11:18:38AM -0800, Jesse Barnes wrote:
> On Tue, 4 Mar 2014 19:23:09 +0200
> Imre Deak <imre.deak@intel.com> wrote:
>
> > Needed by the next patch, wanting to set the underrun reporting as part
> > of a bigger dev_priv->irq_lock'ed sequence.
> >
> > Signed-off-by: Imre Deak <imre.deak@intel.com>
> > ---
> > drivers/gpu/drm/i915/i915_irq.c | 20 +++++++++++++++-----
> > 1 file changed, 15 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > index 9d9309c..bc94cfb 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -387,17 +387,14 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
> > *
> > * Returns the previous state of underrun reporting.
> > */
> > -bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> > - enum pipe pipe, bool enable)
> > +bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
> > + enum pipe pipe, bool enable)
In i915_irq.c we tend to use a simple __ prefix instead of a _nolock
postfix. I've frobbed this while applying (and will fix up the next
patch).
-Daniel
> > {
> > struct drm_i915_private *dev_priv = dev->dev_private;
> > struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> > struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > - unsigned long flags;
> > bool ret;
> >
> > - spin_lock_irqsave(&dev_priv->irq_lock, flags);
> > -
> > ret = !intel_crtc->cpu_fifo_underrun_disabled;
> >
> > if (enable == ret)
> > @@ -415,7 +412,20 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> > broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
> >
> > done:
> > + return ret;
> > +}
> > +
> > +bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> > + enum pipe pipe, bool enable)
> > +{
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + unsigned long flags;
> > + bool ret;
> > +
> > + spin_lock_irqsave(&dev_priv->irq_lock, flags);
> > + ret = intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, enable);
> > spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
> > +
> > return ret;
> > }
> >
>
> Funky how diff left the spin_unlock line alone. :)
>
> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> --
> Jesse Barnes, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v2 21/21] drm/i915: power domains: add vlv power wells
2014-03-04 17:22 [PATCH v2 00/21] drm/i915: vlv power domains support Imre Deak
` (19 preceding siblings ...)
2014-03-04 17:23 ` [PATCH v2 20/21] drm/i915: factor out intel_set_cpu_fifo_underrun_reporting_nolock Imre Deak
@ 2014-03-04 17:23 ` Imre Deak
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
2014-03-06 20:29 ` [PATCH v2 " Jesse Barnes
20 siblings, 2 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-04 17:23 UTC (permalink / raw)
To: intel-gfx
Based on an early draft from Jesse.
Add support for powering on/off the dynamic power wells on VLV by
registering its display and dpio dynamic power wells with the power
domain framework.
For now power on all PHY TX lanes regardless of the actual lane
configuration. Later this can be optimized when the PHY side setup
enables only the required lanes. Atm, it enables all lanes in all
cases.
v2:
- undef function local COND macro after its last use (Ville)
- Take dev_priv->irq_lock around the whole sequence of
intel_set_cpu_fifo_underrun_reporting_nolock() and
valleyview_disable_display_irqs(). They are short and releasing
the lock in between only makes proving correctness more difficult.
- sanitize local var names in vlv_power_well_enabled()
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_dma.c | 1 -
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/intel_display.c | 1 +
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_pm.c | 237 +++++++++++++++++++++++++++++++++++
5 files changed, 241 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index dca4dc3..f8f7a59 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1668,7 +1668,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_mtrrfree;
}
- dev_priv->display_irqs_enabled = true;
intel_irq_init(dev);
intel_uncore_sanitize(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index fea0216..3fad6ed 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1054,7 +1054,7 @@ struct i915_power_well {
/* power well enable/disable usage count */
int count;
unsigned long domains;
- void *data;
+ unsigned long data;
const struct i915_power_well_ops *ops;
};
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6fb40cb..b2eb07a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4224,6 +4224,7 @@ static void valleyview_modeset_global_resources(struct drm_device *dev)
if (req_cdclk != cur_cdclk)
valleyview_set_cdclk(dev, req_cdclk);
+ modeset_update_power_wells(dev);
}
static void valleyview_crtc_enable(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index afc01a4..f2555ac 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
/* i915_irq.c */
bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable);
+bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
+ enum pipe pipe, bool enable);
bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
enum transcoder pch_transcoder,
bool enable);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 39acffd..b8b5e3e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5356,6 +5356,141 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
return true;
}
+static void vlv_set_power_well(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well, bool enable)
+{
+ enum punit_power_well power_well_id = power_well->data;
+ u32 mask;
+ u32 state;
+ u32 ctrl;
+
+ mask = PUNIT_PWRGT_MASK(power_well_id);
+ state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
+ PUNIT_PWRGT_PWR_GATE(power_well_id);
+
+ mutex_lock(&dev_priv->rps.hw_lock);
+
+#define COND \
+ ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
+
+ if (COND)
+ goto out;
+
+ ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL);
+ ctrl &= ~mask;
+ ctrl |= state;
+ vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl);
+
+ if (wait_for(COND, 100))
+ DRM_ERROR("timout setting power well state %08x (%08x)\n",
+ state,
+ vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL));
+
+#undef COND
+
+out:
+ mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ vlv_set_power_well(dev_priv, power_well, power_well->count > 0);
+}
+
+static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ vlv_set_power_well(dev_priv, power_well, true);
+}
+
+static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ vlv_set_power_well(dev_priv, power_well, false);
+}
+
+static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ int power_well_id = power_well->data;
+ bool enabled = false;
+ u32 mask;
+ u32 state;
+ u32 ctrl;
+
+ mask = PUNIT_PWRGT_MASK(power_well_id);
+ ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
+
+ mutex_lock(&dev_priv->rps.hw_lock);
+
+ state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
+ /*
+ * We only ever set the power-on and power-gate states, anything
+ * else is unexpected.
+ */
+ WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) &&
+ state != PUNIT_PWRGT_PWR_GATE(power_well_id));
+ if (state == ctrl)
+ enabled = true;
+
+ /*
+ * A transient state at this point would mean some unexpected party
+ * is poking at the power controls too.
+ */
+ ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
+ WARN_ON(ctrl != state);
+
+ mutex_unlock(&dev_priv->rps.hw_lock);
+
+ return enabled;
+}
+
+static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+
+ WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
+
+ vlv_set_power_well(dev_priv, power_well, true);
+
+ spin_lock_irq(&dev_priv->irq_lock);
+ valleyview_enable_display_irqs(dev_priv);
+ spin_unlock_irq(&dev_priv->irq_lock);
+
+ /*
+ * During driver initialization we need to defer enabling hotplug
+ * processing until fbdev is set up.
+ */
+ if (dev_priv->enable_hotplug_processing)
+ intel_hpd_init(dev_priv->dev);
+
+ i915_redisable_vga_power_on(dev_priv->dev);
+}
+
+static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ struct drm_device *dev = dev_priv->dev;
+ enum pipe pipe;
+
+ WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
+
+ spin_lock_irq(&dev_priv->irq_lock);
+ for_each_pipe(pipe)
+ intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, false);
+
+ valleyview_disable_display_irqs(dev_priv);
+ spin_unlock_irq(&dev_priv->irq_lock);
+
+ spin_lock_irq(&dev->vbl_lock);
+ for_each_pipe(pipe)
+ reset_vblank_counter(dev, pipe);
+ spin_unlock_irq(&dev->vbl_lock);
+
+ vlv_set_power_well(dev_priv, power_well, false);
+}
+
static void check_power_well_state(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
@@ -5488,6 +5623,35 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
(POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
BIT(POWER_DOMAIN_INIT))
+#define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT)
+#define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK
+
+#define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_CRT) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
.sync_hw = i9xx_always_on_power_well_noop,
.enable = i9xx_always_on_power_well_noop,
@@ -5539,6 +5703,77 @@ static struct i915_power_well bdw_power_wells[] = {
},
};
+static const struct i915_power_well_ops vlv_display_power_well_ops = {
+ .sync_hw = vlv_power_well_sync_hw,
+ .enable = vlv_display_power_well_enable,
+ .disable = vlv_display_power_well_disable,
+ .is_enabled = vlv_power_well_enabled,
+};
+
+static const struct i915_power_well_ops vlv_dpio_power_well_ops = {
+ .sync_hw = vlv_power_well_sync_hw,
+ .enable = vlv_power_well_enable,
+ .disable = vlv_power_well_disable,
+ .is_enabled = vlv_power_well_enabled,
+};
+
+static struct i915_power_well vlv_power_wells[] = {
+ {
+ .name = "always-on",
+ .always_on = 1,
+ .domains = VLV_ALWAYS_ON_POWER_DOMAINS,
+ .ops = &i9xx_always_on_power_well_ops,
+ },
+ {
+ .name = "display",
+ .domains = VLV_DISPLAY_POWER_DOMAINS,
+ .data = PUNIT_POWER_WELL_DISP2D,
+ .ops = &vlv_display_power_well_ops,
+ },
+ {
+ .name = "dpio-common",
+ .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
+ .data = PUNIT_POWER_WELL_DPIO_CMN_BC,
+ .ops = &vlv_dpio_power_well_ops,
+ },
+ {
+ .name = "dpio-tx-b-01",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01,
+ },
+ {
+ .name = "dpio-tx-b-23",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23,
+ },
+ {
+ .name = "dpio-tx-c-01",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01,
+ },
+ {
+ .name = "dpio-tx-c-23",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23,
+ },
+};
+
#define set_power_wells(power_domains, __power_wells) ({ \
(power_domains)->power_wells = (__power_wells); \
(power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
@@ -5560,6 +5795,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
} else if (IS_BROADWELL(dev_priv->dev)) {
set_power_wells(power_domains, bdw_power_wells);
hsw_pwr = power_domains;
+ } else if (IS_VALLEYVIEW(dev_priv->dev)) {
+ set_power_wells(power_domains, vlv_power_wells);
} else {
set_power_wells(power_domains, i9xx_always_on_power_well);
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* [PATCH v3 21/21] drm/i915: power domains: add vlv power wells
2014-03-04 17:23 ` [PATCH v2 21/21] drm/i915: power domains: add vlv power wells Imre Deak
@ 2014-03-05 14:20 ` Imre Deak
2014-03-06 20:29 ` [PATCH v2 " Jesse Barnes
1 sibling, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-05 14:20 UTC (permalink / raw)
To: intel-gfx
Based on an early draft from Jesse.
Add support for powering on/off the dynamic power wells on VLV by
registering its display and dpio dynamic power wells with the power
domain framework.
For now power on all PHY TX lanes regardless of the actual lane
configuration. Later this can be optimized when the PHY side setup
enables only the required lanes. Atm, it enables all lanes in all
cases.
v2:
- undef function local COND macro after its last use (Ville)
- Take dev_priv->irq_lock around the whole sequence of
intel_set_cpu_fifo_underrun_reporting_nolock() and
valleyview_disable_display_irqs(). They are short and releasing
the lock in between only makes proving correctness more difficult.
- sanitize local var names in vlv_power_well_enabled()
v3:
- rebase on latest -nightly
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
drivers/gpu/drm/i915/i915_dma.c | 1 -
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/intel_display.c | 1 +
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_pm.c | 237 +++++++++++++++++++++++++++++++++++
5 files changed, 241 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index dca4dc3..f8f7a59 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1668,7 +1668,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_mtrrfree;
}
- dev_priv->display_irqs_enabled = true;
intel_irq_init(dev);
intel_uncore_sanitize(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9a6336a..410fef7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1054,7 +1054,7 @@ struct i915_power_well {
/* power well enable/disable usage count */
int count;
unsigned long domains;
- void *data;
+ unsigned long data;
const struct i915_power_well_ops *ops;
};
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cde6d02..31f5509 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4229,6 +4229,7 @@ static void valleyview_modeset_global_resources(struct drm_device *dev)
if (req_cdclk != cur_cdclk)
valleyview_set_cdclk(dev, req_cdclk);
+ modeset_update_crtc_power_domains(dev);
}
static void valleyview_crtc_enable(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e31eb1e..848cfbb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
/* i915_irq.c */
bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable);
+bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
+ enum pipe pipe, bool enable);
bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
enum transcoder pch_transcoder,
bool enable);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 79d7d13..382e8c1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5394,6 +5394,141 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
return true;
}
+static void vlv_set_power_well(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well, bool enable)
+{
+ enum punit_power_well power_well_id = power_well->data;
+ u32 mask;
+ u32 state;
+ u32 ctrl;
+
+ mask = PUNIT_PWRGT_MASK(power_well_id);
+ state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
+ PUNIT_PWRGT_PWR_GATE(power_well_id);
+
+ mutex_lock(&dev_priv->rps.hw_lock);
+
+#define COND \
+ ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
+
+ if (COND)
+ goto out;
+
+ ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL);
+ ctrl &= ~mask;
+ ctrl |= state;
+ vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl);
+
+ if (wait_for(COND, 100))
+ DRM_ERROR("timout setting power well state %08x (%08x)\n",
+ state,
+ vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL));
+
+#undef COND
+
+out:
+ mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ vlv_set_power_well(dev_priv, power_well, power_well->count > 0);
+}
+
+static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ vlv_set_power_well(dev_priv, power_well, true);
+}
+
+static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ vlv_set_power_well(dev_priv, power_well, false);
+}
+
+static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ int power_well_id = power_well->data;
+ bool enabled = false;
+ u32 mask;
+ u32 state;
+ u32 ctrl;
+
+ mask = PUNIT_PWRGT_MASK(power_well_id);
+ ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
+
+ mutex_lock(&dev_priv->rps.hw_lock);
+
+ state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
+ /*
+ * We only ever set the power-on and power-gate states, anything
+ * else is unexpected.
+ */
+ WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) &&
+ state != PUNIT_PWRGT_PWR_GATE(power_well_id));
+ if (state == ctrl)
+ enabled = true;
+
+ /*
+ * A transient state at this point would mean some unexpected party
+ * is poking at the power controls too.
+ */
+ ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
+ WARN_ON(ctrl != state);
+
+ mutex_unlock(&dev_priv->rps.hw_lock);
+
+ return enabled;
+}
+
+static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+
+ WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
+
+ vlv_set_power_well(dev_priv, power_well, true);
+
+ spin_lock_irq(&dev_priv->irq_lock);
+ valleyview_enable_display_irqs(dev_priv);
+ spin_unlock_irq(&dev_priv->irq_lock);
+
+ /*
+ * During driver initialization we need to defer enabling hotplug
+ * processing until fbdev is set up.
+ */
+ if (dev_priv->enable_hotplug_processing)
+ intel_hpd_init(dev_priv->dev);
+
+ i915_redisable_vga_power_on(dev_priv->dev);
+}
+
+static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ struct drm_device *dev = dev_priv->dev;
+ enum pipe pipe;
+
+ WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
+
+ spin_lock_irq(&dev_priv->irq_lock);
+ for_each_pipe(pipe)
+ intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, false);
+
+ valleyview_disable_display_irqs(dev_priv);
+ spin_unlock_irq(&dev_priv->irq_lock);
+
+ spin_lock_irq(&dev->vbl_lock);
+ for_each_pipe(pipe)
+ reset_vblank_counter(dev, pipe);
+ spin_unlock_irq(&dev->vbl_lock);
+
+ vlv_set_power_well(dev_priv, power_well, false);
+}
+
static void check_power_well_state(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
@@ -5526,6 +5661,35 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
(POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
BIT(POWER_DOMAIN_INIT))
+#define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT)
+#define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK
+
+#define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_PORT_CRT) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
+ BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
+#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \
+ BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
+ BIT(POWER_DOMAIN_INIT))
+
static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
.sync_hw = i9xx_always_on_power_well_noop,
.enable = i9xx_always_on_power_well_noop,
@@ -5577,6 +5741,77 @@ static struct i915_power_well bdw_power_wells[] = {
},
};
+static const struct i915_power_well_ops vlv_display_power_well_ops = {
+ .sync_hw = vlv_power_well_sync_hw,
+ .enable = vlv_display_power_well_enable,
+ .disable = vlv_display_power_well_disable,
+ .is_enabled = vlv_power_well_enabled,
+};
+
+static const struct i915_power_well_ops vlv_dpio_power_well_ops = {
+ .sync_hw = vlv_power_well_sync_hw,
+ .enable = vlv_power_well_enable,
+ .disable = vlv_power_well_disable,
+ .is_enabled = vlv_power_well_enabled,
+};
+
+static struct i915_power_well vlv_power_wells[] = {
+ {
+ .name = "always-on",
+ .always_on = 1,
+ .domains = VLV_ALWAYS_ON_POWER_DOMAINS,
+ .ops = &i9xx_always_on_power_well_ops,
+ },
+ {
+ .name = "display",
+ .domains = VLV_DISPLAY_POWER_DOMAINS,
+ .data = PUNIT_POWER_WELL_DISP2D,
+ .ops = &vlv_display_power_well_ops,
+ },
+ {
+ .name = "dpio-common",
+ .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
+ .data = PUNIT_POWER_WELL_DPIO_CMN_BC,
+ .ops = &vlv_dpio_power_well_ops,
+ },
+ {
+ .name = "dpio-tx-b-01",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01,
+ },
+ {
+ .name = "dpio-tx-b-23",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23,
+ },
+ {
+ .name = "dpio-tx-c-01",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01,
+ },
+ {
+ .name = "dpio-tx-c-23",
+ .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
+ VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
+ .ops = &vlv_dpio_power_well_ops,
+ .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23,
+ },
+};
+
#define set_power_wells(power_domains, __power_wells) ({ \
(power_domains)->power_wells = (__power_wells); \
(power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
@@ -5598,6 +5833,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
} else if (IS_BROADWELL(dev_priv->dev)) {
set_power_wells(power_domains, bdw_power_wells);
hsw_pwr = power_domains;
+ } else if (IS_VALLEYVIEW(dev_priv->dev)) {
+ set_power_wells(power_domains, vlv_power_wells);
} else {
set_power_wells(power_domains, i9xx_always_on_power_well);
}
--
1.8.4
^ permalink raw reply related [flat|nested] 45+ messages in thread* Re: [PATCH v2 21/21] drm/i915: power domains: add vlv power wells
2014-03-04 17:23 ` [PATCH v2 21/21] drm/i915: power domains: add vlv power wells Imre Deak
2014-03-05 14:20 ` [PATCH v3 " Imre Deak
@ 2014-03-06 20:29 ` Jesse Barnes
2014-03-06 20:52 ` Daniel Vetter
1 sibling, 1 reply; 45+ messages in thread
From: Jesse Barnes @ 2014-03-06 20:29 UTC (permalink / raw)
To: Imre Deak; +Cc: intel-gfx
On Tue, 4 Mar 2014 19:23:10 +0200
Imre Deak <imre.deak@intel.com> wrote:
> Based on an early draft from Jesse.
>
> Add support for powering on/off the dynamic power wells on VLV by
> registering its display and dpio dynamic power wells with the power
> domain framework.
>
> For now power on all PHY TX lanes regardless of the actual lane
> configuration. Later this can be optimized when the PHY side setup
> enables only the required lanes. Atm, it enables all lanes in all
> cases.
>
> v2:
> - undef function local COND macro after its last use (Ville)
> - Take dev_priv->irq_lock around the whole sequence of
> intel_set_cpu_fifo_underrun_reporting_nolock() and
> valleyview_disable_display_irqs(). They are short and releasing
> the lock in between only makes proving correctness more difficult.
> - sanitize local var names in vlv_power_well_enabled()
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_dma.c | 1 -
> drivers/gpu/drm/i915/i915_drv.h | 2 +-
> drivers/gpu/drm/i915/intel_display.c | 1 +
> drivers/gpu/drm/i915/intel_drv.h | 2 +
> drivers/gpu/drm/i915/intel_pm.c | 237 +++++++++++++++++++++++++++++++++++
> 5 files changed, 241 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index dca4dc3..f8f7a59 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -1668,7 +1668,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
> goto out_mtrrfree;
> }
>
> - dev_priv->display_irqs_enabled = true;
> intel_irq_init(dev);
> intel_uncore_sanitize(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index fea0216..3fad6ed 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1054,7 +1054,7 @@ struct i915_power_well {
> /* power well enable/disable usage count */
> int count;
> unsigned long domains;
> - void *data;
> + unsigned long data;
> const struct i915_power_well_ops *ops;
> };
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 6fb40cb..b2eb07a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4224,6 +4224,7 @@ static void valleyview_modeset_global_resources(struct drm_device *dev)
>
> if (req_cdclk != cur_cdclk)
> valleyview_set_cdclk(dev, req_cdclk);
> + modeset_update_power_wells(dev);
> }
>
> static void valleyview_crtc_enable(struct drm_crtc *crtc)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index afc01a4..f2555ac 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
> /* i915_irq.c */
> bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> enum pipe pipe, bool enable);
> +bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
> + enum pipe pipe, bool enable);
> bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
> enum transcoder pch_transcoder,
> bool enable);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 39acffd..b8b5e3e 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -5356,6 +5356,141 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
> return true;
> }
>
> +static void vlv_set_power_well(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well, bool enable)
> +{
> + enum punit_power_well power_well_id = power_well->data;
> + u32 mask;
> + u32 state;
> + u32 ctrl;
> +
> + mask = PUNIT_PWRGT_MASK(power_well_id);
> + state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
> + PUNIT_PWRGT_PWR_GATE(power_well_id);
> +
> + mutex_lock(&dev_priv->rps.hw_lock);
> +
> +#define COND \
> + ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
> +
> + if (COND)
> + goto out;
> +
> + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL);
> + ctrl &= ~mask;
> + ctrl |= state;
> + vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl);
> +
> + if (wait_for(COND, 100))
> + DRM_ERROR("timout setting power well state %08x (%08x)\n",
> + state,
> + vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL));
> +
> +#undef COND
> +
> +out:
> + mutex_unlock(&dev_priv->rps.hw_lock);
> +}
> +
> +static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + vlv_set_power_well(dev_priv, power_well, power_well->count > 0);
> +}
> +
> +static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + vlv_set_power_well(dev_priv, power_well, true);
> +}
> +
> +static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + vlv_set_power_well(dev_priv, power_well, false);
> +}
> +
> +static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + int power_well_id = power_well->data;
> + bool enabled = false;
> + u32 mask;
> + u32 state;
> + u32 ctrl;
> +
> + mask = PUNIT_PWRGT_MASK(power_well_id);
> + ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
> +
> + mutex_lock(&dev_priv->rps.hw_lock);
> +
> + state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
> + /*
> + * We only ever set the power-on and power-gate states, anything
> + * else is unexpected.
> + */
> + WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) &&
> + state != PUNIT_PWRGT_PWR_GATE(power_well_id));
> + if (state == ctrl)
> + enabled = true;
> +
> + /*
> + * A transient state at this point would mean some unexpected party
> + * is poking at the power controls too.
> + */
> + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
> + WARN_ON(ctrl != state);
> +
> + mutex_unlock(&dev_priv->rps.hw_lock);
> +
> + return enabled;
> +}
> +
> +static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> +
> + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
> +
> + vlv_set_power_well(dev_priv, power_well, true);
> +
> + spin_lock_irq(&dev_priv->irq_lock);
> + valleyview_enable_display_irqs(dev_priv);
> + spin_unlock_irq(&dev_priv->irq_lock);
> +
> + /*
> + * During driver initialization we need to defer enabling hotplug
> + * processing until fbdev is set up.
> + */
> + if (dev_priv->enable_hotplug_processing)
> + intel_hpd_init(dev_priv->dev);
> +
> + i915_redisable_vga_power_on(dev_priv->dev);
> +}
> +
> +static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
> + struct i915_power_well *power_well)
> +{
> + struct drm_device *dev = dev_priv->dev;
> + enum pipe pipe;
> +
> + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
> +
> + spin_lock_irq(&dev_priv->irq_lock);
> + for_each_pipe(pipe)
> + intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, false);
> +
> + valleyview_disable_display_irqs(dev_priv);
> + spin_unlock_irq(&dev_priv->irq_lock);
> +
> + spin_lock_irq(&dev->vbl_lock);
> + for_each_pipe(pipe)
> + reset_vblank_counter(dev, pipe);
> + spin_unlock_irq(&dev->vbl_lock);
> +
> + vlv_set_power_well(dev_priv, power_well, false);
> +}
> +
> static void check_power_well_state(struct drm_i915_private *dev_priv,
> struct i915_power_well *power_well)
> {
> @@ -5488,6 +5623,35 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
> (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
> BIT(POWER_DOMAIN_INIT))
>
> +#define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT)
> +#define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK
> +
> +#define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \
> + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
> + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
> + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> + BIT(POWER_DOMAIN_PORT_CRT) | \
> + BIT(POWER_DOMAIN_INIT))
> +
> +#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \
> + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
> + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> + BIT(POWER_DOMAIN_INIT))
> +
> +#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \
> + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> + BIT(POWER_DOMAIN_INIT))
> +
> +#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \
> + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
> + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> + BIT(POWER_DOMAIN_INIT))
> +
> +#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \
> + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> + BIT(POWER_DOMAIN_INIT))
> +
> static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
> .sync_hw = i9xx_always_on_power_well_noop,
> .enable = i9xx_always_on_power_well_noop,
> @@ -5539,6 +5703,77 @@ static struct i915_power_well bdw_power_wells[] = {
> },
> };
>
> +static const struct i915_power_well_ops vlv_display_power_well_ops = {
> + .sync_hw = vlv_power_well_sync_hw,
> + .enable = vlv_display_power_well_enable,
> + .disable = vlv_display_power_well_disable,
> + .is_enabled = vlv_power_well_enabled,
> +};
> +
> +static const struct i915_power_well_ops vlv_dpio_power_well_ops = {
> + .sync_hw = vlv_power_well_sync_hw,
> + .enable = vlv_power_well_enable,
> + .disable = vlv_power_well_disable,
> + .is_enabled = vlv_power_well_enabled,
> +};
> +
> +static struct i915_power_well vlv_power_wells[] = {
> + {
> + .name = "always-on",
> + .always_on = 1,
> + .domains = VLV_ALWAYS_ON_POWER_DOMAINS,
> + .ops = &i9xx_always_on_power_well_ops,
> + },
> + {
> + .name = "display",
> + .domains = VLV_DISPLAY_POWER_DOMAINS,
> + .data = PUNIT_POWER_WELL_DISP2D,
> + .ops = &vlv_display_power_well_ops,
> + },
> + {
> + .name = "dpio-common",
> + .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
> + .data = PUNIT_POWER_WELL_DPIO_CMN_BC,
> + .ops = &vlv_dpio_power_well_ops,
> + },
> + {
> + .name = "dpio-tx-b-01",
> + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> + .ops = &vlv_dpio_power_well_ops,
> + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01,
> + },
> + {
> + .name = "dpio-tx-b-23",
> + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> + .ops = &vlv_dpio_power_well_ops,
> + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23,
> + },
> + {
> + .name = "dpio-tx-c-01",
> + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> + .ops = &vlv_dpio_power_well_ops,
> + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01,
> + },
> + {
> + .name = "dpio-tx-c-23",
> + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> + .ops = &vlv_dpio_power_well_ops,
> + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23,
> + },
> +};
> +
> #define set_power_wells(power_domains, __power_wells) ({ \
> (power_domains)->power_wells = (__power_wells); \
> (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
> @@ -5560,6 +5795,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
> } else if (IS_BROADWELL(dev_priv->dev)) {
> set_power_wells(power_domains, bdw_power_wells);
> hsw_pwr = power_domains;
> + } else if (IS_VALLEYVIEW(dev_priv->dev)) {
> + set_power_wells(power_domains, vlv_power_wells);
> } else {
> set_power_wells(power_domains, i9xx_always_on_power_well);
> }
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 45+ messages in thread* Re: [PATCH v2 21/21] drm/i915: power domains: add vlv power wells
2014-03-06 20:29 ` [PATCH v2 " Jesse Barnes
@ 2014-03-06 20:52 ` Daniel Vetter
2014-03-06 21:04 ` Imre Deak
0 siblings, 1 reply; 45+ messages in thread
From: Daniel Vetter @ 2014-03-06 20:52 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
On Thu, Mar 06, 2014 at 12:29:24PM -0800, Jesse Barnes wrote:
> On Tue, 4 Mar 2014 19:23:10 +0200
> Imre Deak <imre.deak@intel.com> wrote:
>
> > Based on an early draft from Jesse.
> >
> > Add support for powering on/off the dynamic power wells on VLV by
> > registering its display and dpio dynamic power wells with the power
> > domain framework.
> >
> > For now power on all PHY TX lanes regardless of the actual lane
> > configuration. Later this can be optimized when the PHY side setup
> > enables only the required lanes. Atm, it enables all lanes in all
> > cases.
> >
> > v2:
> > - undef function local COND macro after its last use (Ville)
> > - Take dev_priv->irq_lock around the whole sequence of
> > intel_set_cpu_fifo_underrun_reporting_nolock() and
> > valleyview_disable_display_irqs(). They are short and releasing
> > the lock in between only makes proving correctness more difficult.
> > - sanitize local var names in vlv_power_well_enabled()
> >
> > Signed-off-by: Imre Deak <imre.deak@intel.com>
> > ---
> > drivers/gpu/drm/i915/i915_dma.c | 1 -
> > drivers/gpu/drm/i915/i915_drv.h | 2 +-
> > drivers/gpu/drm/i915/intel_display.c | 1 +
> > drivers/gpu/drm/i915/intel_drv.h | 2 +
> > drivers/gpu/drm/i915/intel_pm.c | 237 +++++++++++++++++++++++++++++++++++
> > 5 files changed, 241 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> > index dca4dc3..f8f7a59 100644
> > --- a/drivers/gpu/drm/i915/i915_dma.c
> > +++ b/drivers/gpu/drm/i915/i915_dma.c
> > @@ -1668,7 +1668,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
> > goto out_mtrrfree;
> > }
> >
> > - dev_priv->display_irqs_enabled = true;
> > intel_irq_init(dev);
> > intel_uncore_sanitize(dev);
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index fea0216..3fad6ed 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1054,7 +1054,7 @@ struct i915_power_well {
> > /* power well enable/disable usage count */
> > int count;
> > unsigned long domains;
> > - void *data;
> > + unsigned long data;
> > const struct i915_power_well_ops *ops;
> > };
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 6fb40cb..b2eb07a 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -4224,6 +4224,7 @@ static void valleyview_modeset_global_resources(struct drm_device *dev)
> >
> > if (req_cdclk != cur_cdclk)
> > valleyview_set_cdclk(dev, req_cdclk);
> > + modeset_update_power_wells(dev);
> > }
> >
> > static void valleyview_crtc_enable(struct drm_crtc *crtc)
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index afc01a4..f2555ac 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
> > /* i915_irq.c */
> > bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> > enum pipe pipe, bool enable);
> > +bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
> > + enum pipe pipe, bool enable);
> > bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
> > enum transcoder pch_transcoder,
> > bool enable);
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 39acffd..b8b5e3e 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -5356,6 +5356,141 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
> > return true;
> > }
> >
> > +static void vlv_set_power_well(struct drm_i915_private *dev_priv,
> > + struct i915_power_well *power_well, bool enable)
> > +{
> > + enum punit_power_well power_well_id = power_well->data;
> > + u32 mask;
> > + u32 state;
> > + u32 ctrl;
> > +
> > + mask = PUNIT_PWRGT_MASK(power_well_id);
> > + state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
> > + PUNIT_PWRGT_PWR_GATE(power_well_id);
> > +
> > + mutex_lock(&dev_priv->rps.hw_lock);
> > +
> > +#define COND \
> > + ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
> > +
> > + if (COND)
> > + goto out;
> > +
> > + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL);
> > + ctrl &= ~mask;
> > + ctrl |= state;
> > + vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl);
> > +
> > + if (wait_for(COND, 100))
> > + DRM_ERROR("timout setting power well state %08x (%08x)\n",
> > + state,
> > + vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL));
> > +
> > +#undef COND
> > +
> > +out:
> > + mutex_unlock(&dev_priv->rps.hw_lock);
> > +}
> > +
> > +static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
> > + struct i915_power_well *power_well)
> > +{
> > + vlv_set_power_well(dev_priv, power_well, power_well->count > 0);
> > +}
> > +
> > +static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
> > + struct i915_power_well *power_well)
> > +{
> > + vlv_set_power_well(dev_priv, power_well, true);
> > +}
> > +
> > +static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
> > + struct i915_power_well *power_well)
> > +{
> > + vlv_set_power_well(dev_priv, power_well, false);
> > +}
> > +
> > +static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
> > + struct i915_power_well *power_well)
> > +{
> > + int power_well_id = power_well->data;
> > + bool enabled = false;
> > + u32 mask;
> > + u32 state;
> > + u32 ctrl;
> > +
> > + mask = PUNIT_PWRGT_MASK(power_well_id);
> > + ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
> > +
> > + mutex_lock(&dev_priv->rps.hw_lock);
> > +
> > + state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
> > + /*
> > + * We only ever set the power-on and power-gate states, anything
> > + * else is unexpected.
> > + */
> > + WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) &&
> > + state != PUNIT_PWRGT_PWR_GATE(power_well_id));
> > + if (state == ctrl)
> > + enabled = true;
> > +
> > + /*
> > + * A transient state at this point would mean some unexpected party
> > + * is poking at the power controls too.
> > + */
> > + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
> > + WARN_ON(ctrl != state);
> > +
> > + mutex_unlock(&dev_priv->rps.hw_lock);
> > +
> > + return enabled;
> > +}
> > +
> > +static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
> > + struct i915_power_well *power_well)
> > +{
> > +
> > + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
> > +
> > + vlv_set_power_well(dev_priv, power_well, true);
> > +
> > + spin_lock_irq(&dev_priv->irq_lock);
> > + valleyview_enable_display_irqs(dev_priv);
> > + spin_unlock_irq(&dev_priv->irq_lock);
> > +
> > + /*
> > + * During driver initialization we need to defer enabling hotplug
> > + * processing until fbdev is set up.
> > + */
> > + if (dev_priv->enable_hotplug_processing)
> > + intel_hpd_init(dev_priv->dev);
> > +
> > + i915_redisable_vga_power_on(dev_priv->dev);
> > +}
> > +
> > +static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
> > + struct i915_power_well *power_well)
> > +{
> > + struct drm_device *dev = dev_priv->dev;
> > + enum pipe pipe;
> > +
> > + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
> > +
> > + spin_lock_irq(&dev_priv->irq_lock);
> > + for_each_pipe(pipe)
> > + intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, false);
> > +
> > + valleyview_disable_display_irqs(dev_priv);
> > + spin_unlock_irq(&dev_priv->irq_lock);
> > +
> > + spin_lock_irq(&dev->vbl_lock);
> > + for_each_pipe(pipe)
> > + reset_vblank_counter(dev, pipe);
> > + spin_unlock_irq(&dev->vbl_lock);
> > +
> > + vlv_set_power_well(dev_priv, power_well, false);
> > +}
> > +
> > static void check_power_well_state(struct drm_i915_private *dev_priv,
> > struct i915_power_well *power_well)
> > {
> > @@ -5488,6 +5623,35 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
> > (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
> > BIT(POWER_DOMAIN_INIT))
> >
> > +#define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT)
> > +#define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK
> > +
> > +#define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \
> > + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
> > + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> > + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
> > + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> > + BIT(POWER_DOMAIN_PORT_CRT) | \
> > + BIT(POWER_DOMAIN_INIT))
> > +
> > +#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \
> > + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
> > + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> > + BIT(POWER_DOMAIN_INIT))
> > +
> > +#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \
> > + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> > + BIT(POWER_DOMAIN_INIT))
> > +
> > +#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \
> > + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
> > + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> > + BIT(POWER_DOMAIN_INIT))
> > +
> > +#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \
> > + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> > + BIT(POWER_DOMAIN_INIT))
> > +
> > static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
> > .sync_hw = i9xx_always_on_power_well_noop,
> > .enable = i9xx_always_on_power_well_noop,
> > @@ -5539,6 +5703,77 @@ static struct i915_power_well bdw_power_wells[] = {
> > },
> > };
> >
> > +static const struct i915_power_well_ops vlv_display_power_well_ops = {
> > + .sync_hw = vlv_power_well_sync_hw,
> > + .enable = vlv_display_power_well_enable,
> > + .disable = vlv_display_power_well_disable,
> > + .is_enabled = vlv_power_well_enabled,
> > +};
> > +
> > +static const struct i915_power_well_ops vlv_dpio_power_well_ops = {
> > + .sync_hw = vlv_power_well_sync_hw,
> > + .enable = vlv_power_well_enable,
> > + .disable = vlv_power_well_disable,
> > + .is_enabled = vlv_power_well_enabled,
> > +};
> > +
> > +static struct i915_power_well vlv_power_wells[] = {
> > + {
> > + .name = "always-on",
> > + .always_on = 1,
> > + .domains = VLV_ALWAYS_ON_POWER_DOMAINS,
> > + .ops = &i9xx_always_on_power_well_ops,
> > + },
> > + {
> > + .name = "display",
> > + .domains = VLV_DISPLAY_POWER_DOMAINS,
> > + .data = PUNIT_POWER_WELL_DISP2D,
> > + .ops = &vlv_display_power_well_ops,
> > + },
> > + {
> > + .name = "dpio-common",
> > + .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
> > + .data = PUNIT_POWER_WELL_DPIO_CMN_BC,
> > + .ops = &vlv_dpio_power_well_ops,
> > + },
> > + {
> > + .name = "dpio-tx-b-01",
> > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > + .ops = &vlv_dpio_power_well_ops,
> > + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01,
> > + },
> > + {
> > + .name = "dpio-tx-b-23",
> > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > + .ops = &vlv_dpio_power_well_ops,
> > + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23,
> > + },
> > + {
> > + .name = "dpio-tx-c-01",
> > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > + .ops = &vlv_dpio_power_well_ops,
> > + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01,
> > + },
> > + {
> > + .name = "dpio-tx-c-23",
> > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > + .ops = &vlv_dpio_power_well_ops,
> > + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23,
> > + },
> > +};
> > +
> > #define set_power_wells(power_domains, __power_wells) ({ \
> > (power_domains)->power_wells = (__power_wells); \
> > (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
> > @@ -5560,6 +5795,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
> > } else if (IS_BROADWELL(dev_priv->dev)) {
> > set_power_wells(power_domains, bdw_power_wells);
> > hsw_pwr = power_domains;
> > + } else if (IS_VALLEYVIEW(dev_priv->dev)) {
> > + set_power_wells(power_domains, vlv_power_wells);
> > } else {
> > set_power_wells(power_domains, i9xx_always_on_power_well);
> > }
>
> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
I've pulled in the entire series, but due to the different merge order
please double check that all is fine indeed.
I've also thrown in an additional assert_spin_locked where it seemed to be
missing.
Thanks for patches&review.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 45+ messages in thread* Re: [PATCH v2 21/21] drm/i915: power domains: add vlv power wells
2014-03-06 20:52 ` Daniel Vetter
@ 2014-03-06 21:04 ` Imre Deak
0 siblings, 0 replies; 45+ messages in thread
From: Imre Deak @ 2014-03-06 21:04 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Thu, 2014-03-06 at 21:52 +0100, Daniel Vetter wrote:
> On Thu, Mar 06, 2014 at 12:29:24PM -0800, Jesse Barnes wrote:
> > On Tue, 4 Mar 2014 19:23:10 +0200
> > Imre Deak <imre.deak@intel.com> wrote:
> >
> > > Based on an early draft from Jesse.
> > >
> > > Add support for powering on/off the dynamic power wells on VLV by
> > > registering its display and dpio dynamic power wells with the power
> > > domain framework.
> > >
> > > For now power on all PHY TX lanes regardless of the actual lane
> > > configuration. Later this can be optimized when the PHY side setup
> > > enables only the required lanes. Atm, it enables all lanes in all
> > > cases.
> > >
> > > v2:
> > > - undef function local COND macro after its last use (Ville)
> > > - Take dev_priv->irq_lock around the whole sequence of
> > > intel_set_cpu_fifo_underrun_reporting_nolock() and
> > > valleyview_disable_display_irqs(). They are short and releasing
> > > the lock in between only makes proving correctness more difficult.
> > > - sanitize local var names in vlv_power_well_enabled()
> > >
> > > Signed-off-by: Imre Deak <imre.deak@intel.com>
> > > ---
> > > drivers/gpu/drm/i915/i915_dma.c | 1 -
> > > drivers/gpu/drm/i915/i915_drv.h | 2 +-
> > > drivers/gpu/drm/i915/intel_display.c | 1 +
> > > drivers/gpu/drm/i915/intel_drv.h | 2 +
> > > drivers/gpu/drm/i915/intel_pm.c | 237 +++++++++++++++++++++++++++++++++++
> > > 5 files changed, 241 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> > > index dca4dc3..f8f7a59 100644
> > > --- a/drivers/gpu/drm/i915/i915_dma.c
> > > +++ b/drivers/gpu/drm/i915/i915_dma.c
> > > @@ -1668,7 +1668,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
> > > goto out_mtrrfree;
> > > }
> > >
> > > - dev_priv->display_irqs_enabled = true;
> > > intel_irq_init(dev);
> > > intel_uncore_sanitize(dev);
> > >
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > > index fea0216..3fad6ed 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -1054,7 +1054,7 @@ struct i915_power_well {
> > > /* power well enable/disable usage count */
> > > int count;
> > > unsigned long domains;
> > > - void *data;
> > > + unsigned long data;
> > > const struct i915_power_well_ops *ops;
> > > };
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > > index 6fb40cb..b2eb07a 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -4224,6 +4224,7 @@ static void valleyview_modeset_global_resources(struct drm_device *dev)
> > >
> > > if (req_cdclk != cur_cdclk)
> > > valleyview_set_cdclk(dev, req_cdclk);
> > > + modeset_update_power_wells(dev);
> > > }
> > >
> > > static void valleyview_crtc_enable(struct drm_crtc *crtc)
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > > index afc01a4..f2555ac 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -609,6 +609,8 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
> > > /* i915_irq.c */
> > > bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
> > > enum pipe pipe, bool enable);
> > > +bool intel_set_cpu_fifo_underrun_reporting_nolock(struct drm_device *dev,
> > > + enum pipe pipe, bool enable);
> > > bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
> > > enum transcoder pch_transcoder,
> > > bool enable);
> > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > > index 39acffd..b8b5e3e 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -5356,6 +5356,141 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
> > > return true;
> > > }
> > >
> > > +static void vlv_set_power_well(struct drm_i915_private *dev_priv,
> > > + struct i915_power_well *power_well, bool enable)
> > > +{
> > > + enum punit_power_well power_well_id = power_well->data;
> > > + u32 mask;
> > > + u32 state;
> > > + u32 ctrl;
> > > +
> > > + mask = PUNIT_PWRGT_MASK(power_well_id);
> > > + state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
> > > + PUNIT_PWRGT_PWR_GATE(power_well_id);
> > > +
> > > + mutex_lock(&dev_priv->rps.hw_lock);
> > > +
> > > +#define COND \
> > > + ((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
> > > +
> > > + if (COND)
> > > + goto out;
> > > +
> > > + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL);
> > > + ctrl &= ~mask;
> > > + ctrl |= state;
> > > + vlv_punit_write(dev_priv, PUNIT_REG_PWRGT_CTRL, ctrl);
> > > +
> > > + if (wait_for(COND, 100))
> > > + DRM_ERROR("timout setting power well state %08x (%08x)\n",
> > > + state,
> > > + vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL));
> > > +
> > > +#undef COND
> > > +
> > > +out:
> > > + mutex_unlock(&dev_priv->rps.hw_lock);
> > > +}
> > > +
> > > +static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
> > > + struct i915_power_well *power_well)
> > > +{
> > > + vlv_set_power_well(dev_priv, power_well, power_well->count > 0);
> > > +}
> > > +
> > > +static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
> > > + struct i915_power_well *power_well)
> > > +{
> > > + vlv_set_power_well(dev_priv, power_well, true);
> > > +}
> > > +
> > > +static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
> > > + struct i915_power_well *power_well)
> > > +{
> > > + vlv_set_power_well(dev_priv, power_well, false);
> > > +}
> > > +
> > > +static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
> > > + struct i915_power_well *power_well)
> > > +{
> > > + int power_well_id = power_well->data;
> > > + bool enabled = false;
> > > + u32 mask;
> > > + u32 state;
> > > + u32 ctrl;
> > > +
> > > + mask = PUNIT_PWRGT_MASK(power_well_id);
> > > + ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
> > > +
> > > + mutex_lock(&dev_priv->rps.hw_lock);
> > > +
> > > + state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
> > > + /*
> > > + * We only ever set the power-on and power-gate states, anything
> > > + * else is unexpected.
> > > + */
> > > + WARN_ON(state != PUNIT_PWRGT_PWR_ON(power_well_id) &&
> > > + state != PUNIT_PWRGT_PWR_GATE(power_well_id));
> > > + if (state == ctrl)
> > > + enabled = true;
> > > +
> > > + /*
> > > + * A transient state at this point would mean some unexpected party
> > > + * is poking at the power controls too.
> > > + */
> > > + ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
> > > + WARN_ON(ctrl != state);
> > > +
> > > + mutex_unlock(&dev_priv->rps.hw_lock);
> > > +
> > > + return enabled;
> > > +}
> > > +
> > > +static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
> > > + struct i915_power_well *power_well)
> > > +{
> > > +
> > > + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
> > > +
> > > + vlv_set_power_well(dev_priv, power_well, true);
> > > +
> > > + spin_lock_irq(&dev_priv->irq_lock);
> > > + valleyview_enable_display_irqs(dev_priv);
> > > + spin_unlock_irq(&dev_priv->irq_lock);
> > > +
> > > + /*
> > > + * During driver initialization we need to defer enabling hotplug
> > > + * processing until fbdev is set up.
> > > + */
> > > + if (dev_priv->enable_hotplug_processing)
> > > + intel_hpd_init(dev_priv->dev);
> > > +
> > > + i915_redisable_vga_power_on(dev_priv->dev);
> > > +}
> > > +
> > > +static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
> > > + struct i915_power_well *power_well)
> > > +{
> > > + struct drm_device *dev = dev_priv->dev;
> > > + enum pipe pipe;
> > > +
> > > + WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
> > > +
> > > + spin_lock_irq(&dev_priv->irq_lock);
> > > + for_each_pipe(pipe)
> > > + intel_set_cpu_fifo_underrun_reporting_nolock(dev, pipe, false);
> > > +
> > > + valleyview_disable_display_irqs(dev_priv);
> > > + spin_unlock_irq(&dev_priv->irq_lock);
> > > +
> > > + spin_lock_irq(&dev->vbl_lock);
> > > + for_each_pipe(pipe)
> > > + reset_vblank_counter(dev, pipe);
> > > + spin_unlock_irq(&dev->vbl_lock);
> > > +
> > > + vlv_set_power_well(dev_priv, power_well, false);
> > > +}
> > > +
> > > static void check_power_well_state(struct drm_i915_private *dev_priv,
> > > struct i915_power_well *power_well)
> > > {
> > > @@ -5488,6 +5623,35 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
> > > (POWER_DOMAIN_MASK & ~BDW_ALWAYS_ON_POWER_DOMAINS) | \
> > > BIT(POWER_DOMAIN_INIT))
> > >
> > > +#define VLV_ALWAYS_ON_POWER_DOMAINS BIT(POWER_DOMAIN_INIT)
> > > +#define VLV_DISPLAY_POWER_DOMAINS POWER_DOMAIN_MASK
> > > +
> > > +#define VLV_DPIO_CMN_BC_POWER_DOMAINS ( \
> > > + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
> > > + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> > > + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
> > > + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> > > + BIT(POWER_DOMAIN_PORT_CRT) | \
> > > + BIT(POWER_DOMAIN_INIT))
> > > +
> > > +#define VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS ( \
> > > + BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) | \
> > > + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> > > + BIT(POWER_DOMAIN_INIT))
> > > +
> > > +#define VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS ( \
> > > + BIT(POWER_DOMAIN_PORT_DDI_B_4_LANES) | \
> > > + BIT(POWER_DOMAIN_INIT))
> > > +
> > > +#define VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS ( \
> > > + BIT(POWER_DOMAIN_PORT_DDI_C_2_LANES) | \
> > > + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> > > + BIT(POWER_DOMAIN_INIT))
> > > +
> > > +#define VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS ( \
> > > + BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \
> > > + BIT(POWER_DOMAIN_INIT))
> > > +
> > > static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
> > > .sync_hw = i9xx_always_on_power_well_noop,
> > > .enable = i9xx_always_on_power_well_noop,
> > > @@ -5539,6 +5703,77 @@ static struct i915_power_well bdw_power_wells[] = {
> > > },
> > > };
> > >
> > > +static const struct i915_power_well_ops vlv_display_power_well_ops = {
> > > + .sync_hw = vlv_power_well_sync_hw,
> > > + .enable = vlv_display_power_well_enable,
> > > + .disable = vlv_display_power_well_disable,
> > > + .is_enabled = vlv_power_well_enabled,
> > > +};
> > > +
> > > +static const struct i915_power_well_ops vlv_dpio_power_well_ops = {
> > > + .sync_hw = vlv_power_well_sync_hw,
> > > + .enable = vlv_power_well_enable,
> > > + .disable = vlv_power_well_disable,
> > > + .is_enabled = vlv_power_well_enabled,
> > > +};
> > > +
> > > +static struct i915_power_well vlv_power_wells[] = {
> > > + {
> > > + .name = "always-on",
> > > + .always_on = 1,
> > > + .domains = VLV_ALWAYS_ON_POWER_DOMAINS,
> > > + .ops = &i9xx_always_on_power_well_ops,
> > > + },
> > > + {
> > > + .name = "display",
> > > + .domains = VLV_DISPLAY_POWER_DOMAINS,
> > > + .data = PUNIT_POWER_WELL_DISP2D,
> > > + .ops = &vlv_display_power_well_ops,
> > > + },
> > > + {
> > > + .name = "dpio-common",
> > > + .domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
> > > + .data = PUNIT_POWER_WELL_DPIO_CMN_BC,
> > > + .ops = &vlv_dpio_power_well_ops,
> > > + },
> > > + {
> > > + .name = "dpio-tx-b-01",
> > > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > > + .ops = &vlv_dpio_power_well_ops,
> > > + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_01,
> > > + },
> > > + {
> > > + .name = "dpio-tx-b-23",
> > > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > > + .ops = &vlv_dpio_power_well_ops,
> > > + .data = PUNIT_POWER_WELL_DPIO_TX_B_LANES_23,
> > > + },
> > > + {
> > > + .name = "dpio-tx-c-01",
> > > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > > + .ops = &vlv_dpio_power_well_ops,
> > > + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_01,
> > > + },
> > > + {
> > > + .name = "dpio-tx-c-23",
> > > + .domains = VLV_DPIO_TX_B_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_B_LANES_23_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_01_POWER_DOMAINS |
> > > + VLV_DPIO_TX_C_LANES_23_POWER_DOMAINS,
> > > + .ops = &vlv_dpio_power_well_ops,
> > > + .data = PUNIT_POWER_WELL_DPIO_TX_C_LANES_23,
> > > + },
> > > +};
> > > +
> > > #define set_power_wells(power_domains, __power_wells) ({ \
> > > (power_domains)->power_wells = (__power_wells); \
> > > (power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
> > > @@ -5560,6 +5795,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
> > > } else if (IS_BROADWELL(dev_priv->dev)) {
> > > set_power_wells(power_domains, bdw_power_wells);
> > > hsw_pwr = power_domains;
> > > + } else if (IS_VALLEYVIEW(dev_priv->dev)) {
> > > + set_power_wells(power_domains, vlv_power_wells);
> > > } else {
> > > set_power_wells(power_domains, i9xx_always_on_power_well);
> > > }
> >
> > Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> I've pulled in the entire series, but due to the different merge order
> please double check that all is fine indeed.
>
> I've also thrown in an additional assert_spin_locked where it seemed to be
> missing.
Seems to match my local version, except for the w/s and
assert_spin_locked fixup. Thanks all for the quick review on this.
--Imre
^ permalink raw reply [flat|nested] 45+ messages in thread