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)
}
}
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 drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
struct drm_encoder *encoder;
enum pipe pipe = crtc->pipe;
u64 mask;
bitmap_zero(mask->bits, POWER_DOMAIN_NUM);
if (!crtc_state->hw.active)
return 0;
return;
mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe));
mask |= BIT_ULL(POWER_DOMAIN_TRANSCODER(cpu_transcoder));
set_bit(POWER_DOMAIN_PIPE(pipe), mask->bits);
set_bit(POWER_DOMAIN_TRANSCODER(cpu_transcoder), mask->bits);
if (crtc_state->pch_pfit.enabled ||
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,
crtc_state->uapi.encoder_mask) {
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)
mask |= BIT_ULL(POWER_DOMAIN_AUDIO_MMIO);
set_bit(POWER_DOMAIN_AUDIO_MMIO, mask->bits);
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)
mask |= BIT_ULL(intel_dsc_power_domain(crtc, cpu_transcoder));
return mask;
set_bit(intel_dsc_power_domain(crtc, cpu_transcoder), mask->bits);
}
static u64
modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state)
static void
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 drm_i915_private *dev_priv = to_i915(crtc->base.dev);
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;
old_domains = crtc->enabled_power_domains.mask & ~domains;
bitmap_andnot(new_domains.bits,
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,
&crtc->enabled_power_domains,
domain);
return old_domains;
}
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),
&crtc->enabled_power_domains,
......@@ -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 intel_crtc_state *new_crtc_state, *old_crtc_state;
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;
int i;
......@@ -8522,9 +8527,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
new_crtc_state, i) {
if (intel_crtc_needs_modeset(new_crtc_state) ||
new_crtc_state->update_pipe) {
put_domains[crtc->pipe] =
modeset_get_crtc_power_domains(new_crtc_state);
modeset_get_crtc_power_domains(new_crtc_state, &put_domains[crtc->pipe]);
}
}
......@@ -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) {
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);
......@@ -10465,11 +10468,11 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
for_each_intel_crtc(dev, crtc) {
struct intel_crtc_state *crtc_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);
if (drm_WARN_ON(dev, put_domains))
modeset_put_crtc_power_domains(crtc, put_domains);
modeset_get_crtc_power_domains(crtc_state, &put_domains);
if (drm_WARN_ON(dev, !bitmap_empty(put_domains.bits, POWER_DOMAIN_NUM)))
modeset_put_crtc_power_domains(crtc, &put_domains);
}
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
......
......@@ -139,6 +139,10 @@ enum intel_display_power_domain {
((tran) == TRANSCODER_EDP ? POWER_DOMAIN_TRANSCODER_EDP : \
(tran) + POWER_DOMAIN_TRANSCODER_A)
struct intel_power_domain_mask {
DECLARE_BITMAP(bits, POWER_DOMAIN_NUM);
};
struct i915_power_domains {
/*
* Power wells needed for initialization at driver init and suspend
......@@ -156,21 +160,21 @@ struct i915_power_domains {
struct delayed_work async_put_work;
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 intel_display_power_domain_set {
u64 mask;
struct intel_power_domain_mask mask;
#ifdef CONFIG_DRM_I915_DEBUG_RUNTIME_PM
intel_wakeref_t wakerefs[POWER_DOMAIN_NUM];
#endif
};
#define for_each_power_domain(domain, mask) \
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
for_each_if(BIT_ULL(domain) & (mask))
#define for_each_power_domain(__domain, __mask) \
for ((__domain) = 0; (__domain) < POWER_DOMAIN_NUM; (__domain)++) \
for_each_if(test_bit((__domain), (__mask)->bits))
int intel_power_domains_init(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,
void
intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
struct intel_display_power_domain_set *power_domain_set,
u64 mask);
struct intel_power_domain_mask *mask);
static inline void
intel_display_power_put_all_in_set(struct drm_i915_private *i915,
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);
......
......@@ -2084,13 +2084,13 @@ static void init_power_well_domains(const struct i915_power_well_desc *desc,
return;
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;
}
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
......
......@@ -154,9 +154,9 @@ const char *intel_power_well_name(struct i915_power_well *power_well)
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)
......
......@@ -8,6 +8,7 @@
#include <linux/types.h>
#include "intel_display.h"
#include "intel_display_power.h"
struct drm_i915_private;
struct i915_power_well;
......@@ -102,7 +103,7 @@ struct i915_power_well_desc {
struct i915_power_well {
const struct i915_power_well_desc *desc;
u64 domains;
struct intel_power_domain_mask domains;
/* power well enable/disable usage count */
int count;
/* cached hw enabled state */
......@@ -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);
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);
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);
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