summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_pps.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_pps.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.c95
1 files changed, 51 insertions, 44 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
index ffeee9daa568..093fe37a3983 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -29,10 +29,9 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd
static const char *pps_name(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_pps *pps = &intel_dp->pps;
- if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
+ if (display->platform.valleyview || display->platform.cherryview) {
switch (pps->vlv_pps_pipe) {
case INVALID_PIPE:
/*
@@ -122,7 +121,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
DP |= DP_PORT_WIDTH(1);
DP |= DP_LINK_TRAIN_PAT_1;
- if (IS_CHERRYVIEW(dev_priv))
+ if (display->platform.cherryview)
DP |= DP_PIPE_SEL_CHV(pipe);
else
DP |= DP_PIPE_SEL(pipe);
@@ -134,7 +133,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
* So enable temporarily it if it's not already enabled.
*/
if (!pll_enabled) {
- release_cl_override = IS_CHERRYVIEW(dev_priv) &&
+ release_cl_override = display->platform.cherryview &&
!chv_phy_powergate_ch(dev_priv, phy, ch, true);
if (vlv_force_pll_on(dev_priv, pipe, vlv_get_dpll(dev_priv))) {
@@ -356,10 +355,10 @@ static int intel_num_pps(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
- if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
+ if (display->platform.valleyview || display->platform.cherryview)
return 2;
- if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
+ if (display->platform.geminilake || display->platform.broxton)
return 2;
if (INTEL_PCH_TYPE(i915) >= PCH_MTL)
@@ -406,11 +405,10 @@ pps_initial_setup(struct intel_dp *intel_dp)
struct intel_display *display = to_intel_display(intel_dp);
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct intel_connector *connector = intel_dp->attached_connector;
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
lockdep_assert_held(&display->pps.mutex);
- if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
+ if (display->platform.valleyview || display->platform.cherryview) {
vlv_initial_power_sequencer_setup(intel_dp);
return true;
}
@@ -509,9 +507,9 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
memset(regs, 0, sizeof(*regs));
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ if (display->platform.valleyview || display->platform.cherryview)
pps_idx = vlv_power_sequencer_pipe(intel_dp);
- else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
+ else if (display->platform.geminilake || display->platform.broxton)
pps_idx = bxt_power_sequencer_idx(intel_dp);
else
pps_idx = intel_dp->pps.pps_idx;
@@ -522,7 +520,7 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
regs->pp_off = PP_OFF_DELAYS(display, pps_idx);
/* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
- if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ||
+ if (display->platform.geminilake || display->platform.broxton ||
INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
regs->pp_div = INVALID_MMIO_REG;
else
@@ -552,11 +550,10 @@ _pp_stat_reg(struct intel_dp *intel_dp)
static bool edp_have_panel_power(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&display->pps.mutex);
- if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
+ if ((display->platform.valleyview || display->platform.cherryview) &&
intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
return false;
@@ -566,11 +563,10 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp)
static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&display->pps.mutex);
- if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
+ if ((display->platform.valleyview || display->platform.cherryview) &&
intel_dp->pps.vlv_pps_pipe == INVALID_PIPE)
return false;
@@ -801,7 +797,8 @@ bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp)
}
/*
- * Must be paired with intel_pps_off().
+ * Must be paired with intel_pps_vdd_off() or - to disable
+ * both VDD and panel power - intel_pps_off().
* Nested calls to these functions are not allowed since
* we drop the lock. Caller must use some higher level
* locking to prevent nested calls from other threads.
@@ -809,7 +806,6 @@ bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp)
void intel_pps_vdd_on(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *i915 = to_i915(display->drm);
intel_wakeref_t wakeref;
bool vdd;
@@ -819,10 +815,10 @@ void intel_pps_vdd_on(struct intel_dp *intel_dp)
vdd = false;
with_intel_pps_lock(intel_dp, wakeref)
vdd = intel_pps_vdd_on_unlocked(intel_dp);
- I915_STATE_WARN(i915, !vdd, "[ENCODER:%d:%s] %s VDD already requested on\n",
- dp_to_dig_port(intel_dp)->base.base.base.id,
- dp_to_dig_port(intel_dp)->base.base.name,
- pps_name(intel_dp));
+ INTEL_DISPLAY_STATE_WARN(display, !vdd, "[ENCODER:%d:%s] %s VDD already requested on\n",
+ dp_to_dig_port(intel_dp)->base.base.base.id,
+ dp_to_dig_port(intel_dp)->base.base.name,
+ pps_name(intel_dp));
}
static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp)
@@ -861,8 +857,10 @@ static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp)
intel_de_read(display, pp_stat_reg),
intel_de_read(display, pp_ctrl_reg));
- if ((pp & PANEL_POWER_ON) == 0)
+ if ((pp & PANEL_POWER_ON) == 0) {
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
+ intel_dp_invalidate_source_oui(intel_dp);
+ }
intel_display_power_put(dev_priv,
intel_aux_power_domain(dig_port),
@@ -929,18 +927,17 @@ static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
void intel_pps_vdd_off_unlocked(struct intel_dp *intel_dp, bool sync)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&display->pps.mutex);
if (!intel_dp_is_edp(intel_dp))
return;
- I915_STATE_WARN(dev_priv, !intel_dp->pps.want_panel_vdd,
- "[ENCODER:%d:%s] %s VDD not forced on",
- dp_to_dig_port(intel_dp)->base.base.base.id,
- dp_to_dig_port(intel_dp)->base.base.name,
- pps_name(intel_dp));
+ INTEL_DISPLAY_STATE_WARN(display, !intel_dp->pps.want_panel_vdd,
+ "[ENCODER:%d:%s] %s VDD not forced on",
+ dp_to_dig_port(intel_dp)->base.base.base.id,
+ dp_to_dig_port(intel_dp)->base.base.name,
+ pps_name(intel_dp));
intel_dp->pps.want_panel_vdd = false;
@@ -950,10 +947,20 @@ void intel_pps_vdd_off_unlocked(struct intel_dp *intel_dp, bool sync)
edp_panel_vdd_schedule_off(intel_dp);
}
+void intel_pps_vdd_off(struct intel_dp *intel_dp)
+{
+ intel_wakeref_t wakeref;
+
+ if (!intel_dp_is_edp(intel_dp))
+ return;
+
+ with_intel_pps_lock(intel_dp, wakeref)
+ intel_pps_vdd_off_unlocked(intel_dp, false);
+}
+
void intel_pps_on_unlocked(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 pp;
i915_reg_t pp_ctrl_reg;
@@ -978,7 +985,7 @@ void intel_pps_on_unlocked(struct intel_dp *intel_dp)
pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
pp = ilk_get_pp_control(intel_dp);
- if (IS_IRONLAKE(dev_priv)) {
+ if (display->platform.ironlake) {
/* ILK workaround: disable reset around power sequence */
pp &= ~PANEL_POWER_RESET;
intel_de_write(display, pp_ctrl_reg, pp);
@@ -994,7 +1001,7 @@ void intel_pps_on_unlocked(struct intel_dp *intel_dp)
0, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
pp |= PANEL_POWER_ON;
- if (!IS_IRONLAKE(dev_priv))
+ if (!display->platform.ironlake)
pp |= PANEL_POWER_RESET;
intel_de_write(display, pp_ctrl_reg, pp);
@@ -1007,7 +1014,7 @@ void intel_pps_on_unlocked(struct intel_dp *intel_dp)
intel_de_rmw(display, SOUTH_DSPCLK_GATE_D,
PCH_DPLSUNIT_CLOCK_GATE_DISABLE, 0);
- if (IS_IRONLAKE(dev_priv)) {
+ if (display->platform.ironlake) {
pp |= PANEL_POWER_RESET; /* restore panel reset bit */
intel_de_write(display, pp_ctrl_reg, pp);
intel_de_posting_read(display, pp_ctrl_reg);
@@ -1063,6 +1070,8 @@ void intel_pps_off_unlocked(struct intel_dp *intel_dp)
wait_panel_off(intel_dp);
intel_dp->pps.panel_power_off_time = ktime_get_boottime();
+ intel_dp_invalidate_source_oui(intel_dp);
+
/* We got a reference when we enabled the VDD. */
intel_display_power_put(dev_priv,
intel_aux_power_domain(dig_port),
@@ -1148,7 +1157,7 @@ void intel_pps_backlight_power(struct intel_connector *connector, bool enable)
return;
drm_dbg_kms(display->drm, "panel power control backlight %s\n",
- enable ? "enable" : "disable");
+ str_enable_disable(enable));
if (enable)
intel_pps_backlight_on(intel_dp);
@@ -1627,7 +1636,7 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd
/* Haswell doesn't have any port selection bits for the panel
* power sequencer any more. */
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+ if (display->platform.valleyview || display->platform.cherryview) {
port_sel = PANEL_PORT_SELECT_VLV(port);
} else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) {
switch (port) {
@@ -1674,7 +1683,6 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd
void intel_pps_encoder_reset(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *i915 = to_i915(display->drm);
intel_wakeref_t wakeref;
if (!intel_dp_is_edp(intel_dp))
@@ -1685,7 +1693,7 @@ void intel_pps_encoder_reset(struct intel_dp *intel_dp)
* Reinit the power sequencer also on the resume path, in case
* BIOS did something nasty with it.
*/
- if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
+ if (display->platform.valleyview || display->platform.cherryview)
vlv_initial_power_sequencer_setup(intel_dp);
pps_init_delays(intel_dp);
@@ -1721,11 +1729,10 @@ bool intel_pps_init(struct intel_dp *intel_dp)
static void pps_init_late(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
- struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct intel_connector *connector = intel_dp->attached_connector;
- if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
+ if (display->platform.valleyview || display->platform.cherryview)
return;
if (intel_num_pps(display) < 2)
@@ -1783,9 +1790,9 @@ void intel_pps_setup(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
- if (HAS_PCH_SPLIT(i915) || IS_GEMINILAKE(i915) || IS_BROXTON(i915))
+ if (HAS_PCH_SPLIT(i915) || display->platform.geminilake || display->platform.broxton)
display->pps.mmio_base = PCH_PPS_BASE;
- else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
+ else if (display->platform.valleyview || display->platform.cherryview)
display->pps.mmio_base = VLV_PPS_BASE;
else
display->pps.mmio_base = PPS_BASE;
@@ -1857,7 +1864,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe)
MISSING_CASE(port_sel);
break;
}
- } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+ } else if (display->platform.valleyview || display->platform.cherryview) {
/* presumably write lock depends on pipe, not port select */
pp_reg = PP_CONTROL(display, pipe);
panel_pipe = pipe;
@@ -1878,7 +1885,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe)
((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS))
locked = false;
- I915_STATE_WARN(dev_priv, panel_pipe == pipe && locked,
- "panel assertion failure, pipe %c regs locked\n",
- pipe_name(pipe));
+ INTEL_DISPLAY_STATE_WARN(display, panel_pipe == pipe && locked,
+ "panel assertion failure, pipe %c regs locked\n",
+ pipe_name(pipe));
}