0001
0002
0003
0004
0005
0006 #include "hsw_ips.h"
0007 #include "i915_drv.h"
0008 #include "i915_reg.h"
0009 #include "intel_de.h"
0010 #include "intel_display_types.h"
0011 #include "intel_pcode.h"
0012
0013 static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
0014 {
0015 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0016 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
0017
0018 if (!crtc_state->ips_enabled)
0019 return;
0020
0021
0022
0023
0024
0025
0026 drm_WARN_ON(&i915->drm,
0027 !(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
0028
0029 if (IS_BROADWELL(i915)) {
0030 drm_WARN_ON(&i915->drm,
0031 snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL,
0032 IPS_ENABLE | IPS_PCODE_CONTROL));
0033
0034
0035
0036
0037
0038
0039 } else {
0040 intel_de_write(i915, IPS_CTL, IPS_ENABLE);
0041
0042
0043
0044
0045
0046
0047
0048 if (intel_de_wait_for_set(i915, IPS_CTL, IPS_ENABLE, 50))
0049 drm_err(&i915->drm,
0050 "Timed out waiting for IPS enable\n");
0051 }
0052 }
0053
0054 bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
0055 {
0056 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0057 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
0058 bool need_vblank_wait = false;
0059
0060 if (!crtc_state->ips_enabled)
0061 return need_vblank_wait;
0062
0063 if (IS_BROADWELL(i915)) {
0064 drm_WARN_ON(&i915->drm,
0065 snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, 0));
0066
0067
0068
0069
0070
0071 if (intel_de_wait_for_clear(i915, IPS_CTL, IPS_ENABLE, 100))
0072 drm_err(&i915->drm,
0073 "Timed out waiting for IPS disable\n");
0074 } else {
0075 intel_de_write(i915, IPS_CTL, 0);
0076 intel_de_posting_read(i915, IPS_CTL);
0077 }
0078
0079
0080 need_vblank_wait = true;
0081
0082 return need_vblank_wait;
0083 }
0084
0085 static bool hsw_ips_need_disable(struct intel_atomic_state *state,
0086 struct intel_crtc *crtc)
0087 {
0088 struct drm_i915_private *i915 = to_i915(state->base.dev);
0089 const struct intel_crtc_state *old_crtc_state =
0090 intel_atomic_get_old_crtc_state(state, crtc);
0091 const struct intel_crtc_state *new_crtc_state =
0092 intel_atomic_get_new_crtc_state(state, crtc);
0093
0094 if (!old_crtc_state->ips_enabled)
0095 return false;
0096
0097 if (intel_crtc_needs_modeset(new_crtc_state))
0098 return true;
0099
0100
0101
0102
0103
0104
0105
0106 if (IS_HASWELL(i915) &&
0107 (new_crtc_state->uapi.color_mgmt_changed ||
0108 new_crtc_state->update_pipe) &&
0109 new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
0110 return true;
0111
0112 return !new_crtc_state->ips_enabled;
0113 }
0114
0115 bool hsw_ips_pre_update(struct intel_atomic_state *state,
0116 struct intel_crtc *crtc)
0117 {
0118 const struct intel_crtc_state *old_crtc_state =
0119 intel_atomic_get_old_crtc_state(state, crtc);
0120
0121 if (!hsw_ips_need_disable(state, crtc))
0122 return false;
0123
0124 return hsw_ips_disable(old_crtc_state);
0125 }
0126
0127 static bool hsw_ips_need_enable(struct intel_atomic_state *state,
0128 struct intel_crtc *crtc)
0129 {
0130 struct drm_i915_private *i915 = to_i915(state->base.dev);
0131 const struct intel_crtc_state *old_crtc_state =
0132 intel_atomic_get_old_crtc_state(state, crtc);
0133 const struct intel_crtc_state *new_crtc_state =
0134 intel_atomic_get_new_crtc_state(state, crtc);
0135
0136 if (!new_crtc_state->ips_enabled)
0137 return false;
0138
0139 if (intel_crtc_needs_modeset(new_crtc_state))
0140 return true;
0141
0142
0143
0144
0145
0146
0147
0148 if (IS_HASWELL(i915) &&
0149 (new_crtc_state->uapi.color_mgmt_changed ||
0150 new_crtc_state->update_pipe) &&
0151 new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
0152 return true;
0153
0154
0155
0156
0157
0158 if (new_crtc_state->update_pipe && old_crtc_state->inherited)
0159 return true;
0160
0161 return !old_crtc_state->ips_enabled;
0162 }
0163
0164 void hsw_ips_post_update(struct intel_atomic_state *state,
0165 struct intel_crtc *crtc)
0166 {
0167 const struct intel_crtc_state *new_crtc_state =
0168 intel_atomic_get_new_crtc_state(state, crtc);
0169
0170 if (!hsw_ips_need_enable(state, crtc))
0171 return;
0172
0173 hsw_ips_enable(new_crtc_state);
0174 }
0175
0176
0177 bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
0178 {
0179 return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
0180 }
0181
0182 bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
0183 {
0184 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0185 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
0186
0187
0188 if (!hsw_crtc_supports_ips(crtc))
0189 return false;
0190
0191 if (!i915->params.enable_ips)
0192 return false;
0193
0194 if (crtc_state->pipe_bpp > 24)
0195 return false;
0196
0197
0198
0199
0200
0201
0202
0203
0204 if (IS_BROADWELL(i915) &&
0205 crtc_state->pixel_rate > i915->max_cdclk_freq * 95 / 100)
0206 return false;
0207
0208 return true;
0209 }
0210
0211 int hsw_ips_compute_config(struct intel_atomic_state *state,
0212 struct intel_crtc *crtc)
0213 {
0214 struct drm_i915_private *i915 = to_i915(state->base.dev);
0215 struct intel_crtc_state *crtc_state =
0216 intel_atomic_get_new_crtc_state(state, crtc);
0217
0218 crtc_state->ips_enabled = false;
0219
0220 if (!hsw_crtc_state_ips_capable(crtc_state))
0221 return 0;
0222
0223
0224
0225
0226
0227
0228
0229 if (crtc_state->crc_enabled)
0230 return 0;
0231
0232
0233 if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)))
0234 return 0;
0235
0236 if (IS_BROADWELL(i915)) {
0237 const struct intel_cdclk_state *cdclk_state;
0238
0239 cdclk_state = intel_atomic_get_cdclk_state(state);
0240 if (IS_ERR(cdclk_state))
0241 return PTR_ERR(cdclk_state);
0242
0243
0244 if (crtc_state->pixel_rate > cdclk_state->logical.cdclk * 95 / 100)
0245 return 0;
0246 }
0247
0248 crtc_state->ips_enabled = true;
0249
0250 return 0;
0251 }
0252
0253 void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
0254 {
0255 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0256 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
0257
0258 if (!hsw_crtc_supports_ips(crtc))
0259 return;
0260
0261 if (IS_HASWELL(i915)) {
0262 crtc_state->ips_enabled = intel_de_read(i915, IPS_CTL) & IPS_ENABLE;
0263 } else {
0264
0265
0266
0267
0268
0269 crtc_state->ips_enabled = true;
0270 }
0271 }