Commit 888a2a63 authored by Imre Deak's avatar Imre Deak

drm/i915: Convert the u64 power well domains mask to a bitmap

To remove the aliasing of the power domain enum values in a follow-up
patch in this patchset (requiring a bigger mask) and allow for defining
additional power domains in the future (at least some upcoming TypeC
changes requires this) convert the u64 i915_power_well_desc::domains
mask to a bitmap.

For simplicity I changed the for_each_power_domain_well() macros to
accept one domain only instead of a mask, as there isn't any current
user passing multiple domains.

v2: Don't add a typedef for the bitmap struct. (Jani)

Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarJouni Högander <jouni.hogander@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220414210657.1785773-9-imre.deak@intel.com
parent c32ffce4
...@@ -2244,66 +2244,71 @@ intel_legacy_aux_to_power_domain(enum aux_ch aux_ch) ...@@ -2244,66 +2244,71 @@ intel_legacy_aux_to_power_domain(enum aux_ch aux_ch)
} }
} }
static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state) static void get_crtc_power_domains(struct intel_crtc_state *crtc_state,
struct intel_power_domain_mask *mask)
{ {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
struct drm_encoder *encoder; struct drm_encoder *encoder;
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
u64 mask;
bitmap_zero(mask->bits, POWER_DOMAIN_NUM);
if (!crtc_state->hw.active) if (!crtc_state->hw.active)
return 0; return;
mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe)); set_bit(POWER_DOMAIN_PIPE(pipe), mask->bits);
mask |= BIT_ULL(POWER_DOMAIN_TRANSCODER(cpu_transcoder)); set_bit(POWER_DOMAIN_TRANSCODER(cpu_transcoder), mask->bits);
if (crtc_state->pch_pfit.enabled || if (crtc_state->pch_pfit.enabled ||
crtc_state->pch_pfit.force_thru) crtc_state->pch_pfit.force_thru)
mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe)); set_bit(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe), mask->bits);
drm_for_each_encoder_mask(encoder, &dev_priv->drm, drm_for_each_encoder_mask(encoder, &dev_priv->drm,
crtc_state->uapi.encoder_mask) { crtc_state->uapi.encoder_mask) {
struct intel_encoder *intel_encoder = to_intel_encoder(encoder); struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
mask |= BIT_ULL(intel_encoder->power_domain); set_bit(intel_encoder->power_domain, mask->bits);
} }
if (HAS_DDI(dev_priv) && crtc_state->has_audio) if (HAS_DDI(dev_priv) && crtc_state->has_audio)
mask |= BIT_ULL(POWER_DOMAIN_AUDIO_MMIO); set_bit(POWER_DOMAIN_AUDIO_MMIO, mask->bits);
if (crtc_state->shared_dpll) if (crtc_state->shared_dpll)
mask |= BIT_ULL(POWER_DOMAIN_DISPLAY_CORE); set_bit(POWER_DOMAIN_DISPLAY_CORE, mask->bits);
if (crtc_state->dsc.compression_enable) if (crtc_state->dsc.compression_enable)
mask |= BIT_ULL(intel_dsc_power_domain(crtc, cpu_transcoder)); set_bit(intel_dsc_power_domain(crtc, cpu_transcoder), mask->bits);
return mask;
} }
static u64 static void
modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state) modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
struct intel_power_domain_mask *old_domains)
{ {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum intel_display_power_domain domain; enum intel_display_power_domain domain;
u64 domains, new_domains, old_domains; struct intel_power_domain_mask domains, new_domains;
domains = get_crtc_power_domains(crtc_state); get_crtc_power_domains(crtc_state, &domains);
new_domains = domains & ~crtc->enabled_power_domains.mask; bitmap_andnot(new_domains.bits,
old_domains = crtc->enabled_power_domains.mask & ~domains; domains.bits,
crtc->enabled_power_domains.mask.bits,
POWER_DOMAIN_NUM);
bitmap_andnot(old_domains->bits,
crtc->enabled_power_domains.mask.bits,
domains.bits,
POWER_DOMAIN_NUM);
for_each_power_domain(domain, new_domains) for_each_power_domain(domain, &new_domains)
intel_display_power_get_in_set(dev_priv, intel_display_power_get_in_set(dev_priv,
&crtc->enabled_power_domains, &crtc->enabled_power_domains,
domain); domain);
return old_domains;
} }
static void modeset_put_crtc_power_domains(struct intel_crtc *crtc, static void modeset_put_crtc_power_domains(struct intel_crtc *crtc,
u64 domains) struct intel_power_domain_mask *domains)
{ {
intel_display_power_put_mask_in_set(to_i915(crtc->base.dev), intel_display_power_put_mask_in_set(to_i915(crtc->base.dev),
&crtc->enabled_power_domains, &crtc->enabled_power_domains,
...@@ -8505,7 +8510,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) ...@@ -8505,7 +8510,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc_state *new_crtc_state, *old_crtc_state;
struct intel_crtc *crtc; struct intel_crtc *crtc;
u64 put_domains[I915_MAX_PIPES] = {}; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {};
intel_wakeref_t wakeref = 0; intel_wakeref_t wakeref = 0;
int i; int i;
...@@ -8522,9 +8527,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) ...@@ -8522,9 +8527,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
new_crtc_state, i) { new_crtc_state, i) {
if (intel_crtc_needs_modeset(new_crtc_state) || if (intel_crtc_needs_modeset(new_crtc_state) ||
new_crtc_state->update_pipe) { new_crtc_state->update_pipe) {
modeset_get_crtc_power_domains(new_crtc_state, &put_domains[crtc->pipe]);
put_domains[crtc->pipe] =
modeset_get_crtc_power_domains(new_crtc_state);
} }
} }
...@@ -8624,7 +8627,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) ...@@ -8624,7 +8627,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
intel_post_plane_update(state, crtc); intel_post_plane_update(state, crtc);
modeset_put_crtc_power_domains(crtc, put_domains[crtc->pipe]); modeset_put_crtc_power_domains(crtc, &put_domains[crtc->pipe]);
intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state); intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state);
...@@ -10465,11 +10468,11 @@ intel_modeset_setup_hw_state(struct drm_device *dev, ...@@ -10465,11 +10468,11 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
for_each_intel_crtc(dev, crtc) { for_each_intel_crtc(dev, crtc) {
struct intel_crtc_state *crtc_state = struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state); to_intel_crtc_state(crtc->base.state);
u64 put_domains; struct intel_power_domain_mask put_domains;
put_domains = modeset_get_crtc_power_domains(crtc_state); modeset_get_crtc_power_domains(crtc_state, &put_domains);
if (drm_WARN_ON(dev, put_domains)) if (drm_WARN_ON(dev, !bitmap_empty(put_domains.bits, POWER_DOMAIN_NUM)))
modeset_put_crtc_power_domains(crtc, put_domains); modeset_put_crtc_power_domains(crtc, &put_domains);
} }
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
......
...@@ -22,13 +22,13 @@ ...@@ -22,13 +22,13 @@
#include "intel_snps_phy.h" #include "intel_snps_phy.h"
#include "vlv_sideband.h" #include "vlv_sideband.h"
#define for_each_power_domain_well(__dev_priv, __power_well, __domain_mask) \ #define for_each_power_domain_well(__dev_priv, __power_well, __domain) \
for_each_power_well(__dev_priv, __power_well) \ for_each_power_well(__dev_priv, __power_well) \
for_each_if((__power_well)->domains & (__domain_mask)) for_each_if(test_bit((__domain), (__power_well)->domains.bits))
#define for_each_power_domain_well_reverse(__dev_priv, __power_well, __domain_mask) \ #define for_each_power_domain_well_reverse(__dev_priv, __power_well, __domain) \
for_each_power_well_reverse(__dev_priv, __power_well) \ for_each_power_well_reverse(__dev_priv, __power_well) \
for_each_if((__power_well)->domains & (__domain_mask)) for_each_if(test_bit((__domain), (__power_well)->domains.bits))
const char * const char *
intel_display_power_domain_str(enum intel_display_power_domain domain) intel_display_power_domain_str(enum intel_display_power_domain domain)
...@@ -191,7 +191,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, ...@@ -191,7 +191,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
is_enabled = true; is_enabled = true;
for_each_power_domain_well_reverse(dev_priv, power_well, BIT_ULL(domain)) { for_each_power_domain_well_reverse(dev_priv, power_well, domain) {
if (intel_power_well_is_always_on(power_well)) if (intel_power_well_is_always_on(power_well))
continue; continue;
...@@ -307,10 +307,13 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv, ...@@ -307,10 +307,13 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv,
#define POWER_DOMAIN_MASK (GENMASK_ULL(POWER_DOMAIN_NUM - 1, 0)) #define POWER_DOMAIN_MASK (GENMASK_ULL(POWER_DOMAIN_NUM - 1, 0))
static u64 __async_put_domains_mask(struct i915_power_domains *power_domains) static void __async_put_domains_mask(struct i915_power_domains *power_domains,
struct intel_power_domain_mask *mask)
{ {
return power_domains->async_put_domains[0] | bitmap_or(mask->bits,
power_domains->async_put_domains[1]; power_domains->async_put_domains[0].bits,
power_domains->async_put_domains[1].bits,
POWER_DOMAIN_NUM);
} }
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
...@@ -321,8 +324,11 @@ assert_async_put_domain_masks_disjoint(struct i915_power_domains *power_domains) ...@@ -321,8 +324,11 @@ assert_async_put_domain_masks_disjoint(struct i915_power_domains *power_domains)
struct drm_i915_private *i915 = container_of(power_domains, struct drm_i915_private *i915 = container_of(power_domains,
struct drm_i915_private, struct drm_i915_private,
power_domains); power_domains);
return !drm_WARN_ON(&i915->drm, power_domains->async_put_domains[0] &
power_domains->async_put_domains[1]); return !drm_WARN_ON(&i915->drm,
bitmap_intersects(power_domains->async_put_domains[0].bits,
power_domains->async_put_domains[1].bits,
POWER_DOMAIN_NUM));
} }
static bool static bool
...@@ -331,14 +337,17 @@ __async_put_domains_state_ok(struct i915_power_domains *power_domains) ...@@ -331,14 +337,17 @@ __async_put_domains_state_ok(struct i915_power_domains *power_domains)
struct drm_i915_private *i915 = container_of(power_domains, struct drm_i915_private *i915 = container_of(power_domains,
struct drm_i915_private, struct drm_i915_private,
power_domains); power_domains);
struct intel_power_domain_mask async_put_mask;
enum intel_display_power_domain domain; enum intel_display_power_domain domain;
bool err = false; bool err = false;
err |= !assert_async_put_domain_masks_disjoint(power_domains); err |= !assert_async_put_domain_masks_disjoint(power_domains);
err |= drm_WARN_ON(&i915->drm, !!power_domains->async_put_wakeref != __async_put_domains_mask(power_domains, &async_put_mask);
!!__async_put_domains_mask(power_domains)); err |= drm_WARN_ON(&i915->drm,
!!power_domains->async_put_wakeref !=
!bitmap_empty(async_put_mask.bits, POWER_DOMAIN_NUM));
for_each_power_domain(domain, __async_put_domains_mask(power_domains)) for_each_power_domain(domain, &async_put_mask)
err |= drm_WARN_ON(&i915->drm, err |= drm_WARN_ON(&i915->drm,
power_domains->domain_use_count[domain] != 1); power_domains->domain_use_count[domain] != 1);
...@@ -346,14 +355,14 @@ __async_put_domains_state_ok(struct i915_power_domains *power_domains) ...@@ -346,14 +355,14 @@ __async_put_domains_state_ok(struct i915_power_domains *power_domains)
} }
static void print_power_domains(struct i915_power_domains *power_domains, static void print_power_domains(struct i915_power_domains *power_domains,
const char *prefix, u64 mask) const char *prefix, struct intel_power_domain_mask *mask)
{ {
struct drm_i915_private *i915 = container_of(power_domains, struct drm_i915_private *i915 = container_of(power_domains,
struct drm_i915_private, struct drm_i915_private,
power_domains); power_domains);
enum intel_display_power_domain domain; enum intel_display_power_domain domain;
drm_dbg(&i915->drm, "%s (%lu):\n", prefix, hweight64(mask)); drm_dbg(&i915->drm, "%s (%d):\n", prefix, bitmap_weight(mask->bits, POWER_DOMAIN_NUM));
for_each_power_domain(domain, mask) for_each_power_domain(domain, mask)
drm_dbg(&i915->drm, "%s use_count %d\n", drm_dbg(&i915->drm, "%s use_count %d\n",
intel_display_power_domain_str(domain), intel_display_power_domain_str(domain),
...@@ -371,9 +380,9 @@ print_async_put_domains_state(struct i915_power_domains *power_domains) ...@@ -371,9 +380,9 @@ print_async_put_domains_state(struct i915_power_domains *power_domains)
power_domains->async_put_wakeref); power_domains->async_put_wakeref);
print_power_domains(power_domains, "async_put_domains[0]", print_power_domains(power_domains, "async_put_domains[0]",
power_domains->async_put_domains[0]); &power_domains->async_put_domains[0]);
print_power_domains(power_domains, "async_put_domains[1]", print_power_domains(power_domains, "async_put_domains[1]",
power_domains->async_put_domains[1]); &power_domains->async_put_domains[1]);
} }
static void static void
...@@ -397,11 +406,13 @@ verify_async_put_domains_state(struct i915_power_domains *power_domains) ...@@ -397,11 +406,13 @@ verify_async_put_domains_state(struct i915_power_domains *power_domains)
#endif /* CONFIG_DRM_I915_DEBUG_RUNTIME_PM */ #endif /* CONFIG_DRM_I915_DEBUG_RUNTIME_PM */
static u64 async_put_domains_mask(struct i915_power_domains *power_domains) static void async_put_domains_mask(struct i915_power_domains *power_domains,
struct intel_power_domain_mask *mask)
{ {
assert_async_put_domain_masks_disjoint(power_domains); assert_async_put_domain_masks_disjoint(power_domains);
return __async_put_domains_mask(power_domains); __async_put_domains_mask(power_domains, mask);
} }
static void static void
...@@ -410,8 +421,8 @@ async_put_domains_clear_domain(struct i915_power_domains *power_domains, ...@@ -410,8 +421,8 @@ async_put_domains_clear_domain(struct i915_power_domains *power_domains,
{ {
assert_async_put_domain_masks_disjoint(power_domains); assert_async_put_domain_masks_disjoint(power_domains);
power_domains->async_put_domains[0] &= ~BIT_ULL(domain); clear_bit(domain, power_domains->async_put_domains[0].bits);
power_domains->async_put_domains[1] &= ~BIT_ULL(domain); clear_bit(domain, power_domains->async_put_domains[1].bits);
} }
static bool static bool
...@@ -419,16 +430,19 @@ intel_display_power_grab_async_put_ref(struct drm_i915_private *dev_priv, ...@@ -419,16 +430,19 @@ intel_display_power_grab_async_put_ref(struct drm_i915_private *dev_priv,
enum intel_display_power_domain domain) enum intel_display_power_domain domain)
{ {
struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct intel_power_domain_mask async_put_mask;
bool ret = false; bool ret = false;
if (!(async_put_domains_mask(power_domains) & BIT_ULL(domain))) async_put_domains_mask(power_domains, &async_put_mask);
if (!test_bit(domain, async_put_mask.bits))
goto out_verify; goto out_verify;
async_put_domains_clear_domain(power_domains, domain); async_put_domains_clear_domain(power_domains, domain);
ret = true; ret = true;
if (async_put_domains_mask(power_domains)) async_put_domains_mask(power_domains, &async_put_mask);
if (!bitmap_empty(async_put_mask.bits, POWER_DOMAIN_NUM))
goto out_verify; goto out_verify;
cancel_delayed_work(&power_domains->async_put_work); cancel_delayed_work(&power_domains->async_put_work);
...@@ -450,7 +464,7 @@ __intel_display_power_get_domain(struct drm_i915_private *dev_priv, ...@@ -450,7 +464,7 @@ __intel_display_power_get_domain(struct drm_i915_private *dev_priv,
if (intel_display_power_grab_async_put_ref(dev_priv, domain)) if (intel_display_power_grab_async_put_ref(dev_priv, domain))
return; return;
for_each_power_domain_well(dev_priv, power_well, BIT_ULL(domain)) for_each_power_domain_well(dev_priv, power_well, domain)
intel_power_well_get(dev_priv, power_well); intel_power_well_get(dev_priv, power_well);
power_domains->domain_use_count[domain]++; power_domains->domain_use_count[domain]++;
...@@ -531,20 +545,22 @@ __intel_display_power_put_domain(struct drm_i915_private *dev_priv, ...@@ -531,20 +545,22 @@ __intel_display_power_put_domain(struct drm_i915_private *dev_priv,
struct i915_power_domains *power_domains; struct i915_power_domains *power_domains;
struct i915_power_well *power_well; struct i915_power_well *power_well;
const char *name = intel_display_power_domain_str(domain); const char *name = intel_display_power_domain_str(domain);
struct intel_power_domain_mask async_put_mask;
power_domains = &dev_priv->power_domains; power_domains = &dev_priv->power_domains;
drm_WARN(&dev_priv->drm, !power_domains->domain_use_count[domain], drm_WARN(&dev_priv->drm, !power_domains->domain_use_count[domain],
"Use count on domain %s is already zero\n", "Use count on domain %s is already zero\n",
name); name);
async_put_domains_mask(power_domains, &async_put_mask);
drm_WARN(&dev_priv->drm, drm_WARN(&dev_priv->drm,
async_put_domains_mask(power_domains) & BIT_ULL(domain), test_bit(domain, async_put_mask.bits),
"Async disabling of domain %s is pending\n", "Async disabling of domain %s is pending\n",
name); name);
power_domains->domain_use_count[domain]--; power_domains->domain_use_count[domain]--;
for_each_power_domain_well_reverse(dev_priv, power_well, BIT_ULL(domain)) for_each_power_domain_well_reverse(dev_priv, power_well, domain)
intel_power_well_put(dev_priv, power_well); intel_power_well_put(dev_priv, power_well);
} }
...@@ -573,7 +589,8 @@ queue_async_put_domains_work(struct i915_power_domains *power_domains, ...@@ -573,7 +589,8 @@ queue_async_put_domains_work(struct i915_power_domains *power_domains,
} }
static void static void
release_async_put_domains(struct i915_power_domains *power_domains, u64 mask) release_async_put_domains(struct i915_power_domains *power_domains,
struct intel_power_domain_mask *mask)
{ {
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
container_of(power_domains, struct drm_i915_private, container_of(power_domains, struct drm_i915_private,
...@@ -621,12 +638,15 @@ intel_display_power_put_async_work(struct work_struct *work) ...@@ -621,12 +638,15 @@ intel_display_power_put_async_work(struct work_struct *work)
goto out_verify; goto out_verify;
release_async_put_domains(power_domains, release_async_put_domains(power_domains,
power_domains->async_put_domains[0]); &power_domains->async_put_domains[0]);
/* Requeue the work if more domains were async put meanwhile. */ /* Requeue the work if more domains were async put meanwhile. */
if (power_domains->async_put_domains[1]) { if (!bitmap_empty(power_domains->async_put_domains[1].bits, POWER_DOMAIN_NUM)) {
power_domains->async_put_domains[0] = bitmap_copy(power_domains->async_put_domains[0].bits,
fetch_and_zero(&power_domains->async_put_domains[1]); power_domains->async_put_domains[1].bits,
POWER_DOMAIN_NUM);
bitmap_zero(power_domains->async_put_domains[1].bits,
POWER_DOMAIN_NUM);
queue_async_put_domains_work(power_domains, queue_async_put_domains_work(power_domains,
fetch_and_zero(&new_work_wakeref)); fetch_and_zero(&new_work_wakeref));
} else { } else {
...@@ -678,9 +698,9 @@ void __intel_display_power_put_async(struct drm_i915_private *i915, ...@@ -678,9 +698,9 @@ void __intel_display_power_put_async(struct drm_i915_private *i915,
/* Let a pending work requeue itself or queue a new one. */ /* Let a pending work requeue itself or queue a new one. */
if (power_domains->async_put_wakeref) { if (power_domains->async_put_wakeref) {
power_domains->async_put_domains[1] |= BIT_ULL(domain); set_bit(domain, power_domains->async_put_domains[1].bits);
} else { } else {
power_domains->async_put_domains[0] |= BIT_ULL(domain); set_bit(domain, power_domains->async_put_domains[0].bits);
queue_async_put_domains_work(power_domains, queue_async_put_domains_work(power_domains,
fetch_and_zero(&work_wakeref)); fetch_and_zero(&work_wakeref));
} }
...@@ -711,6 +731,7 @@ void __intel_display_power_put_async(struct drm_i915_private *i915, ...@@ -711,6 +731,7 @@ void __intel_display_power_put_async(struct drm_i915_private *i915,
void intel_display_power_flush_work(struct drm_i915_private *i915) void intel_display_power_flush_work(struct drm_i915_private *i915)
{ {
struct i915_power_domains *power_domains = &i915->power_domains; struct i915_power_domains *power_domains = &i915->power_domains;
struct intel_power_domain_mask async_put_mask;
intel_wakeref_t work_wakeref; intel_wakeref_t work_wakeref;
mutex_lock(&power_domains->lock); mutex_lock(&power_domains->lock);
...@@ -719,8 +740,8 @@ void intel_display_power_flush_work(struct drm_i915_private *i915) ...@@ -719,8 +740,8 @@ void intel_display_power_flush_work(struct drm_i915_private *i915)
if (!work_wakeref) if (!work_wakeref)
goto out_verify; goto out_verify;
release_async_put_domains(power_domains, async_put_domains_mask(power_domains, &async_put_mask);
async_put_domains_mask(power_domains)); release_async_put_domains(power_domains, &async_put_mask);
cancel_delayed_work(&power_domains->async_put_work); cancel_delayed_work(&power_domains->async_put_work);
out_verify: out_verify:
...@@ -799,13 +820,13 @@ intel_display_power_get_in_set(struct drm_i915_private *i915, ...@@ -799,13 +820,13 @@ intel_display_power_get_in_set(struct drm_i915_private *i915,
{ {
intel_wakeref_t __maybe_unused wf; intel_wakeref_t __maybe_unused wf;
drm_WARN_ON(&i915->drm, power_domain_set->mask & BIT_ULL(domain)); drm_WARN_ON(&i915->drm, test_bit(domain, power_domain_set->mask.bits));
wf = intel_display_power_get(i915, domain); wf = intel_display_power_get(i915, domain);
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
power_domain_set->wakerefs[domain] = wf; power_domain_set->wakerefs[domain] = wf;
#endif #endif
power_domain_set->mask |= BIT_ULL(domain); set_bit(domain, power_domain_set->mask.bits);
} }
bool bool
...@@ -815,7 +836,7 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, ...@@ -815,7 +836,7 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
{ {
intel_wakeref_t wf; intel_wakeref_t wf;
drm_WARN_ON(&i915->drm, power_domain_set->mask & BIT_ULL(domain)); drm_WARN_ON(&i915->drm, test_bit(domain, power_domain_set->mask.bits));
wf = intel_display_power_get_if_enabled(i915, domain); wf = intel_display_power_get_if_enabled(i915, domain);
if (!wf) if (!wf)
...@@ -824,7 +845,7 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, ...@@ -824,7 +845,7 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
power_domain_set->wakerefs[domain] = wf; power_domain_set->wakerefs[domain] = wf;
#endif #endif
power_domain_set->mask |= BIT_ULL(domain); set_bit(domain, power_domain_set->mask.bits);
return true; return true;
} }
...@@ -832,11 +853,12 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, ...@@ -832,11 +853,12 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
void void
intel_display_power_put_mask_in_set(struct drm_i915_private *i915, intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set, struct intel_display_power_domain_set *power_domain_set,
u64 mask) struct intel_power_domain_mask *mask)
{ {
enum intel_display_power_domain domain; enum intel_display_power_domain domain;
drm_WARN_ON(&i915->drm, mask & ~power_domain_set->mask); drm_WARN_ON(&i915->drm,
!bitmap_subset(mask->bits, power_domain_set->mask.bits, POWER_DOMAIN_NUM));
for_each_power_domain(domain, mask) { for_each_power_domain(domain, mask) {
intel_wakeref_t __maybe_unused wf = -1; intel_wakeref_t __maybe_unused wf = -1;
...@@ -845,7 +867,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915, ...@@ -845,7 +867,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
wf = fetch_and_zero(&power_domain_set->wakerefs[domain]); wf = fetch_and_zero(&power_domain_set->wakerefs[domain]);
#endif #endif
intel_display_power_put(i915, domain, wf); intel_display_power_put(i915, domain, wf);
power_domain_set->mask &= ~BIT_ULL(domain); clear_bit(domain, power_domain_set->mask.bits);
} }
} }
...@@ -947,8 +969,6 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) ...@@ -947,8 +969,6 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
dev_priv->dmc.target_dc_state = dev_priv->dmc.target_dc_state =
sanitize_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); sanitize_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
BUILD_BUG_ON(POWER_DOMAIN_NUM > 64);
mutex_init(&power_domains->lock); mutex_init(&power_domains->lock);
INIT_DELAYED_WORK(&power_domains->async_put_work, INIT_DELAYED_WORK(&power_domains->async_put_work,
......
...@@ -139,6 +139,10 @@ enum intel_display_power_domain { ...@@ -139,6 +139,10 @@ enum intel_display_power_domain {
((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \ ((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
(tran) + POWER_DOMAIN_TRANSCODER_A) (tran) + POWER_DOMAIN_TRANSCODER_A)
struct intel_power_domain_mask {
DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);
};
struct i915_power_domains { struct i915_power_domains {
/* /*
* Power wells needed for initialization at driver init and suspend * Power wells needed for initialization at driver init and suspend
...@@ -156,21 +160,21 @@ struct i915_power_domains { ...@@ -156,21 +160,21 @@ struct i915_power_domains {
struct delayed_work async_put_work; struct delayed_work async_put_work;
intel_wakeref_t async_put_wakeref; intel_wakeref_t async_put_wakeref;
u64 async_put_domains[2]; struct intel_power_domain_mask async_put_domains[2];
struct i915_power_well *power_wells; struct i915_power_well *power_wells;
}; };
struct intel_display_power_domain_set { struct intel_display_power_domain_set {
u64 mask; struct intel_power_domain_mask mask;
#ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM #ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM
intel_wakeref_t wakerefs[POWER_DOMAIN_NUM]; intel_wakeref_t wakerefs[POWER_DOMAIN_NUM];
#endif #endif
}; };
#define for_each_power_domain(domain, mask) \ #define for_each_power_domain(__domain, __mask) \
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \ for ((__domain) = 0; (__domain) < POWER_DOMAIN_NUM; (__domain)++) \
for_each_if(BIT_ULL(domain) & (mask)) for_each_if(test_bit((__domain), (__mask)->bits))
int intel_power_domains_init(struct drm_i915_private *dev_priv); int intel_power_domains_init(struct drm_i915_private *dev_priv);
void intel_power_domains_cleanup(struct drm_i915_private *dev_priv); void intel_power_domains_cleanup(struct drm_i915_private *dev_priv);
...@@ -251,13 +255,13 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915, ...@@ -251,13 +255,13 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
void void
intel_display_power_put_mask_in_set(struct drm_i915_private *i915, intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set, struct intel_display_power_domain_set *power_domain_set,
u64 mask); struct intel_power_domain_mask *mask);
static inline void static inline void
intel_display_power_put_all_in_set(struct drm_i915_private *i915, intel_display_power_put_all_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set) struct intel_display_power_domain_set *power_domain_set)
{ {
intel_display_power_put_mask_in_set(i915, power_domain_set, power_domain_set->mask); intel_display_power_put_mask_in_set(i915, power_domain_set, &power_domain_set->mask);
} }
void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m); void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m);
......
...@@ -2084,13 +2084,13 @@ static void init_power_well_domains(const struct i915_power_well_desc *desc, ...@@ -2084,13 +2084,13 @@ static void init_power_well_domains(const struct i915_power_well_desc *desc,
return; return;
if (desc->domain_list->count == 0) { if (desc->domain_list->count == 0) {
power_well->domains = GENMASK_ULL(POWER_DOMAIN_NUM - 1, 0); bitmap_fill(power_well->domains.bits, POWER_DOMAIN_NUM);
return; return;
} }
for (j = 0; j < desc->domain_list->count; j++) for (j = 0; j < desc->domain_list->count; j++)
power_well->domains |= BIT_ULL(desc->domain_list->list[j]); set_bit(desc->domain_list->list[j], power_well->domains.bits);
} }
static int static int
......
...@@ -154,9 +154,9 @@ const char *intel_power_well_name(struct i915_power_well *power_well) ...@@ -154,9 +154,9 @@ const char *intel_power_well_name(struct i915_power_well *power_well)
return power_well->desc->name; return power_well->desc->name;
} }
u64 intel_power_well_domains(struct i915_power_well *power_well) struct intel_power_domain_mask *intel_power_well_domains(struct i915_power_well *power_well)
{ {
return power_well->domains; return &power_well->domains;
} }
int intel_power_well_refcount(struct i915_power_well *power_well) int intel_power_well_refcount(struct i915_power_well *power_well)
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#include "intel_display.h" #include "intel_display.h"
#include "intel_display_power.h"
struct drm_i915_private; struct drm_i915_private;
struct i915_power_well; struct i915_power_well;
...@@ -102,7 +103,7 @@ struct i915_power_well_desc { ...@@ -102,7 +103,7 @@ struct i915_power_well_desc {
struct i915_power_well { struct i915_power_well {
const struct i915_power_well_desc *desc; const struct i915_power_well_desc *desc;
u64 domains; struct intel_power_domain_mask domains;
/* power well enable/disable usage count */ /* power well enable/disable usage count */
int count; int count;
/* cached hw enabled state */ /* cached hw enabled state */
...@@ -129,7 +130,7 @@ bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, ...@@ -129,7 +130,7 @@ bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
enum i915_power_well_id power_well_id); enum i915_power_well_id power_well_id);
bool intel_power_well_is_always_on(struct i915_power_well *power_well); bool intel_power_well_is_always_on(struct i915_power_well *power_well);
const char *intel_power_well_name(struct i915_power_well *power_well); const char *intel_power_well_name(struct i915_power_well *power_well);
u64 intel_power_well_domains(struct i915_power_well *power_well); struct intel_power_domain_mask *intel_power_well_domains(struct i915_power_well *power_well);
int intel_power_well_refcount(struct i915_power_well *power_well); int intel_power_well_refcount(struct i915_power_well *power_well);
void chv_phy_powergate_lanes(struct intel_encoder *encoder, void chv_phy_powergate_lanes(struct intel_encoder *encoder,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment