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);
......
...@@ -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